feat(ui): the cost cards say what kind of money they are, and the plan gets its own meter - #56
Conversation
…-column' into adriano/dev
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md # docs/guide/dashboard.md # src/ui/mod.rs
The same project legitimately earns two rows: a checkout with an origin remote reports owner/name, while a copy of the same code with no remote - a scratch workspace, an agent's own working folder - reports its directory basename. On a real machine that split "HAI Neo" from "holistic-ai/hai-neo", cutting one project's ~$450 of spend into two rows that ranked separately. surface never guesses that two names are one project: folding spend together on a string resemblance is misattribution, the thing the Projects view promises never to do silently. The operator declares it instead, in config, and the declaration is applied where prices are - at read time, never to the stored keys - so an alias added today regroups the whole window retroactively and a wrong one is one edit away from undone. One hop only: an alias pointing at another alias does not chase, so a config cycle cannot loop a scan. Project totals, daily rows and the session breakdown all follow the alias; the session pane filters by the name the row above shows, so sessions recorded under either name attach to the folded row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # src/ledger.rs # src/ui/mod.rs
Plans are enforced in 5-hour windows - how many get started and how deep each runs - and the token table answers neither. Claude Desktop samples that meter every few minutes into plan-usage-history.json; a new scan section reconstructs the windows (rise from zero, a gap of a window length, or a sharp drop while sampling stayed continuous) and the Usage view's m key shows them per day: windows started, average and deepest peak, and the deepest as a bar against the cap itself, amber from 90%. Timestamps and percentages are all that is read - the org id is never kept - and a machine without the file gets the absence stated rather than a zero. The count is a floor: samples exist only while Claude Desktop runs. Claude-only; Codex's equivalent lives in its transcripts' rate_limits and is a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # src/demo.rs # src/scan/mod.rs # src/ui/mod.rs
# Conflicts: # CHANGELOG.md # src/ui/mod.rs
# Conflicts: # CHANGELOG.md # src/ui/mod.rs
SPEND, TOKENS, TOKEN COST, AVG USAGE RATE, TOOLS & SITES - the actual bill first, the work done, the API-rate hypothetical it would have cost, how hard the plan is being driven, the machine's inventory last. SPEND now carries only real money: the saving-vs-API-rates line moves off it (that comparison lives on TOKEN COST and in the Cost view) and in its place the card says whether extra usage is in play, from the metering samples - 'no extra usage' while no window has ever pegged, 'extra usage likely' once one has, and nothing claimed on a machine without history. AVG USAGE RATE is new: the mean peak of the 5-hour windows, the number that predicts a cap hit before it bills, with the hottest window amber from 90% and a pointer to the per-day breakdown on [m]. TOOLS and AI SITES fold into one inventory card. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # docs/guide/dashboard.md # src/ui/mod.rs
|
@kleyt0n — correcting something stated when #51 was closed, since it affects how much of this you need to re-read. I said the metering commits were unchanged since your approval. That is not exactly right. Your approval on #51 was against
So: the feature commits are byte-identical to what you approved, but the approved tip is not an ancestor of this branch. Treat the metering work as needing a fresh look rather than trusting the earlier sign-off. |
Two conflicts, both from main having merged #44 (spend-vs-token-cost) after this branch already carried it. src/ui/mod.rs — main's copy of `the_token_cost_card_qualifies_its_dollars` landed as a duplicate of the one already here (commit cf88d91 gave this branch's copy the same cache rates), and git split the duplicate across the metering tests. Dropped the duplicate, kept main's fuller doc comment on the surviving copy, and kept `metering: Default::default()` on the fixture main does not know the field for. CHANGELOG.md — this branch had flattened main's entries to ASCII (`—` → `-`, `≥` → `>=`), truncated their prose and added a UTF-8 BOM. Main's text is canonical for the shared entries, so the section is rebuilt from it plus the three entries only this branch adds: the card row, the metering view and `[usage.repo_aliases]`. BOM removed. cargo fmt / clippy -D warnings clean; 287 tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Packs the outstanding cost-monitoring work into one branch, superseding #52, #51 and #49.
What this adds
The Overview's card row becomes five cards that each say what kind of money they are, and the plan's own meter gets a view of its own.
The SPEND / TOKEN COST split is the point: actual money and list-rate arithmetic are different claims, and neither leaks into the other.
[m]on Usage swaps the token table for the plan's own metering windows.Review it in the same chunks the stacked PRs would have given you
History is left as-is rather than rewritten, so each superseded PR is still a contiguous set of commits:
Supersedes #52 — the card row
f0ed7e6feat(ui): the Overview cards say what kind of money they are, in order77938b2fix: the spend fixtures gain the metering fieldSupersedes #51 — the metering view (this carried your approval of Aug 3)
e09f8c4feat(usage): [m] swaps the Usage view for the plan's own meter32eb523fix: main's new fixture gains the metering fieldSupersedes #49 — repo aliases
54bbe87feat(usage): [usage.repo_aliases] folds two names for one projectOnly on this branch — integration fixes that came out of merging the three together, and exist in none of the PRs above
c4284a0fix(integration): the queue's fixtures gain the metering fieldcf88d91fix(integration): the all-priced token-cost fixture gains cache rates4ecb38afix(integration): the tools-column fixture gains the plans field3cc6bf4fix(integration): widen the token-cost card test for the five-card rowCarried over from #49
@kleyt0n, your review on #49 was dismissed before it could be actioned, so restating it here rather than losing it with the PR:
This is not claimed as resolved —
[usage.repo_aliases]is opt-in and off unless configured, but the aliasing runs inside the usage fold, so it is worth your eye on the hot path before this merges.Checks
Run locally on
adriano/dev, all green:Note
Contains one known cosmetic defect, not yet fixed: the TOKEN COST detail line renders
over 30 days · ≈ $65.67/— 27 characters into a 24-column card, so the/dayunit is cut. Happy to fix it here or leave it for a follow-up, whichever you prefer.🤖 Generated with Claude Code