Skip to content

Commit 4c4ada8

Browse files
skoob13a-liderjonathanlab
authored
hackathon: Mobile App (#224)
Co-authored-by: Alex <alex.lider@posthog.com> Co-authored-by: JonathanLab <jonathanmieloo@gmail.com>
1 parent 509d093 commit 4c4ada8

99 files changed

Lines changed: 16153 additions & 3222 deletions

File tree

Some content is hidden

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

.npmrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
node-linker=hoisted
1+
node-linker=hoisted
2+
shamefully-hoist=true

README.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
# PostHog Array Monorepo
66

7-
This is the monorepo for PostHog's Array desktop task manager and the agent framework that powers it.
7+
This is the monorepo for PostHog's Array apps and the agent framework that powers them.
88

99
## Projects
1010

11-
- **[apps/array](./apps/array)** - The Array desktop application
11+
- **[apps/array](./apps/array)** - Array desktop application (Electron)
12+
- **[apps/mobile](./apps/mobile)** - PostHog mobile app (React Native / Expo)
1213
- **[packages/agent](./packages/agent)** - The TypeScript agent framework
1314

1415
## Development
@@ -42,6 +43,24 @@ pnpm dev:agent # Run agent in watch mode
4243
pnpm dev:array # Run array app
4344
```
4445

46+
### Mobile App
47+
48+
```bash
49+
# Install mobile dependencies
50+
pnpm mobile:install
51+
52+
# Build and run on iOS simulator
53+
pnpm mobile:run:ios
54+
55+
# Start development server (without rebuilding again)
56+
pnpm mobile:start
57+
58+
# Submit to TestFlight
59+
pnpm mobile:testflight
60+
```
61+
62+
See [apps/mobile/README.md](./apps/mobile/README.md) for more details on developing the mobile app.
63+
4564
### Other Commands
4665

4766
```bash
@@ -63,7 +82,8 @@ pnpm test
6382
```
6483
array-monorepo/
6584
├── apps/
66-
│ └── array/ # Electron desktop app
85+
│ ├── array/ # Electron desktop app
86+
│ └── mobile/ # React Native mobile app (Expo)
6787
├── packages/
6888
│ └── agent/ # Agent framework
6989
├── pnpm-workspace.yaml # Workspace configuration

apps/array/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
"@testing-library/react": "^16.3.0",
4646
"@testing-library/user-event": "^14.6.1",
4747
"@types/node": "^20.19.21",
48-
"@types/react": "^18.2.48",
49-
"@types/react-dom": "^18.2.18",
48+
"@types/react": "^19.1.0",
49+
"@types/react-dom": "^19.1.0",
5050
"@types/uuid": "^9.0.7",
5151
"@vitejs/plugin-react": "^4.2.1",
5252
"@vitest/ui": "^4.0.10",
@@ -57,11 +57,11 @@
5757
"jsdom": "^26.0.0",
5858
"lint-staged": "^15.5.2",
5959
"postcss": "^8.4.33",
60-
"tailwindcss": "^3.4.1",
60+
"tailwindcss": "^3.4.18",
6161
"tsx": "^4.20.6",
6262
"typed-openapi": "^2.2.2",
6363
"typescript": "^5.9.3",
64-
"vite": "^5.0.12",
64+
"vite": "^6.0.7",
6565
"vite-tsconfig-paths": "^5.1.4",
6666
"vitest": "^4.0.10",
6767
"yaml": "^2.8.1"
@@ -138,8 +138,8 @@
138138
"posthog-js": "^1.283.0",
139139
"posthog-node": "^4.18.0",
140140
"radix-themes-tw": "0.2.3",
141-
"react": "^18.2.0",
142-
"react-dom": "^18.2.0",
141+
"react": "19.1.0",
142+
"react-dom": "19.1.0",
143143
"react-hook-form": "^7.64.0",
144144
"react-hotkeys-hook": "^4.4.4",
145145
"react-markdown": "^10.1.0",

apps/array/src/renderer/features/sessions/components/raw-logs/RawLogsHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface RawLogsHeaderProps {
1010
onToggleSearch: () => void;
1111
onCopyAll: () => void;
1212
onSearchChange: (query: string) => void;
13-
searchInputRef: RefObject<HTMLInputElement>;
13+
searchInputRef: RefObject<HTMLInputElement | null>;
1414
}
1515

1616
export function RawLogsHeader({

apps/array/src/renderer/hooks/useAutoScroll.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface UseAutoScrollOptions<T extends string> {
1010
}
1111

1212
interface UseAutoScrollReturn {
13-
scrollRef: React.RefObject<HTMLDivElement>;
13+
scrollRef: React.RefObject<HTMLDivElement | null>;
1414
autoScroll: boolean;
1515
setAutoScroll: (value: boolean) => void;
1616
}

apps/mobile/.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2+
3+
# dependencies
4+
node_modules/
5+
6+
# Expo
7+
.expo/
8+
dist/
9+
web-build/
10+
expo-env.d.ts
11+
12+
# Native
13+
.kotlin/
14+
*.orig.*
15+
*.jks
16+
*.p8
17+
*.p12
18+
*.key
19+
*.mobileprovision
20+
21+
# Metro
22+
.metro-health-check*
23+
24+
# debug
25+
npm-debug.*
26+
yarn-debug.*
27+
yarn-error.*
28+
29+
# macOS
30+
.DS_Store
31+
*.pem
32+
33+
# local env files
34+
.env*.local
35+
36+
# typescript
37+
*.tsbuildinfo
38+
39+
# generated native folders
40+
/ios
41+
/android

apps/mobile/README.md

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
# PostHog Mobile App
2+
3+
React Native mobile app built with Expo and expo-router.
4+
5+
## Quick Start
6+
7+
From the **repository root**:
8+
9+
```bash
10+
# Install dependencies
11+
pnpm mobile:install
12+
13+
# Build and run on iOS simulator
14+
pnpm mobile:run:ios
15+
16+
# Start the development server (after initial build)
17+
pnpm mobile:start
18+
```
19+
20+
## Tech Stack
21+
22+
- [Expo](https://expo.dev) - Build tooling, native APIs, OTA updates
23+
- [expo-router](https://docs.expo.dev/router/introduction/) - File-based routing
24+
- [NativeWind](https://www.nativewind.dev/) - Tailwind CSS for React Native
25+
- [React Query](https://tanstack.com/query) - Async data fetching and caching
26+
- [Zustand](https://zustand-demo.pmnd.rs/) - Client state management (UI state, selections, local flags)
27+
- [Phosphor Icons](https://phosphoricons.com/) - Icon library
28+
29+
## Architecture
30+
31+
### Feature Folders
32+
33+
Code is organized by feature in `src/features/`. Each feature is self-contained with its own components, hooks, stores, and API logic.
34+
35+
```
36+
src/features/
37+
├── auth/ # Authentication & user session
38+
│ ├── hooks/
39+
│ ├── lib/
40+
│ ├── stores/
41+
│ └── types.ts
42+
├── chat/ # PostHog AI chat interface
43+
│ ├── components/
44+
│ ├── hooks/
45+
│ ├── stores/
46+
│ └── types.ts
47+
├── conversations/ # PostHog AI conversation list & management
48+
│ ├── api.ts
49+
│ ├── components/
50+
│ ├── hooks/
51+
│ └── stores/
52+
└── tasks/ # Task management
53+
├── api.ts
54+
├── components/
55+
├── hooks/
56+
└── stores/
57+
```
58+
59+
### File-Based Routing
60+
61+
Routes for the screens are defined by the file structure in `src/app/` using expo-router.
62+
63+
- `(tabs)/` - Parentheses create a layout group (tab navigator)
64+
- `_layout.tsx` - Configures the navigator for that directory
65+
- `[id].tsx` - Square brackets define dynamic route parameters
66+
- Stacks and modals live outside tab group, configured in `_layout.tsx`
67+
68+
```
69+
src/app/
70+
├── _layout.tsx # Root layout
71+
├── index.tsx # Entry redirect
72+
├── auth.tsx # Auth screen (unauthenticated)
73+
├── (tabs)/ # Tabs group
74+
│ ├── _layout.tsx # Layout for all tabs
75+
│ ├── index.tsx # Home tab (Conversations)
76+
│ ├── tasks.tsx # Tasks tab
77+
│ └── settings.tsx # Settings tab
78+
├── chat/ # Chat stack
79+
│ ├── index.tsx # New chat
80+
│ └── [id].tsx # Chat by ID (dynamic route)
81+
└── task/ # Task stack
82+
├── index.tsx # New task
83+
└── [id].tsx # Task by ID (dynamic route)
84+
```
85+
86+
### Shared Code
87+
88+
```
89+
src/
90+
├── components/ # Reusable UI components (Text, etc.)
91+
└── lib/
92+
├── posthog.ts # Analytics setup
93+
├── queryClient.ts # React Query client
94+
├── theme.ts # Design tokens
95+
└── logger.ts # Logger setup
96+
```
97+
98+
## Prerequisites
99+
100+
- Node.js 22+
101+
- pnpm 10.23.0
102+
- Xcode (for iOS development)
103+
- Android Studio (for Android development)
104+
- EAS CLI: `npm install -g eas-cli`
105+
106+
## Commands
107+
108+
### From Repository Root
109+
110+
**Development server:**
111+
```bash
112+
pnpm mobile:start # Start Expo dev server
113+
pnpm mobile:start:clear # Start with cleared Metro cache
114+
```
115+
116+
**Build and run:**
117+
```bash
118+
pnpm mobile:run:ios # iOS simulator
119+
pnpm mobile:run:ios:device # iOS device (requires Apple Developer account)
120+
pnpm mobile:run:android # Android emulator/device
121+
```
122+
123+
**Native code generation:**
124+
```bash
125+
pnpm mobile:prebuild # Generate ios/ and android/ folders
126+
pnpm mobile:prebuild:clean # Delete and regenerate (when adding native deps)
127+
```
128+
129+
**EAS builds:**
130+
```bash
131+
pnpm mobile:build:dev # Development build (iOS, cloud)
132+
pnpm mobile:build:dev:local # Development build (iOS, local)
133+
pnpm mobile:build:preview # Preview build (iOS)
134+
pnpm mobile:build:production # Production build (iOS)
135+
```
136+
137+
**TestFlight:**
138+
```bash
139+
pnpm mobile:testflight # Submit to TestFlight
140+
```
141+
142+
**Utilities:**
143+
```bash
144+
pnpm mobile:install # Install mobile dependencies
145+
pnpm mobile:lint # Run Biome check
146+
pnpm mobile:format # Run Biome format
147+
```
148+
149+
### From apps/mobile/ Directory
150+
151+
```bash
152+
cd apps/mobile
153+
154+
# Development server
155+
npx expo start
156+
npx expo start --clear
157+
158+
# Build and run
159+
npx expo run:ios
160+
npx expo run:ios --device
161+
npx expo run:android
162+
npx expo run:android --device
163+
164+
# Generate native code
165+
npx expo prebuild
166+
npx expo prebuild --clean
167+
168+
# EAS builds (iOS)
169+
npx eas build --profile development --platform ios
170+
npx eas build --profile development --platform ios --local
171+
npx eas build --profile preview --platform ios
172+
npx eas build --profile production --platform ios
173+
174+
# EAS builds (Android)
175+
npx eas build --profile development --platform android
176+
npx eas build --profile preview --platform android
177+
npx eas build --profile production --platform android
178+
179+
# TestFlight
180+
npx testflight
181+
npx eas submit --platform ios
182+
183+
# Linting
184+
pnpm lint
185+
pnpm lint:fix
186+
pnpm format
187+
```
188+
189+
## Prebuild Explained
190+
191+
`expo prebuild` generates the native `ios/` and `android/` folders from your Expo configuration.
192+
193+
**When to run `prebuild`:**
194+
- First time setting up the project
195+
- After adding/removing native dependencies (e.g., `expo-camera`, `react-native-maps`)
196+
- After changing `app.json` iOS/Android configuration
197+
- After updating Expo SDK version
198+
199+
**When to use `--clean`:**
200+
- Switching between Expo SDK versions
201+
- Native build is failing and you want a fresh start
202+
- You've made manual changes to native files that you want to discard
203+
204+
The `--clean` flag removes existing `ios/` and `android/` directories before regenerating.
205+
206+
## Build Profiles
207+
208+
Defined in `eas.json`:
209+
210+
| Profile | Purpose | Distribution |
211+
|---------|---------|--------------|
212+
| `development` | Dev client with debugging | Internal only |
213+
| `preview` | Production-like for testing | Internal only |
214+
| `production` | App Store / Play Store release | Public |
215+
216+
**Local vs Cloud builds:**
217+
- Cloud (default): Runs on Expo's servers, no local Xcode needed
218+
- Local (`--local`): Runs on your machine, faster iteration, requires Xcode/Android SDK

0 commit comments

Comments
 (0)