* fix(security): fail closed on biometric init error H-03: setting isAuthenticated: true on initialization failure was a security bypass — any crash during biometric setup granted full access. Fail closed instead; user sees auth prompt on next open. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(security): use Crypto.randomUUID for connection IDs H-04: Math.random() is not cryptographically random. Connection IDs are used as SecureStore key suffixes; switch to expo-crypto randomUUID for a secure source. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(deps): pin expo-crypto to ~15.0.9 15.0.10 does not exist on npm; ~15.0.9 is the latest stable in the 15.x series compatible with Expo SDK 54. * feat: add OpenCode Connect coming-soon waitlist card Adds a discoverable 'OpenCode Connect — Coming Soon' card to the add-connection quick-connect screen. Users can enter their email and tap 'Join Waitlist' to send a pre-filled mailto. No backend required. * fix(cua): detect actual screen dimensions and fix JSON parsing - Get real screen size via `wm size` instead of hardcoding 1080x2400; emulator is 1080x1920 so y-coordinates were systematically off - Extract first JSON object via regex when model returns multiple objects - Use AZURE_OPENAI_MODEL env var for deployment name (defaults gpt-5.4) - Add AZURE_DEV_AI_* path for Azure AI Foundry endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(security): SHA-pin upload-google-play and sanitize notification bodies M-02: Pin r0adkll/upload-google-play to commit SHA e738b9d (v1.1.5) to prevent supply-chain hijack via tag mutation. M-03: Sanitize all push notification bodies — strip control chars, truncate to 200 chars. Prevents server-supplied strings (error messages, file paths from permission patterns, session titles) from leaking unbounded text into the OS notification drawer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(privacy): add telemetry consent gate for Sentry crash reporting Sentry was always-on, violating F-Droid anti-feature policy and user trust norms. Now gated behind explicit opt-in: - First-launch consent modal (TelemetryConsentModal) shows once on fresh install; user can Allow or Decline. - Consent state persisted in expo-secure-store (survives restarts). - Settings > Privacy section: crash reporting toggle + privacy policy link. - initSentry() called only after consent granted — not on app start. Closes #3 (partial) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(config): add real icons and complete iOS/Android app.json config - Add 1024×1024 app icon, 432×432 adaptive icon foreground, 200×200 splash - iOS: push notification entitlement (aps-environment: production), speech/ microphone/camera/photo usage descriptions for future features, disable ITSAppUsesNonExemptEncryption - Android: adaptive icon with dark background (#0F172A), versionCode: 1 - expo-notifications plugin wired in app.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(dist): add iOS CI workflow, README rewrite, CONTRIBUTING, and LICENSE - publish-app-store.yml: EAS Build + TestFlight submission; runs on tag/release/ workflow_dispatch; bumps ios.buildNumber from github.run_number - README: full rewrite — features, install badges, connection guide, contributing - CONTRIBUTING.md: contribution guide for OSS contributors - LICENSE: MIT Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(dist): add store listings, strategy, privacy policy, F-Droid/IzzyOnDroid templates - distribution/strategy.md: monetization strategy (free client + opencode Cloud) - distribution/play-listing.md: Google Play store copy (name, description, tags) - distribution/app-store-listing.md: App Store listing copy - distribution/privacy-policy.{md,html}: GDPR-compliant privacy policy - distribution/PLAY_CONSOLE_SETUP.md: Play Console setup runbook - distribution/ios-enrollment-runbook.md: Apple Developer Program enrollment steps - distribution/SIGNING-KEY-FINGERPRINTS.md: keystore fingerprint for reproducible builds - distribution/fdroid-submission/: F-Droid metadata template - distribution/izzyondroid-submission/: IzzyOnDroid submission template - distribution/whatsnew/: Play Store release notes (en-US) - distribution/whatsnew-ios/: TestFlight release notes - distribution/play-graphics/: Play Store screenshot placeholders - distribution/app-store-graphics/: App Store screenshot placeholders Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(telemetry): handle SecureStore failure + Android back button - add .catch() on loadTelemetryConsent() so SecureStore rejection shows the consent modal instead of blocking startup forever - add onRequestClose={onDecline} to Modal so Android back button records the decline rather than silently dismissing - fix catch block in telemetry.ts to not clobber _resolved when SecureStore read fails mid-session Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): run gradlew clean to prevent stale modules.json duplicate Sentry Gradle plugin writes modules.json to src/main/assets; cached build intermediates contain an old copy → mergeReleaseAssets fails with 'Duplicate resources'. Running clean before assembleRelease clears the intermediate state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): remove android build output cache causing duplicate modules.json Caching android/app/build/intermediates and android/app/.cxx causes two issues: 1. Stale modules.json in intermediates → Duplicate resources error 2. .cxx CMake artifacts reference absolute paths → ninja clean fails Keeping only Gradle distribution cache (~/.gradle) which is safe. Expo prebuild regenerates android sources fresh each run anyway. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
184 lines
8.0 KiB
Markdown
184 lines
8.0 KiB
Markdown
# OpenCode Mobile
|
|
|
|
**The open-source mobile client for the [opencode](https://github.com/sst/opencode) AI coding agent.**
|
|
AI-assisted coding from your phone — iOS, Android, and F-Droid.
|
|
|
|
[](LICENSE)
|
|
[](https://play.google.com/store/apps/details?id=ai.opencode.mobile)
|
|
[](https://apps.apple.com/app/opencode-mobile/id0000000000)
|
|
[](https://f-droid.org/packages/ai.opencode.mobile)
|
|
[](https://apt.izzysoft.de/fdroid/index/apk/ai.opencode.mobile)
|
|
|
|
---
|
|
|
|
OpenCode Mobile is a React Native / Expo app that brings the power of the [opencode](https://github.com/sst/opencode) AI coding agent to your phone. Connect to your own self-hosted opencode server over your local network, a Cloudflare Tunnel, ngrok, Tailscale, or the upcoming opencode Cloud — and write, review, and ship code from anywhere. The mobile client is **free and open-source** under the MIT license. There is no feature gate, no telemetry you did not opt into, and no ad network.
|
|
|
|
---
|
|
|
|
<p align="center">
|
|
<img src="distribution/play-graphics/phone-01.png" width="220" alt="Session list screen" />
|
|
<img src="distribution/play-graphics/phone-02.png" width="220" alt="Chat screen with diff viewer" />
|
|
<img src="distribution/play-graphics/phone-03.png" width="220" alt="Connection setup wizard" />
|
|
</p>
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- **Multi-connection** — manage multiple opencode servers (local network, Cloudflare Tunnel, ngrok, Tailscale, or opencode Cloud)
|
|
- **Biometric unlock** — Face ID, Touch ID, or Android fingerprint protects the app and individual message sends
|
|
- **Streaming chat** — token-by-token streaming responses directly from your opencode server
|
|
- **Diff viewer** — inline side-by-side diffs of every file change the agent makes
|
|
- **Tool call approval** — review and approve (or reject) tool calls before the agent executes them
|
|
- **Secure credential storage** — server credentials stored in iOS Keychain / Android Keystore via `expo-secure-store`
|
|
- **Session management** — browse, create, and resume coding sessions
|
|
|
|
---
|
|
|
|
## Get OpenCode Mobile
|
|
|
|
| Platform | Link |
|
|
|---|---|
|
|
| Google Play | [play.google.com — ai.opencode.mobile](https://play.google.com/store/apps/details?id=ai.opencode.mobile) |
|
|
| Apple App Store | [apps.apple.com — OpenCode Mobile](https://apps.apple.com/app/opencode-mobile/id0000000000) |
|
|
| F-Droid | [f-droid.org/packages/ai.opencode.mobile](https://f-droid.org/packages/ai.opencode.mobile) |
|
|
| IzzyOnDroid | [apt.izzysoft.de — ai.opencode.mobile](https://apt.izzysoft.de/fdroid/index/apk/ai.opencode.mobile) |
|
|
|
|
> **Note**: App Store and F-Droid listings are pending final review. Play Store internal testing is live.
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
**Step 1 — Start opencode on your machine**
|
|
|
|
```bash
|
|
# Install opencode (if you haven't already)
|
|
npm install -g opencode
|
|
|
|
# Run opencode in server mode
|
|
OPENCODE_SERVER_PASSWORD=yourpassword opencode serve --hostname 0.0.0.0 --port 4096
|
|
```
|
|
|
|
**Step 2 — Install OpenCode Mobile** from any store above (or build from source — see [CONTRIBUTING.md](CONTRIBUTING.md)).
|
|
|
|
**Step 3 — Add a connection in the app**
|
|
|
|
Open the app, tap **Add Connection**, and choose your connection type:
|
|
|
|
- **Local network** — your machine's LAN IP, e.g. `http://192.168.1.100:4096`
|
|
- **Tunnel** — a Cloudflare Tunnel or ngrok URL, e.g. `https://my-opencode.trycloudflare.com`
|
|
- **Tailscale** — your machine's Tailscale IP, e.g. `http://100.x.x.x:4096`
|
|
- **opencode Cloud** *(coming soon)* — one-tap managed hosting, no server to run
|
|
|
|
Enter the password you set in Step 1, tap **Connect**, and you're in.
|
|
|
|
---
|
|
|
|
## How It Works
|
|
|
|
OpenCode Mobile is a thin client. It speaks the opencode HTTP + SSE API: listing sessions, sending messages, streaming responses, and subscribing to file-change events. All AI model calls are handled by your opencode server — you bring your own API keys (OpenAI, Anthropic, etc.) and the app never touches them. The app never proxies your code or conversation through our servers.
|
|
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ OpenCode Mobile │
|
|
│ (React Native / Expo, this repo) │
|
|
└──────────────┬──────────────────────┘
|
|
│ HTTP + SSE
|
|
│ (local network / tunnel / cloud)
|
|
▼
|
|
┌─────────────────────────────────────┐
|
|
│ opencode server │
|
|
│ (github.com/sst/opencode, MIT) │
|
|
│ Running on your laptop / VPS │
|
|
└──────────────┬──────────────────────┘
|
|
│ API calls
|
|
▼
|
|
┌─────────────────────────────────────┐
|
|
│ Your AI provider │
|
|
│ (OpenAI / Anthropic / Gemini / …) │
|
|
│ Your keys, your bill │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Project Status
|
|
|
|
**Current version: v0.2.3**
|
|
|
|
| Feature | Status |
|
|
|---|---|
|
|
| Multi-connection management | Stable |
|
|
| Session list + creation | Stable |
|
|
| Streaming chat | Stable |
|
|
| Diff viewer | Stable |
|
|
| Biometric unlock | Stable |
|
|
| Tool call approval UI | Stable |
|
|
| Sentry crash reporting (opt-in) | Stable |
|
|
| Cloudflare / ngrok tunnel wizard | Beta |
|
|
| opencode Cloud one-tap connect | Planned |
|
|
| iPad / tablet layout | Planned |
|
|
| Offline session history | Planned |
|
|
|
|
---
|
|
|
|
## Supporters and Sponsors
|
|
|
|
OpenCode Mobile is built and maintained by [VIBE TECHNOLOGIES, LLC](https://opencode.vibebrowser.app). GitHub Sponsors help cover Sentry, EAS Build, and CI costs (~$60/month). The opencode Cloud hosted backend (planned, $10/mo) is the long-term revenue model.
|
|
|
|
If OpenCode Mobile saves you time, consider sponsoring:
|
|
|
|
**[github.com/sponsors/VibeTechnologies](https://github.com/sponsors/VibeTechnologies)**
|
|
|
|
| Tier | Price | Perk |
|
|
|---|---|---|
|
|
| Supporter | $5/mo | Your name in `SUPPORTERS.md` |
|
|
| Backer | $15/mo | Name + early access to opencode Cloud beta |
|
|
| Business | $50/mo | Logo on [opencode.vibebrowser.app](https://opencode.vibebrowser.app) + quarterly support call |
|
|
|
|
Questions or private support: [support@vibebrowser.app](mailto:support@vibebrowser.app)
|
|
|
|
---
|
|
|
|
## Roadmap
|
|
|
|
Tracked on the [GitHub Projects board](https://github.com/dzianisv/opencode-mobile/projects) and in the [open milestones](https://github.com/dzianisv/opencode-mobile/milestones).
|
|
|
|
Near-term priorities:
|
|
- opencode Cloud one-tap connect + managed hosting
|
|
- F-Droid mainline acceptance (FCM audit + reproducible build verification)
|
|
- Tunnel setup wizard (Cloudflare / ngrok / Tailscale)
|
|
- iPad / tablet layout
|
|
- Offline session history cache
|
|
|
|
---
|
|
|
|
## Contributing
|
|
|
|
We welcome bug reports, feature requests, and pull requests. See [CONTRIBUTING.md](CONTRIBUTING.md) for how to set up a dev environment and the contribution process.
|
|
|
|
---
|
|
|
|
## Privacy
|
|
|
|
OpenCode Mobile does not collect personal data. Optional Sentry crash reporting (opt-in, off by default) sends anonymised crash traces to Sentry. No analytics SDKs are bundled. Credentials are stored exclusively on-device in the OS keystore.
|
|
|
|
Full privacy policy: [opencode.vibebrowser.app/privacy](https://opencode.vibebrowser.app/privacy)
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT — see [LICENSE](LICENSE).
|
|
|
|
Copyright (c) 2026 VIBE TECHNOLOGIES, LLC
|
|
|
|
---
|
|
|
|
## Acknowledgments
|
|
|
|
- [sst/opencode](https://github.com/sst/opencode) — the AI coding agent this app connects to (MIT)
|
|
- [Expo](https://expo.dev) — the React Native toolchain powering the app
|
|
- Every contributor who filed a bug, opened a PR, or starred the repo
|