Repository navigation
feat: add API usage widgets (session, weekly, reset, context bar) - #168
Conversation
|
@pcvelz Thanks, I'll review this soon, travelling at the moment. How does this handle Windows and WSL? If they are unsupported, I'd like to still merge it, but with a system to gate it properly and have it only appear on supported OS's. |
|
@sirmalloc can this be merged? |
… reset, context bar) Resolved conflicts: keep both fork widgets (session-name, free-memory) and PR widgets (session-usage, weekly-usage, reset-timer, context-bar). Made-with: Cursor
|
Hi, this is quite a handy feature for Subscription users. Since the PR is still pending merge, would you mind adding a small custom feature that allows users to choose whether to hide or unhide the progress bar? For example, I like to keep the status line compact and only show the used percentage. |
e643ee6 to
b7dae7c
Compare
|
@sirmalloc I've updated this PR with Windows support, based on @zac15987's working Windows snippet on issue #94. I don't have access to a Windows machine myself, so I can't verify this with absolute certainty. That said, I'm fairly confident it works — I analyzed the differences between zac15987's working Windows script and our widget code, and the only deviation was The rest of the code was already platform-agnostic:
On Windows, credentials are read from The fix is also published as v2.1.8 in the fork. |
Add four new widgets that display Claude Code API usage data: - session-usage: 5-hour session utilization with progress bar - weekly-usage: 7-day utilization with progress bar - reset-timer: countdown to session reset - context-bar: context window usage with progress bar Fetches data from /api/oauth/usage using existing OAuth credentials (macOS Keychain + Linux file fallback). Includes 180s cache with 30s rate limiting to minimize API calls. Also enhances ContextPercentage widget to use context_window data from Claude Code's stdin JSON when available. Closes sirmalloc#94
b7dae7c to
07dd5d8
Compare
|
@pcvelz I've got a Windows machine I can test on. I'll dig into reviewing this today. |
|
@sirmalloc Anything further needed on this? I'd like to see it merged into main so happy to help with any outstanding issues. |
…statusline
- parse credentials/cache/API response via zod with nullable field support\n- move usage cache+lock to ~/.cache/ccstatusline/usage.{json,lock}\n- add missing getCategory() methods on API usage widgets\n- resolve context percentage brace-style lint issue
Split API usage widgets into dedicated files and a shared usage utility, replacing the monolithic ApiUsage widget module. Key changes: - add src/utils/usage.ts for API fetch/caching, parsing, error mapping, progress-bar helpers, and shared 5-hour window math - move widgets to standalone files: SessionUsage, WeeklyUsage, ResetTimer, ContextBar - remove src/widgets/ApiUsage.tsx and update widget exports/registry wiring - make BlockTimer usage-aware with usage API first and JSONL fallback via shared resolver - make ResetTimer follow BlockTimer UX: time/progress/short-progress modes, raw value support, invert toggle, and JSONL fallback when usage timing is unavailable - make SessionUsage and WeeklyUsage match timer interaction model: progress mode cycling, invert toggle, invert-clearing when returning to text mode, and raw-value support - update ItemsEditor to hide/disable invert keybind when widget is in text mode - remove eager block-metric parsing from ccstatusline render path so JSONL fallback is only invoked when usage timing is missing - add comprehensive tests for usage window fallback behavior and widget mode/toggle/raw output behavior Validation: - bun test - bun run lint
- add a shared context-window metrics utility to normalize context_window fields (window size, percentages, usage, and token snapshots) - make context window size from status JSON authoritative for context calculations when present; derive usable limit as 80% of reported size - keep model-id fallback behavior for missing context_window data, including case-insensitive [1m]/[1M] detection - update Context %, Context % (usable), Context Length, and Context Bar to use status JSON first and fall back to JSONL token metrics when needed - update Session Clock to use cost.total_duration_ms first with JSONL duration fallback - keep Tokens Input/Output JSON-first, while reverting Tokens Cached/Total to cumulative session JSONL totals - simplify render pipeline behavior to always parse current session JSONL token metrics when transcript_path exists - add/expand tests for context-window parsing, denominator precedence, 1M-without-suffix scenarios, case-insensitive suffix fallback, token widget source behavior, context bar rendering, and session clock behavior
- switch Context Bar usage basis from total current_usage (input+output+cache) to context-length usage (input+cache), matching Context Length widget - keep statusline JSON-first behavior with JSONL/model fallbacks unchanged - keep short-by-default progress mode and long/short toggle behavior - update ContextBar tests for new token basis and progress-mode expectations
|
Merged, will publish soon |
|
@pcvelz This has been published as v2.1.0 |
|
@sirmalloc Getting API error when adding the usage status lines. How can I debug what exactly is the issue?
|
|
@sanjeevpenupala What OS are you on? |
|
@sirmalloc I'm on macOS Sequoia 15.6.1. Also, I just did Does the code require to periodically refresh your credentials, to show your usage?
|
|
@sanjeevpenupala interesting. On macOS it uses your oauth token from the keychain, maybe /login refreshed it? I only tested on macOS 26, let me know if this occurs again or stops working. |
|
@sanjeevpenupala It's possible if you hadn't launched claude in a bit that the oauth token in your keychain was expired, and claude had not refreshed it during the first rendering of the statusline. there's also a 30s lock / error window on the usage fetch, so it's possible doing any message in claude that force a token refresh and then refreshed the statusline would have fixed it. I'll explore some better UX around this. |
|
@sanjeevpenupala Actually I think their usage api is acting up. Doing |
…rmalloc#168) * feat: add API usage widgets (session, weekly, reset timer, context bar) Add four new widgets that display Claude Code API usage data: - session-usage: 5-hour session utilization with progress bar - weekly-usage: 7-day utilization with progress bar - reset-timer: countdown to session reset - context-bar: context window usage with progress bar Fetches data from /api/oauth/usage using existing OAuth credentials (macOS Keychain + Linux file fallback). Includes 180s cache with 30s rate limiting to minimize API calls. Also enhances ContextPercentage widget to use context_window data from Claude Code's stdin JSON when available. Closes sirmalloc#94 * fix(api-usage): zod-validate usage data and move cache to ~/.cache/ccstatusline - parse credentials/cache/API response via zod with nullable field support\n- move usage cache+lock to ~/.cache/ccstatusline/usage.{json,lock}\n- add missing getCategory() methods on API usage widgets\n- resolve context percentage brace-style lint issue * Refactor usage widgets and unify timer/usage display modes Split API usage widgets into dedicated files and a shared usage utility, replacing the monolithic ApiUsage widget module. Key changes: - add src/utils/usage.ts for API fetch/caching, parsing, error mapping, progress-bar helpers, and shared 5-hour window math - move widgets to standalone files: SessionUsage, WeeklyUsage, ResetTimer, ContextBar - remove src/widgets/ApiUsage.tsx and update widget exports/registry wiring - make BlockTimer usage-aware with usage API first and JSONL fallback via shared resolver - make ResetTimer follow BlockTimer UX: time/progress/short-progress modes, raw value support, invert toggle, and JSONL fallback when usage timing is unavailable - make SessionUsage and WeeklyUsage match timer interaction model: progress mode cycling, invert toggle, invert-clearing when returning to text mode, and raw-value support - update ItemsEditor to hide/disable invert keybind when widget is in text mode - remove eager block-metric parsing from ccstatusline render path so JSONL fallback is only invoked when usage timing is missing - add comprehensive tests for usage window fallback behavior and widget mode/toggle/raw output behavior Validation: - bun test - bun run lint * Prefer status JSON context-window metrics with robust fallbacks - add a shared context-window metrics utility to normalize context_window fields (window size, percentages, usage, and token snapshots) - make context window size from status JSON authoritative for context calculations when present; derive usable limit as 80% of reported size - keep model-id fallback behavior for missing context_window data, including case-insensitive [1m]/[1M] detection - update Context %, Context % (usable), Context Length, and Context Bar to use status JSON first and fall back to JSONL token metrics when needed - update Session Clock to use cost.total_duration_ms first with JSONL duration fallback - keep Tokens Input/Output JSON-first, while reverting Tokens Cached/Total to cumulative session JSONL totals - simplify render pipeline behavior to always parse current session JSONL token metrics when transcript_path exists - add/expand tests for context-window parsing, denominator precedence, 1M-without-suffix scenarios, case-insensitive suffix fallback, token widget source behavior, context bar rendering, and session clock behavior * Align Context Bar with Context Length semantics - switch Context Bar usage basis from total current_usage (input+output+cache) to context-length usage (input+cache), matching Context Length widget - keep statusline JSON-first behavior with JSONL/model fallbacks unchanged - keep short-by-default progress mode and long/short toggle behavior - update ContextBar tests for new token basis and progress-mode expectations * usage: honor CLAUDE_CONFIG_DIR and use runtime-safe HTTPS API fetch * Fix context bar overflow and preserve usage error states * Group usage widgets under new Usage picker category * Rename context remaining toggle to used/remaining shortcut --------- Co-authored-by: Peter van Velzen <[email protected]> Co-authored-by: Matthew Breedlove <[email protected]>
…rmalloc#168) * feat: add API usage widgets (session, weekly, reset timer, context bar) Add four new widgets that display Claude Code API usage data: - session-usage: 5-hour session utilization with progress bar - weekly-usage: 7-day utilization with progress bar - reset-timer: countdown to session reset - context-bar: context window usage with progress bar Fetches data from /api/oauth/usage using existing OAuth credentials (macOS Keychain + Linux file fallback). Includes 180s cache with 30s rate limiting to minimize API calls. Also enhances ContextPercentage widget to use context_window data from Claude Code's stdin JSON when available. Closes sirmalloc#94 * fix(api-usage): zod-validate usage data and move cache to ~/.cache/ccstatusline - parse credentials/cache/API response via zod with nullable field support\n- move usage cache+lock to ~/.cache/ccstatusline/usage.{json,lock}\n- add missing getCategory() methods on API usage widgets\n- resolve context percentage brace-style lint issue * Refactor usage widgets and unify timer/usage display modes Split API usage widgets into dedicated files and a shared usage utility, replacing the monolithic ApiUsage widget module. Key changes: - add src/utils/usage.ts for API fetch/caching, parsing, error mapping, progress-bar helpers, and shared 5-hour window math - move widgets to standalone files: SessionUsage, WeeklyUsage, ResetTimer, ContextBar - remove src/widgets/ApiUsage.tsx and update widget exports/registry wiring - make BlockTimer usage-aware with usage API first and JSONL fallback via shared resolver - make ResetTimer follow BlockTimer UX: time/progress/short-progress modes, raw value support, invert toggle, and JSONL fallback when usage timing is unavailable - make SessionUsage and WeeklyUsage match timer interaction model: progress mode cycling, invert toggle, invert-clearing when returning to text mode, and raw-value support - update ItemsEditor to hide/disable invert keybind when widget is in text mode - remove eager block-metric parsing from ccstatusline render path so JSONL fallback is only invoked when usage timing is missing - add comprehensive tests for usage window fallback behavior and widget mode/toggle/raw output behavior Validation: - bun test - bun run lint * Prefer status JSON context-window metrics with robust fallbacks - add a shared context-window metrics utility to normalize context_window fields (window size, percentages, usage, and token snapshots) - make context window size from status JSON authoritative for context calculations when present; derive usable limit as 80% of reported size - keep model-id fallback behavior for missing context_window data, including case-insensitive [1m]/[1M] detection - update Context %, Context % (usable), Context Length, and Context Bar to use status JSON first and fall back to JSONL token metrics when needed - update Session Clock to use cost.total_duration_ms first with JSONL duration fallback - keep Tokens Input/Output JSON-first, while reverting Tokens Cached/Total to cumulative session JSONL totals - simplify render pipeline behavior to always parse current session JSONL token metrics when transcript_path exists - add/expand tests for context-window parsing, denominator precedence, 1M-without-suffix scenarios, case-insensitive suffix fallback, token widget source behavior, context bar rendering, and session clock behavior * Align Context Bar with Context Length semantics - switch Context Bar usage basis from total current_usage (input+output+cache) to context-length usage (input+cache), matching Context Length widget - keep statusline JSON-first behavior with JSONL/model fallbacks unchanged - keep short-by-default progress mode and long/short toggle behavior - update ContextBar tests for new token basis and progress-mode expectations * usage: honor CLAUDE_CONFIG_DIR and use runtime-safe HTTPS API fetch * Fix context bar overflow and preserve usage error states * Group usage widgets under new Usage picker category * Rename context remaining toggle to used/remaining shortcut --------- Co-authored-by: Peter van Velzen <[email protected]> Co-authored-by: Matthew Breedlove <[email protected]>


Summary
Adds four new widgets that display Claude Code API usage data, closing #94:
context_windowdata from Claude Code stdin JSON)Also enhances the existing
ContextPercentagewidget to usecontext_windowdata when transcript-based token metrics aren't available.How it works
GET /api/oauth/usageusing existing OAuth credentials (macOS Keychain + Linux~/.claude/.credentials.jsonfallback)Files changed
src/widgets/ApiUsage.tsxsrc/widgets/index.tssrc/utils/widgets.tssrc/types/StatusJSON.tscontext_windowschema for Claude Code's context datasrc/widgets/ContextPercentage.tscontext_windowfrom stdin when availableContext
This was originally prototyped as a bash script and then implemented as native TypeScript widgets in a fork. This PR extracts just the widget code with no other changes.
Uses the same API approach as claude-pulse — same endpoint, same auth headers.
Test plan
bun run buildsucceedsbun testpasses[No credentials]gracefully when OAuth token is unavailable~/.cache/ccstatusline-api.jsonafter first API call~/.claude/.credentials.json