提交

提交图

379 次代码提交

作者 SHA1 备注 提交日期
mathisdittrich 1599ba1951 Revert "Stage file uploads for remote browsers" 2026-05-15 00:17:53 -07:00
mathisdittrich 27ca67fd49 Merge pull request #365 from browser-use/revert-363-add-llms-browser-use-box-link
Revert "Add LLM discovery file"
2026-05-14 23:43:59 -07:00
mathisdittrich 93ce332934 Revert "Add LLM discovery file" 2026-05-14 23:42:52 -07:00
mathisdittrich b664e58d83 Merge pull request #364 from browser-use/revert-358-promote-browser-use-box-demo
Revert "Link Browser Use Box deployment demo"
2026-05-14 23:42:23 -07:00
mathisdittrich 87fe826b5e Revert "Link Browser Use Box deployment demo" 2026-05-14 23:40:46 -07:00
shawn pana d0cef34b42 Merge pull request #363 from browser-use/add-llms-browser-use-box-link
Add LLM discovery file
2026-05-15 01:36:49 -04:00
shawn pana f2dca2bc0c Add LLM discovery file 2026-05-15 05:35:01 +00:00
shawn pana caebe67fc7 Merge pull request #358 from ShawnPana/promote-browser-use-box-demo
Link Browser Use Box deployment demo
2026-05-14 20:04:58 -04:00
bux bdd550b9be Link Browser Use Box deployment demo 2026-05-15 00:03:46 +00:00
shawn pana e87f8b7b4f Merge pull request #357 from browser-use/fix-cloud-file-upload
Stage file uploads for remote browsers
2026-05-14 15:24:40 -04:00
shawn pana f226972302 Stage file uploads for remote browsers 2026-05-14 19:14:44 +00:00
Saurav Panda 2f22ed6709 Merge pull request #344 from claytonlin1110/feat/doctor-snap-chromium-detect
feat: warn on Snap Chromium and add doctor --fix-snap guide
2026-05-13 15:44:17 -07:00
Saurav Panda 21c94e342c Fix Snap Chromium symlink detection 2026-05-13 15:40:27 -07:00
Clayton a6957b8a5f feat: warn on Snap Chromium and add doctor --fix-snap guide 2026-05-12 07:45:42 -05:00
Sarath S Menon f186cd963d Merge pull request #343 from browser-use/remove-c-stdin-cli
Remove -c script execution
2026-05-12 15:37:11 +05:30
Sarath Suresh a9f7b1d547 Remove -c script execution 2026-05-12 15:35:12 +05:30
Saurav Panda 0e679e2c56 Merge pull request #306 from kunghim/add-weread-skills
add weread domain skill
2026-05-07 20:49:41 -07:00
Alexander Yue 2106221dc4 Merge pull request #322 from browser-use/feat/horse-tab-marker
feat: use 🐴 (horse) instead of 🟢 as the controlled-tab marker
2026-05-07 13:20:57 -07:00
Alezander9 0d6e472c7c feat: use 🐴 (horse) instead of 🟢 as the controlled-tab marker
The green-circle prefix didn't fit the harness theme. Horse echoes the project name (browser-harness) and pairs naturally with chess-knight imagery.

Also fixes a latent slice bug: the prefix is 3 UTF-16 units (surrogate pair + space), so unmark uses slice(3) and removes the trailing space cleanly. The previous 🟢 + slice(2) left the space behind, which would slowly accumulate leading spaces across switch_tab cycles.
2026-05-07 13:04:40 -07:00
Alexander Yue 13769f4aba Merge pull request #312 from J3m5/fix/detect-helium-browser
Detect Helium as a local browser
2026-05-07 12:44:02 -07:00
Alexander Yue d4536580ec Merge pull request #320 from MinJaeLee1/docs/hermes-domain-skills-nudge
docs: nudge agents to read matching domain skills
2026-05-07 12:38:54 -07:00
Alexander Yue ecb66b0772 Merge pull request #321 from browser-use/fix/install-demo-no-star-prompt
install.md: drop star-the-repo prompt from first-run demo
2026-05-07 12:38:19 -07:00
Magnus Müller 32be32fa66 install.md: drop star-the-repo prompt from first-run demo
Several users flagged that the install.md demo prompts the agent to ask
whether to star browser-harness on their behalf, which reads as star-farming.
Drop the star ask entirely — the demo still opens the repo page so the user
can see the harness has attached, but no longer solicits a star.
2026-05-07 16:49:14 +00:00
MinJaeLee1 226876d56e docs: nudge agents to read matching domain skills 2026-05-07 21:16:03 +09:00
Alexander Yue 32d8d515ed Merge pull request #318 from browser-use/feat/runtime-dir-split
feat(ipc): split BH_RUNTIME_DIR (sock) from BH_TMP_DIR (logs/screenshots)
2026-05-06 14:55:20 -07:00
Alezander9 6e86f7cf2b feat(ipc): split BH_RUNTIME_DIR (sock) from BH_TMP_DIR (logs/screenshots)
A single BH_TMP_DIR conflated two storage concerns with opposite
constraints: sock/port/pid files are bound by AF_UNIX sun_path (104
bytes on macOS, 108 on Linux) and must live in a short path; log files
and screenshots have no length limit and benefit from a deep, indexable,
persistent location. Forcing both into one dir means callers either
bury screenshots under /tmp or risk silently overrunning sun_path.

Decouple with a new BH_RUNTIME_DIR for sock/port/pid. BH_TMP_DIR keeps
log/screenshot duty. BH_RUNTIME_DIR falls back to BH_TMP_DIR, then to
/tmp on POSIX or tempfile.gettempdir() on Windows, so single-dir callers
keep working unchanged.
2026-05-06 14:37:03 -07:00
Alexander Yue 5acfe37cf8 Merge pull request #305 from hunnyboy1217/fix/current-tab-missing-target-id
current_tab: resolve attached target_id server-side via daemon meta
2026-05-06 10:44:07 -07:00
J3m5 16925613bf fix: detect Helium as a local browser 2026-05-06 11:26:21 +02:00
Alexander Yue bc186db66d Merge pull request #310 from browser-use/Alezander9-patch-2
Update VOUCHED.td
2026-05-06 01:31:35 -07:00
Alexander Yue 8ee028d828 Update VOUCHED.td 2026-05-06 01:31:23 -07:00
Alexander Yue e8a11879a7 Merge pull request #309 from browser-use/fix/ipc-socket-umask
fix(ipc): set umask 0077 around AF_UNIX bind to avoid chmod TOCTOU
2026-05-06 01:27:31 -07:00
Alezander9 8dc728598e fix(ipc): set umask 0077 around AF_UNIX bind to avoid chmod TOCTOU
Previously start_unix_server() would bind() and listen() with mode
derived from the process umask before os.chmod(0o600) ran, leaving a
brief window where the socket's mode reflected umask. Setting umask
0o077 around the bind makes the socket land at 0600 directly, removing
the window.

Refs #298
2026-05-05 23:54:47 -07:00
Alexander Yue 455fc04ccc Merge pull request #308 from browser-use/Alezander9-patch-1
Update VOUCHED.td
2026-05-05 23:40:00 -07:00
Alexander Yue a248e2115d Update VOUCHED.td 2026-05-05 23:39:42 -07:00
Alexander Yue 45182147b9 Merge pull request #263 from femto/add-chrome-canary-support
daemon: add Chrome Canary profile discovery
2026-05-05 23:36:52 -07:00
home 4339d5a37c add weread domain skill 2026-05-06 03:44:22 +08:00
Saurav Panda 30d54b7216 Merge pull request #303 from song-swivel/song-swivel-patch-1
Undo #302
2026-05-05 12:07:28 -07:00
Hunnyboy1217 b766246def current_tab: resolve attached target_id server-side via daemon meta
Calling Target.getTargetInfo from helpers can't work: the daemon strips
session_id for any Target.* method, so the call hit the browser-level
connection with no targetId, and Chrome silently returned info about the
*browser* target (empty url/title) instead of the attached page. New
current_tab meta uses self.target_id like connection_status already does.
Fixes #304.
2026-05-05 15:07:01 -04:00
Song Du 1a1aa3175d Delete agent-workspace/domain-skills/mrm/analytics-reports.md
Remove
2026-05-05 14:37:08 -04:00
Saurav Panda 5b07dde532 Merge pull request #302 from song-swivel/domain-skill-freewheel-mrm
Add FreeWheel MRM analytics report skill
2026-05-05 11:33:13 -07:00
Saurav Panda 0c9597bfef Merge pull request #301 from ComBba/feat/domain-skills-browser-use-cloud
feat(domain-skills): add browser-use-cloud (REST + cleanup-zombies)
2026-05-05 10:38:23 -07:00
Saurav Panda 3de7fe07eb cleanup-zombies: also catch URLError so transient network failures don't abort the loop
A DNS/timeout/socket error during PATCH /browsers/{id} was bubbling out
of the loop, leaving remaining zombies running and still billing.
HTTPError is a subclass of URLError, so the existing clause stays first
and the URLError catch handles only the transport-level failures.
2026-05-05 10:35:26 -07:00
Saurav Panda 2b8a3a6348 Merge pull request #300 from ComBba/fix/run-respect-explicit-cdp-endpoint
fix(run): respect explicit CDP endpoint before cloud auto-bootstrap
2026-05-05 10:28:38 -07:00
Your Name 4b84df96c2 Add FreeWheel MRM analytics report skill 2026-05-05 12:22:28 -04:00
ComBba 84e7a2c0ae feat(domain-skills): add browser-use-cloud (REST + cleanup-zombies)
Adds an operator-facing skill for cloud.browser-use.com / api.browser-use.com,
covering the same REST surface that the harness's own admin.py already
uses (X-Browser-Use-API-Key header, /browsers, /profiles), plus a
companion script for the most common automation -- stopping zombie
sessions older than N minutes.

Live-tested on 2026-05-05 with a real BROWSER_USE_API_KEY:

  POST   /browsers              201 - shape verified incl. liveUrl on live.browser-use.com
  PATCH  /browsers/{id} stop    200 - returns final cost
  GET    /browsers              200 - paginated {items, totalItems, ...}
  GET    /profiles              200 - same envelope
  GET    /profiles/{id}         200 - cookieDomains=None on fresh profiles
  GET    /usage                 404 - no public endpoint, doc'd accordingly
  GET    /                      404 - no root metadata

The cleanup-zombies.py companion is the regression artefact; running it
in dry-run mode is the cheapest smoke test, and a full E2E loop
(spawn -> list -> stop -> re-list) was confirmed end-to-end during
authoring.

Notable wire gotchas surfaced and documented:

- Cost / proxy fields (proxyCost, browserCost, proxyUsedMb) are returned
  as JSON strings, not numbers; cast to float before arithmetic.
- liveUrl host is live.browser-use.com (different from cloud.browser-use.com),
  with the cdp WebSocket encoded as a ?wss= query parameter.
- cookieDomains can be null on a freshly-created profile despite
  list_cloud_profiles' docstring describing it as an array.
- GET /usage returns 404 -- per-session cost lives on each browser
  record; aggregate billing only on the dashboard.

Style follows the claude-ai/share-export (#267) pattern of
markdown-skill-with-companion-py, sized at 222 + 161 LOC. Discovery
under helpers.py:163's current logic would resolve cloud.browser-use.com
to "cloud/" rather than "browser-use-cloud/" -- the skill folder name
mirrors the convention used by claude-ai/, vercel/, and tasksquad-ai/
which are also not auto-discoverable today; PR #165 is the broader fix
for that.

Refs: PR #300 (run.py precedence fix in the same area), PR #267
(claude-ai companion-script pattern), PR #288 (vercel dashboard skill
header style).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 22:45:53 +09:00
ComBba 8dc337ff03 fix(run): respect explicit CDP endpoint before cloud auto-bootstrap
install.md:58-59 documents BU_CDP_URL / BU_CDP_WS as overrides for local
Chrome discovery, but run.py:87-92's auto-bootstrap guard never checked
either env var. With BU_CDP_URL set plus BROWSER_USE_API_KEY and
BU_AUTOSPAWN (commonly set together for unrelated reasons -- profile sync,
headless CI fallback, parent agents managing their own session), no daemon,
and no local Chrome on 9222/9223, the guard fires and start_remote_daemon()
provisions a billed cloud browser. admin.py:471 then calls
ensure_daemon(env={"BU_CDP_WS": _cdp_ws_from_url(browser["cdpUrl"]), ...}),
overwriting the user's explicit endpoint with the cloud WebSocket. Net:
surprise cloud bill plus silent endpoint replacement.

Add _explicit_cdp_configured() next to _local_chrome_listening() and gate
the auto-bootstrap with `not _explicit_cdp_configured()`. Mirrors the
existing _is_local_chrome_mode helper at admin.py:159-161 that already
treats BU_CDP_WS as the "not local discovery" signal. #277's
fresh-headless-box behaviour (no explicit endpoint set) is preserved.

Tests: 8 new unit tests in tests/unit/test_run.py covering URL/WS variants,
both-set, empty-string, daemon-alive and local-Chrome short-circuit
robustness, and direct helper input/output. tests/unit/ goes from 66 to 74,
all green. Without this patch, exactly 5 of the new tests fail (the ones
targeting the guard + helper); the 3 short-circuit/empty edge cases pass
even unpatched because existing guards already cover those paths.

Refs #266, #277, #292.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:50:25 +09:00
Saurav Panda 0f300e83e3 Merge pull request #296 from browser-use/fix/switch-tab-enable-all-domains
fix(daemon): set_session must enable all four default domains, not just Page
2026-05-04 19:03:15 -07:00
Saurav Panda 2a9c64548e set_session: run disable+enables in parallel; background cosmetic title prefix
codex flagged that set_session was now performing up to four sequential
domain enables (5s timeout each) plus a 2s Network.disable, so a slow
or remote daemon could block the synchronous IPC reply for ~22s while
the helper's _send() socket has only a 5s read timeout. Old code only
awaited Page.enable (3s) on this path.

Three changes to keep the reply under the IPC deadline:

1. _enable_default_domains now awaits asyncio.gather over the four
   Domain.enable coroutines instead of looping sequentially. Per-call
   timeout reduced from 5s to 4s. Worst case is bounded by a single
   CDP round trip rather than four.

2. set_session schedules the old-session Network.disable in the same
   gather as the four enables on the new session — independent CDP
   sessions, no ordering required for correctness (the consumer-side
   filter in wait_for_network_idle is the actual correctness gate).

3. The 🟢 tab-marker title-prefix Runtime.evaluate is now fire-and-forget
   via asyncio.create_task (+ _silent). It's purely cosmetic; agents
   shouldn't wait on it.

Worst-case set_session reply time: max(2s disable, 4s parallel enables)
≈ 4s, comfortably under the 5s IPC timeout. Normal case on a remote
daemon drops from ~800ms (4 sequential round trips) to ~200ms (1 round
trip in parallel).

Two new tests in tests/unit/test_daemon.py use a fake CDP whose
send_raw blocks on an asyncio.Event, then assert the peak in-flight
call count:
- with a previous session: peak == 5 (1 disable + 4 enables)
- first attach: peak == 4 (4 enables, disable skipped)
Sequential await would peak at 1 on both. Full suite: 65 passed.
2026-05-04 18:48:36 -07:00
Saurav Panda 45b75e62c4 wait_for_network_idle: filter by session_id; set_session: disable old Network
codex flagged a P2 follow-on to the just-added Network.enable: my fix
reliably enables Network on every fresh session, but old sessions
never get Network disabled (helpers.switch_tab attaches without
detaching), and wait_for_network_idle reads from the daemon's global
drain_events stream without filtering by session_id. Net effect: an
agent that visited a polling/SSE tab and switched away would observe
that background tab's traffic in a later wait, either timing out or
waiting on the wrong tab's requests.

Two narrow fixes:

1. helpers.wait_for_network_idle now captures the active session at
   the start of the wait and skips events whose session_id doesn't
   match. That's the consumer-side root-cause fix.

2. daemon set_session now calls Network.disable on the previous
   session before enabling on the new one. Defense in depth — keeps
   the daemon's event buffer from filling with background-tab noise
   in the first place. Best-effort with its own 2s timeout; failure
   doesn't abort the rest of the handler.

Tests added:
- tests/unit/test_helpers.py: events from a background session are
  ignored; the active session can reach idle even when the
  background session is busy.
- tests/unit/test_daemon.py: set_session disables Network on the old
  session; first set_session call (no prior session) does not call
  Network.disable.

Full suite: 63 passed (60 -> 63).
2026-05-04 18:34:18 -07:00
Saurav Panda c789a9fb9c set_session: enable Page/DOM/Runtime/Network (parity with initial attach)
Prior to this change, the daemon's set_session meta-handler only called
Page.enable on the new CDP session. The initial-attach path enabled all
four of Page/DOM/Runtime/Network. set_session is what backs switch_tab()
and new_tab() in helpers.py, so any helper that depends on Network
events — most notably the wait_for_network_idle() that just landed in
PR #258 — silently stopped receiving events after a tab switch.

Refactored: extracted the domain-enable loop into a private
_enable_default_domains(session_id) helper used by both attach_first_page
and the set_session handler. Each domain is enabled with its own
timeout, and a single failure does not abort the others.

Also tightened the target_id fallback semantics: if a caller passes
target_id=None on set_session, the daemon keeps its existing target_id
rather than overwriting with None (preserves the existing 'or' fallback,
just covered by a test now).

Tests in new tests/unit/test_daemon.py drive Daemon.handle() directly
with a fake CDP client and assert:
- set_session enables all four default domains on the new session
  (the regression — would fail against the old single-Page.enable code)
- target_id is preserved when caller passes None
- _enable_default_domains attempts every domain even when one raises

Identified via codex review (P1). Full suite: 60 passed.
2026-05-04 18:26:08 -07:00