项目文件夹
Two related issues that have shown up across recent PRs: 1. press_key always emitted a `char` event after every single-char keyDown, regardless of modifiers. With Ctrl/Cmd held, that `char` makes Chrome treat the press as printable text input (typing "a") instead of firing the shortcut (Cmd+A). PR #258 worked around this inside fill_input by dispatching the select-all directly via raw CDP calls, but every other shortcut was still broken. 2. The keyDown's `code` and `windowsVirtualKeyCode` for letters/digits came from a literal-key fallback (code="a", vk=ord("a")=97). CDP's shortcut handlers compare against canonical physical-key codes — "KeyA" / 65 for the A key, "Digit5" / 53 for the 5 key. Without that, e.code in JS is wrong and shortcut listeners that check `e.code === "KeyA"` (a common pattern) do not fire. Fix at source so every shortcut works for any caller: - Added _key_metadata(key) which returns the canonical (vk, code, text) for letters (Key{X}, ord(upper)), digits (Digit{N}, ord(N)), and the pre-existing special-key table. Punctuation/symbols fall back to ASCII vk + literal code. - press_key suppresses both `text` on keyDown and the entire `char` event when any of Alt/Ctrl/Meta is set (modifier bits 0b0111). Shift alone is still text input. - fill_input's clear path now just calls press_key("a", modifiers=...) instead of dispatching directly via cdp; the helper does the right thing now. 10 new tests in tests/unit/test_helpers.py cover: - canonical code/vk for letters (KeyA/65, KeyZ/90) and digits (Digit5/53) - Enter/Backspace/etc still use the _KEYS table - no-modifier press emits text + char - Ctrl / Meta / Alt each suppress text + char - Shift alone keeps text + char - Ctrl+Shift combo suppresses (modifier wins over Shift) - keyUp metadata is consistent Identified via codex review (P1). Full suite: 93 passed (83 -> 93).
Browser Harness ♞
Connect an LLM directly to your real browser with a thin, editable CDP harness. For browser tasks where you need complete freedom.
One websocket to Chrome, nothing between. The agent writes what's missing during execution. The harness improves itself every run.
● agent: wants to upload a file
│
● agent-workspace/agent_helpers.py → helper missing
│
● agent writes it agent_helpers.py
│ + custom helper
✓ file uploaded
You will never use the browser again.
Setup prompt
Paste into Claude Code or Codex:
Set up https://github.com/browser-use/browser-harness for me.
Read `install.md` and follow the steps to install browser-harness and connect it to my browser.
The agent will open chrome://inspect/#remote-debugging. Tick the checkbox so the agent can connect to your browser:
Click Allow when the per-attach popup appears (Chrome 144+):
See agent-workspace/domain-skills/ for example tasks.
Free Browser Use Cloud browsers
Stealth, sub-agents, or headless deployment.
Browser Use Cloud free tier: 3 concurrent browsers, proxies, captcha solving, and more. No card required.
- Grab a key at cloud.browser-use.com/new-api-key
- Or let the agent sign up itself via docs.browser-use.com/llms.txt (setup flow + challenge context included).
Architecture (~1k lines across 4 core files)
install.md— first-time install and browser bootstrapSKILL.md— day-to-day usagesrc/browser_harness/— protected core packageagent-workspace/agent_helpers.py— helper code the agent editsagent-workspace/domain-skills/— reusable site-specific skills the agent edits
Contributing
PRs and improvements welcome. The best way to help: contribute a new domain skill under agent-workspace/domain-skills/ for a site or task you use often (LinkedIn outreach, ordering on Amazon, filing expenses, etc.). Each skill teaches the agent the selectors, flows, and edge cases it would otherwise have to rediscover.
- Skills are written by the harness, not by you. Just run your task with the agent — when it figures something non-obvious out, it files the skill itself (see SKILL.md). Please don't hand-author skill files; agent-generated ones reflect what actually works in the browser.
- Open a PR with the generated
agent-workspace/domain-skills/<site>/folder — small and focused is great. - Bug fixes, docs tweaks, and helper improvements are equally welcome.
- Browse existing skills (
github/,linkedin/,amazon/, ...) to see the shape.
If you're not sure where to start, open an issue and we'll point you somewhere useful.
Domain skills
Set BH_DOMAIN_SKILLS=1 to enable agent-workspace/domain-skills/ — community-contributed per-site playbooks goto_url surfaces by domain. Contribute via PR.
The Bitter Lesson of Agent Harnesses · Web Agents That Actually Learn