Commit graph

2 commits

Author SHA1 Message Date
Resham Joshi
16c41df8eb
Compare periods: lead sentence, three tiles, day bars, top movers (#1446)
* Add per-day cost for both sides to the compare-periods report

* Rebuild the Compare periods screen around a lead sentence, day bars and top movers

* Update the Compare periods doc for the new layout

* Extract the duplicated chart tooltip into one ChartTip component

* Make the Compare periods sentence, tiles, day chart and movers table say what they measure

* Cover the compare lead sentence rules and the percent, date and path formats

* Update the Compare periods doc for the new day chart

* Style the Compare periods Swap button as an outlined pill instead of a solid grey block

* Fix the round-2 findings on the Compare periods chart, range label, Swap button and duration

* Fix single-day range label doubling and lone day bar width in Compare periods

rangeLabel now short-circuits from === to like terseRangeLabel already did.
pcmp-bar uses flex 0 1 50% so a lone bar in a slot takes half the slot
instead of the full slot, matching paired bars.

* Keep a lone day bar the same width as a paired one
2026-09-15 23:12:12 +02:00
ozymandiashh
f7a66e51f5 feat(cli): compare-periods command with a deterministic B-minus-A diff engine
Add src/period-diff.ts: pure period-vs-period difference engine. Totals come
from the shared buildPeriodData rules; contributions per project and per model
carry status new/gone/up/down/flat with pct=null at A=0 (labeled New, never an
infinite percentage); normalized views per day and per 100 calls print their
denominators; day arithmetic walks local midnights so DST and month boundaries
count calendar days. historyBasis cross-checks the durable daily cache and
reports aggregate-only carried days separately instead of force-reconciling
them into the totals. diffSessions joins the drill-down on the canonical
session identity (provider + project path + sessionId), attributing the
model's own slice for the model lens.

New command: compare-periods --format json|sessions with explicit
--from-a/--to-a/--from-b/--to-b (local YYYY-MM-DD, validated loudly) defaulting
to the last seven complete days vs the seven before, plus --provider and the
existing --project/--exclude filtering. Range slicing reuses parseAllSessions'
call-granularity behavior, so a session straddling the boundary contributes to
each side by its own calls.

Tests: engine fixtures including the X/Y/Z acceptance reconciliation, A=0/B=0,
unequal lengths, DST and month walks, carried history, a real-parse boundary
session split by call and joined back into one drill-down row, and CLI runs on
a temp HOME fixture.
2026-09-12 13:43:24 -07:00