Browse — Browser Automation for Agents
Setup
Check if browse is installed:
browse version
If not installed, ask the user before installing. Prefer a pinned release artifact with a published checksum or signature. Do not pipe a mutable remote script directly into bash. If the user approves a convenience installer, download it to a temporary file, show the source URL, inspect or verify it where possible, then execute the local file.
How it works
browse is a CLI that wraps Playwright behind a persistent daemon on a Unix socket. The daemon cold-starts in ~3s on first use, then every command runs in sub-200ms. Session state (cookies, localStorage, auth tokens) persists across commands within a session.
All output is plain text. Objects are JSON-stringified. Commands return non-zero on failure with an error message.
Important constraints:
- Commands are sequential — do not run multiple
browse commands in parallel. The daemon handles one command at a time.
- Run
browse help for the full command list, or browse help <command> for detailed usage and flags.
The ref system — read this first
Refs (@e1, @e2, ...) are how you target elements. They replace CSS selectors for most interactions.
Rules:
- Always
browse snapshot before interacting. Refs only exist after a snapshot.
- Refs are ephemeral. Every
snapshot call regenerates them. Old refs are invalid.
- Refs go stale after navigation. Any
goto or click that changes the page invalidates refs. You'll get a clear error — just browse snapshot again.
Core interaction loop:
browse snapshot # see what's on the page — get refs
browse fill @e3 "test" # fill the search field
browse click @e4 # click a button
browse snapshot # re-snapshot after the page changes
Workflow
The standard pattern for any browser task:
- Navigate:
browse goto <url>
- Observe:
browse snapshot for page structure (interactive elements with refs). Use browse snapshot -i to include structural elements (headings, text), or -f for the full accessibility tree.
- Check for errors:
browse console --level error after navigation.
- Interact:
browse fill @eN "value", browse click @eN, browse hover @eN, browse press Tab, browse select @eN "option", browse scroll @eN (scroll into view).
- Use
browse press <key> for keyboard navigation (Tab, Escape, Enter, ArrowDown, Shift+Tab, etc.). Multiple keys: browse press Tab Tab Tab.
- Use
browse scroll down/up to page through content, browse scroll top/bottom to jump to extremes.
- After clicks that trigger SPA navigation, use
browse wait url /path, browse wait text "Expected", or browse wait visible .selector before snapshotting.
- Verify:
browse snapshot or browse screenshot after each interaction to confirm the result.
- Repeat: Move through pages and flows.
For configured applications, browse healthcheck gives a quick pass/fail across key pages.
Key commands by category
| Category |
Commands |
| Navigate |
goto <url>, url, back, forward, reload [--hard], text, version, quit, wipe |
| Observe |
snapshot, screenshot, console, network |
| Interact |
click @eN, hover @eN [--duration ms], press <key> [key ...], fill @eN "value", select @eN "option", upload @eN <file> [file ...], attr @eN [attribute], scroll down/up/top/bottom/@eN/x y |
| Wait |
wait url <str>, wait text <str>, wait visible <sel>, wait hidden <sel>, wait network-idle, wait <ms> |
| Viewport |
viewport, goto --viewport/--device/--preset |
| Evaluate |
eval <expr> (in-page JS), page-eval <expr> (Playwright page API) |
| Auth |
login --env <name>, auth-state save/load <path> |
| Tabs |
tab list/new/switch/close |
| Assert |
assert visible/text-contains/url-contains/... |
| Accessibility |
a11y (full page), a11y @eN (element), a11y --standard wcag2aa, a11y --json |
| Flows |
flow list, flow <name> --var key=value, healthcheck |
Run browse help <command> for flags and detailed usage — don't guess at flags.
Authentication
Configured login (preferred — uses browse.config.json):
browse login --env staging
Manual login:
browse goto https://app.example.com/login
browse snapshot
browse fill @e1 "user@example.com"
browse fill @e2 "password123"
browse click @e3
browse snapshot # verify redirect / dashboard loaded
Session reuse — save after login, load in future sessions:
browse auth-state save /tmp/auth.json
browse auth-state load /tmp/auth.json
Use browse wipe to clear all session data before switching accounts or at the end of a session.
Timeout control
Any command accepts --timeout <ms> (default 30s). Use for slow pages:
browse goto https://slow-page.example.com --timeout 60000
Error recovery
| Error |
Fix |
"element is outside of the viewport" |
Run browse scroll @eN to scroll it into view, then retry |
"Refs are stale" / "Unknown ref" |
Run browse snapshot to refresh refs |
"Daemon connection lost" |
Re-run the command — CLI auto-restarts the daemon |
"Command timed out after Nms" |
Use --timeout 60000, or check the URL |
"Daemon crashed and recovery failed" |
Run browse quit, then retry |
"Unknown command" for a valid command |
Stale daemon — run browse quit, then retry |
"Unknown flag" |
Check browse help <cmd> for valid flags |
| Login fails |
Check env vars, verify login URL, browse screenshot to see the page |
1---2name: browse3description: Browser automation CLI for AI agents. Use when the user needs to interact with a web page or web app in a real browser, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting page data, testing rendered UI, or running browser-based health checks. Do not use for code review, API-only checks, generic QA, or general web research unless browser interaction is required.4---56# Browse — Browser Automation for Agents78## Setup910Check if `browse` is installed:1112```bash13browse version14```1516If not installed, ask the user before installing. Prefer a pinned release artifact with a published checksum or signature. Do not pipe a mutable remote script directly into `bash`. If the user approves a convenience installer, download it to a temporary file, show the source URL, inspect or verify it where possible, then execute the local file.1718## How it works1920`browse` is a CLI that wraps Playwright behind a persistent daemon on a Unix socket. The daemon cold-starts in ~3s on first use, then every command runs in sub-200ms. Session state (cookies, localStorage, auth tokens) persists across commands within a session.2122All output is plain text. Objects are JSON-stringified. Commands return non-zero on failure with an error message.2324**Important constraints:**25- Commands are sequential — do not run multiple `browse` commands in parallel. The daemon handles one command at a time.26- Run `browse help` for the full command list, or `browse help <command>` for detailed usage and flags.2728## The ref system — read this first2930Refs (`@e1`, `@e2`, ...) are how you target elements. They replace CSS selectors for most interactions.3132**Rules:**331. **Always `browse snapshot` before interacting.** Refs only exist after a snapshot.342. **Refs are ephemeral.** Every `snapshot` call regenerates them. Old refs are invalid.353. **Refs go stale after navigation.** Any `goto` or click that changes the page invalidates refs. You'll get a clear error — just `browse snapshot` again.3637**Core interaction loop:**3839```40browse snapshot # see what's on the page — get refs41browse fill @e3 "test" # fill the search field42browse click @e4 # click a button43browse snapshot # re-snapshot after the page changes44```4546## Workflow4748The standard pattern for any browser task:49501. **Navigate:** `browse goto <url>`512. **Observe:** `browse snapshot` for page structure (interactive elements with refs). Use `browse snapshot -i` to include structural elements (headings, text), or `-f` for the full accessibility tree.523. **Check for errors:** `browse console --level error` after navigation.534. **Interact:** `browse fill @eN "value"`, `browse click @eN`, `browse hover @eN`, `browse press Tab`, `browse select @eN "option"`, `browse scroll @eN` (scroll into view).54 - Use `browse press <key>` for keyboard navigation (Tab, Escape, Enter, ArrowDown, Shift+Tab, etc.). Multiple keys: `browse press Tab Tab Tab`.55 - Use `browse scroll down/up` to page through content, `browse scroll top/bottom` to jump to extremes.56 - After clicks that trigger SPA navigation, use `browse wait url /path`, `browse wait text "Expected"`, or `browse wait visible .selector` before snapshotting.575. **Verify:** `browse snapshot` or `browse screenshot` after each interaction to confirm the result.586. **Repeat:** Move through pages and flows.5960For configured applications, `browse healthcheck` gives a quick pass/fail across key pages.6162## Key commands by category6364| Category | Commands |65|----------|----------|66| **Navigate** | `goto <url>`, `url`, `back`, `forward`, `reload [--hard]`, `text`, `version`, `quit`, `wipe` |67| **Observe** | `snapshot`, `screenshot`, `console`, `network` |68| **Interact** | `click @eN`, `hover @eN [--duration ms]`, `press <key> [key ...]`, `fill @eN "value"`, `select @eN "option"`, `upload @eN <file> [file ...]`, `attr @eN [attribute]`, `scroll down/up/top/bottom/@eN/x y` |69| **Wait** | `wait url <str>`, `wait text <str>`, `wait visible <sel>`, `wait hidden <sel>`, `wait network-idle`, `wait <ms>` |70| **Viewport** | `viewport`, `goto --viewport/--device/--preset` |71| **Evaluate** | `eval <expr>` (in-page JS), `page-eval <expr>` (Playwright page API) |72| **Auth** | `login --env <name>`, `auth-state save/load <path>` |73| **Tabs** | `tab list/new/switch/close` |74| **Assert** | `assert visible/text-contains/url-contains/...` |75| **Accessibility** | `a11y` (full page), `a11y @eN` (element), `a11y --standard wcag2aa`, `a11y --json` |76| **Flows** | `flow list`, `flow <name> --var key=value`, `healthcheck` |7778Run `browse help <command>` for flags and detailed usage — don't guess at flags.7980## Authentication8182**Configured login** (preferred — uses `browse.config.json`):8384```85browse login --env staging86```8788**Manual login:**8990```91browse goto https://app.example.com/login92browse snapshot93browse fill @e1 "user@example.com"94browse fill @e2 "password123"95browse click @e396browse snapshot # verify redirect / dashboard loaded97```9899**Session reuse** — save after login, load in future sessions:100101```102browse auth-state save /tmp/auth.json103browse auth-state load /tmp/auth.json104```105106Use `browse wipe` to clear all session data before switching accounts or at the end of a session.107108## Timeout control109110Any command accepts `--timeout <ms>` (default 30s). Use for slow pages:111112```113browse goto https://slow-page.example.com --timeout 60000114```115116## Error recovery117118| Error | Fix |119|-------|-----|120| `"element is outside of the viewport"` | Run `browse scroll @eN` to scroll it into view, then retry |121| `"Refs are stale"` / `"Unknown ref"` | Run `browse snapshot` to refresh refs |122| `"Daemon connection lost"` | Re-run the command — CLI auto-restarts the daemon |123| `"Command timed out after Nms"` | Use `--timeout 60000`, or check the URL |124| `"Daemon crashed and recovery failed"` | Run `browse quit`, then retry |125| `"Unknown command"` for a valid command | Stale daemon — run `browse quit`, then retry |126| `"Unknown flag"` | Check `browse help <cmd>` for valid flags |127| Login fails | Check env vars, verify login URL, `browse screenshot` to see the page |