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 클라이언트를 동시에 수용합니다. 주요 자동화 클라이언트는 하나의 클라이언트이며, 이 스킬은 관찰 도메인(네트워크, 콘솔, 런타임, 로그, 페이지)만 활성화하고 액션 명령을 절대 전송하지 않는 두 번째 클라이언트를 추가합니다.
추적기는 세 가지 구성 요소로 이루어져 있습니다:
- 파이어호스:
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 클라이언트가 연결을 끊는 즉시 세션을 종료합니다. `
--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, 프로젝트, 리전, 시작 시간, 만료 시간, 디버거 URL)을 포함합니다. bb-finalize.mjs 다음과 같이 기록합니다:
— 최종/browserbase/session.json browse cloud sessions get스냅샷 (proxyBytes, status, ended_at, viewport, …)—/browserbase/logs.json browse cloud sessions logs출력. 대개 비어 있습니다.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.
'Summary' 셰이프
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 는 실제 시간(ms)으로, manifest.started_at 에 각 이벤트의 CDP 단조 증가 타임스탬프 오프셋을 더하여 도출됩니다. domains[*] 는 0이 아닐 때만 errors/warnings 0이 아닐 때만 키를 포함합니다.
다음과 같이 드릴다운하여 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 }'
전체 jq 레시피 라이브러리와 메서드별 이분 탐색 맵은 REFERENCE.md를 참조하세요. 종단 간 디버깅 시나리오는 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초보다 빠르게 폴링하지 마세요: 각 샘플은 브라우저 CLI 읽기 명령을 실행하고 Chrome 스크린샷을 찍습니다. 2초가 적절한 기본값입니다.
- 도메인을 신중하게 선택하세요: 기본값(
Network Console Runtime Log Page)는 대부분의 디버깅을 처리합니다.DOM를 통해 DOM 트리 변경(노이즈가 매우 많음)을 처리하십시오.O11Y_DOMAINS="$O11Y_DOMAINS DOM". - 원격의 자동화 클라이언트용 Browserbase 세션을 재사용하려면 해당 세션의
connectUrl를 사용하여 연결하십시오.browse open ... --cdp "$CONNECT_URL" --session를 사용하여 원격의 자동화 클라이언트에 대해 하나의 Browserbase 세션을 재사용하십시오.--session플래그는 로컬 브라우저 데몬의 이름을 지정하는 것이며, Browserbase 세션 연결 플래그가 아닙니다. - 충돌 발생 후에도 항상 `
stop-capture.mjs`를 실행하여 백그라운드 프로세스가 잔류하지 않도록 하고, 매니페스트가stopped_at. - 실행할 때마다 한 번씩 이분법 검색을 수행합니다:
bisect-cdp.mjs는 항등 연산(idempotent)을 수행합니다. 즉, 매번raw.ndjson매번 덮어씁니다.
문제 해결
browse cdp exited immediately: 대개 대상에 연결할 수 없거나(잘못된 포트) Browserbase 세션이 이미 종료되었음을 의미합니다. 원격의 경우, 다음을 통해 확인하십시오.browse cloud sessions get— 만약status인 경우COMPLETED인 경우,--keep-alive를 사용하여 세션을 다시 생성하고 먼저 자동화를 연결하십시오.- 프로세스가 실행 중임에도
raw.ndjson가 비어 있는 경우: CDP 클라이언트가 실제로 페이지를 제어하고 있는지 확인하십시오. 트레이서는 브라우저에서 생성된 이벤트만 전송하므로, 유휴 상태인 브라우저는 약 5줄의 attach/discover 메시지만 생성하고 그 외에는 아무것도 생성하지 않습니다. - 모든 스크린샷이 똑같이 보이는 경우: 다음을 확인하십시오
index.jsonl— 만약url변화하지 않는다면, 페이지가 아직 이동하지 않은 것입니다. 폴링 루프는 메인 자동화의 진행 속도와는 독립적으로 실행됩니다. - 실행 도중 Browserbase 세션이 종료되는 경우: 아마도
--timeout. 타임아웃 값을 높여 다시 생성하십시오(BB_SESSION_TIMEOUT=1800 node scripts/bb-capture.mjs --new ...)로 설정하거나 타임아웃 플래그를 제거하여 다시 생성하십시오. bb-capture.mjs"not RUNNING"이라고 표시됨: 연결하려고 했던 세션이 종료되었습니다.browse cloud sessions list | jq '.[] | select(.status == "RUNNING")'를 사용하여 후보 목록을 확인하고 다시 시도하십시오.browserbase/logs.json[]가 비어 있습니다: 예상된 현상입니다 —browse cloud sessions logs실제로는 드문 경우입니다.cdp/raw.ndjson가 신뢰할 수 있는 정보의 출처입니다.- 세션 녹화(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).
모든 파일
13개 파일browser-trace 설치
스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.
ZIP 다운로드저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.
git clone https://github.com/browserbase/skills/tree/main/skills/browser-trace # Copy SKILL.md to your .claude/skills/ directory
복사





집
