Review of PR #57, suggestions 1 and 2:
- the excluded open day is now the most recent date of the snapshot,
not its last element, so the rule no longer depends on the order the
days were sent in (the sanitizer does not sort them);
- a day dated past the server's UTC reception day is never archived, and
GET /claude-usage/history no longer takes a month file dated past the
current month as its default end. A skewed workstation clock could
otherwise open history/2099-12.json and leave the default range empty.
Refs #55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agent/claude-usage/backfill-history.js runs by hand from the repo (never
from the cron install, the agent is unchanged). It rebuilds the closed days
with the agent's own aggregate() on past windows and writes { days } to the
--out file, which the server merges with `claude-usage-history.js --import`
(an already archived date wins).
Each 30-day window keeps only its 28 inner days and the next steps back 28
days, so a request straddling a window boundary is deduplicated by the
window that keeps it and counted once. The first window stops at D-2. The
walk is bounded by --max-windows (default 24) rather than guessed from file
mtimes, which say nothing of the oldest line a resumed session holds.
It never reads the credentials file, opens no connection, writes only the
--out file (mode 600, never overwritten) and prints counts only.
Refs #55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /claude-usage now merges every day of the sanitized snapshot except
the last one (today, still open) into <dir of CLAUDE_USAGE_PATH>/history/
YYYY-MM.json, after the snapshot itself is written. The latest snapshot
wins, so a day leaving the 30-day window keeps the value the agent froze
at D+2. Each month file is written atomically (same-dir temp, mode 600,
rename). A month file that cannot be read back is never overwritten, and
an archive failure is logged (months and error codes only) without
changing the 204.
GET /claude-usage/history?from=YYYY-MM&to=YYYY-MM (read token) serves the
archived days, defaulting to the 12 months up to the last archived month,
400 on a bad format, from > to or a span over 36 months. Month files are
re-read through the snapshot's per-day whitelist, now exported from
claude-usage.js as sanitizeDay().
The new module also carries the one-shot import command used by the
backfill (`node claude-usage-history.js --import <file|->`), where an
already archived date always wins.
Refs #55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>