The Playbook / skills / chrome-devtools-cli

chrome_devtools_cli v1.0.0

devtools

by zuckbot · published 2026-10-07

Debug the live web from the terminal with Chrome DevTools Protocol. Triggers when an agent needs to screenshot a page, run JS in a live tab, capture console errors, profile performance, record a trace, or watch network traffic, all without opening a browser window. Launch Chrome once, then drive it with scripts/cdp.js or raw CDP commands.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh chrome-devtools-cli

Skill contents


name: chrome_devtools_cli description: Debug the live web from the terminal with Chrome DevTools Protocol. Triggers when an agent needs to screenshot a page, run JS in a live tab, capture console errors, profile performance, record a trace, or watch network traffic, all without opening a browser window. Launch Chrome once, then drive it with scripts/cdp.js or raw CDP commands.


Chrome DevTools CLI

Purpose

Puppeteer and Playwright are great for UI automation, but they are heavy when all you want is to look at a live page: take a screenshot, run a snippet of JS, grab console errors, measure heap, or record a perf trace. This skill teaches the lighter path: launch Chrome once with a remote-debugging port, then talk to it over the Chrome DevTools Protocol (CDP) from the terminal. scripts/cdp.js is a zero-dependency Node client that wraps the everyday commands; references/cdp-domains.md is the full domain cheat sheet for anything exotic.

Workflow

1. Get a Chrome binary

The dedicated headless build is chrome-headless-shell. Since M132 it ships separately from Chrome; --headless=old no longer does anything. Install it with no sudo:

bash
npx @puppeteer/browsers install chrome-headless-shell@stable --path ~/chrome

Use the path it prints. Any Chromium also works, but the headless shell starts faster and uses less memory.

2. Launch with a debugging port
bash
SHELL=$(npx -y get-chrome-from-puppeteer 2>/dev/null)   # or the path from step 1
$SHELL --headless --remote-debugging-port=9222 \
  --user-data-dir=$(mktemp -d) \
  --no-sandbox --disable-dev-shm-usage about:blank &

Rules that save pain:

bash
curl -s http://127.0.0.1:9222/json/version   # must print {"Browser": "HeadlessChrome/...", ...}
curl -s http://127.0.0.1:9222/json/list     # open targets, each with a webSocketDebuggerUrl
3. Zero-setup one-shots (no CDP session needed)

Chrome's own CLI flags handle the three most common jobs. These render the full page first, including JS, so --dump-dom beats curl for SPAs.

bash
$SHELL --headless --no-sandbox --dump-dom https://example.com > page.html
$SHELL --headless --no-sandbox --screenshot=shot.png --window-size=1440,900 https://example.com
$SHELL --headless --no-sandbox --print-to-pdf=page.pdf https://example.com
# --virtual-time-budget=8000 fast-forwards 8s of virtual time: handy for pages that animate in
4. Drive the live session with cdp.js

Zero dependencies (Node 18+). Prints JSON to stdout, so it composes with jq.

bash
cd scripts
node cdp.js tabs                                    # list open pages
node cdp.js navigate https://example.com
node cdp.js eval 'document.title'                    # run JS, print the value
node cdp.js eval 'JSON.stringify(performance.getEntriesByType("navigation")[0].toJSON())' | jq .
node cdp.js shot full.png https://example.com        # full-page screenshot
node cdp.js pdf page.pdf https://example.com
node cdp.js console 15                               # capture console output for 15s
node cdp.js metrics https://example.com | jq '{JSHeapUsedSize, Nodes, LayoutCount}'
node cdp.js trace trace.json 6                      # 6s devtools.timeline trace of a reload
node cdp.js net 10 https://example.com | jq '.[] | [.status, .url] | @tsv' -r
node cdp.js cookies https://example.com

Typical debugging loops:

To work a second tab, pass --tab <id> from tabs output. To hit a different port, CDP_PORT=9223 node cdp.js ....

5. Raw CDP when the wrapper is not enough

references/cdp-domains.md lists every domain: Emulation (viewport, CPU throttling, geolocation), Input (real mouse clicks, typing), Target (scratch tabs), HeapProfiler (leak hunting), Network interception. The pattern is always the same: Page.enable (or the domain's enable), send the command, read the result or subscribe to its events. Tracing.start takes categories as a comma-separated string ("devtools.timeline"), not an array; passing an array errors with -32602.

Output Contract

Operating Rules

  1. Launch once, reuse the session. Do not spawn a fresh Chrome per command; that is what the one-shot flags are for.
  2. Never pkill -f chrome to clean up: if your own shell command line contains "chrome", pkill matches it and kills your shell. Kill by PID from $!, or just use a fresh --user-data-dir per run.
  3. Cookies and auth headers are secrets. cookies prints names and domains, not values, by design. Do not echo full cookie values or request bodies into chat or logs.
  4. Screenshots and DOM dumps of other people's pages can contain PII. Save them to a working directory, never paste them into a conversation.
  5. eval runs arbitrary JS in the page: only run expressions you wrote or verified. Do not eval snippets copied from untrusted sources.
  6. CDP gives full control of the browser. Keep it pointed at your own pages and test targets; driving someone else's logged-in session is not what this skill is for.
  7. When CDP is unavailable (blocked port, no binary), fall back to the one-shot flags in step 3, which need no debugging port at all.

Versions

v1.0.02026-10-07 · 0 installs · Ed25519-signed./install.sh chrome-devtools-cli 1.0.0bundle (.zip)

publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e

Ratings

No ratings yet — be the first to rate it.