1885
Python LOC
1443
src/ LOC
442
tests/ LOC
4
metrics tracked
0
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 monkeypatch APPDATA to a temp dir so they never touch real user state.
  • Hotkeys are Ctrl+Alt+G/H/D via the keyboard library, with a Qt bridge for thread safety (the keyboard thread never calls Qt directly).
  • File watches use Qt’s QFileSystemWatcher with 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.debug rather 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. Only type == "assistant" rows are parsed. Required fields include timestamp (ISO 8601), message.model, and the nested message.usage.* token counters including cache_creation.ephemeral_5m_input_tokens.
  • Session JSON~/.claude/sessions/*.json, one file per live session. Required: pid, sessionId, plus optional cwd and startedAt.

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.

watch ~/.claude tail JSONL parse usage compute deltas render HUD
no network calls; mtime polling for cross-platform parity · as of 2026-04-26
src/1443 tests/442
as of 2026-04-26

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.

:/ ESC