Commit Graph

44 Commits

Author SHA1 Message Date
Den
af7da46c0f chore(release): v0.4.13 (versionCode 40) — waitlist retry queue (#166)
* chore(release): v0.4.13 (versionCode 40) — waitlist retry queue reaches users

Ships 2f81d34 (#165): failed waitlist signups are persisted on-device and
retried on app foreground instead of silently falling back to mailto.
Until this Play release, no user is running that fix.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* fix(waitlist): stamp the app version into the mailto escape hatch

AGE-100 asks for the post-release mailto count "split by app version where the
mail body allows it". It did not allow it: the body was "Sign me up!\n\nEmail: x"
and nothing else, so a mail from an unreachable pre-v0.4.8 sideload is byte-identical
to one from a current build whose retry queue leaked. Those two readings have
opposite meanings — the first is the known permanent cohort, the second is a defect.

Now the escape hatch appends "App: OpenCode Mobile v<version>" (app.json, same
source Sentry uses). Absence of the line == pre-v0.4.13 build. waitlist.ts stays
free of react-native/JSON imports; the screen injects the version.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: engineer <engineer@macbookpro.lan>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-14 02:02:53 -07:00
Den
2f81d34200 fix(waitlist): queue + retry failed signups instead of silently opening mailto (#165)
A signup that hit a network error, the 8s timeout or a 5xx was handed straight
to a `mailto:` composer. That path is lossy by design: it only works if the user
actually presses send, and if we keep reconciling the support inbox into Brevo
list 4 forever (AGE-61's hourly job). 20 of 21 signups were lost that way before
that reconciler existed, and Play's active base is ~100% on v0.4.10+ — so this
was current builds leaking, not just the ~436 stale sideloads.

Now:
- Failed-but-retryable signups are persisted on-device
  (`opencode.waitlist.pending.v1`, AsyncStorage) and retried on every app
  foreground (`app/_layout.tsx`) and on the Add Connection screen mount.
- 4xx stays non-retryable: the server will never accept that address, so we ask
  the user to fix it instead of queueing garbage forever.
- `mailto:` is now only ever opened by an explicit user tap ("Still not working?
  Email us instead"), shown after 3 failed attempts, or offered in an alert when
  device storage itself refuses the write — never as the silent default.
- The UI tells the truth: "Saved on this device — we'll finish signing you up as
  soon as you're back online" instead of implying it was sent.
- `WaitlistResult.fallback` -> `retryable`, `shouldFallbackToMailto` ->
  `isRetryableFailure`: the decision is about retry, not about mail.

Queue policy: dedupe by email, cap 5 entries, 30-day TTL, corrupt/foreign JSON
is discarded rather than replayed. Storage and the clock are injected so the
whole thing runs under `node --test` (16 new tests, incl. the acceptance case:
offline signup -> queued -> reconnect -> reaches the server, no mail client).

Also commits the AGE-61 measurement artifacts that were only ever local
(`distribution/waitlist-signup-path-coverage.md`, `scripts/play-version-share.mjs`)
and updates the doc's "current builds still leak" section, which this fixes.

Refs AGE-87, AGE-61.

Co-authored-by: engineer <engineer@macbookpro.lan>
2026-08-14 01:30:23 -07:00
Den
98233d351f measure: how much of the install base has no in-app waitlist signup path (#164)
AGE-61 asked for a number: what share of installs is still on a build older
than v0.4.8, where the ONLY waitlist path is a mailto: to a human inbox that
nothing reconciles back into the store (20 of 21 signups lost, 2026-08-03 →
2026-08-13). Answering it by hand is how it stays unanswered next quarter, so
this is a script, not a screenshot.

- scripts/play-version-share.mjs: Play Developer Reporting API
  (crashRateMetricSet -> distinctUsers by versionCode) for the auto-updating
  channel, plus --github for lifetime release-APK downloads per tag, which is
  the only per-version signal the sideload channel emits. Mints its own token
  from the service account we already ship to CI; no new deps, no new secret.
  Play versionCodes are run_number+100, NOT the gradle ones — the mapping is
  derived from the publish runs and documented inline (139 = v0.4.8).
- distribution/waitlist-signup-path-coverage.md: the measured answer.

The answer, 2026-08-14: Play is 0% stale (single reported versionCode 142 =
v0.4.10, ~90-100 daily users); the sideload channel is 25.9% stale (436 of
1682 lifetime APK downloads predate v0.4.8) and can never auto-update. There
is no iOS listing and no IzzyOnDroid presence, so nothing else contributes.

Two consequences worth stating plainly: the hourly mailto reconciler is
permanent infrastructure, not a stopgap; and shipping updates does NOT close
the leak, because on current builds the fallback still fires on timeout/5xx/
offline (src/lib/waitlist.ts:shouldFallbackToMailto).

Co-authored-by: engineer <engineer@macbookpro.lan>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-14 00:42:42 -07:00
Den
a750e1b080 growth: qualify 8 founding-member leads + outreach draft (#154)
* growth: qualify 8 founding-member leads + draft outreach; park Stripe test key as founder-gated

Leads qualified from real repo engagement (issues, PRs, forks, stars), ranked
by purchase intent, each with contact channel and fit rationale. Outreach
message drafted with per-lead hooks and send rules.

Blocked on: Bitwarden Secure Note STRIPE_TEST_SECRET_KEY (folder opencode-mobile).
Vault only has OpenClawBot - STRIPE_SECRET_KEY which is sk_live_ and off-limits.

* docs(memory): log founding-member qualification and Stripe blocker

---------

Co-authored-by: Den <vibeteaichnologies@gmail.com>
2026-07-29 20:25:43 -07:00
Den
d6e24e9f99 fix(compliance): disclose email collection in Play Data Safety + align privacy docs (#146)
* fix(compliance): disclose email collection in Play Data Safety + align privacy docs (closes #143)

Google Play rejected cc.agentlabs.opencode (2026-07-22) because the Data
Safety declaration did not disclose collection of Email Address. Root
cause: the optional "OpenCode Connect" waitlist card on the Connect
screen (app/connection/add.tsx -> src/lib/waitlist.ts) collects an email
and forwards it to Brevo (email marketing/CRM) via the beta-signup
backend.

Audited all other PII surfaces and confirmed no other undisclosed
collection: Chatwoot support reports stay anonymous (no email/name),
Sentry strips URLs/tokens and sends no default PII, and PostHog
analytics uses only a random anonymous ID with coarse event properties.

Updates:
- distribution/play-listing.md: Data Safety table now declares
  Personal info / Email address (collected, shared with Brevo,
  optional, purpose account management); embedded privacy-policy draft
  and app description updated to match.
- distribution/privacy-policy.md/.html + docs/privacy/index.html: new
  section 3c discloses the waitlist email collection, third-party
  services list adds Brevo, retention/rights sections and the Apple
  Privacy Nutrition Label table updated accordingly.
- docs/playstore.md: checklist entry documents the rejection and points
  to the fix.
- PUBLISHING.md: adds exact Play Console resubmission steps (Data
  types -> Personal info -> Email address -> collected/shared/purpose)
  plus a note on the earlier unrelated "Missing sign-in details" App
  access blocker in case it resurfaces.

No app code changed; npm test (209 pass) and tsc --noEmit are clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ci): run required checks on docs-only PRs (unblock branch protection)

ios-ci.yml (which emits the required 'Typecheck and unit tests' check) had
paths-ignore for docs/**, docs-site/**, distribution/**, **/*.md. A required
status check that is path-filtered never runs on docs-only PRs, so those PRs
sit permanently in mergeStateStatus=BLOCKED (missing required check). Remove the
paths-ignore so required checks always run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: test <test@test.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:01:48 -07:00
dzianisv
3ac7eb786c chore(release): v0.4.12 (versionCode 39) — global recent sessions + integration test (#145) 2026-07-23 00:59:16 -07:00
Den
c9b504711e chore(release): prepare v0.4.11 (#142)
Align release metadata for the F-Droid reproducibility repair tracked in issue #95.

Co-authored-by: engineer <engineer@gray-knight-m1.local>
2026-07-22 09:42:21 -07:00
Den
b05f386711 fix(release): update stale Play whatsnew to 0.4.10; correct runbook (#128)
The Play publish workflow uses distribution/whatsnew/whatsnew-en-US (its
whatsNewDirectory), NOT the fastlane changelogs/*.txt (those feed F-Droid).
That file was stale at v0.4.7 — so 0.4.8/0.4.9/0.4.10 all shipped to the
internal track with outdated release notes. Updated it to 0.4.10 (<500 chars).

Also corrected PUBLISHING.md, which I'd previously written wrong: (a) app.json
android.versionCode is overridden by CI (github.run_number+100), so 0.4.10's
real Play versionCode is 142, not the app.json value — hand-bumping it is
pointless for Play; (b) Play release notes live in distribution/whatsnew, not
fastlane changelogs. Discovered while promoting 0.4.10 (the Console showed
versionCode 142, not the app.json 37).


Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

Co-authored-by: engineer <engineer@macbookpro.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 12:04:37 -07:00
Den
1ea84f8236 chore(launch): reconcile README/store live-status + add demo-funnel analytics (#111)
Two scoped changes for the no-spend growth launch (Growth Launch Kit,
Notion page 3a1ac25eb49f81099cc9f3a4286c8ec4):

1. README.md and distribution/play-listing.md said Google Play was
   "coming soon" / internal-testing-only, while distribution/retention-analysis.md
   and the live play.google.com listing show it's actually public with 1K+
   installs. Fixed the contradiction, added Google Play as a third install
   channel, and added an accurate mention of the new offline demo mode
   ("Try a Demo" — reasoning, grep, diff, permission prompt, ~30s, no server)
   matching what app/demo.tsx + src/lib/demo-script.ts actually render.
   play-listing.md's stale pre-launch checklists are marked historical
   instead of rewritten, so #83's ASO copy/keyword work is untouched.

2. Added the demo funnel's key metric (demo-completion, per the launch
   kit) as four consent-gated PostHog events: demo_started,
   demo_step_advanced, demo_completed, demo_exited_to_connect. Pure
   property-derivation logic lives in src/lib/demo-analytics.ts (no
   RN/PostHog imports, unit-tested with node --test, same pattern as
   analytics-classify.ts) and is wired into app/demo.tsx's lifecycle.
   Updated docs/analytics.md's event table and the privacy policy's event
   list (distribution/privacy-policy.md + its two HTML mirrors) per the
   repo's "new event requires a policy update" convention.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 19:49:47 -07:00
Den
d54a74d3f5 fix(onboarding): clarify opencode-serve requirement + fail connect fast (retention) (#107)
* fix(onboarding): clarify opencode-serve requirement and fail connect tests fast

New users bounce at ~0% 7-day retention because nothing tells them the app
needs a computer running `opencode serve` on the same network/Tailscale, and
a bad IP hangs for the full 30s request timeout before failing.

- Rewrite the no-connection empty state subtitle and add a "How to set up a
  server" link to the setup guide (app/(tabs)/index.tsx, src/lib/links.ts).
- Surface the opencode-serve prerequisite as a one-line notice at the top of
  the Quick Connect form, above the existing detailed help box
  (app/connection/add.tsx).
- Give the interactive connection test (testConnection) its own 12s timeout
  via an optional Client.global.health(timeoutMs) parameter, instead of
  reusing the general 30s REQUEST_TIMEOUT_MS used for real session traffic
  (src/lib/sdk.ts, src/stores/connections.ts).
- Mirror all new/changed strings in the zh-Hans catalog; catalog-parity test
  keeps them in sync.

* docs(distribution): add retention analysis motivating first-run fixes

Diagnoses ~0% D7 retention as product-shape (no path to value without a
self-hosted server, no demo mode, store copy sets no expectation). Ranks
fixes and isolates the two owner-only strategic calls (store-copy honesty,
hosted OpenCode Connect).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

* fix(onboarding): drop connect-screen prerequisite notice (kept off-screen the submit button in E2E)

The added notice pushed connect-submit-button below the fold, breaking the
Maestro activation-positive flow (and the other flows sharing the connect
prelude). The empty state already sets the opencode-serve expectation one
screen earlier, so this notice was redundant. Empty-state guidance + guide
link and the fast-fail connect timeout are unaffected and retained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T12AhSnQVrSxNnvwfCx2z6

---------

Co-authored-by: engineer <engineer@macbookpro.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 17:55:12 -07:00
Den
922cffffbd ci(fdroid): build a separate fdroid-stripped release APK for reproducible-build parity (closes #95) (#99)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:18:37 -07:00
Den
63f3ec3c7e docs+consent: disclose activation analytics honestly across consent modal, privacy policy, and store docs (#81)
The app ships PostHog activation-funnel analytics gated behind the same
consent flag as Sentry, but the consent modal, Settings toggle, privacy
policy, and Play Data safety draft only mentioned crash reporting. Fix
the disclosure everywhere:

- TelemetryConsentModal: body + bullets + a11y labels now cover anonymous
  usage analytics (PostHog EU) alongside crash reports
- Settings: toggle renamed 'Crash Reports & Usage Analytics', description
  names both Sentry and PostHog
- Privacy policy (md + html + live gh-pages mirror): new section 3a with
  the full event/property table, PostHog EU destination, anonymous-ID
  statement, decline/revoke (drop-on-revoke) semantics; sections 4-7, 9
  and the Apple nutrition-label addendum updated for analytics
- play-listing.md: Data safety draft declares App interactions + Device
  or other IDs (opt-in, default OFF, shared with PostHog/Sentry)
- docs/playstore.md: Data safety row flipped to re-verify with pointer
  to the new design record
- docs/analytics.md: new design record — event schema, consent gating
  incl. buffered-event drop on revoke, disclosure surfaces to keep in
  sync, verification checklist (all TODO)
- website privacy page metadata mentions analytics opt-in

Closes #63


Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E

Co-authored-by: engineer <engineer@gray-knight-m1.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 03:28:00 -07:00
Den
004fa13795 chore(store): refresh Play listing — drop dated 'GPT-4', ASO keyword pass (#83)
* chore(store): refresh Play listing — drop dated "GPT-4", ASO keyword pass

distribution/play-listing.md is the canonical copy-paste source for the
Play Console listing (per distribution/strategy.md). It still named
"GPT-4" and was missing the directory picker and reasoning-effort
features shipped since. Rewrite title/short description/full
description to be model-agnostic ("Claude, GPT, Gemini, or any other
model") so it stops dating itself, add the two new feature bullets, a
connection-options section, and screenshot captions.

Also fixes the same stale "GPT-4" mention in the orphaned
distribution/play-store-listing.md (marked superseded — it was never
merged back into play-listing.md), distribution/aso-audit.md's
recommended-copy example, and distribution/app-store-listing.md for
cross-store consistency.

fastlane/metadata/android/en-US/full_description.txt is untouched: it
already had no stale model name, and it is shared with the F-Droid
auto-pull (plain text + AntiFeatures disclosure required by mainline
F-Droid) so it must not get Play-style HTML/marketing copy. Only
title.txt and short_description.txt (Play/App-store-only fields, not
read by F-Droid's metadata.yml which sets AutoName explicitly) were
aligned with the new short description.

* docs(store): correct full-description char count annotation (3410→3366)

---------

Co-authored-by: engineer <engineer@gray-knight-m1.local>
2026-07-16 19:08:29 -07:00
engineer
c20f470545 chore(ios): switch Apple ID to vibeteaichnologies@gmail.com (owner decision 2026-07-17) 2026-07-16 18:13:26 -07:00
Den
5c14ce0a5d feat: add daily product intelligence and versioned site assets (#64)
Adds privacy-safe aggregate product intelligence, reviewed/versioned website assets, and a dispatch-only rollout until the dedicated Sentry token is verified. Independent review blockers were fixed in 8bc47e4; app checks, website production build, Android CI, and iOS CI are green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-15 11:59:40 -07:00
Dennis V
d1071b2a44 fix(ios): close final release review blockers
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 17:49:53 +00:00
Dennis V
f9b18a06f3 fix(privacy): stop telemetry on consent revocation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 06:30:09 +00:00
Dennis V
791588647b feat(ios): add native build and TestFlight automation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 06:16:36 +00:00
Dennis V
cc0f5217b1 release: bump to v0.4.7 (versionCode 34)
SSE disconnect banner, backgrounded permission notifications,
scrubUrl unit tests (13 tests, 81/81 suite green).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:39:43 +00:00
Dennis V
9498b19457 fix(pages): replace vibebrowser.app with agentlabs.cc across all pages
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>
2026-06-23 05:18:12 +00:00
Dennis V
2f052e3833 fix(dist): update play whatsnew, fdroid email, package name in strategy
- whatsnew-en-US: v0.4.6 sessions fix notes (actually used by Play CI)
- fdroid metadata AuthorEmail: support@agentlabs.cc
- strategy.md: ai.opencode.mobile → cc.agentlabs.opencode

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 05:06:02 +00:00
Dennis V
7616f97326 release: bump to v0.4.6 (versionCode 33)
Sessions loading regression now properly tested in CI — CUA sessions_reload
phase confirmed passing. Also: support email, descriptions, screenshots.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 04:49:49 +00:00
Dennis V
1f476f1eab fix(support): update contact email to support@agentlabs.cc
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>
2026-06-23 00:17:06 +00:00
Dennis V
09b034eaf3 feat(distribution): add Play Store ASO listing content
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
2026-06-20 21:13:30 +00:00
engineer
3bdeeb6bef fdroid(mainline): add Binaries field to recipe; sync local metadata + log
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>
2026-06-08 09:21:45 -07:00
engineer
18fcfab2bc marketing: add real on-device demo GIF (connect -> sessions -> streaming reply)
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>
2026-06-08 09:19:10 -07:00
engineer
8c75007ee5 launch: pre-flight accuracy pass on Show HN + Reddit copy
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>
2026-06-08 09:15:59 -07:00
engineer
e39cec3847 fix(launch): Expo SDK 52->54 in HN/Reddit copy; add reply-flow E2E evidence; version refs
- 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>
2026-06-08 07:42:19 -07:00
engineer
366a936431 docs(launch): fill launch drafts with live install URLs — post-ready (Play marked pending)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:19:29 -07:00
engineer
dc7cc749c2 docs(distribution): cite live GitHub Pages privacy URL for store submissions (unblocks Play/IzzyOnDroid)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:11:39 -07:00
engineer
c8458cd397 docs(distribution): reconcile privacy-policy URL to opencode.vibebrowser.app; v0.4.3
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>
2026-06-02 01:52:09 -07:00
engineer
67773fc8ba docs(izzyondroid): correct stale package id and version in inclusion request
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>
2026-06-02 00:21:20 -07:00
Den
14e858a402 ci(play): production track input + launch kit + F-Droid metadata fix (#19)
* 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>
2026-06-01 15:32:19 -07:00
Den
c9a57901c4 fix(ci): CUA smoke true-E2E with local opencode server (#15) (#18)
* 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>
2026-06-01 15:32:06 -07:00
engineer
d1888dc392 docs(play): draft App content declaration answers to speed console publish
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.
2026-06-01 15:24:39 -07:00
engineer
8e06b860ac fix(dist): remove AI-generated fake screenshots; use real app captures
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).
2026-06-01 14:36:23 -07:00
engineer
6351dd6e71 docs: repoint website links to www.vibebrowser.app/opencode
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>
2026-05-31 13:20:39 -07:00
engineer
6dc7e71a40 docs: point website/homepage links to agentlabs.cc/opencode
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>
2026-05-30 15:08:27 -07:00
engineer
a4cd22ef4b docs(aso): finalize Play Store SEO listing copy
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>
2026-05-30 04:09:16 -07:00
engineer
7ec3461304 fix: use release keystore in CI when RELEASE_STORE_FILE is set
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>
2026-05-28 00:20:21 -07:00
Dzianis Vauchok
586b01e7f8 chore: release v0.3.2 — session visibility fix 2026-05-26 08:30:49 +00:00
Dennis V
b8fb390f5c feat(release): production signing in build.yml + F-Droid metadata filled
- 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>
2026-05-26 01:26:35 +00:00
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
Dennis V
7ea41216c8 feat(release): add keystore setup + Play Store deployment guide
- Generated PKCS12 keystore (production-release.jks, alias: upload)
- Updated GitHub secrets: KEYSTORE_BASE64/PASSWORD/KEY_ALIAS/KEY_PASSWORD
- Added keystores/ to .gitignore
- Added distribution/PLAY_CONSOLE_SETUP.md: step-by-step guide to
  create GCP service account, link to Play Console, first manual
  upload, and configure PLAY_STORE_SERVICE_ACCOUNT_JSON secret
- Installed android-playstore-setup skills (sub-skills)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 10:51:56 +00:00