Grok arrives in usage reports and the interactive dashboard with four synchronized lookup tables
Developers who regularly collaborate with Grok can now finally include its usage in statistics when running usage report or switching to the interactive dashboard.
While the macOS menu bar previously had a Grok quota card and the loader loaders/grok_loader.py could produce per-call token details, the adapter layer lacked adapters/grok.py, leaving the terminal report and dashboard blind to it. In addition to adding the adapter, this update synchronizes the four lookup tables that must agree: the registry's detector list, AGENT_LOADERS in the CLI and report generator, and AGENT_SHORT and AGENT_LABEL in the table UI.
FEATURE
Reports split tokens into four categories and display cache hit rates to clarify real consumption
To understand actual AI consumption, the headline "tokens burned" at the top of previous reports summed four distinct numbers into a single total, obscuring key details.
In local testing across a period of 2,565,454,499 tokens, as much as 93.8% was cache read while only 0.7% was output the model actually generated, rendering the raw total meaningless. The report now formally breaks down usage into input, cache write, cache read, and output, while calculating cache hit rates for each tool. The formula divides cache read by the sum of the three input contexts, excluding the generated output. A high hit rate indicates that old context is reused at roughly one-tenth the unit price, and the copy across all five languages explicitly frames this metric as a sign of healthy efficiency rather than wasteful repetition. The underlying layer has always recorded all four fields and previous versions merely discarded them during report aggregation, so no cache clearing or data format upgrade is required.
FEATURE
One-pass rate becomes an independent third section in the report, removing duplicates from top KPI cards
For those wanting to know which model requires the least intervention and fewest follow-up fixes, "one-pass rate" has been promoted to a standalone third section in the report. This metric measuring whether AI completes tasks on the first attempt was already computed, but previously sat buried inside a small card under section 11 "usage habits" where most users never scrolled. It is now positioned after Insights and before Tools, with model rows using a ranked layout sorted by pass rate from highest to lowest to directly answer which model needs the fewest revisions rather than just looking at turn count. The top key performance indicator (KPI) cards also removed the duplicate one-pass rate, fixing an awkward layout where five cards were squeezed into a two-column grid without requiring any new i18n localization keys.
FEATURE
AI roundtable incorporates Codex's default Astra model as the allowlist is no longer hardcoded
When convening an AI roundtable to deliberate issues across multiple models, you can now assign Codex's latest Astra model to the discussion.
gpt-6-astra is Codex's current new default model, but the roundtable's previous model allowlist hardcoded three older 5.6 variants, preventing the new flagship from appearing. Enabling it required no changes to pricing tables or reports: LiteLLM's price list already covers the model's four actual prices, and report color assignments match automatically on the gpt prefix, so switching works without another change.
FEATURE
"Cost burned" is renamed to "API equivalent", removing NTD conversion and clarifying gaps via subtitles
Opening the report and seeing the "Cost burned" label often gave the mistaken impression that one had actually paid that amount out of pocket. Because this figure is merely a hypothetical number multiplied out from official list prices, it easily misled subscription users who pay a fixed monthly fee with zero marginal cost. The label is now unified across all five languages as "API equivalent", and the NTD conversion previously unique to Traditional Chinese has been removed to avoid distorting an assumed number a second time through exchange rates. The value itself remains available for pay-as-you-go API users who need it. Furthermore, because "tokens burned" counts all agents while "API equivalent" can only calculate models with published list prices, the two headline cards do not share the same denominator; a subtitle now explains the gap, but only when unpriced usage actually exists.
BUGFIX
Token composition and cache hit rates switch to ranked lists, preventing tiny shares from collapsing
When a single category exceeds ninety percent, traditional stacked bar charts turn into a layout disaster. Previously, with cache reads reaching 93.8%, the other three categories collapsed into invisible slivers, in-bar percentage text overlapped into 4.6% 0.1.93.7% at the far left edge, and legend color swatches lacked sizing styles entirely. Input, cache write, and cache read all represent incoming context while output consists of generated text, making them fundamentally distinct in nature. The presentation has now shifted to ranked lines where each of the four categories receives its own row and dedicated columns, with bars given a 2% minimum width to keep even a tiny 0.7% output clearly visible. Per-tool cache hit rates adopt the same layout sorted by hit rate, placing the worst-performing tool on the final row. Meanwhile, a test issue where mypy rejected loop variables used as keys on TypedDict types was resolved cleanly using an Any intermediate variable.
FEATURE
Report data rows become full-width bars, aligning values across sections to a shared baseline
When reviewing data across different report sections, numbers and bars no longer jitter unpredictably between left and right.
The previous layout suffered from four separate defects: two row styles (.rank-line and .tool-row) used differing column widths and gaps that placed numbers at different horizontal positions across sections; share bars were trapped inside the name column and abruptly stopped halfway across the row; every section stacked three redundant borders of section, card, and row frames; and two sections lacked column headers entirely. Data rows are now full-width progress bars, the tools section adds bar elements, and tool colors are keyed directly to the agent ID rather than sort position to avoid repainting every tool whenever rankings shift.
FEATURE
Report timeframes and comparison markers gain clarity, removing scaleless daily line charts
When tracking long-term consumption trends, the report's timeframes are now clearer and more rigorous. The weekly burn trend section dropped its embedded daily line chart because it had no scale or values, failed to match the "weekly" heading, and provided no actionable information, while the week numbers, values, and week-over-week bars below remain unchanged. At the same time, the report clarifies its comparison baseline by unifying "vs. last month" and "vs. last week" into "vs. previous period", while the annual section is renamed "last 53 weeks" with the week count passed from program constants so the copy updates automatically if constants change.
FEATURE
Quota warning copy streamlined to fit inside menu bar panels without truncation
When your model quota is running low, the red warning text now displays fully within the interface. Previously, the hardcoded nowrap warning required 320 to 470 pixels of width, but the menu bar panel text box was only 304 to 320 pixels, and because card frames hid overflowing content to preserve a retro aesthetic, the red line was cut off directly. Across 13 panels in 5 languages, Japanese suffered the most by losing 81 to 150 pixels, and English fit in only three panels. The copy is now universally shortened while preserving its original meaning, and the head-to-head World Cup panel provides an ultra-short variant that omits the reset time, fitting neatly into the narrow 151 pixels on each side.
FEATURE
Year ledger is no longer silently cleared on version mismatches, safeguarding historical records
A full year of accumulated AI usage history will no longer vanish silently to zero due to software upgrades.
The year ledger module previously had four execution paths that returned an empty ledger, the most severe being schema version mismatches; whenever developers tweaked fields and bumped the version, users worldwide quietly lost their entire history with no backups to recover from. Testing during development revealed that a single version bump caused the local heatmap to plunge from 119 days to 36. Version mismatches now merely log a warning and continue parsing older data day by day, moving files into the ~/.usage/quarantine/ directory as isolated backups only when they are genuinely unreadable or structurally corrupted to protect historical records.
BUGFIX
Bare repo worktrees no longer split one project into two, cleaning suffixes and repairing history
When creating a worktree from a bare repository, the same project will no longer be split into two separate entries in reports. Previously, the project name resolver resolved worktree paths back to the main directory and took the basename directly, leaving the project name with an unwanted .git suffix. This caused path-only Claude to report obsidian00 while the other three loaders reported obsidian00.git; locally, this amounted to 5997 entries against 3732, splitting the same project in the report into 21.70% and 10.80%. All three architectural layers have been fixed: the resolver strips the trailing .git, the Codex shard cache was bumped to re-parse 28 old shards, and the year ledger folds .git back into the base project name at read time.
BUGFIX
Token units no longer miscalculate tiers on round-up, recalibrating automatically after rounding
When your token consumption nears the boundary of a unit tier, numbers and units on reports will now advance correctly.
When formatting token values, the _fmt_tokens function previously selected unit tiers from unscaled raw values, but failed to re-check whether rounding pushed the number across the tier threshold after scaling. This caused 999,950 to be printed as an awkward 1000.0K after rounding, and 999,950,000 as 1000.0M. Unit tiers are now re-evaluated after rounding to ensure units advance properly.
Original changelog
Original changelogGrok arrives in usage reports and the interactive dashboard with four synchronized lookup tables
**Grok now appears in the report and the interactive dashboard.** The menu bar has carried a Grok quota card for a while and `loaders/grok_loader.py` could already produce per-call token detail, but there was no `adapters/grok.py`, so both `usage report` and the dashboard were blind to it. The adapter was added along with the four lookup tables that have to agree: the registry's detector list, the `AGENT_LOADERS` maps in `usage_cli` and `reporter`, and `AGENT_SHORT` / `AGENT_LABEL` in `ui/tables`.
Original changelogReports split tokens into four categories and display cache hit rates to clarify real consumption
**The report breaks tokens into four kinds and shows each tool's cache hit rate.** The headline "tokens burned" was one number summing four different things; locally, 93.8% of a 2,565,454,499-token period was `cache_read` and only 0.7% was output the model actually generated, so the total said nothing. `UsageEntry` has always carried all four fields and `loaders/disk_cache_common.py` serialized all four — `reporter` was dropping them when it built the summary, so no cache and no schema version had to change. Cache hit rate is `cache_read / (input + cache_creation + cache_read)`; output is excluded because it is generated, not sent in. A high rate is the healthy end — old context reused at roughly a tenth of the price instead of re-sent at full rate — and the copy in all five languages is written to keep it from being read as "most of my tokens are wasted repeats."
Original changelogOne-pass rate becomes an independent third section in the report, removing duplicates from top KPI cards
**"One-pass rate" is now a section of its own, third from the top.** Whether the AI finished without you stepping in is a measure with no pre-LLM equivalent; the data was already computed and already drawn, but it sat in a small card inside "usage habits" in section 11, where most people never scrolled. It is now a full section placed after Insights and before Tools, and the model rows use the report's existing rank-line layout sorted by pass rate rather than by turns — the question the section answers is which model needs the least going back over, not which one is used most. No new i18n keys were required.
**The top KPI row no longer repeats the one-pass rate.** Five cards laid out badly in a two-column grid, and the full section below already carries the per-model detail.
Original changelogAI roundtable incorporates Codex's default Astra model as the allowlist is no longer hardcoded
**The AI roundtable can pick Codex's Astra model.** `gpt-6-astra` is Codex's new default, but the roundtable's model allowlist hard-coded the three 5.6 variants. Pricing and the report needed no change: LiteLLM's table already carries real prices in all four of its fields, and the report's color assignment matches on the `gpt` prefix.
Original changelog"Cost burned" is renamed to "API equivalent", removing NTD conversion and clarifying gaps via subtitles
**"Cost burned" is now "API equivalent."** The label presented a figure multiplied out from list prices as money actually spent, which is misleading for subscription users whose marginal cost is zero. Renamed in all five languages; the Traditional Chinese-only NTD conversion went with it, since that ran an assumed figure through an exchange rate a second time. The number itself stays — API users still need it. The two headline cards never shared a denominator: "tokens burned" counts every agent, while "API equivalent" can only count models with a published price, so a subtitle now explains the gap, and only when unpriced tokens actually exist.
Original changelogToken composition and cache hit rates switch to ranked lists, preventing tiny shares from collapsing
**Token composition is a ranked list instead of a stacked bar.** With one category at 93.8%, the other three collapsed into invisible slivers, the in-bar percentage labels piled up into `4.6% 0.1.93.7%` at the left edge, and the legend's swatches had no size styling at all. A stacked bar is the wrong chart once a single category passes ninety percent, and the four are not peers anyway — input, cache write and cache read are all context sent in, output is generated. Each category now gets its own row with its own columns, and the bar's 2% minimum width keeps a 0.7% share visible. Per-tool cache hit rates use the same layout, sorted by rate, so the weakest tool is the last row rather than something you have to hunt for.
**A type error in the token composition tests.** `data["summary"]` and the elements of `data["by_agent"]` are TypedDicts, so mypy rejects a loop variable used as a key; the two assertions now go through an `Any` intermediate. The lines came from the composition work and were not caught earlier because that batch had not been pushed yet.
Original changelogReport data rows become full-width bars, aligning values across sections to a shared baseline
**The report's data rows are filled bars, with columns that line up across every section.** Four separate problems: the two row systems (`.rank-line` and `.tool-row`) used different track widths and gaps, so numbers sat at different x positions in different sections; the share bar was a child of `.name` and capped by the name column, so it drew to about half the row and stopped; every section nested a section frame, a card frame and a row frame; and two sections used the shared layout with no column headers. The tools section had no bar element at all and now has one, with each tool's color keyed on its agent id rather than its sort position — `by_agent` is ordered by tokens, so a palette indexed by position would repaint every tool whenever two swapped places.
Original changelogReport timeframes and comparison markers gain clarity, removing scaleless daily line charts
**The weekly burn section lost its daily line chart.** It had no scale and no values, did not match the "weekly" heading it sat under, and could not be read for anything actionable. The rows below it, carrying week number, value and week-over-week change, are unchanged.
**The report says which span it is comparing against.** "vs. last month" and "vs. last week" became a single "vs. previous period," and the annual block is now "last 53 weeks" with the week count supplied by `WrappedReportData.weeks` from `_YEAR_WEEKS`, so the copy follows the constant if it ever changes.
Original changelogQuota warning copy streamlined to fit inside menu bar panels without truncation
**The quota warning fits inside the panels.** The red "running out" line was `white-space: nowrap` and needed 320–470px, but the panels' text box is 304–320px and the cards are `overflow: hidden` — deliberate retro chrome, not removable — so the sentence was cut off. Measured across 13 panels × 5 languages: Japanese lost 81–150px, and only three panels' English fit. The wording is now shorter with the same meaning. The World Cup panel gets an even shorter variant that omits the reset time, since its head-to-head layout leaves each side only 151px.
Original changelogYear ledger is no longer silently cleared on version mismatches, safeguarding historical records
**The year ledger is never silently discarded.** `_read_year_ledger()` had four paths that returned an empty ledger, the worst being a `schema_version` mismatch: anyone changing a ledger field and bumping the version would have quietly zeroed every user's accumulated history, with no backup to recover from. This file exists precisely so that history survives after the raw logs rotate away, so clearing it defeats the thing it is for. Measured during development: one version bump took the local heatmap from 119 days to 36. A mismatched version now logs a warning and parses day by day anyway — `_year_day_from_json` already tolerates missing fields — and only a genuinely unreadable or structurally wrong file is moved into `~/.usage/quarantine/` before returning empty, matching what the disk cache already does.
Original changelogBare repo worktrees no longer split one project into two, cleaning suffixes and repairing history
**A git worktree whose main repo is bare no longer splits one project into two.** `resolve_project_name()` resolved the worktree back to its main path and took the basename, so the project name carried a `.git` suffix. `adapters/claude.py` parses paths without calling git and reported `obsidian00`, while the other three loaders went through `project_resolver` and reported `obsidian00.git`; locally that was 5997 entries against 3732, and the report listed one project twice, at 21.70% and 10.80%. The same bug sat in three layers: the resolver now strips a trailing `.git`, Codex's shard cache went from schema 4 to 5 so the 28 shards holding the old name are re-parsed, and the year ledger — which cannot be invalidated by a version bump without losing the only copy of that history — folds `X.git` back into `X` at read time instead.
Original changelogToken units no longer miscalculate tiers on round-up, recalibrating automatically after rounding
**Token units no longer skip a tier when they round up.** `_fmt_tokens` picked the tier from the raw value and rounded afterwards without re-checking, so 999,950 printed as `1000.0K` and 999,950,000 as `1000.0M`.