Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
0b59b55
Added new nav bar
Gilbert09 May 13, 2026
68ed364
Nav changes
Gilbert09 May 13, 2026
72b5c15
New styles
Gilbert09 May 13, 2026
2b7d485
Added icons to the task list
Gilbert09 May 13, 2026
33083e0
task list icons
Gilbert09 May 13, 2026
c0285fb
Added smooth nav
Gilbert09 May 13, 2026
0cdf6ad
Added filtering
Gilbert09 May 13, 2026
d0d37c5
Added better nav presses
Gilbert09 May 13, 2026
caef810
new task UI
Gilbert09 May 13, 2026
b9f8cbf
Add mobile task automations UI
annikaschmid May 13, 2026
32cd2ba
i think we have notifications now but i haven't read the code
dmarticus May 13, 2026
ede8764
binch
dmarticus May 13, 2026
13bf4d1
Merge hackathon-mobile-app into mobile automations
annikaschmid May 13, 2026
1a0821e
poosh
dmarticus May 13, 2026
af59c3d
based
dmarticus May 13, 2026
9eb94ab
sickos yes
oliverb123 May 13, 2026
a2a6ea4
fix icon
dmarticus May 13, 2026
543eede
Merge branch 'hackathon-mobile-app' of github.com:PostHog/code into h…
dmarticus May 13, 2026
d677d33
Store last used repo
Gilbert09 May 13, 2026
96b551d
Added a text input for the chat view
Gilbert09 May 13, 2026
a0869b2
Remove local settings from source control
Gilbert09 May 13, 2026
a9aead1
Updated settings file
Gilbert09 May 13, 2026
6ea5aad
Updated claude.md with mobile stuff
Gilbert09 May 13, 2026
8a1bda5
Updated the task view to be a lot better
Gilbert09 May 13, 2026
19ea4c2
fix(mobile): improve automation run status updates
annikaschmid May 13, 2026
4dc29a1
cater to degens
oliverb123 May 13, 2026
c820e4b
pretty reports
oliverb123 May 13, 2026
aa26857
Floating UI
Gilbert09 May 13, 2026
08d3168
Added inbox header
Gilbert09 May 14, 2026
b051e11
Updated filter overlay
Gilbert09 May 14, 2026
0bbb8ae
fix task title bar
oliverb123 May 14, 2026
c04f1f3
style(mobile): replace monospace UI fonts
annikaschmid May 14, 2026
f2a4f05
Added attachments
Gilbert09 May 14, 2026
97a8074
git ignore
Gilbert09 May 14, 2026
f7f4cd1
fix this
dmarticus May 14, 2026
df9823b
Added voice recording
Gilbert09 May 14, 2026
282f6a7
Added git status to a task
Gilbert09 May 14, 2026
80b2066
Fixed task header fade
Gilbert09 May 14, 2026
ce8220a
swipe right on me baby
oliverb123 May 14, 2026
2d50115
Added file diff viewer
Gilbert09 May 14, 2026
28aaa87
chat feed updates
Gilbert09 May 14, 2026
c846cfd
Improve mobile tool call details and session activity
annikaschmid May 14, 2026
9e8770c
Render images in chat
Gilbert09 May 14, 2026
2e1105c
Merge remote-tracking branch 'origin/hackathon-mobile-app' into hacka…
annikaschmid May 14, 2026
06b6ee2
Persist images
Gilbert09 May 14, 2026
028d526
tinder tweaks
oliverb123 May 14, 2026
2c11f86
Upgraded settings a bunch
Gilbert09 May 14, 2026
49c1692
Adjust mobile task icon precedence
annikaschmid May 14, 2026
2e536c5
Merge remote-tracking branch 'origin/hackathon-mobile-app' into hacka…
annikaschmid May 14, 2026
0385074
Guard mobile attachment pickers
annikaschmid May 14, 2026
6fbe8b9
Removed Hedgehog mode
Gilbert09 May 14, 2026
574c2e2
enhance the reports inbox
dmarticus May 14, 2026
1fea6c7
resolve conflicts
dmarticus May 14, 2026
480e172
tinder for all
oliverb123 May 14, 2026
64aad3f
Match mobile app icon to desktop app
annikaschmid May 14, 2026
970eefc
Merge remote-tracking branch 'origin/hackathon-mobile-app' into hacka…
annikaschmid May 14, 2026
331806f
mobile: stream cloud runs over SSE (#2147)
oliverb123 May 14, 2026
2444535
fixing the tool call ui
dmarticus May 14, 2026
e14bddf
Merge branch 'hackathon-mobile-app' of github.com:PostHog/code into h…
dmarticus May 14, 2026
b0e0689
feat(mobile): add automation templates
annikaschmid May 14, 2026
2a1cc20
i think this fixes tool calls
dmarticus May 14, 2026
377f559
Merge remote-tracking branch 'origin/hackathon-mobile-app' into hacka…
annikaschmid May 14, 2026
6510d92
Added mcp servers
Gilbert09 May 14, 2026
6e50256
Automations list UX
Gilbert09 May 14, 2026
974e9cd
fix(code): preserve repo selection in task input
annikaschmid May 14, 2026
333c5d3
fix(mobile): hide running automation badge
annikaschmid May 14, 2026
69ff33c
Added universal links
Gilbert09 May 14, 2026
421c769
Remove AI chat
Gilbert09 May 14, 2026
3ca028d
feat(mobile): add watch app (#2148)
ioannisj May 14, 2026
4469052
fix push notif auth
dmarticus May 14, 2026
6854225
feat(mobile): build skill-based automation creation
annikaschmid May 14, 2026
bf662f1
Merge remote-tracking branch 'origin/hackathon-mobile-app' into hacka…
annikaschmid May 14, 2026
c3646f6
fix: le
ioannisj May 14, 2026
fa36ee8
fix:
ioannisj May 14, 2026
9f794ef
tinder tweaks
oliverb123 May 14, 2026
c05fd3c
fix icons
oliverb123 May 14, 2026
4bd771f
feat(mobile): add plan approvals and PostHog chips
annikaschmid May 14, 2026
72f26d1
Merge branch 'hackathon-mobile-app' of github.com:PostHog/code into h…
dmarticus May 14, 2026
8e3afa6
Expo build setup
Gilbert09 May 14, 2026
6347303
Png
Gilbert09 May 14, 2026
09c24fc
ugh stop breaking shit
dmarticus May 14, 2026
69d804b
Merge branch 'hackathon-mobile-app' of github.com:PostHog/code into h…
dmarticus May 14, 2026
4d230ed
prod eas
Gilbert09 May 14, 2026
b8c3173
Merge branch 'hackathon-mobile-app' of github.com:PostHog/code into h…
dmarticus May 14, 2026
6c49f7b
updated the readme
dmarticus May 17, 2026
f2a79a6
few more fixes
dmarticus May 17, 2026
1a1ad48
Task loading state, loading old tasks fix, app.icon > posthog.icon
oliverb123 May 17, 2026
67a5bef
repo selector caching, automation ui touch up
oliverb123 May 17, 2026
ef6fa5c
remove watch stuff
dmarticus May 19, 2026
ddc4027
fix plan crashes
dmarticus May 19, 2026
abe535c
Merge remote-tracking branch 'origin/main' into hackathon-mobile-app
dmarticus May 19, 2026
20ac39c
fix(mobile): resolve biome ci errors
dmarticus May 19, 2026
c1e7e41
fix(mobile): resolve test failures
dmarticus May 20, 2026
4f48227
nice, this UX feels crispy
dmarticus May 20, 2026
573d582
feedback on many things
dmarticus May 20, 2026
e386042
we done?
dmarticus May 20, 2026
d0eafcb
Merge remote-tracking branch 'origin/main' into hackathon-mobile-app
dmarticus May 20, 2026
eba1990
Fixed github auth
Gilbert09 May 21, 2026
43fed8e
Added a debug info section to settings
Gilbert09 May 21, 2026
6cf5ffd
Updated github connection
Gilbert09 May 21, 2026
df2c657
Added a project picker in-app
Gilbert09 May 21, 2026
3560c69
Added workflows for building the app
Gilbert09 May 21, 2026
5eb4591
Merge branch 'main' into hackathon-mobile-app
dmarticus May 21, 2026
1a51404
Potential fix for pull request finding 'CodeQL / Workflow does not co…
Gilbert09 May 22, 2026
6bb1abe
fix(ci): avoid shell injection in mobile workflows
Gilbert09 May 22, 2026
f18c092
revert: drop stray desktop repo-selection fix from mobile branch
Gilbert09 May 22, 2026
f2815a1
Merge branch 'main' into hackathon-mobile-app
Gilbert09 May 22, 2026
45e302b
feat(mobile): add Auto execution mode to match desktop
Gilbert09 May 22, 2026
ab97fa5
fix(mobile): stop vitest hanging on native module mocks
Gilbert09 May 22, 2026
9feb8f3
chore: remove mobile planning docs from branch
Gilbert09 May 22, 2026
de350bc
chore(ci): use EAS-stored Google Play credentials for mobile promote
Gilbert09 May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/workflows/mobile-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Mobile Build

# Builds the Expo mobile app (apps/mobile) for iOS and Android on EAS.
# The two platforms run as parallel matrix jobs, so both builds are queued
# simultaneously.
#
# Required repository secret:
# EXPO_TOKEN - an Expo access token with build permissions for the
# "posthog" account (https://expo.dev/settings/access-tokens).

on:
workflow_dispatch:
inputs:
profile:
description: "EAS build profile"
type: choice
default: production
options:
- development
- preview
- production
wait:
description: "Wait for the EAS build to finish (uncheck to just queue and exit)"
type: boolean
default: true

concurrency:
group: mobile-build-${{ github.ref }}-${{ inputs.profile }}
cancel-in-progress: false

jobs:
build:
name: Build (${{ matrix.platform }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
permissions:
contents: read
defaults:
run:
working-directory: apps/mobile
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false

- name: Setup pnpm
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: "pnpm"

- name: Setup EAS
uses: expo/expo-github-action@4479f9c12e08b76bb8a6ae00a31544a13d3b3d68 # v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: .

- name: EAS build
env:
PLATFORM: ${{ matrix.platform }}
PROFILE: ${{ inputs.profile }}
WAIT_FLAG: ${{ inputs.wait && '--wait' || '--no-wait' }}
run: |
eas build \
--non-interactive \
--platform "$PLATFORM" \
--profile "$PROFILE" \
"$WAIT_FLAG"

# Auto-promote the freshly built production binaries. Only runs when the build
# job waited for completion (otherwise there is no finished build to submit).
promote:
permissions: {}
needs: build
if: ${{ inputs.profile == 'production' && inputs.wait }}
uses: ./.github/workflows/mobile-promote.yml
with:
platform: all
profile: production
secrets: inherit
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
98 changes: 98 additions & 0 deletions .github/workflows/mobile-promote.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Mobile Promote

# Promotes the most recent finished EAS build to the stores:
# iOS -> App Store Connect (build becomes available in TestFlight)
# Android -> Google Play "internal" testing track
#
# Uses `eas submit --latest`, which submits the latest successful build for the
# selected platform/profile. Run "Mobile Build" with the matching profile first.
#
# Required repository secret:
# EXPO_TOKEN - Expo access token (submit permissions).
#
# Store credentials live on EAS, not in this repo: the iOS App Store Connect API
# key and the Android Google Play service account key are configured once via
# `eas credentials` so that `--non-interactive` submits can authenticate.

on:
workflow_dispatch:
inputs:
platform:
description: "Platform to promote"
type: choice
default: all
options:
- all
- ios
- android
profile:
description: "EAS submit profile"
type: choice
default: production
options:
- production
# Allows "Mobile Build" to chain into this workflow after a successful build.
workflow_call:
inputs:
platform:
type: string
default: all
profile:
type: string
default: production
secrets:
EXPO_TOKEN:
required: true

concurrency:
group: mobile-promote-${{ github.ref }}
cancel-in-progress: false

jobs:
submit:
name: Submit (${{ matrix.platform }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: ${{ inputs.platform == 'all' && fromJSON('["ios","android"]') || fromJSON(format('["{0}"]', inputs.platform)) }}
permissions:
contents: read
defaults:
run:
working-directory: apps/mobile
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false

- name: Setup pnpm
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: "pnpm"

- name: Setup EAS
uses: expo/expo-github-action@4479f9c12e08b76bb8a6ae00a31544a13d3b3d68 # v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: .

- name: EAS submit
env:
PLATFORM: ${{ matrix.platform }}
PROFILE: ${{ inputs.profile }}
run: |
eas submit \
--non-interactive \
--platform "$PLATFORM" \
--profile "$PROFILE" \
--latest
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ plugins/posthog/local-skills/

# Symlinked copies of posthog, to make developing against those APIs easier
posthog-sym

.claude/settings.local.json

apps/mobile/ROADMAP.md
83 changes: 83 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ See [ARCHITECTURE.md](./apps/code/ARCHITECTURE.md) for detailed patterns (DI, se
- Saga pattern for atomic multi-step operations with automatic rollback
- Built with tsup, outputs ESM

### Mobile App (apps/mobile)

- React Native + Expo (SDK 54), expo-router for file-based routing
- NativeWind v4 for styling (Tailwind classes compiled to RN styles)
- React Query for server state, Zustand for client state
- See [Mobile App](#mobile-app-appsmobile-1) section below for UI rules and patterns — Electron patterns in `Code Patterns` do NOT apply on mobile

## Agent Integration Guidelines

- **No rawInput**: Don't use Claude Code SDK's `rawInput` - only use Zod validated meta fields. This keeps us agent agnostic and gives us a maintainable, extensible format for logs.
Expand Down Expand Up @@ -364,6 +371,82 @@ export const useNavigationStore = create<NavigationStore>()(
);
```

## Mobile App (apps/mobile)

When working in `apps/mobile/`, the patterns in `Code Patterns` above are for the **Electron renderer** (web DOM, Radix, web Tailwind v4). They do NOT apply here. Mobile is React Native: no `<div>`, no `window`/`document`/`localStorage`, no `:hover`/`cursor-*`/`focus-visible:`, no CSS `position: fixed`, no `overflow-y-auto`. If a feature only exists in CSS, it doesn't exist on mobile — design for touch and native primitives.

See [apps/mobile/README.md](./apps/mobile/README.md) for setup, build profiles, and full command list.

### Mobile UI Principles

Every screen must be designed for a phone: portrait-first, touch-driven, dark + light mode, safe areas honoured, keyboard-aware. Treat tablet/landscape as a stretch goal, not a baseline — but never let layouts hard-break on them.

- **Touch targets are 44pt minimum.** Use `hitSlop` to widen the hit area when the visual element is smaller. Never assume a pointer.
- **Provide press feedback.** `active:opacity-*` or `active:bg-*` on every `Pressable`. There is no hover state — feedback only happens on press.
- **Honour safe areas.** Use `useSafeAreaInsets()` from `react-native-safe-area-context` for top/bottom padding. Never hardcode status-bar height. Edge-to-edge screens (no native header) MUST account for the notch and home indicator.
- **Keyboard handling is mandatory for any input.** Use `react-native-keyboard-controller`'s `KeyboardAvoidingView` / `KeyboardAwareScrollView`. Set `keyboardShouldPersistTaps="handled"` on scroll containers that contain inputs. Verify the composer/input remains visible with the keyboard up.
- **Dark mode is not optional.** Every new screen must work in both light and dark. Pick from theme tokens, never raw hex.
- **One-handed reachability.** Primary actions belong in the bottom half of the screen where the thumb actually lives. Avoid forcing reach to the top corners for frequent actions — that's what `FloatingBackButton` / floating CTAs are for.
- **Respect platform conventions.** iOS swipe-back gestures, Android hardware back, sheet/modal idioms. Don't reinvent navigation.

### Primitives

- **Layout & containers:** `View`, `ScrollView`, `FlatList`. Never reach for HTML elements; they don't exist.
- **Long lists:** Always `FlatList` (or `SectionList`) with a stable `keyExtractor`. Plain `ScrollView` is for short, bounded content only.
- **Text:** Import from `@components/text` — it applies the project's default font stack. Direct `react-native` `Text` is monkey-patched in [textDefaults.ts](apps/mobile/src/lib/textDefaults.ts) but the wrapper is preferred for consistency.
- **Buttons / tappables:** `Pressable`. Always set `hitSlop` and an `active:*` class.
- **Icons:** `phosphor-react-native`. Pass color via `useThemeColors()` (e.g. `color={themeColors.gray[12]}`), never a hex literal.
- **Animations:** `react-native-reanimated` v4. Do not use the legacy `Animated` API.
- **Haptics:** `expo-haptics` for confirmation / destructive actions. Pair with visual feedback — haptics alone are not a signal.

### Styling: NativeWind + Theme Tokens

Mobile uses NativeWind v3 with the token system defined in [theme.ts](apps/mobile/src/lib/theme.ts) and exposed via [tailwind.config.js](apps/mobile/tailwind.config.js).

- **Use named token classes**, not hex: `bg-gray-1`, `bg-gray-2`, `text-gray-12`, `border-gray-6`, `bg-accent-9`, `text-accent-11`, `bg-background`, `bg-card`, `text-status-error`. These automatically switch between light and dark.
- **Arbitrary values** (`text-[15px]`, `pl-[18px]`) are fine when the design token doesn't match. Pair body text with `leading-snug`, titles with `leading-tight`.
- **For native props that take a color directly** — `ActivityIndicator`, `RefreshControl`, `StatusBar`, gradient stops, icon `color={...}` — call `useThemeColors()` and pass the hex. Don't hardcode.
- **For transparent variants** (gradients, overlays), use `toRgba(themeColors.background, 0.92)` rather than guessing rgba values.

Inline `style={{}}` on mobile is acceptable ONLY for:

1. **Runtime-computed values:** `style={{ paddingTop: insets.top + 8 }}`, `style={{ height: fadeHeight }}`, `transform: [{ translateY }]` driven by Reanimated/measurement.
2. **Library configuration objects** that aren't React props (e.g. `LinearGradient`'s absolute fill, gesture handler configs).
3. **Theme tokens consumed by native components** that don't accept className (passed to `contentStyle`, `headerStyle`, etc.).

Do NOT use inline `style` for static color, spacing, layout, border, radius, opacity, position, or z-index — those are all NativeWind classes. If a conditional looks like `style={{ color: isActive ? a : b }}`, rewrite as ``className={`base ${isActive ? "text-accent-9" : "text-gray-10"}`}``.

When writing custom components, accept `className?: string` and merge it into the inner element so call sites can override styling without inline `style`.

### Navigation & Screen Patterns

- **expo-router**, file-based. Routes live in [src/app/](apps/mobile/src/app/). `(group)/` is a layout group, `[id].tsx` is a dynamic param.
- **Modals:** Configure on the Stack screen with `presentation: "modal"` — see [_layout.tsx](apps/mobile/src/app/_layout.tsx). Don't roll a custom modal component when a stack modal will do.
- **Headers:** Prefer the existing floating header pattern ([FloatingBackButton](apps/mobile/src/components/FloatingBackButton.tsx), [FloatingTaskHeader](apps/mobile/src/features/tasks/components/FloatingTaskHeader.tsx)) over the native stack header. It lets content fill the full screen (incl. behind the status bar) and looks correct in both light/dark.
- **Don't go back blindly.** Always guard with `if (router.canGoBack()) router.back()`.

### Storage & Side Effects

- **Persistent key/value:** `@react-native-async-storage/async-storage` — NOT `localStorage` (doesn't exist on RN).
- **Secrets / tokens:** `expo-secure-store`.
- **Logger:** Use `@/lib/logger`. Never `console.*` in source.
- **Path alias:** `@/*` → `apps/mobile/src/*`. Don't use deep relative imports.

### Platform Differences

- Split iOS/Android behavior with `Platform.OS === "ios"`. Don't ship iOS-only APIs (`expo-glass-effect`, certain haptics, modal `presentation: "formSheet"`) without an Android fallback.
- iOS swipe-back is on by default — don't disable it without a strong reason. On Android, ensure hardware back behaves the same.

### Verifying Mobile UI Work

You cannot fully validate mobile UI from a typecheck. Before claiming a mobile UI task is done:

1. Mentally (or actually) walk the layout through: small iPhone (e.g. iPhone SE), large iPhone (Pro Max), with and without dynamic type bumped.
2. Check both light and dark mode — switch the simulator's appearance and verify token-based colors still read.
3. With the keyboard up — does the focused input stay visible? Does the back/submit button still tap?
4. Safe areas — does anything sit under the notch or home indicator?
5. If you can't actually run it, say so explicitly rather than reporting success.

## Testing

### Commands
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ yarn-error.*
*.tsbuildinfo

# generated native folders
/ios
/ios/*
/android
Loading
Loading