--- name: browser-skill description: | Use when the user asks to perform browser automation tasks against their logged-in browser: visit and read pages, fill forms, scrape data, click through a flow, regression-test a PR's UI, validate a deployed page. Requires the bsk CLI installed and the browser-skill extension loaded. --- # browser-skill Drive the user's **real Chromium browser** (with their logins and cookies) through the `bsk` CLI. The extension opens an isolated **Agent Window** for automation; the user's normal windows stay protected unless you explicitly borrow a tab. ## When to use - Open pages, read titles/text, scrape structured data from sites the user can already access - Fill forms, click through multi-step flows, smoke-test a UI change - Understand pages with `bsk snapshot` first; use `bsk get-html` or `bsk screenshot` only when the snapshot is insufficient - Operate on a specific user tab they point you at (after `bsk tab borrow`) ## When NOT to use - Tasks with **no browser** involved (files, APIs, databases only) - Installing or configuring the extension (point the user to setup docs instead) - **Credential harvesting** — never run `bsk evaluate` on banking, SSO, or password-manager pages to extract tokens, cookies, or secrets - Long-lived control of a user's personal login window — borrow only for the immediate step, then `bsk tab return` or end the session - Replacing the user's manual browsing when they only wanted an explanation ## Prerequisites 1. `bsk` on `PATH` (Rust CLI from browser-skill) 2. browser-skill **extension** loaded in Chromium and connected (popup shows green) 3. Any `bsk` command auto-starts background services as needed; use `bsk doctor` if anything fails ## Mandatory workflow Every automation task **must** follow this lifecycle. Do **not** rely on idle timeouts (default session idle is 5 minutes). ``` 1. bsk session start → capture the 4-letter session id printed on stdout 2. … every tool command … → always pass --session 3. bsk session stop → REQUIRED when done (even on error paths) ``` Optional: `bsk session start --browser ` when multiple browsers are connected (`bsk browsers` / error output lists them). Add `--no-focus` to open the Agent Window in the background without stealing focus from the user's current window. Emergency cleanup: `bsk session stop --all` or the Agent Window overlay **Stop all**. ## Stop when the goal is met Every task is a **bounded goal**, not open-ended browsing. The goal may come from the user's request, a recorded `trace.json`, or both. 1. **Define success first** — one concrete, observable condition derived from the user's words, `purpose`, or the last meaningful step in a trace (e.g. "form submitted", "item added to cart", "playback started"). 2. **Take the shortest path** — snapshot → act → at most one check. Do not wander, re-try unrelated actions, or stack exploratory steps. 3. **Stop as soon as success is reached** — run `bsk session stop ` immediately unless the user explicitly asked to keep the session open (e.g. "don't close yet", "keep browsing"). 4. **No post-success work** — once the goal is met, do not click, refresh, navigate, re-search, switch tabs, or "double-check" that it worked. Further verification is a new task. 5. **When blocked, pause — do not brute-force** — if the page requires human input (login, captcha, OTP, payment confirmation) or an action fails twice with no progress, call `bsk request-help` instead of retrying blindly. See **Ask the human for help** below. 6. **When unsure** — at most one extra `bsk snapshot`. If success looks met, stop. If not, ask the user; do not keep clicking. **With a trace:** replay steps in order using `target` role/name/tag and raw `value`/`selection` fields. After the last step (or when its `effect.navigated_to` / success hint is satisfied), apply rules 3–4 immediately. The trace guides execution; it does not extend control beyond the goal. **Without a trace:** the user's request *is* the success condition. Satisfying it ends the task — same stop rules apply. ## Core interaction loop Write operations only affect tabs in the **Agent Window** (or tabs you **borrowed** into it). ``` bsk navigate --session bsk observe --session → primary semantic VOM view; reveals hover/focus surfaces bsk snapshot --session → static aria tree fallback when VOM is insufficient bsk hover @e3 --session → reveal hover-triggered menus before re-observing/clicking bsk click @e4 --session → or bsk fill, bsk select, bsk press bsk observe --session → again after navigation / DOM change ``` **Refs invalidate after navigation** — always re-snapshot before clicking, filling, or selecting on a new page. Prefer `@eN` refs from the latest snapshot over raw CSS selectors. Use `--ref` / `--selector` when ambiguous (`bsk click --help`). When VOM renders `[hover first: …]` on an element, the listed items are not currently clickable refs. Run `bsk hover --session `, then immediately run `bsk snapshot` or `bsk observe` again and click the newly visible menu item ref. Do not click the trigger itself unless the user explicitly wants the trigger action. ## Observation priority Start with `bsk observe` to understand page structure, text, controls, element refs, and conditional hover/focus surfaces. Use `bsk snapshot` only when you need the stricter static accessibility tree or VOM is insufficient. Only escalate to raw HTML or screenshots when the latest observation cannot answer the question: 1. `bsk observe` — primary semantic VOM observation; may run bounded perception probes such as hover-surface discovery 2. `bsk snapshot` — strict static accessibility tree fallback 3. `bsk get-html` — when hidden DOM, metadata, or markup details are required 4. `bsk screenshot` — when visual layout, canvas/image content, or styling cannot be inferred from the observation. Use `--ref @eN` (from the latest snapshot/observe) to crop to one element; omit `--ref` for the full visible tab. Do **not** call `bsk get-html` or `bsk screenshot` first just to inspect a page. ## Sandbox rules | Rule | Detail | |------|--------| | Agent Window | `bsk tab create`, `bsk navigate`, `bsk click`, etc. work on agent tabs by default | | User tabs | Read-only until borrowed: `bsk tab list --session --scope user` then `bsk tab borrow --session ` | | Return borrowed tabs | Call `bsk tab return --session ` when finished; unreturned tabs are **auto-returned** on `bsk session stop` | | Writes off-agent | Commands that mutate the page fail if the tab is not in the Agent Window — borrow or create a tab first | ## Global flags | Flag | Purpose | |------|---------| | `--json` | Machine-readable JSON on stdout (errors too) | | `--quiet` | Suppress informational stderr | | `-v` / `-vv` | More verbose logging | Auto-update is **on by default** — the background daemon upgrades `bsk` itself when a new release is available (postponed while a session is active). Set `BSK_AUTO_UPDATE=off` to disable it and upgrade manually with `bsk update`. Command-specific flags (timeouts, `--tab-id`, `--wait-until`, …): **`bsk --help`** ## CLI command reference (one line each) Details and flags: **`bsk --help`** ### Diagnostics | Command | Summary | |---------|---------| | `bsk status` | Connection health, connected browsers, active sessions | | `bsk doctor` | Deep diagnostics and repair hints | | `bsk browsers` | List connected browser instances (ids, labels, versions) | ### Session | Command | Summary | |---------|---------| | `bsk session start` | Open Agent Window (`--width`/`--height` for initial size); prints **4-letter session id** | | `bsk session start --no-focus` | Open Agent Window in the background without stealing focus | | `bsk session stop ` | End session, close Agent Window, auto-return borrowed tabs | | `bsk session stop --all` | Stop every active session | | `bsk session list` | List active sessions | ### Window (require `--session `) | Command | Summary | |---------|---------| | `bsk window resize` | Resize the Agent Window (`--width`, `--height`; 100..=7680 CSS px) | ### Device emulation — `bsk emulate` (requires `--session `) Emulate a mobile device environment on the agent tab via CDP — viewport, User-Agent, and touch — to debug a page's mobile layout and behaviour: ```bash bsk emulate --session --device iphone-14 bsk emulate --session --width 390 --height 844 --dpr 3 --mobile --ua "Mozilla/5.0 (iPhone…" --touch bsk emulate --session --off ``` - Presets (`--device`): `iphone-14`, `iphone-14-pro-max`, `iphone-se`, `pixel-7`, `galaxy-s23`, `ipad-mini`, `galaxy-tab-s8`. Manual flags (`--width`/`--height`/`--dpr`/`--mobile`/`--ua`/`--accept-language`/`--touch`/`--max-touch-points`) also work without a preset, or override individual preset fields; `--no-mobile`/`--no-touch` turn a preset's mobile viewport / touch emulation back off. - Repeated runs merge field by field onto the tab's current emulation state — only the flags you pass change. E.g. after `--device iphone-14`, `bsk emulate --session --width 390 --height 844` keeps the preset's dpr (`3`) and mobile viewport. (The extension remembers the state per tab; after an extension reload the next run applies only the fields it carries.) - `--off` clears every override (viewport, UA, touch) and the remembered state, restoring the tab's real environment. - Scope: overrides apply to **one tab only** (CDP per-target) and are **not inherited by new tabs** — re-run `bsk emulate` after opening or switching to another tab (default target is the session's active tab; `--tab-id` overrides). - Emulation covers viewport/UA/touch only; it does not throttle the network, fake geolocation, or synthesise real touch-event streams. ### Tabs (require `--session `) | Command | Summary | |---------|---------| | `bsk tab list` | List tabs (`--scope user\|agent\|all`, default `all`) | | `bsk tab create` | New tab in Agent Window (`--url`, `--no-active`, `--index`) | | `bsk tab close ` | Close an agent tab | | `bsk tab select ` | Focus an agent tab | | `bsk tab borrow ` | Move a user tab into the Agent Window | | `bsk tab return ` | Return a borrowed tab to its original window | ### Observation (require `--session` unless noted) | Command | Summary | |---------|---------| | `bsk snapshot` | First-choice static page understanding: accessibility tree with `@eN` element refs | | `bsk observe` | Semantic VOM observation with bounded perception probes for conditional surfaces | | `bsk get-html` | Raw HTML dump after snapshot is insufficient (high token cost) | | `bsk screenshot` | PNG capture after snapshot is insufficient: full visible tab, or `--ref @eN` to crop to one element (`--out` path optional) | ### Console & network debugging (read-only; require `--session`) | Command | Summary | |---------|---------| | `bsk console` | Buffered page console messages, JS exceptions, and browser log entries (`--include-stack` for stack traces) | | `bsk network` | Buffered network responses (status, method, URL, MIME/resource type) and failures (`net::ERR_*` reason) | Both capture from the moment the tab is attached and read a bounded per-tab buffer: `--since ` pages from a cursor (`next_since` in the result), `--limit` (default 50, max 200), `--max-text-chars` (default 1000, max 4096), `--tab-id` to target a non-active tab. Both are strictly read-only — they never intercept or modify traffic, and request/response headers, bodies, and timings are not captured. ### Navigation | Command | Summary | |---------|---------| | `bsk navigate ` | Go to URL in agent tab (`--wait-until`, `--timeout`) | | `bsk navigate-back` | History back one step | | `bsk navigate-forward` | History forward one step | | `bsk reload` | Reload current tab (`--hard` bypass cache) | (`bsk navigate back` / `bsk navigate forward` are equivalent subcommands.) ### Interaction | Command | Summary | |---------|---------| | `bsk click ` | Click element (`--button`, `--click-count`, `--modifiers`) | | `bsk hover ` | Move the mouse to an element and wait for hover UI to settle (`--settle`, `--modifiers`) | | `bsk scroll-to ` | Scroll an element and its frame owners into the visible viewport | | `bsk fill --value ` | Clear and type into input | | `bsk select --value ` | Set `