Optimal architecture (chosen over the WS+token copy): the ab-connect extension
talks to a local agent-browser native-messaging host. No localhost port, no
token — Chrome authenticates the extension to the host by id. This is the
codex/claude-style "install once, no per-use confirmation" model.
- extensions/ab-connect: rewritten transport WebSocket+token → native messaging
(chrome.runtime.connectNative). Pinned the extension id via a manifest `key`
(→ bdoiejojpjogcjojeladhioioijhgade) so the host manifest can authorize it.
Kept the proven chrome.debugger attach + Target.attachedToTarget emulation;
dropped WS/token/options. Rebranded to "agent-browser connect".
- cli connect.rs: `agent-browser extension install` writes the native-messaging
host manifest (Chrome/Chromium/Edge/Brave) + a launcher; hidden `__nm-host`
speaks the 4-byte-length native-messaging framing.
Validated end-to-end on real Chrome: Chrome spawned the host (origin matched the
pinned id) and the extension attached the user's real logged-in tabs, streaming
Target.attachedToTarget over native messaging — zero token, zero port.
Next: bridge the host to the daemon relay (relay.rs) + CdpClient so
`agent-browser click/eval/...` drives those tabs.
First step toward zero-confirmation direct connect to the user's real Chrome:
Chrome 136 killed --remote-debugging-port on the default profile, so the only
sanctioned way to drive the user's live logged-in window is an extension using
chrome.debugger (same approach as Codex/Claude, whose extensions are closed).
Vendors the MIT-licensed openclaw-browser-relay extension into
extensions/ab-connect/, rebranded to "agent-browser connect" (NOTICE.md keeps
attribution). It already handles the hard parts: chrome.debugger auto-attach all
tabs, new-tab auto-attach, MV3 service-worker keepalive (alarms) + reconnect,
sessionId↔tab mapping, token auth, and a CDP-over-WebSocket envelope
(connect handshake / forwardCDPCommand / forwardCDPEvent / ping-pong).
Inert for now — not wired. Next: an abs-daemon relay that speaks this envelope
and bridges it to the existing CdpClient (raw CDP), then a `connect` command.