@divebell/agent-browser 0.33.1-divebell.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1831 -0
  3. package/bin/agent-browser-darwin-arm64 +0 -0
  4. package/bin/agent-browser-darwin-x64 +0 -0
  5. package/bin/agent-browser-linux-arm64 +0 -0
  6. package/bin/agent-browser-linux-musl-arm64 +0 -0
  7. package/bin/agent-browser-linux-musl-x64 +0 -0
  8. package/bin/agent-browser-linux-x64 +0 -0
  9. package/bin/agent-browser-win32-x64.exe +0 -0
  10. package/bin/agent-browser.js +120 -0
  11. package/cli/src/native/a11y/LICENSE-axe-core-THIRD-PARTY.txt +66 -0
  12. package/cli/src/native/a11y/LICENSE-axe-core.txt +362 -0
  13. package/package.json +61 -0
  14. package/scripts/build-all-platforms.sh +85 -0
  15. package/scripts/check-version-sync.js +81 -0
  16. package/scripts/copy-native.js +36 -0
  17. package/scripts/postinstall.js +321 -0
  18. package/scripts/sync-version.js +125 -0
  19. package/scripts/windows-debug/provision.sh +220 -0
  20. package/scripts/windows-debug/run.sh +92 -0
  21. package/scripts/windows-debug/start.sh +43 -0
  22. package/scripts/windows-debug/stop.sh +28 -0
  23. package/scripts/windows-debug/sync.sh +27 -0
  24. package/skill-data/agentcore/SKILL.md +115 -0
  25. package/skill-data/core/SKILL.md +518 -0
  26. package/skill-data/core/references/authentication.md +380 -0
  27. package/skill-data/core/references/commands.md +511 -0
  28. package/skill-data/core/references/profiling.md +120 -0
  29. package/skill-data/core/references/proxy-support.md +194 -0
  30. package/skill-data/core/references/session-management.md +180 -0
  31. package/skill-data/core/references/snapshot-refs.md +219 -0
  32. package/skill-data/core/references/trust-boundaries.md +51 -0
  33. package/skill-data/core/references/video-recording.md +175 -0
  34. package/skill-data/core/references/webgpu.md +118 -0
  35. package/skill-data/core/templates/authenticated-session.sh +105 -0
  36. package/skill-data/core/templates/capture-workflow.sh +69 -0
  37. package/skill-data/core/templates/form-automation.sh +62 -0
  38. package/skill-data/derive-client/SKILL.md +86 -0
  39. package/skill-data/dogfood/SKILL.md +220 -0
  40. package/skill-data/dogfood/references/issue-taxonomy.md +109 -0
  41. package/skill-data/dogfood/templates/dogfood-report-template.md +53 -0
  42. package/skill-data/electron/SKILL.md +236 -0
  43. package/skill-data/slack/SKILL.md +285 -0
  44. package/skill-data/slack/references/slack-tasks.md +348 -0
  45. package/skill-data/slack/templates/slack-report-template.md +163 -0
  46. package/skill-data/vercel-sandbox/SKILL.md +213 -0
  47. package/skills/agent-browser/SKILL.md +51 -0
package/README.md ADDED
@@ -0,0 +1,1831 @@
1
+ # agent-browser
2
+
3
+ Browser automation CLI for AI agents. This Divebell build adds memory diagnostics and code coverage support.
4
+
5
+ [![skills.sh](https://skills.sh/b/vercel-labs/agent-browser)](https://skills.sh/vercel-labs/agent-browser)
6
+
7
+ ## Installation
8
+
9
+ ### Global Installation (recommended)
10
+
11
+ Installs the native Rust binary:
12
+
13
+ ```bash
14
+ npm install -g @divebell/agent-browser
15
+ agent-browser install # Download Chrome from Chrome for Testing (first time only)
16
+ ```
17
+
18
+ ### Project Installation (local dependency)
19
+
20
+ For projects that want to pin the version in `package.json`:
21
+
22
+ ```bash
23
+ npm install @divebell/agent-browser
24
+ agent-browser install
25
+ ```
26
+
27
+ Then use via `package.json` scripts or by invoking `agent-browser` directly.
28
+
29
+ ### Homebrew (macOS)
30
+
31
+ ```bash
32
+ brew install agent-browser
33
+ agent-browser install # Download Chrome from Chrome for Testing (first time only)
34
+ ```
35
+
36
+ ### Cargo (Rust)
37
+
38
+ ```bash
39
+ cargo install agent-browser
40
+ agent-browser install # Download Chrome from Chrome for Testing (first time only)
41
+ ```
42
+
43
+ ### From Source
44
+
45
+ Requires Node.js 24+, pnpm 11+, and Rust.
46
+
47
+ ```bash
48
+ git clone https://github.com/2heal1/agent-browser
49
+ cd agent-browser
50
+ pnpm install
51
+ pnpm build
52
+ pnpm build:native # Requires Rust (https://rustup.rs)
53
+ pnpm link --global # Makes agent-browser available globally
54
+ agent-browser install
55
+ ```
56
+
57
+ ### Linux Dependencies
58
+
59
+ On Linux, install system dependencies:
60
+
61
+ ```bash
62
+ agent-browser install --with-deps
63
+ ```
64
+
65
+ This exits nonzero if the package manager cannot install every required browser library.
66
+
67
+ ### Updating
68
+
69
+ Upgrade to the latest version:
70
+
71
+ ```bash
72
+ agent-browser upgrade
73
+ ```
74
+
75
+ Detects your installation method (npm, Homebrew, or Cargo) and runs the appropriate update command automatically.
76
+
77
+ ### Requirements
78
+
79
+ - **Chrome** - Run `agent-browser install` to download Chrome from [Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (Google's official automation channel). Existing Chrome, Brave, Playwright, and Puppeteer installations are detected automatically. No Playwright or Node.js required for the daemon.
80
+ - **Node.js 24+ and pnpm 11+** - Only needed when building from source.
81
+ - **Rust** - Only needed when building from source (see From Source above).
82
+
83
+ ## Quick Start
84
+
85
+ ```bash
86
+ agent-browser open example.com
87
+ agent-browser snapshot # Get accessibility tree with refs
88
+ agent-browser click @e2 # Click by ref from snapshot
89
+ agent-browser fill @e3 "test@example.com" # Fill by ref
90
+ agent-browser get text @e1 # Get text by ref
91
+ agent-browser screenshot page.png
92
+ agent-browser close
93
+ ```
94
+
95
+ Clicks fail early when another element covers the target's click point, for example a consent banner or modal. Dismiss or interact with the reported covering element, then take a fresh snapshot before retrying the original ref.
96
+
97
+ Headless Chromium screenshots hide native scrollbars for consistent image output. Pass `--hide-scrollbars false` when launching to keep native scrollbars visible.
98
+
99
+ ### Traditional Selectors (also supported)
100
+
101
+ ```bash
102
+ agent-browser click "#submit"
103
+ agent-browser fill "#email" "test@example.com"
104
+ agent-browser find role button click --name "Submit"
105
+ ```
106
+
107
+ ## Commands
108
+
109
+ ### Core Commands
110
+
111
+ ```bash
112
+ agent-browser open # Launch browser (no navigation); stays on about:blank
113
+ agent-browser open <url> # Launch + navigate to URL (aliases: goto, navigate)
114
+ agent-browser read [url] # Fetch agent-readable text, or read rendered active-tab DOM
115
+ agent-browser click <sel> # Click element (--new-tab to open in new tab)
116
+ agent-browser dblclick <sel> # Double-click element
117
+ agent-browser focus <sel> # Focus element
118
+ agent-browser type <sel> <text> # Type into element
119
+ agent-browser fill <sel> <text> # Clear and fill
120
+ agent-browser press <key> # Press key (Enter, Tab, Control+a) (alias: key)
121
+ agent-browser keyboard type <text> # Type with real keystrokes (no selector, current focus)
122
+ agent-browser keyboard inserttext <text> # Insert text without key events (no selector)
123
+ agent-browser keydown <key> # Hold key down
124
+ agent-browser keyup <key> # Release key
125
+ agent-browser hover <sel> # Hover element
126
+ agent-browser select <sel> <val> # Select dropdown option
127
+ agent-browser check <sel> # Check checkbox
128
+ agent-browser uncheck <sel> # Uncheck checkbox
129
+ agent-browser scroll <dir> [px] # Scroll (up/down/left/right, --selector <sel>)
130
+ agent-browser scrollintoview <sel> # Scroll element into view (alias: scrollinto)
131
+ agent-browser drag <src> <tgt> # Drag and drop
132
+ agent-browser upload <sel> <files> # Upload files
133
+ agent-browser screenshot [path] # Take screenshot (--full for full page, saves to a temporary directory if no path)
134
+ agent-browser screenshot --annotate # Annotated screenshot with numbered element labels
135
+ agent-browser screenshot --screenshot-dir ./shots # Save to custom directory
136
+ agent-browser screenshot --screenshot-format jpeg --screenshot-quality 80
137
+ agent-browser pdf <path> # Save as PDF
138
+ agent-browser snapshot # Accessibility tree with refs (best for AI)
139
+ agent-browser eval <js> # Run JavaScript (-b for base64, --stdin for piped input)
140
+ agent-browser connect <port> # Connect to browser via CDP
141
+ agent-browser stream enable [--port <port>] # Start runtime WebSocket streaming
142
+ agent-browser stream status # Show runtime streaming state and bound port
143
+ agent-browser stream disable # Stop runtime WebSocket streaming
144
+ agent-browser close # Close browser (aliases: quit, exit)
145
+ agent-browser close --all # Close all active sessions
146
+ agent-browser chat "<instruction>" # AI chat: natural language browser control (single-shot)
147
+ agent-browser chat # AI chat: interactive REPL mode
148
+ ```
149
+
150
+ ### Get Info
151
+
152
+ ```bash
153
+ agent-browser get text <sel> # Get text content
154
+ agent-browser get html <sel> # Get innerHTML
155
+ agent-browser get value <sel> # Get input value
156
+ agent-browser get attr <sel> <attr> # Get attribute
157
+ agent-browser get title # Get page title
158
+ agent-browser get url # Get current URL
159
+ agent-browser get cdp-url # Get CDP WebSocket URL (for DevTools, debugging)
160
+ agent-browser get count <sel> # Count matching elements
161
+ agent-browser get box <sel> # Get bounding box
162
+ agent-browser get styles <sel> # Get computed styles
163
+ ```
164
+
165
+ ### Read Agent-Friendly Text
166
+
167
+ ```bash
168
+ agent-browser read
169
+ agent-browser read https://example.com/article
170
+ agent-browser read https://example.com/article --filter overview
171
+ agent-browser read https://example.com/article --outline
172
+ agent-browser read https://docs.example.com --llms index --filter auth
173
+ agent-browser read https://docs.example.com --llms full --filter auth
174
+ agent-browser read example.com/article --require-md
175
+ agent-browser read https://example.com/article --json
176
+ ```
177
+
178
+ `read` fetches a URL without launching Chrome. Omit the URL to read the rendered DOM of the active tab in the current browser session, including browser auth state and client-side updates. Explicit URL reads send `Accept: text/markdown` by default, try the same URL with `.md` appended when the first response is not markdown, walk ancestor paths toward `/` to find the nearest `llms.txt` for a matching docs link, print markdown or plain text when available, and fall back to readable text extracted from HTML. `--llms` and `--require-md` with no URL use the active tab URL because they depend on HTTP resources. `read` does not read `llms-full.txt` unless you ask for it.
179
+
180
+ Options: `--raw` prints the response body without HTML extraction, `--require-md` fails unless the server returns `Content-Type: text/markdown`, `--outline` prints a compact heading outline for one page, `--llms index` prints a compact nearest-ancestor `llms.txt` link list, `--llms full` reads the nearest-ancestor `llms-full.txt`, `--filter <text>` narrows page sections, llms links/sections, or outline headings, and `--timeout <ms>` changes the request timeout. Global safeguards such as `--allowed-domains`, `--content-boundaries`, and `--max-output` also apply to read fetches and output.
181
+
182
+ ### Check State
183
+
184
+ ```bash
185
+ agent-browser is visible <sel> # Check if visible
186
+ agent-browser is enabled <sel> # Check if enabled
187
+ agent-browser is checked <sel> # Check if checked
188
+ ```
189
+
190
+ ### Find Elements (Semantic Locators)
191
+
192
+ ```bash
193
+ agent-browser find role <role> <action> [value] # By ARIA role
194
+ agent-browser find text <text> <action> [value] # By text content
195
+ agent-browser find label <label> <action> [value] # By label
196
+ agent-browser find placeholder <ph> <action> [value] # By placeholder
197
+ agent-browser find alt <text> <action> [value] # By alt text
198
+ agent-browser find title <text> <action> [value] # By title attr
199
+ agent-browser find testid <id> <action> [value] # By data-testid
200
+ agent-browser find first <sel> <action> [value] # First match
201
+ agent-browser find last <sel> <action> [value] # Last match
202
+ agent-browser find nth <n> <sel> <action> [value] # Nth match
203
+ ```
204
+
205
+ **Actions:** `click`, `fill`, `check`, `hover`, `text`
206
+
207
+ **Options:** `--name <name>` (filter role by accessible name), `--exact` (exact, case-sensitive match; for `role` it applies to the accessible name, whose default is a case-insensitive substring)
208
+
209
+ **Examples:**
210
+
211
+ ```bash
212
+ agent-browser find role button click --name "Submit"
213
+ agent-browser find role heading text --name "Skills" # implicit roles work: <h2>=heading, <ul>=list, top-level <header>=banner
214
+ agent-browser find text "Sign In" click
215
+ agent-browser find label "Email" fill "test@test.com"
216
+ agent-browser find first ".item" click
217
+ agent-browser find nth 2 "a" text
218
+ ```
219
+
220
+ ### Wait
221
+
222
+ ```bash
223
+ agent-browser wait <selector> # Wait for element to be visible
224
+ agent-browser wait <ms> # Wait for time (milliseconds)
225
+ agent-browser wait --text "Welcome" # Wait for text to appear (substring match)
226
+ agent-browser wait --url "**/dash" # Wait for URL pattern
227
+ agent-browser wait --load networkidle # Wait for load state
228
+ agent-browser wait --fn "window.ready === true" # Wait for JS condition
229
+
230
+ # Wait for text/element to disappear
231
+ agent-browser wait --fn "!document.body.innerText.includes('Loading...')"
232
+ agent-browser wait "#spinner" --state hidden
233
+ ```
234
+
235
+ **Load states:** `load`, `domcontentloaded`, `networkidle`
236
+
237
+ ### Batch Execution
238
+
239
+ Execute multiple commands in a single invocation. Commands can be passed as quoted arguments or piped as JSON via stdin. This avoids per-command process startup overhead when running multi-step workflows.
240
+
241
+ ```bash
242
+ # Argument mode: each quoted argument is a full command
243
+ agent-browser batch "open https://example.com" "snapshot -i" "screenshot"
244
+
245
+ # With --bail to stop on first error
246
+ agent-browser batch --bail "open https://example.com" "click @e1" "screenshot"
247
+
248
+ # Stdin mode: pipe commands as JSON
249
+ echo '[
250
+ ["open", "https://example.com"],
251
+ ["snapshot", "-i"],
252
+ ["click", "@e1"],
253
+ ["screenshot", "result.png"]
254
+ ]' | agent-browser batch --json
255
+ ```
256
+
257
+ ### Clipboard
258
+
259
+ ```bash
260
+ agent-browser clipboard read # Read text from clipboard
261
+ agent-browser clipboard write "Hello, World!" # Write text to clipboard
262
+ agent-browser clipboard copy # Copy current selection (Ctrl+C)
263
+ agent-browser clipboard paste # Paste from clipboard (Ctrl+V)
264
+ ```
265
+
266
+ ### Mouse Control
267
+
268
+ ```bash
269
+ agent-browser mouse move <x> <y> # Move mouse
270
+ agent-browser mouse down [button] # Press button (left/right/middle)
271
+ agent-browser mouse up [button] # Release button
272
+ agent-browser mouse wheel <dy> [dx] # Scroll wheel
273
+ ```
274
+
275
+ ### Browser Settings
276
+
277
+ ```bash
278
+ agent-browser set viewport <w> <h> [scale] # Set viewport size (scale for retina, e.g. 2)
279
+ agent-browser set device <name> # Emulate device ("iPhone 14")
280
+ agent-browser set geo <lat> <lng> # Set geolocation
281
+ agent-browser set offline [on|off] # Toggle offline mode
282
+ agent-browser set headers <json> # Extra HTTP headers
283
+ agent-browser set credentials <u> <p> # HTTP basic auth
284
+ agent-browser set media [dark|light] # Emulate color scheme
285
+ ```
286
+
287
+ ### Cookies & Storage
288
+
289
+ ```bash
290
+ agent-browser cookies # Get all cookies
291
+ agent-browser cookies set <name> <val> # Set cookie
292
+ agent-browser cookies set --curl <file> # Import cookies from a Copy-as-cURL dump,
293
+ # JSON array, or bare Cookie header (auto-detected)
294
+ agent-browser cookies clear # Clear cookies
295
+
296
+ agent-browser storage local # Get all localStorage
297
+ agent-browser storage local <key> # Get specific key
298
+ agent-browser storage local set <k> <v> # Set value
299
+ agent-browser storage local clear # Clear all
300
+
301
+ agent-browser storage session # Same for sessionStorage
302
+ ```
303
+
304
+ ### Network
305
+
306
+ ```bash
307
+ agent-browser network route <url> # Intercept requests
308
+ agent-browser network route <url> --abort # Block requests
309
+ agent-browser network route <url> --body <json> # Mock response
310
+ agent-browser network route '*' --abort --resource-type script # Block scripts only
311
+ agent-browser network unroute [url] # Remove routes
312
+ agent-browser network requests # View tracked requests
313
+ agent-browser network requests --filter api # Filter requests
314
+ agent-browser network requests --type xhr,fetch # Filter by resource type
315
+ agent-browser network requests --method POST # Filter by HTTP method
316
+ agent-browser network requests --status 2xx # Filter by status (200, 2xx, 400-499)
317
+ agent-browser network request <requestId> # View full request/response detail
318
+ agent-browser network har start # Start HAR recording (embeds text response bodies)
319
+ agent-browser network har start --content all # Embed all response bodies (binary as base64)
320
+ agent-browser network har start --content none # Metadata only, no bodies
321
+ agent-browser network har stop [output.har] # Stop and save HAR (temp path if omitted)
322
+ ```
323
+
324
+ ### Tabs & Windows
325
+
326
+ ```bash
327
+ agent-browser tab # List tabs (shows `tabId` and optional label)
328
+ agent-browser tab new [url] # New tab (optionally with URL)
329
+ agent-browser tab new --label docs [url] # New tab with a user-assigned label
330
+ agent-browser tab <t<N>|label> # Switch to a tab by id or label
331
+ agent-browser tab close [t<N>|label] # Close a tab (defaults to active)
332
+ agent-browser window new # New window
333
+ ```
334
+
335
+ Tab ids are stable strings of the form `t1`, `t2`, `t3`. They're never reused within a session, so scripts and agents can keep referring to the same tab even after other tabs are opened or closed. Positional integers like `tab 2` are **not** accepted; the `t` prefix disambiguates handles from indices and mirrors the `@e1` convention used for element refs.
336
+
337
+ You can also assign a memorable label (`docs`, `app`, `admin`) and use it interchangeably with the id. Labels are never auto-generated and never rewritten on navigation — they're yours to name and keep:
338
+
339
+ ```bash
340
+ agent-browser tab new --label docs https://docs.example.com
341
+ agent-browser tab docs # switch to the docs tab
342
+ agent-browser snapshot # populate refs for docs
343
+ agent-browser click @e3 # click uses docs's refs
344
+ agent-browser tab close docs # close by label
345
+ ```
346
+
347
+ Switching to a tab discarded by Chrome's Memory Saver reactivates it, since a discarded tab has no renderer to drive. Reactivation reloads the discarded page and resets its unsaved state, and the switch result reports `"revived": true`. A tab whose page is paused by a JavaScript dialog is alive rather than discarded, so the switch leaves it untouched and reports `"dialogBlocked": true`; resolve the dialog with `dialog accept` or `dialog dismiss` before interacting. Closing the active tab onto a discarded successor revives it the same way and reports `"activeTabRevived": true`.
348
+
349
+ ### Frames
350
+
351
+ ```bash
352
+ agent-browser frame <sel> # Switch to iframe
353
+ agent-browser frame main # Back to main frame
354
+ ```
355
+
356
+ ### Dialogs
357
+
358
+ ```bash
359
+ agent-browser dialog accept [text] # Accept (with optional prompt text)
360
+ agent-browser dialog dismiss # Dismiss
361
+ agent-browser dialog status # Check if a dialog is currently open
362
+ ```
363
+
364
+ By default, `alert` and `beforeunload` dialogs are automatically accepted so they never block the agent. `confirm` and `prompt` dialogs still require explicit handling. Use `--no-auto-dialog` (or `AGENT_BROWSER_NO_AUTO_DIALOG=1`) to disable automatic handling.
365
+
366
+ When a JavaScript dialog is pending, all command responses include a `warning` field with the dialog type and message.
367
+
368
+ ### Diff
369
+
370
+ ```bash
371
+ agent-browser diff snapshot # Compare current vs last snapshot
372
+ agent-browser diff snapshot --baseline before.txt # Compare current vs saved snapshot file
373
+ agent-browser diff snapshot --selector "#main" --compact # Scoped snapshot diff
374
+ agent-browser diff screenshot --baseline before.png # Visual pixel diff against baseline
375
+ agent-browser diff screenshot --baseline b.png -o d.png # Save diff image to custom path
376
+ agent-browser diff screenshot --baseline b.png -t 0.2 # Adjust color threshold (0-1)
377
+ agent-browser diff url https://v1.com https://v2.com # Compare two URLs (snapshot diff)
378
+ agent-browser diff url https://v1.com https://v2.com --screenshot # Also visual diff
379
+ agent-browser diff url https://v1.com https://v2.com --wait-until networkidle # Custom wait strategy
380
+ agent-browser diff url https://v1.com https://v2.com --selector "#main" # Scope to element
381
+ ```
382
+
383
+ ### Debug
384
+
385
+ ```bash
386
+ agent-browser trace start # Start recording trace
387
+ agent-browser trace stop [path] # Stop and save trace
388
+ agent-browser profiler start # Start Chrome DevTools profiling
389
+ agent-browser profiler stop [path] # Stop and save profile (.json)
390
+ agent-browser memory metrics # Read JS heap and DOM counters
391
+ agent-browser memory sampling start # Start allocation sampling on this page
392
+ agent-browser memory sampling stop # Save allocation profile and top call sites
393
+ agent-browser memory snapshot # Stream a heap snapshot to a local file
394
+ agent-browser memory status # Show the active capture
395
+ agent-browser memory cancel # Cancel the active capture
396
+ agent-browser console # View console messages (log, error, warn, info)
397
+ agent-browser console --json # JSON output with raw CDP args for programmatic access
398
+ agent-browser console --clear # Clear console
399
+ agent-browser errors # View page errors (uncaught JavaScript exceptions)
400
+ agent-browser errors --clear # Clear errors
401
+ agent-browser highlight <sel> # Highlight element
402
+ agent-browser inspect # Open Chrome DevTools for the active page
403
+ agent-browser state save <path> # Save auth state
404
+ agent-browser state load <path> # Load auth state
405
+ agent-browser state list # List saved state files
406
+ agent-browser state show <file> # Show state summary
407
+ agent-browser state rename <old> <new> # Rename state file
408
+ agent-browser state clear [name] # Clear states for session
409
+ agent-browser state clear --all # Clear all saved states
410
+ agent-browser state clean --older-than <days> # Delete old states
411
+ ```
412
+
413
+ ### Memory diagnostics
414
+
415
+ Memory diagnostics reuse the current agent-browser Chrome session. No separate CDP port or address is required. They are disabled on Lightpanda, Safari, and other engines that do not provide the required Chrome memory capabilities.
416
+
417
+ ```bash
418
+ agent-browser open https://example.com
419
+ agent-browser memory metrics
420
+
421
+ agent-browser memory sampling start --sampling-interval 65536
422
+ # Repeat the page flow that may retain objects
423
+ agent-browser memory sampling stop ./allocations.heapprofile --top 10
424
+
425
+ agent-browser memory collect-garbage
426
+ agent-browser memory snapshot ./after.heapsnapshot --timeout 120000
427
+ ```
428
+
429
+ Only one memory capture can be active in a browser session. Allocation sampling stays bound to the page where it started even if another tab becomes active. `memory status` reports the capture ID, type, original page, and start time. `memory cancel` stops sampling or interrupts an in-progress snapshot and removes partial output.
430
+
431
+ Heap snapshots are written one chunk at a time and are never printed to the terminal or JSON response. If no path is supplied, artifacts go to the runtime temporary directory and default artifacts older than 24 hours are cleaned when a new capture starts. Use `--max-size <bytes>` to cap artifact size, `--no-gc` to skip the default garbage collection before a snapshot, and `--json` for structured summaries and stable `errorCode` values.
432
+
433
+ Heap snapshots and allocation profiles can contain page text, application data, credentials, and tokens. Keep them on trusted local storage, do not commit them, and delete them when the diagnosis is complete.
434
+
435
+ ### Navigation
436
+
437
+ ```bash
438
+ agent-browser back # Go back
439
+ agent-browser forward # Go forward
440
+ agent-browser reload # Reload page
441
+ agent-browser pushstate <url> # SPA client-side nav; auto-detects window.next.router.push,
442
+ # falls back to history.pushState + popstate
443
+ ```
444
+
445
+ ### Pre-navigation setup
446
+
447
+ Some flows (SSR debug, auth cookies for protected origins, init scripts) need state set up *before* the first navigation. Use `open` with no URL to launch the browser, then stage cookies / routes / init scripts, then navigate. `batch` sends it all in one CLI call:
448
+
449
+ ```bash
450
+ agent-browser batch \
451
+ '["open"]' \
452
+ '["network","route","*","--abort","--resource-type","script"]' \
453
+ '["cookies","set","--curl","cookies.curl","--domain","localhost"]' \
454
+ '["navigate","http://localhost:3000/target"]'
455
+ ```
456
+
457
+ Without `batch` the same sequence is three commands that all reuse the same daemon (fast, but not one turn).
458
+
459
+ ### React / Web Vitals
460
+
461
+ Agent-browser ships with first-class React introspection and universal Web Vitals metrics. The React commands need the React DevTools hook installed at launch; Web Vitals and pushstate are framework-agnostic.
462
+
463
+ ```bash
464
+ agent-browser open --enable react-devtools <url> # Launch with React hook installed
465
+ agent-browser react tree # Full component tree
466
+ agent-browser react inspect <fiberId> # props, hooks, state, source
467
+ agent-browser react renders start # Begin fiber render recording
468
+ agent-browser react renders stop [--json] # Stop and print profile (--json for raw data)
469
+ agent-browser react suspense [--only-dynamic] [--json] # Suspense boundaries + classifier
470
+ # --only-dynamic hides the "static" list
471
+ agent-browser vitals [url] [--json] # LCP/CLS/TTFB/FCP/INP + hydration summary
472
+ ```
473
+
474
+ Each `react ...` subcommand requires `--enable react-devtools` to have been passed at launch (the React DevTools `installHook.js` is embedded in the binary). Without it the commands error with `React DevTools hook not installed
475
+ - relaunch with --enable react-devtools`.
476
+
477
+ Works on any React app — Next.js, Remix, Vite+React, CRA, TanStack Start, React Native Web, etc. `vitals` and `pushstate` are framework-agnostic. `vitals` prints a summary by default; pass `--json` for the full structured payload.
478
+
479
+ ### Accessibility audits
480
+
481
+ Run an [axe-core](https://github.com/dequelabs/axe-core) accessibility audit against the current page or a URL. The axe-core engine is embedded in the binary, so it works offline and under strict CSP. It runs private partial audits across the page's frame tree and merges serialized results without page messaging, so page-provided `window.axe` values remain intact and iframe violations retain their frame selector paths. Accessibility audits require a CDP browser and are not available with Safari or iOS WebDriver sessions.
482
+
483
+ ```bash
484
+ agent-browser a11y # Audit the current page
485
+ agent-browser a11y https://example.com # Navigate, then audit
486
+ agent-browser a11y --tags wcag2a,wcag2aa # Only rules with these axe tags
487
+ agent-browser a11y --selector "#main" # Scope the audit to a subtree
488
+ agent-browser a11y example.com --json # Full structured results
489
+ ```
490
+
491
+ The default output lists each violation with its impact, rule id, fix guidance URL, and the CSS selectors of failing nodes:
492
+
493
+ ```
494
+ url: https://example.com/
495
+ axe-core: 4.12.1 violations: 2 incomplete: 0 passes: 24
496
+
497
+ [critical] image-alt: Images must have alternative text (3 nodes)
498
+ https://dequeuniversity.com/rules/axe/4.12/image-alt
499
+ - img.hero
500
+ - #logo > img
501
+ - footer img
502
+ [serious] color-contrast: Elements must meet minimum color contrast ratio thresholds (1 node)
503
+ https://dequeuniversity.com/rules/axe/4.12/color-contrast
504
+ - .nav a.muted
505
+ ```
506
+
507
+ `--json` returns the same data structured for automation (`counts`, `violations`, `incomplete`, each violation's `nodes` with `target`, `html`, and `failureSummary`). Each `target` preserves axe's selector path arrays, including nested arrays for shadow DOM boundaries. Rules that axe could not evaluate automatically are reported under `incomplete` for manual review.
508
+
509
+ ### Init scripts
510
+
511
+ ```bash
512
+ agent-browser open --init-script <path> # Register page init script before first navigation
513
+ # (repeatable; also AGENT_BROWSER_INIT_SCRIPTS env)
514
+ agent-browser addinitscript <js> # Register at runtime (returns identifier)
515
+ agent-browser removeinitscript <identifier> # Remove a previously registered init script
516
+ ```
517
+
518
+ ### Setup
519
+
520
+ ```bash
521
+ agent-browser install # Download Chrome from Chrome for Testing (Google's official automation channel)
522
+ agent-browser install --with-deps # Also install system deps (Linux)
523
+ agent-browser upgrade # Upgrade agent-browser to the latest version
524
+ agent-browser doctor # Diagnose the install and auto-clean stale daemon files
525
+ agent-browser doctor --fix # Also run destructive repairs (reinstall Chrome, purge old state, ...)
526
+ agent-browser doctor --offline --quick # Skip network probes and the live launch test
527
+ agent-browser mcp # Start an MCP stdio server
528
+ ```
529
+
530
+ `doctor` checks your environment, Chrome install, daemon state, config files, encryption key, providers, network reachability, and runs a live headless browser launch test. Stale socket/pid sidecar files are auto-cleaned. Output is also available as `--json` for agents.
531
+
532
+ ### Skills
533
+
534
+ ```bash
535
+ agent-browser skills # List available skills
536
+ agent-browser skills list # Same as above
537
+ agent-browser skills get <name> # Output a skill's full content
538
+ agent-browser skills get <name> --full # Include references and templates
539
+ agent-browser skills get --all # Output every skill
540
+ agent-browser skills path [name] # Print skill directory path
541
+ ```
542
+
543
+ Serves bundled skill content that always matches the installed CLI version. AI agents use this to get current instructions rather than relying on cached copies. Set `AGENT_BROWSER_SKILLS_DIR` to override the skills directory path.
544
+
545
+ ### MCP Server
546
+
547
+ ```bash
548
+ agent-browser mcp
549
+ agent-browser mcp --tools all
550
+ agent-browser mcp --tools core,network,react
551
+ ```
552
+
553
+ Starts a Model Context Protocol server over stdio. MCP clients launch this command as a subprocess and exchange newline-delimited JSON-RPC on stdin and stdout. The server defaults to MCP protocol 2025-11-25 and accepts older supported client protocol versions during initialization.
554
+
555
+ The default tools profile is `core`, which keeps MCP context small for everyday browser automation. Use `--tools all` for the full typed CLI parity surface, or combine profiles with commas, such as `--tools core,network,react`.
556
+
557
+ Profiles:
558
+
559
+ - `core` — Default. Navigation, snapshots, interaction, waits, reads, screenshots, JavaScript eval, close, tab basics, and profile discovery
560
+ - `network` — Network routes, request inspection, HAR, headers, credentials, offline
561
+ - `state` — Cookies, storage, auth, saved state, sessions, profiles, skills
562
+ - `debug` — Console/errors, tracing, profiling, recording, a11y audit, clipboard, plugins, doctor, dashboard, install, upgrade, chat, diff, batch, confirm/deny
563
+ - `tabs` — Back/forward/reload, tabs, windows, frames, dialogs
564
+ - `react` — React tree/inspect/renders/suspense, vitals, pushstate
565
+ - `mobile` — Viewport/device/geolocation/media, touch, swipe, mouse, keyboard
566
+ - `all` — Every MCP tool, including the full typed CLI parity surface
567
+
568
+ Common tools include:
569
+
570
+ - `agent_browser_tools_profiles`
571
+ - `agent_browser_open`
572
+ - `agent_browser_snapshot`
573
+ - `agent_browser_click`
574
+ - `agent_browser_fill`
575
+ - `agent_browser_type`
576
+ - `agent_browser_press`
577
+ - `agent_browser_wait_for_selector`
578
+ - `agent_browser_screenshot`
579
+ - `agent_browser_get_url`
580
+ - `agent_browser_eval`
581
+ - `agent_browser_close`
582
+
583
+ Each tool has typed fields such as `url`, `selector`, `text`, `key`, `session`, and `allowedDomains`, so MCP clients show meaningful approval prompts instead of raw command arrays. The common `allowedDomains` array maps to `--allowed-domains` and activates the same WebRTC containment and launch-mode restrictions. Each tool also accepts `extraArgs` for advanced CLI flags and exact CLI parity. Tool discovery is paginated and includes read-only/open-world annotations so modern MCP clients can load the large typed surface incrementally.
584
+
585
+ Example MCP client config:
586
+
587
+ ```json
588
+ {
589
+ "mcpServers": {
590
+ "agent-browser": {
591
+ "command": "agent-browser",
592
+ "args": ["mcp"]
593
+ }
594
+ }
595
+ }
596
+ ```
597
+
598
+ Full parity MCP client config:
599
+
600
+ ```json
601
+ {
602
+ "mcpServers": {
603
+ "agent-browser": {
604
+ "command": "agent-browser",
605
+ "args": ["mcp", "--tools", "all"]
606
+ }
607
+ }
608
+ }
609
+ ```
610
+
611
+ Tool invocations use the same config files and environment variables as the CLI. Use `session` in the tool arguments, or set `AGENT_BROWSER_SESSION`, to isolate browser state.
612
+
613
+ ## Authentication
614
+
615
+ agent-browser provides multiple ways to persist login sessions so you don't re-authenticate every run.
616
+
617
+ ### Quick summary
618
+
619
+ | Approach | Best for | Flag / Env |
620
+ |----------|----------|------------|
621
+ | **Chrome profile reuse** | Reuse your existing Chrome login state (cookies, sessions) with zero setup | `--profile <name>` / `AGENT_BROWSER_PROFILE` |
622
+ | **Persistent profile** | Full browser state (cookies, IndexedDB, service workers, cache) across restarts | `--profile <path>` / `AGENT_BROWSER_PROFILE` |
623
+ | **Session persistence** | Auto-save/restore cookies + localStorage from a stable session key | `--session <id> --restore` / `AGENT_BROWSER_RESTORE` |
624
+ | **Import from your browser** | Grab auth from a Chrome session you already logged into | `--auto-connect` + `state save` |
625
+ | **State file** | Load a previously saved state JSON on launch | `--state <path>` / `AGENT_BROWSER_STATE` |
626
+ | **Auth vault** | Store credentials locally (encrypted), login by name | `auth save` / `auth login` |
627
+
628
+ ### Import auth from your browser
629
+
630
+ If you are already logged in to a site in Chrome, you can grab that auth state and reuse it:
631
+
632
+ ```bash
633
+ # 1. Launch Chrome with remote debugging enabled
634
+ # macOS:
635
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222
636
+ # Or use --auto-connect to discover an already-running Chrome
637
+
638
+ # 2. Connect and save the authenticated state
639
+ agent-browser --auto-connect state save ./my-auth.json
640
+
641
+ # 3. Use the saved auth in future sessions
642
+ agent-browser --state ./my-auth.json open https://app.example.com/dashboard
643
+
644
+ # 4. Or use --restore for automatic persistence
645
+ SESSION="$(agent-browser session id --scope worktree --prefix myapp)"
646
+ agent-browser --session "$SESSION" --restore --state ./my-auth.json open https://app.example.com/dashboard
647
+ # From now on, --session "$SESSION" --restore auto-saves/restores this state
648
+ ```
649
+
650
+ > **Security notes:**
651
+ > - `--remote-debugging-port` exposes full browser control on localhost. Any local process can connect. Only use on trusted machines and close Chrome when done.
652
+ > - State files contain session tokens in plaintext. Add them to `.gitignore` and delete when no longer needed. For encryption at rest, set `AGENT_BROWSER_ENCRYPTION_KEY` (see [State Encryption](#state-encryption)).
653
+
654
+ For full details on login flows, OAuth, 2FA, cookie-based auth, and the auth vault, see the [Authentication](docs/src/app/sessions/page.mdx) docs.
655
+
656
+ ## Sessions
657
+
658
+ Run multiple isolated browser instances:
659
+
660
+ ```bash
661
+ # Different sessions
662
+ agent-browser --session agent1 open site-a.com
663
+ agent-browser --session agent2 open site-b.com
664
+
665
+ # Or via environment variable
666
+ AGENT_BROWSER_SESSION=agent1 agent-browser click "#btn"
667
+
668
+ # List active sessions
669
+ agent-browser session list
670
+ # Output:
671
+ # Active sessions:
672
+ # -> default
673
+ # agent1
674
+
675
+ # Show current session
676
+ agent-browser session
677
+
678
+ # Generate a stable worktree-scoped session id
679
+ agent-browser session id --scope worktree --prefix next-dev-loop
680
+
681
+ # Inspect daemon, launch, and restore status
682
+ agent-browser session info --json
683
+ ```
684
+
685
+ Each session has its own:
686
+
687
+ - Browser instance
688
+ - Cookies and storage
689
+ - Navigation history
690
+ - Authentication state
691
+
692
+ ## Chrome Profile Reuse
693
+
694
+ The fastest way to use your existing login state: pass a Chrome profile name to `--profile`:
695
+
696
+ ```bash
697
+ # List available Chrome profiles
698
+ agent-browser profiles
699
+
700
+ # Reuse your default Chrome profile's login state
701
+ agent-browser --profile Default open https://gmail.com
702
+
703
+ # Use a named profile (by display name or directory name)
704
+ agent-browser --profile "Work" open https://app.example.com
705
+
706
+ # Or via environment variable
707
+ AGENT_BROWSER_PROFILE=Default agent-browser open https://gmail.com
708
+ ```
709
+
710
+ This copies your Chrome profile to a temp directory (read-only snapshot, no changes to your original profile), so the browser launches with your existing cookies and sessions.
711
+
712
+ > **Note:** On Windows, close Chrome before using `--profile <name>` if Chrome is running, as some profile files may be locked.
713
+
714
+ ## Persistent Profiles
715
+
716
+ For a persistent custom profile directory that stores state across browser restarts, pass a path to `--profile`:
717
+
718
+ ```bash
719
+ # Use a persistent profile directory
720
+ agent-browser --profile ~/.myapp-profile open myapp.com
721
+
722
+ # Login once, then reuse the authenticated session
723
+ agent-browser --profile ~/.myapp-profile open myapp.com/dashboard
724
+
725
+ # Or via environment variable
726
+ AGENT_BROWSER_PROFILE=~/.myapp-profile agent-browser open myapp.com
727
+ ```
728
+
729
+ The profile directory stores:
730
+
731
+ - Cookies and localStorage
732
+ - IndexedDB data
733
+ - Service workers
734
+ - Browser cache
735
+ - Login sessions
736
+
737
+ **Tip**: Use different profile paths for different projects to keep their browser state isolated.
738
+
739
+ ## Session Persistence
740
+
741
+ Use `--restore` with a stable `--session` to automatically save and restore cookies and localStorage across browser restarts:
742
+
743
+ ```bash
744
+ # Generate a stable id for this worktree and auto-save/load state
745
+ SESSION="$(agent-browser session id --scope worktree --prefix twitter)"
746
+ agent-browser --session "$SESSION" --restore open twitter.com
747
+
748
+ # Login once, then state persists automatically
749
+ # State files stored in ~/.agent-browser/sessions/
750
+
751
+ # Optional: validate restored state before auto-saving again
752
+ agent-browser --session "$SESSION" --restore --restore-check-text Dashboard open twitter.com
753
+ ```
754
+
755
+ State is saved when the browser closes (explicit `close`, idle timeout, or daemon shutdown) and also periodically while the browser is open, so a browser window you close by hand still leaves a recent save behind. Periodic autosave waits for commands to settle, then saves at most once per `AGENT_BROWSER_AUTOSAVE_INTERVAL_MS` (default 30000; set to `0` to save only on close). Idle sessions keep saving on the same interval, so changes the page makes on its own (token refreshes, background requests) are captured too. It respects the `--restore-save` policy.
756
+
757
+ ### State Encryption
758
+
759
+ Encrypt saved session data at rest with AES-256-GCM:
760
+
761
+ ```bash
762
+ # Generate key: openssl rand -hex 32
763
+ export AGENT_BROWSER_ENCRYPTION_KEY=<64-char-hex-key>
764
+
765
+ # State files are now encrypted automatically
766
+ agent-browser --session secure --restore open example.com
767
+ ```
768
+
769
+ | Variable | Description |
770
+ | --------------------------------- | -------------------------------------------------- |
771
+ | `AGENT_BROWSER_RESTORE` | Auto-save/load state persistence name |
772
+ | `AGENT_BROWSER_RESTORE_SAVE` | Restore save policy: `auto`, `always`, or `never` |
773
+ | `AGENT_BROWSER_AUTOSAVE_INTERVAL_MS` | Min ms between periodic autosaves (default: 30000, 0 disables) |
774
+ | `AGENT_BROWSER_NAMESPACE` | Namespace for daemon sockets and restore state |
775
+ | `AGENT_BROWSER_SESSION_NAME` | Legacy auto-save/load state persistence name |
776
+ | `AGENT_BROWSER_ENCRYPTION_KEY` | 64-char hex key for AES-256-GCM encryption |
777
+ | `AGENT_BROWSER_STATE_EXPIRE_DAYS` | Auto-delete states older than N days (default: 30) |
778
+
779
+ ## Security
780
+
781
+ agent-browser includes security features for safe AI agent deployments. All features are opt-in, and existing workflows are unaffected until you explicitly enable a feature:
782
+
783
+ - **Authentication Vault**: Store credentials locally (always encrypted), reference by name. The LLM never sees passwords. `auth login` navigates with `load` and then waits for login form selectors to appear (SPA-friendly, timeout follows the default action timeout). A key is auto-generated at `~/.agent-browser/.encryption-key` if `AGENT_BROWSER_ENCRYPTION_KEY` is not set: `echo "pass" | agent-browser auth save github --url https://github.com/login --username user --password-stdin` then `agent-browser auth login github`
784
+ - **Plugin System**: Extend agent-browser with external executable plugins. Plugins run out-of-process over the `agent-browser.plugin.v1` stdio JSON protocol and declare capabilities such as `credential.read`, `browser.provider`, `launch.mutate`, or `command.run`.
785
+ - **Content Boundary Markers**: Wrap page output in delimiters so LLMs can distinguish tool output from untrusted content: `--content-boundaries`
786
+ - **Domain Allowlist**: Restrict navigation to trusted domains (wildcards like `*.example.com` also match the bare domain): `--allowed-domains "example.com,*.example.com"`. Sub-resource requests (scripts, images, fetch), WebSocket/EventSource connections, and `sendBeacon` calls to non-allowed domains are blocked. WebRTC peer connections are disabled in supported Chromium sessions while the allowlist is active to prevent STUN, TURN, and DNS traffic from bypassing HTTP interception. Dedicated and shared workers are guarded with a bootstrap wrapper; if a page CSP forbids that wrapper, the worker fails closed rather than running without the allowlist guard. Pre-existing CDP sessions, auto-connect, Chrome profiles, direct-page provider plugins, agent-browser restore or state-file replay, raw Chrome args that select profiles, restore sessions, or open startup pages, iOS, and Safari reject this option because agent-browser cannot install equivalent containment before page scripts run. Include any CDN domains your target pages depend on (e.g., `*.cdn.example.com`).
787
+ - **Action Policy**: Gate destructive actions with a static policy file: `--action-policy ./policy.json`
788
+ - **Action Confirmation**: Require explicit approval for sensitive action categories: `--confirm-actions eval,download`
789
+ - **Output Length Limits**: Prevent context flooding: `--max-output 50000`
790
+
791
+ | Variable | Description |
792
+ | ----------------------------------- | ---------------------------------------- |
793
+ | `AGENT_BROWSER_CONTENT_BOUNDARIES` | Wrap page output in boundary markers |
794
+ | `AGENT_BROWSER_MAX_OUTPUT` | Max characters for page output |
795
+ | `AGENT_BROWSER_ALLOWED_DOMAINS` | Comma-separated allowed domain patterns; requires a fresh controllable browser context without profile/session startup args, restore/state replay, or direct-page provider plugins |
796
+ | `AGENT_BROWSER_ACTION_POLICY` | Path to action policy JSON file |
797
+ | `AGENT_BROWSER_CONFIRM_ACTIONS` | Action categories requiring confirmation |
798
+ | `AGENT_BROWSER_CONFIRM_INTERACTIVE` | Enable interactive confirmation prompts |
799
+ | `AGENT_BROWSER_PLUGINS` | JSON plugin registry override |
800
+
801
+ See [Security documentation](https://agent-browser.dev/security) for details.
802
+
803
+ ### Plugin System
804
+
805
+ Plugins let third-party tools integrate without becoming built-in agent-browser dependencies. Add a plugin from npm or GitHub:
806
+
807
+ ```bash
808
+ agent-browser plugin add agent-browser-plugin-captcha
809
+ agent-browser plugin add @company/agent-browser-plugin-vault --name vault
810
+ agent-browser plugin add org/agent-browser-plugin-cloud-browser
811
+ ```
812
+
813
+ References are resolved by shape: `name` uses npm, `@scope/name` uses npm, and `owner/repo` uses GitHub. `plugin add` writes `./agent-browser.json` by default; use `--global` for `~/.agent-browser/config.json`.
814
+
815
+ Plugin packages should support `plugin.manifest` so `plugin add` can discover their name and capabilities automatically. If a plugin does not support manifests, pass `--capability <name>` during add.
816
+
817
+ Plugins can also be configured manually in `agent-browser.json`:
818
+
819
+ ```json
820
+ {
821
+ "plugins": [
822
+ {
823
+ "name": "vault",
824
+ "command": "agent-browser-plugin-vault",
825
+ "capabilities": ["credential.read"]
826
+ },
827
+ {
828
+ "name": "cloud-browser",
829
+ "command": "agent-browser-plugin-cloud-browser",
830
+ "capabilities": ["browser.provider"]
831
+ },
832
+ {
833
+ "name": "stealth",
834
+ "command": "agent-browser-plugin-stealth",
835
+ "capabilities": ["launch.mutate"]
836
+ },
837
+ {
838
+ "name": "captcha",
839
+ "command": "agent-browser-plugin-captcha",
840
+ "capabilities": ["command.run", "captcha.solve"]
841
+ }
842
+ ]
843
+ }
844
+ ```
845
+
846
+ Inspect configured plugins:
847
+
848
+ ```bash
849
+ agent-browser plugin list
850
+ agent-browser plugin show vault
851
+ ```
852
+
853
+ Use a credential provider plugin for one login:
854
+
855
+ ```bash
856
+ agent-browser auth login my-app --credential-provider vault --item "My App"
857
+ agent-browser auth login my-app --credential-provider vault --item "My App" --url https://app.example.com/login --username-selector "#email" --password-selector "#password" --submit-selector "button[type=submit]"
858
+ ```
859
+
860
+ Use a browser provider plugin:
861
+
862
+ ```bash
863
+ agent-browser --provider cloud-browser open https://example.com
864
+ ```
865
+
866
+ Use a launch mutator plugin for stealth or local launch customization. The plugin can append Chrome args, extensions, and init scripts before the browser starts:
867
+
868
+ ```bash
869
+ agent-browser open https://example.com
870
+ ```
871
+
872
+ Use a generic plugin command for domain-specific tools such as CAPTCHA solvers:
873
+
874
+ ```bash
875
+ agent-browser plugin run captcha captcha.solve --payload '{"siteKey":"...","url":"https://example.com"}'
876
+ ```
877
+
878
+ The protocol request always includes `protocol`, `type`, `capability`, and `request`. A credential plugin receives `credential.resolve`, a browser provider receives `browser.launch`, a launch mutator receives `launch.mutate`, and generic commands receive the supplied request type. `plugin run` is for `command.run` and custom capabilities; core capabilities and protocol request types use their dedicated command paths. agent-browser keeps browser automation, redaction-sensitive output, and policy enforcement in core.
879
+
880
+ Gate plugin access by capability action:
881
+
882
+ ```bash
883
+ agent-browser --confirm-actions plugin:vault:credential.read auth login my-app --credential-provider vault --item "My App"
884
+ agent-browser --confirm-actions plugin:cloud-browser:browser.provider --provider cloud-browser open https://example.com
885
+ agent-browser --confirm-actions plugin:stealth:launch.mutate open https://example.com
886
+ ```
887
+
888
+ Do not put vault tokens or passwords in plugin command args. Use the vault vendor's own login/session mechanism or environment outside agent-browser config.
889
+
890
+ ## Snapshot Options
891
+
892
+ The `snapshot` command supports filtering to reduce output size:
893
+
894
+ ```bash
895
+ agent-browser snapshot # Full accessibility tree
896
+ agent-browser snapshot -i # Interactive elements only (buttons, inputs, links)
897
+ agent-browser snapshot -i --urls # Interactive elements with link URLs
898
+ agent-browser snapshot -c # Compact (remove empty structural elements)
899
+ agent-browser snapshot -d 3 # Limit depth to 3 levels
900
+ agent-browser snapshot -s "#main" # Scope to CSS selector
901
+ agent-browser snapshot -i -c -d 5 # Combine options
902
+ ```
903
+
904
+ | Option | Description |
905
+ | ---------------------- | ----------------------------------------------------------------------- |
906
+ | `-i, --interactive` | Only show interactive elements (buttons, links, inputs) |
907
+ | `-u, --urls` | Include href URLs for link elements |
908
+ | `-c, --compact` | Remove empty structural elements |
909
+ | `-d, --depth <n>` | Limit tree depth |
910
+ | `-s, --selector <sel>` | Scope to CSS selector |
911
+
912
+ ## Annotated Screenshots
913
+
914
+ The `--annotate` flag overlays numbered labels on interactive elements in the screenshot. Each label `[N]` corresponds to ref `@eN`, so the same refs work for both visual and text-based workflows.
915
+
916
+ Annotated screenshots are supported on the CDP-backed browser path (Chrome/Lightpanda). The Safari/WebDriver backend does not yet support `--annotate`.
917
+
918
+ ```bash
919
+ agent-browser screenshot --annotate
920
+ # -> Screenshot saved to /tmp/screenshot-2026-02-17T12-00-00-abc123.png
921
+ # [1] @e1 button "Submit"
922
+ # [2] @e2 link "Home"
923
+ # [3] @e3 textbox "Email"
924
+ ```
925
+
926
+ After an annotated screenshot, refs are cached so you can immediately interact with elements:
927
+
928
+ ```bash
929
+ agent-browser screenshot --annotate ./page.png
930
+ agent-browser click @e2 # Click the "Home" link labeled [2]
931
+ ```
932
+
933
+ This is useful for multimodal AI models that can reason about visual layout, unlabeled icon buttons, canvas elements, or visual state that the text accessibility tree cannot capture.
934
+
935
+ ## Options
936
+
937
+ | Option | Description |
938
+ |--------|-------------|
939
+ | `--session <name>` | Use isolated session (or `AGENT_BROWSER_SESSION` env) |
940
+ | `--restore [name]` | Auto-save/restore session state. Bare `--restore` uses `--session` as the key |
941
+ | `--restore-save <policy>` | Restore save policy: `auto`, `always`, or `never` |
942
+ | `--restore-check-url <glob>` | Validate restored state against a URL pattern |
943
+ | `--restore-check-text <text>` | Validate restored state against page text |
944
+ | `--restore-check-fn <js>` | Validate restored state against a truthy JavaScript expression |
945
+ | `--namespace <name>` | Isolate daemon sockets and restore-state directories |
946
+ | `--session-name <name>` | Legacy alias for restore persistence key |
947
+ | `--profile <name\|path>` | Chrome profile name or persistent directory path (or `AGENT_BROWSER_PROFILE` env) |
948
+ | `--state <path>` | Load storage state from JSON file (or `AGENT_BROWSER_STATE` env) |
949
+ | `--headers <json>` | Set HTTP headers scoped to the URL's origin |
950
+ | `--executable-path <path>` | Custom browser executable (or `AGENT_BROWSER_EXECUTABLE_PATH` env) |
951
+ | `--extension <path>` | Load browser extension (repeatable; or `AGENT_BROWSER_EXTENSIONS` env) |
952
+ | `--init-script <path>` | Register a page init script before the first navigation (repeatable; or `AGENT_BROWSER_INIT_SCRIPTS` env) |
953
+ | `--enable <feature>` | Built-in init scripts: `react-devtools` (repeatable or comma-list; or `AGENT_BROWSER_ENABLE` env) |
954
+ | `--args <args>` | Browser launch args, comma or newline separated (or `AGENT_BROWSER_ARGS` env) |
955
+ | `--user-agent <ua>` | Custom User-Agent string (or `AGENT_BROWSER_USER_AGENT` env) |
956
+ | `--proxy <url>` | Proxy server URL with optional auth (or `AGENT_BROWSER_PROXY` env) |
957
+ | `--proxy-bypass <hosts>` | Hosts to bypass proxy (or `AGENT_BROWSER_PROXY_BYPASS` env) |
958
+ | `--ignore-https-errors` | Ignore HTTPS certificate errors (useful for self-signed certs) |
959
+ | `--allow-file-access` | Allow file:// URLs to access local files (Chromium only) |
960
+ | `--hide-scrollbars <bool>` | Hide native scrollbars in headless Chromium screenshots, enabled by default (or `AGENT_BROWSER_HIDE_SCROLLBARS` env) |
961
+ | `-p, --provider <name>` | Browser provider, including configured `browser.provider` plugins (or `AGENT_BROWSER_PROVIDER` env) |
962
+ | `--device <name>` | iOS device name, e.g. "iPhone 15 Pro" (or `AGENT_BROWSER_IOS_DEVICE` env) |
963
+ | `--json` | JSON output (for agents) |
964
+ | `--annotate` | Annotated screenshot with numbered element labels (or `AGENT_BROWSER_ANNOTATE` env) |
965
+ | `--screenshot-dir <path>` | Default screenshot output directory (or `AGENT_BROWSER_SCREENSHOT_DIR` env) |
966
+ | `--screenshot-quality <n>` | JPEG quality 0-100 (or `AGENT_BROWSER_SCREENSHOT_QUALITY` env) |
967
+ | `--screenshot-format <fmt>` | Screenshot format: `png`, `jpeg` (or `AGENT_BROWSER_SCREENSHOT_FORMAT` env) |
968
+ | `--headed` | Show browser window (not headless) (or `AGENT_BROWSER_HEADED` env) |
969
+ | `--webgpu` | Enable WebGPU; SwiftShader software Vulkan on Linux, no GPU required (or `AGENT_BROWSER_WEBGPU` env) |
970
+ | `--cdp <port\|url>` | Connect via Chrome DevTools Protocol (port or WebSocket URL) |
971
+ | `--auto-connect` | Auto-discover and connect to running Chrome (or `AGENT_BROWSER_AUTO_CONNECT` env) |
972
+ | `--color-scheme <scheme>` | Color scheme: `dark`, `light`, `no-preference` (or `AGENT_BROWSER_COLOR_SCHEME` env) |
973
+ | `--download-path <path>` | Default download directory (or `AGENT_BROWSER_DOWNLOAD_PATH` env) |
974
+ | `--content-boundaries` | Wrap page output in boundary markers for LLM safety (or `AGENT_BROWSER_CONTENT_BOUNDARIES` env) |
975
+ | `--max-output <chars>` | Truncate page output to N characters (or `AGENT_BROWSER_MAX_OUTPUT` env) |
976
+ | `--allowed-domains <list>` | Comma-separated allowed domain patterns; also disables WebRTC peer connections in supported Chromium sessions and rejects CDP, auto-connect, Chrome profiles, restore/state replay, direct-page provider plugins, unsafe startup `--args`, iOS, and Safari (or `AGENT_BROWSER_ALLOWED_DOMAINS` env) |
977
+ | `--action-policy <path>` | Path to action policy JSON file (or `AGENT_BROWSER_ACTION_POLICY` env) |
978
+ | `--confirm-actions <list>` | Action categories requiring confirmation (or `AGENT_BROWSER_CONFIRM_ACTIONS` env) |
979
+ | `--confirm-interactive` | Interactive confirmation prompts; auto-denies if stdin is not a TTY (or `AGENT_BROWSER_CONFIRM_INTERACTIVE` env) |
980
+ | `--engine <name>` | Browser engine: `chrome` (default), `lightpanda` (or `AGENT_BROWSER_ENGINE` env) |
981
+ | `--idle-timeout <time>` | Shut down the daemon after inactivity (`10s`, `3m`, `1h`, or raw ms). Defaults to `1h`; use `0` to disable (or `AGENT_BROWSER_IDLE_TIMEOUT_MS` env) |
982
+ | `--no-auto-dialog` | Disable automatic dismissal of `alert`/`beforeunload` dialogs (or `AGENT_BROWSER_NO_AUTO_DIALOG` env) |
983
+ | `--model <name>` | AI model for chat command (or `AI_GATEWAY_MODEL` env) |
984
+ | `-v`, `--verbose` | Show tool commands and their raw output (chat) |
985
+ | `-q`, `--quiet` | Show only AI text responses, hide tool calls (chat) |
986
+ | `--config <path>` | Use a custom config file (or `AGENT_BROWSER_CONFIG` env) |
987
+ | `--debug` | Debug output |
988
+
989
+ ## Observability Dashboard
990
+
991
+ Monitor agent-browser sessions in real time with a local web dashboard showing a live viewport and command activity feed.
992
+
993
+ ```bash
994
+ # Start the dashboard server (runs in background on port 4848)
995
+ agent-browser dashboard start
996
+ agent-browser dashboard start --port 8080 # Custom port
997
+
998
+ # All sessions are automatically visible in the dashboard
999
+ agent-browser open example.com
1000
+
1001
+ # Stop the dashboard
1002
+ agent-browser dashboard stop
1003
+ ```
1004
+
1005
+ The dashboard runs as a standalone background process on port 4848, independent of browser sessions. It stays available even when no sessions are running, and it works from `http://localhost:4848` or a proxied/forwarded URL that reaches the dashboard server, such as `https://dashboard.agent-browser.localhost` or a Coder workspace URL. The browser stays on the dashboard origin; session-specific tabs, status, and stream traffic are proxied internally, so session ports do not need to be exposed.
1006
+
1007
+ The dashboard displays:
1008
+ - **Live viewport**: real-time JPEG frames from the browser
1009
+ - **Activity feed**: chronological command/result stream with timing and expandable details
1010
+ - **Console output**: browser console messages (log, warn, error)
1011
+ - **Session creation**: create new sessions from the UI with local engines (Chrome, Lightpanda) or cloud providers (AgentCore, Browserbase, Browserless, Browser Use, Kernel)
1012
+ - **AI Chat**: chat with an AI assistant directly in the dashboard (requires Vercel AI Gateway configuration)
1013
+
1014
+ ### AI Chat
1015
+
1016
+ The dashboard includes an optional AI chat panel powered by the Vercel AI Gateway. The same functionality is available directly from the CLI via the `chat` command. Set these environment variables to enable AI chat:
1017
+
1018
+ ```bash
1019
+ export AI_GATEWAY_API_KEY=gw_your_key_here
1020
+ export AI_GATEWAY_MODEL=anthropic/claude-sonnet-4.6 # optional, this is the default
1021
+ export AI_GATEWAY_URL=https://ai-gateway.vercel.sh # optional, this is the default
1022
+ ```
1023
+
1024
+ **CLI usage:**
1025
+
1026
+ ```bash
1027
+ agent-browser chat "open google.com and search for cats" # Single-shot
1028
+ agent-browser chat # Interactive REPL
1029
+ agent-browser -q chat "summarize this page" # Quiet mode (text only)
1030
+ agent-browser -v chat "fill in the login form" # Verbose (show command output)
1031
+ agent-browser --model openai/gpt-4o chat "take a screenshot" # Override model
1032
+ ```
1033
+
1034
+ The `chat` command translates natural language instructions into agent-browser commands, executes them, and streams the AI response. In interactive mode, type `quit` to exit. Use `--json` for structured output suitable for agent consumption.
1035
+
1036
+ **Dashboard usage:**
1037
+
1038
+ The Chat tab is always visible in the dashboard. When `AI_GATEWAY_API_KEY` is set, the Rust server proxies requests to the gateway and streams responses back using the Vercel AI SDK's UI Message Stream protocol. Without the key, sending a message shows an error inline.
1039
+
1040
+ ## Configuration
1041
+
1042
+ Create an `agent-browser.json` file to set persistent defaults instead of repeating flags on every command.
1043
+
1044
+ **Locations (lowest to highest priority):**
1045
+
1046
+ 1. `~/.agent-browser/config.json`: user-level defaults
1047
+ 2. `./agent-browser.json`: project-level overrides (in working directory)
1048
+ 3. `AGENT_BROWSER_*` environment variables override config file values
1049
+ 4. CLI flags override everything
1050
+
1051
+ **Example `agent-browser.json`:**
1052
+
1053
+ ```json
1054
+ {
1055
+ "headed": true,
1056
+ "proxy": "http://localhost:8080",
1057
+ "profile": "./browser-data",
1058
+ "userAgent": "my-agent/1.0",
1059
+ "hideScrollbars": false,
1060
+ "ignoreHttpsErrors": true,
1061
+ "plugins": [
1062
+ {
1063
+ "name": "vault",
1064
+ "command": "agent-browser-plugin-vault",
1065
+ "capabilities": ["credential.read"]
1066
+ }
1067
+ ]
1068
+ }
1069
+ ```
1070
+
1071
+ Use `--config <path>` or `AGENT_BROWSER_CONFIG` to load a specific config file instead of the defaults:
1072
+
1073
+ ```bash
1074
+ agent-browser --config ./ci-config.json open example.com
1075
+ AGENT_BROWSER_CONFIG=./ci-config.json agent-browser open example.com
1076
+ ```
1077
+
1078
+ All options from the table above can be set in the config file using camelCase keys (e.g., `--executable-path` becomes `"executablePath"`, `--proxy-bypass` becomes `"proxyBypass"`). Plugins are configured with the `"plugins"` array shown above. Unknown keys are ignored for forward compatibility.
1079
+
1080
+ A [JSON Schema](agent-browser.schema.json) is available for IDE autocomplete and validation. Add a `$schema` key to your config file to enable it:
1081
+
1082
+ ```json
1083
+ {
1084
+ "$schema": "https://agent-browser.dev/schema.json",
1085
+ "headed": true
1086
+ }
1087
+ ```
1088
+
1089
+ Boolean flags accept an optional `true`/`false` value to override config settings. For example, `--headed false` disables `"headed": true` from config. A bare `--headed` is equivalent to `--headed true`.
1090
+
1091
+ Auto-discovered config files that are missing are silently ignored. If `--config <path>` points to a missing or invalid file, agent-browser exits with an error. Extensions from user and project configs are merged (concatenated), not replaced.
1092
+
1093
+ > **Tip:** If your project-level `agent-browser.json` contains environment-specific values (paths, proxies), consider adding it to `.gitignore`.
1094
+
1095
+ ## Default Timeout
1096
+
1097
+ The default timeout for standard operations (clicks, waits, fills, etc.) is 25 seconds. This is intentionally below the CLI's 30-second IPC read timeout so that the daemon returns a proper error instead of the CLI timing out with EAGAIN.
1098
+
1099
+ Override the default timeout via environment variable:
1100
+
1101
+ ```bash
1102
+ # Set a longer timeout for slow pages (in milliseconds)
1103
+ export AGENT_BROWSER_DEFAULT_TIMEOUT=45000
1104
+ ```
1105
+
1106
+ > **Note:** Setting this above 30000 (30s) may cause EAGAIN errors on slow operations because the CLI's read timeout will expire before the daemon responds. The CLI retries transient errors automatically, but response times will increase.
1107
+
1108
+ | Variable | Description |
1109
+ | ------------------------------- | ---------------------------------------- |
1110
+ | `AGENT_BROWSER_DEFAULT_TIMEOUT` | Default operation timeout in ms (default: 25000) |
1111
+
1112
+ ## Selectors
1113
+
1114
+ ### Refs (Recommended for AI)
1115
+
1116
+ Refs provide deterministic element selection from snapshots:
1117
+
1118
+ ```bash
1119
+ # 1. Get snapshot with refs
1120
+ agent-browser snapshot
1121
+ # Output:
1122
+ # - heading "Example Domain" [ref=e1] [level=1]
1123
+ # - button "Submit" [ref=e2]
1124
+ # - textbox "Email" [ref=e3]
1125
+ # - link "Learn more" [ref=e4]
1126
+
1127
+ # 2. Use refs to interact
1128
+ agent-browser click @e2 # Click the button
1129
+ agent-browser fill @e3 "test@example.com" # Fill the textbox
1130
+ agent-browser get text @e1 # Get heading text
1131
+ agent-browser hover @e4 # Hover the link
1132
+ ```
1133
+
1134
+ When a ref click is blocked by an overlay, the error includes the covering element, such as `covered by <div#consent-banner>`. Click the banner or dialog control first, then run `snapshot` again before reusing refs.
1135
+
1136
+ **Why use refs?**
1137
+
1138
+ - **Deterministic**: Ref points to exact element from snapshot
1139
+ - **Fast**: No DOM re-query needed
1140
+ - **AI-friendly**: Snapshot + ref workflow is optimal for LLMs
1141
+
1142
+ ### CSS Selectors
1143
+
1144
+ ```bash
1145
+ agent-browser click "#id"
1146
+ agent-browser click ".class"
1147
+ agent-browser click "div > button"
1148
+ ```
1149
+
1150
+ ### Text & XPath
1151
+
1152
+ ```bash
1153
+ agent-browser click "text=Submit"
1154
+ agent-browser click "xpath=//button"
1155
+ ```
1156
+
1157
+ ### Semantic Locators
1158
+
1159
+ ```bash
1160
+ agent-browser find role button click --name "Submit"
1161
+ agent-browser find label "Email" fill "test@test.com"
1162
+ ```
1163
+
1164
+ ## Agent Mode
1165
+
1166
+ Use `--json` for machine-readable output:
1167
+
1168
+ ```bash
1169
+ agent-browser snapshot --json
1170
+ # Returns: {"success":true,"data":{"snapshot":"...","refs":{"e1":{"role":"heading","name":"Title"},...}}}
1171
+
1172
+ agent-browser get text @e1 --json
1173
+ agent-browser is visible @e2 --json
1174
+ ```
1175
+
1176
+ ### Optimal AI Workflow
1177
+
1178
+ ```bash
1179
+ # 1. Navigate and get snapshot
1180
+ agent-browser open example.com
1181
+ agent-browser snapshot -i --json # AI parses tree and refs
1182
+
1183
+ # 2. AI identifies target refs from snapshot
1184
+ # 3. Execute actions using refs
1185
+ agent-browser click @e2
1186
+ agent-browser fill @e3 "input text"
1187
+
1188
+ # 4. Get new snapshot if page changed
1189
+ agent-browser snapshot -i --json
1190
+ ```
1191
+
1192
+ ### Command Chaining
1193
+
1194
+ Commands can be chained with `&&` in a single shell invocation. The browser persists via a background daemon, so chaining is safe and more efficient:
1195
+
1196
+ ```bash
1197
+ # Open, wait for load, and snapshot in one call
1198
+ agent-browser open example.com && agent-browser wait --load networkidle && agent-browser snapshot -i
1199
+
1200
+ # Chain multiple interactions
1201
+ agent-browser fill @e1 "user@example.com" && agent-browser fill @e2 "pass" && agent-browser click @e3
1202
+
1203
+ # Navigate and screenshot
1204
+ agent-browser open example.com && agent-browser wait --load networkidle && agent-browser screenshot page.png
1205
+ ```
1206
+
1207
+ Use `&&` when you don't need intermediate output. Run commands separately when you need to parse output first (e.g., snapshot to discover refs before interacting).
1208
+
1209
+ ## Headed Mode
1210
+
1211
+ Show the browser window for debugging:
1212
+
1213
+ ```bash
1214
+ agent-browser open example.com --headed
1215
+ ```
1216
+
1217
+ This opens a visible browser window instead of running headless.
1218
+
1219
+ On Linux hosts with no display (servers, containers), `--headed` still works: when `DISPLAY` is unset and Xvfb is installed, agent-browser starts a private virtual display for the browser and cleans it up on close (opt out with `AGENT_BROWSER_NO_XVFB=1`). Needed for [WebGPU screenshots](#webgpu), and useful for extensions that misbehave headless.
1220
+
1221
+ > **Note:** Browser extensions work in both headed and headless mode (Chrome's `--headless=new`).
1222
+
1223
+ ## WebGPU
1224
+
1225
+ Headless Chrome does not expose WebGPU by default, so pages using it (three.js `WebGPURenderer`, Babylon.js, etc.) silently render black. The `--webgpu` flag enables a launch preset that makes WebGPU work, including in GPU-less containers and CI:
1226
+
1227
+ ```bash
1228
+ agent-browser --webgpu open https://my-webgpu-app.example.com
1229
+ agent-browser screenshot app.png
1230
+ ```
1231
+
1232
+ On macOS and Windows this uses the hardware Metal/D3D backend. On Linux it routes WebGPU through SwiftShader's software Vulkan (no GPU needed), which requires the system Vulkan loader and Mesa ICD:
1233
+
1234
+ ```bash
1235
+ apt-get install -y libvulkan1 mesa-vulkan-drivers
1236
+ ```
1237
+
1238
+ One upstream caveat: headless Chrome cannot capture WebGPU canvas presentation in screenshots on Windows and Linux (rendering and in-page readbacks work; the capture is black). Screenshots of WebGPU pages work headless on macOS; on Windows run `--headed` in a logged-in desktop session; on Linux just add `--headed` — when no `DISPLAY` is set and Xvfb is installed, agent-browser starts a private virtual display automatically (opt out with `AGENT_BROWSER_NO_XVFB=1`).
1239
+
1240
+ Verify the full pipeline (adapter, render pass, and screenshot capture) with:
1241
+
1242
+ ```bash
1243
+ agent-browser doctor --webgpu
1244
+ ```
1245
+
1246
+ Notes for WebGPU pages:
1247
+
1248
+ - WebGPU only exists in secure contexts (`https://`, `http://localhost`, or `file://`).
1249
+ - three.js `WebGPURenderer` initializes asynchronously and silently falls back to WebGL2 when no adapter is available — wait for the app to render its first frame before taking a screenshot.
1250
+ - To prefer a real GPU on Linux instead of SwiftShader, override both the Vulkan driver and the adapter with `--args "--use-vulkan=native,--use-webgpu-adapter=default"` (user args win over the preset; `--use-webgpu-adapter` alone still enumerates only SwiftShader).
1251
+
1252
+ See the [WebGPU docs page](https://agent-browser.dev/webgpu) for the full platform matrix and container recipe.
1253
+
1254
+ ## Authenticated Sessions
1255
+
1256
+ Use `--headers` to set HTTP headers for a specific origin, enabling authentication without login flows:
1257
+
1258
+ ```bash
1259
+ # Headers are scoped to api.example.com only
1260
+ agent-browser open api.example.com --headers '{"Authorization": "Bearer <token>"}'
1261
+
1262
+ # Requests to api.example.com include the auth header
1263
+ agent-browser snapshot -i --json
1264
+ agent-browser click @e2
1265
+
1266
+ # Navigate to another domain - headers are NOT sent (safe!)
1267
+ agent-browser open other-site.com
1268
+ ```
1269
+
1270
+ This is useful for:
1271
+
1272
+ - **Skipping login flows** - Authenticate via headers instead of UI
1273
+ - **Switching users** - Start new sessions with different auth tokens
1274
+ - **API testing** - Access protected endpoints directly
1275
+ - **Security** - Headers are scoped to the origin, not leaked to other domains
1276
+
1277
+ To set headers for multiple origins, use `--headers` with each `open` command:
1278
+
1279
+ ```bash
1280
+ agent-browser open api.example.com --headers '{"Authorization": "Bearer token1"}'
1281
+ agent-browser open api.acme.com --headers '{"Authorization": "Bearer token2"}'
1282
+ ```
1283
+
1284
+ For global headers (all domains), use `set headers`:
1285
+
1286
+ ```bash
1287
+ agent-browser set headers '{"X-Custom-Header": "value"}'
1288
+ ```
1289
+
1290
+ ## Custom Browser Executable
1291
+
1292
+ Use a custom browser executable instead of the bundled Chromium. This is useful for:
1293
+
1294
+ - **Serverless deployment**: Use lightweight Chromium builds like `@sparticuz/chromium` (~50MB vs ~684MB)
1295
+ - **System browsers**: Use an existing Chrome/Chromium installation
1296
+ - **Custom builds**: Use modified browser builds
1297
+
1298
+ ### CLI Usage
1299
+
1300
+ ```bash
1301
+ # Via flag
1302
+ agent-browser --executable-path /path/to/chromium open example.com
1303
+
1304
+ # Via environment variable
1305
+ AGENT_BROWSER_EXECUTABLE_PATH=/path/to/chromium agent-browser open example.com
1306
+ ```
1307
+
1308
+ ### Serverless (Vercel)
1309
+
1310
+ Run agent-browser + Chrome in an ephemeral Vercel Sandbox microVM. No external server needed:
1311
+
1312
+ ```typescript
1313
+ import { runAgentBrowserCommand, withAgentBrowserSandbox } from "@agent-browser/sandbox/vercel";
1314
+
1315
+ const result = await withAgentBrowserSandbox(async (sandbox) => {
1316
+ await runAgentBrowserCommand(sandbox, ["open", "https://example.com"]);
1317
+ return runAgentBrowserCommand(sandbox, ["screenshot"]);
1318
+ });
1319
+ ```
1320
+
1321
+ Install `@agent-browser/sandbox` and `@vercel/sandbox` in the consuming app. See the [sandbox helper example](examples/sandbox/) for minimal Vercel Sandbox usage, or the [environments example](examples/environments/) for a full UI demo with a deploy-to-Vercel button.
1322
+
1323
+ Fresh Vercel and eve sandboxes install Chromium system dependencies by default. Pass `installSystemDependencies: false` only when your sandbox image already includes those libraries.
1324
+
1325
+ ### eve extension
1326
+
1327
+ Give an [eve](https://eve.dev) agent the full browser tool set by mounting the [`@agent-browser/eve`](packages/@agent-browser/eve/) extension:
1328
+
1329
+ ```typescript
1330
+ // agent/extensions/browser.ts
1331
+ import browser from "@agent-browser/eve";
1332
+
1333
+ export default browser({});
1334
+ ```
1335
+
1336
+ This composes ~20 namespaced tools into the agent — `browser__navigate`, `browser__snapshot`, `browser__click`, `browser__fill`, `browser__find`, `browser__screenshot`, and more — all running agent-browser inside the agent's sandbox. agent-browser installs automatically on first use; pre-install it in `agent/sandbox.ts` with the `@agent-browser/eve/sandbox` helpers to bake the cost into the sandbox template instead. Configuration (domain allowlists, output limits, session naming) and per-tool overrides are covered in the [package README](packages/@agent-browser/eve/README.md), and the [eve example](examples/eve/) is a complete app with the extension mounted.
1337
+
1338
+ ### Serverless (AWS Lambda)
1339
+
1340
+ ```typescript
1341
+ import chromium from '@sparticuz/chromium';
1342
+ import { execSync } from 'child_process';
1343
+
1344
+ export async function handler() {
1345
+ const executablePath = await chromium.executablePath();
1346
+ const result = execSync(
1347
+ `AGENT_BROWSER_EXECUTABLE_PATH=${executablePath} agent-browser open https://example.com && agent-browser snapshot -i --json`,
1348
+ { encoding: 'utf-8' }
1349
+ );
1350
+ return JSON.parse(result);
1351
+ }
1352
+ ```
1353
+
1354
+ ## Local Files
1355
+
1356
+ Open and interact with local files (PDFs, HTML, etc.) using `file://` URLs:
1357
+
1358
+ ```bash
1359
+ # Enable file access (required for JavaScript to access local files)
1360
+ agent-browser --allow-file-access open file:///path/to/document.pdf
1361
+ agent-browser --allow-file-access open file:///path/to/page.html
1362
+
1363
+ # Take screenshot of a local PDF
1364
+ agent-browser --allow-file-access open file:///Users/me/report.pdf
1365
+ agent-browser screenshot report.png
1366
+ ```
1367
+
1368
+ The `--allow-file-access` flag adds Chromium flags (`--allow-file-access-from-files`, `--allow-file-access`) that allow `file://` URLs to:
1369
+
1370
+ - Load and render local files
1371
+ - Access other local files via JavaScript (XHR, fetch)
1372
+ - Load local resources (images, scripts, stylesheets)
1373
+
1374
+ **Note:** This flag only works with Chromium. For security, it's disabled by default.
1375
+
1376
+ ## CDP Mode
1377
+
1378
+ Connect to an existing browser via Chrome DevTools Protocol:
1379
+
1380
+ ```bash
1381
+ # Start Chrome with: google-chrome --remote-debugging-port=9222
1382
+
1383
+ # Connect once, then run commands without --cdp
1384
+ agent-browser connect 9222
1385
+ agent-browser snapshot
1386
+ agent-browser tab
1387
+ agent-browser close
1388
+
1389
+ # Or pass --cdp on each command
1390
+ agent-browser --cdp 9222 snapshot
1391
+
1392
+ # Connect to remote browser via WebSocket URL
1393
+ agent-browser --cdp "wss://your-browser-service.com/cdp?token=..." snapshot
1394
+ ```
1395
+
1396
+ The `--cdp` flag accepts either:
1397
+
1398
+ - A port number (e.g., `9222`) for local connections via `http://localhost:{port}`
1399
+ - A full WebSocket URL (e.g., `wss://...` or `ws://...`) for remote browser services
1400
+
1401
+ This enables control of:
1402
+
1403
+ - Electron apps
1404
+ - Chrome/Chromium instances with remote debugging
1405
+ - WebView2 applications
1406
+ - Any browser exposing a CDP endpoint
1407
+
1408
+ ### Auto-Connect
1409
+
1410
+ Use `--auto-connect` to automatically discover and connect to a running Chrome instance without specifying a port:
1411
+
1412
+ ```bash
1413
+ # Auto-discover running Chrome with remote debugging
1414
+ agent-browser --auto-connect open example.com
1415
+ agent-browser --auto-connect snapshot
1416
+
1417
+ # Or via environment variable
1418
+ AGENT_BROWSER_AUTO_CONNECT=1 agent-browser snapshot
1419
+ ```
1420
+
1421
+ Auto-connect discovers Chrome by:
1422
+
1423
+ 1. Reading Chrome's `DevToolsActivePort` file from the default user data directory
1424
+ 2. Falling back to probing common debugging ports (9222, 9229)
1425
+ 3. If HTTP-based discovery (`/json/version`, `/json/list`) fails, falling back to a direct WebSocket connection
1426
+
1427
+ This is useful when:
1428
+
1429
+ - Chrome 144+ has remote debugging enabled via `chrome://inspect/#remote-debugging` (which uses a dynamic port)
1430
+ - You want a zero-configuration connection to your existing browser
1431
+ - You don't want to track which port Chrome is using
1432
+
1433
+ ## Streaming (Browser Preview)
1434
+
1435
+ Stream the browser viewport via WebSocket for live preview or "pair browsing" where a human can watch and interact alongside an AI agent.
1436
+
1437
+ ### Streaming
1438
+
1439
+ Every session automatically starts a WebSocket stream server on an OS-assigned port. Use `stream status` to see the bound port and connection state:
1440
+
1441
+ ```bash
1442
+ agent-browser stream status
1443
+ ```
1444
+
1445
+ To bind to a specific port, set `AGENT_BROWSER_STREAM_PORT`:
1446
+
1447
+ ```bash
1448
+ AGENT_BROWSER_STREAM_PORT=9223 agent-browser open example.com
1449
+ ```
1450
+
1451
+ You can also manage streaming at runtime with `stream enable`, `stream disable`, and `stream status`:
1452
+
1453
+ ```bash
1454
+ agent-browser stream enable --port 9223 # Re-enable on a specific port
1455
+ agent-browser stream disable # Stop streaming for the session
1456
+ ```
1457
+
1458
+ The WebSocket server streams the browser viewport and accepts input events.
1459
+
1460
+ ### WebSocket Protocol
1461
+
1462
+ Connect to `ws://localhost:9223` to receive frames and send input:
1463
+
1464
+ **Receive frames:**
1465
+
1466
+ ```json
1467
+ {
1468
+ "type": "frame",
1469
+ "data": "<base64-encoded-jpeg>",
1470
+ "metadata": {
1471
+ "deviceWidth": 1280,
1472
+ "deviceHeight": 720,
1473
+ "pageScaleFactor": 1,
1474
+ "offsetTop": 0,
1475
+ "scrollOffsetX": 0,
1476
+ "scrollOffsetY": 0
1477
+ }
1478
+ }
1479
+ ```
1480
+
1481
+ **Send mouse events:**
1482
+
1483
+ ```json
1484
+ {
1485
+ "type": "input_mouse",
1486
+ "eventType": "mousePressed",
1487
+ "x": 100,
1488
+ "y": 200,
1489
+ "button": "left",
1490
+ "clickCount": 1
1491
+ }
1492
+ ```
1493
+
1494
+ **Send keyboard events:**
1495
+
1496
+ ```json
1497
+ {
1498
+ "type": "input_keyboard",
1499
+ "eventType": "keyDown",
1500
+ "key": "Enter",
1501
+ "code": "Enter"
1502
+ }
1503
+ ```
1504
+
1505
+ **Send touch events:**
1506
+
1507
+ ```json
1508
+ {
1509
+ "type": "input_touch",
1510
+ "eventType": "touchStart",
1511
+ "touchPoints": [{ "x": 100, "y": 200 }]
1512
+ }
1513
+ ```
1514
+
1515
+ ## Architecture
1516
+
1517
+ agent-browser uses a client-daemon architecture:
1518
+
1519
+ 1. **Rust CLI** - Parses commands, communicates with daemon
1520
+ 2. **Rust Daemon** - Pure Rust daemon using direct CDP, no Node.js required
1521
+
1522
+ The daemon starts automatically on first command and persists between commands for fast subsequent operations. After **1 hour** with no commands or dashboard input it saves configured restore state, closes the browser, and exits, so an integration that dies without calling `close` cannot leak the daemon and its browser indefinitely; the next command starts a fresh daemon and configured state restore works as usual. A session without `--restore` or another restore key does not save browser state, so its transient state and open tabs are discarded at shutdown. Set `--idle-timeout` to a duration such as `30s`, `5m`, or `1h`, or set `AGENT_BROWSER_IDLE_TIMEOUT_MS` to a value in milliseconds. Use `0` to disable idle shutdown entirely. The default never closes a headed browser, including Safari and iOS WebDriver sessions, or a user-attached browser because those may be in direct human use. Provider-owned cloud browsers remain eligible for cleanup. An explicitly set timeout applies to every browser.
1523
+
1524
+ **Browser Engine:** Uses Chrome (from Chrome for Testing) by default. The `--engine` flag selects between `chrome` and `lightpanda`. Supported browsers: Chromium/Chrome (via CDP) and Safari (via WebDriver for iOS).
1525
+
1526
+ ## Platforms
1527
+
1528
+ | Platform | Binary |
1529
+ | ----------- | ----------- |
1530
+ | macOS ARM64 | Native Rust |
1531
+ | macOS x64 | Native Rust |
1532
+ | Linux ARM64 | Native Rust |
1533
+ | Linux x64 | Native Rust |
1534
+ | Windows x64 | Native Rust |
1535
+
1536
+ ## Usage with AI Agents
1537
+
1538
+ ### Just ask the agent
1539
+
1540
+ The simplest approach is to tell your agent to use it:
1541
+
1542
+ ```
1543
+ Use agent-browser to test the login flow. Run agent-browser --help to see available commands.
1544
+ ```
1545
+
1546
+ The `--help` output is comprehensive and most agents can figure it out from there.
1547
+
1548
+ ### AI Coding Assistants (recommended)
1549
+
1550
+ Add the skill to your AI coding assistant for richer context:
1551
+
1552
+ ```bash
1553
+ npx skills add vercel-labs/agent-browser
1554
+ ```
1555
+
1556
+ This works with Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Goose, OpenCode, and Windsurf. The skill is fetched from the repository, so it stays up to date automatically. Do not copy `SKILL.md` from `node_modules` as it will become stale.
1557
+
1558
+ ### Claude Code
1559
+
1560
+ Install as a Claude Code skill:
1561
+
1562
+ ```bash
1563
+ npx skills add vercel-labs/agent-browser
1564
+ ```
1565
+
1566
+ This adds a thin discovery stub at `.claude/skills/agent-browser/SKILL.md`. The stub is intentionally minimal — it points Claude Code at `agent-browser skills get core` to load the actual workflow content at runtime. This way the instructions always match the installed CLI version instead of going stale between releases.
1567
+
1568
+ ### AGENTS.md / CLAUDE.md
1569
+
1570
+ For more consistent results, add to your project or global instructions file:
1571
+
1572
+ ```markdown
1573
+ ## Browser Automation
1574
+
1575
+ Use `agent-browser` for web automation. Run `agent-browser --help` for all commands.
1576
+
1577
+ Core workflow:
1578
+
1579
+ 1. `agent-browser open <url>` - Navigate to page
1580
+ 2. `agent-browser snapshot -i` - Get interactive elements with refs (@e1, @e2)
1581
+ 3. `agent-browser click @e1` / `fill @e2 "text"` - Interact using refs
1582
+ 4. Re-snapshot after page changes
1583
+ ```
1584
+
1585
+ ## Integrations
1586
+
1587
+ ### iOS Simulator
1588
+
1589
+ Control real Mobile Safari in the iOS Simulator for authentic mobile web testing. Requires macOS with Xcode.
1590
+
1591
+ **Setup:**
1592
+
1593
+ ```bash
1594
+ # Install Appium and XCUITest driver
1595
+ npm install -g appium
1596
+ appium driver install xcuitest
1597
+ ```
1598
+
1599
+ **Usage:**
1600
+
1601
+ ```bash
1602
+ # List available iOS simulators
1603
+ agent-browser device list
1604
+
1605
+ # Launch Safari on a specific device
1606
+ agent-browser -p ios --device "iPhone 16 Pro" open https://example.com
1607
+
1608
+ # Same commands as desktop
1609
+ agent-browser -p ios snapshot -i
1610
+ agent-browser -p ios tap @e1
1611
+ agent-browser -p ios fill @e2 "text"
1612
+ agent-browser -p ios screenshot mobile.png
1613
+
1614
+ # Mobile-specific commands
1615
+ agent-browser -p ios swipe up
1616
+ agent-browser -p ios swipe down 500
1617
+
1618
+ # Close session
1619
+ agent-browser -p ios close
1620
+ ```
1621
+
1622
+ Or use environment variables:
1623
+
1624
+ ```bash
1625
+ export AGENT_BROWSER_PROVIDER=ios
1626
+ export AGENT_BROWSER_IOS_DEVICE="iPhone 16 Pro"
1627
+ agent-browser open https://example.com
1628
+ ```
1629
+
1630
+ | Variable | Description |
1631
+ | -------------------------- | ----------------------------------------------- |
1632
+ | `AGENT_BROWSER_PROVIDER` | Set to `ios` to enable iOS mode |
1633
+ | `AGENT_BROWSER_IOS_DEVICE` | Device name (e.g., "iPhone 16 Pro", "iPad Pro") |
1634
+ | `AGENT_BROWSER_IOS_UDID` | Device UDID (alternative to device name) |
1635
+
1636
+ **Supported devices:** All iOS Simulators available in Xcode (iPhones, iPads), plus real iOS devices.
1637
+
1638
+ **Note:** The iOS provider boots the simulator, starts Appium, and controls Safari. First launch takes ~30-60 seconds; subsequent commands are fast.
1639
+
1640
+ #### Real Device Support
1641
+
1642
+ Appium also supports real iOS devices connected via USB. This requires additional one-time setup:
1643
+
1644
+ **1. Get your device UDID:**
1645
+
1646
+ ```bash
1647
+ xcrun xctrace list devices
1648
+ # or
1649
+ system_profiler SPUSBDataType | grep -A 5 "iPhone\|iPad"
1650
+ ```
1651
+
1652
+ **2. Sign WebDriverAgent (one-time):**
1653
+
1654
+ ```bash
1655
+ # Open the WebDriverAgent Xcode project
1656
+ cd ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent
1657
+ open WebDriverAgent.xcodeproj
1658
+ ```
1659
+
1660
+ In Xcode:
1661
+
1662
+ - Select the `WebDriverAgentRunner` target
1663
+ - Go to Signing & Capabilities
1664
+ - Select your Team (requires Apple Developer account, free tier works)
1665
+ - Let Xcode manage signing automatically
1666
+
1667
+ **3. Use with agent-browser:**
1668
+
1669
+ ```bash
1670
+ # Connect device via USB, then:
1671
+ agent-browser -p ios --device "<DEVICE_UDID>" open https://example.com
1672
+
1673
+ # Or use the device name if unique
1674
+ agent-browser -p ios --device "John's iPhone" open https://example.com
1675
+ ```
1676
+
1677
+ **Real device notes:**
1678
+
1679
+ - First run installs WebDriverAgent to the device (may require Trust prompt)
1680
+ - Device must be unlocked and connected via USB
1681
+ - Slightly slower initial connection than simulator
1682
+ - Tests against real Safari performance and behavior
1683
+
1684
+ ### Browserless
1685
+
1686
+ [Browserless](https://browserless.io) provides cloud browser infrastructure with a Sessions API. Use it when running agent-browser in environments where a local browser isn't available.
1687
+
1688
+ To enable Browserless, use the `-p` flag:
1689
+
1690
+ ```bash
1691
+ export BROWSERLESS_API_KEY="your-api-token"
1692
+ agent-browser -p browserless open https://example.com
1693
+ ```
1694
+
1695
+ Or use environment variables for CI/scripts:
1696
+
1697
+ ```bash
1698
+ export AGENT_BROWSER_PROVIDER=browserless
1699
+ export BROWSERLESS_API_KEY="your-api-token"
1700
+ agent-browser open https://example.com
1701
+ ```
1702
+
1703
+ Optional configuration via environment variables:
1704
+
1705
+ | Variable | Description | Default |
1706
+ | -------------------------- | ------------------------------------------------ | --------------------------------------- |
1707
+ | `BROWSERLESS_API_URL` | Base API URL (for custom regions or self-hosted) | `https://production-sfo.browserless.io` |
1708
+ | `BROWSERLESS_BROWSER_TYPE` | Type of browser to use (chromium or chrome) | chromium |
1709
+ | `BROWSERLESS_TTL` | Session TTL in milliseconds | `300000` |
1710
+ | `BROWSERLESS_STEALTH` | Enable stealth mode (`true`/`false`) | `true` |
1711
+
1712
+ When enabled, agent-browser connects to a Browserless cloud session instead of launching a local browser. All commands work identically.
1713
+
1714
+ Get your API token from the [Browserless Dashboard](https://browserless.io).
1715
+
1716
+ ### Browserbase
1717
+
1718
+ [Browserbase](https://browserbase.com) provides remote browser infrastructure to make deployment of agentic browsing agents easy. Use it when running the agent-browser CLI in an environment where a local browser isn't feasible.
1719
+
1720
+ To enable Browserbase, use the `-p` flag:
1721
+
1722
+ ```bash
1723
+ export BROWSERBASE_API_KEY="your-api-key"
1724
+ agent-browser -p browserbase open https://example.com
1725
+ ```
1726
+
1727
+ Or use environment variables for CI/scripts:
1728
+
1729
+ ```bash
1730
+ export AGENT_BROWSER_PROVIDER=browserbase
1731
+ export BROWSERBASE_API_KEY="your-api-key"
1732
+ agent-browser open https://example.com
1733
+ ```
1734
+
1735
+ When enabled, agent-browser connects to a Browserbase session instead of launching a local browser. All commands work identically.
1736
+
1737
+ Get your API key from the [Browserbase Dashboard](https://browserbase.com/overview).
1738
+
1739
+ ### Browser Use
1740
+
1741
+ [Browser Use](https://browser-use.com) provides cloud browser infrastructure for AI agents. Use it when running agent-browser in environments where a local browser isn't available (serverless, CI/CD, etc.).
1742
+
1743
+ To enable Browser Use, use the `-p` flag:
1744
+
1745
+ ```bash
1746
+ export BROWSER_USE_API_KEY="your-api-key"
1747
+ agent-browser -p browseruse open https://example.com
1748
+ ```
1749
+
1750
+ Or use environment variables for CI/scripts:
1751
+
1752
+ ```bash
1753
+ export AGENT_BROWSER_PROVIDER=browseruse
1754
+ export BROWSER_USE_API_KEY="your-api-key"
1755
+ agent-browser open https://example.com
1756
+ ```
1757
+
1758
+ When enabled, agent-browser connects to a Browser Use cloud session instead of launching a local browser. All commands work identically.
1759
+
1760
+ Get your API key from the [Browser Use Cloud Dashboard](https://cloud.browser-use.com/settings?tab=api-keys). Free credits are available to get started, with pay-as-you-go pricing after.
1761
+
1762
+ ### Kernel
1763
+
1764
+ [Kernel](https://www.kernel.sh) provides cloud browser infrastructure for AI agents with features like stealth mode and persistent profiles.
1765
+
1766
+ To enable Kernel, use the `-p` flag:
1767
+
1768
+ ```bash
1769
+ export KERNEL_API_KEY="your-api-key"
1770
+ agent-browser -p kernel open https://example.com
1771
+ ```
1772
+
1773
+ Or use environment variables for CI/scripts:
1774
+
1775
+ ```bash
1776
+ export AGENT_BROWSER_PROVIDER=kernel
1777
+ export KERNEL_API_KEY="your-api-key"
1778
+ agent-browser open https://example.com
1779
+ ```
1780
+
1781
+ Optional configuration via environment variables:
1782
+
1783
+ | Variable | Description | Default |
1784
+ | ------------------------ | -------------------------------------------------------------------------------- | ------- |
1785
+ | `KERNEL_HEADLESS` | Run browser in headless mode (`true`/`false`) | `true` |
1786
+ | `KERNEL_STEALTH` | Enable stealth mode to avoid bot detection (`true`/`false`) | `false` |
1787
+ | `KERNEL_TIMEOUT_SECONDS` | Session timeout in seconds | `300` |
1788
+ | `KERNEL_PROFILE_NAME` | Browser profile name for persistent cookies/logins (created if it doesn't exist) | (none) |
1789
+
1790
+ When enabled, agent-browser connects to a Kernel cloud session instead of launching a local browser. All commands work identically.
1791
+
1792
+ **Profile Persistence:** When `KERNEL_PROFILE_NAME` is set, the profile will be created if it doesn't already exist. Cookies, logins, and session data are automatically saved back to the profile when the browser session ends, making them available for future sessions.
1793
+
1794
+ Get your API key from the [Kernel Dashboard](https://dashboard.onkernel.com).
1795
+
1796
+ ### AgentCore
1797
+
1798
+ [AWS Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/) provides cloud browser sessions with SigV4 authentication.
1799
+
1800
+ To enable AgentCore, use the `-p` flag:
1801
+
1802
+ ```bash
1803
+ agent-browser -p agentcore open https://example.com
1804
+ ```
1805
+
1806
+ Or use environment variables for CI/scripts:
1807
+
1808
+ ```bash
1809
+ export AGENT_BROWSER_PROVIDER=agentcore
1810
+ agent-browser open https://example.com
1811
+ ```
1812
+
1813
+ Credentials are automatically resolved from environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) or the AWS CLI (`aws configure export-credentials`), which supports SSO, profiles, and IAM roles.
1814
+
1815
+ Optional configuration via environment variables:
1816
+
1817
+ | Variable | Description | Default |
1818
+ | -------------------------- | -------------------------------------------------------------------- | ---------------- |
1819
+ | `AGENTCORE_REGION` | AWS region for the AgentCore endpoint | `us-east-1` |
1820
+ | `AGENTCORE_BROWSER_ID` | Browser identifier | `aws.browser.v1` |
1821
+ | `AGENTCORE_PROFILE_ID` | Browser profile for persistent state (cookies, localStorage) | (none) |
1822
+ | `AGENTCORE_SESSION_TIMEOUT`| Session timeout in seconds | `3600` |
1823
+ | `AWS_PROFILE` | AWS CLI profile for credential resolution | `default` |
1824
+
1825
+ **Browser profiles:** When `AGENTCORE_PROFILE_ID` is set, browser state (cookies, localStorage) is persisted across sessions automatically.
1826
+
1827
+ When enabled, agent-browser connects to an AgentCore cloud browser session instead of launching a local browser. All commands work identically.
1828
+
1829
+ ## License
1830
+
1831
+ Apache-2.0