feat(cost): split local cost history by weekly quota window (#321)

* feat(cost): split local cost history by weekly quota window

Mirror the macOS 0.62.0 recent-windows list as a Plasma-native "Quota
weeks" list in a provider's expanded cost details: the local cost and
tokens of the current weekly quota window and up to three earlier ones.
No CLI contract is added. The boundaries come from the weekly usage
row's `resetsAt` and `windowMinutes`, which the CLI already emits
(verified: Codex reports windowMinutes 10080), and the amounts from the
daily history the widget already holds.

QuotaWindowCost.js is a pure module with explicit inputs, including the
clock. History is day-granular while a window resets at any instant, so
a whole day is attributed to the window holding its local midnight and a
boundary inside a day marks the totals as estimated. Unknown days never
count as zero: they make a total a lower bound. A window reaching back
before the scanned history is dropped rather than shown as a complete
week, and a stale reset yields nothing.

Running the module on real CLI data found a bug the synthetic cases
missed: right after a mid-day reset the current window holds no local
midnight yet, and stopping there hid every earlier week. Such a window is
now skipped; a regression test pins it.

ProviderNormalizer.rateWindowMetrics now keeps `windowMinutes` when it is
a whole number of minutes up to a year. The usage cache format is
unchanged, so a restored row shows no weeks until a live refresh.

The cost-section harness forwarded only the first i18n argument, which
left `%1` unreplaced in every templated string it rendered; it now
forwards all of them.

Documentation impact: usage guide describes Quota weeks, CHANGELOG gains
an Added entry, and the completed TODO entry is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cost): keep quota weeks honest for privacy mode and sparse history

Three review findings on #321, each confirmed against the code:

- Privacy mode lost the feature. PrivacyPresentation.quota rebuilds each
  row and dropped `windowMinutes`, so no weekly row was ever found. The
  window length identifies nothing, so the projection now keeps it
  (numbers only).
- A missing or duplicated date was summed silently. fillMissingCostDays
  returns rows unfilled for malformed labels and duplicates, so a week
  could show a complete total with a day absent, or count a day twice.
  Each window now counts the scanned local dates it should contain and
  marks a total partial when any is missing; a duplicated date refuses
  the split entirely.
- Two finite daily values could sum to Infinity, which rendered as "-"
  instead of "Cost unavailable". An overflowing total is now unknown.

Each fix has a test that fails when the fix is reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
6ccbb51407Simone committed on 9/22/2026, 9:26:21 PM· committed by GitHubparent3ad47e0
17 files changedLine totals unavailable