plugins/dev/skills/agent-browser/SKILL.md
Fast browser automation CLI for AI agents. **ALWAYS use instead of Playwright MCP tools** for web testing, screenshots, form filling, and UI verification. Use when user says "open in browser", "check the site", "take a screenshot", "fill the form", "test the UI", or any browser interaction. Also use as a fallback when a task requires visual browser interaction that CLIs and APIs cannot handle (e.g., OAuth flows, complex dashboards, visual verification).
npx skillsauth add coalesce-labs/catalyst agent-browserInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Prefer programmatic tools first (CLIs, APIs, MCP servers). Use agent-browser when:
Do NOT use Playwright MCP tools. If browser automation is needed, always use agent-browser CLI instead.
agent-browser runs a persistent per-session daemon that owns a real "Chrome for Testing" browser. That daemon outlives the CLI — the browser keeps running (and, if left on an auto-refreshing page, keeps re-rendering and pegging a CPU core) until something closes it. On shared fleet/worker hosts a leaked browser starves the box (CTL-1500). So treat every session as something you must open with a name and always close:
--session <name>. Pick a short task-specific name
(e.g. ctl-1500-verify, gh-review). Never rely on the implicit default
session — a shared default collides across concurrent workers and is the hardest
leak to attribute and clean up.close when done. End every task with
agent-browser --session <name> close. Do it in the same turn you finish the
browser work — do not leave a session open "in case". If you took a wrong turn,
close before starting over.default sessions. Every open must carry an
explicit --session. An un-named session on a worker host is a leak waiting to
happen.agent-browser ... open (e.g. until agent-browser --session s open <url>; do sleep …; done) without a guaranteed matching close. Each failed open can
spawn/adopt a browser; a loop that exits without closing strands them. If you must
poll, open once, then use wait/reload, and close in a trap/finally.ALWAYS use --headed and a named session. Headed mode shows a visible browser window so the user can watch. Sessions preserve browser state so they survive accidental closes and can be resumed. Always close the session when the task is done (see Session Hygiene above).
agent-browser --headed --session my-task open https://example.com
agent-browser --headed --session my-task snapshot -i -c
Pick a short descriptive session name for the task (e.g., v0-chat, gh-review, test-login). Use the same --headed --session <name> flags on every command.
If a site requires login, you MUST use --headed so the user can see and interact with the browser window.
agent-browser --headed --session my-task open https://example.com/login
agent-browser --headed --session my-task snapshot -i -c
agent-browser --headed --session my-task state save ./auth-state.json
Sessions persist across commands — once logged in, the session stays active for all subsequent commands. If the browser is closed accidentally, re-open with the same --session name to resume.
These flags apply to ALL commands and should appear before the command name:
--headed # Show visible browser window (default: headless) — ALWAYS USE THIS
--session <name> # Use a named session (preserves state across commands) — ALWAYS USE THIS
--profile <path> # Persistent browser profile directory (survives restarts)
--state <path> # Load storage state from JSON file
--headers <json> # Set HTTP headers scoped to origin
--proxy <url> # Use a proxy server
--ignore-https-errors # Ignore SSL certificate errors
--device <name> # Emulate a device (e.g., "iPhone 14")
--json # Output in JSON format
--debug # Enable debug output
--config <path> # Path to config file
Environment variables (alternative to flags):
AGENT_BROWSER_HEADED=1 # Enable headed mode
AGENT_BROWSER_SESSION=<name> # Set session name
AGENT_BROWSER_PROFILE=<path> # Set profile directory
# Navigation (always include --headed --session <name>)
agent-browser --headed --session s open <url> # Open URL
agent-browser --headed --session s back # Navigate back
agent-browser --headed --session s reload # Reload page
# Get page state (use -i -c for efficiency)
agent-browser --headed --session s snapshot -i -c # Interactive elements only, compact
# Interact using @refs from snapshot
agent-browser --headed --session s click @e2 # Click element
agent-browser --headed --session s fill @e3 "text" # Fill input
agent-browser --headed --session s type @e3 "text" # Type (preserves existing)
agent-browser --headed --session s press Enter # Press key
# Screenshots
agent-browser --headed --session s screenshot # Viewport
agent-browser --headed --session s screenshot -f # Full page
agent-browser --headed --session s screenshot file.png # Save to file
# Get info
agent-browser --headed --session s get text @e1 # Get element text
agent-browser --headed --session s get url # Current URL
agent-browser --headed --session s get title # Page title
# Session management
agent-browser session list # List sessions
agent-browser --headed --session s close # Close browser
-i -c flags on snapshot to get only interactive elements in compact form&& for quick workflows--headed — default is headless, user needs to see the browseragent-browser open <url> # Navigate (aliases: goto, navigate)
agent-browser back # Browser back
agent-browser forward # Browser forward
agent-browser reload # Reload page
agent-browser close # Close browser session (aliases: quit, exit)
agent-browser click <sel> # Click element (--new-tab for new tab)
agent-browser dblclick <sel> # Double-click
agent-browser focus <sel> # Focus element
agent-browser type <sel> <text> # Type without clearing
agent-browser fill <sel> <text> # Clear then fill
agent-browser press <key> # Press key (Enter, Tab, Control+a)
agent-browser hover <sel> # Hover element
agent-browser select <sel> <val> # Select dropdown option
agent-browser check <sel> # Check checkbox
agent-browser uncheck <sel> # Uncheck checkbox
agent-browser scroll <dir> [px] # Scroll (up/down/left/right)
agent-browser scrollintoview <sel> # Scroll element into view
agent-browser drag <src> <tgt> # Drag and drop
agent-browser upload <sel> <files> # Upload files
agent-browser snapshot # Full accessibility tree with refs
agent-browser snapshot -i # Interactive elements only
agent-browser snapshot -i -c # Interactive + compact (RECOMMENDED)
agent-browser snapshot -C # Include cursor-interactive elements
agent-browser snapshot -d <n> # Limit tree depth
agent-browser snapshot -s "<css>" # Scope to CSS selector
agent-browser snapshot --json # JSON output
agent-browser screenshot [path] # Viewport screenshot
agent-browser screenshot -f # Full page screenshot
agent-browser screenshot --annotate # With numbered element labels
agent-browser pdf <path> # Save as PDF
agent-browser get text <sel> # Get text content
agent-browser get html <sel> # Get innerHTML
agent-browser get value <sel> # Get input value
agent-browser get attr <sel> <attr># Get attribute
agent-browser get title # Get page title
agent-browser get url # Get current URL
agent-browser get count <sel> # Count matching elements
agent-browser get box <sel> # Get bounding box
agent-browser get styles <sel> # Get computed styles
agent-browser is visible <sel> # Check visibility
agent-browser is enabled <sel> # Check enabled state
agent-browser is checked <sel> # Check checked state
agent-browser wait <selector> # Wait for element visibility
agent-browser wait <ms> # Wait N milliseconds
agent-browser wait --text "text" # Wait for text to appear
agent-browser wait --url "pattern" # Wait for URL pattern
agent-browser wait --load networkidle # Wait for network idle
agent-browser wait --fn "condition" # Wait for JS condition
agent-browser wait --download [path] # Wait for download
agent-browser state save <path> # Save cookies/localStorage to file
agent-browser state load <path> # Load state from file
agent-browser state list # List saved states
agent-browser state show <file> # Show state contents
agent-browser state clear [name] # Clear a specific state
agent-browser state clear --all # Clear all states
agent-browser auth save <name> # Save an auth flow definition
agent-browser auth save <name> \
--url <url> \
--username <user> \
--password <pass> \
--username-selector <sel> \
--password-selector <sel> \
--submit-selector <sel> # Save with full config
agent-browser auth login <name> # Re-run a saved login
agent-browser auth list # List saved auth configs
agent-browser auth show <name> # Show auth config
agent-browser auth delete <name> # Delete auth config
agent-browser cookies # List cookies
agent-browser cookies set <n> <v> # Set cookie
agent-browser cookies clear # Clear cookies
agent-browser storage local # List localStorage
agent-browser storage local <key> # Get localStorage value
agent-browser storage local set <k> <v> # Set localStorage value
agent-browser storage local clear # Clear localStorage
agent-browser storage session # Same for sessionStorage
agent-browser tab # List tabs
agent-browser tab new [url] # Open new tab
agent-browser tab <n> # Switch to tab n
agent-browser tab close [n] # Close tab
agent-browser frame <sel> # Switch to iframe
agent-browser frame main # Return to main frame
agent-browser eval '<expression>' # Run JavaScript
agent-browser eval --stdin # Read JS from stdin
agent-browser console # View console messages
agent-browser console --clear # Clear console log
agent-browser errors # View JS errors
agent-browser dialog accept [text] # Accept dialog
agent-browser dialog dismiss # Dismiss dialog
agent-browser set viewport <w> <h> # Set viewport size
agent-browser set device <name> # Device emulation (e.g., "iPhone 14")
agent-browser set media [dark|light] # Color scheme
agent-browser set geo <lat> <lng> # Set geolocation
agent-browser set offline [on|off] # Toggle offline mode
agent-browser set headers <json> # Set global headers
agent-browser set credentials <u> <p> # Set HTTP basic auth
agent-browser network requests # Show network requests
agent-browser network requests --filter api # Filter requests
agent-browser network requests --clear # Clear request log
agent-browser network route <url> --abort # Block URL
agent-browser network route <url> --body <json> # Mock response
agent-browser network unroute [url] # Remove intercept
agent-browser find role <role> <action> # Find by ARIA role
agent-browser find text <text> <action> # Find by text
agent-browser find label <label> <action> # Find by label
agent-browser find placeholder <ph> <action> # Find by placeholder
agent-browser find alt <text> <action> # Find by alt text
agent-browser find testid <id> <action> # Find by test ID
agent-browser find nth <n> <sel> <action> # Find nth match
agent-browser trace start [path] # Start Playwright trace
agent-browser trace stop [path] # Stop trace
agent-browser record start <path> # Record interactions
agent-browser record stop # Stop recording
agent-browser highlight <sel> # Highlight element
agent-browser connect <port|url> # Connect to existing browser
--headed on every command — default is headless, user needs to see the browser--session <name> on every command — preserves state, enables recovery--headed and ask the user to log in manuallyagent-browser --session <name> close. The daemon + browser outlive the CLI and leak a CPU-pegging browser on shared hosts if left open (CTL-1500). Never leave a session open; never use unnamed/shared-default sessions or abandoned until … open loops. See Session Hygiene above.development
Migrate a single-harness repo to the dual-harness layout so both Claude Code and Codex load the same instructions and skills — AGENTS.md as the portable canonical doc, a thin CLAUDE.md `@AGENTS.md` bridge, and a `.agents/skills` dir with a `.claude/skills` symlink onto it. Use when asked to migrate to dual-harness, make this repo work in both Claude and Codex, or for agent metadata cleanup.
tools
Goal-driven senior-engineer pipeline-unstick sweep (CTL-1176 rung 3). Given the stuck/failed/needs-human set (or ONE ticket handed by the recovery router), its GOAL is to get the pipeline MOVING again — not to fix one ticket's review findings (that is phase-remediate). It runs AFTER the eyes (diagnostician evidence) and the hands (deterministic unstuck-sweep seams) have already tried, and it CONSUMES their output from a recovery-pass.json brief rather than re-diagnosing or redoing their narrow work. It acts like a senior engineer with full tool access — it resolves merge conflicts, rebases, force-pushes, merges green PRs, and re-dispatches stalled phases AUTONOMOUSLY — and escalates to the operator ONLY for a genuine value judgment / something that degrades other functionality / a real cost-benefit trade-off / a serious architecture change / an ADR conflict. On escalation it AUTHORS the operator inbox row + the push notification (executive-voiced). Dispatched as a `claude --bg` job by phase-agent-dispatch via slash command, AND invocable bare by the operator as a sweep — hence `user-invocable: true`. Ships behind CATALYST_RECOVERY_PASS (off by default — no live behavior change until shadow/enforce).
tools
Diagnose and fix Catalyst setup issues. Validates tools, database, config, OTel, direnv, and thoughts. Automatically fixes what it can — creates directories, initializes the database, sets WAL mode, runs migrations. Use for new installs, upgrades, or when something isn't working.
tools
--- name: phase-triage description: Phase agent that triages a Linear ticket — expands acronyms, classifies (feature/bug/docs/refactor/chore), identifies genuine blockers (a semantic second-pass over the backlog — NOT a prose scrape; CTL-838), estimates scope, writes triage.json, and posts a triage analysis comment to Linear. Triage completion is signaled by that comment plus the local triage.json — there is no `triaged` label. Emits phase.triage.complete.<TICKET> on success and phase.triage.fai