Repository navigation
v2.0.2: Fable 5 pricing, attribution & quota fixes, cost-composition charts - #29
Merged
Carl723000 merged 13 commits intoJun 11, 2026
Conversation
Three related status-bar refresh fixes (problem reported: quota stuck at a stale 100% after the 5h window reset; status bar not updating promptly during ultracode runs). 1. Stale quota after reset (adapted from PR ClaudeCodeUsage#24 by @nickearnshaw): add liveWindows() in statusBar.ts. A window's utilization is only valid until its resets_at; once that passes the cached value is stale. We now drop expired windows before display and hide the indicator if nothing current remains, rather than rendering a value we can no longer trust. Bounds staleness to each window's period (<=5h / <=1 week) instead of forever. 2. Activity-aware cadence: track the last .jsonl write (lastActivityAt, updated by the recursive fs.watch). While active (a write in the last 60s) the polling timer ticks every ~15s and the quota cache shrinks to 20s, so high-consumption ultracode/workflow runs update promptly. When idle, both fall back to the user's interval (min 30s) / 120s. The auto refresh timer became self-rescheduling to support this. 3. Coalesce overlapping refreshes: instead of dropping a trigger that arrives mid-load (which starved updates while many sub-agent files were being written rapidly), set a pendingRefresh flag and run exactly one more refresh after the current finishes.
…onthly The daily (This Month tab) and monthly (All Time tab) charts previously showed a flat single-colour cost bar with no scale. They now: - Render inside the gridded hc-wrap layout: a Y-axis (max / max-2 / 0) and two dashed reference lines, matching the hourly chart. This gives the "three reference levels" the user asked for. - Render the cost metric as a stacked composition — input / output / cache-write / cache-read, same colours as the summary's Cost Composition (blue / orange / purple / green). Each segment's height is its share of that day's/month's cost, so a glance shows both total spend and where it went. The metric switcher still works: switching to a token/message metric re-renders single-colour bars (updateMainChart now rebuilds bar content per metric from data attributes rather than only resizing). Cost segments are pointer-events:none so clicking a bar still drills down to the hourly / daily detail. Implementation notes: - Shared renderMainCostChart() backs both renderDailyChart and renderAllTimeChart. - Bars carry the cost breakdown as data-cost-* attributes so the client can rebuild the stack on metric switch without a round-trip. - The fixed-height .chart-container wrapper was removed for these two charts (hc-wrap is self-contained with its own scroll), avoiding a double scrollbar.
- README.md: the changelog links pointed to `changelog.md` (lowercase)
but the file is `CHANGELOG.md` — broken on case-sensitive GitHub.
Fixed both occurrences. Dropped the stale "v2 translations in 2.0.1"
note.
- The five language READMEs were still v1-era content: old feature lists,
old upstream jack21 screenshot links, inline v1 changelogs. Rewritten
to v2:
- en / zh-TW / ja / ko: concise editions — slogan, v2 screenshots
(images/v2-*-en.png), feature list, install, key settings,
troubleshooting (incl. cleanupPeriodDays + sub-agent note), and a
pointer to the main README for full detail.
- zh-CN: full translation of README.md (Chinese is the highest-traffic
locale for this repo's README).
All language editions now carry the "coach in your status bar"
positioning and the "issues/PRs welcome" note.
…ue templates - CLAUDE.md rewritten to the v2 architecture (advisor / claudeApiClient / adviceDemoSample modules, adaptive refresh, curl-based OAuth, automated release workflow) and the project's positioning + conventions. - CLAUDE.local.md added for per-maintainer personal notes (gitignored and .vscodeignored — not committed, not packaged). Documents the local environment, working preferences, collaborators and roadmap. - CONTRIBUTING.md added: scope, dev setup, PR checklist, the planned node:test direction (issue ClaudeCodeUsage#25), and the automated release flow. - GitHub issue templates (bug report / feature request) added, both noting the project scope so requests land in-scope. - CHANGELOG [2.0.2] entry covering the quota / refresh / chart fixes and the docs refresh.
…l, per-workspace session Follow-ups from v2.0.2 RC testing: - Today's hourly cost chart is now a stacked composition (input / output / cache-write / cache-read), matching the daily and monthly charts. - The drill-down charts (daily under a month, hourly under a day) were still flat single-colour bars with no scale and day-number-only labels. They now use the same gridded layout (Y-axis + two reference lines) and stacked cost composition via a shared `griddedChart` client helper. The daily drill-down x-axis shows month/day instead of a bare day number. - Expanding a detail now scrolls it into view. Clicking a bar at the top of a tab previously expanded a detail row far down the table that users never noticed. - "Current session" in the status bar is now the single most-recent conversation scoped to this window's workspace, instead of a global 5-hour aggregate across all projects. Different workspaces now show their own current-session cost; returns nothing if idle >5h so a stale session doesn't show as current.
…'this project today' Final v2.0.2 RC fixes from testing: - Chart Y-axis now updates per metric. The metric switcher left the reference-line labels stuck on the cost metric's units because the container holds two hc-yaxis elements (main chart + token-composition chart) — the 6-value query failed its `=== 3` guard. Now scoped to the main chart's own wrap. - Quota no longer vanishes when a window resets. An expired window is rolled forward to 0% with its reset time advanced by whole periods (5h / 1 week), instead of being hidden. A forced refetch (bypassing the cache when an expired window is detected) replaces the 0% estimate with the real new-window value shortly after. - Status bar secondary number changed from "current session" to "this project today" — today's cost for the current workspace. Both numbers are now midnight-stable (the old session figure vanished after 5h idle and was identical across all windows because it aggregated the last 5h globally). New i18n key `workspaceToday` (6 languages); icon is $(folder). The per-workspace current-session figure is still computed for the webview. Adds ClaudeDataLoader.filterByWorkspace().
…de review) Two correctness fixes from a self code-review of the v2.0.2 branch: - startAutoRefresh's self-rescheduling timer could spawn duplicate chains: if it ran again (e.g. on a config change) while a tick's refreshData().finally(tick) was mid-flight, the orphaned chain would keep its own setTimeout alive alongside the new one, multiplying the refresh cadence over time. A generation token now stops any superseded chain. - liveWindows roll-to-0% (so a reset window doesn't vanish) is now bounded: a window that expired more than ~2 periods ago is dropped instead of shown at a fabricated 0%. This avoids implying "full quota available" when the OAuth fetch has actually been failing for a long time (expired creds, offline). A genuine recent reset still shows 0% and is corrected by the forced refetch within a TTL.
…ent session attribution Batch of fixes from v2.0.2 RC round 3 + new-model support: Pricing - Claude Fable 5 / Mythos 5 added ($10/$50, cache write $12.50, cache read $1 per MTok — verified 2026-06-09 against the official pricing page). Family fallback maps unknown fable/mythos snapshots to this tier. - getModelPricing now strips a trailing "[1m]" long-context marker before lookup (1M-context variants bill at standard rates). This also fixes pricing for users whose proxy config pins e.g. "deepseek-v4-pro[1m]". Status bar - "This project" no longer disappears at $0: the figure shows whenever a workspace is open, including $0.00. Hiding at zero read as a bug. - filterByWorkspace now also matches records that only carry the dash-encoded project directory name (records without a cwd field): the workspace path is encoded the same way Claude Code does (D:\Jiaming\My_Proj → d--Jiaming-My-Proj) and compared directly. Previously such records counted in the global total but never in the per-project figure — part of the "project sums don't add up" report. Session attribution (pre-v2.1 hardening) - parseSessionInfo now resolves files nested under a session directory (subagents/workflows/*/agent-*.jsonl) to their parent session id and real project directory. They previously got a 'wf_xxx' pseudo-project and 'agent-xxx' session ids, fragmenting Sessions/Projects aggregation — the other part of the mismatch report, and groundwork for the v2.1 workflow attribution. Sessions tab - New sortable "Session" column showing the conversation title (the name `claude --resume` shows, harvested from each session's summary log line), falling back to the session id. Same-project sessions are now distinguishable. i18n key sessionTitle added for all six languages. Drill-down charts - Removed the fixed-height chart-container wrapper around the gridded drill-down charts (double scrollbar). - Date labels/tooltips parse 'YYYY-MM-DD' textually instead of new Date(...) UTC parsing, which shifted labels a day back in negative-UTC timezones. Cleanup - getCurrentSessionData reuses filterByWorkspace (drops duplicate norm).
Full implementation spec for v2.1.0 at docs/V2.1-WORKFLOW-SPEC.md, written to be handed to a fresh Claude Code session for end-to-end implementation. Covers: verified on-disk data formats for workflow / sub-agent logs, the five phases (advice reliability fix, loader data model, Workflows tab, thinking share + quota guard, per-skill stats, advice upgrade), acceptance criteria per phase, conventions, and real verification data locations. docs/ excluded from the .vsix.
…e count, startup visibility
Root-caused with on-disk diagnostics this round:
Workspace attribution ("This project" undercount)
- A single conversation's per-record cwd wanders as work moves between
folders (observed: one session split 10/71 across two cwds), so
cwd-based matching fragmented the per-project figure ($9.51 of $36.78).
Records now carry _projectDirEncoded — the encoded project directory
the session file lives in (= where the session was started) — and
filterByWorkspace matches that first, attributing whole conversations
to their workspace. cwd matching remains as a secondary net.
Verified: workspace-today now equals global-today when all of today's
work happened in one workspace.
Session titles
- Titles were showing raw uuids: current Claude Code stores titles as
`ai-title` / `custom-title` jsonl lines, not the legacy `summary` type.
Harvest both (custom beats AI; summary kept for old logs). Verified
against real data — custom titles like 【CC usage插件】… now display.
Messages = what the user typed
- messageCount previously counted API calls (one conversation showed 33
"messages" for 5 actual prompts). The loader now synthesizes zero-usage
marker records for genuine user prompts (excluding meta/command lines,
sidechain dispatches, and anything in sub-agent logs) and messageCount
counts only those. Token figures are unchanged. Sessions with spend but
no typed prompt in scope remain listed.
Startup visibility (also reported on GitHub: "usage not showing the
first time I open VS Code")
- The cost item rendered empty text until the first full refresh, which
was blocked behind an awaited OAuth quota fetch (curl; seconds or a
failure on a cold network). The status bar now shows a loading state
from t=0, the quota fetch is fire-and-forget so local figures land
immediately, and a failed first quota fetch retries up to 3× with
backoff instead of waiting for the next tick.
Cadence
- Active refresh tick 15s → 8s, active quota TTL 20s → 15s (Fable 5
consumption moves fast enough that 15s read as laggy).
Community standards
- PULL_REQUEST_TEMPLATE.md (structured for fast review and future
automated triage), question.yml issue template.
Docs
- docs/V2.2-AUTOMATION-SPEC.md: human-gated AI issue/PR handling spec
(mention-driven claude-code-action + label/draft-queue triage where
merging a triage PR is the explicit authorization to post).
…command echoes from message count Two issues from RC testing: Quota "only comes back after I restart VS Code" - Root cause: when the in-memory OAuth token expired and our own refresh failed, getValidCredentials never re-read ~/.claude/.credentials.json — which Claude Code itself keeps refreshing. So a stale cached token stuck until the extension host restarted. Now an expired in-memory token triggers a disk re-read first (Claude Code has very likely already rotated it), falling back to our refresh only if the disk copy is also expired. - The 429 cool-down was a flat 5 minutes, so a single rate-limit looked like a multi-minute outage. Cut to 60 s. - The previous round's aggressive cadence likely caused those 429s: quota TTL is now 60 s active / 120 s idle (was 15 s) and the cold-start retry is a single attempt, not a storm. Local cost still refreshes every ~8 s via the fs watcher — only the slow-moving quota % is throttled, which is what keeps /usage under its rate limit. Message count inflated by system markers - "Messages" counted Claude Code's own user-line markers: interruption notices ([Request interrupted by user]) and slash-command echoes (<command-name>/model…, <local-command-stdout>…). Excluded via isSyntheticUserText. Example session: 106 → 86 (matches the genuine typed-prompt count).
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.
Patch release. All changes are backwards-compatible; new settings default to existing behaviour.
Added
[1m]long-context model ids resolve to base pricing (also fixes proxy configs likedeepseek-v4-pro[1m]).Fixed
~/.claude/.credentials.json(which Claude Code keeps refreshing) before our own refresh; 429 cool-down cut from 5 min to 60 s; gentler/usagecadence (60 s active / 120 s idle). Quota-after-reset adapted from Fix: quota indicator (5h/wk %) gets stuck showing a stale value #24 (@nickearnshaw)./commandechoes, interruption markers); token figures unchanged.preLaunchTask(fix: correct preLaunchTask reference in launch.json (F5 fails) #22, @nickearnshaw).Docs / project
CONTRIBUTING.md, PR + issue templates;cleanupPeriodDaysdocs (docs: explain how to retain more usage history (cleanupPeriodDays) #21) and webview loading guard (Fix webview/status bar getting stuck on "Loading…" #20) from @nickearnshaw;CLAUDE.mdupdated.Full detail: CHANGELOG
[2.0.2].Known issue #27 (v2.0.1 dashboard won't open) — webview was substantially reworked here; asking the reporter to verify on v2.0.2. macOS Keychain support (#28) scheduled for v2.0.3.
Co-Authored-By: Claude noreply@anthropic.com