Estimates AI token usage from claude.ai network traffic and (soon) renders it as a fire-themed contribution heatmap, exportable as a LinkedIn/X cover photo. Conversation text is processed locally in memory only long enough to estimate tokens; the extension stores counts and metadata, never conversation text.
Phase 1: single-player, Claude only, zero backend. See TokenBurn-PRD.md
(product) and TokenBurn-ESOD.md (engineering) for the full specs, and
CLAUDE.md for the build contract.
Spike 0 result (ESOD §4.3): claude.ai's consumer completion stream
(POST .../chat_conversations/<id>/completion) parses as clean SSE but carries
no usage/token integers — only message.model, stop_reason, and a
message_limit object. So TokenBurn uses estimate capture: it tokenizes
the observed prompt (request.prompt) and the assistant's visible answer text
(content_block_delta text_delta), excluding extended-thinking by design
(ESOD §4.4). Model is captured natively (e.g. claude-opus-4-6).
The pipeline now runs end to end:
fetch/XHR (MAIN world)
→ interceptor (clone stream, page untouched) lib/interceptor.ts
→ dispatch → Claude adapter (estimate) lib/dispatch.ts, lib/providers/claude.ts
→ normalizer (UsageEvent) lib/normalize.ts
→ window.postMessage → relay (isolated) entrypoints/relay.content.ts
→ background aggregator (fold on write) entrypoints/background.ts, lib/aggregator.ts
→ chrome.storage.local (daily buckets + meta) lib/store.ts
→ popup (lifetime, streak, today) entrypoints/popup/
Adapter/normalizer/aggregator/store/popup are all provider-agnostic; the only
Claude-specific file is lib/providers/claude.ts (ESOD §6). The discovery probe
(lib/probe.ts) is retired but kept as a tool for bringing up future providers.
Next: build-order step 2 — heatmap renderer + dashboard + PNG export at 1584×396 and 1500×500. Phase 1 ships there.
npm install
npm run dev # launches Chrome with the extension loaded (Firefox: npm run dev:firefox)
npm run build # production build → .output/chrome-mv3
npm run compile # type-check onlynpm run build- Chrome →
chrome://extensions→ enable Developer mode - Load unpacked → select
.output/chrome-mv3
- Load the extension (above), then reload it on
chrome://extensionsafter any rebuild. - Open https://claude.ai and hard-refresh (
Cmd/Ctrl + Shift + R). - (Optional) For diagnostic logging, use
npm run devinstead of the production build. The page DevTools Console will show a local-estimation notice and, after each reply, a[TokenBurn] captured <model>: in≈N out≈M (estimate)line. - Send a message or two.
- Click the TokenBurn toolbar icon — the popup shows lifetime tokens, current streak, today's total, and message count, with the honest "observed in your browser" caveat.
No prompt or response text is stored or transmitted. The active capture path
observes prompt and visible-response text locally in memory to estimate token
counts, then discards that text. Only counts, model, date, and capture metadata
are saved in chrome.storage.local. The retired probe redacts string values by
length before logging. Capture is from the network layer, never the DOM, and
host access is limited to claude.ai.