|
| 1 | +--- |
| 2 | +description: One-time setup for a persistent debug browser on `127.0.0.1:9222` for `dev-browser --connect`. Use when browser work is needed but no reusable debug browser is running yet. |
| 3 | +--- |
| 4 | + |
| 5 | +# Browser Debug Setup |
| 6 | + |
| 7 | +Use this skill when `dev-browser --connect http://127.0.0.1:9222` fails because |
| 8 | +no persistent debug browser is running yet. |
| 9 | + |
| 10 | +## Goal |
| 11 | + |
| 12 | +Get the user onto one persistent browser/profile that both the human and the |
| 13 | +agent reuse. Minimize the `Allow remote debugging?` popup by keeping one |
| 14 | +dedicated debug browser/profile alive. |
| 15 | + |
| 16 | +## Rules |
| 17 | + |
| 18 | +- Prefer one permanent debug browser/profile over disposable automation |
| 19 | + browsers. |
| 20 | +- Treat a custom `--user-data-dir` as mandatory, not optional. Chrome 136+ |
| 21 | + basically wants remote debugging to happen from a dedicated profile. |
| 22 | +- Keep auth in that profile. Do not fall back to cookie dumps or state files |
| 23 | + unless the user asks. |
| 24 | +- Use a separate signed-in Chrome profile for browser work, like `dev`. Do not |
| 25 | + use the user's normal daily `Default` profile as the source profile. |
| 26 | +- Clone that separate signed-in Chrome profile into the dedicated debug |
| 27 | + `--user-data-dir`; do not point `9222` straight at the user's daily Chrome |
| 28 | + data dir. |
| 29 | +- On macOS, use `open -na "Google Chrome" --args ...` for the debug browser. |
| 30 | + That starts a separate Chrome instance with the dedicated debug profile |
| 31 | + without touching the user's normal Chrome window. |
| 32 | + |
| 33 | +## Preferred Shape |
| 34 | + |
| 35 | +Use a dedicated browser/profile with: |
| 36 | + |
| 37 | +- `--remote-debugging-address=127.0.0.1` |
| 38 | +- `--remote-debugging-port=9222` |
| 39 | +- a persistent `--user-data-dir=<debug-profile-dir>` |
| 40 | + |
| 41 | +Sign in once in that dedicated browser and keep reusing it for agent work. |
| 42 | + |
| 43 | +Quick sanity check: |
| 44 | + |
| 45 | +```bash |
| 46 | +curl -sS http://127.0.0.1:9222/json/version |
| 47 | +``` |
| 48 | + |
| 49 | +Healthy output includes a JSON object with `webSocketDebuggerUrl`. Empty output |
| 50 | +or `404` means the wrong process owns `9222`. |
| 51 | + |
| 52 | +Then verify `dev-browser`: |
| 53 | + |
| 54 | +```bash |
| 55 | +dev-browser --connect http://127.0.0.1:9222 <<'EOF' |
| 56 | +const page = await browser.getPage("persistent-main"); |
| 57 | +console.log(await page.title()); |
| 58 | +EOF |
| 59 | +``` |
| 60 | + |
| 61 | +If `dev-browser --connect http://127.0.0.1:9222` still cannot resolve CDP even |
| 62 | +though `/json/version` is healthy, connect with the exact websocket URL: |
| 63 | + |
| 64 | +```bash |
| 65 | +WS=$(curl -sS http://127.0.0.1:9222/json/version | jq -r '.webSocketDebuggerUrl') |
| 66 | + |
| 67 | +dev-browser --connect "$WS" <<'EOF' |
| 68 | +const page = await browser.getPage("persistent-main"); |
| 69 | +console.log(await page.title()); |
| 70 | +EOF |
| 71 | +``` |
| 72 | + |
| 73 | +## Google Chrome Path |
| 74 | + |
| 75 | +Default setup on macOS: |
| 76 | + |
| 77 | +1. Pick a separate signed-in Chrome profile for agent work, like `dev`, not |
| 78 | + the daily `Default` profile. |
| 79 | +2. Map that human-facing Chrome profile name to the real folder in `Local State`. |
| 80 | +3. Clone that profile into the dedicated debug dir. |
| 81 | +4. Launch a separate Chrome instance on `9222`. |
| 82 | +5. Leave that debug window open and reuse it. |
| 83 | + |
| 84 | +```bash |
| 85 | +python3 - <<'PY' |
| 86 | +import json, pathlib |
| 87 | +p = pathlib.Path('~/Library/Application Support/Google/Chrome/Local State').expanduser() |
| 88 | +obj = json.loads(p.read_text()) |
| 89 | +for key, val in obj.get('profile', {}).get('info_cache', {}).items(): |
| 90 | + print(f"{key}\tname={val.get('name')}\tgaia_name={val.get('gaia_name')}") |
| 91 | +PY |
| 92 | + |
| 93 | +# Example: if `dev` maps to `Profile 1`, clone `Profile 1`. |
| 94 | +mkdir -p "$HOME/.config/google-chrome-debug-profile/Default" |
| 95 | +rsync -a --delete \ |
| 96 | + --exclude='Singleton*' \ |
| 97 | + --exclude='DevToolsActivePort' \ |
| 98 | + --exclude='lockfile' \ |
| 99 | + "$HOME/Library/Application Support/Google/Chrome/Profile 1/" \ |
| 100 | + "$HOME/.config/google-chrome-debug-profile/Default/" |
| 101 | +cp "$HOME/Library/Application Support/Google/Chrome/Local State" \ |
| 102 | + "$HOME/.config/google-chrome-debug-profile/Local State" |
| 103 | + |
| 104 | +open -na "Google Chrome" --args \ |
| 105 | + --user-data-dir="$HOME/.config/google-chrome-debug-profile" \ |
| 106 | + --profile-directory="Default" \ |
| 107 | + --remote-debugging-address=127.0.0.1 \ |
| 108 | + --remote-debugging-port=9222 |
| 109 | +``` |
| 110 | + |
| 111 | +That keeps the signed-in identity while still satisfying Chrome's dedicated |
| 112 | +`--user-data-dir` requirement. |
| 113 | + |
| 114 | +Then keep reusing that exact debug browser. Do not point `9222` at your normal |
| 115 | +daily `Default` Chrome profile. |
| 116 | + |
| 117 | +## After Setup |
| 118 | + |
| 119 | +- Use `dev-browser --connect http://127.0.0.1:9222` for browser work. |
| 120 | +- Reuse named pages like `persistent-main`. |
| 121 | +- Do not stop the user's debug browser unless they ask. |
| 122 | +- If the wrong Chrome steals `9222`, identify it with `lsof -nP -iTCP:9222 -sTCP:LISTEN`, |
| 123 | + kill that listener, and relaunch the dedicated debug browser. Do not keep |
| 124 | + debugging against a stale `404` or empty `/json/version` owner. |
0 commit comments