Detect available browser interaction layer (Playwright MCP, Slicc playwright-cli, cmux-browser, CDP) and load the right commands — then navigate, click, fill, and screenshot through a unified verb set. 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.
100
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
Detect which browser interaction layer is available and load its commands. Four supported layers: Playwright MCP, Slicc playwright-cli, cmux-browser, CDP.
If the consuming skill or user specifies a layer, use that directly and skip detection. Otherwise, detect and use default priority below.
Run these checks in parallel to determine available layers:
Check if mcp__plugin_playwright_playwright__browser_navigate exists in your
available tools. If yes, Playwright MCP is available. No shell command needed.
playwright-cli help 2>/dev/nullAvailable if the output contains Slicc-specific commands (snapshot, tab-list,
teleport). A generic playwright-cli without these is NOT Slicc.
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 multiple layers are detected, use: Slicc > cmux-browser > Playwright MCP > CDP
If all checks fail, report this to the user and stop:
No browser interaction layer detected. To enable one:
- Playwright MCP: install the Playwright MCP plugin for Claude Code
- Slicc: run `npx sliccy` to launch a Slicc session
- 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 MCP, Slicc playwright-cli, cmux-browser, or CDP) for targeting model, key commands, and layer-specific gotchas.
Quick reference mapping universal actions to layer-specific commands:
| Verb | Playwright MCP | Slicc | cmux-browser | CDP |
|---|---|---|---|---|
| navigate | browser_navigate | goto | navigate | navigate |
| snapshot | browser_snapshot | snapshot | snapshot --compact | ax-tree |
| click | browser_click (ref) | click (ref) | click (selector) | click (selector) |
| fill | browser_type (ref) | fill (ref) | fill (selector) | type (selector) |
| eval | browser_evaluate | eval | eval | eval |
| screenshot | browser_take_screenshot | screenshot | snapshot | screenshot |
| wait | browser_wait_for | eval polling | wait --load-state | eval polling |
| tabs.list | browser_tabs | tab-list | tab list | list |
| tabs.open | browser_tabs (create) | open / tab-new | tab new | eval "window.open()" |
| tabs.select | browser_tabs (select) | tab-select (index) | tab switch | --id <target-id> |
| tabs.close | browser_tabs (close) | tab-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.