Repository navigation
v2.0.1: dedup fix, DeepSeek pricing, auto-refresh toggle, loading fix - #23
Merged
Carl723000 merged 16 commits intoJun 3, 2026
Merged
Conversation
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.
…eepSeek pricing Issue ClaudeCodeUsage#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 ClaudeCodeUsage#18)
…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 ClaudeCodeUsage#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 ClaudeCodeUsage#17.
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.
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%).
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".
…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.
… 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.
…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 ClaudeCodeUsage#17
follow-up — agents writing to logs no longer thrash an open dashboard.
… 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 ClaudeCodeUsage#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.
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.
…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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Patch release following v2.0.0. All changes are backwards-compatible and the new settings default to the previous behaviour.
What's fixed
tokens=0placeholder first, then the real values. The dedup now keeps whichever record has the higher total token sum.deepseek-chat/deepseek-reasonercorrected from V4-Flash rates to V4-Pro ($0.435/$0.87, cache hit $0.003625).What's new
claudeCodeUsage.fileWatchingsetting — opt-out offs.watch.claudeCodeUsage.pauseDashboardRefreshsetting.Docs
cleanupPeriodDaysfor history retention (thanks PR docs: explain how to retain more usage history (cleanupPeriodDays) #21), sub-agent token under-counting note.Dev
launch.jsonpreLaunchTaskfixed (F5 works in single-root checkout, thanks PR fix: correct preLaunchTask reference in launch.json (F5 fails) #22).Credits
This release incorporates community contributions from:
Many code changes drafted with Claude Code.
Co-Authored-By: Claude noreply@anthropic.com