Replace stale opencode.vibebrowser.app / www.vibebrowser.app domain refs
with the current agentlabs.cc/opencode branding, and update the privacy
policy package id ai.opencode.mobile -> cc.agentlabs.opencode.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace all @vibebrowser.app email addresses with @agentlabs.cc across
22 files including privacy policy, Play/App Store listings, fastlane
metadata, docs, README, CONTRIBUTING, eas.json, and in-app mailto links.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Structured store listing copy for cc.agentlabs.opencode:
- Optimized title, short description, and full description
- Keyword strategy for AI coding agent / developer tools niche
- Screenshot captions for 5 key screens
- Notes for Play Console entry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No3k1AEioE4PNUZg12TxQo
MR #39530 remaining blocker was the missing top-level Binaries: field
(maintainer: AllowedAPKSigningKeys rejects the APK without it). Added
Binaries pointing at the GitHub release APK (v%v) and synced the stale
local distribution copy to the canonical fork recipe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Built from the on-device verification capture (360px, 92KB, looping). Added to README
hero (top repo conversion surface) + docs-site/ and distribution/ for landing + launch
attachment. Demo media is the #1 conversion lever for HN/Reddit/PH — none existed before.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixed claims a technical audience would catch:
- Android build is Gradle (assembleRelease/bundleRelease), NOT EAS — EAS is only in
the unshipped iOS workflow. Changed 'GitHub Actions + EAS' -> 'GitHub Actions (Gradle)'.
- App is Android-only: dropped 'iOS Keychain', kept 'Android Keystore'.
- Diff viewer renders into native views (ScrollView), not a FlatList.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Launch posts claimed Expo SDK 52 but app is on SDK 54 (factual accuracy
before public posting — HN/Reddit devs check this)
- docs/qa/REPLY-FLOW-E2E-2026-06-08.md: verified send->streaming reply works
against the live opencode server via app-identical sdk.ts calls (free model);
closes the 'opencode can't reply in CI' residual at the data-contract level
- owner-submissions.md: 0.4.3 -> 0.4.4
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Privacy URL was inconsistent across owner docs (agentlabs.cc/opencode/privacy
in 3 spots vs opencode.vibebrowser.app/privacy in the majority). Reconciled
all to the canonical opencode.vibebrowser.app/privacy (Search-Console-verified
domain; what privacy-policy.html self-references). Also fixed stale v0.4.2 AAB
reference in PLAY-APP-CONTENT-ANSWERS.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
App ID is cc.agentlabs.opencode (post-rename), not ai.opencode.mobile; bump the
example release to v0.4.2. Verified against the live v0.4.2 APK: package
cc.agentlabs.opencode, versionName 0.4.2, signing SHA-256 0C:25:..:99 matches the
documented fingerprint. Makes the IzzyOnDroid submission filing-ready.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* ci(play): add track/status inputs to publish workflow
Lets the Play publish run target a public track (production/beta) and
choose draft vs completed, instead of being hard-wired to internal.
Defaults stay internal/completed so tag-push and release triggers are
unchanged. Enables promoting the app to a publicly-downloadable track —
the prerequisite for any real download growth.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(play): record user authorization for production go-live
* docs(fdroid): correct metadata to cc.agentlabs.opencode + agentlabs.cc, flag post-rename tag gate
The fdroiddata submission still referenced the old package ai.opencode.mobile
and v0.3.1. Update package id, website, and document the real blocker: F-Droid
mainline needs a release tag built AFTER the package rename (v0.4.1 APK is the
old id) plus Play production live and a reproducible build. Signing fingerprint
is unchanged across the rename.
* docs(launch): ready-to-fire distribution kit (Show HN, Reddit, PH, X, dev.to)
Copy-paste launch posts + ordered fire checklist so distribution starts the
moment the public listing is live. Store URLs left as {{PLAY_URL}}/{{FDROID_URL}}
placeholders; web hub agentlabs.cc/opencode is live now.
---------
Co-authored-by: engineer <engineer@opencode.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* chore: repoint OpenCode links to agentlabs.cc/opencode
agentlabs.cc/opencode and /opencode/privacy are now live (200). Repoint
README, distribution listings (Play/App Store/F-Droid/IzzyOnDroid/iOS),
docs, and in-app privacy links (settings + telemetry consent) from
www.vibebrowser.app/opencode to the canonical agentlabs.cc hub.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(ci): run local opencode server for CUA smoke true-E2E (#15)
GitHub-hosted runners can't reach the Tailscale dev server
(100.108.64.76:4096), so the CUA smoke always failed at session creation.
- Install opencode-ai and run `opencode serve` on the runner host; the
Android emulator reaches it via 10.0.2.2. OPENCODE_URL now points there.
- Healthcheck /global/health before launching the app; dump server log on
failure for diagnosis.
- Add --only-connect-scenario to the smoke script and run just the
connect-and-verify-sessions path in CI: deterministic, needs no model
backend. The scenario now creates a session if the list is empty, so a
fresh server still yields a non-empty list.
This makes the smoke a true E2E and also exercises the #10 sessions-list
rendering path against a real server.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(ci): emulator smoke script is dash, not bash — drop brace-group healthcheck
android-emulator-runner runs the script: block under /usr/bin/sh (dash). The
multi-line `|| { ...; }` healthcheck was a dash syntax error (end of file
unexpected), failing the step before the smoke ran. Replace with a non-fatal
one-line re-check; the server was already health-gated in the prior step.
* docs(tasks): record smoke CI round 1 failure + dash fix
---------
Co-authored-by: engineer <engineer@opencode.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Pre-fills data safety / content rating / target audience / ads declarations from
the app's actual behavior so the one human gate (Play Console App content) is a
quick verify-and-enter. User must review before attesting.
The phone-01/02/03 'screenshots' were AI-generated mockups (Apple '9:41'
marketing clock on an Android app, synthetic dark-theme rendering that doesn't
match the app's actual light theme, text overlapping buttons). Shipping these
as screenshots violates Google Play's real-screenshot policy and misleads users.
- Delete the three fake mockups.
- Add a real screenshot captured from the app running on an Android emulator
(build cc.agentlabs.opencode) under play-graphics/screenshots/.
- Fix README store badges: were falsely marked 'available' linking the old
ai.opencode.mobile package. Now: real APK download (GitHub releases),
Google Play 'coming soon', F-Droid 'submitted' (MR #39530).
Connected-state screenshots (session list, streaming chat, diff viewer) will be
captured from the end-to-end smoke test (app + real opencode server).
The canonical public landing page is https://www.vibebrowser.app/opencode.
Repoint README and store-listing website references from agentlabs.cc/opencode
to www.vibebrowser.app/opencode. Privacy-policy URLs and GitHub repo links
left unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update product/marketing website references in README and store-listing
docs from the old vibebrowser.app subdomain to the new landing page at
https://agentlabs.cc/opencode. Privacy-policy URLs and source-repo links
left unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add ASO audit and apply recommendations to play-listing.md (optimized
title, short/full description, category, tags), refresh whatsnew, and
update AGENTS.md Play Console section for the cc.agentlabs.opencode rebrand.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The build.gradle now reads RELEASE_STORE_FILE, RELEASE_STORE_PASSWORD,
RELEASE_KEY_ALIAS, and RELEASE_KEY_PASSWORD env vars for release signing.
Falls back to debug keystore for local development.
Also updates whatsnew for v0.4.1.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- build.yml: use production keystore (KEYSTORE_BASE64) on tag pushes,
fall back to debug key for PRs/branch builds — build.gradle already
reads RELEASE_STORE_FILE env var so no Gradle changes needed
- distribution/fdroid-submission/metadata.yml: filled
AllowedAPKSigningKeys with actual SHA-256 fingerprint, commit tag
updated to v0.3.1, version bumped to 0.3.1
- app.json: bump version 0.2.3 → 0.3.1, versionCode 1 → 2
- Add eas.json + EAS README for iOS App Store builds
- Add fastlane/metadata/android for Play Store / F-Droid graphics
- Add distribution docs: applestore, fdroid, market, playstore,
security, threat-model, opencode-site-deploy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* 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>