Skip to content

docs: explain how to retain more usage history (cleanupPeriodDays) - #21

Merged
Carl723000 merged 1 commit into
ClaudeCodeUsage:mainfrom
nickearnshaw:nickearnshaw/docs-history-retention
Jun 15, 2026
Merged

Carl723000 merged 1 commit into
ClaudeCodeUsage:mainfrom
nickearnshaw:nickearnshaw/docs-history-retention

Conversation

@nickearnshaw

Copy link
Copy Markdown
Contributor

Problem

Usage history from previous months disappears from the dashboard over time.

Cause

The extension reads Claude Code's conversation transcripts live and keeps no separate store. Claude Code automatically deletes transcripts older than its cleanupPeriodDays setting (default: 30 days), so once those logs are gone the corresponding usage can no longer be displayed. This is expected behaviour of the data source rather than an extension bug.

Change

Documentation only — adds a "Missing History from Previous Months" entry to the Troubleshooting section of every README locale:

  • README.md, README-en.md, README-zh-TW.md, README-zh-CN.md, README-ja.md, README-ko.md

It explains the cause and shows how to retain more history by raising cleanupPeriodDays in ~/.claude/settings.json:

{
  "cleanupPeriodDays": 365
}

…with the caveat that this only affects data kept from now on — already-deleted transcripts cannot be recovered.

🤖 Generated with Claude Code

Previous months disappear from the dashboard because the extension reads
Claude Code's transcripts live, and Claude Code deletes transcripts older
than its cleanupPeriodDays setting (default 30 days). Document this in the
Troubleshooting section of all README locales, with the setting to raise
to keep more history.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Carl723000 added a commit to Carl723000/ClaudeCodeUsage that referenced this pull request Jun 3, 2026
…ner, iOS toggle

Summary of all changes landing in the v2.0.1 release:

Fixes
- Dedup now keeps the higher-token record when hashes collide (issue ClaudeCodeUsage#18,
  @zhaoxiao9302). Proxy "placeholder + real" pairs are handled correctly.
- DeepSeek pricing: deepseek-chat and deepseek-reasoner corrected from
  Flash rates to Pro rates ($0.435/$0.87). Added deepseek-v4-pro entry.
- Quota indicator no longer hides when workspace has no local Claude data.
- Webview / status bar no longer gets stuck on "Loading…" (PR ClaudeCodeUsage#20,
  @nickearnshaw): re-entrancy guard + spinner only on cold start.
- Log timestamps now use local time (not UTC).

Added
- Dashboard "Auto-refresh" toggle (iOS-style) with localised label.
  When off: status bar still updates, webview pauses until "Refresh Now".
- claudeCodeUsage.fileWatching setting (opt-out fs.watch).
- claudeCodeUsage.pauseDashboardRefresh setting.
- Opus 4.8 explicit pricing entry.
- Diagnostic output channel: per-refresh stats + per-model record/token counts.

Docs
- README intro rewritten to "The Claude Code coach in your status bar"
  slogan (all language variants updated).
- New Troubleshooting entries: cleanupPeriodDays for history retention
  (PR ClaudeCodeUsage#21, @nickearnshaw) and sub-agent token under-counting note.
- Credits updated for PRs ClaudeCodeUsage#20, ClaudeCodeUsage#21, ClaudeCodeUsage#22 (@nickearnshaw).

Dev
- launch.json preLaunchTask fixed for single-root checkout (PR ClaudeCodeUsage#22,
  @nickearnshaw).
Carl723000 added a commit that referenced this pull request Jun 3, 2026
…#23)

* chore(pricing): add Opus 4.8 to the pricing table

Assumed at the current Opus tier rate ($5 / $25 input/output per MTok,
$6.25 cache-write, $0.5 cache-read), same as 4.7 / 4.6 / 4.5.
Family-aware fallback would already pick the Opus tier for unknown
opus-4-* snapshots, but an explicit entry is cleaner and keeps the
"Per-model rates" line in the dashboard accurate.

If Anthropic differentiates Opus 4.8 pricing later, override here or
just hit the "Refresh Token Pricing" button to pull live LiteLLM data.

* fix: keep the higher-token record on uniqueHash collision + correct DeepSeek pricing

Issue #18 (zhaoxiao9302): when a proxy like mimo or CC Switch writes
two records per message — a tokens=0 placeholder when streaming starts
and the real values after the response completes — both records share
the same messageId and lack a requestId, so they hash identically.
The previous dedup kept whichever appeared first, which was almost
always the zero-value placeholder, leading to massively under-reported
usage (the reporter measured \$0.20 displayed vs. \$7.98 actual on a
single day; 185 of 188 today-records had this pattern).

Fix: switch processedHashes from Set<string> to Map<string, number>
(hash → records[] index). On a duplicate hash, compare the new and
existing total token sums and keep whichever is higher. This naturally
resolves the placeholder/real pair regardless of arrival order, without
needing to detect the proxy itself.

DeepSeek pricing was also wrong: `deepseek-chat` and `deepseek-reasoner`
were priced at V4-Flash rates (\$0.14 / \$0.28 per MTok) even though
the `deepseek-chat` alias has pointed to V4-Pro since 2024-09. They are
now priced at the Pro tier (\$0.435 / \$0.87 / cache hit \$0.003625),
verified against https://api-docs.deepseek.com/quick_start/pricing/.
Added a separate `deepseek-v4-pro` entry. The family fallback for
unknown DeepSeek snapshots now also resolves to the Pro tier.

This is the same root cause behind the under-reported DeepSeek usage
seen by users running CC Switch.

Reported-by: @zhaoxiao9302 (issue #18)

* fix: decouple quota from local data + opt-out file watcher + shorter cache

Three related fixes for the quota indicator and the file watcher:

1. Quota now refreshes unconditionally at the start of every refresh
   cycle and is no longer hidden when the workspace lacks Claude history
   or when the data directory cannot be found. The quota is account-
   level, so a fresh workspace should not affect it.

2. Quota fetch cache shortened from 2 min to 30 s, so switching between
   VS Code windows no longer shows a stale percentage for up to two
   minutes.

3. New setting `claudeCodeUsage.fileWatching` (default: true) — when
   disabled, falls back to interval-based refresh only. Closes issue
   #17 (Rissew): constant refreshes during active token use can be
   distracting, this gives users the calmer mode on demand.

StatusBarManager.updateUsageData() no longer touches the quota item:
the caller (extension.refreshData) calls updateQuota() separately at
the very start of the cycle. This change is callback-compatible — the
optional usageLimits arg still works for callers wanting a single
update path.

Closes issue #17.

* feat: HTML+SVG progress-bar quota tooltip

Replace the Markdown table tooltip with an HTML <table> that embeds
inline SVG progress bars per row, mirroring what the official `/usage`
command shows. The bar fill colour changes by threshold to match the
status-bar warning/error backgrounds:

  - green  at  <80%   ("plenty left")
  - amber  at  >=80%  ("getting close")
  - red    at  >=95%  ("at the limit")

SVG was chosen over CSS-styled <div>s because VS Code's MarkdownString
sanitiser strips most `style` attributes but lets SVG through intact.
This means the bars render correctly on both light and dark themes
without needing theme-aware CSS variables.

The percentage and reset countdown columns are kept for users who
prefer the precise number; the weekly row still uses <br> to put the
reset moment and the countdown on two lines.

* fix: relax validator, restore 120s quota cache, HTML+span progress bars

Four small follow-ups from RC testing:

- Bump package.json to 2.0.1 so the packaged .vsix has the right name
  during the RC cycle.

- Quota cache: 30 s → 120 s. Multi-workspace sync was the goal of the
  shorter window, but 30 s feels too chatty during active token writes;
  120 s matches the polling interval.

- Relax validateUsageRecord. The previous version dropped any record
  whose secondary fields had an unexpected type (e.g. `model` is null,
  `requestId` is a number). That likely cost us records from new
  Claude Code features (xhigh / ultracode / workflow) and from some
  proxies that write slightly atypical JSON. Now only the two real
  must-haves are required: timestamp + numeric input/output tokens.
  All other fields are treated as best-effort.

  Added validationDropReason() and a stats counter so the loader writes
  a one-line "X files, Y lines, kept=N, dedup-replaced=…, rejected: …"
  summary to the "Claude Code Usage" output channel on every refresh.
  This lets us see exactly which validator rule is rejecting records
  rather than guessing.

- Quota tooltip progress bars: SVG was being stripped by VS Code's
  markdown sanitiser (so the new look never reached users). Switched
  to coloured <span>s with non-breaking-space padding — pure HTML,
  background-color is in the safe-CSS allowlist, renders consistently.
  Same colour thresholds as the status-bar background (green / amber
  at 80% / red at 95%).

* fix(tooltip): wider bar, 70% height, gray 100% frame, 24h weekly reset

Small polish on the quota tooltip from RC testing:

- Bar widened from 16 to 24 segments so low percentages (5h:24%) read
  proportionally instead of "barely a sliver".
- Bar height compressed via font-size:70% on the outer span so the bar
  looks like a thin strip rather than a full-height block.
- Outer span now has a gray 100%-width background — the "track" /
  frame is always visible regardless of fill, so users can see where
  the bar ends and where the boundary is.
- Weekly reset time switched to 24-hour format (hour12:false) to
  suppress AM/PM that some locales add. "Wed 03:00" stays "Wed 03:00".

* fix(tooltip): rounded corners, visible gray frame, 60% compression + diagnostics model breakdown

Tooltip polish (round 2):
- border-radius: 4px on both bar layers for rounded corners.
- Gray frame opacity bumped from 0.30 -> 0.55 so the 100% boundary is
  actually visible (previous version disappeared on most themes).
- font-size 70% -> 60% — bar reads as a thin horizontal strip rather
  than a full-line block.

Loader diagnostics now also list every model name found, sorted by
record count. This makes it instantly obvious whether a proxy is
writing records under a non-default model name (e.g. CC Switch's
deepseek-v4-pro[1m]) so we can investigate without guessing.

* fix(tooltip+diag): visible bar border + 48% height; log token-sum per model

Two follow-ups from RC testing round 4:

- Quota tooltip:
  - Bar height further compressed (font-size 60% → 48%) so the bar
    reads as a thin strip; height is now ~80% of what RC round 3 showed.
  - Added a 1px gray border on the outer span so the 0-100% frame is
    visible at all fill levels (the rgba track alone was easy to miss
    on busy backgrounds). Inner fill keeps 3px radius for soft corners.

- Loader diagnostic: model summary now reports token sum per model in
  addition to record count, formatted as e.g. `deepseek-v4-flash=99/0`.
  A model with N records but 0 total tokens is conclusive proof that
  every record for that model was a proxy zero-token placeholder — the
  pattern behind the missing-Flash story in CC Switch sub-agent paths.

* fix: visible tooltip frame, local-time logs, pause-dashboard-refresh setting

Three RC-round-5 improvements bundled as one meaningful commit (in line
with the "every commit should pull its weight" rule):

1. Quota tooltip progress bar:
   The previous outer-span + rgba border was invisible under both light
   and dark themes. Rebuilt as four adjacent solid-coloured spans:
   `[dark-gray bookend][filled cells][light-gray empty][dark-gray bookend]`.
   The dark-gray (#666) bookends mark 0% and 100% with strong contrast on
   any theme; the light-gray (#cccccc) empty fill keeps the unfilled range
   obvious. Bar colour by threshold (green / amber / red) unchanged.

2. Diagnostic log timestamps now use the local timezone instead of UTC
   (`toLocaleTimeString(undefined, { hour12: false })`). Affects both the
   loader and the API client output channel lines.

3. New `claudeCodeUsage.pauseDashboardRefresh` setting (default false).
   When on, fs.watch and the polling timer skip the webview update; the
   status bar still refreshes so today's cost and quota stay live. The
   "Refresh Usage Data" command always force-updates the webview so
   users can pull a fresh view on demand. Addresses the issue #17
   follow-up — agents writing to logs no longer thrash an open dashboard.

* feat(dashboard): in-page auto-refresh toggle; tooltip uses solid gray track

Two improvements in one commit:

1. Dashboard now has an "Auto-refresh: ON/OFF" toggle in the header.
   Default state mirrors the `claudeCodeUsage.pauseDashboardRefresh`
   setting. Clicking the toggle:
     - flips the CSS class on <body> (auto-off) so the conditional
       "Refresh Now" button appears in the header
     - persists the new state by updating the setting
   When OFF, the status bar still refreshes; the dashboard waits for
   the user to press "Refresh Now" or run the command. This addresses
   issue #17's follow-up comment — agents writing to logs no longer
   thrash an open dashboard while still keeping the user in control.

2. Quota tooltip progress bar reverted to the previously-rendering
   nested-span structure (the bookend approach didn't render in
   testing). Outer track is now solid #bbb instead of rgba — solid
   light-gray is visible on both light and dark themes without
   relying on opacity that some themes wash out. Inner colour fill
   sits on top with green/amber/red thresholds unchanged.

If the solid-gray track is still not visible enough, the path forward
is a v2.1 redesign rather than another small CSS tweak — this commit
is the last cosmetic attempt for v2.0.1.

* feat(dashboard): iOS-style auto-refresh toggle + i18n for label

Replace the previous text button with a proper switch:

- A native-looking <label> with an iOS-style slider (32x18 px). Slider
  turns green (#34c759) when auto-refresh is on, gray when off. Knob
  slides across via CSS transition. Focus ring uses the VS Code focus
  border colour.
- Switch state stays in sync with `claudeCodeUsage.pauseDashboardRefresh`
  and survives reload. The "Refresh Now" button only shows when the
  switch is off (controlled by the .auto-off body class).
- New i18n key `autoRefresh` translated for all six languages:
  EN "Auto refresh", DE "Auto-Aktualisierung", zh-TW "自動刷新",
  zh-CN "自动刷新", JA "自動更新", KO "자동 새로고침". Replaces the
  hardcoded English label.

Tooltip stays at 4e3f238 (nested-span with solid #bbb gray); further
cosmetic work deferred to v2.1.

* fix(v2.0.1): dedup, DeepSeek pricing, quota always-show, loading spinner, iOS toggle

Summary of all changes landing in the v2.0.1 release:

Fixes
- Dedup now keeps the higher-token record when hashes collide (issue #18,
  @zhaoxiao9302). Proxy "placeholder + real" pairs are handled correctly.
- DeepSeek pricing: deepseek-chat and deepseek-reasoner corrected from
  Flash rates to Pro rates ($0.435/$0.87). Added deepseek-v4-pro entry.
- Quota indicator no longer hides when workspace has no local Claude data.
- Webview / status bar no longer gets stuck on "Loading…" (PR #20,
  @nickearnshaw): re-entrancy guard + spinner only on cold start.
- Log timestamps now use local time (not UTC).

Added
- Dashboard "Auto-refresh" toggle (iOS-style) with localised label.
  When off: status bar still updates, webview pauses until "Refresh Now".
- claudeCodeUsage.fileWatching setting (opt-out fs.watch).
- claudeCodeUsage.pauseDashboardRefresh setting.
- Opus 4.8 explicit pricing entry.
- Diagnostic output channel: per-refresh stats + per-model record/token counts.

Docs
- README intro rewritten to "The Claude Code coach in your status bar"
  slogan (all language variants updated).
- New Troubleshooting entries: cleanupPeriodDays for history retention
  (PR #21, @nickearnshaw) and sub-agent token under-counting note.
- Credits updated for PRs #20, #21, #22 (@nickearnshaw).

Dev
- launch.json preLaunchTask fixed for single-root checkout (PR #22,
  @nickearnshaw).
@Carl723000

Copy link
Copy Markdown
Collaborator

Landed in v2.0.1 🎉 thanks @nickearnshaw!

@Carl723000 Carl723000 closed this Jun 8, 2026
@Carl723000 Carl723000 reopened this Jun 15, 2026
@Carl723000
Carl723000 merged commit 4b28966 into ClaudeCodeUsage:main Jun 15, 2026
1 check passed
@Carl723000

Copy link
Copy Markdown
Collaborator

Reopened and merged this properly. Thanks again.

@Carl723000 Carl723000 added the skip-changelog Exclude from auto-generated release notes label Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Exclude from auto-generated release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants