オプション
家家 Skill DevOps と CI/CD browser-trace

browser-trace

browserbase/skills browserbase/skills

任意のブラウザ自動化処理の DevTools プロトコル・トレースを完全に取得し、そのストリームをページごとに検索可能なバケットに分割して、デバッグのために進行中のセッションにトレースを添付します。

...すべて拡張します
0
更新された時間 2026年9月30日

ブラウザトレース

メインの自動化ツールによってすでに制御されているブラウザセッションに、2つ目の読み取り専用CDPクライアントを接続します。このトレースは、DevToolsからの全ログをNDJSON形式で記録し、スクリーンショットやDOMダンプを並行して取得し、それらすべてをbashツールで検索可能なディレクトリツリーに整理します。

このスキルはページを操作するものではなく、単に受信するだけです。これを browser スキル、 browse、Stagehand、Playwright、あるいはCDPに対応したその他のツールと組み合わせて使用できます。

使用場面

  • ユーザーがブラウザ自動化の実行をデバッグしたい場合(フォームの失敗、要素の欠落、ナビゲーションのフリーズ、JS例外など)。
  • ユーザーが実行中の自動化処理があり、再起動せずに実行途中でトレースを添付したい場合。
  • ユーザーがCDPのファイアホースを、ネットワーク/コンソール/DOM/ページの各バケットに分割したい場合。
  • ユーザーが、タイムスタンプによってCDPイベントと関連付けられた、経時的なスクリーンショットとDOMスナップショットを取得したい場合。

単にブラウザを操作したいだけの場合は、代わりに 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クライアントを同時に受け入れます。メインの自動化は1つのクライアントですが、このスキルは2つ目のクライアントを追加します。このクライアントは、監視ドメイン(ネットワーク、コンソール、ランタイム、ログ、ページ)のみを有効にし、アクションコマンドを送信することはありません。

トレーサーは以下の3つの要素で構成されています:

  1. Firehose: browse cdp すべてのCDPイベントを、1行につき1つのJSONオブジェクトとしてストリーム配信し、 cdp/raw.ndjson.
  2. Sampler:ポーリングループが browse screenshot --cdp --path を呼び出し、 browse get html body --cdp 一定の間隔(デフォルトは2秒)で呼び出されます。このヘルパーは --cdp をサンプル時に渡すことで、自身のプロセスからトレース対象にアタッチできるようにします。ブラウズデーモンのセッションが CDP ターゲットに一度アタッチされると、そのセッション内の後続コマンドで --cdp.
  3. Bisector:実行後、 bisect-cdp.mjs ウォーク raw.ndjson 1回ウォークし、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 リモート

2 つのヘルパー関数が、プラットフォーム側の管理処理をラップしています。 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 が信頼できる情報源であり、これは副次的な情報源です。
  • /browserbase/downloads.zip — セッションでダウンロードされたファイル(ある場合)。(スクリプトは、ファイルがない場合に生成される空の22バイトの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[*] は、 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 }'

jqのレシピライブラリ全体と、メソッドごとのバイセクトマップについては、REFERENCE.mdを参照してください。エンドツーエンドのデバッグシナリオについては、EXAMPLES.mdを参照してください。

ベストプラクティス

  1. Browserbaseではbb-capture.mjsを使用してください。これにより、 --keep-alive、connectUrlを取得し、デバッガーのURLをキャプチャし、マニフェストにスタンプを押し込みます。手動で行うとミスを招く恐れがあります。
  2. 自分が所有していないセッションに対して--releaseを実行しないでください: bb-finalize.mjs --release は、 --newで作成したセッションを対象としています。 bb-capture.mjs を介して本番環境のセッションにアタッチする際は、を実行してください。 bb-finalize.mjs を省略して --release 実行してください。そうすることで、元のオートメーションが継続して実行されます。
  3. リモート接続では順序が重要です。Browserbaseでは、トレーサーの前に(または同時に)メインのオートメーションクライアントを接続し、 --keep-aliveでセッションを作成してください。そうしないと、トレーサーのWSが閉じるとすぐにセッションが終了してしまいます。
  4. ポーリング間隔は~1秒より短くしないでください:各サンプルでは、ブラウザCLIの読み取りコマンドを実行し、Chromeのスクリーンショットを撮影します。デフォルトでは2秒が適しています。
  5. ドメインは慎重に選択してください:デフォルト設定(Network Console Runtime Log Page)で、ほとんどのデバッグに対応できます。DOMツリーの変更(ノイズが非常に多い)については DOM を使用してDOMツリーの変更(ノイズが非常に多い)を検出してください O11Y_DOMAINS="$O11Y_DOMAINS DOM".
  6. リモート上の自動化クライアントでは、そのセッションの connectUrl を使用して接続することで、リモート上の自動化クライアントで1つのBrowserbaseセッションを再利用できます。 browse open ... --cdp "$CONNECT_URL" --session 。 --session フラグはローカルのブラウズデーモンを指定するものであり、Browserbaseセッションへのアタッチフラグではありません。
  7. クラッシュ後であっても常にstop-capture.mjsを実行するようにします。これにより、バックグラウンドプロセスが残存せず、マニフェストが stopped_at.
  8. 実行ごとに 1 回バイセクトを実行します: bisect-cdp.mjs は冪等性があり、バケットごとのファイルを 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を参照してください。

GitHubで見る
---
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).

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

コピー コピー
クイックセットアップ: スキルフォルダを .claude/skills/ にコピーしてください。 Claude が自動的にそのスキルを検出して使用します。
リポジトリ browserbase/skills

関連スキル

klingai-upgrade-migration
更新された時間 2026年7月3日
Verification &amp; Quality Assurance
更新された時間 2026年6月29日
base44-cli
更新された時間 2026年6月29日
Railway CLI Management
更新された時間 2026年7月2日
OR