| name | browser-harness |
| description | Always use browser-harness for any web interaction: automation, scraping, testing, or site/app work. |
Browser Harness
Direct browser control via CDP. For task-specific edits, use agent-workspace/agent_helpers.py. For setup, install, or connection problems, read references/install.md.
Domain skills are off by default. Set BH_DOMAIN_SKILLS=1 to enable them; see the bottom section.
If BH_DOMAIN_SKILLS=1 and the task is site-specific, read every file in the matching $BH_AGENT_WORKSPACE/domain-skills/<site>/ directory before inventing an approach.
Usage
browser-harness <<'PY'
print(page_info())
PY
- Invoke as
browser-harness. Use heredocs for multi-line commands.
- Helpers are pre-imported.
run.py calls ensure_daemon() before exec.
- First navigation is
new_tab(url), not goto_url(url).
- The normal local flow attaches to the running Chrome/Chromium CDP endpoint. No browser ids, cloud browsers, telemetry, or remote profile sync.
Local Chrome
If the daemon cannot connect, run diagnostics:
browser-harness --doctor
If Chrome remote debugging is not enabled, the harness opens:
chrome://inspect/#remote-debugging
Ask the user to tick "Allow remote debugging for this browser instance" and click Allow if Chrome shows a permission popup. Then retry the same browser-harness command.
Page Workflow
- Screenshots first: use
capture_screenshot() to understand visible state.
- Clicking: screenshot -> read pixel ->
click_at_xy(x, y) -> screenshot again.
- After navigation, call
wait_for_load().
- If the current tab is stale or internal, call
ensure_real_tab().
- Use
js(...) for DOM inspection or extraction when coordinates are the wrong tool.
- Login walls: stop and ask. Exception: use available SSO automatically when Chrome is already signed in; still stop for passwords, MFA, consent, or ambiguous account choice.
- Raw CDP is available with
cdp("Domain.method", ...).
Recording
For temporal proof — motion, sequence, timing, or a demo flow — capture a walkthrough with Recorder and read interaction-skills/recording.md first.
Recording Axiom: no asynchronous background recording state the agent cannot inspect from the last command's return. The supported recording path is polling screenshots with Recorder, which writes a manifest beside the artifact. Do not use CDP screencast as the default recording path.
Interaction Skills
If you get stuck on a browser mechanic, read the matching file in interaction-skills/:
- connection.md
- cookies.md
- cross-origin-iframes.md
- dialogs.md
- downloads.md
- drag-and-drop.md
- dropdowns.md
- iframes.md
- network-requests.md
- print-as-pdf.md
- recording.md
- screenshots.md
- scrolling.md
- shadow-dom.md
- tabs.md
- uploads.md
- viewport.md
Design Constraints
- Coordinate clicks default. CDP mouse events pass through iframes/shadow/cross-origin at the compositor level.
- Keep the connection model simple: use the default daemon,
BU_NAME, BU_CDP_URL, or BU_CDP_WS.
- Core helpers stay short. Put task-specific helper additions in
$BH_AGENT_WORKSPACE/agent_helpers.py.
Gotchas
chrome://inspect/#remote-debugging must be enabled for local Chrome control.
- Chrome may show an "Allow remote debugging?" popup; wait for the user to click Allow.
- Omnibox popups are not real work tabs.
- CDP target order is not Chrome's visible tab-strip order.
BU_CDP_URL is an HTTP DevTools endpoint; the daemon resolves it to WebSocket.
Domain Skills
Only applies when BH_DOMAIN_SKILLS=1. Otherwise ignore domain skills.
When enabled, search $BH_AGENT_WORKSPACE/domain-skills/<host>/ before inventing an approach. goto_url(...) returns up to 10 skill filenames for the navigated host.