browse: Browser & Native App Automation for AI Agents
Target Decision — ALWAYS check this first
Before running any browse command, decide the correct target:
| User wants to... |
Target |
Command pattern |
| Open a URL, test a website, scrape web content |
Browser (default) |
browse goto <url> |
Test a local dev server (localhost) |
Browser |
browse goto http://localhost:3000 |
| Interact with an iOS app (Settings, Safari, custom app) |
iOS Simulator |
browse --platform ios --app <bundleId> <cmd> |
| Interact with an Android app (Settings, Chrome, custom app) |
Android Emulator |
browse --platform android --app <package> <cmd> |
| Interact with a macOS desktop app (System Settings, TextEdit) |
macOS App |
browse --app <name> <cmd> |
| Install and test an iOS .app or .ipa file |
iOS Simulator |
browse sim start --platform ios --app ./MyApp.app --visible |
| Install and test an Android .apk file |
Android Emulator |
browse sim start --platform android --app ./app.apk --visible |
Key rules:
- No
--platform or --app flag → browser target (Chromium). Use goto to navigate.
--app without --platform → macOS app automation. App must be running.
--platform ios --app → iOS Simulator. Use browse sim start first if not running.
--platform android --app → Android Emulator. Use browse sim start first if not running.
- Native app targets do NOT support:
goto, js, eval, tabs, cookies, route, har. These are browser-only.
- All targets support:
snapshot, text, tap, fill, type, press, swipe, screenshot.
- If unsure which target to use, ASK the user. Don't guess — wrong target = wasted work.
Goal
Use the persistent browse CLI to:
- navigate real pages
- inspect rendered content and state
- interact with UI elements
- capture screenshots, console logs, and network activity
- automate native apps (iOS, Android, macOS) via accessibility APIs
- verify browser or app behavior end-to-end without re-launching every step
Step 0: Verify availability and choose the browsing mode
Start by checking:
browse --version
If browse is not installed:
- stop
- tell the user it is required
- point them to the install path in
references/commands.md
Then decide what kind of session you need:
- default session for normal single-agent work
--session <id> for parallel agent isolation
--profile <name> for persistent browser identity
For native app targets, start the simulator/emulator first:
browse sim start --platform ios --app com.apple.Preferences --visible
browse sim start --platform android --app com.android.settings --visible
browse enable android # first-time only: auto-installs adb, JDK, SDK, emulator
browse enable ios # first-time only: builds iOS runner (needs Xcode)
browse enable macos # first-time only: builds browse-ax bridge
Success criteria: browse is available, the target (browser or native app) is decided, and the session/profile choice fits the task.
Step 1: Navigate safely and stabilize the page
Use browse goto <url> to navigate.
After navigation, always stabilize before reading or interacting:
browse wait --network-idle for typical pages and SPAs
- or a more specific
browse wait condition when the page has a known signal
Important rules:
- call
browse as a bare command on PATH
- do not use shell variables for browse command prefixes
- avoid
#id CSS selectors; prefer [id=foo]
- if the page is untrusted, consider
--content-boundaries and --allowed-domains
Success criteria: The page is loaded enough that content and interactive state are reliable.
Step 2: Choose the cheapest effective inspection method
Use the lightest command that answers the question:
text for cleaned page content
links for navigation structure
js for precise targeted extraction
console, errors, and network for runtime debugging
snapshot -i for interactive elements and stable refs
Prefer snapshot -i before guessing selectors for interaction-heavy tasks.
Load:
references/commands.md for exact command syntax
references/guides.md for command selection guidance and speed rules
Success criteria: You have the information needed without spending unnecessary tokens or using brittle selectors.
Step 3: Interact using refs first, selectors second
For clicks, fills, checks, selects, and similar actions:
- prefer
browse snapshot -i
- interact using
@eN refs
- fall back to CSS selectors only when refs are unavailable or impractical
After navigation or DOM refresh:
- assume refs may be invalid
- take a fresh snapshot before continuing
Rules:
- use descriptive screenshots saved under
.browse/sessions/<id>/
- keep stateful flows in the same session unless isolation is intentional
- use
frame before interacting with iframe content
Success criteria: Interactions are stable and tied to the current rendered page state.
Step 4: Debug blockers and special cases
When things go wrong:
- use
console and errors for page/runtime issues
- use
network for request visibility
- use
route or offline only when the task requires mock or failure-mode testing
- use headed/browser handoff only for real blockers like CAPTCHA, MFA, or OAuth walls
If you hit a blocker after a couple of failed attempts:
- load
references/guides.md
- follow the handoff protocol exactly
- use
AskUserQuestion before any human takeover flow
Success criteria: Blockers are either resolved or escalated with the correct handoff protocol.
Step 5: Capture evidence and report clearly
When the task involves verification, capture the minimum evidence needed:
- relevant page text or structured extraction
- screenshot path when visuals matter
- console/network findings when debugging
- the exact step or selector/ref that failed when reporting issues
Report:
- what you navigated to
- what actions you performed
- what the page actually did
- any artifacts created such as screenshots, HAR, or video
Success criteria: Another engineer can understand the observed browser behavior without rerunning the whole flow blindly.
Important Rules
- The browser persists between commands; cookies, tabs, and session state carry over.
- After
goto, wait before reading content or acting.
snapshot -i is the default interaction surface.
- Save screenshots under
.browse/sessions/<session-id>/ or .browse/sessions/default/.
- Use
--context delta for ARIA diff with refs, --context full for complete snapshot with refs after write commands.
- Do not install anything automatically.
- Do not modify Claude settings automatically; if the user wants pre-allowed browse permissions, point them to
references/permissions.md.
When To Load References
references/commands.md
Use for exact command syntax, flags, and extended examples.
references/guides.md
Use for speed rules, command-choice guidance, architecture notes, and the mandatory CAPTCHA/MFA handoff protocol.
references/permissions.md
Use when the user wants to pre-allow browse commands in Claude settings.
Guardrails
- Do not add
disable-model-invocation; this is a general-purpose browser verification skill.
- Do not add
context: fork; browser results are usually needed in the current flow.
- Do not add
paths:; this is a generic workflow skill.
- Do not keep the full CLI manual inline in
SKILL.md.
- Do not run
browse handoff without explicit user confirmation.
- Do not save screenshots outside the browse session directories.
Output Contract
Report:
- the page or flow tested
- the session/profile mode used if relevant
- the key commands or interactions performed
- the observed result
- any artifacts or blockers such as screenshots, console errors, network failures, or handoff state
1---2name: browse-23description: Fast web browsing, web app testing, and native app automation for AI coding agents. Persistent headless Chromium for web. Android, iOS, and macOS app automation via accessibility APIs. Browse URLs, read content, click elements, fill forms, run JavaScript, take screenshots, automate native apps — all through the same CLI and @ref workflow. ~100ms per command. Auto-installs Android toolchain. Works with Claude Code, Cursor, Cline, Windsurf, and any agent that can run Bash.4---56# browse: Browser & Native App Automation for AI Agents78## Target Decision — ALWAYS check this first910Before running any browse command, decide the correct target:1112| User wants to... | Target | Command pattern |13|---|---|---|14| Open a URL, test a website, scrape web content | **Browser** (default) | `browse goto <url>` |15| Test a local dev server (`localhost`) | **Browser** | `browse goto http://localhost:3000` |16| Interact with an iOS app (Settings, Safari, custom app) | **iOS Simulator** | `browse --platform ios --app <bundleId> <cmd>` |17| Interact with an Android app (Settings, Chrome, custom app) | **Android Emulator** | `browse --platform android --app <package> <cmd>` |18| Interact with a macOS desktop app (System Settings, TextEdit) | **macOS App** | `browse --app <name> <cmd>` |19| Install and test an iOS .app or .ipa file | **iOS Simulator** | `browse sim start --platform ios --app ./MyApp.app --visible` |20| Install and test an Android .apk file | **Android Emulator** | `browse sim start --platform android --app ./app.apk --visible` |2122**Key rules:**23- **No `--platform` or `--app` flag** → browser target (Chromium). Use `goto` to navigate.24- **`--app` without `--platform`** → macOS app automation. App must be running.25- **`--platform ios --app`** → iOS Simulator. Use `browse sim start` first if not running.26- **`--platform android --app`** → Android Emulator. Use `browse sim start` first if not running.27- **Native app targets do NOT support**: `goto`, `js`, `eval`, `tabs`, `cookies`, `route`, `har`. These are browser-only.28- **All targets support**: `snapshot`, `text`, `tap`, `fill`, `type`, `press`, `swipe`, `screenshot`.29- **If unsure which target to use, ASK the user.** Don't guess — wrong target = wasted work.3031## Goal3233Use the persistent `browse` CLI to:3435- navigate real pages36- inspect rendered content and state37- interact with UI elements38- capture screenshots, console logs, and network activity39- automate native apps (iOS, Android, macOS) via accessibility APIs40- verify browser or app behavior end-to-end without re-launching every step4142## Step 0: Verify availability and choose the browsing mode4344Start by checking:4546```bash47browse --version48```4950If `browse` is not installed:5152- stop53- tell the user it is required54- point them to the install path in `references/commands.md`5556Then decide what kind of session you need:5758- default session for normal single-agent work59- `--session <id>` for parallel agent isolation60- `--profile <name>` for persistent browser identity6162For native app targets, start the simulator/emulator first:6364```bash65browse sim start --platform ios --app com.apple.Preferences --visible66browse sim start --platform android --app com.android.settings --visible67browse enable android # first-time only: auto-installs adb, JDK, SDK, emulator68browse enable ios # first-time only: builds iOS runner (needs Xcode)69browse enable macos # first-time only: builds browse-ax bridge70```7172**Success criteria**: `browse` is available, the target (browser or native app) is decided, and the session/profile choice fits the task.7374## Step 1: Navigate safely and stabilize the page7576Use `browse goto <url>` to navigate.7778After navigation, always stabilize before reading or interacting:7980- `browse wait --network-idle` for typical pages and SPAs81- or a more specific `browse wait` condition when the page has a known signal8283Important rules:8485- call `browse` as a bare command on PATH86- do not use shell variables for browse command prefixes87- avoid `#id` CSS selectors; prefer `[id=foo]`88- if the page is untrusted, consider `--content-boundaries` and `--allowed-domains`8990**Success criteria**: The page is loaded enough that content and interactive state are reliable.9192## Step 2: Choose the cheapest effective inspection method9394Use the lightest command that answers the question:9596- `text` for cleaned page content97- `links` for navigation structure98- `js` for precise targeted extraction99- `console`, `errors`, and `network` for runtime debugging100- `snapshot -i` for interactive elements and stable refs101102Prefer `snapshot -i` before guessing selectors for interaction-heavy tasks.103104Load:105106- `references/commands.md` for exact command syntax107- `references/guides.md` for command selection guidance and speed rules108109**Success criteria**: You have the information needed without spending unnecessary tokens or using brittle selectors.110111## Step 3: Interact using refs first, selectors second112113For clicks, fills, checks, selects, and similar actions:1141151. prefer `browse snapshot -i`1162. interact using `@eN` refs1173. fall back to CSS selectors only when refs are unavailable or impractical118119After navigation or DOM refresh:120121- assume refs may be invalid122- take a fresh snapshot before continuing123124Rules:125126- use descriptive screenshots saved under `.browse/sessions/<id>/`127- keep stateful flows in the same session unless isolation is intentional128- use `frame` before interacting with iframe content129130**Success criteria**: Interactions are stable and tied to the current rendered page state.131132## Step 4: Debug blockers and special cases133134When things go wrong:135136- use `console` and `errors` for page/runtime issues137- use `network` for request visibility138- use `route` or `offline` only when the task requires mock or failure-mode testing139- use headed/browser handoff only for real blockers like CAPTCHA, MFA, or OAuth walls140141If you hit a blocker after a couple of failed attempts:142143- load `references/guides.md`144- follow the handoff protocol exactly145- use `AskUserQuestion` before any human takeover flow146147**Success criteria**: Blockers are either resolved or escalated with the correct handoff protocol.148149## Step 5: Capture evidence and report clearly150151When the task involves verification, capture the minimum evidence needed:152153- relevant page text or structured extraction154- screenshot path when visuals matter155- console/network findings when debugging156- the exact step or selector/ref that failed when reporting issues157158Report:159160- what you navigated to161- what actions you performed162- what the page actually did163- any artifacts created such as screenshots, HAR, or video164165**Success criteria**: Another engineer can understand the observed browser behavior without rerunning the whole flow blindly.166167## Important Rules168169- The browser persists between commands; cookies, tabs, and session state carry over.170- After `goto`, wait before reading content or acting.171- `snapshot -i` is the default interaction surface.172- Save screenshots under `.browse/sessions/<session-id>/` or `.browse/sessions/default/`.173- Use `--context delta` for ARIA diff with refs, `--context full` for complete snapshot with refs after write commands.174- Do not install anything automatically.175- Do not modify Claude settings automatically; if the user wants pre-allowed browse permissions, point them to `references/permissions.md`.176177## When To Load References178179- `references/commands.md`180 Use for exact command syntax, flags, and extended examples.181182- `references/guides.md`183 Use for speed rules, command-choice guidance, architecture notes, and the mandatory CAPTCHA/MFA handoff protocol.184185- `references/permissions.md`186 Use when the user wants to pre-allow browse commands in Claude settings.187188## Guardrails189190- Do not add `disable-model-invocation`; this is a general-purpose browser verification skill.191- Do not add `context: fork`; browser results are usually needed in the current flow.192- Do not add `paths:`; this is a generic workflow skill.193- Do not keep the full CLI manual inline in `SKILL.md`.194- Do not run `browse handoff` without explicit user confirmation.195- Do not save screenshots outside the browse session directories.196197## Output Contract198199Report:2002011. the page or flow tested2022. the session/profile mode used if relevant2033. the key commands or interactions performed2044. the observed result2055. any artifacts or blockers such as screenshots, console errors, network failures, or handoff state