browser-trace について
browser-traceは、ブラウザー自動化の実行を調査する読み取り専用の観測スキルです。ページを操作せず、CDPイベント、定期的なスクリーンショット、DOMスナップショットを記録して整理します。
主な機能
- 01読み取り専用のCDPイベント記録
- 02定期的なスクリーンショットとDOM取得
- 03メソッド別・ページ別のイベント分割
- 04ページ、エラー、ホストの検索
活用シーン
- 01フォームやナビゲーションの失敗調査
- 02実行中の自動化へのトレース追加
- 03ネットワーク・コンソールイベントの確認
- 04スクリーンショットとDOMの時系列比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ browserbase/ skills --skill browser-traceインストール後、Claude Code で/browser-traceを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
EXAMPLES.mdLICENSE.txtpackage.jsonREFERENCE.mdscripts/bb-capture.mjsbb-finalize.mjsbisect-cdp.mjslib.mjsquery.mjssnapshot-loop.mjsstart-capture.mjsstop-capture.mjs詳細
Browser Trace
メインの自動化処理がすでに操作しているブラウザーセッションに、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つ目のクライアントを追加します。このクライアントは監視用ドメイン(Network、Console、Runtime、Log、Page)のみを有効にし、操作コマンドは一切送信しません。
トレーサーは次の3つの要素で構成されます。
- Firehose:
browse cdp <target>は、すべての CDP イベントを1行につき1つの JSON オブジェクトとしてcdp/raw.ndjsonにストリーミングします。 - サンプラー:ポーリングループが一定間隔(デフォルトは2秒)で
browse screenshot --cdp <target> --path <file>とbrowse get html body --cdp <target>を呼び出します。サンプリング時にヘルパーが--cdpを渡すのは、独自のプロセスからトレース対象のターゲットに接続するためです。browse デーモンのセッションが CDP ターゲットに接続されると、そのセッションでの後続コマンドでは--cdpを繰り返し指定する必要はありません。 - 分割処理:実行後、
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は keep-alive セッションの作成とトレーサーのセットアップを行いますが、自動化処理は別途接続する必要があります。
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
すでに実行中のセッション(たとえば、本番ワーカーが作成したセッション)に接続する場合は、--new の代わりにセッション ID を指定して bb-capture.mjs を実行します。
# 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
Browserbase プラットフォームから取得できるもの
bb-capture.mjs は manifest.json に browserbase ブロックを追加します(セッション ID、プロジェクト、リージョン、started_at、expires_at、デバッガー URL)。bb-finalize.mjs は次のファイルを書き出します。
<run>/browserbase/session.json— 最終的なbrowse cloud sessions getのスナップショット(proxyBytes、status、ended_at、viewport など)<run>/browserbase/logs.json—browse cloud sessions logsの出力。空であることがよくあります。 正確な記録はcdp/raw.ndjsonの CDP 全イベントであり、これは補助的な情報経路です。<run>/browserbase/downloads.zip— セッションがダウンロードしたファイル。ダウンロードがない場合に生成される空の22バイトの ZIP は、スクリプトによって破棄されます。
セッションリプレイアーティファクトの取得は非推奨であり、取得されません。視覚的な正確な記録として、screenshots/ と dom/ のスクリーンショットおよび DOM ダンプを使用してください。
マニフェスト内のライブ debugger_url を開くと、Browserbase が提供するインタラクティブな Chrome DevTools ビューを表示できます。トレーサーが CDP の全イベントをディスクに記録している間、長時間実行中の自動化を監視するのに便利です。
ファイルシステムのレイアウト
.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)
bb-capture.mjs 経由で実行を開始した場合、manifest.json にはトップレベルの browserbase ブロックも含まれます。ここには session_id、project_id、region、started_at、expires_at、keep_alive、debugger_url が含まれます。
サマリーの形式
cdp/summary.json はあらゆる分析の入口です。セッションレベルの合計と、トップレベルの Page.frameNavigated に基づいてインデックスされた pages[] 配列があります。ページごとのエントリはナビゲーション順に出力されます(page 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 キーが含まれるのは、値が 0 以外の場合のみです。
query.mjs で詳細を調べる
対話的に調べる場合は、パスを覚える代わりに scripts/query.mjs <run-id> <command> を使用します。
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/<pid>/ ツリーを読み込んでいるだけです。形式がわかったら、生の jq/rg で直接調べてもかまいません。
主なトラバーサルのレシピ
# 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 }'
jq のレシピ集とメソッドごとの二分探索マップについては、REFERENCE.md を参照してください。デバッグのエンドツーエンドのシナリオについては、EXAMPLES.md を参照してください。
ベストプラクティス
- Browserbase では
bb-capture.mjsを使用してください:--keep-aliveを適用し、connectUrl を取得して、デバッガー URL を記録し、マニフェストにタイムスタンプを記録します。手動で行うとミスが発生しやすくなります。 - 自分が所有していないセッションを
--releaseしないでください:bb-finalize.mjs --releaseは、自分で--newを使って作成したセッション向けです。bb-capture.mjs <session-id>経由で本番セッションに接続する場合は、元の自動化を実行し続けるため、--releaseを付けずにbb-finalize.mjsを実行してください。 - リモートでは順序が重要です:Browserbase では、トレーサーの前に(または同時に)メインの自動化クライアントを接続し、
--keep-aliveを付けてセッションを作成してください。そうしないと、トレーサーの WS が閉じた時点でセッションが終了します。 - 約 1 秒より短い間隔でポーリングしないでください:各サンプルではブラウザー CLI の読み取りコマンドを実行し、Chrome のスクリーンショットを撮影します。デフォルトには 2 秒が適しています。
- ドメインを意図的に選択してください:デフォルト(
Network Console Runtime Log Page)で、ほとんどのデバッグをカバーできます。DOM ツリーの変更を調べる場合は、O11Y_DOMAINS="$O11Y_DOMAINS DOM"を使ってDOMを追加してください(非常に大量のログが出ます)。 - リモートでは、1 つの Browserbase セッションを自動化クライアントと再利用してください:
browse open ... --cdp "$CONNECT_URL" --session <name>で、そのセッションのconnectUrlに接続します。--sessionフラグはローカルの browse デーモンの名前を指定するもので、Browserbase セッションへの接続フラグではありません。 - クラッシュ後も含め、必ず
stop-capture.mjsを実行してください:バックグラウンドプロセスが残らないようにし、マニフェストにstopped_atを記録します。 - 二分探索は実行ごとに 1 回行ってください:
bisect-cdp.mjsは冪等です。実行するたびに、raw.ndjsonからバケットごとのファイルを上書きします。
トラブルシューティング
browse cdp exited immediately:通常、対象に到達できない(ポートが間違っている)か、Browserbase セッションがすでに終了していることを意味します。リモートの場合は、browse cloud sessions get <id>で確認してください。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 <id>が「not RUNNING」と表示する:接続しようとしたセッションは終了しています。browse cloud sessions list | jq '.[] | select(.status == "RUNNING")'で候補を一覧表示し、もう一度試してください。browserbase/logs.jsonが空の[]:想定どおりです。実際にはbrowse cloud sessions logsから取得できるログはわずかです。信頼できる情報源は、cdp/raw.ndjsonの CDP イベントストリームです。- セッションの記録(rrweb)はどこにありますか?:セッションリプレイのアーティファクト取得は非推奨になっており、このスキルでは取得しません。
screenshots/のスクリーンショットストリームと、dom/の DOM ダンプを使用してください。
詳しくは、REFERENCE.md を参照してください。 デバッグ実行の例については、EXAMPLES.md を参照してください。