Skip to content

feat(extension): prepare Chrome Web Store beta - #32

Merged
kitlangton merged 1 commit into
mainfrom
feat/chrome-web-store-beta
Jul 20, 2026
Merged

feat(extension): prepare Chrome Web Store beta#32
kitlangton merged 1 commit into
mainfrom
feat/chrome-web-store-beta

Conversation

@kitlangton

Copy link
Copy Markdown
Collaborator

What

Prepare Browser Control's thin MV3 extension for an unlisted Chrome Web Store beta while keeping the local relay as the Playwright/session driver.

  • adds protocol-based extension/relay compatibility and readiness reporting
  • makes cold relay startup wait for extension inventory reconciliation
  • recovers reset/delete when an extension update permanently loses a relay-owned debugger attachment
  • scopes replacement sockets, target reconciliation, and command responses so reconnects cannot leave phantom targets or cross socket generations
  • adds deterministic Store ZIP packaging, icons, listing copy, privacy policy, reviewer instructions, and a Changesets patch entry
  • reports protocol compatibility through status and doctor

Before / After

Before

  1. Chrome updated or reloaded the extension and dropped every chrome.debugger attachment.
  2. The relay restored a persisted session pointing at a target ID that could never re-announce.
  3. Both session reset and session delete rejected forever with "target has not re-announced yet".
  4. Recovery required stopping the relay and manually editing sessions.json.
  5. During reconnects, readiness could also cross socket generations, failed inventory reconciliation could be treated as complete, and existing CDP clients could retain phantom targets.

After

  1. Protocol 1 sends hello, re-announces its complete attached-tab inventory, reconciles groups, then sends socket-scoped ready.
  2. The relay clears old live target generations with proper CDP detach events while preserving durable session ownership.
  3. Reconciliation workers are extension-generation scoped; failures retry and then force reconnect instead of publishing false readiness.
  4. Reset/delete wait for a matching target during a bounded grace period. A completed inventory without that relay-owned target declares its durable identity dead and allows recovery without guessing which physical tab to close.
  5. Adopted user tabs never enter the dead relay-target close path.

How

  • extension/src/background.ts implements the protocol-1 handshake, socket-scoped inventory and responses, bounded reconnect behavior, and runtime manifest version reporting.
  • src/extension-rpc.ts, src/protocol.ts, and src/relay.ts gate authoritative events on handshake compatibility/readiness and serialize target reconciliation by extension generation.
  • src/relay.ts adds bounded dead-target release and preserves durable ownership while detaching stale live CDP generations.
  • src/http-api.ts, src/relay-schema.ts, src/doctor.ts, and src/cli.ts expose version-independent protocol diagnostics.
  • scripts/package-extension.ts validates the manifest/resources and emits a deterministic, allowlisted Store ZIP.
  • docs/CHROME_WEB_STORE.md and docs/PRIVACY.md contain submission copy, permission justifications, reviewer steps, disclosure, local-storage categories, and Limited Use language.
  • src/execute.ts keeps snapshot() callbacks self-contained under source-mode esbuild/tsx transforms; src/cli.ts preserves nested secrets run -- <command> operands across the current Effect CLI parser.

Scope

  • The Store-assigned production extension ID is not available yet. It must be pinned in accepted extension origins before submission; arbitrary chrome-extension:// origins remain a development-only submission blocker.
  • A required 1280x800 or 640x400 product screenshot still needs to be captured from the final Store-ID-pinned build.
  • The extension still requires the local @opencode-ai/browser-control relay; this PR does not move Playwright, session state, capture, or artifacts into the extension.
  • The shared live relay remains on published npm 0.3.0 for x-live-chat; final cold-start verification of this exact commit is deferred until that relay can be deliberately upgraded without interrupting the stream workflow.

Testing

  • pnpm run ci
    • TypeScript typecheck
    • 42 test files / 382 tests
    • CLI and extension builds
    • deterministic Store package validation
  • focused replacement, failed-inventory, dead-target reset/delete, persistence, CDP visibility, and extension RPC tests on the final commit
  • complete 22-case browser smoke matrix passed before the final replacement-boundary hardening, including reconnect, redirect reconnect, page recovery, snapshots, handoffs, OOPIF, dedicated workers, authenticated network capture, recording capability, ghost cursor, isolation, multi-client, stale-client, and raw-first checkout
  • live extension 0.0.22 connected successfully to the existing protocol-compatible npm 0.3.0 relay without taking ownership away from x-live-chat
  • Store artifact: artifacts/browser-control-extension-0.0.22.zip
  • SHA-256: bbcf6c18b7ad65cf2cac6dc0ab8b5094d0c33d528d68e20185038f85f59a2d6a

Flow

sequenceDiagram
  participant Extension
  participant Relay
  participant Registry as Target Registry
  participant Session as Durable Session
  participant Client as Playwright/CDP Client

  Extension->>Relay: hello(version, protocol=1)
  Relay->>Client: detach old live target generations
  Relay->>Registry: clear live state
  Note over Session: preserve target identity during reconciliation
  loop attached tabs
    Extension->>Relay: debugger.attached(tabId)
    Relay->>Registry: reconcile exact target generation
  end
  Extension->>Relay: ready
  alt all announced targets reconciled
    Relay->>Relay: mark extension ready
  else reconciliation failed
    Relay-->>Extension: close and reconnect
  end
  alt reset/delete target is live
    Relay->>Extension: close exact tabId
  else complete inventory omits relay target
    Relay->>Session: forget dead target identity
  end
Loading

@kitlangton
kitlangton merged commit abfcabb into main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant