tokeney,
a tab-corner readout for an interactive bill.
A floating PySide6 HUD that reads Claude Code transcripts and session files off disk and reports tokens, cost, and context-window usage in real time. No network. No Anthropic API calls.
tokeney is a Qt HUD that lives in the corner of the screen and answers, at a glance, "what does this conversation actually cost?" Every number it shows comes from JSONL transcripts and session JSON in ~/.claude/ --- nothing leaves the machine. The pricing table is a versioned JSON resource, refreshed by hand after Anthropic price changes; a weekly subagent watches Claude Code's on-disk schemas for drift and reports before tokeney undercounts.
Tech scope
- Configuration and state live in
%APPDATA%\tokenbar\. Tests monkeypatchAPPDATAto a temp dir so they never touch real user state. - Hotkeys are Ctrl+Alt+G/H/D via the
keyboardlibrary, with a Qt bridge for thread safety (thekeyboardthread never calls Qt directly). - File watches use Qt’s
QFileSystemWatcherwith a 10-second sweep timer as belt-and-suspenders against missed FS events on Windows. - All parsers tolerate missing optional fields and
except Exception → log.debugrather than raise --- one bad transcript line should never blank the HUD.
Architecture
__main__.py → app.py::run()
│―― TranscriptIndex # file watchers, tail-reads JSONL
│―― UsageAggregator # in-memory rollup (session/day/7d/30d/alltime)
│―― WidgetWindow # the floating HUD
│―― Tray # system tray icon + menu
└― HotkeyManager # global hotkeys
Input contract --- brittle on purpose
tokeney parses two on-disk formats Anthropic has not committed to keeping stable:
- Transcript JSONL —
~/.claude/projects/<slug>/*.jsonl, one JSON object per line. Onlytype == "assistant"rows are parsed. Required fields includetimestamp(ISO 8601),message.model, and the nestedmessage.usage.*token counters includingcache_creation.ephemeral_5m_input_tokens. - Session JSON —
~/.claude/sessions/*.json, one file per live session. Required:pid,sessionId, plus optionalcwdandstartedAt.
Neither format carries a schema version. If Anthropic renames a field, tokeney silently drops the record and the HUD undercounts. A weekly drift report is run by the tokeney-schema-check subagent — check its output before tagging a release.
Pricing table
src/tokenbar/resources/default_prices.json is hardcoded and not auto-refreshed. It holds $/MTok for input, output, cache-creation-5m, cache-creation-1h, and cache-read per model, plus context_window per model. Stale pricing means wrong displayed cost; the same drift subagent checks for Anthropic pricing changes alongside schema drift.
Surface
tokeney is a floating PySide6 window that reads transcript JSONL files out of ~/.claude/projects/ and reports four numbers in real time: tokens used in the live turn, accumulated cost, cache hit ratio, and remaining context budget. There is no API call — everything is derived from on-disk state. The read path is a tail-once-then-watch loop with mtime polling rather than fsnotify, deliberately, for cross-platform parity.
Numbers
Zero API calls is the load-bearing number. The HUD has to keep up with a Claude Code session in real time without making network calls itself, both for cost reasons and so it works against any project regardless of API connectivity. The 4 metrics are scoped tightly — this is a HUD, not a dashboard, and a 5th metric would lose the at-a-glance read. Test ratio (442 / 1885 ≈ 23%) sits where it does because the parser is the part that has to be right; the HUD itself is mostly composition over the parser's output.