Skip to content

Release v1.9.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 19:58
82362c1

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 allocate no longer requires --project. Omitting it reports every project's slice of the spend, ranked by amount, with one column per plan held.
  • --top bounds the list and states the remainder rather than dropping it; --top 0 shows 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.