litter is a native iOS + Android client for Codex.
apps/ios: iOS app (LitterRemoteandLitterschemes)apps/android: Android appapp: Compose UI shell, app state, server manager, SSH/auth flowscore/bridge: native bridge bootstrapping and core RPC clientcore/network: discovery services (Bonjour/Tailscale/LAN probing)docs/qa-matrix.md: Android parity QA matrix
shared/rust-bridge/codex-bridge: shared Rust bridge crateshared/third_party/codex: upstream Codex submodulepatches/codex: local Codex patch settools/scripts: cross-platform helper scripts
iOS supports:
LitterRemote: remote-only mode (default scheme; no bundled on-device Rust server)Litter: includes the on-device Rust bridge (codex_bridge.xcframework)
- Xcode.app (full install, not only CLT)
- Rust + iOS targets:
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
xcodegen(for regeneratingLitter.xcodeproj):brew install xcodegen
This repo now vendors upstream Codex as a submodule:
shared/third_party/codex->https://github.com/openai/codex
On-device iOS exec hook changes are kept as a local patch:
patches/codex/ios-exec-hook.patch
Sync/apply patch (idempotent):
./apps/ios/scripts/sync-codex.sh./apps/ios/scripts/build-rust.shThis script:
- Syncs
shared/third_party/codexand applies the iOS hook patch - Builds
shared/rust-bridge/codex-bridgefor device + simulator targets - Repackages
apps/ios/Frameworks/codex_bridge.xcframework
Regenerate project if apps/ios/project.yml changed:
xcodegen generate --spec apps/ios/project.yml --project apps/ios/Litter.xcodeprojOpen in Xcode:
open apps/ios/Litter.xcodeprojSchemes:
LitterRemote(default): no on-device Rust bridgeLitter: uses bundledcodex_bridge.xcframework
CLI build example:
xcodebuild -project apps/ios/Litter.xcodeproj -scheme LitterRemote -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 17 Pro' buildPrerequisites:
- Java 17
- Android SDK + build tools for API 35
- Gradle 8.x (or wrapper, once added)
Build Android flavors:
gradle -p apps/android :app:assembleOnDeviceDebug :app:assembleRemoteOnlyDebugRun Android unit tests:
gradle -p apps/android :app:testOnDeviceDebugUnitTest :app:testRemoteOnlyDebugUnitTestStart emulator and install on-device debug build:
ANDROID_SDK_ROOT=/opt/homebrew/share/android-commandlinetools \
$ANDROID_SDK_ROOT/emulator/emulator -avd litterApi35
adb -e install -r apps/android/app/build/outputs/apk/onDevice/debug/app-onDevice-debug.apk
adb -e shell am start -n com.sigkitten.litter.android/com.litter.android.MainActivityBuild Android Rust JNI libs (optional bridge runtime step):
./tools/scripts/build-android-rust.shapps/ios/project.yml: source of truth for Xcode project/schemesshared/rust-bridge/codex-bridge/: Rust staticlib wrapper exposingcodex_start_server/codex_stop_servershared/third_party/codex/: upstream Codex source (submodule)patches/codex/ios-exec-hook.patch: iOS-specific hook patch applied to submoduleapps/ios/Sources/Litter/Bridge/: Swift bridge + JSON-RPC clientapps/android/app/src/main/java/com/litter/android/ui/: Android Compose UI shell and screensapps/android/app/src/main/java/com/litter/android/state/: Android state, transports, session/server orchestrationapps/android/core/bridge/: Android bridge bootstrap and core websocket clientapps/android/core/network/: discovery servicesapps/android/app/src/test/java/: Android unit tests (runtime mode + transport policy scaffolding)apps/android/docs/qa-matrix.md: Android parity checklisttools/scripts/build-android-rust.sh: builds Android JNI Rust artifacts intojniLibsapps/ios/Sources/Litter/Resources/brand_logo.svg: source logo (SVG)apps/ios/Sources/Litter/Resources/brand_logo.png: in-app logo image used byBrandLogoapps/ios/Sources/Litter/Assets.xcassets/AppIcon.appiconset/: generated app icon set
- Home/launch branding uses
BrandLogo(apps/ios/Sources/Litter/Views/BrandLogo.swift) backed bybrand_logo.png. - The app icon is generated from the same logo and stored in
AppIcon.appiconset. - If logo art changes, regenerate icon sizes from
Icon-1024.png(or re-run your ImageMagick resize pipeline) before building.
