SuperAPI AI Directory

browser-cdp

Testing & quality

View repository

Updated 10-15 21:40

About this skill

Browser CDP operation tool

Control Chrome via the CDP protocol, reuse existing login sessions, and perform browser automation operations.

Prerequisites

  • macOS / Linux / Windows (experimental), Google Chrome installed
  • Node.js 20+
  • agent-browser Installed:npm install -g agent-browser

⚠️ On first launch, it will kill the user's regular Chrome. Before launching, you must obtain the user's consent (see "Launch flow" below), otherwise the user may lose unsaved tabs/drafts.


Launch flow (mandatory steps in skill-mode)

Step 1: Detect the current state (no side effects)

node {SKILL_DIR}/scripts/setup-cdp-chrome.js 9222 --detect-only

Output in the form:

CDP_STATUS=ready                        # 已就绪,可直接复用
CDP_URL=http://127.0.0.1:9222/json/version
BROWSER=Chrome/148.0.7778.168

Or:

CDP_STATUS=needs-setup
CHROME_RUNNING=yes                      # 用户有 Chrome 在跑,启动会杀掉
CHROME_PID_COUNT=3

Step 2: Branch based on the detection result

  • CDP_STATUS=ready → Use directly agent-browser --cdp 9222 ...,Do not run setup。
  • CDP_STATUS=needs-setup and CHROME_RUNNING=no → Safe launch:
    node {SKILL_DIR}/scripts/setup-cdp-chrome.js 9222 --yes
    
  • CDP_STATUS=needs-setup and CHROME_RUNNING=yes → First confirm with the user using the current platform's interactive capability(Claude can use AskUserQuestion; TRAE Code asks directly in the main session and waits for a reply): inform them that N Chrome processes will be killed and unsaved work may be lost; after the user agrees, launch with --yes ; if the user refuses, abandon this automation.

Why you cannot directly --yes: In a non-TTY environment (i.e., skill mode / Bash tool), if the script detects that Chrome is running and there is no --yes, it will exit with code 3 reporting NEEDS_CONSENT: ... and abort,will notsilently kill processes. This is an intentional fallback—but the skill flow should still ask the user first, rather than blindly passing --yes。


Launch script options

Option Description
--detect-only Only detect, do not modify any state (used by skill)
--yes Consent has been obtained, skip the interactive prompt
--reset Clear before launch ~/chrome-debug-profile(used when login has expired)
--profile <name> Use a non-Default Chrome profile (e.g., "Profile 1")
--dry-run Print the steps to be executed without executing them

Exit codes:0 success / 1 general error / 2 user refused (TTY) / 3 consent required but missing --yes。


Common operations

Open a page and wait for it to load

agent-browser --cdp 9222 open "<URL>"
agent-browser --cdp 9222 wait 3000

Extract page text

agent-browser --cdp 9222 eval 'document.body.innerText.substring(0, 8000)'

Extract Auth Token

agent-browser --cdp 9222 eval 'localStorage.getItem("token") || document.cookie'

Complex JS (containing quotes / $ / backticks)

Shell escaping is error-prone; use one of the following two methods:

# 1) base64 包裹
agent-browser --cdp 9222 eval -b "$(echo -n "document.querySelectorAll('a').length" | base64)"

# 2) heredoc + --stdin
cat <<'EOF' | agent-browser --cdp 9222 eval --stdin
const links = document.querySelectorAll('a');
links.length;
EOF

Page interaction (snapshot to get element references)

agent-browser --cdp 9222 snapshot -i        # 仅交互元素
agent-browser --cdp 9222 click "<CSS or @e1>"
agent-browser --cdp 9222 type "<sel>" "<text>"

Stop / clean up

  • Just close the debug Chrome window. If the window is unresponsive, first press --user-data-dir verify the PID of the debug instance and then end only it:
    • macOS / Linux:pgrep -af chrome-debug-profile
    • Windows:wmic process where "name='chrome.exe'" get ProcessId,CommandLine | findstr chrome-debug-profile After obtaining the PID kill -9 {PID} / taskkill /F /PID {PID}. If ownership cannot be verified, stop;Manual cleanup must not batch-kill processes by the Chrome executable name—that would also kill the user's regular Chrome. Exception:setup-cdp-chrome.js --reset internally does perform a cleanup by executable name; it belongs to this skill's built-in launch flow that requires --yes explicit consent; do not copy this approach for manual troubleshooting.
  • Login session expired:node {SKILL_DIR}/scripts/setup-cdp-chrome.js 9222 --reset --yes(note that --yes also requires asking the user first).

OpenCode environment notes

opencode has no tool for executing command-line operations in the background. Long-running CDP operations (such as waiting for page loads or large-scale data scraping) will block the entire session, causing the CLI to become unresponsive.

Timeout Wrapper

On Windows, use a PowerShell Job wrapper timeout for CDP commands:

$job = Start-Job { agent-browser --cdp 9222 eval "window.location.replace('https://www.qidian.com/rank/')" }
Wait-Job $job -Timeout 30 | Out-Null
if ($job.State -eq 'Running') { Stop-Job $job; Write-Output "⏱ CDP 操作超时(30s),请重试或手动打断" }
else { Receive-Job $job }
Remove-Job $job -Force

On macOS / Linux, use the timeout command:

timeout 30 agent-browser --cdp 9222 eval "window.location.replace('https://www.qidian.com/rank/')" || echo "⏱ CDP 操作超时(30s),请重试或手动打断"

Known Limitations

Even with the timeout wrapper, the following scenarios may still cause problems:

Scenario Risk Mitigation
Page load timeout The eval command waits and never returns Set a 30s timeout and retry after timeout
Large-scale data scraping Cumulative wait becomes too long when paging through multiple pages Independent timeout per page; continue from the breakpoint after failure
Chrome process hangs CDP connection is lost but the process has not exited First verify the PID corresponding to the debug profile, end only that debug instance, then reconnect; do not terminate regular Chrome as well
Network fluctuations Requests hang with no timeout Automatically retry once after timeout

If you encounter an operation that keeps hanging, press ESC in opencode to interrupt it manually.


FAQ

Problem Solution
NEEDS_CONSENT + exit code 3 Use the current platform's interactive capability to ask the user whether Chrome may be killed; with Claude you can use AskUserQuestion, TRAE Code asks directly and waits for a reply; after approval add --yes and rerun
CDP port is not listening --detect-only and confirm again; if the port is occupied, switch to another port
Page redirects to the login page snapshot -i to find the login button and interact with it
eval returns null Check the localStorage key name; for JS containing quotes, use eval -b or --stdin
Login state expired setup-cdp-chrome.js 9222 --reset --yes and copy again
There are multiple Chrome profiles --profile "Profile 1" specify
Chrome will not start (30s timeout) Try --reset; check for port conflicts; check whether ~/chrome-debug-profile/ is corrupted