token-spend-report · git:20260706.7ed8c4d · 2026-07-06 · sha256 560a4347f023e582

token-spend-report git:20260706.7ed8c4dA

Immutable. This exact content is served forever at /api/v1/blob/560a4347f023e582.

---
name: token-spend-report
description: Regenerate Overdeck's public token spend report from the post-rebrand cost archive
triggers:
  - token spend report
  - regenerate spend report
  - update cost report
  - rebuild token report
  - cost history report
allowed-tools:
  - Bash
  - Read
  - Edit
---

# Token Spend Report

Use this skill when regenerating `docs/token-spend-report/index.html`, the public
Overdeck token spend report published at
`https://eltmon.github.io/overdeck/token-spend-report/`.

## Non-Negotiables

- Use `~/.overdeck/costs/events.jsonl` as the single report data source.
- Sort events by `ts` before aggregating. Backfill can append older reconstructed
  events after newer rows.
- Run `pan cost backfill` first. Use dry-run first, then `pan cost backfill --write`
  when the dry-run summary is sane.
- Keep the per-harness coverage boundary from
  `docs/token-spend-report/coverage.json` visible in the report.
- Keep the archival note that the pre-rebrand era, Feb 2025 through Jun 2026
  with 734,117 calls and about $54k spend, was deliberately not imported.
- Do not combine with a legacy SQLite database or any pre-rebrand live cost file.
- Do not regenerate videos unless the user explicitly asks.

## Pre-Flight

Read the existing report before editing:

```bash
sed -n '1,220p' docs/token-spend-report/index.html
```

Check the current coverage file when present:

```bash
test -f docs/token-spend-report/coverage.json && cat docs/token-spend-report/coverage.json
```

Preserve the report's existing dark visual system and chart structure unless the
user asks for a redesign. In particular, keep the monthly cost chart as a bar
chart with `borderRadius: 6` and `borderSkipped: false`, and keep the subscription
comparison labels unchanged.

## Backfill First

Run the catch-up command before extracting report numbers:

```bash
pan cost backfill
pan cost backfill --write
```

The dry-run should print per-source sessions scanned, would-import/imported
events, duplicates skipped, errors, and earliest/latest event timestamps. Treat
non-zero errors or surprising coverage gaps as something to investigate before
regenerating the HTML.

## Extract Data

Aggregate from `~/.overdeck/costs/events.jsonl` only:

```bash
node <<'NODE'
const fs = require('fs');
const path = `${process.env.HOME}/.overdeck/costs/events.jsonl`;
const events = fs.readFileSync(path, 'utf8')
  .split('\n')
  .filter(Boolean)
  .map((line) => JSON.parse(line))
  .sort((a, b) => String(a.ts).localeCompare(String(b.ts)));

const total = events.reduce((acc, e) => {
  acc.cost += Number(e.cost || 0);
  acc.calls += 1;
  acc.tokens += Number(e.input || 0) + Number(e.output || 0)
    + Number(e.cacheRead || 0) + Number(e.cacheWrite || 0);
  return acc;
}, { cost: 0, calls: 0, tokens: 0 });

console.log(total);
NODE
```

For the report data object, compute:

- `models`: top 10 by cost, with token totals.
- `providers`: provider cost totals.
- `stages`: `sessionType` cost totals.
- `monthly`: `YYYY-MM` cost totals sorted chronologically.
- `issues`: top 15 by `issueId`, with cost, calls, and average cost per call.
- `dailyCosts`: `YYYY-MM-DD` cost totals sorted chronologically.

Fetch issue titles from the Overdeck repo when useful:

```bash
gh issue view <number> --repo eltmon/overdeck --json title --jq '.title'
```

Use descriptive placeholders for `UNKNOWN`, test issues, or non-GitHub IDs.

## Update HTML

Edit `docs/token-spend-report/index.html`:

- Update hero counters from the extracted totals.
- Replace the full `reportData` object, preserving the variable name.
- Preserve existing card and chart structure.
- Keep the coverage banner prominent and orange/warning-styled.
- Keep the archival note stating the pre-rebrand era was deliberately not imported.
- Do not claim continuity with the old $54k figure.

If updating `fileGrowth`, use true git tree snapshots, not per-commit churn:

```bash
git log --format="%ad %H" --date=short --reverse \
  | awk '{ last[$1]=$2 } END { for (d in last) print d, last[d] }' | sort \
  | while read -r day hash; do
      echo "{\"date\":\"$day\",\"files\":$(git ls-tree -r --name-only "$hash" | wc -l)}"
    done | paste -sd, - | sed 's/^/const fileGrowth = [/; s/$/];/'
```

Do not add a running-max smoothing pass. Repository file count is allowed to go
down when files are deleted.

## Verify

Run the report data parse check:

```bash
node -e "const html=require('fs').readFileSync('docs/token-spend-report/index.html','utf8');const m=html.match(/reportData\s*=\s*(\{[\s\S]*?\});/);JSON.parse(JSON.stringify(eval('('+m[1]+')')));console.log('reportData parses')"
```

Confirm the required honesty language is present:

```bash
grep -c "deliberately not imported\\|734,117\\|~/.overdeck/costs/events.jsonl" docs/token-spend-report/index.html
```

For visual verification, serve the repo and inspect the page with an isolated
browser profile:

```bash
python3 -m http.server 8765
```

Open `http://localhost:8765/docs/token-spend-report/`, check every chart, and
confirm there are no console errors.

## Publish

Do not publish manually. The GitHub Pages workflow in
`.github/workflows/pages.yml` publishes only `docs/token-spend-report/` after
merge to `main`.