Detect the available browser interaction layer and load the right commands — then navigate, click, fill, and screenshot through a unified verb set. playwright-cli is the default, recommended layer; falls back to Playwright MCP, cmux-browser, or CDP when it is absent. Use before any browser interaction in skills that shouldn't hardcode a specific layer. Triggers on: browser universal, detect browser, browser layer, browser setup, which browser, browser interaction, open browser, use browser.
77
97%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Detect which browser interaction layer is available and load its commands.
playwright-cli is the default, recommended layer. If it is not present, fall
back to Playwright MCP, cmux-browser, or CDP — in that order.
If the consuming skill or user specifies a layer, use that directly and skip detection. Otherwise, run the detection ladder below.
Check each layer in order. The first one available wins — use it and stop. Do not keep probing once a layer is found.
command -v playwright-cliAvailable if this exits 0 (the binary is on PATH). That is the whole check — no subcommand inspection needed. If found, use it and skip the rest of the ladder.
Check if mcp__plugin_playwright_playwright__browser_navigate exists in your
available tools. If yes, Playwright MCP is available. No shell command needed.
cmux ping 2>/dev/nullAvailable if this returns success (exit code 0).
CDP_JS="$(command -v cdp.js 2>/dev/null || \
find ~/.claude -path "*/cdp-connect/scripts/cdp.js" -type f 2>/dev/null | head -1)"
[[ -n "$CDP_JS" ]] && node "$CDP_JS" list --port 9222Available if cdp.js is found AND list returns tab output (not a connection
error). Store CDP_JS for all subsequent CDP commands.
If every check fails, report this to the user and stop:
No browser interaction layer detected. To enable one:
- playwright-cli: install it so it's on your PATH (recommended)
- Playwright MCP: install the Playwright MCP plugin for Claude Code
- cmux-browser: start cmux and create a browser surface
- CDP: launch Chrome with `chrome --remote-debugging-port=9222`Do not proceed with browser actions — this is a blocking error.
Load the detected layer's command reference from the layers guide. Read only the section matching the detected layer (playwright-cli, Playwright MCP, cmux-browser, or CDP) for targeting model, key commands, and layer-specific gotchas.
Quick reference mapping universal actions to layer-specific commands:
| Verb | playwright-cli | Playwright MCP | cmux-browser | CDP |
|---|---|---|---|---|
| navigate | goto | browser_navigate | navigate | navigate |
| snapshot | snapshot | browser_snapshot | snapshot --compact | ax-tree |
| click | click (ref) | browser_click (ref) | click (selector) | click (selector) |
| fill | fill (ref) | browser_type (ref) | fill (selector) | type (selector) |
| eval | eval | browser_evaluate | eval | eval |
| screenshot | screenshot | browser_take_screenshot | snapshot | screenshot |
| wait | eval polling | browser_wait_for | wait --load-state | eval polling |
| tabs.list | tab-list | browser_tabs | tab list | list |
| tabs.open | open / tab-new | browser_tabs (create) | tab new | eval "window.open()" |
| tabs.select | tab-select (index) | browser_tabs (select) | tab switch | --id <target-id> |
| tabs.close | tab-close | browser_tabs (close) | tab close | eval "window.close()" |
e5, e12) → refs invalidate after state changes → re-snapshot.#submit,
.btn-primary, button[type="submit"]).After any state-changing action (click, fill, navigate, tab switch), re-read page state (snapshot) before the next interaction. This applies to every layer.