-
Xcode.app (full install, not only Command Line Tools):
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
-
Rust via rustup with iOS targets. If Homebrew's
rustformula is installed, itscargo/rustcwill shadow rustup and break cross-compilation. Eitherbrew uninstall rustor ensure~/.cargo/binappears before/opt/homebrew/binin yourPATH.curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
-
meson + ninja (required by
webrtc-audio-processing-sys):brew install meson
-
xcodegen (for regenerating
Litter.xcodeproj):brew install xcodegen
Use this flow to make Codex sessions from your Mac visible in the iOS/Android app.
-
Enable SSH on the Mac.
- UI:
System Settings->General->Sharing-> enableRemote Login. - CLI:
sudo systemsetup -setremotelogin on
- If you get a Full Disk Access error, grant it to your terminal app in
System Settings->Privacy & Security->Full Disk Access, then restart terminal and retry.
- UI:
-
Verify SSH and Codex binaries from a non-interactive SSH shell.
ssh <mac-user>@<mac-host-or-ip> 'echo ok' ssh <mac-user>@<mac-host-or-ip> 'command -v codex || command -v codex-app-server'
If the second command prints nothing, install Codex and/or fix shell PATH startup files.
-
Connect from the Litter app.
- Keep phone and Mac on the same LAN (or same Tailnet).
- In Discovery: tap a host showing
codex runningto connect directly, or tap anSSHhost and enter credentials.
-
Fallback: run app-server manually bound to loopback and forward the port over SSH.
On the Mac:
codex app-server --listen ws://127.0.0.1:8390
Then connect the phone via the
SSHflow in Discovery — Litter opens the SSH connection, port-forwards127.0.0.1:8390, and connects through the tunnel. Do not bind0.0.0.0unless you fully understand the exposure; the SSH flow is the supported path. -
Thread/session listing is
cwd-scoped. If expected sessions are missing, choose the same working directory used when those sessions were created.
Upstream Codex is vendored as a submodule at shared/third_party/codex.
Current local patch set (applied by sync-codex.sh):
patches/codex/ios-exec-hook.patchpatches/codex/client-controlled-handoff.patchpatches/codex/mobile-code-mode-stub.patch
Additional patches (not auto-applied):
patches/codex/android-vendored-openssl.patchpatches/codex/realtime-transcript-deltas.patch
Sync/apply (idempotent):
./apps/ios/scripts/sync-codex.shPass --recorded-gitlink to reset the submodule to the commit recorded in the superproject.
./apps/ios/scripts/build-rust.sh # package mode (device + sim + xcframework)
./apps/ios/scripts/build-rust.sh --fast-device # raw device staticlib onlyRegenerate project if apps/ios/project.yml changed:
make xcgenOpen in Xcode:
open apps/ios/Litter.xcodeprojCLI build:
xcodebuild -project apps/ios/Litter.xcodeproj -scheme Litter -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 17 Pro' buildPrerequisites: Java 17, Android SDK + build tools for API 35, Gradle 8.x.
open -a "Android Studio" apps/android # open in Android Studio
cd apps/android && ./gradlew :app:testDebugUnitTest # run tests
gradle -p apps/android :app:assembleOnDeviceDebug :app:assembleRemoteOnlyDebug # build flavors-
Authenticate with App Store Connect:
asc auth login \ --name "Litter ASC" \ --key-id "<KEY_ID>" \ --issuer-id "<ISSUER_ID>" \ --private-key "$HOME/AppStore.p8" \ --network
-
Bootstrap TestFlight defaults:
APP_BUNDLE_ID=<BUNDLE_ID> ./apps/ios/scripts/testflight-setup.sh
-
Build and upload:
APP_BUNDLE_ID=<BUNDLE_ID> \ APP_STORE_APP_ID=<APP_STORE_CONNECT_APP_ID> \ TEAM_ID=<APPLE_TEAM_ID> \ ASC_KEY_ID=<KEY_ID> \ ASC_ISSUER_ID=<ISSUER_ID> \ ASC_PRIVATE_KEY_PATH="$HOME/AppStore.p8" \ ./apps/ios/scripts/testflight-upload.sh
- Reads
MARKETING_VERSIONfromapps/ios/project.yml; auto-bumps patch if the version is already live. - Auto-increments build number from the latest App Store Connect build.
- Reads
APP_BUNDLE_ID=<BUNDLE_ID> \
APP_STORE_APP_ID=<APP_STORE_CONNECT_APP_ID> \
TEAM_ID=<APPLE_TEAM_ID> \
ASC_KEY_ID=<KEY_ID> \
ASC_ISSUER_ID=<ISSUER_ID> \
ASC_PRIVATE_KEY_PATH="$HOME/AppStore.p8" \
./apps/ios/scripts/app-store-release.shMetadata is sourced from apps/ios/fastlane/metadata/en-US/.