browser-trace
browserbase/skills
擷取任何瀏覽器自動化操作的完整 DevTools 協定追蹤記錄,將資料流分割為可按頁面搜尋的區塊,並將追蹤記錄附加至正在進行的執行階段以進行除錯。
...展開全部瀏覽器追蹤
將第二個唯讀的 CDP 客戶端附加至已由您的主要自動化程式驅動的瀏覽器會話。此追蹤功能會將完整的 DevTools 資料流記錄至 NDJSON,並同步擷取螢幕截圖與 DOM 轉儲,最後將所有內容切片成可供 bash 工具搜尋的目錄樹。
此技能不會驅動網頁——它僅負責監聽。請搭配 browser 技能、 browse、Stagehand、Playwright,或任何支援 CDP 協定的工具。
何時使用
- 使用者希望除錯瀏覽器自動化執行過程(表單提交失敗、元素遺漏、導覽卡住、JS 異常)。
- 使用者正在執行自動化任務,並希望在不重新啟動的情況下,於執行過程中附加追蹤資訊。
- 使用者希望將 CDP 資料流拆分為網路/控制台/DOM/頁面等不同類別。
- 使用者希望取得隨時間推移的螢幕截圖與 DOM 快照,並透過時間戳記與 CDP 事件關聯。
若使用者僅需驅動瀏覽器,請改用 browser 技能。
設定檢查
node --version # require Node 18+
which browse || npm install -g browse
which jq || true # optional — used only for ad-hoc querying
請確認 browse cdp 是否存在:
browse --help | grep -q "^\s*cdp " || echo "browse cdp not available — update browse"
運作原理
每個 Chrome DevTools 目標皆可同時接收多個 CDP 客戶端。您的主要自動化程式即為其中一個客戶端;此技能會新增第二個客戶端,該客戶端僅啟用觀察域(網路、主控台、執行時、日誌、頁面),且絕不會傳送操作指令。
此追蹤器包含三個部分:
- Firehose:
browse cdp將每個 CDP 事件以每行一個 JSON 物件的形式串流至cdp/raw.ndjson. - 取樣器:一個輪詢迴圈會呼叫
browse screenshot --cdp並--path browse get html body --cdp以固定間隔(預設 2 秒)執行。該輔助程式在--cdp,以便從其自身程序中附加至被追蹤的目標;一旦瀏覽守護程式會話附加至 CDP 目標後,該會話中的後續指令便無需重複--cdp. - Bisector:執行結束後,
bisect-cdp.mjs會遍歷raw.ndjson一次,將其切分成以 CDP 方法為鍵的各桶位 JSONL 檔案,並額外以頂層Page.frameNavigated事件作為分界點,對每頁進行二分搜尋。
快速入門
本機版 Chrome
# 1. Launch Chrome with a debugger port (any user-data-dir keeps it isolated).
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-o11y \
about:blank &
# 2. Start the tracer.
node scripts/start-capture.mjs 9222 my-run
# 3. Run your main automation against port 9222.
browse open https://example.com --cdp 9222
# ...whatever the run does...
# 4. Stop and bisect.
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run
Browserbase 遠端
兩個輔助函式負責封裝平台端的記錄管理: bb-capture.mjs 建立或連接至一個會話,並啟動追蹤器; bb-finalize.mjs 在執行結束時將平台產出(最終會話元資料、伺服器日誌、下載檔案)匯入執行目錄。
當 Browserbase 的最後一個 CDP 客戶端斷開連接時,Browserbase 會立即結束該會話。請使用 `
--keep-alive` 建立會話,然後在啟動追蹤器之前或與其同時,將自動化任務附加至該會話的 `connectUrl`。bb-capture.mjs --new此操作會處理保持連線的會話及追蹤器設定;您的自動化仍需自行附加。
export BROWSERBASE_API_KEY=...
# 1. Create a keep-alive session AND start the tracer in one step.
# Prints the session id, connectUrl prefix, and a live debugger URL you
# can open in a browser to watch the run interactively.
node scripts/bb-capture.mjs --new my-run
# 2. Drive automation. bb-capture stamped the session id into the manifest.
SID=$(jq -r .browserbase.session_id .o11y/my-run/manifest.json)
CONNECT_URL="$(browse cloud sessions get "$SID" | jq -r .connectUrl)"
BROWSE_NAME=my-run-browser
browse open https://example.com --cdp "$CONNECT_URL" --session "$BROWSE_NAME"
browse open https://news.ycombinator.com --session "$BROWSE_NAME"
# 3. Stop the tracer, bisect, then pull platform artifacts and release.
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run
node scripts/bb-finalize.mjs my-run --release
若要附加至已執行的會話(例如由您的生產線工作人員所建立的會話)—— bb-capture.mjs 接受會話 ID 而非 --new:
# Pick a running session (filter client-side; browse cloud sessions list has no --status flag)
browse cloud sessions list | jq -r '.[] | select(.status == "RUNNING") | .id'
node scripts/bb-capture.mjs mid-flight-debug
# ...tracer runs alongside the existing automation client; no disruption...
node scripts/stop-capture.mjs mid-flight-debug
node scripts/bisect-cdp.mjs mid-flight-debug
node scripts/bb-finalize.mjs mid-flight-debug # without --release: leave the session running
您從 Browserbase 平台獲得的內容
bb-capture.mjs 新增一個 browserbase 區塊至 manifest.json (會話 ID、專案、區域、開始時間、到期時間、除錯器網址)。 bb-finalize.mjs 寫入:
— 最終/browserbase/session.json browse cloud sessions get快照 (proxyBytes, 狀態, 結束時間, 檢視區, …)—/browserbase/logs.json browse cloud sessions logs輸出。通常為空。CDP 資料流在cdp/raw.ndjson是權威資料來源;此處僅為輔助管道。— 該會話所下載的檔案(如有);若無檔案,腳本會捨棄您收到的那個 22 位元組的空 ZIP 檔案/browserbase/downloads.zip
會話重播資料的擷取功能已廢棄,且不會被擷取。請改用 screenshots/ 以及 dom/ 中的螢幕截圖與 DOM 轉儲作為視覺上的真實參考。
若在 debugger_url 項目將開啟由 Browserbase 提供的互動式 Chrome DevTools 視圖 —— 當追蹤器將龐大流量記錄至磁碟時,此功能可方便您監看長時間運行的自動化流程。
檔案系統佈局
.o11y//
manifest.json run metadata: target, domains, started_at, stopped_at
index.jsonl one line per sample: {ts, screenshot, dom, url}
cdp/
raw.ndjson full CDP firehose (one JSON object per line)
summary.json {sessionId, duration, totalEvents, pages[]} — see shape below
network/{requests,responses,finished,failed,websocket}.jsonl session-wide buckets (always written)
console/{logs,exceptions}.jsonl
runtime/all.jsonl
log/entries.jsonl
page/{navigations,lifecycle,frames,dialogs,all}.jsonl
dom/all.jsonl (only if O11Y_DOMAINS includes DOM)
target/{attached,detached}.jsonl
pages/ per-page slices, indexed by top-level frameNavigated boundaries
000/ first concrete page
url.txt the URL for this page
summary.json this page's domains/network/timing block (same shape as a pages[] entry)
raw.jsonl firehose scoped to this page
network/, console/, page/, runtime/, log/, target/, dom/ same buckets, only non-empty files
screenshots/.png one PNG per sample interval
dom/.html one HTML dump per sample interval
browserbase/ added by bb-finalize.mjs (Browserbase runs only)
session.json final `browse cloud sessions get` snapshot (proxyBytes, status, ended_at, …)
logs.json `browse cloud sessions logs` output (often [])
downloads.zip `browse cloud sessions downloads get` output (only if the session downloaded files)
當透過 bb-capture.mjs, manifest.json 也包含一個頂層 browserbase 區塊: session_id, project_id, region, started_at, expires_at, keep_alive, debugger_url.
摘要形狀
cdp/summary.json 是所有分析的起點:它包含工作階段層級的總計,以及一個 pages[] 以頂層 Page.frameNavigated作為索引的陣列。各頁面的條目會依照導覽順序輸出(第 0 頁 = 第一個具體 URL)。
{
"sessionId": "45f28023-…",
"duration": { "startMs": 1777312533000, "endMs": 1777312609000, "totalMs": 76000 },
"totalEvents": 420,
"pages": [
{
"pageId": 0,
"url": "https://example.com/",
"startMs": 1777312533000, "endMs": 1777312538886, "durationMs": 5886,
"eventCount": 60,
"domains": {
"Network": { "count": 18, "errors": 1 },
"Console": { "count": 2 },
"Page": { "count": 24 },
"Runtime": { "count": 13 }
},
"network": { "requests": 4, "failed": 1, "byType": { "Document": 2, "Script": 1, "Other": 1 } }
}
]
}
startMs / endMs / durationMs 為實時毫秒,源自 manifest.started_at 加上每個事件的 CDP 單調時間戳的偏移量。 domains[*] 僅包含 errors/warnings 非零的鍵值。
透過 query.mjs
若要進行互動式探索,請使用 scripts/query.mjs ,無需記憶路徑:
node scripts/query.mjs my-run list # one-line table of pages
node scripts/query.mjs my-run page 1 # full summary for page 1
node scripts/query.mjs my-run page 1 network/failed # cat failed.jsonl for page 1
node scripts/query.mjs my-run errors # all errors across pages, attributed by pid
node scripts/query.mjs my-run errors 2 # errors from page 2 only
node scripts/query.mjs my-run hosts # top hosts by request count
node scripts/query.mjs my-run host api.example.com # all requests/responses for a host
node scripts/query.mjs my-run summary # full summary.json
在幕後,它只是讀取 cdp/summary.json ,並生成 cdp/pages/ 樹狀結構 — 一旦熟悉了形狀, jq/rg 。
頂部遍歷實用範例
# All failed network requests (use jq -c to keep it line-delimited)
jq -c '.params' .o11y//cdp/network/failed.jsonl
# Find requests to a specific host
jq -c 'select(.params.request.url | test("api\\.example\\.com"))' \
.o11y//cdp/network/requests.jsonl
# 4xx/5xx responses
jq -c 'select(.params.response.status >= 400)
| {status: .params.response.status, url: .params.response.url}' \
.o11y//cdp/network/responses.jsonl
# Console errors only
jq -c 'select(.params.type == "error")' .o11y//cdp/console/logs.jsonl
# Sequence of URLs visited
jq -r '.params.frame.url' .o11y//cdp/page/navigations.jsonl
# Find the screenshot taken closest to a timestamp (e.g., when an exception fired)
ls .o11y//screenshots/ | sort | awk -v t=20260427T1714123NZ '
$0 >= t { print; exit }'
請參閱 REFERENCE.md 以取得完整的 jq 指令庫及逐項方法的二分搜尋對應表。請參閱 EXAMPLES.md 以了解端到端的除錯情境。
最佳實務
- 請在 Browserbase 上使用 `
bb-capture.mjs`:它會強制執行--keep-alive,擷取 connectUrl、記錄除錯器 URL,並在清單檔案上加蓋標記。手動操作容易導致錯誤。 - 請勿對非您所擁有的會話執行 `
--release`:bb-finalize.mjs --release僅適用於您使用--new所建立的會話。當透過bb-capture.mjs附著至生產環境會話時,請執行,bb-finalize.mjs時請勿使用--release,以便原始自動化能持續運行。 - 遠端操作時順序很重要:在 Browserbase 上,請在追蹤器之前(或與其同時)附加主自動化客戶端,並使用
--keep-alive建立工作階段。否則,一旦追蹤器的 WS 關閉,工作階段便會立即結束。 - 輪詢頻率請勿低於約 1 秒:每次採樣都會執行瀏覽器命令列的讀取指令並擷取 Chrome 螢幕截圖。2 秒是個不錯的預設值。
- 請謹慎選擇網域:預設值(
Network Console Runtime Log Page) 已涵蓋多數除錯需求。若需偵測DOM透過O11Y_DOMAINS="$O11Y_DOMAINS DOM". - 透過附加至該連線的
connectUrl並使用browse open ... --cdp "$CONNECT_URL" --session。--session標誌用於指定本機瀏覽器守護程式;這並非 Browserbase 連線標誌。 - 請始終執行
stop-capture.mjs,即使在發生當機後亦然,以確保背景程序不會殘留,並使清單能stopped_at. - 每次執行時進行一次二分法排查:
bisect-cdp.mjs是幂等操作 — 它會覆寫raw.ndjson每次。
疑難排解
browse cdp exited immediately:通常表示目標無法連線(端口錯誤)或 Browserbase 會話已結束。若為遠端執行,請使用browse cloud sessions get— 若status為COMPLETED,請使用--keep-alive並先附加自動化程式。- 即使程序正在運行,
raw.ndjson仍為空:請確認 CDP 客戶端確實正在驅動該頁面。追蹤器僅會發出瀏覽器所產生的事件,因此閒置的瀏覽器僅會產生約 5 行連接/偵測訊息,除此之外別無其他。 - 所有螢幕截圖看起來都一模一樣:檢查
index.jsonl— 若url沒有變化,表示頁面尚未進行導航。輪詢迴圈的執行節奏獨立於主要自動化流程。 - Browserbase 會話在執行中途結束:這很可能是觸發了
--timeout。請以較長的超時設定重新建立(BB_SESSION_TIMEOUT=1800 node scripts/bb-capture.mjs --new ...) 重新建立,或移除超時標記。 bb-capture.mjs顯示「未執行中」:您嘗試附加的執行階段已結束。請列出候選項目並browse cloud sessions list | jq '.[] | select(.status == "RUNNING")'並重新嘗試。browserbase/logs.json[]為空:屬預期行為 —browse cloud sessions logs在實際應用中較為稀疏。位於cdp/raw.ndjson中的 CDP 數據流才是最終依據。- 會話錄影(rrweb)在哪裡?:會話重播資料的擷取功能已廢棄;此技能不會擷取該資料。請使用
screenshots/中的螢幕截圖串流,以及dom/.
完整參考資料請參閱 REFERENCE.md。 範例除錯執行請參閱 EXAMPLES.md。
---
name: browser-trace
description: Capture a full DevTools-protocol trace of any browser automation, bisect the stream into per-page searchable buckets, and attach a trace to an in-progress session for debugging.
license: MIT
---
# Browser Trace
Attach a **second, read-only CDP client** to a browser session that is already being driven by your main automation. The trace records the full DevTools firehose to NDJSON, polls for screenshots and DOM dumps in parallel, and slices everything into a directory tree that bash tools can search.
This skill does **not** drive pages — it only listens. Pair it with the `browser` skill, `browse`, Stagehand, Playwright, or anything else that speaks CDP.
## When to use
- The user wants to debug a browser-automation run (failing form, missing element, hung navigation, JS exception).
- The user has a running automation and wants to attach a trace mid-flight without restarting it.
- The user wants to split a CDP firehose into network / console / DOM / page buckets.
- The user wants screenshots + DOM snapshots over time, joined to CDP events by timestamp.
If the user just wants to **drive** the browser, use the `browser` skill instead.
## Setup check
```bash
node --version # require Node 18+
which browse || npm install -g browse
which jq || true # optional — used only for ad-hoc querying
```
Verify `browse cdp` exists:
```bash
browse --help | grep -q "^\s*cdp " || echo "browse cdp not available — update browse"
```
## How it works
Every Chrome DevTools target accepts **multiple concurrent CDP clients**. Your main automation is one client; this skill adds a second one that only enables observation domains (Network, Console, Runtime, Log, Page) and never sends action commands.
The tracer has three pieces:
1. **Firehose**: `browse cdp <target>` streams every CDP event as one JSON object per line to `cdp/raw.ndjson`.
2. **Sampler**: a polling loop calls `browse screenshot --cdp <target> --path <file>` and `browse get html body --cdp <target>` on an interval (default 2s). The helper passes `--cdp` when it samples so it can attach to the traced target from its own process; once a browse daemon session is attached to a CDP target, follow-up commands in that session do not need to repeat `--cdp`.
3. **Bisector**: after the run, `bisect-cdp.mjs` walks `raw.ndjson` once, slices it into per-bucket JSONL files keyed by CDP method, and additionally bisects per page using top-level `Page.frameNavigated` events as boundaries.
## Quickstart
### Local Chrome
```bash
# 1. Launch Chrome with a debugger port (any user-data-dir keeps it isolated).
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-o11y \
about:blank &
# 2. Start the tracer.
node scripts/start-capture.mjs 9222 my-run
# 3. Run your main automation against port 9222.
browse open https://example.com --cdp 9222
# ...whatever the run does...
# 4. Stop and bisect.
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run
```
### Browserbase remote
Two helpers wrap the platform-side bookkeeping: `bb-capture.mjs` creates or attaches to a session and starts the tracer; `bb-finalize.mjs` pulls platform artifacts (final session metadata, server logs, downloads) into the run dir at the end.
> Browserbase ends a session as soon as its last CDP client disconnects. **Create with `--keep-alive`, then attach automation to the session's `connectUrl` before or together with the tracer.** `bb-capture.mjs --new` handles the keep-alive session and tracer setup; your automation still needs to attach.
```bash
export BROWSERBASE_API_KEY=...
# 1. Create a keep-alive session AND start the tracer in one step.
# Prints the session id, connectUrl prefix, and a live debugger URL you
# can open in a browser to watch the run interactively.
node scripts/bb-capture.mjs --new my-run
# 2. Drive automation. bb-capture stamped the session id into the manifest.
SID=$(jq -r .browserbase.session_id .o11y/my-run/manifest.json)
CONNECT_URL="$(browse cloud sessions get "$SID" | jq -r .connectUrl)"
BROWSE_NAME=my-run-browser
browse open https://example.com --cdp "$CONNECT_URL" --session "$BROWSE_NAME"
browse open https://news.ycombinator.com --session "$BROWSE_NAME"
# 3. Stop the tracer, bisect, then pull platform artifacts and release.
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run
node scripts/bb-finalize.mjs my-run --release
```
Attaching to a session that's *already running* (e.g. one your production worker created) — `bb-capture.mjs` accepts a session id instead of `--new`:
```bash
# Pick a running session (filter client-side; browse cloud sessions list has no --status flag)
browse cloud sessions list | jq -r '.[] | select(.status == "RUNNING") | .id'
node scripts/bb-capture.mjs <session-id> mid-flight-debug
# ...tracer runs alongside the existing automation client; no disruption...
node scripts/stop-capture.mjs mid-flight-debug
node scripts/bisect-cdp.mjs mid-flight-debug
node scripts/bb-finalize.mjs mid-flight-debug # without --release: leave the session running
```
#### What you get from the Browserbase platform
`bb-capture.mjs` adds a `browserbase` block to `manifest.json` (session id, project, region, started_at, expires_at, debugger URL). `bb-finalize.mjs` writes:
- `<run>/browserbase/session.json` — final `browse cloud sessions get` snapshot (proxyBytes, status, ended_at, viewport, …)
- `<run>/browserbase/logs.json` — `browse cloud sessions logs` output. **Often empty.** The CDP firehose in `cdp/raw.ndjson` is the source of truth; this is a side channel.
- `<run>/browserbase/downloads.zip` — files the session downloaded, if any (the script discards the empty 22-byte zip you get when there are none)
Session replay artifact fetching is **deprecated** and isn't fetched. Use the screenshots + DOM dumps in `screenshots/` and `dom/` for visual ground truth.
The live `debugger_url` in the manifest opens an interactive Chrome DevTools view served by Browserbase — handy for *watching* a long-running automation while the tracer captures the firehose to disk.
## Filesystem layout
```
.o11y/<run-id>/
manifest.json run metadata: target, domains, started_at, stopped_at
index.jsonl one line per sample: {ts, screenshot, dom, url}
cdp/
raw.ndjson full CDP firehose (one JSON object per line)
summary.json {sessionId, duration, totalEvents, pages[]} — see shape below
network/{requests,responses,finished,failed,websocket}.jsonl session-wide buckets (always written)
console/{logs,exceptions}.jsonl
runtime/all.jsonl
log/entries.jsonl
page/{navigations,lifecycle,frames,dialogs,all}.jsonl
dom/all.jsonl (only if O11Y_DOMAINS includes DOM)
target/{attached,detached}.jsonl
pages/ per-page slices, indexed by top-level frameNavigated boundaries
000/ first concrete page
url.txt the URL for this page
summary.json this page's domains/network/timing block (same shape as a pages[] entry)
raw.jsonl firehose scoped to this page
network/, console/, page/, runtime/, log/, target/, dom/ same buckets, only non-empty files
screenshots/<iso-ts>.png one PNG per sample interval
dom/<iso-ts>.html one HTML dump per sample interval
browserbase/ added by bb-finalize.mjs (Browserbase runs only)
session.json final `browse cloud sessions get` snapshot (proxyBytes, status, ended_at, …)
logs.json `browse cloud sessions logs` output (often [])
downloads.zip `browse cloud sessions downloads get` output (only if the session downloaded files)
```
When a run was started via `bb-capture.mjs`, `manifest.json` also carries a top-level `browserbase` block: `session_id`, `project_id`, `region`, `started_at`, `expires_at`, `keep_alive`, `debugger_url`.
### Summary shape
`cdp/summary.json` is the entry point for any analysis: it has session-level totals and a `pages[]` array indexed by top-level `Page.frameNavigated`. Per-page entries are emitted in navigation order (page 0 = first concrete URL).
```json
{
"sessionId": "45f28023-…",
"duration": { "startMs": 1777312533000, "endMs": 1777312609000, "totalMs": 76000 },
"totalEvents": 420,
"pages": [
{
"pageId": 0,
"url": "https://example.com/",
"startMs": 1777312533000, "endMs": 1777312538886, "durationMs": 5886,
"eventCount": 60,
"domains": {
"Network": { "count": 18, "errors": 1 },
"Console": { "count": 2 },
"Page": { "count": 24 },
"Runtime": { "count": 13 }
},
"network": { "requests": 4, "failed": 1, "byType": { "Document": 2, "Script": 1, "Other": 1 } }
}
]
}
```
`startMs` / `endMs` / `durationMs` are wall-clock ms, derived from `manifest.started_at` plus the offset of each event's CDP monotonic timestamp. `domains[*]` only includes `errors`/`warnings` keys when non-zero.
### Drilling in with `query.mjs`
For interactive exploration, use `scripts/query.mjs <run-id> <command>` instead of remembering paths:
```bash
node scripts/query.mjs my-run list # one-line table of pages
node scripts/query.mjs my-run page 1 # full summary for page 1
node scripts/query.mjs my-run page 1 network/failed # cat failed.jsonl for page 1
node scripts/query.mjs my-run errors # all errors across pages, attributed by pid
node scripts/query.mjs my-run errors 2 # errors from page 2 only
node scripts/query.mjs my-run hosts # top hosts by request count
node scripts/query.mjs my-run host api.example.com # all requests/responses for a host
node scripts/query.mjs my-run summary # full summary.json
```
Behind the scenes it just reads `cdp/summary.json` and the `cdp/pages/<pid>/` tree — feel free to bypass it with raw `jq`/`rg` once you know the shape.
## Top traversal recipes
```bash
# All failed network requests (use jq -c to keep it line-delimited)
jq -c '.params' .o11y/<run>/cdp/network/failed.jsonl
# Find requests to a specific host
jq -c 'select(.params.request.url | test("api\\.example\\.com"))' \
.o11y/<run>/cdp/network/requests.jsonl
# 4xx/5xx responses
jq -c 'select(.params.response.status >= 400)
| {status: .params.response.status, url: .params.response.url}' \
.o11y/<run>/cdp/network/responses.jsonl
# Console errors only
jq -c 'select(.params.type == "error")' .o11y/<run>/cdp/console/logs.jsonl
# Sequence of URLs visited
jq -r '.params.frame.url' .o11y/<run>/cdp/page/navigations.jsonl
# Find the screenshot taken closest to a timestamp (e.g., when an exception fired)
ls .o11y/<run>/screenshots/ | sort | awk -v t=20260427T1714123NZ '
$0 >= t { print; exit }'
```
See **REFERENCE.md** for the full jq recipe library and a method-by-method bisect map. See **EXAMPLES.md** for end-to-end debug scenarios.
## Best practices
1. **Use `bb-capture.mjs` on Browserbase**: it enforces `--keep-alive`, fetches the connectUrl, captures the debugger URL, and stamps the manifest. Doing it manually invites mistakes.
2. **Don't `--release` a session you don't own**: `bb-finalize.mjs --release` is for sessions *you* created with `--new`. When attaching to a production session via `bb-capture.mjs <session-id>`, run `bb-finalize.mjs` without `--release` so the original automation keeps running.
3. **Order matters for remote**: on Browserbase, attach the main automation client before (or together with) the tracer, and create the session with `--keep-alive`. Otherwise the session ends as soon as the tracer's WS closes.
4. **Don't poll faster than ~1s**: each sample runs browser CLI read commands and screenshots Chrome. 2s is a good default.
5. **Pick domains deliberately**: defaults (`Network Console Runtime Log Page`) cover most debugging. Add `DOM` for DOM-tree mutations (very noisy) via `O11Y_DOMAINS="$O11Y_DOMAINS DOM"`.
6. **Reuse one Browserbase session for the automation client on remote** by attaching to that session's `connectUrl` with `browse open ... --cdp "$CONNECT_URL" --session <name>`. The `--session` flag names the local browse daemon; it is not a Browserbase session attach flag.
7. **Always run `stop-capture.mjs`**, even after a crash, so background processes don't linger and the manifest gets `stopped_at`.
8. **Bisect once per run**: `bisect-cdp.mjs` is idempotent — it overwrites the per-bucket files from `raw.ndjson` each time.
## Troubleshooting
- **`browse cdp exited immediately`**: usually means the target is unreachable (wrong port) or the Browserbase session has already ended. For remote, verify with `browse cloud sessions get <id>` — if `status` is `COMPLETED`, recreate with `--keep-alive` and attach automation first.
- **Empty `raw.ndjson` even though processes are running**: confirm a CDP client is actually driving the page. The tracer only emits events that the browser generates, so an idle browser produces ~5 lines of attach/discover messages and nothing else.
- **Screenshots all look identical**: check `index.jsonl` — if `url` doesn't change, the page hasn't navigated yet. The polling loop runs independently of the main automation's pace.
- **Browserbase session ends mid-run**: it likely hit `--timeout`. Recreate with a higher timeout (`BB_SESSION_TIMEOUT=1800 node scripts/bb-capture.mjs --new ...`) or remove the timeout flag.
- **`bb-capture.mjs <id>` says "not RUNNING"**: the session you tried to attach to ended. List candidates with `browse cloud sessions list | jq '.[] | select(.status == "RUNNING")'` and try again.
- **`browserbase/logs.json` is empty `[]`**: expected — `browse cloud sessions logs` is sparse in practice. The CDP firehose in `cdp/raw.ndjson` is the source of truth.
- **Where's the session recording (rrweb)?**: session replay artifact fetching is deprecated; this skill doesn't fetch it. Use the screenshot stream in `screenshots/` and DOM dumps in `dom/`.
For full reference, see [REFERENCE.md](REFERENCE.md).
For example debug runs, see [EXAMPLES.md](EXAMPLES.md).





首頁
