Files
opencode-mobile/distribution/app-store-listing.md
Den 2b9b571d6e feat(privacy+dist): telemetry consent gate + app store distribution prep (#4)
* 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>
2026-05-25 17:42:03 -07:00

14 KiB
Raw Blame History

App Store Listing — OpenCode (iOS)

Copy-paste reference for App Store Connect. Use this once the Apple Developer Program enrollment is approved and the app is created in App Store Connect.


App Information

App Name (max 30 chars)

OpenCode

(8 chars)

Subtitle (max 30 chars)

AI Coding Agent, In Your Pocket

(31 chars — trim to:)

AI Coding Agent in Your Pocket

(30 chars exactly)

Promotional Text (max 170 chars — appears above description, can be updated without a new review)

Drive your self-hosted AI coding agent from anywhere. Connect to opencode on your workstation and review, approve, and guide AI-generated code changes in real time.

(165 chars)

Description (max 4000 chars)

OpenCode is an open-source mobile client for the opencode AI coding agent (github.com/sst/opencode). Connect to your self-hosted opencode server and drive AI-powered coding sessions directly from your iPhone or iPad.

KEY FEATURES

• Multiple connection types — local network (Wi-Fi), secure tunnels (Cloudflare Tunnel, ngrok), or cloud-hosted opencode instances
• Biometric unlock — Face ID / Touch ID to keep your sessions private
• Real-time streaming chat — watch your AI agent think and respond live as it works through your code
• File diff viewer — see exactly what code changes the agent proposes before you accept them
• Multi-session management — start, resume, and switch between coding sessions
• Tool call approval — review and approve file writes, shell commands, and other actions before the agent executes them on your code

WHO IT'S FOR

• Developers who run opencode on their workstation or a server and want to check in from their phone
• Engineers away from their desk who want to guide long-running AI coding sessions
• Teams who self-host AI dev tools and want a polished mobile companion

WHAT IT IS NOT

• Not an AI model — you bring your own opencode server (which connects to Claude, GPT-4, Gemini, or local models via your API keys)
• Not a code editor — pairs with your existing IDE and terminal workflow
• Not a subscription service — the app is free and open source

OPEN SOURCE

OpenCode Mobile is MIT licensed. Source code, issue tracker, and community discussion:
https://github.com/dzianisv/opencode-mobile

PRIVACY

OpenCode Mobile does not collect your code, prompts, or AI responses. All AI traffic goes directly from the app to YOUR opencode server — never through our infrastructure. We use Sentry for crash reporting only (no personally identifiable information, no message content). See our privacy policy for full details.

SELF-HOSTED FIRST

OpenCode requires you to run an opencode server:
1. Install: npm install -g opencode-ai
2. Run: opencode serve
3. Connect the app to the server URL

If you cannot self-host, contact support@vibebrowser.app and we will provide a temporary review endpoint.

SUPPORT

Email: support@vibebrowser.app
Issues: https://github.com/dzianisv/opencode-mobile/issues

(Character count: ~1,750 — well under 4,000 limit. Add more feature detail or FAQ if desired.)


Keywords (max 100 chars, comma-separated)

opencode,AI coding,developer,LLM,Claude,GPT,coding agent,self-hosted,mobile dev,terminal

(89 chars)

Alternative / supplemental terms to rotate in A/B: code review, AI assistant, remote dev, SSH, copilot


URLs

Field Value
Support URL https://www.vibebrowser.app/
Marketing URL https://github.com/dzianisv/opencode-mobile
Privacy Policy URL https://opencode.vibebrowser.app/privacy

App Category

Field Value
Primary Category Developer Tools
Secondary Category Productivity

Pricing & Availability

Field Value
Price Free
In-App Purchases None
Availability All territories (no regional restrictions)

Age Rating Questionnaire

Apple uses a questionnaire to assign an age rating. Answer as follows for OpenCode Mobile:

Question Answer Notes
Cartoon or fantasy violence None Dev tool — no violence content
Realistic violence None
Prolonged graphic violence None
Sexual content or nudity None
Profanity or crude humor None
Mature or suggestive themes None
Horror/fear-inducing content None
Medical/treatment information None
Alcohol, tobacco, drugs None
Gambling None
Contests None
Unrestricted web access No App connects to user-specified servers only, no general browser
Sharing location data No
User-generated content No Chat is between user and their own AI backend, not user-to-user

Expected rating: 4+ (no objectionable content; developer tool)


Privacy Nutrition Label (App Privacy)

Apple requires you to declare what data the app collects. Fill the App Privacy section in App Store Connect as follows.

Data Not Collected

OpenCode Mobile does NOT collect any of the following:

  • Name, Email address, Phone number, Physical address, Other contact info
  • Health/fitness data
  • Financial info, payment info
  • Precise or coarse location
  • Contacts
  • Emails or text messages
  • Photos or videos
  • Audio data
  • Gameplay content
  • Customer support data
  • Browsing history, search history
  • Sensitive info
  • User content (code, prompts, AI responses are not sent to our servers)
  • Identifiers (User ID, Device ID — Sentry uses an installation-scoped anonymous ID, see below)

Data Linked to You: None

Data Not Linked to You

Data Type Category Purpose Optional?
Crash Data Diagnostics App functionality No — always on (see note)
Performance Data Diagnostics App functionality No — always on (see note)
Other Diagnostic Data Diagnostics App functionality No

Explanation: Sentry crash reporting sends device model, OS version, app version, and stack traces. Sentry assigns an anonymous installation ID (not linked to any Apple ID or personal information). No user-generated content (code, prompts, responses) is ever sent.

Sentry opt-in status: As of v0.2.3, Sentry is always on when a DSN is configured. If you add a settings toggle for Sentry consent (planned), change Optional? to "Yes" and add a note that users who decline are in the "Data Not Collected" category. In App Store Connect, once opt-in is implemented, this section can be removed or marked optional.

"Are you or your third-party partners using this data to track users?": No

App Tracking Transparency (ATT): OpenCode Mobile does not use the ATT framework (AppTrackingTransparency) and does not access the IDFA (Identifier for Advertisers). No ad networks or cross-app tracking SDKs are present. No ATT permission prompt is shown to users.


Export Compliance

Apple asks about encryption during submission. Answer:

Question Answer
Does the app use encryption beyond what is in the operating system? No
Does the app qualify for any exemptions? N/A

Rationale: OpenCode Mobile uses only standard HTTPS/TLS provided by iOS networking APIs (URLSession via React Native's fetch). It does not implement any custom cryptographic algorithms. Per US Export Administration Regulations (EAR), apps using only standard OS-provided encryption and that do not modify the encryption are exempt from ERN requirements. Source: https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations

Action: In App Store Connect > App Information > Export Compliance, select "No" when asked if the app uses non-exempt encryption.


App Review Notes — ATS Justification

The app's Info.plist sets NSAllowsArbitraryLoads: true in NSAppTransportSecurity. Apple App Store review may ask for justification. Paste the following in the App Review Notes field in App Store Connect, or in the reviewer communication:


Justification for NSAllowsArbitraryLoads:

OpenCode is a developer tool that connects to user-self-hosted opencode CLI servers. These servers typically run on localhost or a LAN address (e.g. http://192.168.1.100:4096) over plain HTTP. Requiring TLS would prevent the app from functioning as designed for the dev-tool use case, because:

  1. The opencode server (opencode serve) serves over plain HTTP by default. Requiring the user to configure TLS certificates for a localhost developer tool is an unreasonable burden.
  2. The connection targets are the user's own machines, not third-party services. There is no user-to-user data exchange and no third-party server communication through this code path.
  3. NSAllowsArbitraryLoadsInWebContent is explicitly set to false — we only relax ATS for the app's own network calls to the user-configured backend.

This is exactly the use case Apple's own documentation acknowledges when describing developer tools and enterprise apps that connect to custom internal servers. Reference: https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity

We do not weaken security for any user-facing content delivered by third parties. If the reviewer requires additional justification or a demonstration, we are happy to provide a screen recording or a live server endpoint.


App Review Information

Sign-in Required

Field Value
Sign-in required? No — the app does not have user accounts

App Access Notes

Paste the following in the "Notes" field of the App Review Information section:

OpenCode Mobile requires the reviewer to connect to an opencode server.

OPTION A — We provide a hosted review endpoint:
Contact support@vibebrowser.app before the review window and we will email a temporary server URL valid for 72 hours.

OPTION B — Self-host (5 minutes):
1. Install Node.js 20+ on any macOS/Linux machine
2. Run: npm install -g opencode-ai
3. Run: opencode serve --hostname 0.0.0.0
4. The terminal prints a URL like: http://192.168.x.x:4096
5. In the app: tap "Add Connection" → enter that URL → tap "Connect"
6. Tap "New Session" → type any prompt (e.g. "list files in current directory")
7. Observe streaming response and tool call approval flow

Note: The --hostname 0.0.0.0 flag makes the server listen on all interfaces
so the iOS device (or simulator) on the same Wi-Fi network can reach it.
Without it, the server only accepts connections from localhost.

The app has no hidden features or paywalls. All functionality is accessible after connecting to a server.

Graphic Assets — Required Before Submission

All icons and screenshots must be provided before submitting for review.

App Icon

Asset Size Format Notes
App Icon 1024×1024 px PNG, no alpha channel Used for App Store; Xcode fans out all other sizes

The 1024×1024 icon must NOT have rounded corners (Apple applies them). No transparency.

Current status: assets/icon.json is a placeholder — real PNG required before submission.

iPhone Screenshots (REQUIRED)

Minimum 1 screenshot per device class. Recommended: 3–5 showing key flows.

Device Resolution Size name in App Store Connect
iPhone 6.7" (iPhone 16 Pro Max / 15 Plus) 1320×2868 or 1290×2796 6.7" Super Retina XDR Display
iPhone 6.5" (iPhone 14 Plus / 11 Pro Max) 1242×2688 6.5" Super Retina XDR Display
iPhone 5.5" (iPhone 8 Plus) 1242×2208 5.5" Retina HD Display

Note: As of 2024, Apple only requires 6.7" and 6.5" for new submissions. 5.5" is optional but recommended for coverage.

Suggested screenshot subjects:

  1. Connection setup screen (add server URL)
  2. Active chat session — streaming AI response
  3. File diff view — seeing a code change
  4. Tool approval dialog
  5. Session list / multi-session view
  6. Biometric unlock (if possible to screenshot without triggering auth)

iPad Screenshots (REQUIRED for Universal apps)

Since supportsTablet: true, iPad screenshots are required.

Device Resolution Size name in App Store Connect
iPad 12.9" (iPad Pro 6th gen) 2048×2732 12.9" iPad Pro (6th gen)
iPad 11" (iPad Pro M4) 1668×2388 11" iPad Pro (M4)

Minimum 1 per device class required. iPad screenshots can be the same content as iPhone.

Preview Videos (Optional)

  • Max 30 seconds
  • Same resolution as screenshots for each device class
  • MP4 or MOV
  • No audio required

TestFlight Beta App Description (shown to TestFlight testers)

OpenCode Mobile — iOS beta

Drive your self-hosted opencode AI coding agent from your iPhone or iPad. Connect to opencode running on your workstation (or any server) and guide AI coding sessions remotely.

This is an early beta. Please report issues via the TestFlight feedback button or email support@vibebrowser.app.

To use: you need opencode running somewhere accessible (local Wi-Fi, Tailscale, Cloudflare Tunnel, etc). Run `opencode serve` and enter the server URL in the app.

Pending Before First Submission

  • Apple Developer Program enrollment approved (D-U-N-S 142059652, VIBE TECHNOLOGIES LLC)
  • App Store Connect app record created (bundle ID: ai.opencode.mobile)
  • App icon 1024×1024 PNG (no alpha, no rounded corners)
  • iPhone screenshots (6.7" minimum; 6.5" strongly recommended)
  • iPad screenshots (12.9" minimum)
  • Privacy policy live at https://opencode.vibebrowser.app/privacy
  • App Store Connect API key created (for CI — Key ID, Issuer ID, .p8 file)
  • Apple Distribution certificate + provisioning profile (or use EAS managed signing)
  • Export compliance answered (No to custom encryption)
  • App privacy nutrition label filled
  • Age rating questionnaire completed (expected: 4+)
  • TestFlight internal group created
  • Review notes prepared with temporary server URL or self-host instructions