Skip to content

Commit 27e7d6d

Browse files
Merge branch 'main' of https://github.com/slopus/happy
2 parents 4afd67e + 45a9038 commit 27e7d6d

File tree

87 files changed

+16259
-1078
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+16259
-1078
lines changed

.github/workflows/typecheck.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: TypeScript typecheck
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
jobs:
10+
typecheck:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 15
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Setup Node
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: 20
21+
cache: yarn
22+
23+
- name: Install dependencies
24+
run: yarn install --frozen-lockfile
25+
26+
- name: TypeScript typecheck
27+
run: yarn typecheck

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ yarn-error.*
4444

4545
CLAUDE.local.md
4646

47-
.dev/worktree/*
47+
.dev/worktree/*
48+
49+
# Development planning notes (keep local, don't commit)
50+
notes/

CLAUDE.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
77
### Development
88
- `yarn start` - Start the Expo development server
99
- `yarn ios` - Run the app on iOS simulator
10-
- `yarn android` - Run the app on Android emulator
10+
- `yarn android` - Run the app on Android emulator
1111
- `yarn web` - Run the app in web browser
1212
- `yarn prebuild` - Generate native iOS and Android directories
1313
- `yarn typecheck` - Run TypeScript type checking after all changes
1414

15+
### macOS Desktop (Tauri)
16+
- `yarn tauri:dev` - Run macOS desktop app with hot reload
17+
- `yarn tauri:build:dev` - Build development variant
18+
- `yarn tauri:build:preview` - Build preview variant
19+
- `yarn tauri:build:production` - Build production variant
20+
1521
### Testing
1622
- `yarn test` - Run tests in watch mode (Jest with jest-expo preset)
1723
- No existing tests in the codebase yet

CONTRIBUTING.md

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
# Contributing to Happy
2+
3+
## Development Workflow: Build Variants
4+
5+
The Happy app supports three build variants across **iOS, Android, and macOS desktop**, each with separate bundle IDs so all three can be installed simultaneously:
6+
7+
| Variant | Bundle ID | App Name | Use Case |
8+
|---------|-----------|----------|----------|
9+
| **Development** | `com.slopus.happy.dev` | Happy (dev) | Local development with hot reload |
10+
| **Preview** | `com.slopus.happy.preview` | Happy (preview) | Beta testing & OTA updates before production |
11+
| **Production** | `com.ex3ndr.happy` | Happy | Public App Store release |
12+
13+
**Why Preview?**
14+
- **Development**: Fast iteration, dev server, instant reload
15+
- **Preview**: Beta testers get OTA updates (`eas update --branch preview`) without app store submission
16+
- **Production**: Stable App Store builds
17+
18+
This allows you to test production-like builds with real users before releasing to the App Store.
19+
20+
## Quick Start
21+
22+
### iOS Development
23+
24+
```bash
25+
# Development variant (default)
26+
npm run ios:dev
27+
28+
# Preview variant
29+
npm run ios:preview
30+
31+
# Production variant
32+
npm run ios:production
33+
```
34+
35+
### Android Development
36+
37+
```bash
38+
# Development variant
39+
npm run android:dev
40+
41+
# Preview variant
42+
npm run android:preview
43+
44+
# Production variant
45+
npm run android:production
46+
```
47+
48+
### macOS Desktop (Tauri)
49+
50+
```bash
51+
# Development variant - run with hot reload
52+
npm run tauri:dev
53+
54+
# Build development variant
55+
npm run tauri:build:dev
56+
57+
# Build preview variant
58+
npm run tauri:build:preview
59+
60+
# Build production variant
61+
npm run tauri:build:production
62+
```
63+
64+
**How Tauri Variants Work:**
65+
- Base config: `src-tauri/tauri.conf.json` (production defaults)
66+
- Partial configs: `tauri.dev.conf.json`, `tauri.preview.conf.json`
67+
- Tauri merges partial configs using [JSON Merge Patch (RFC 7396)](https://datatracker.ietf.org/doc/html/rfc7396)
68+
- Only differences need to be specified in partial configs (DRY principle)
69+
70+
### Development Server
71+
72+
```bash
73+
# Start dev server for development variant
74+
npm run start:dev
75+
76+
# Start dev server for preview variant
77+
npm run start:preview
78+
79+
# Start dev server for production variant
80+
npm run start:production
81+
```
82+
83+
## Visual Differences
84+
85+
Each variant displays a different app name on your device:
86+
- **Development**: "Happy (dev)" - Yellow/orange theme
87+
- **Preview**: "Happy (preview)" - Preview theme
88+
- **Production**: "Happy" - Standard theme
89+
90+
This makes it easy to distinguish which version you're testing!
91+
92+
## Common Workflows
93+
94+
### Testing Development Changes
95+
96+
1. **Build development variant:**
97+
```bash
98+
npm run ios:dev
99+
```
100+
101+
2. **Make your changes** to the code
102+
103+
3. **Hot reload** automatically updates the app
104+
105+
4. **Rebuild if needed** for native changes:
106+
```bash
107+
npm run ios:dev
108+
```
109+
110+
### Testing Preview (Pre-Release)
111+
112+
1. **Build preview variant:**
113+
```bash
114+
npm run ios:preview
115+
```
116+
117+
2. **Test OTA updates:**
118+
```bash
119+
npm run ota # Publishes to preview branch
120+
```
121+
122+
3. **Verify** the preview build works as expected
123+
124+
### Production Release
125+
126+
1. **Build production variant:**
127+
```bash
128+
npm run ios:production
129+
```
130+
131+
2. **Submit to App Store:**
132+
```bash
133+
npm run submit
134+
```
135+
136+
3. **Deploy OTA updates:**
137+
```bash
138+
npm run ota:production
139+
```
140+
141+
## All Variants Simultaneously
142+
143+
You can install all three variants on the same device:
144+
145+
```bash
146+
# Build all three variants
147+
npm run ios:dev
148+
npm run ios:preview
149+
npm run ios:production
150+
```
151+
152+
All three apps appear on your device with different icons and names!
153+
154+
## EAS Build Profiles
155+
156+
The project includes EAS build profiles for automated builds:
157+
158+
```bash
159+
# Development build
160+
eas build --profile development
161+
162+
# Production build
163+
eas build --profile production
164+
```
165+
166+
## Environment Variables
167+
168+
Each variant can use different environment variables via `APP_ENV`:
169+
170+
```javascript
171+
// In app.config.js
172+
const variant = process.env.APP_ENV || 'development';
173+
```
174+
175+
This controls:
176+
- Bundle identifier
177+
- App name
178+
- Associated domains (deep linking)
179+
- Intent filters (Android)
180+
- Other variant-specific configuration
181+
182+
## Deep Linking
183+
184+
Only **production** variant has deep linking configured:
185+
186+
- **Production**: `https://app.happy.engineering/*`
187+
- **Development**: No deep linking
188+
- **Preview**: No deep linking
189+
190+
This prevents dev/preview builds from interfering with production deep links.
191+
192+
## Testing Connected to Different Servers
193+
194+
You can connect different variants to different Happy CLI instances:
195+
196+
```bash
197+
# Development app → Dev CLI daemon
198+
npm run android:dev
199+
# Connect to CLI running: npm run dev:daemon:start
200+
201+
# Production app → Stable CLI daemon
202+
npm run android:production
203+
# Connect to CLI running: npm run stable:daemon:start
204+
```
205+
206+
Each app maintains separate authentication and sessions!
207+
208+
## Local Server Development
209+
210+
To test with a local Happy server:
211+
212+
```bash
213+
npm run start:local-server
214+
```
215+
216+
This sets:
217+
- `EXPO_PUBLIC_HAPPY_SERVER_URL=http://localhost:3005`
218+
- `EXPO_PUBLIC_DEBUG=1`
219+
- Debug logging enabled
220+
221+
## Troubleshooting
222+
223+
### Build fails with "Bundle identifier already in use"
224+
225+
This shouldn't happen - each variant has a unique bundle ID. If it does:
226+
227+
1. Check `app.config.js` - verify `bundleId` is set correctly for the variant
228+
2. Clean build:
229+
```bash
230+
npm run prebuild
231+
npm run ios:dev # or whichever variant
232+
```
233+
234+
### App not updating after changes
235+
236+
1. **For JS changes**: Hot reload should work automatically
237+
2. **For native changes**: Rebuild the variant:
238+
```bash
239+
npm run ios:dev # Force rebuild
240+
```
241+
3. **For config changes**: Clean and prebuild:
242+
```bash
243+
npm run prebuild
244+
npm run ios:dev
245+
```
246+
247+
### All three apps look the same
248+
249+
Check the app name on the home screen:
250+
- "Happy (dev)"
251+
- "Happy (preview)"
252+
- "Happy"
253+
254+
If they're all the same name, the variant might not be set correctly. Verify:
255+
256+
```bash
257+
# Check what APP_ENV is set to
258+
echo $APP_ENV
259+
260+
# Or look at the build output
261+
npm run ios:dev # Should show "Happy (dev)" as the name
262+
```
263+
264+
### Connected device not found
265+
266+
For iOS connected device testing:
267+
268+
```bash
269+
# List available devices
270+
xcrun devicectl list devices
271+
272+
# Run on specific connected device
273+
npm run ios:connected-device
274+
```
275+
276+
## Tips
277+
278+
1. **Use development variant for active work** - Fast iteration, debug features enabled
279+
2. **Use preview for pre-release testing** - Test OTA updates before production
280+
3. **Use production for final validation** - Exact configuration that ships to users
281+
4. **Install all three simultaneously** - Compare behaviors side-by-side
282+
5. **Different CLI instances** - Connect dev app to dev CLI, prod app to stable CLI
283+
6. **Check app name** - Always visible which variant you're testing
284+
285+
## How It Works
286+
287+
The `app.config.js` file reads the `APP_ENV` environment variable:
288+
289+
```javascript
290+
const variant = process.env.APP_ENV || 'development';
291+
const bundleId = {
292+
development: "com.slopus.happy.dev",
293+
preview: "com.slopus.happy.preview",
294+
production: "com.ex3ndr.happy"
295+
}[variant];
296+
```
297+
298+
The `cross-env` package ensures this works cross-platform:
299+
300+
```json
301+
{
302+
"scripts": {
303+
"ios:dev": "cross-env APP_ENV=development expo run:ios"
304+
}
305+
}
306+
```
307+
308+
Cross-platform via `cross-env` - works identically on Windows, macOS, and Linux!

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Use Claude Code or Codex from anywhere with end-to-end encryption.
1010

1111
<div align="center">
1212

13-
[📱 **iOS App**](https://apps.apple.com/us/app/happy-claude-code-client/id6748571505)[🤖 **Android App**](https://play.google.com/store/apps/details?id=com.ex3ndr.happy)[🌐 **Web App**](https://app.happy.engineering)[🎥 **See a Demo**](https://youtu.be/GCS0OG9QMSE)[📚 **Documentation**](https://happy.engineering/docs/)[💬 **Discord**](https://discord.gg/aVhXZfYh)
13+
[📱 **iOS App**](https://apps.apple.com/us/app/happy-claude-code-client/id6748571505)[🤖 **Android App**](https://play.google.com/store/apps/details?id=com.ex3ndr.happy)[🌐 **Web App**](https://app.happy.engineering)[🎥 **See a Demo**](https://youtu.be/GCS0OG9QMSE)[📚 **Documentation**](https://happy.engineering/docs/)[💬 **Discord**](https://discord.gg/fX9WBAhyfD)
1414

1515
</div>
1616

@@ -76,6 +76,7 @@ We're engineers scattered across Bay Area coffee shops and hacker houses, consta
7676
## 📚 Documentation & Contributing
7777

7878
- **[Documentation Website](https://happy.engineering/docs/)** - Learn how to use Happy Coder effectively
79+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Development setup including iOS, Android, and macOS desktop variant builds
7980
- **[Edit docs at github.com/slopus/slopus.github.io](https://github.com/slopus/slopus.github.io)** - Help improve our documentation and guides
8081

8182
## License

0 commit comments

Comments
 (0)