Session Report
Generates a single self-contained HTML file that reconstructs an agent session from its transcript and shows what is in the model's context window and how every token is spent — a forensic debugger for context bloat and the "dumb zone" (context-rot past ~40% of the window).
This is a user-invoked command (/session-report); it is not auto-invoked by the model. The session id is passed as the $session_id argument.
What the report shows
- Verdict header + gauge: peak context vs window, health (Healthy / Degrading / Rotting), one-click jump chips to every issue.
- Context budget at peak: a stacked bar + table partitioning the peak context into system+tools, listings (skills/agents/tools), CLAUDE.md/memory, opened files, user prompts, tool results, assistant text, thinking, and an honest "unattributed (tool schemas/overhead)".
- Context-growth timeline: inline-SVG stacked area of real context size per turn, with the dumb-zone band, the 200K-model ghost line, compaction cliffs, peak marker, and the first dumb-zone crossing.
- Loaded artifacts: CLAUDE.md/AGENTS.md/memory sizes (read from disk), skill/agent/tool listings, opened files — sortable, with "trim me" callouts.
- Biggest items and a full collapsible history of every event (tool calls, results, attachments) with search/filter and the dumb-zone divider inline.
How to run
The generator is a zero-dependency TypeScript script with no build step. Run it from the
skill's scripts/ dir with the requested session id ($session_id). Pick whichever runtime the user has — they need only one:
# Node >= 22.18 / >= 23.6 (native TS type-stripping; most Claude Code users have Node):
node generate-report.ts "$session_id" --open
# Bun:
bun run generate-report.ts "$session_id" --open
# Older Node (no type-stripping) — no install needed, npx fetches it:
npx tsx generate-report.ts "$session_id" --open
Detect what's available (e.g. command -v node bun) and use that. A direct transcript path and options also work, e.g. node generate-report.ts /path/to/<id>.jsonl --out report.html --window 1000000.
If $session_id is empty (the user ran /session-report with no argument), list recent Claude Code sessions and ask which one — e.g. ls -t ~/.claude/projects/*/*.jsonl | head — then re-run with the chosen id.
It finds the transcript by id under ~/.claude/projects/*/, parses it, reads the relevant CLAUDE.md/AGENTS.md/memory files from disk, and writes the HTML (then --opens it if asked).Print the output path to the user.
Options:
--out <file> — output path (default ./ccx-<id>.html).
--window <tokens> — context-window size. Leave the default. Claude Code always runs the 1M window, so keep 1M and do NOT pass --window 200000 unless the user explicitly asks for a 200K view. A peak near 200K is normal 1M usage (~20% full), not evidence of a 200K cap — never infer the window from the peak or from a healthy-looking gauge, and never regenerate to "double-check." If the user does want to compare, the report header has a live in-browser window override, so there's no need to regenerate at all. (Codex records its real window directly, so this flag is irrelevant there.)
--dumb-zone <frac> — degradation threshold as a fraction of the window (default 0.40).
--no-subagents — skip parsing subagent transcripts.
--no-redact — disable secret redaction. Best-effort secret redaction (API keys, tokens, private keys, credential assignments) is ON by default; this flag turns it off and embeds the transcript verbatim.
--codex — force Codex-rollout parsing (auto-detected by default from the file/path).
Key concepts (so you can interpret the report for the user)
- Ground truth vs estimate: per-turn context size is exact from
usage metadata(input + cache_read + cache_creation); per-item sizes are chars/4 estimates.
- Thinking is the usual hidden giant: thinking text is not stored in the transcript, but it is retained in context. The report recovers it from real
output_tokens minus visible text/tool_use — so a huge "thinking" band is accurate, not a guess.
- System+tools residual: first-turn context minus visible loads = the fixed floor (system prompt + tool schemas + global CLAUDE.md). Not in the transcript; partly attributed from disk.
- Unattributed = real peak minus everything attributable ≈ growing tool-definition schemas (from tool search / many MCP servers), per-turn reminders, and encoding overhead. Large value ⇒ tool bloat.
Codex sessions
Codex rollouts (~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl) are also supported; Codex even records model_context_window directly. Pass the rollout path. See scripts/lib/codex.ts.
Notes
- Output is a single HTML file — no server, no network, no external libraries. Open in any browser.
- A deterministic script reads the transcript and writes the HTML; the model never reads or echoes session content. CLAUDE.md/AGENTS.md/memory files are read for size only and are not embedded. The report is a local, private, human-facing artifact — it is not meant to be fed back into an LLM as context.
- Transcript content is HTML-escaped (safe to open in a browser — no XSS), and best-effort secret redaction runs by default, but the file may still contain sensitive data from your session — review before sharing. The report opens with a dismissible banner reminding you of this; use
--no-redact to embed the raw transcript verbatim.
- Large sessions produce multi-MB files (everything is inlined and collapsed by default).
1---2name: session-report3description: Generate a self-contained HTML report that debugs what is in a Claude Code or Codex session's context window and how every token is spent — context budget, the hidden cost of retained thinking, the dumb-zone cutoff, loaded CLAUDE.md/skills, and the full history.4---56# Session Report78Generates a single self-contained HTML file that reconstructs an agent session from its transcript and shows **what is in the model's context window and how every token is spent** — a forensic debugger for context bloat and the "dumb zone" (context-rot past ~40% of the window).910This is a **user-invoked** command (`/session-report`); it is not auto-invoked by the model. The session id is passed as the `$session_id` argument.1112## What the report shows1314- **Verdict header + gauge**: peak context vs window, health (Healthy / Degrading / Rotting), one-click jump chips to every issue.15- **Context budget at peak**: a stacked bar + table partitioning the peak context into system+tools, listings (skills/agents/tools), CLAUDE.md/memory, opened files, user prompts, tool results, assistant text, **thinking**, and an honest "unattributed (tool schemas/overhead)".16- **Context-growth timeline**: inline-SVG stacked area of real context size per turn, with the dumb-zone band, the 200K-model ghost line, compaction cliffs, peak marker, and the first dumb-zone crossing.17- **Loaded artifacts**: CLAUDE.md/AGENTS.md/memory sizes (read from disk), skill/agent/tool listings, opened files — sortable, with "trim me" callouts.18- **Biggest items** and a **full collapsible history** of every event (tool calls, results, attachments) with search/filter and the dumb-zone divider inline.1920## How to run2122The generator is a zero-dependency TypeScript script with **no build step**. Run it from the23skill's `scripts/` dir with the requested session id (`$session_id`). Pick whichever runtime the user has — they need only one:2425```bash26# Node >= 22.18 / >= 23.6 (native TS type-stripping; most Claude Code users have Node):27node generate-report.ts "$session_id" --open28# Bun:29bun run generate-report.ts "$session_id" --open30# Older Node (no type-stripping) — no install needed, npx fetches it:31npx tsx generate-report.ts "$session_id" --open32```3334Detect what's available (e.g. `command -v node bun`) and use that. A direct transcript path and options also work, e.g. `node generate-report.ts /path/to/<id>.jsonl --out report.html --window 1000000`.3536If `$session_id` is empty (the user ran `/session-report` with no argument), list recent Claude Code sessions and ask which one — e.g. `ls -t ~/.claude/projects/*/*.jsonl | head` — then re-run with the chosen id.3738It finds the transcript by id under `~/.claude/projects/*/`, parses it, reads the relevant CLAUDE.md/AGENTS.md/memory files from disk, and writes the HTML (then `--open`s it if asked).Print the output path to the user.3940Options:41- `--out <file>` — output path (default `./ccx-<id>.html`).42- `--window <tokens>` — context-window size. **Leave the default. Claude Code always runs the 1M window, so keep 1M and do NOT pass `--window 200000` unless the user explicitly asks for a 200K view.** A peak near 200K is normal 1M usage (~20% full), not evidence of a 200K cap — never infer the window from the peak or from a healthy-looking gauge, and never regenerate to "double-check." If the user does want to compare, the report header has a live in-browser window override, so there's no need to regenerate at all. (Codex records its real window directly, so this flag is irrelevant there.)43- `--dumb-zone <frac>` — degradation threshold as a fraction of the window (default `0.40`).44- `--no-subagents` — skip parsing subagent transcripts.45- `--no-redact` — disable secret redaction. Best-effort secret redaction (API keys, tokens, private keys, credential assignments) is **ON by default**; this flag turns it off and embeds the transcript verbatim.46- `--codex` — force Codex-rollout parsing (auto-detected by default from the file/path).4748## Key concepts (so you can interpret the report for the user)4950- **Ground truth vs estimate**: per-turn context size is exact from `usage` metadata(`input + cache_read + cache_creation`); per-item sizes are chars/4 estimates.51- **Thinking is the usual hidden giant**: thinking text is *not* stored in the transcript, but it is retained in context. The report recovers it from real `output_tokens` minus visible text/tool_use — so a huge "thinking" band is accurate, not a guess.52- **System+tools residual**: first-turn context minus visible loads = the fixed floor (system prompt + tool schemas + global CLAUDE.md). Not in the transcript; partly attributed from disk.53- **Unattributed** = real peak minus everything attributable ≈ growing tool-definition schemas (from tool search / many MCP servers), per-turn reminders, and encoding overhead. Large value ⇒ tool bloat.5455## Codex sessions5657Codex rollouts (`~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`) are also supported; Codex even records `model_context_window` directly. Pass the rollout path. See `scripts/lib/codex.ts`.5859## Notes6061- Output is a single HTML file — no server, no network, no external libraries. Open in any browser.62- A deterministic script reads the transcript and writes the HTML; the model never reads or echoes session content. CLAUDE.md/AGENTS.md/memory files are read for **size only** and are **not** embedded. The report is a **local, private, human-facing artifact** — it is not meant to be fed back into an LLM as context.63- Transcript content is HTML-escaped (safe to **open** in a browser — no XSS), and best-effort secret redaction runs by default, but the file may still contain sensitive data from your session — **review before sharing**. The report opens with a dismissible banner reminding you of this; use `--no-redact` to embed the raw transcript verbatim.64- Large sessions produce multi-MB files (everything is inlined and collapsed by default).