This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
chrome-cdp is a Go CLI that drives the user's already-running local Chrome over the DevTools Protocol (via chromedp).
It reuses the live session's logins and cookies, and speaks one JSON envelope + one stable exit-code contract to both humans and AI agents.
Read the resource file that matches your task before making changes:
- Architecture — the envelope/exit-code contract, the
internal/package map, thechrome.Browserseam, and the connection/daemon model. Read this before touching anything cross-cutting. - Development — build, test (
go test -shortto skip live Chrome), lint, what CI runs, and release. - Test-writing guidelines — how tests are structured here (stub-driven unit tests,
testing.Short()-guarded live-Chrome tests) and which conventions are adopted vs. deviated from. - Implementing an RFC — the seven places a new browser capability has to touch (including the daemon RPC, which compiles fine when you forget it and then fails for every real user), and the traps specific to this codebase.
Read before implementing anything in
docs/rfc/.
- The result envelope is public API.
Every command emits one
result.Envelope; both humans and the Claude skill parse it. A new failure mode needs aCode*constant and acodeToExitentry, or it silently degrades toExitGeneric. Never let human-formatting changes alter the JSON shape. Validate usage/args before connecting to Chrome. - The CLI never connects to Chrome directly.
cli.Appholds function seams (WithConnector,WithStickyTarget,WithDaemonCtl) thatcmd/chrome-cdp/main.gowires to the daemon. To add a browser capability: extend thechrome.Browserinterface → add a default inchrometest.StubBrowser(one place) → implement ininternal/chrome→ wire both halves of the daemon RPC (aremoteBrowserforwarder and adispatchcase ininternal/daemon/daemon.go) → add the matchingboundBrowserforwarder ininternal/mcp/bind.go. Skip the daemon step and the method compiles, passes every stub-backed test, and then fails for every real user — the daemon is the default path.TestDispatchCoversBrowserguards it, andTestBoundBrowserBindsEveryMethodguards thebind.gostep the same way.
User-facing docs live in docs/ and README.md; the Agent Skills live in skills/ (drive-chrome-cdp is the core one; chrome-cdp skill serves it from the binary).
When editing any markdown, follow the repo style: one sentence per line.
Push branches and let the user open PRs unless asked otherwise.