Skip to content
Back to skills

Session Stats

ASecurity

Render the quantitative metrics of a Claude Code session as one self-contained, dark-theme HTML page. The output is **stats only**: KPI cards for headline numbers (duration, prompts, tool calls, files written/edited, output tokens, est. cost), a per-tool usage table with share bars, and a token-bucket table (input, output, cache created, cache read). No prompts, observations, tone analysis, or recommendations.

  • 3 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 6, 2026
ai-agentspythonshellbashgitapi

Works with

  • claude code
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 1, 2026

npx -y skills add chrismccoy/forge --skill session-stats --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Session Stats?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Session Stats
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrismccoy-session-stats/badge)](https://www.skillsdirectory.com/skills/chrismccoy-session-stats)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# session-stats

## Purpose

Render the quantitative metrics of a Claude Code session as one self-contained, dark-theme HTML
page. The output is **stats only**: KPI cards for headline numbers (duration, prompts, tool calls,
files written/edited, output tokens, est. cost), a per-tool usage table with share bars, and a
token-bucket table (input, output, cache created, cache read). No prompts, observations, tone
analysis, or recommendations.

Two bundled scripts form an offline pipeline with no third-party Python packages (standard library only; requires Python 3). `scan_jsonl.py` parses a
session `.jsonl` transcript and computes every metric, including a cost estimate derived from each
assistant message's token `usage` times per-model pricing. `build_stats_html.py` injects the result
into a fixed dark template and writes a standalone document.

## When to Use

Use this skill to produce a shareable visual of session *numbers* - duration, prompts, tool calls,
files written/edited, output tokens, est. cost, per-tool usage breakdown, and token buckets - styled
in the dark template, written to a standalone `.html` file that opens in any browser with no external
assets, scripts, or fonts.

Do not use this skill for full session summaries, narrative retros, or recommendations - this skill
emits stats only.

## Process

1. **Get the scan JSON.** `${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/scan_jsonl.py` parses a Claude Code `.jsonl` transcript and emits
   the metrics JSON, computing cost from token `usage` times per-model pricing (the transcript stores
   token counts, not dollars, so cost is always computed here). Find the current session file, then
   scan it:

   ```bash
   # Locate the current session transcript (POSIX: macOS / Linux / WSL / Git Bash)
   ls -t "$HOME/.claude/projects/<project-slug>"/*.jsonl | head -1
   # Scan it
   python3 "${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/scan_jsonl.py" --in <session.jsonl> > /tmp/scan.json
   ```

   On Windows/PowerShell, resolve the newest transcript natively:

   ```powershell
   Get-ChildItem "$env:USERPROFILE\.claude\projects\<project-slug>\*.jsonl" |
     Sort-Object LastWriteTime -Descending | Select-Object -First 1
   ```

   Or just use the Glob tool (`**/.claude/projects/<project-slug>/*.jsonl`, newest first) to stay
   shell-agnostic. Invoke the scripts with `python` (the usual command on Windows); if that is not
   found, try `py -3` - note `python3` is often absent on Windows.

   Pricing follows the current Claude API catalog via a per-model table (Opus, Sonnet, Haiku, Fable),
   defaulting to Opus 4.8 = $5/$25 per MTok in/out, cache write $6.25, cache read $0.50. A model with
   no table entry renders cost as `N/A` rather than $0. Override rates without editing the script via
   env vars (per MTok): `IN_RATE`, `OUT_RATE`, `CW_RATE`, `CR_RATE`. promptCount excludes slash-command
   and system turns.

2. **Render the HTML.** Run the builder, or pipe the two stages directly:

   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/build_stats_html.py" --in /tmp/scan.json --out session-stats.html
   ```

   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/scan_jsonl.py" --in <session.jsonl> \
     | python3 "${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/build_stats_html.py" --out session-stats.html
   ```

   When a scan holds multiple sessions, select one by id/slug prefix:

   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/build_stats_html.py" --in /tmp/scan.json --session 657aa92f --out session-stats.html
   ```

3. **Report.** State the output path and confirm the page is self-contained (no `<script>`, no
   external assets). Offer to open it or change the destination. Render values come only from the
   transcript - never invent metrics; missing fields render as `N/A`.

### Bundled files

- **`${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/scan_jsonl.py`** - Parses a Claude Code `.jsonl` transcript into the metrics JSON,
  computing cost from token `usage` times per-model pricing. Pure stdlib, no third-party packages.
  Supports `IN_RATE`/`OUT_RATE`/`CW_RATE`/`CR_RATE` env overrides. Cost groups assistant messages by
  model and sums input/output/cache-write/cache-read tokens times their rates, divided by one million;
  an unpriced model makes the whole cost render `N/A`, never $0. Also emits a per-tool call breakdown
  (`toolBreakdown`, sorted by count) and summed token buckets (`tokens`: input/output/cacheCreated/cacheRead)
  that feed the usage and token tables. The `API errors` metric is a heuristic (substring match on
  assistant text), so treat it as approximate.
- **`${CLAUDE_PLUGIN_ROOT}/lib/session-stats/scripts/build_stats_html.py`** - Converts the metrics JSON into the stats HTML. Handles session
  selection (`--session` prefix match), duration/cost/int formatting, HTML-escaping, and template
  injection. `--template <path>` overrides the bundled `${CLAUDE_PLUGIN_ROOT}/lib/session-stats/assets/template.html`. Pure stdlib. Exit
  codes: `0` ok, `1` no session / bad JSON, `2` template missing.
- **`${CLAUDE_PLUGIN_ROOT}/lib/session-stats/assets/template.html`** - The fixed dark-theme shell, an inline static-CSS port of the design (no
  Tailwind, no `<script>`, no external assets). The script replaces the single `<!-- CONTENT -->` marker
  with the rendered stats body. To restyle, edit the CSS variables in `:root` (e.g. `--accent`, `--ember`,
  `--ink`, `--coal`); `build_content()` in `build_stats_html.py` emits the matching `.kpi` / `table.t` /
  `.bar` classes, so keep those class names in sync if structural rules change.

## Validation

- [ ] Output is one complete `<!DOCTYPE html>` document with no external references and no `<script>` tags.
- [ ] Stats only: no narrative sections, observations, or recommendations.
- [ ] Every number traces to the transcript; absent metrics show `N/A`, never a guess.
- [ ] The page is self-contained and opens in any browser with no external assets, scripts, or fonts.

Files in this skill

  • SKILL.md5.9 KB
  • assets/template.html2.7 KB
  • scripts/build_stats_html.py6.3 KB
  • scripts/scan_jsonl.py8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.