You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The 1.61.0->1.61.1 bump leaves patchedDependencies keyed to
playwright-core@1.61.0, so the bundled-ws->built-in-ws patch silently
stops applying. playwright-core 1.61.1 still ships the unpatched
`var ws = wrapper_default;`, which deadlocks the CDP websocket handshake
under Bun. Re-key the patch (content unchanged, still applies cleanly to
the 1.61.1 bundle), regenerate the lockfile, and update the patch-filename
citations in the browser tooling and the browser-automation-engine ADR.
Copy file name to clipboardExpand all lines: docs/adr/browser-automation-engine.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ Findings from source inspection (v0.27.1) and external research:
22
22
23
23
1.**The subprocess boundary is incompatible with our trust model.** Per [Browser Fill Secret](browser-fill-secret.md) and [Browser Stealth Identity](browser-stealth-identity.md), every string that leaves the browser layer passes through per-task + cross-task secret redaction, navigation passes through SSRF/DNS-rebinding pre-flight and post-redirect re-validation, screenshots go only to a vision side-call with pre-blur and post-OCR redaction, and uploads are approval-gated. All of that lives on in-process hooks into the Playwright session. agent-browser offers no interception points — adopting it means rebuilding the trust machinery as wrappers around opaque CLI text output, or weakening it.
24
24
2.**Its core innovation is one we already have.** The `@eN` ref snapshot model — the reason agent-browser wins benchmarks against Playwright MCP — is structurally what `src/tools/browser.ts` already produces, with budgeting agent-browser lacks (32 KB default cap, hidden-element budget, middle-out truncation).
25
-
3.**It is weakest exactly where we need the most reliability.** Headed connect for user sign-in and CDP attach to the user's own Chrome had open bugs at evaluation; the CDP-attach issue under Bun (playwright-core's bundled `ws` deadlocking the websocket handshake) is fixed in-place by `patches/playwright-core@1.61.0.patch` — a far smaller intervention than swapping the engine for one with the same class of bug and no API contract.
25
+
3.**It is weakest exactly where we need the most reliability.** Headed connect for user sign-in and CDP attach to the user's own Chrome had open bugs at evaluation; the CDP-attach issue under Bun (playwright-core's bundled `ws` deadlocking the websocket handshake) is fixed in-place by `patches/playwright-core@1.61.1.patch` — a far smaller intervention than swapping the engine for one with the same class of bug and no API contract.
26
26
4.**Dependency risk.** Pre-1.0, single-maintainer, experimental org, one rewrite already behind it — a poor foundation for a security-sensitive layer whose host has no programmatic contract with it.
27
27
28
28
agent-browser stays in our *development* workflow (driving the Next.js dev server for QA, per `CLAUDE.md`) — that use is interactive, low-trust, and plays to its strengths. This ADR is only about Gini's runtime browser tools.
@@ -62,7 +62,7 @@ The runtime's DEFAULT transport is a per-instance branded Chrome it **spawns its
62
62
63
63
`src/tools/chrome-launch.ts` (`launchSpawnedChrome`) launches a branded Chrome via `chromium.launchPersistentContext` over Playwright's pipe transport — `--headless=new` + the shared stealth args + a clean (non-`HeadlessChrome`) UA + the per-instance `--user-data-dir` + a free-picked `--remote-debugging-port`. `launchPersistentContext` drives the spawned page over the pipe inherently; the TCP debug port is an extra local endpoint the sign-in screencast bridge attaches to over raw CDP, **not** the automation transport. On a machine with neither a branded Chrome nor Playwright's bundled Chromium on disk, the launch downloads Playwright's Chromium on demand (`src/tools/chrome-install.ts`) and retries — so "no Chrome installed" is a supported, self-provisioning case rather than a hard failure.
64
64
65
-
The cdp attach (`cdpSessionProvider` in `src/tools/browser.ts`) calls `chromium.connectOverCDP(record.cdpUrl)` to the user's external Chrome and reuses its first context. We never spawn or signal that process: disconnect calls `Browser.disconnect()` when present and NEVER `close()` (which on some Playwright builds would kill the user's Chrome). `connectOverCDP` works under Bun via `patches/playwright-core@1.61.0.patch`, which routes playwright-core's bundled `ws` to Bun's built-in `ws` — without it the websocket handshake deadlocks. The cdp attach is an opt-in transport (the user must point the runtime at their own Chrome) rather than the default.
65
+
The cdp attach (`cdpSessionProvider` in `src/tools/browser.ts`) calls `chromium.connectOverCDP(record.cdpUrl)` to the user's external Chrome and reuses its first context. We never spawn or signal that process: disconnect calls `Browser.disconnect()` when present and NEVER `close()` (which on some Playwright builds would kill the user's Chrome). `connectOverCDP` works under Bun via `patches/playwright-core@1.61.1.patch`, which routes playwright-core's bundled `ws` to Bun's built-in `ws` — without it the websocket handshake deadlocks. The cdp attach is an opt-in transport (the user must point the runtime at their own Chrome) rather than the default.
66
66
67
67
The active handle (spawned or cdp) installs into the single per-instance `shared` slot — one shared browser per instance (cookies bleed across tasks within the instance, per the explicit product decision). For the spawned handle, teardown closes the persistent context and, only if that wedges, reaps the Chrome bound to the instance's own profile dir (never `killall`, never the user's own `:9222`). See [Browser Stealth Identity](browser-stealth-identity.md).
0 commit comments