Bug Fixes
- Model distribution shows all families:
ModelUsageBarnow renders every model family — Sonnet, Opus, Haiku, and an "Other" bucket for anything else — instead of only Sonnet/Opus. Haiku and other models no longer vanish from the usage bar or skew the displayed percentages. (#124, #164) - Plan is now saved and restored: the selected
--planis persisted inlast_used.jsonand reloaded on the next run; an explicit--planon the command line still takes priority. (#162) - Saved theme no longer overwritten: an explicitly chosen
light/dark/classictheme is preserved across runs instead of being silently replaced by background auto-detection. (#102, #200) - Clear message on unsupported Python: running on Python older than 3.9 now prints a clear "Python 3.9+ is required" message (with a
uvinstall hint) instead of failing cryptically; the version check is now actually wired into startup and uses the documented 3.9 minimum. (#172) - Helpful "no data" diagnostic: when no Claude data directory is found, the monitor now lists the exact paths it searched and how to fix it, instead of a single terse line / blank screen. (#110)
- CLAUDE_CONFIG_DIR is honored: when set, usage data under
$CLAUDE_CONFIG_DIR/projectsis discovered (comma-separated directories supported) and checked before the standard locations; path discovery also deduplicates repeated directories. (#116) - Up-to-date, version-specific model pricing: token costs now use current Anthropic rates — Opus 4.5+ at $5/$25 (previously billed at the legacy $15/$75, a 3x overcharge), Haiku 4.5 at $1/$5, and Fable 5 at $10/$50 — while older models (Opus 3/4.0/4.1, Haiku 3/3.5) keep their original rates. (#182)
--reset-houris now actually applied: the flag was accepted and persisted but never used in any calculation. It now sets the daily rollover boundary in the daily/monthly table views, so a usage day runs fromreset_hourtoreset_hour(e.g.--reset-hour 4counts 02:00 toward the previous day) instead of midnight to midnight. It deliberately does not shift the rolling 5-hour window, whose reset comes from the session/official data. (#95, #96, #106)- Reset time prefers what Claude reported: when a session block contains a rate-limit message with a reset time, that time is shown as the reset instead of the start-plus-5h estimate, so the displayed reset matches what Claude actually told you. Official statusline limits still take precedence when available. (#114, #106)
- Epoch reset timestamps parsed in UTC: a numeric reset timestamp from a
limit reached|<epoch>message was parsed as local wall time and then mislabeled as UTC, shifting the shown reset by the host's offset on non-UTC machines (e.g. two hours off in Central Europe). Epochs are now interpreted as the absolute UTC instant they are. (#106, #220) - Windows and local timezone detection now use IANA zones: Windows auto-detection now uses
tzlocaland refuses to return rawtzutillabels such asEastern Standard Timeas if they were validpytzzones; the accepted--timezone localalias now resolves before display code runs. Added regression coverage for Istanbul reset display so reset times do not drift by an extra hour. (#188, #98, #121, #220) - Non-Anthropic models are no longer priced as Claude: a model routed through Claude Code Router (e.g. a GPT or DeepSeek model) was silently billed at the Sonnet rate, inflating reported cost. Models that are not recognizably Anthropic now report as unpriced ($0) instead of a fabricated Claude cost; unknown but clearly-Claude models still use the family fallback. (#217, #199)
- Official limits hardened against stale and malformed captures: a statusline capture older than the freshness window no longer drives the displayed reset, status, or
confidence: officiallabel (it falls back to the local estimate, flaggedstale); an official percentage drives the exit code even with no local session; and non-finite values (NaN/Infinity) in a capture are rejected instead of crashing the reader or emitting invalid JSON. (#119, #108) - Rich TUI now uses official-aware limit overlays: the interactive live view and rich
--onceoutput now route token usage through the same snapshot used by compact/state/export surfaces, so fresh statusline limits can drive the displayed five-hour percentage with an explicitofficiallabel instead of showing a conflicting local-estimate bar. - Time-to-reset alignment and Windows glyph fallback: progress rows now pad by terminal display width using
wcwidth, so clock emoji no longer shift the "Time to Reset" bar. Startup forces UTF-8 output where possible and enables an ASCII fallback for non-UTF-8 Windows streams. (#144, #160)
Features
--hide-model-distribution: new flag to hide the model distribution bar in the live view. (#161)--no-header/--no-emoji: hide the header banner, or render the live view without emoji (plain output). (#57)--once --output {rich,json,text}: one-shot, machine-readable usage snapshot for hooks/CI/companions instead of parsing the live TUI. Emits a versioned schema (schema_version,source,confidence,limits,local,local_history,forecast) with every number labeledlocal_estimate, plus automation exit codes (0 ok, 10 near limit, 11 limit hit, 20 indeterminate, 30 no data). Official account/weekly limits are shaped in but deferred until the statusline reader lands. (#126)--write-state: continuously write the same versioned snapshot to a state file (default~/.claude-monitor/state/latest.json, override with--state-file) that status bars, tray apps, and dashboards can poll. Writes are atomic (temp file + replace) so a reader never sees a partial file; reuses the one-shot builder. (#184)--compact: single-line output for tmux/status bars — usage percent, tokens used/limit, burn rate, reset time, and session cost on one line. Works both live (updates in place) and one-shot with--once. Built from the same snapshot as--once, so the numbers never diverge from the full views. (#65, #17, #111)--set-terminal-title: opt-in terminal title updates from the canonical snapshot, with a validated--title-formattemplate (pct,plan,used,limit,cost,reset) so live mode and--onceuse the same values as state/export surfaces. (#142)- Pace, official weekly, and forecast labels in snapshot outputs: snapshots now include a source-labeled pace indicator based on the active five-hour reset, local history is explicitly labeled as history, and forecast displays use
Today/Tomorrow/date context with an estimated tag.--compactadds onepace=...token and only renders7dwhen the officialseven_daystatusline block is present. Forecasts now stop instead of predicting beyond a hit limit. (#216, #183, #128) --data-pathsmulti-source substrate: the reader, live mode, table views, and one-shot snapshot path now accept multiple Claude data directories without collapsing to the first path. Entries are deduplicated across directories, tagged withsource.kindand account path, and split into separate 5-hour blocks per source so multiple profiles/accounts do not merge into one limit window. WSL Claude data paths are discovered additively when available. (#196, #92, #127, #94)--warehousepersistent usage store: opt-in versioned JSON usage warehouse with atomic writes, retention pruning, per source/account/project/model/day records, and daily dimension queries. The default stays off;--warehouse-fileand--warehouse-retention-dayscontrol location and retention. Daily/monthly tables also keep--date-formatand--abbreviate-tokens, with sparklines available only behind--sparklines. (#145, #175, #8, #43, #120)- Warehouse reports and exports:
--view entries|sessions|burn-rate --output json|csvnow exports warehouse-backed reports with source/provenance fields, valid CSV/JSON, session counts, P50/P90/P95 metrics, sessions ended by detected limits, burn-rate rows, and plan recommendations explicitly labeled as estimates. (#8, #120, #80, #43) - Team plan label and experimental usage API:
--plan teamis accepted as an unverified estimate label with guidance to prefer official statusline data or--plan custom, and--apiadds an opt-in experimental Anthropic OAuth usage reader with TTL cache and Retry-After backoff. Experimental API limits are labeledconfidence: experimentaland never override fresh official statusline limits. (#195, #202, #193, #157) - Related Tools and adapter boundary: README now shows the Awesome Claude Code badge, documents external companion tools that should consume
--write-state/--once --output json, and codifies that provider adapters must use separatesource.kindvalues instead of auto-merging non-Claude data into the Claude 5-hour subscription window. Cursor and Claude Desktop are documented as out of scope unless they expose a local usage/limit signal. (#219, #109, #177, #146, #198, #178, #176, #133, #166, #24, #25) --filter-models anthropic: count only Claude models, excluding non-Anthropic ones (e.g. GPT or DeepSeek routed through Claude Code Router) from the usage, cost, and limit math so they no longer pollute the Claude session reading. Applies consistently to the live view, one-shot/state output, and the daily/monthly tables; defaults toall(no change). (#113)- Official limits via the statusline (
--statusline): a Claude Code statusline hook that reads the session JSON on stdin, captures the officialrate_limits(5-hour and 7-dayused_percentage+resets_at, Pro/Max on Claude Code 2.1.80+), and prints a one-line status. Add"statusLine": {"type": "command", "command": "claude-monitor --statusline"}to Claude Code's settings. When a capture is present, the monitor uses the official percentage and reset as the source of truth (confidence: official) and labels it as such; the 5-hour figure also drives the--onceexit code. Without it, every number stays a clearly-labeled local estimate. Captures older than 10 minutes are flaggedstale. The known leak whereused_percentagecan carry the reset epoch is guarded against. (#119, #108, #104, #97, #150, #152)