Skip to content

Commit a3487ef

Browse files
authored
Merge pull request #34 from browser-use/sync/harness-59a166f
sync: harness 59a166f
2 parents b5f890a + c8d2c2f commit a3487ef

20 files changed

Lines changed: 718 additions & 272 deletions

File tree

UPSTREAM.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Each upstream has its own append-only table. Add a row every time you pull.
9292
| 2026-04-29 | `2125cea` | `997ee45` | bcode | 6 upstream commits (PRs #241, #244, #245). `src/browser_harness/_ipc.py`: when `BH_TMP_DIR` is set, drop the `bu-<NAME>` filename prefix (caller-isolated dir means no shared-tmpdir disambiguation needed); without `BH_TMP_DIR` the original `bu-<NAME>` scheme is unchanged. `src/browser_harness/admin.py`: `_daemon_endpoint_names` short-circuits to the local NAME when `BH_TMP_DIR` is set (no glob); plus catch `SystemError` from `os.kill` on Windows during `restart_daemon`. `src/browser_harness/daemon.py`: discover DevToolsActivePort in Comet and Arc profiles on macOS. `tests/unit/test_admin.py`: 2 new tests for the `BH_TMP_DIR` discovery path. All in protected `src/browser_harness/*.py` + tests — taken verbatim. Smoke test + 12 admin unit tests pass. The `_ipc` filename change pairs with our recent per-session BH_TMP_DIR work (browsercode PR #22) — caller isolation now extends to filenames as well as the dir. Divergences touched: none. |
9393
| 2026-04-30 | `997ee45` | `660827d` | bcode | 11 upstream commits (PRs #246, #247, #251, #254, #256, #260). `src/browser_harness/daemon.py`: resolve WS via `/json/version` to avoid stale `DevToolsActivePort` path (PR #260) + report `cdp_disconnected` on stale CDP probe in `connection_status` (PR #254) + cleanup remote browser when daemon startup fails (PR #251). `src/browser_harness/admin.py`: companion changes for the daemon fixes. `tests/unit/test_admin.py`: 7 new tests. New domain skills: `agent-workspace/domain-skills/xiaohongshu/scraping.md` (PR #246), and a top-level `domain-skills/shopify-admin/` tree (PR #247: README, embedded-apps, knowledge-base, polaris-inputs). Note: PR #247 added skills at the top-level `domain-skills/` path, not under `agent-workspace/domain-skills/` as the post-#229 layout would suggest — vendored verbatim to match upstream layout. Doc updates: README operator framing (PR #255), install.md heredoc → `-c` flag (PR #256), profile-sync.md same. All files outside divergences — taken verbatim. Smoke test + 19 admin unit tests pass. Divergences touched: none. |
9494
| 2026-05-01 | `660827d` | `013097a` | bcode | 8 upstream commits (PRs #261, #265, #266). `src/browser_harness/daemon.py` (PR #265): split `DevToolsActivePort` into port + ws-path lines and fall back to `ws://127.0.0.1:<port><ws_path>` when `/json/version` returns 404 (Chrome 147+ disables `/json/*` HTTP discovery on the default user-data-dir). `src/browser_harness/run.py` (PR #266): when no daemon is alive, no local Chrome is listening on 9222/9223 (probed via `/json/version`, not bare TCP), and `BROWSER_USE_API_KEY` is set, auto-bootstrap a cloud daemon. `tests/unit/test_run.py`: 2 new tests for the cloud bootstrap path. PR #261 moved `domain-skills/shopify-admin/` → `agent-workspace/domain-skills/shopify-admin/` upstream — both paths are excluded from the vendored tree per §3, so this rename is a no-op for browsercode (`script/check-harness-diff.sh` filters both via `IGNORED_PATHS_REGEX`). All in protected `src/browser_harness/*.py` + tests — taken verbatim. Smoke test + 23 unit tests pass. Divergences touched: none. |
95+
| 2026-05-03 | `013097a` | `59a166f` | bcode | 62 upstream commits. **Helper additions** (PRs #258, #279): `helpers.py` adds `fill_input` (raises on missing element, optional timeout for SPA rendering, dispatches select-all without char event so Cmd/Ctrl+A fires on macOS), `wait_for_element` (prefers `checkVisibility`, falls back to computed style), `wait_for_network_idle`. `tests/unit/test_helpers.py`: +253 lines covering the new helpers. `daemon.py`: discover Dia browser profile on macOS. **Windows IPC hardening** (PR #276): `_ipc.py` adds ping handshake, token auth, atomic port file. **Domain-skills opt-in** (PR #274): `helpers.py` gates auto-injected domain skills behind `BH_DOMAIN_SKILLS=1` (default off). Aligns upstream default with browsercode's exclusion policy — no behavior change for us, but the `BH_DOMAIN_SKILLS` env name is now the canonical knob if we ever decide to ship a curated set. **Cloud bootstrap opt-in** (PR #277): `run.py` makes cloud auto-bootstrap opt-in via `BU_AUTOSPAWN` instead of triggering on any `BROWSER_USE_API_KEY` presence. Plus admin tweaks (`tests/unit/test_admin.py` +10 lines), doc canonicalization (`README.md`, `SKILL.md`, `install.md`, `interaction-skills/profile-sync.md` PR #280), and new top-level scaffolding: `AGENTS.md` (repo orientation for coding agents), `.github/ISSUE_TEMPLATE/{bug-report,feature-request,config}.yml`, `.github/VOUCHED.td`, `docs/allow-remote-debugging.png`. All non-excluded paths taken verbatim. **Excluded paths** (per §3): 14 new domain-skills directories added upstream (aa, alaska, articulate-rise, bigbang-hr, bilibili, BOSS-zhipin, claude-ai, ctrip, flipkart, ly-com, manus, perplexity, wehotel, plus amazon under top-level `domain-skills/`) — skipped. **Divergence update**: `.gitignore` now also includes upstream's new `.idea/` and `.claude/` entries while preserving our `.venv/`. Smoke test (imports + `--version`) clean. Divergences touched: `.gitignore` (extended, same intent). |
9596

9697
---
9798

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Bug report
2+
description: Report a reproducible bug in browser-harness.
3+
labels: [bug]
4+
body:
5+
- type: checkboxes
6+
id: preflight
7+
attributes:
8+
label: Before submitting
9+
options:
10+
- label: I searched existing issues for duplicates.
11+
required: true
12+
- label: I ran `browser-harness --doctor` and read the output.
13+
required: true
14+
- label: I read the troubleshooting section of `install.md`.
15+
required: true
16+
- label: This is a reproducible bug in browser-harness — not a question, feature request, or `cloud.browser-use.com` issue.
17+
required: true
18+
19+
- type: textarea
20+
id: summary
21+
attributes:
22+
label: Summary
23+
description: What's broken, in one or two sentences.
24+
validations:
25+
required: true
26+
27+
- type: textarea
28+
id: repro
29+
attributes:
30+
label: Repro
31+
description: Numbered steps. Include the exact command and the output you saw.
32+
placeholder: |
33+
1. Chrome 147 on default profile, remote debugging on
34+
2. browser-harness -c 'print(page_info())'
35+
3. RuntimeError: DevTools is not live yet on 127.0.0.1:9222
36+
validations:
37+
required: true
38+
39+
- type: textarea
40+
id: environment
41+
attributes:
42+
label: Environment
43+
placeholder: |
44+
OS:
45+
Chrome version:
46+
browser-harness --version:
47+
browser-harness --doctor output:
48+
validations:
49+
required: true
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Question or how-to
4+
url: https://github.com/browser-use/browser-harness/discussions/categories/q-a
5+
about: Ask in Discussions Q&A, not Issues.
6+
- name: Install or setup troubleshooting
7+
url: https://github.com/browser-use/browser-harness/blob/main/install.md
8+
about: Most install and "DevTools not live" errors are covered here.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Feature request
2+
description: Propose a new feature or change.
3+
labels: [feature-request]
4+
body:
5+
- type: checkboxes
6+
id: preflight
7+
attributes:
8+
label: Before submitting
9+
options:
10+
- label: I searched existing issues and discussions.
11+
required: true
12+
- label: This is a feature request, not a bug.
13+
required: true
14+
15+
- type: textarea
16+
id: problem
17+
attributes:
18+
label: Problem
19+
description: What user pain or limitation motivates this?
20+
validations:
21+
required: true
22+
23+
- type: textarea
24+
id: proposal
25+
attributes:
26+
label: Proposal
27+
description: What you'd like to happen.
28+
validations:
29+
required: true
30+
31+
- type: textarea
32+
id: alternatives
33+
attributes:
34+
label: Alternatives considered
35+
description: What else you tried, or why other approaches fall short.
36+
validations:
37+
required: true
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Vouched (or denounced) users for browser-harness.
2+
#
3+
# See https://github.com/mitchellh/vouch for details.
4+
#
5+
# Syntax:
6+
# - One handle per line (without @), sorted alphabetically.
7+
# - Optional platform prefix: platform:username (e.g., github:user).
8+
# - Denounce by prefixing with minus: -username
9+
# - Optional reason after a space following the handle.
10+
11+
molesza
12+
rohitdutt108
13+
shaunandrewjackson1977

packages/bcode-browser/harness/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ __pycache__/
55
.venv/
66
uv.lock
77
*.egg-info/
8+
.idea/
9+
.claude/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
browser-harness is a thin layer that connects agents to browsers via an editable CDP harness.
2+
3+
# Code priorities
4+
- Clarity
5+
- Precision
6+
- Low verbosity
7+
- Versatility
8+
9+
# Overview
10+
Core code lives in `src/browser_harness/`:
11+
- `admin.py` — daemon lifecycle, diagnostics, updates, profile management
12+
- `daemon.py` — the long-lived middleman process between the browser and the agent
13+
- `helpers.py` — CDP wrapper and core browser primitives auto-imported into `-c` scripts
14+
- `run.py` — the `browser-harness` CLI
15+
16+
`SKILL.md` tells agents how to use the harness and CLI.
17+
`install.md` tells agents how to install it, attach a browser, and troubleshoot.
18+
19+
An agent operating the harness only edits inside `agent-workspace/`:
20+
- `agent_helpers.py` — task-specific browser helpers the agent adds
21+
- `domain-skills/` — skills the agent writes and reads
22+
23+
# Contributing
24+
Consider what is really needed. Prefer the smallest diff that fixes the bug.

packages/bcode-browser/harness/README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,28 @@ Paste into Claude Code or Codex:
2525
```text
2626
Set up https://github.com/browser-use/browser-harness for me.
2727
28-
Read `install.md` first to install and connect this repo to my real browser. Then read `SKILL.md` for normal usage. Use `agent-workspace/agent_helpers.py` and `agent-workspace/domain-skills/` for task-specific edits. When you open a setup or verification tab, activate it so I can see the active browser tab. After it is installed, open this repository in my browser and, if I am logged in to GitHub, ask me whether you should star it for me as a quick demo that the interaction works — only click the star if I say yes. If I am not logged in, just go to browser-use.com.
28+
Read `install.md` and follow the steps to install browser-harness and connect it to my browser.
2929
```
3030

31-
When this page appears, tick the checkbox so the agent can connect to your browser:
31+
The agent will open `chrome://inspect/#remote-debugging`. Tick the checkbox so the agent can connect to your browser:
3232

3333
<img src="docs/setup-remote-debugging.png" alt="Remote debugging setup" width="520" style="border-radius: 12px;" />
3434

35+
Click Allow when the per-attach popup appears (Chrome 144+):
36+
37+
<img src="docs/allow-remote-debugging.png" alt="Allow remote debugging popup" width="520" style="border-radius: 12px;" />
38+
3539
See [agent-workspace/domain-skills/](agent-workspace/domain-skills/) for example tasks.
3640

37-
## Free remote browsers
41+
## Free Browser Use Cloud browsers
3842

39-
Useful for stealth, sub-agents, or deployment.<br>
40-
**Free tier: 3 concurrent browsers, proxies, captcha solving, and more. No card required.**
43+
Stealth, sub-agents, or headless deployment.<br>
44+
**Browser Use Cloud free tier: 3 concurrent browsers, proxies, captcha solving, and more. No card required.**
4145

4246
- Grab a key at [cloud.browser-use.com/new-api-key](https://cloud.browser-use.com/new-api-key)
4347
- Or let the agent sign up itself via [docs.browser-use.com/llms.txt](https://docs.browser-use.com/llms.txt) (setup flow + challenge context included).
4448

45-
## How simple is it? (~592 lines of Python)
49+
## Architecture (~1k lines across 4 core files)
4650

4751
- `install.md` — first-time install and browser bootstrap
4852
- `SKILL.md` — day-to-day usage
@@ -61,6 +65,10 @@ PRs and improvements welcome. The best way to help: **contribute a new domain sk
6165

6266
If you're not sure where to start, open an issue and we'll point you somewhere useful.
6367

68+
## Domain skills
69+
70+
Set `BH_DOMAIN_SKILLS=1` to enable [agent-workspace/domain-skills/](agent-workspace/domain-skills/) — community-contributed per-site playbooks `goto_url` surfaces by domain. Contribute via PR.
71+
6472
---
6573

6674
[The Bitter Lesson of Agent Harnesses](https://browser-use.com/posts/bitter-lesson-agent-harnesses) · [Web Agents That Actually Learn](https://browser-use.com/posts/web-agents-that-actually-learn)

packages/bcode-browser/harness/SKILL.md

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ description: Direct browser control via CDP. Use when the user wants to automate
55

66
# browser-harness
77

8-
Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py` and `agent-workspace/domain-skills/`. For setup, install, or connection problems, read install.md.
8+
Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py`. For setup, install, or connection problems, read install.md.
9+
10+
Domain skills (community-contributed per-site playbooks under `agent-workspace/domain-skills/`) are off by default. Set `BH_DOMAIN_SKILLS=1` to enable them; see the bottom section.
911

1012
## Usage
1113

@@ -20,13 +22,6 @@ print(page_info())
2022
- Invoke as browser-harness — it's on $PATH. No cd, no uv run.
2123
- First navigation is new_tab(url), not goto_url(url) — goto runs in the user's active tab and clobbers their work.
2224

23-
Available interaction skills:
24-
- interaction-skills/connection.md — startup sequence, tab visibility, omnibox popup fix
25-
26-
Available domain skills:
27-
- tiktok/upload.md
28-
- polymarket/scraping.md
29-
3025
## Tool call shape
3126

3227
```bash
@@ -60,11 +55,10 @@ start_remote_daemon prints liveUrl and auto-opens it in the local browser (if a
6055

6156
Profiles (cookies-only login state) live in interaction-skills/profile-sync.md — covers list_cloud_profiles(), the chat-driven "which profile?" pattern, and sync_local_profile() for uploading a local Chrome profile.
6257

63-
## Search first
58+
## Interaction skills
6459

65-
Search `agent-workspace/domain-skills/` first for the domain you are working on before inventing a new approach.
66-
67-
Only if you start struggling with a specific mechanic while navigating, look in interaction-skills/ for helpers. The available interaction skills are:
60+
If you start struggling with a specific mechanic while navigating, look in interaction-skills/ for helpers. They cover reusable UI mechanics like dialogs, tabs, dropdowns, iframes, and uploads. The available interaction skills are:
61+
- connection.md
6862
- cookies.md
6963
- cross-origin-iframes.md
7064
- dialogs.md
@@ -82,44 +76,6 @@ Only if you start struggling with a specific mechanic while navigating, look in
8276
- uploads.md
8377
- viewport.md
8478

85-
Useful commands:
86-
87-
```bash
88-
rg --files agent-workspace/domain-skills
89-
rg -n "tiktok|upload" agent-workspace/domain-skills
90-
```
91-
92-
## Always contribute back
93-
94-
If you learned anything non-obvious about how a site works, open a PR to `agent-workspace/domain-skills/<site>/` before you finish. Default to contributing. The harness gets better only because agents file what they learn. If figuring something out cost you a few steps, the next run should not pay the same tax.
95-
96-
Examples of what's worth a PR:
97-
98-
- A private API the page calls (XHR/fetch endpoint, request shape, auth) — often 10× faster than DOM scraping.
99-
- A stable selector that beats the obvious one, or an obfuscated CSS-module class to avoid.
100-
- A framework quirk — "the dropdown is a React combobox that only commits on Escape", "this Vue list only renders rows inside its own scroll container, so scrollIntoView on the row doesn't work — you have to scroll the container".
101-
- A URL pattern — direct route, required query params (?lang=en, ?th=1), a variant that skips a loader.
102-
- A wait that wait_for_load() misses, with the reason.
103-
- A trap — stale drafts, legacy IDs that now return null, unicode quirks, beforeunload dialogs, CAPTCHA surfaces.
104-
105-
### What a domain skill should capture
106-
107-
The *durable* shape of the site — the map, not the diary. Focus on what the next agent on this site needs to know before it starts:
108-
109-
- URL patterns and query params.
110-
- Private APIs and their payload shape.
111-
- Stable selectors (data-*, aria-*, role, semantic classes).
112-
- Site structure — containers, items per page, framework, where state lives.
113-
- Framework/interaction quirks unique to this site.
114-
- Waits and the reasons they're needed.
115-
- Traps and the selectors that *don't* work.
116-
117-
### Do not write
118-
119-
- Raw pixel coordinates. They break on viewport, zoom, and layout changes. Describe how to *locate* the target (selector, scrollIntoView, aria-label, visible text) — never where it happened to be on your screen.
120-
- Run narration or step-by-step of the specific task you just did.
121-
- Secrets, cookies, session tokens, user-specific state. `agent-workspace/domain-skills/` is shared and public.
122-
12379
## What actually works
12480

12581
- Screenshots first: use capture_screenshot() to understand the current page quickly, find visible targets, and decide whether you need a click, a selector, or more navigation.
@@ -155,7 +111,10 @@ The *durable* shape of the site — the map, not the diary. Focus on what the ne
155111
- Prefer compositor-level actions over framework hacks. Try screenshots, coordinate clicks, and raw key input before adding DOM-specific workarounds.
156112
- If you need framework-specific DOM tricks, check interaction-skills/ first. That is where dropdown, dialog, iframe, shadow DOM, and form-specific guidance belongs.
157113

158-
## Interaction notes
114+
## Domain skills (opt-in)
115+
116+
Only applies when `BH_DOMAIN_SKILLS=1`. Otherwise ignore — `agent-workspace/domain-skills/` is dormant and `goto_url` won't surface skill files.
117+
118+
When enabled, search `agent-workspace/domain-skills/<host>/` before inventing an approach. `goto_url` returns up to 10 skill filenames for the navigated host.
159119

160-
- interaction-skills/ holds reusable UI mechanics such as dialogs, tabs, dropdowns, iframes, and uploads.
161-
- `agent-workspace/domain-skills/` holds site-specific workflows and should be updated when you discover reusable patterns for a website.
120+
If you learn anything non-obvious — a private API, stable selector, framework quirk, URL pattern, hidden wait, or site-specific trap — open a PR to `agent-workspace/domain-skills/<site>/`. Capture the durable shape of the site (the map, not the diary). Don't write pixel coordinates (break on layout), task narration, or secrets — the directory is public.
188 KB
Loading

0 commit comments

Comments
 (0)