feat(browser): drive the running Arc by attaching, never launch a duplicate (PHNX-2399) - #3299
Conversation
…licate (PHNX-2399) Arc is single-instance: relaunching the Arc binary with a fresh --user-data-dir produced a stray window and no CDP endpoint rather than a debuggable instance — the "second window/instance" bug. An Arc profile now ATTACHES to the Arc the user already has open, and when that Arc exposes no CDP endpoint on the profile's port it fails loud with the one relaunch that fixes it (open -a Arc --args --remote-debugging-port=<port>) instead of silently spawning a duplicate. - drivers/local.ts: for browser==='arc', never fall through to launchBrowser; attach or throw arcAttachRequiredError (names the profile, the port, the fix). - service.ts: arcNotDrivableError now describes the truth — Arc DOES expose page targets and honors Page.navigate; only Target.createTarget (new-tab creation, a CDP-only op) crashes it, so tab-creating verbs fail clearly. - browser.ts: --target-filter is accepted for --browser arc (bind the profile to a Space's tab), not just --electron. - open-url.ts: Arc viewer message corrected — it can't open a fresh viewer tab. - docs/browser.md + CHANGELOG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…99 review follow-up) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rst navigate (PHNX-2399 review)
Two blockers from review:
1. --target-filter was accepted/stored for Arc profiles but never consulted at
drive time — pickReusableTargetWithoutCreate now scopes reusable tabs to the
bound url:/title: filter (and refuses when nothing matches), so navigate drives
the pinned Space rather than an unrelated tab.
2. The documented 'navigate --profile arc --url …' first-use flow threw on a
task-less profile: start({url}) for Arc now routes through navigate() (like
Electron) so it attaches to a reusable tab instead of createPageTarget's refusal;
it still fails loud when there is genuinely no tab to drive.
Also corrects the browserType doc comment (Arc DOES expose page targets). Tests:
new Arc target-filter selection, no-match refusal, and first-use attach; full
browser suite green (567).
Non-author review (code-reviewer subagent — prix-cloud paused, #1767)Verdict: APPROVE (clear to merge) First pass found two BLOCKERS, both now fixed in
The stale |
What & why
agents browseron macOS launched a second Arc window/instance instead of driving the user's existing Arc — and could not reliably drive Arc at all. Arc is single-instance: relaunching the Arc binary with a fresh--user-data-dirdoesn't start a second debuggable process — macOS routes the launch to the already-open Arc (started with no debug port), yielding a stray window and no CDP endpoint.This makes an Arc profile attach to the running Arc, and fail loud when that Arc has no debuggable endpoint — it never silently spawns a duplicate.
Closes PHNX-2399.
Behavior change
drivers/local.ts). Forbrowser === 'arc',connectLocalno longer falls through tolaunchBrowser. It attaches to the running Arc's CDP endpoint, or throwsarcAttachRequiredError— which names the profile, the port, and the one relaunch that fixes it:browser.ts).--target-filter(url:/title:) is now accepted for--browser arc, not just--electron. Arc does not expose Spaces as separate CDP contexts, so you bind the profile to a tab that lives in the Space you want;navigatereuses that tab in place (never hijacks a page you're reading).service.ts). Opening a brand-new tab (Target.createTarget) crashes Arc, so tab-creating verbs fail with an accurate, actionable error. The old message wrongly claimed Arc "exposes no CDP page targets" — it exposes them and honorsPage.navigate; only tab creation is unsupported.open-url.ts). Arc still falls back to the OS browser for anything a human reads, because showing a page needs its own fresh tab.docs/browser.md, new Arc — attach to your running window section) + CHANGELOG.Verification
Live end-to-end against a real Arc is macOS-only and requires the operator to relaunch Arc with a debug port, so it can't run in CI or on this Linux worker. The real attach contract is unit-tested (the fail-loud path runs against a real socket, exactly like the existing
#43test), and the full browser suite passes:New tests:
drivers/local.test.ts— Arc fails loud (never launches) both when nothing serves CDP on the port and when a non-CDP listener holds it;arcAttachRequiredErrornames profile/port/relaunch. Updatedservice.test.tsassertions to the accurate messages.Follow-up
phnx-labs/.agentsskills/browser/browser-use.md) to teach the attach model — linked separately.🤖 Generated with Claude Code