[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DNR8BYVG74DX1F137X58ET":3,"skill-same:01M6DNR8BYVG74DX1F137X58ET":97},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":58,"ownerDescription":6,"updatedAt":59,"install":60,"resources":73},"01M6DNR8BYVG74DX1F137X58ET","browse",null,"Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include: any mention of 'browse', 'check the page', 'take a screenshot', 'test the UI', 'fill the form', 'click the button', 'QA', 'visual check', 'healthcheck', and any task requiring a real browser.","forjd\u002Fbrowse","forjd","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F248055561?v=4","01M6DNR1VGKGY64VB81X028RBM","Forjd","01M6DNR1ZQ1MXM5YPQZF88BV28",13,"MIT","https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbrowse\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[5,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"apps","testing","click","triggers","pages","real browser","forms","take","page","Bash","data","ui","screenshot","browser","qa","ai agents","browser automation","cli","screenshots","2026-11-10 10:12:30",false,"---\nname: browse\ndescription: \"Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include: any mention of 'browse', 'check the page', 'take a screenshot', 'test the UI', 'fill the form', 'click the button', 'QA', 'visual check', 'healthcheck', and any task requiring a real browser.\"\nallowed-tools: Bash(browse:*)\n---\n\n# Browse — Browser Automation for Agents\n\n## How it works\n\n`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.\n\nAll output is plain text. Objects are JSON-stringified. Commands return non-zero on failure with an error message.\n\n**Important constraints:**\n- Commands are sequential — do not run multiple `browse` commands in parallel. The daemon handles one command at a time.\n- Run `browse help` for the full command list, or `browse help \u003Ccommand>` for detailed usage and flags.\n\n## The ref system — read this first\n\nRefs (`@e1`, `@e2`, ...) are how you target elements. They replace CSS selectors for most interactions.\n\n**Rules:**\n1. **Always `browse snapshot` before interacting.** Refs only exist after a snapshot.\n2. **Refs are ephemeral.** Every `snapshot` call regenerates them. Old refs are invalid.\n3. **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.\n\n**Core interaction loop:**\n\n```\nbrowse snapshot              # see what's on the page — get refs\nbrowse fill @e3 \"test\"       # fill the search field\nbrowse click @e4             # click a button\nbrowse snapshot              # re-snapshot after the page changes\n```\n\n## Workflow\n\nThe standard pattern for any browser task:\n\n1. **Navigate:** `browse goto \u003Curl>`\n2. **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.\n3. **Check for errors:** `browse console --level error` after navigation.\n4. **Interact:** `browse fill @eN \"value\"`, `browse click @eN`, `browse hover @eN`, `browse press Tab`, `browse select @eN \"option\"`, `browse scroll @eN` (scroll into view).\n   - Use `browse press \u003Ckey>` for keyboard navigation (Tab, Escape, Enter, ArrowDown, Shift+Tab, etc.). Multiple keys: `browse press Tab Tab Tab`.\n   - Use `browse scroll down\u002Fup` to page through content, `browse scroll top\u002Fbottom` to jump to extremes.\n   - After clicks that trigger SPA navigation, use `browse wait url \u002Fpath`, `browse wait text \"Expected\"`, or `browse wait visible .selector` before snapshotting.\n5. **Verify:** `browse snapshot` or `browse screenshot` after each interaction to confirm the result.\n6. **Repeat:** Move through pages and flows.\n\nFor configured applications, `browse healthcheck` gives a quick pass\u002Ffail across key pages.\n\n## Key commands by category\n\n| Category | Commands |\n|----------|----------|\n| **Navigate** | `goto \u003Curl>`, `url`, `back`, `forward`, `reload [--hard]`, `text`, `version`, `quit`, `wipe` |\n| **Observe** | `snapshot`, `screenshot` (`--diff`, `--threshold`), `console`, `network` |\n| **Interact** | `click @eN`, `hover @eN [--duration ms]`, `press \u003Ckey> [key ...]`, `fill @eN \"value\"`, `select @eN \"option\"`, `upload @eN \u003Cfile> [file ...]`, `attr @eN [attribute]`, `scroll down\u002Fup\u002Ftop\u002Fbottom\u002F@eN\u002Fx y`, `form --data '{\"field\":\"value\"}'` |\n| **Wait** | `wait url \u003Cstr>`, `wait text \u003Cstr>`, `wait visible \u003Csel>`, `wait hidden \u003Csel>`, `wait network-idle`, `wait \u003Cms>` |\n| **Viewport** | `viewport`, `goto --viewport\u002F--device\u002F--preset` |\n| **Evaluate** | `eval \u003Cexpr>` (in-page JS), `page-eval \u003Cexpr>` (Playwright page API) |\n| **Auth** | `login --env \u003Cname>`, `auth-state save\u002Fload \u003Cpath>` |\n| **Tabs** | `tab list\u002Fnew\u002Fswitch\u002Fclose` |\n| **Assert** | `assert visible\u002Ftext-contains\u002Furl-contains\u002F...`, `assert-ai \"\u003Cvisual assertion>\"` |\n| **Accessibility** | `a11y` (full page), `a11y @eN` (element), `a11y --standard wcag2aa`, `a11y --json`, `a11y coverage`, `a11y tree`, `a11y tab-order`, `a11y headings` |\n| **Performance** | `perf` (Core Web Vitals), `perf --budget lcp=2500,cls=0.1`, `perf --json` |\n| **Security** | `security` (headers, cookies, mixed content), `security --json` |\n| **Responsive** | `responsive` (multi-viewport screenshots), `responsive --breakpoints 320x568,1920x1080`, `responsive --url \u003Curl>` |\n| **Extract** | `extract table \u003Csel>` (`--csv`, `--json`), `extract links` (`--filter`), `extract meta`, `extract select \u003Csel>` (`--attr`) |\n| **Flows** | `flow list`, `flow init \u003Ctemplate> [name] [--force]`, `flow \u003Cname> --var key=value` (`--reporter junit\\|json\\|markdown`, `--dry-run`, `--stream`, `--webhook \u003Curl>`), `healthcheck` (`--reporter junit\\|json\\|markdown`, `--parallel`, `--concurrency`, `--webhook \u003Curl>`), `test-matrix --roles r1,r2 --flow \u003Cname>`, `diff --baseline \u003Curl> --current \u003Curl>`. Flows can be defined inline in config or as individual JSON files in a `flows\u002F` directory; `flow init` scaffolds built-in `smoke` and `login-smoke` templates. |\n| **Sessions** | `session list\u002Fcreate\u002Fclose`, `--session \u003Cname>` on any command |\n| **Tracing** | `trace start` (`--screenshots`, `--snapshots`), `trace stop --out \u003Cpath>`, `trace view [\u003Cpath>] --latest --port \u003Cn>`, `trace list`, `trace status` |\n| **Video** | `video start [--size WxH]`, `video stop [--out \u003Cpath>]`, `video status`, `video list` |\n| **Crawl** | `crawl \u003Curl>` (`--depth`, `--extract table\\|links\\|meta\\|text`, `--paginate`, `--rate-limit`, `--output`, `--dry-run`) |\n| **Record** | `record start` (`--output`, `--name`), `record stop`, `record pause\u002Fresume` |\n| **Network Sim** | `throttle \u003Cpreset\\|off\\|status>` (slow-3g, 3g, 4g, wifi, cable), `offline on\u002Foff` |\n| **NL Commands** | `do \"\u003Cinstruction>\"` (`--dry-run`, `--provider`, `--model`) |\n| **VRT** | `vrt init`, `vrt baseline`, `vrt check` (`--threshold`), `vrt update` (`--all`), `vrt list` |\n| **SEO** | `seo [url]` (`--check`, `--score`, `--json`) |\n| **Compliance** | `compliance [url]` (`--standard gdpr\\|ccpa\\|eprivacy`, `--json`) |\n| **Security Scan** | `security-scan` (`--checks xss,csp,clickjack,forms`, `--verbose`, `--json`) |\n| **i18n** | `i18n --locales en,fr,de --url \u003Curl>`, `i18n check-keys`, `i18n rtl-check` |\n| **API Assert** | `api-assert \u003Curl-pattern>` (`--status`, `--timing`, `--schema`, `--body-contains`, `--header`) |\n| **Design** | `design-audit --tokens \u003Cfile>`, `design-audit --extract` |\n| **Doc Capture** | `doc-capture --flow \u003Cfile> --output \u003Cdir>` (`--markdown`, `--update`) |\n| **Gestures** | `gesture swipe \u003Cdir>`, `gesture long-press @eN`, `gesture double-tap @eN`, `gesture drag @eN --to @eN` |\n| **Devices** | `devices list`, `devices search \u003Cquery>`, `devices info \u003Cname>` |\n| **Monitor** | `monitor check --config \u003Cfile>`, `monitor history`, `monitor status` |\n| **Dev Server** | `dev start`, `dev stop`, `dev status` |\n| **CI\u002FCD** | `ci-init` (`--ci github\\|gitlab\\|circleci`) |\n| **Events** | `subscribe` (`--events navigation,console,network`, `--level`, `--idle-timeout`) |\n| **Watch\u002FREPL** | `watch \u003Cflow-file>`, `repl` |\n| **Tooling** | `init`, `framework init \u003Cvitest\\|jest>`, `report --out \u003Cpath>`, `replay --out \u003Cpath>`, `flow-share export\u002Fimport\u002Flist\u002Finstall\u002Fpublish`, `screenshots list\u002Fclean\u002Fcount`, `completions bash\u002Fzsh\u002Ffish`, `status [--json] [--watch] [--exit-code] [--metrics]` |\n| **Plugins** | Custom commands via plugins — see the `browse-plugins` skill. Plugin commands appear in `browse help` output |\n\nRun `browse help \u003Ccommand>` for flags and detailed usage — don't guess at flags.\n\n### Observability quick notes\n\n- Use `browse status --metrics` when CI or monitoring expects Prometheus-style output.\n- Use `browse status --json` for structured health + daemon metadata in automation.\n- Optional daemon env knobs:\n  - `BROWSE_LOG_FORMAT=plain|json` — controls daemon log output format (human-readable text vs structured JSON).\n  - `BROWSE_LOG_LEVEL=debug|info|warn|error` — sets minimum log severity; lower levels (like `debug`) increase verbosity.\n  - `BROWSE_MAX_RSS_MB=\u003Climit>` — when RSS exceeds this limit, daemon triggers memory-pressure mitigation (buffer cleanup + deferred ref cleanup + optional GC).\n  - `BROWSE_SLOW_COMMAND_MS=\u003Cms>` — logs slow-command profiling details for commands that exceed this duration threshold.\n\n### Named sessions\n\nUse named sessions to run multiple independent page groups:\n\n```sh\nbrowse session create worker-1               # shared context (same cookies\u002Fstorage)\nbrowse session create worker-2 --isolated    # isolated context (separate cookies\u002Fstorage)\nbrowse --session worker-1 goto https:\u002F\u002Fa.com\nbrowse --session worker-2 goto https:\u002F\u002Fb.com\nbrowse session list\nbrowse session close worker-1\n```\n\nBy default, sessions share the browser context. Use `--isolated` for fully separate cookies, storage, and permissions.\n\n## Authentication\n\n**Configured login** (preferred — uses `browse.config.json`):\n\n```\nbrowse login --env staging\n```\n\n**Manual login:**\n\n```\nbrowse goto https:\u002F\u002Fapp.example.com\u002Flogin\nbrowse snapshot\nbrowse fill @e1 \"user@example.com\"\nbrowse fill @e2 \"password123\"\nbrowse click @e3\nbrowse snapshot        # verify redirect \u002F dashboard loaded\n```\n\n**Session reuse** — save after login, load in future sessions:\n\n```\nbrowse auth-state save \u002Ftmp\u002Fauth.json\nbrowse auth-state load \u002Ftmp\u002Fauth.json\n```\n\nUse `browse wipe` to clear all session data before switching accounts or at the end of a session.\n\n## Visual diff\n\nCompare screenshots against a baseline to detect visual regressions:\n\n```bash\nbrowse screenshot current.png --diff baseline.png\nbrowse screenshot current.png --diff baseline.png --threshold 5\n```\n\nOutput includes similarity percentage, diff pixel count, and a path to the diff image (changed pixels highlighted in red).\n\n## Multi-browser\n\nBrowse defaults to Chromium. Use `--browser` to switch:\n\n```bash\nbrowse --browser firefox goto https:\u002F\u002Fexample.com\nbrowse --browser webkit goto https:\u002F\u002Fexample.com\nBROWSE_BROWSER=firefox browse goto https:\u002F\u002Fexample.com\n```\n\nStealth features and CDP console capture are Chromium-only; Firefox\u002FWebKit use standard Playwright.\n\n## Proxy\n\nRoute browser traffic through a proxy:\n\n```bash\nbrowse --proxy http:\u002F\u002Fproxy:8080 goto https:\u002F\u002Fexample.com\nBROWSE_PROXY=socks5:\u002F\u002Fproxy:1080 browse goto https:\u002F\u002Fexample.com\n```\n\nOr configure in `browse.config.json` with `\"proxy\": { \"server\": \"http:\u002F\u002Fproxy:8080\", \"bypass\": \"localhost\", \"username\": \"u\", \"password\": \"p\" }`.\n\n## Playwright passthrough\n\nPass any Playwright launch or context option via `browse.config.json` without waiting for explicit `browse` support:\n\n```json\n{\n  \"playwright\": {\n    \"launchOptions\": { \"locale\": \"fr-FR\", \"timezoneId\": \"Europe\u002FParis\" },\n    \"contextOptions\": { \"colorScheme\": \"dark\", \"geolocation\": { \"latitude\": 48.86, \"longitude\": 2.35 } }\n  }\n}\n```\n\n`launchOptions` are applied at browser startup; `contextOptions` are applied to isolated sessions and video recording contexts. Browse's own options (headless, viewport, stealth) take precedence on conflict.\n\n## Headed mode\n\nLaunch the browser visibly for debugging (set before the daemon starts):\n\n```bash\nBROWSE_HEADED=1 browse goto https:\u002F\u002Fexample.com\n```\n\n## Timeout control\n\nAny command accepts `--timeout \u003Cms>` (default 30s). Use for slow pages:\n\n```\nbrowse goto https:\u002F\u002Fslow-page.example.com --timeout 60000\n```\n\n## Error recovery\n\n| Error | Fix |\n|-------|-----|\n| `\"element is outside of the viewport\"` | Run `browse scroll @eN` to scroll it into view, then retry |\n| `\"Refs are stale\"` \u002F `\"Unknown ref\"` | Run `browse snapshot` to refresh refs |\n| `\"Daemon connection lost\"` | Re-run the command — CLI auto-restarts the daemon |\n| `\"Command timed out after Nms\"` | Use `--timeout 60000`, or check the URL |\n| `\"Daemon crashed and recovery failed\"` | Run `browse quit`, then retry |\n| `\"Unknown command\"` for a valid command | Stale daemon — run `browse quit`, then retry |\n| `\"Unknown flag\"` | Check `browse help \u003Ccmd>` for valid flags |\n| Login fails | Check env vars, verify login URL, `browse screenshot` to see the page |\n","# Browse — Browser Automation for Agents\n\n## How it works\n\n`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.\n\nAll output is plain text. Objects are JSON-stringified. Commands return non-zero on failure with an error message.\n\n**Important constraints:**\n- Commands are sequential — do not run multiple `browse` commands in parallel. The daemon handles one command at a time.\n- Run `browse help` for the full command list, or `browse help \u003Ccommand>` for detailed usage and flags.\n\n## The ref system — read this first\n\nRefs (`@e1`, `@e2`, ...) are how you target elements. They replace CSS selectors for most interactions.\n\n**Rules:**\n1. **Always `browse snapshot` before interacting.** Refs only exist after a snapshot.\n2. **Refs are ephemeral.** Every `snapshot` call regenerates them. Old refs are invalid.\n3. **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.\n\n**Core interaction loop:**\n\n```\nbrowse snapshot              # see what's on the page — get refs\nbrowse fill @e3 \"test\"       # fill the search field\nbrowse click @e4             # click a button\nbrowse snapshot              # re-snapshot after the page changes\n```\n\n## Workflow\n\nThe standard pattern for any browser task:\n\n1. **Navigate:** `browse goto \u003Curl>`\n2. **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.\n3. **Check for errors:** `browse console --level error` after navigation.\n4. **Interact:** `browse fill @eN \"value\"`, `browse click @eN`, `browse hover @eN`, `browse press Tab`, `browse select @eN \"option\"`, `browse scroll @eN` (scroll into view).\n   - Use `browse press \u003Ckey>` for keyboard navigation (Tab, Escape, Enter, ArrowDown, Shift+Tab, etc.). Multiple keys: `browse press Tab Tab Tab`.\n   - Use `browse scroll down\u002Fup` to page through content, `browse scroll top\u002Fbottom` to jump to extremes.\n   - After clicks that trigger SPA navigation, use `browse wait url \u002Fpath`, `browse wait text \"Expected\"`, or `browse wait visible .selector` before snapshotting.\n5. **Verify:** `browse snapshot` or `browse screenshot` after each interaction to confirm the result.\n6. **Repeat:** Move through pages and flows.\n\nFor configured applications, `browse healthcheck` gives a quick pass\u002Ffail across key pages.\n\n## Key commands by category\n\n| Category | Commands |\n|----------|----------|\n| **Navigate** | `goto \u003Curl>`, `url`, `back`, `forward`, `reload [--hard]`, `text`, `version`, `quit`, `wipe` |\n| **Observe** | `snapshot`, `screenshot` (`--diff`, `--threshold`), `console`, `network` |\n| **Interact** | `click @eN`, `hover @eN [--duration ms]`, `press \u003Ckey> [key ...]`, `fill @eN \"value\"`, `select @eN \"option\"`, `upload @eN \u003Cfile> [file ...]`, `attr @eN [attribute]`, `scroll down\u002Fup\u002Ftop\u002Fbottom\u002F@eN\u002Fx y`, `form --data '{\"field\":\"value\"}'` |\n| **Wait** | `wait url \u003Cstr>`, `wait text \u003Cstr>`, `wait visible \u003Csel>`, `wait hidden \u003Csel>`, `wait network-idle`, `wait \u003Cms>` |\n| **Viewport** | `viewport`, `goto --viewport\u002F--device\u002F--preset` |\n| **Evaluate** | `eval \u003Cexpr>` (in-page JS), `page-eval \u003Cexpr>` (Playwright page API) |\n| **Auth** | `login --env \u003Cname>`, `auth-state save\u002Fload \u003Cpath>` |\n| **Tabs** | `tab list\u002Fnew\u002Fswitch\u002Fclose` |\n| **Assert** | `assert visible\u002Ftext-contains\u002Furl-contains\u002F...`, `assert-ai \"\u003Cvisual assertion>\"` |\n| **Accessibility** | `a11y` (full page), `a11y @eN` (element), `a11y --standard wcag2aa`, `a11y --json`, `a11y coverage`, `a11y tree`, `a11y tab-order`, `a11y headings` |\n| **Performance** | `perf` (Core Web Vitals), `perf --budget lcp=2500,cls=0.1`, `perf --json` |\n| **Security** | `security` (headers, cookies, mixed content), `security --json` |\n| **Responsive** | `responsive` (multi-viewport screenshots), `responsive --breakpoints 320x568,1920x1080`, `responsive --url \u003Curl>` |\n| **Extract** | `extract table \u003Csel>` (`--csv`, `--json`), `extract links` (`--filter`), `extract meta`, `extract select \u003Csel>` (`--attr`) |\n| **Flows** | `flow list`, `flow init \u003Ctemplate> [name] [--force]`, `flow \u003Cname> --var key=value` (`--reporter junit\\|json\\|markdown`, `--dry-run`, `--stream`, `--webhook \u003Curl>`), `healthcheck` (`--reporter junit\\|json\\|markdown`, `--parallel`, `--concurrency`, `--webhook \u003Curl>`), `test-matrix --roles r1,r2 --flow \u003Cname>`, `diff --baseline \u003Curl> --current \u003Curl>`. Flows can be defined inline in config or as individual JSON files in a `flows\u002F` directory; `flow init` scaffolds built-in `smoke` and `login-smoke` templates. |\n| **Sessions** | `session list\u002Fcreate\u002Fclose`, `--session \u003Cname>` on any command |\n| **Tracing** | `trace start` (`--screenshots`, `--snapshots`), `trace stop --out \u003Cpath>`, `trace view [\u003Cpath>] --latest --port \u003Cn>`, `trace list`, `trace status` |\n| **Video** | `video start [--size WxH]`, `video stop [--out \u003Cpath>]`, `video status`, `video list` |\n| **Crawl** | `crawl \u003Curl>` (`--depth`, `--extract table\\|links\\|meta\\|text`, `--paginate`, `--rate-limit`, `--output`, `--dry-run`) |\n| **Record** | `record start` (`--output`, `--name`), `record stop`, `record pause\u002Fresume` |\n| **Network Sim** | `throttle \u003Cpreset\\|off\\|status>` (slow-3g, 3g, 4g, wifi, cable), `offline on\u002Foff` |\n| **NL Commands** | `do \"\u003Cinstruction>\"` (`--dry-run`, `--provider`, `--model`) |\n| **VRT** | `vrt init`, `vrt baseline`, `vrt check` (`--threshold`), `vrt update` (`--all`), `vrt list` |\n| **SEO** | `seo [url]` (`--check`, `--score`, `--json`) |\n| **Compliance** | `compliance [url]` (`--standard gdpr\\|ccpa\\|eprivacy`, `--json`) |\n| **Security Scan** | `security-scan` (`--checks xss,csp,clickjack,forms`, `--verbose`, `--json`) |\n| **i18n** | `i18n --locales en,fr,de --url \u003Curl>`, `i18n check-keys`, `i18n rtl-check` |\n| **API Assert** | `api-assert \u003Curl-pattern>` (`--status`, `--timing`, `--schema`, `--body-contains`, `--header`) |\n| **Design** | `design-audit --tokens \u003Cfile>`, `design-audit --extract` |\n| **Doc Capture** | `doc-capture --flow \u003Cfile> --output \u003Cdir>` (`--markdown`, `--update`) |\n| **Gestures** | `gesture swipe \u003Cdir>`, `gesture long-press @eN`, `gesture double-tap @eN`, `gesture drag @eN --to @eN` |\n| **Devices** | `devices list`, `devices search \u003Cquery>`, `devices info \u003Cname>` |\n| **Monitor** | `monitor check --config \u003Cfile>`, `monitor history`, `monitor status` |\n| **Dev Server** | `dev start`, `dev stop`, `dev status` |\n| **CI\u002FCD** | `ci-init` (`--ci github\\|gitlab\\|circleci`) |\n| **Events** | `subscribe` (`--events navigation,console,network`, `--level`, `--idle-timeout`) |\n| **Watch\u002FREPL** | `watch \u003Cflow-file>`, `repl` |\n| **Tooling** | `init`, `framework init \u003Cvitest\\|jest>`, `report --out \u003Cpath>`, `replay --out \u003Cpath>`, `flow-share export\u002Fimport\u002Flist\u002Finstall\u002Fpublish`, `screenshots list\u002Fclean\u002Fcount`, `completions bash\u002Fzsh\u002Ffish`, `status [--json] [--watch] [--exit-code] [--metrics]` |\n| **Plugins** | Custom commands via plugins — see the `browse-plugins` skill. Plugin commands appear in `browse help` output |\n\nRun `browse help \u003Ccommand>` for flags and detailed usage — don't guess at flags.\n\n### Observability quick notes\n\n- Use `browse status --metrics` when CI or monitoring expects Prometheus-style output.\n- Use `browse status --json` for structured health + daemon metadata in automation.\n- Optional daemon env knobs:\n  - `BROWSE_LOG_FORMAT=plain|json` — controls daemon log output format (human-readable text vs structured JSON).\n  - `BROWSE_LOG_LEVEL=debug|info|warn|error` — sets minimum log severity; lower levels (like `debug`) increase verbosity.\n  - `BROWSE_MAX_RSS_MB=\u003Climit>` — when RSS exceeds this limit, daemon triggers memory-pressure mitigation (buffer cleanup + deferred ref cleanup + optional GC).\n  - `BROWSE_SLOW_COMMAND_MS=\u003Cms>` — logs slow-command profiling details for commands that exceed this duration threshold.\n\n### Named sessions\n\nUse named sessions to run multiple independent page groups:\n\n```sh\nbrowse session create worker-1               # shared context (same cookies\u002Fstorage)\nbrowse session create worker-2 --isolated    # isolated context (separate cookies\u002Fstorage)\nbrowse --session worker-1 goto https:\u002F\u002Fa.com\nbrowse --session worker-2 goto https:\u002F\u002Fb.com\nbrowse session list\nbrowse session close worker-1\n```\n\nBy default, sessions share the browser context. Use `--isolated` for fully separate cookies, storage, and permissions.\n\n## Authentication\n\n**Configured login** (preferred — uses `browse.config.json`):\n\n```\nbrowse login --env staging\n```\n\n**Manual login:**\n\n```\nbrowse goto https:\u002F\u002Fapp.example.com\u002Flogin\nbrowse snapshot\nbrowse fill @e1 \"user@example.com\"\nbrowse fill @e2 \"password123\"\nbrowse click @e3\nbrowse snapshot        # verify redirect \u002F dashboard loaded\n```\n\n**Session reuse** — save after login, load in future sessions:\n\n```\nbrowse auth-state save \u002Ftmp\u002Fauth.json\nbrowse auth-state load \u002Ftmp\u002Fauth.json\n```\n\nUse `browse wipe` to clear all session data before switching accounts or at the end of a session.\n\n## Visual diff\n\nCompare screenshots against a baseline to detect visual regressions:\n\n```bash\nbrowse screenshot current.png --diff baseline.png\nbrowse screenshot current.png --diff baseline.png --threshold 5\n```\n\nOutput includes similarity percentage, diff pixel count, and a path to the diff image (changed pixels highlighted in red).\n\n## Multi-browser\n\nBrowse defaults to Chromium. Use `--browser` to switch:\n\n```bash\nbrowse --browser firefox goto https:\u002F\u002Fexample.com\nbrowse --browser webkit goto https:\u002F\u002Fexample.com\nBROWSE_BROWSER=firefox browse goto https:\u002F\u002Fexample.com\n```\n\nStealth features and CDP console capture are Chromium-only; Firefox\u002FWebKit use standard Playwright.\n\n## Proxy\n\nRoute browser traffic through a proxy:\n\n```bash\nbrowse --proxy http:\u002F\u002Fproxy:8080 goto https:\u002F\u002Fexample.com\nBROWSE_PROXY=socks5:\u002F\u002Fproxy:1080 browse goto https:\u002F\u002Fexample.com\n```\n\nOr configure in `browse.config.json` with `\"proxy\": { \"server\": \"http:\u002F\u002Fproxy:8080\", \"bypass\": \"localhost\", \"username\": \"u\", \"password\": \"p\" }`.\n\n## Playwright passthrough\n\nPass any Playwright launch or context option via `browse.config.json` without waiting for explicit `browse` support:\n\n```json\n{\n  \"playwright\": {\n    \"launchOptions\": { \"locale\": \"fr-FR\", \"timezoneId\": \"Europe\u002FParis\" },\n    \"contextOptions\": { \"colorScheme\": \"dark\", \"geolocation\": { \"latitude\": 48.86, \"longitude\": 2.35 } }\n  }\n}\n```\n\n`launchOptions` are applied at browser startup; `contextOptions` are applied to isolated sessions and video recording contexts. Browse's own options (headless, viewport, stealth) take precedence on conflict.\n\n## Headed mode\n\nLaunch the browser visibly for debugging (set before the daemon starts):\n\n```bash\nBROWSE_HEADED=1 browse goto https:\u002F\u002Fexample.com\n```\n\n## Timeout control\n\nAny command accepts `--timeout \u003Cms>` (default 30s). Use for slow pages:\n\n```\nbrowse goto https:\u002F\u002Fslow-page.example.com --timeout 60000\n```\n\n## Error recovery\n\n| Error | Fix |\n|-------|-----|\n| `\"element is outside of the viewport\"` | Run `browse scroll @eN` to scroll it into view, then retry |\n| `\"Refs are stale\"` \u002F `\"Unknown ref\"` | Run `browse snapshot` to refresh refs |\n| `\"Daemon connection lost\"` | Re-run the command — CLI auto-restarts the daemon |\n| `\"Command timed out after Nms\"` | Use `--timeout 60000`, or check the URL |\n| `\"Daemon crashed and recovery failed\"` | Run `browse quit`, then retry |\n| `\"Unknown command\"` for a valid command | Stale daemon — run `browse quit`, then retry |\n| `\"Unknown flag\"` | Check `browse help \u003Ccmd>` for valid flags |\n| Login fails | Check env vars, verify login URL, `browse screenshot` to see the page |\n",{"name":5,"description":7,"allowed-tools":51},"Bash(browse:*)","main","08c1df099509b31238c641fc0aa9dd35a795555a",".agents\u002Fskills\u002Fbrowse",1,"https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse","https:\u002F\u002Fgithub.com\u002Fforjd","https:\u002F\u002Fforjd.dev","2026-09-27 05:49:40",{"source":8,"skillName":5,"commands":61,"prompt":71,"zipAvailable":72},[62,65,68],{"tool":63,"command":64},"npx","npx skills add forjd\u002Fbrowse --skill browse",{"tool":66,"command":67},"bunx","bunx skills add forjd\u002Fbrowse --skill browse",{"tool":69,"command":70},"pnpm","pnpm dlx skills add forjd\u002Fbrowse --skill browse","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbrowse\u002FSKILL.md",true,[74,80,84,88,94],{"path":75,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":78,"sourceHtmlUrl":79},"index.json","REFERENCE","参考文档",1080,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fics-historian-server\u002Findex.json",{"path":81,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":82,"sourceHtmlUrl":83},"references\u002Fapi-reference.md",1521,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fics-historian-server\u002Freferences\u002Fapi-reference.md",{"path":85,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002Findex.json",84,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fics-historian-server\u002Freferences\u002Findex.json",{"path":89,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":92,"sourceHtmlUrl":93},"scripts\u002Fagent.py","SCRIPT","脚本",7980,"https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fics-historian-server\u002Fscripts\u002Fagent.py",{"path":95,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":86,"sourceHtmlUrl":96},"scripts\u002Findex.json","https:\u002F\u002Fgithub.com\u002FDCx7C5\u002Fai-marketplace\u002Fblob\u002Fmain\u002Fskills\u002Fics-historian-server\u002Fscripts\u002Findex.json",[98,103,111],{"skillNo":99,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":46},"01M6DNRESSR03S2ZEVQ1YD2YTW","https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fbrowse\u002FSKILL.md",[],[5],{"skillNo":104,"name":105,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":46},"01M6DNRCA99WDD0E2ACC2BM8BA","browse-plugins","https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fbrowse-plugins\u002FSKILL.md",[],[109,5,110],"browse plugins","plugins",{"skillNo":112,"name":105,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":46},"01M6DNR4ZXPQ9AWTJCV1N59QX4","Create plugins for the browse CLI. Use when the user wants to extend browse with custom commands, add lifecycle hooks, or build a browse plugin. Triggers include: 'create a plugin', 'add a command to browse', 'extend browse', 'browse plugin', 'hook into browse'.","https:\u002F\u002Fgithub.com\u002Fforjd\u002Fbrowse\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbrowse-plugins\u002FSKILL.md",[],[110,5,109,117,30,118,119,44,120,121,122,123,124,125],"hooks","commands","build","use","user","command","lifecycle","create","plugin"]