Files
opencode-mobile/distribution/fdroid-submission/SUBMISSION-CHECKLIST.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

154 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# F-Droid Mainline Submission Checklist
This checklist covers the steps to file a Merge Request against
https://gitlab.com/fdroid/fdroiddata to add `ai.opencode.mobile` to the
F-Droid main repository.
**Do NOT start this process until ALL prerequisites are checked.**
---
## Prerequisites (must all be true before filing)
- [ ] First Google Play release is live (proves signing key is in production use)
- [ ] Signed APK (not AAB) is attached to a GitHub release tag (e.g. `v0.2.4`)
- [ ] Sentry opt-in gate is merged to `main` (avoids `Tracking` anti-feature)
- [ ] `expo-notifications` FCM-free flavor exists OR F-Droid team has been pre-warned
(see `SIZE-OPTIMIZATION.md` section "FCM Flavor")
- [ ] Signing key SHA-256 fingerprint is confirmed in `distribution/SIGNING-KEY-FINGERPRINTS.md`
- [ ] Reproducible build has been tested locally (see `REPRODUCIBLE-BUILD-NOTES.md`)
---
## Step 1 — Prepare the signing key fingerprint
```bash
# Get the colon-separated fingerprint
keytool -list -v \
-keystore keystores/production-release.jks \
-storepass <STOREPASS> \
| grep "SHA256:"
# Example output:
# SHA256: 0C:25:9D:94:E0:FF:EA:5D:63:19:61:4B:22:9D:4B:6B:DC:22:DE:1F:56:E3:8E:76:94:83:98:D2:DF:6A:A0:99
# Convert to lowercase without colons (AllowedAPKSigningKeys format):
# 0c259d94e0ffea5d6319614b229d4b6bdc22de1f56e38e769483 98d2df6aa099
```
Update `distribution/fdroid-submission/metadata.yml`:
- Replace `<SIGNING_KEY_SHA256_FINGERPRINT_LOWERCASE_NO_COLONS>` with the fingerprint
- Replace `<FIRST_GITHUB_RELEASE_TAG>` with the actual tag (e.g. `v0.2.4`)
---
## Step 2 — Fork fdroiddata
```bash
# On GitLab
# 1. Go to https://gitlab.com/fdroid/fdroiddata
# 2. Fork to your personal GitLab account (not org — fdroid prefers personal forks)
# 3. Clone locally:
git clone https://gitlab.com/<YOUR_GITLAB_USERNAME>/fdroiddata.git
cd fdroiddata
git remote add upstream https://gitlab.com/fdroid/fdroiddata.git
git fetch upstream
git checkout -b add-ai.opencode.mobile upstream/master
```
---
## Step 3 — Add the metadata file
```bash
cp /path/to/opencode-mobile/distribution/fdroid-submission/metadata.yml \
metadata/ai.opencode.mobile.yml
```
Verify:
- `metadata/ai.opencode.mobile.yml` exists
- `AllowedAPKSigningKeys` has the correct lowercase-no-colons fingerprint
- `commit:` points to a real tag in the GitHub repo
- `versionCode` and `versionName` match the APK attached to the release
---
## Step 4 — Test the build locally (optional but strongly recommended)
F-Droid provides a Docker-based build environment:
```bash
# Install fdroidserver
pip install fdroidserver
# Verify metadata parses cleanly
fdroid readmeta
# Attempt a build (requires Docker + significant time)
fdroid build ai.opencode.mobile:<versionCode>
```
If the build fails, fix `metadata/ai.opencode.mobile.yml` before filing the MR.
---
## Step 5 — File the Merge Request
```bash
git add metadata/ai.opencode.mobile.yml
git commit -m "Add ai.opencode.mobile (OpenCode Mobile)"
git push origin add-ai.opencode.mobile
```
Go to https://gitlab.com/<YOUR_GITLAB_USERNAME>/fdroiddata → open an MR
against `fdroid/fdroiddata:master`.
MR title: `Add ai.opencode.mobile`
MR description template:
```
## New app: OpenCode Mobile
**Package:** ai.opencode.mobile
**License:** MIT
**Category:** Development
**Source:** https://github.com/dzianisv/opencode-mobile
OpenCode Mobile is a free, open-source mobile client for the opencode AI
coding agent (sst/opencode). MIT licensed. Crash reporting opt-in default OFF.
Anti-features: NonFreeNet (user-self-hosted backend may connect to proprietary AI APIs).
Using AllowedAPKSigningKeys path — pre-signed APK from GitHub releases.
Build steps: npm install → expo prebuild → Gradle assembleRelease.
```
---
## Step 6 — Respond to reviewer feedback
- F-Droid maintainers typically review within 2–8 weeks.
- Monitor the MR for comments. Common asks:
- Build reproducibility evidence
- Clarification on anti-features
- Pinning build dependencies to exact versions
- Removing or stubbing FCM/GMS dependencies
---
## Step 7 — After acceptance
- F-Droid builds from source on their CI. First index update may take 1–2 weeks.
- Add `ai.opencode.mobile` to F-Droid's inclusion notice in `docs/fdroid.md`.
- Update `distribution/strategy.md` status row for F-Droid.
- Notify IzzyOnDroid via the inclusion issue that mainline accepted the app
(IzzyOnDroid will then auto-delist within their next index rebuild).
---
## Reference
- F-Droid inclusion criteria: https://f-droid.org/en/docs/Inclusion_Policy/
- F-Droid metadata format: https://f-droid.org/en/docs/Build_Metadata_Reference/
- AllowedAPKSigningKeys: https://f-droid.org/en/docs/Reproducible_Builds/
- fdroiddata: https://gitlab.com/fdroid/fdroiddata