Skip to content

feat(ui): the cost cards say what kind of money they are, and the plan gets its own meter - #56

Merged
kleyt0n merged 23 commits into
mainfrom
adriano/dev
Aug 11, 2026
Merged

feat(ui): the cost cards say what kind of money they are, and the plan gets its own meter#56
kleyt0n merged 23 commits into
mainfrom
adriano/dev

Conversation

@as-koshiyama

Copy link
Copy Markdown
Contributor

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.

Card Says
SPEND Real money — seats, and whether overflow billing is in play
TOKENS Counts: messages and distinct models
TOKEN COST The hypothetical, at API list rates
AVG USAGE RATE How hard the plan is driven — average peak across 5-hour windows
TOOLS & SITES Detection counts

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

  • f0ed7e6 feat(ui): the Overview cards say what kind of money they are, in order
  • 77938b2 fix: the spend fixtures gain the metering field

Supersedes #51 — the metering view (this carried your approval of Aug 3)

  • e09f8c4 feat(usage): [m] swaps the Usage view for the plan's own meter
  • 32eb523 fix: main's new fixture gains the metering field

Supersedes #49 — repo aliases

  • 54bbe87 feat(usage): [usage.repo_aliases] folds two names for one project

Only on this branch — integration fixes that came out of merging the three together, and exist in none of the PRs above

  • c4284a0 fix(integration): the queue's fixtures gain the metering field
  • cf88d91 fix(integration): the all-priced token-cost fixture gains cache rates
  • 4ecb38a fix(integration): the tools-column fixture gains the plans field
  • 3cc6bf4 fix(integration): widen the token-cost card test for the five-card row

Carried 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:

Approved. But make sure that the changes are not generalized and will not provoke any damage to perfomance.

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:

cargo fmt --all --check          clean
cargo clippy --workspace --all-targets -- -D warnings    clean
cargo test --workspace           284 passed, 0 failed

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 /day unit is cut. Happy to fix it here or leave it for a follow-up, whichever you prefer.


🤖 Generated with Claude Code

as-koshiyama and others added 22 commits August 1, 2026 15:32
# 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
@as-koshiyama

Copy link
Copy Markdown
Contributor Author

@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 95f2152, the tip of origin/feat/metering-view. That branch has three commits; this branch carries only two of them:

Commit On origin/feat/metering-view In this PR
e09f8c4 feat(usage): [m] swaps the Usage view for the plan's own meter yes yes
32eb523 fix: main's new fixture gains the metering field yes yes
95f2152 fix: main's two new spend-card fixtures gain the metering field yes (approved tip) no

95f2152 adds two metering: Default::default(), lines to spend-card test fixtures. Its substance is present here — this branch sets that field on 14 fixtures against 11 on the branch you approved, because the integration commits (c4284a0, 77938b2, 4ecb38a) covered the same ground while merging — and cargo test --workspace passes at 284.

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>
@kleyt0n
kleyt0n merged commit 4632d94 into main Aug 11, 2026
7 checks passed
@kleyt0n
kleyt0n deleted the adriano/dev branch August 11, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants