What it reads
Codex records two figures per event.
last_token_usage is that turn; total_token_usage is cumulative, so only one of them can be summed. cached_input_tokens is a subset of input_tokens, not an addition to it — counting both would inflate every total.
Nothing is written back to either directory, and nothing is sent anywhere.
Prices
Cost comes from a built-in table of Anthropic rates, plus anything you add yourself inprices.json.
A model with no rate reports its tokens and a dash. It never reports a guessed figure.
prices.json re-prices your whole history immediately — there is no cache to clear.
Keeping rates current
Published prices move, and a stale rate is worse than a missing one because it looks right.--price-routine writes a script that checks the public price lists and proposes an update:
The charts
Cost and tokens by week sit between the totals and the tables, drawn in a singleCanvas rather than through a charting library. That keeps the app dependency-free and gives full control over how a line reads on a dark background.
The tiles answer “the last 30 days” and the charts want your whole history, so the view builds the ledger twice. The second build is nearly free, because the per-file cache already holds it. Both modes draw the same chart.
Headless
Where the tokens went that did not need to
The ledger answers what your agents cost. The optimizer answers which of it was avoidable, from the same local transcripts.
Four of the estimates are measured rather than modelled, and each finding records which meter its tokens sat on — fresh input, output, or cache read. Carried context is a cache read at a tenth of fresh input; pricing it as fresh input overstates the waste tenfold, which is a mistake this app made once on real data.
The optimizer reads whole sessions that ended in the window; the ledger counts turns by the day they ran. Both are right, they answer different questions, and each figure says which it used. They will not add up to each other.
Right-sizing, not recommending
It prices the traffic each model actually ran against the next model down, and says what the transcripts suggest about whether the work would survive the swap — a high thinking share is the worst candidate, heavy tool use the most plausible one. It never picks a model for you.Caps
The only part of the ledger that acts. Everything is off until you switch it on, and every limit is a number you set.
Four presets — off, careful, everyday, lean — size themselves from this Mac’s own busy days rather than its median ones, and each states how often it would have stopped you over your recorded history. That number, not the token count, is what tells you whether a cap is livable.
Checking it
scripts/check-ledger.py checks the arithmetic against hand-computed costs — 22 checks, covering cache invalidation, re-pricing from prices.json, and the cache-write premium.
The three caveats
Intuitive mode states these on the card itself, because a number this easy to misread should carry them:Not a bill
API-equivalent cost, not what you were charged.
Prices have an age
Rates are only as current as the last time the routine ran.
Nothing was sent
Every figure is rebuilt from files already on your Mac.
