Repository navigation
Release v1.9.0
Summary
--project was required, so the only question allocate could answer was what one project is owed. The prior question — where did the money actually go — had no answer, and working it out meant running the command once per project and adding up the results by hand.
Naming a project still asks for a claim. Omitting it now asks for a breakdown:
$ workstats allocate --sub claude=2@1866 --sub codex=3@1992 \
--currency NOK --vat 25 --month 2026-08 --top 6
ALLOCATION every project
2026-08 · 5 subscriptions · 12,135 kr billed incl. 25% tax · basis: output tokens
PROJECTS
project claude openai TOTAL % out tokens
──────────────────────────────────────────────────────────────────────────────────────────────────
Ada 2,072 kr 3,048 kr 5,121 kr 42.2% 111.3M 38.28B
Chronicle.Wolverine [f81e3bee] 102 kr 1,020 kr 1,121 kr 9.2% 18.5M 7.56B
AI 295 kr 433 kr 728 kr 6.0% 15.8M 7.41B
cratis 385 kr 261 kr 646 kr 5.3% 16.1M 5.89B
Screenplay 83 kr 532 kr 616 kr 5.1% 10.6M 5.07B
Strategy 90 kr 491 kr 581 kr 4.8% 10.2M 5.55B
(59 smaller projects) 3,322 kr 27.4%One column per plan held, so a project leaning on a single vendor is visible at a glance — Screenplay draws six times as much from OpenAI as from Claude, cratis the other way.
Added
workstats allocateno longer requires--project. Omitting it reports every project's slice of the spend, ranked by amount, with one column per plan held.--topbounds the list and states the remainder rather than dropping it;--top 0shows every project.
Notes for review
- The rows reconcile exactly to what was billed, and a test pins that — a breakdown that does not add up is not a breakdown of anything.
- Ranking is by money, not tokens. A test covers the case where a project with less total output outranks one with more because it drew on the pool backed by more plans; that is the correct answer and an easy one to get wrong.
- A project absent from a pool contributes zero to it rather than silently borrowing another project's share. Also tested.
- Stating the remainder follows the rule the rest of the command already uses for pruned history and unmatched project names: never a silent zero.
- 288 tests pass (2 new). Clippy, rustfmt, MSRV 1.88 and rustdoc clean locally.