Cross-checked AGENTS.md, README.md, SKILL.md, install.md, and profile-sync.md for accuracy. Tightened the sync_local_profile docstring and the chrome://inspect stderr message to match. Cloud-bootstrap test updated to set BU_AUTOSPAWN. All unit tests pass.
Domain skills auto-injected by goto_url() are community-contributed and quality varies; defaulting them off avoids polluting the average run while preserving the contribution loop. Set BH_DOMAIN_SKILLS=1 to opt in.
Rebased from #170 (authored by @mvanhorn) onto current main.
The original branch was based on a stale README; only the two
intentional lines from that PR are reapplied here.
* refactor(tests): reorganize into tests/unit and tests/integration
Moves all root-level test_*.py files into a structured tests/ directory:
- tests/unit/ — admin, helpers (was test_screenshot), run
- tests/integration/ — js expression tests
- tests/conftest.py — shared fake_png pytest fixture, eliminating duplication
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: move to src layout, agent-workspace, and fix SKILL.md invocation format
- Move package to src/browser_harness/ and domain-skills/interaction-skills to agent-workspace/
- Fix all browser-harness <<'PY' heredoc examples in SKILL.md and run.py HELP string to use the correct -c '...' flag format (heredoc was never supported by the CLI)
- Update SKILL.md path references from domain-skills/ to agent-workspace/domain-skills/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: suggest starring the repo, don't auto-star it
The verification task at the end of install was for the agent to
directly star the harness repo if the user was logged in to GitHub.
That conflates "verify the harness is attached" with "make a social
action on behalf of the user" — the latter shouldn't happen
without explicit user intent.
Reword install.md step 8 and the README setup prompt + example task
so the agent navigates to the repo (still verifies attach + activates
the tab so the user can see it) and *suggests* starring if the user
likes the project, instead of clicking the star itself.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: agent should ask permission, not redirect star action to user
Previous wording told the agent "suggest the user star it themselves;
don't click yourself." That dropped the agent's role in the demo
entirely. The intent is the opposite: the *agent* should offer to
star the repo for the user (as a live demo that the harness can
interact with the page), and only do it if the user agrees.
Also drop the "Example task: ..." tagline from README — point to
domain-skills/ for examples instead.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- rename "example prompt" → "setup prompt"; coding agent handles clone,
uv sync, opens chrome://inspect on macOS, walks user through the
allow-debugging checkbox, verifies connection, navigates to the repo,
then offers the first task (star the repo)
- setup prompt explicitly tells the agent to read SKILL.md end-to-end first
- add Features section: raw CDP + editable helpers, Browser Use cloud
for parallel sub-agents (each gets its own live URL), iframe/shadow
passthrough, http_get bulk fallback
- how-it-works now shows line counts (~580 total) to show how small it is
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* add remote browser support via Browser Use cloud + multi-daemon
HARNESLESS_NAME suffixes socket/pid/log — daemons are independent, no
supervisor. start_remote_daemon() creates a Browser Use cloud browser and
launches a daemon attached to it; kill_daemon() stops both. Local Chrome
path is unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* rename env vars to BU_ prefix (shorter, less noisy in tool calls)
HARNESLESS_NAME → BU_NAME
HARNESLESS_CDP_WS → BU_CDP_WS
HARNESLESS_REMOTE_BROWSER_ID → BU_BROWSER_ID
Socket/pid/log files keep the harnesless- prefix on disk so they're
recognizable in /tmp. BROWSER_USE_API_KEY unchanged (external convention).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* rename project from harnesless to bu
Socket/pid/log paths now /tmp/bu-<name>.{sock,pid,log}. pyproject package
name updated, uv.lock regenerated. Slash command now /bu.
Note: the repo directory itself is still named harnesless on disk. Rename
manually (mv harnesless bu) so the absolute paths in docs line up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>