Option
HeimHeim Skill DevOps und CI/CD browser-trace

browser-trace

browserbase/skills browserbase/skills

Erfassen Sie einen vollständigen DevTools-Protokoll-Trace einer beliebigen Browser-Automatisierung, unterteilen Sie den Datenstrom in nach Seiten durchsuchbare Segmente und fügen Sie einen Trace zur Fehlerbehebung einer laufenden Sitzung hinzu.

...Alle erweitern
0
Zeit aktualisiert 30. September 2026

Browser-Trace

Fügen Sie einen zweiten, schreibgeschützten CDP-Client zu einer Browsersitzung hinzu, die bereits von Ihrer Hauptautomatisierung gesteuert wird. Die Ablaufverfolgung zeichnet den gesamten DevTools-Datenstrom in NDJSON auf, fragt parallel nach Screenshots und DOM-Dumps ab und gliedert alles in eine Verzeichnisstruktur, die mit Bash-Tools durchsucht werden kann.

Diese Funktion steuert keine Seiten – sie hört lediglich zu. Kombinieren Sie sie mit der browser Funktion, browse, Stagehand, Playwright oder alles andere, was CDP versteht.

Anwendungsfälle

  • Der Benutzer möchte einen Browser-Automatisierungslauf debuggen (fehlerhaftes Formular, fehlendes Element, hängende Navigation, JS-Ausnahme).
  • Der Benutzer hat eine laufende Automatisierung und möchte während des Ablaufs eine Ablaufverfolgung einfügen, ohne sie neu zu starten.
  • Der Benutzer möchte einen CDP-Firehose in die Kategorien „Netzwerk“, „Konsole“, „DOM“ und „Seite“ aufteilen.
  • Der Benutzer möchte Screenshots und DOM-Snapshots im Zeitverlauf, die anhand von Zeitstempeln mit CDP-Ereignissen verknüpft sind.

Wenn der Benutzer lediglich den Browser steuern möchte, sollte er stattdessen das browser Skill.

Einrichtungsprüfung

node --version                                  # require Node 18+
which browse || npm install -g browse
which jq     || true                                # optional — used only for ad-hoc querying

Überprüfen Sie, ob browse cdp vorhanden ist:

browse --help | grep -q "^\s*cdp " || echo "browse cdp not available — update browse"

So funktioniert es

Jedes Chrome DevTools-Ziel akzeptiert mehrere gleichzeitige CDP-Clients. Ihre Hauptautomatisierung ist ein Client; dieser Skill fügt einen zweiten hinzu, der ausschließlich Beobachtungsdomänen (Netzwerk, Konsole, Laufzeit, Protokoll, Seite) aktiviert und niemals Aktionsbefehle sendet.

Der Tracer besteht aus drei Komponenten:

  1. Firehose: browse cdp überträgt jedes CDP-Ereignis als ein JSON-Objekt pro Zeile an cdp/raw.ndjson.
  2. Sampler: Eine Abfrageschleife ruft browse screenshot --cdp --path und browse get html body --cdp in einem bestimmten Intervall (Standard: 2 s). Der Helper übergibt --cdp , wann er abtastet, damit er sich von seinem eigenen Prozess aus an das verfolgte Ziel anhängen kann; sobald eine Browse-Daemon-Sitzung an ein CDP-Ziel angehängt ist, müssen Folgebefehle in dieser Sitzung nicht wiederholt werden --cdp.
  3. Bisector: Nach dem Lauf bisect-cdp.mjs durchläuft raw.ndjson einmal durch, zerlegt es in JSONL-Dateien pro Bucket, die nach CDP-Methode sortiert sind, und führt zusätzlich eine Bisektion pro Seite anhand von Ereignissen der obersten Ebene Page.frameNavigated Ereignisse als Grenzen.

Schnellstart

Lokaler 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-Remote

Zwei Hilfsfunktionen übernehmen die plattformseitige Verwaltung: bb-capture.mjs erstellt eine Sitzung oder schließt sich einer an und startet den Tracer; bb-finalize.mjs lädt am Ende Plattform-Artefakte (abschließende Sitzungsmetadaten, Serverprotokolle, Downloads) in das Ausführungsverzeichnis.

Browserbase beendet eine Sitzung, sobald sich der letzte CDP-Client abmeldet. Erstellen Sie die Sitzung mit `--keep-alive` und verknüpfen Sie die Automatisierung anschließend vor oder gleichzeitig mit dem Tracer mit dem `connectUrl` der Sitzung. bb-capture.mjs --new übernimmt die Einrichtung der Keep-Alive-Sitzung und des Tracers; Ihre Automatisierung muss weiterhin angehängt werden.

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

Das Anhängen an eine bereits laufende Sitzung (z. B. eine, die Ihr Produktionsmitarbeiter erstellt hat) — bb-capture.mjs akzeptiert eine Sitzungs-ID anstelle von --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

Was Sie von der Browserbase-Plattform erhalten

bb-capture.mjs fügt einen browserbase Block zu manifest.json (Sitzungs-ID, Projekt, Region, started_at, expires_at, Debugger-URL). bb-finalize.mjs schreibt:

  • /browserbase/session.json — endgültiger browse cloud sessions get Snapshot (proxyBytes, Status, ended_at, Viewport, …)
  • /browserbase/logs.json — browse cloud sessions logs Ausgabe. Oft leer. Der CDP-Firehose in cdp/raw.ndjson ist die maßgebliche Quelle; dies ist ein Nebenkanal.
  • /browserbase/downloads.zip — Dateien, die die Sitzung heruntergeladen hat, falls vorhanden (das Skript verworfen die leere 22-Byte-ZIP-Datei, die man erhält, wenn keine vorhanden sind)

Das Abrufen von Session-Replay-Artefakten ist veraltet und wird nicht mehr durchgeführt. Verwenden Sie die Screenshots + DOM-Dumps in screenshots/ und dom/ als visuelle Referenz.

Das Live- debugger_url im Manifest öffnet eine interaktive Chrome-DevTools-Ansicht, die von Browserbase bereitgestellt wird – praktisch, um eine lang andauernde Automatisierung zu beobachten, während der Tracer den Datenstrom auf die Festplatte aufzeichnet.

Dateisystemstruktur

.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)

Wenn ein Lauf über bb-capture.mjs, manifest.json enthält zudem einen Block der obersten Ebene browserbase Block auf oberster Ebene: session_id, project_id, region, started_at, expires_at, keep_alive, debugger_url.

Das „Summary“-Element

cdp/summary.json ist der Einstiegspunkt für jede Analyse: Sie enthält Summen auf Sitzungsebene und ein pages[] Array, das durch die oberste Ebene Page.frameNavigated. Einträge pro Seite werden in Navigationsreihenfolge ausgegeben (Seite 0 = erste konkrete 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 sind Millisekunden der Echtzeit, abgeleitet aus manifest.started_at sowie dem Offset des monotonen CDP-Zeitstempels jedes Ereignisses. domains[*] enthält nur errors/warnings Schlüssel, wenn diese ungleich Null sind.

Vertiefung mit query.mjs

Für die interaktive Erkundung verwenden Sie scripts/query.mjs anstatt sich Pfade zu merken:

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

Im Hintergrund wird lediglich cdp/summary.json und den cdp/pages// Baum – du kannst das gerne mit den Rohdaten jq/rg , sobald du die Struktur kennst.

Die besten Rezepte für die Top-Traversierung

# 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 }'

Die vollständige jq-Rezeptbibliothek sowie eine Methode-für-Methode-Bisektionsübersicht findest du in REFERENCE.md. End-to-End-Debugging-Szenarien findest du in EXAMPLES.md.

Bewährte Vorgehensweisen

  1. Verwende „bb-capture.mjs“ auf Browserbase: Es erzwingt --keep-alive, ruft die `connectUrl` ab, erfasst die Debugger-URL und versieht das Manifest mit einem Zeitstempel. Eine manuelle Vorgehensweise birgt die Gefahr von Fehlern.
  2. Führen Sie „--release“ nicht für eine Sitzung aus, deren Eigentümer Sie nicht sind: bb-finalize.mjs --release gilt nur für Sitzungen, die Sie mit --new. Wenn du dich über bb-capture.mjs , führen Sie bb-finalize.mjs ohne --release , damit die ursprüngliche Automatisierung weiterläuft.
  3. Bei der Fernsteuerung ist die Reihenfolge entscheidend: Verbinden Sie auf Browserbase den Haupt-Automatisierungs-Client vor (oder gleichzeitig mit) dem Tracer und erstellen Sie die Sitzung mit --keep-alive. Andernfalls endet die Sitzung, sobald die WS des Tracers geschlossen wird.
  4. Führen Sie Abfragen nicht schneller als etwa 1 s durch: Bei jedem Durchlauf werden Befehle über die Browser-CLI ausgeführt und Screenshots von Chrome erstellt. 2 s sind ein guter Standardwert.
  5. Wählen Sie Domains bewusst aus: Die Standardeinstellungen (Network Console Runtime Log Page) decken den Großteil der Debugging-Anfälle ab. Füge DOM für DOM-Baum-Änderungen (sehr viele Ereignisse) über O11Y_DOMAINS="$O11Y_DOMAINS DOM".
  6. Verwenden Sie eine Browserbase-Sitzung für den Automatisierungs-Client auf dem Remote-Rechner wieder, indem Sie eine Verbindung zu der connectUrl mit browse open ... --cdp "$CONNECT_URL" --session . Das --session Flag benennt den lokalen Browser-Daemon; es handelt sich nicht um ein Flag zum Anbinden an eine Browserbase-Sitzung.
  7. Führen Sie „stop-capture.mjs“ immer aus, auch nach einem Absturz, damit Hintergrundprozesse nicht weiterlaufen und das Manifest stopped_at.
  8. Führen Sie pro Lauf einmal eine Bisektion durch: bisect-cdp.mjs ist idempotent – es überschreibt die Dateien pro Bucket bei raw.ndjson jedes Mal.

Fehlerbehebung

  • browse cdp exited immediately: Bedeutet in der Regel, dass das Ziel nicht erreichbar ist (falscher Port) oder die Browserbase-Sitzung bereits beendet wurde. Bei Remote-Zugriff überprüfen Sie dies mit browse cloud sessions get — ob status ist COMPLETED, erstellen Sie die Sitzung mit --keep-alive und fügen Sie die Automatisierung zuerst hinzu.
  • Leere „raw.ndjson“, obwohl Prozesse laufen: Vergewissern Sie sich, dass tatsächlich ein CDP-Client die Seite steuert. Der Tracer gibt nur Ereignisse aus, die der Browser generiert; daher erzeugt ein inaktivier Browser etwa 5 Zeilen mit „attach/discover“-Meldungen und sonst nichts.
  • Alle Screenshots sehen identisch aus: Überprüfen Sie index.jsonl — wenn url sich nichts ändert, wurde die Seite noch nicht aufgerufen. Die Abfrageschleife läuft unabhängig vom Tempo der Hauptautomatisierung.
  • Browserbase-Sitzung wird während der Ausführung beendet: Es wurde wahrscheinlich --timeout. Erstellen Sie die Sitzung mit einem höheren Timeout neu (BB_SESSION_TIMEOUT=1800 node scripts/bb-capture.mjs --new ...) oder entferne das Timeout-Flag.
  • bb-capture.mjs zeigt „not RUNNING“ an: Die Sitzung, an die Sie sich anschließen wollten, wurde beendet. Listen Sie mögliche Kandidaten auf und browse cloud sessions list | jq '.[] | select(.status == "RUNNING")' und versuchen Sie es erneut.
  • browserbase/logs.json ist leer []: erwartet – browse cloud sessions logs ist in der Praxis jedoch lückenhaft. Der CDP-Firehose in cdp/raw.ndjson ist die maßgebliche Quelle.
  • Wo ist die Sitzungsaufzeichnung (rrweb)?: Das Abrufen von Artefakten zur Sitzungswiedergabe ist veraltet; diese Funktion ruft diese nicht ab. Verwenden Sie den Screenshot-Stream in screenshots/ und die DOM-Dumps in dom/.

Eine vollständige Referenz finden Sie in REFERENCE.md. Beispiele für Debug-Läufe finden Sie in EXAMPLES.md.

Auf GitHub ansehen
---
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 installieren

Laden Sie die Skill-Dateien herunter und entpacken Sie sie in Ihr Verzeichnis „.claude/skills/“.

ZIP herunterladen

Klonen Sie das Repository und kopieren Sie die Skill-Dateien in Ihr Projekt.

git clone https://github.com/browserbase/skills/tree/main/skills/browser-trace # Copy SKILL.md to your .claude/skills/ directory

Kopieren Kopieren
Schnelle Einrichtung: Kopiere den Skill-Ordner nach .claude/skills/ Claude erkennt den Skill automatisch und nutzt ihn.
Repository browserbase/skills

Ähnliche Skills

klingai-upgrade-migration
Zeit aktualisiert 3. Juli 2026
Verification &amp; Quality Assurance
Zeit aktualisiert 29. Juni 2026
base44-cli
Zeit aktualisiert 29. Juni 2026
Railway CLI Management
Zeit aktualisiert 2. Juli 2026
OR