Fallback browser automation with persistent Chrome state. Use only when Browser Use is unavailable or blocked.
63
76%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/dev-browser/SKILL.mdUse 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 installRun 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/versionHealthy 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());
EOFIf 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());
EOFDefault 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=9222Do not point 9222 at the normal daily Default Chrome profile.
If the wrong Chrome steals 9222, identify it with:
lsof -nP -iTCP:9222 -sTCP:LISTENKill that listener and relaunch the dedicated debug browser. Do not keep debugging against a stale 404 or empty /json/version owner.
45116fd
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.