Commit Graph

259 Commits

Author SHA1 Message Date
engineer
e72e82df8e feat(ci): add Play Store review triage workflow
scripts/triage-reviews.py was fully written but had no workflow, so it
never ran. Add a daily 07:00 UTC cron (staggered after product-intelligence)
plus workflow_dispatch, with Python 3.12 + the Android Publisher API client
deps the script imports, and GOOGLE_SERVICE_ACCOUNT_JSON / GH_TOKEN passed
through as named secrets.

Also fix a stale doc-string reference: the issue body linked to a
non-existent monitor-reviews.yml; point it at the workflow actually created.
2026-07-16 15:46:21 -07:00
engineer
14a130cf66 feat(ci): schedule daily product-intelligence run
The workflow existed with only workflow_dispatch, so it never ran on its
own. Add a daily 06:00 UTC cron alongside the manual trigger.
2026-07-16 15:46:16 -07:00
Den
a5723bf087 feat: improve project picker with recents and server projects (#52)
Adds recent and server-project discovery to the new-session directory picker. Reviewed against current main; Android, iOS Simulator, and mandatory CUA checks are green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-15 12:06:46 -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
Den
cbe00c3222 feat: prepare iOS build and TestFlight CI (#66)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 11:16:25 -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
c287ecad70 docs(agents): switch browser automation to VibeBrowser
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 16:56:56 +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
679475d0a4 docs(site): publish iOS implementation progress
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-14 06:16:36 +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
d546c41e22 fix(cua): connect phase — verify by connection entry appearing, not by reading tiny URL text 2026-06-24 08:48:42 +00:00
Dennis V
378e6ecf0a fix(cua): connect phase — app uses separate IP + Port fields, button is 'Connect' below scroll 2026-06-24 08:23:34 +00:00
Dennis V
28f8182f09 fix(cua): session_list phase — tapping connection only sets active, must then navigate to Sessions tab 2026-06-24 08:00:11 +00:00
Dennis V
2ed26dcbe2 fix(cua): increase default max_steps_per_phase to 25 — connect phase needs more room for first-launch UI navigation 2026-06-24 07:34:21 +00:00
Dennis V
00409c71b4 fix(ci): use temp script file to avoid sh -c quoting issues with CUA dispatch 2026-06-24 07:07:29 +00:00
Dennis V
1f59602fce fix(ci): fix shell syntax in emulator runner script — avoid complex elfi chain, use flat script 2026-06-24 06:42:18 +00:00
Dennis V
00378ba7ed fix(ci): YAML syntax error — double-quotes in GH expression default value; add no-tap instruction to showcase typescript phase 2026-06-24 06:15:51 +00:00
Dennis V
d413d5f927 docs: add --e2e and --query to CI dispatch + AGENTS.md
cua-smoke.yml:
  - Add scenario/query/e2e_* workflow_dispatch inputs
  - Runner step dispatches to --query / --e2e / --showcase based on inputs
  - Upload /tmp/cua_eval_report.json as artifact (--query output)

AGENTS.md:
  - Document all 3 run modes: --showcase, --e2e, --query
  - List available models on dev server (deepseek-v4-flash-free etc.)
  - Add dispatch inputs reference for CI
  - Add --e2e / --query to 'when to run' guidance

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 04:57:03 +00:00
Dennis V
a305936f2b feat(cua): add --e2e and --query modes with structured evaluation
--e2e mode: full end-to-end coding task scenario
  - connect → long-press FAB to create session in custom project dir
  - select AI model via model picker (hint substring match)
  - submit coding task → DETERMINISTIC API poll for session idle
  - DETERMINISTIC API message scan for target filename
  - DETERMINISTIC ADB uiautomator check for filename in UI
  - LLM screenshot + visual evaluation summary

--query mode: natural-language test description → structured test run
  - LLM planner converts the query into JSON phases + deterministic checks
  - Executes each phase via the CUA loop (with critical/informational split)
  - Runs deterministic checks: ui_text | session_idle | file_created
  - LLM evaluator produces scored JSON report: overall/score/phases/recommendations

New helpers:
  - wait_for_session_idle(): polls GET /session until status==idle (no LLM)
  - check_session_file_created(): scans session messages API for filename
  - _api_base(): translates emulator host route for host-side API calls
  - run_scenario_hello_world_e2e(): 8-phase hardcoded e2e scenario
  - run_query_test(): planner → execute → evaluator pipeline

Also adds hello_world_e2e to --scenarios catalog for named invocation.

Usage:
  # Hardcoded e2e:
  python scripts/android-cua-smoke.py --e2e --opencode-url http://100.108.64.76:4096

  # Natural-language query:
  python scripts/android-cua-smoke.py --query \
    'Open android app. Connect to server. Open ~/workspace/opencode-mobile. \
     Choose deepseek model. Ask to write hello_world.py. Validate it was created.'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 03:53:01 +00:00
Dennis V
4c2f6793de feat: add Vercel analytics to website + Play Store review triage script
- docs-site/index.html: add Vercel Analytics + Speed Insights CDN scripts
  (only fires on opencode.agentlabs.cc served via Vercel, not GitHub Pages)
- scripts/triage-reviews.py: fetch recent Play Store reviews via Android
  Publisher API, create GitHub issues for ≤3★ reviews not yet tracked

Run review triage manually on VM:
  DAYS_BACK=7 GOOGLE_SERVICE_ACCOUNT_JSON=... GH_TOKEN=... python3 scripts/triage-reviews.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 20:18:15 +00:00
Dennis V
4f10cd4ccf assets: expand to 7 screenshots covering full PRD app flow
Shows every major screen: connect, sessions list, chat input,
tool calls streaming, file writes, completed result, settings/model.

01 - Add connection screen (onboarding)
02 - Sessions list loaded from server
03 - Session chat view with message sent
04 - AI tool calls streaming (reading files)
05 - AI writing TypeScript files to disk
06 - Completed session — hello.ts created
07 - Settings + model selection

Website updated to show all 7 in a tighter grid (max-width 260px).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 17:31:57 +00:00
Dennis V
c1ced308cc assets: update screenshots and demo from CUA run 28041009456 (v0.4.7)
Fresh from successful onboarding showcase: connect → sessions → TypeScript
coding task → verify → settings. All critical phases PASS.

Screenshots:
  01: Sessions list loaded after connecting
  02: TypeScript hello.ts completed successfully (AI output visible)
  03: Sessions reload after navigation back

Demo: 10x speed (168s → 31s), 116KB mp4 + 1.2MB gif fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 17:06:07 +00:00
Dennis V
7c4fdbdb57 assets: update Play Store phone screenshots from CUA run 28013924527
- 01.png: sessions list view
- 02.png: active TypeScript session (code generation)
- 03.png: settings/model selection screen

Uploaded to cc.agentlabs.opencode Play Console (en-US, phoneScreenshots).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:42:59 +00:00
Dennis V
3882e0d255 assets: update screenshots from CUA run 28013924527
- 01.png: sessions list view
- 02.png: active TypeScript session (code generation in progress)
- 03.png: settings/model selection screen

Source: CI run 28013924527 (cua-smoke.yml), upscaled 4x (1280×2560)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:41:15 +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
029bf2be04 fix(notifications): use user-friendly title and dedup keys for permission/question notifications
- Change permission notification title from `req.permission || 'Permission requested'`
  to the user-friendly 'Agent needs approval'; permission type + patterns now appear
  in the body (e.g. 'bash: echo hello') for context.
- Add `dedupeKey: `perm-${req.id}`` and `dedupeKey: `question-${req.id}``
  (60 s cooldown) to both events so a SSE reconnect after disconnect() clears state
  can't fire a second notification for the same pending request.
- Fix stale CUA-test comment that claimed 'Agent needs approval' did not exist;
  fallback assertion already matched correct title; update the comment to reflect
  the real events.ts behavior.

Closes #39

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:33:27 +00:00
Dennis V
5427abdb5e feat(ux): SSE disconnect/reconnect banner in session view (#42)
Shows amber 'Reconnecting… (attempt N)' banner when SSE is down.
Shows brief green 'Connected ✓' flash on reconnect (useRef transition
to avoid atomic state reset bug where lastDisconnectAt resets with
reconnectAttempts in the same set() call).

Banner disappears automatically when SSE is stable.

Updates CUA scenario to check for both ASCII and Unicode ellipsis.

Closes #42

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:31:58 +00:00
Dennis V
6fee057355 test(sentry): extract pure scrub module + add unit tests — privacy regression guard
Extracts scrubUrl/scrubString/scrubObject into src/lib/scrub.ts (no RN deps)
so they can be tested with node --test without native module issues.

Adds src/lib/scrub.test.ts with 13 test cases covering:
- basic-auth credential stripping
- query-param secret redaction (token, api_key, password, access_token)
- clean URL passthrough
- mixed-param URL (only secrets redacted)
- embedded URL in error message strings
- nested object recursive scrubbing
- non-string value preservation

Closes #40

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 16:31:15 +00:00
Dennis V
ca57bab72d docs(agents): fix stale Play Console status — cc.agentlabs.opencode IS live on internal track
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 15:42:34 +00:00
Dennis V
38da2813b0 test(cua): fix #39/#42 deterministic assertions to match real app behavior
#39 (backgrounded permission notification):
- Event is permission.asked, not permission.requested (events.ts already calls
  notify() for it; send() only fires while backgrounded).
- Assert on APP_PACKAGE (the only token guaranteed in every dumpsys record) plus
  the actual copy ('Permission requested' / 'A tool needs your approval') instead
  of the non-existent 'Agent needs approval' string.

#42 (SSE disconnect banner):
- reconnectAttempts only zeroes after STABLE_CONNECTION_MS (10s) past a healthy
  reconnect, and the pending backoff timer can take up to 15s — so the banner can
  linger ~25s. Poll up to 40s for dismissal instead of a fixed 15s sleep to avoid
  a false 'still showing' failure.

Refs #39 #42

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 15:36:55 +00:00
Dennis V
e4a84e72ea docs: update goal.md to current state (v0.4.6 shipped, Play Store internal, website live, CUA green)
Rewrite <current_mission>: the Play Store publication blocker is cleared
(cc.agentlabs.opencode live on internal track), website opencode.agentlabs.cc
is live (HTTP 200), and the CUA sessions_reload phase is green (run 28002986180).
Refocus the mission on growth: Play Store promotion, F-Droid mainline, content
marketing, and organic SEO/ASO.

Closes #44

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 15:36:42 +00:00
Dennis V
e29f381aab docs(tdd): correct stale references — clarify path.get()/serverHome, add speech.ts, fix version note
- §4: path.get() is still live (feeds serverHome → directory switcher ~ expansion);
  only the dead session-scoping plumbing (sessionScope.ts) was removed in 472ff8d.
  Clarify rather than delete, since the call site is not dead.
- §2: document src/lib/speech.ts (experimental voice input; PRD §7 scope caveat).
- §7: app.json and package.json versions are kept in sync since v0.4.6 (both 0.4.6).

Refs #43

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 15:36:35 +00:00
Dennis V
1f8bae3342 feat(cua): add deterministic ADB-based assertion helpers + feature test scenarios
Adds three deterministic helpers that use ADB instead of LLM vision,
so pass/fail cannot be hallucinated:

  check_ui_text(text)          — uiautomator XML dump + grep
  check_notification_drawer(text, timeout) — dumpsys notification poll
  simulate_network_drop() / restore_network() — svc wifi/data disable

Plus two new feature-test scenarios with deterministic gating:

  sse_disconnect_banner (#42)
    - ADB cuts WiFi+data, waits, checks UI XML for 'Reconnecting' text
    - LLM visual check is supplementary/informational only
    - ADB restores network, checks banner disappears

  backgrounded_permission_notification (#39)
    - ADB backgrounds app (Home key)
    - API sends permission-triggering message
    - adb dumpsys notification checked for 'Agent needs approval'
    - No LLM involved in pass/fail decision

Also adds background_app() / foreground_app() helpers.
Wires new scenarios into --scenarios catalog alongside LLM ones.
Updates --scenarios help text to document both types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 15:19:34 +00:00
Dennis V
73656c783d retro: document 2026-06-23 sessions false-fixes + CF detour lessons
Key entries:
- Vacuous CUA test goal ('empty is fine') enabled 3x false 'fixed' reports
- Cloudflare 2h detour: wrong zone ID + 20+ repeated DOM failures
- task_complete gate: real-channel verification required
- Overhead sequencing: reproduce before document
- Regression guards must run before model-dependent phases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 14:10:59 +00:00
Dennis V
6198e4e165 fix(cua): stronger connect phase + fallback pre-create for external server
connect phase: now verifies the connection appears in the list after saving,
not just that the form was dismissed. Prevents false PASS when the LLM
declares connect done before the entry is actually visible.

_precreate_test_session: when external URL (Tailscale) times out from the
CI runner, fall back to localhost:4096 (the runner-local opencode serve).
This ensures the named-session assertion stays active in standard CI runs
while also working when dispatched against a live external server.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 09:11:20 +00:00
Dennis V
1dafdcbc65 ci(cua): add opencode_url dispatch input for live server testing
When dispatched with opencode_url set (e.g. Tailscale URL), the workflow
skips starting a local opencode server and the model probe, and points the
emulator directly at the external server.

This allows running the full CUA test against a live dev server without
depending on the flaky CI-hosted opencode serve setup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 08:45:34 +00:00
Dennis V
ca33f246e4 refactor(ci): remove unused SCENARIOS branch from probe step
The probe step computed a SCENARIOS output, but the emulator step runs
--showcase hardcoded and never consumes steps.probe.outputs.SCENARIOS, so
the selection logic was dead. Drop it and keep MODEL_CAPABLE as an
informational signal. Showcase mode handles model-unavailability gracefully
(typescript/verify phases are informational-only).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 05:21:38 +00:00
Dennis V
472ff8d27d refactor(sessions): remove dead serverHome/path.get() plumbing
sessionScopeDirectory() always returned null and ignored its home arg, so
the scope plumbing in loadSessions/createSession was dead: scopeDir was
always null, listClient always the default client, and the lazy path.get()
fetch fed only that dead branch. Collapse both call sites to use the
connection's default client directly and delete the now-orphaned
sessionScope.ts helper and its test.

serverHome is intentionally KEPT in connections.ts: it is still consumed by
the directory switcher UI (DirectorySwitcher.tsx, app/(tabs)/index.tsx) for
~ path expansion, so it is not dead code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 05:20:41 +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
2de1d22904 assets: update screenshots and demo video from CI run 27992695069
Screenshots from CUA smoke test showing:
- 01: Sessions list loading real sessions from server on connect
- 02: Streaming AI response in a coding session
- 03: Sessions tab after navigating back (sessions_reload regression guard)

Demo: 10x speed video (138s → 14s) of full onboarding flow.
Website now shows <video> with mp4 source + gif fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:37:15 +00:00
Dennis V
8ad088b771 copy(descriptions): rewrite Play Store + website for technical clarity — lead with opencode serve remote control, Tailscale setup
- full_description.txt: replace fluffy copy with concrete HOW IT WORKS steps,
  TAILSCALE recommendation, explicit WHAT THIS APP IS NOT section, updated
  support email to support@agentlabs.cc
- short_description.txt: 77-char tagline focused on opencode serve remote control
- docs-site/index.html: update meta description, og:description, twitter:description,
  ld+json description, hero tagline, and 'What is OpenCode Mobile?' paragraphs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:18:22 +00:00
Dennis V
80cefa798d fix(support): correct typo connect@ → support@agentlabs.cc in connection error mailto
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:17:50 +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
bbe8af9378 fix(cua): pre-create API call must use 127.0.0.1 not 10.0.2.2 on host
The CUA script runs on the CI runner (host), not inside the emulator.
10.0.2.2 is the emulator's special address for the host — it is only
reachable FROM INSIDE the emulator. Calling it from the runner always
fails, so _precreate_test_session returned None, and the session_list
phase fell back to the weak 'screen visible' assertion instead of the
strong 'pre-created session must appear' check.

Fix: replace 10.0.2.2 → 127.0.0.1 before making the pre-create call.
Localhost URLs (100.x.x.x, custom dev server) pass through unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:06:32 +00:00
Dennis V
cdbea50287 fix(cua): fix sessions_reload banner label (moved to step 4b)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:04:20 +00:00
Dennis V
212b80b4a8 fix(cua): move sessions_reload before typescript; fix CI emulator boot
sessions_reload regression phase now runs BEFORE the TypeScript task.
Previously it was gated behind typescript which fails in CI when the model
is unavailable — meaning the actual sessions regression check never ran.

Phase order is now:
  connect → session_list (pre-created session required) → new_session
  → sessions_reload (navigate back, list must be non-empty) [CRITICAL]
  → typescript (informational) → verify (informational) → settings

Critical phases: connect, session_list, new_session, sessions_reload.
TypeScript/verify/settings are informational (model availability varies).

CI emulator fixes:
- api-level: 30 → 28 (more stable, boots reliably on ubuntu-latest)
- target: google_apis → default (lighter, no Play Services needed for
  sessions regression test, avoids known boot issues with google_apis)
- disable-animations: true (reduces boot overhead)
- emulator-boot-timeout: 600 (explicit, matches action default)
- Switch from --scenarios to --showcase (runs the new structured flow
  with _precreate_test_session + sessions_reload phase)
- Clear app state before install (pm clear) for deterministic first-run

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 00:02:13 +00:00
Dennis V
42aa883f99 test(cua): make session_list phase actually test sessions load regression
Previously the session_list phase goal said 'The session list may be empty
(no sessions yet) — that is fine' and 'Report done when you can see the
session list screen (even if empty)'. This means an empty sessions list
was treated as a test PASS, so every previous 'fix' was validated against
a test that cannot detect the regression.

Two changes:
1. _precreate_test_session(): calls POST /session via HTTP before the CUA
   starts. The session_list phase goal now explicitly names this session and
   requires it to be visible — if the app fails to load server sessions,
   the phase fails (not passes silently with an empty list).
   Falls back gracefully if the server is unreachable at pre-create time.

2. sessions_reload phase (new, critical): after completing the TypeScript
   task the test navigates back to the Sessions tab and asserts the list is
   non-empty. This catches the other variant of the regression — sessions
   vanishing after navigating away from a session and back.

Both phases are now in the critical list, so a failure in either causes the
overall test to report partial/fail instead of success.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 23:54:22 +00:00
Dennis V
c5f90ee3c0 fix(cua): explicitly prohibit stray taps after sending — stray tap navigates away from session and breaks SSE 2026-06-22 23:04:17 +00:00