.agents/skills/dev-browser/SKILL.md
Use this only as the fallback browser path when [@browser-use](plugin://browser-use@openai-bundled) is unavailable or blocked.
Do not substitute Puppeteer, standalone Playwright, or raw Chrome DevTools for this fallback path.
npm install -g dev-browser
dev-browser install
Run dev-browser --help to learn more.
dev-browser --connect http://127.0.0.1:9222 by default. Do not preflight 9222 first.9222 after a direct dev-browser --connect http://127.0.0.1:9222 attempt fails.127.0.0.1:9222. Do not spin up disposable browser instances unless the user asks.--user-data-dir for that debug browser, not the user's normal daily Chrome data dir.open -na "Google Chrome" --args ... --remote-debugging-port=9222 so it opens as a separate Chrome instance without hijacking the user's normal window.browser.getPage("persistent-main") for the main app.dev-browser instead of agent-browser or next-devtools browser_eval./blocks/[id]-demo over docs wrappers when that standalone demo route exists.dev-browser gets blocked by a human prompt or loops on the same step, stop and ask the user to unblock.Use this only after dev-browser --connect http://127.0.0.1:9222 fails because no reusable debug Chrome is available or the CDP endpoint is broken.
--user-data-dir as mandatory, not optional. Chrome 136+ expects remote debugging to happen from a dedicated profile.dev. Do not use the user's normal daily Default profile as the source profile.--user-data-dir; do not point 9222 straight at the user's daily Chrome data dir.open -na "Google Chrome" --args ... for the debug browser. That starts a separate Chrome instance with the dedicated debug profile without touching the user's normal Chrome window.Use a dedicated browser/profile with:
--remote-debugging-address=127.0.0.1--remote-debugging-port=9222--user-data-dir=<debug-profile-dir>Sign in once in that dedicated browser and keep reusing it for agent work.
Quick sanity check:
curl -sS http://127.0.0.1:9222/json/version
Healthy output includes a JSON object with webSocketDebuggerUrl. Empty output or 404 means the wrong process owns 9222.
Then verify:
dev-browser --connect http://127.0.0.1:9222 <<'EOF'
const page = await browser.getPage("persistent-main");
console.log(await page.title());
EOF
If direct connect still cannot resolve CDP even though /json/version is healthy, connect with the exact websocket URL:
WS=$(curl -sS http://127.0.0.1:9222/json/version | jq -r '.webSocketDebuggerUrl')
dev-browser --connect "$WS" <<'EOF'
const page = await browser.getPage("persistent-main");
console.log(await page.title());
EOF
Default setup on macOS:
dev, not the daily Default profile.Local State.9222.python3 - <<'PY'
import json, pathlib
p = pathlib.Path('~/Library/Application Support/Google/Chrome/Local State').expanduser()
obj = json.loads(p.read_text())
for key, val in obj.get('profile', {}).get('info_cache', {}).items():
print(f"{key}\tname={val.get('name')}\tgaia_name={val.get('gaia_name')}")
PY
# Example: if `dev` maps to `Profile 1`, clone `Profile 1`.
mkdir -p "$HOME/.config/google-chrome-debug-profile/Default"
rsync -a --delete \
--exclude='Singleton*' \
--exclude='DevToolsActivePort' \
--exclude='lockfile' \
"$HOME/Library/Application Support/Google/Chrome/Profile 1/" \
"$HOME/.config/google-chrome-debug-profile/Default/"
cp "$HOME/Library/Application Support/Google/Chrome/Local State" \
"$HOME/.config/google-chrome-debug-profile/Local State"
open -na "Google Chrome" --args \
--user-data-dir="$HOME/.config/google-chrome-debug-profile" \
--profile-directory="Default" \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-port=9222
Do not point 9222 at the normal daily Default Chrome profile.
If the wrong Chrome steals 9222, identify it with:
lsof -nP -iTCP:9222 -sTCP:LISTEN
Kill that listener and relaunch the dedicated debug browser. Do not keep debugging against a stale 404 or empty /json/version owner.