Handle [1M], (1M), and optional context labels when inferring model context size; use model id + display_name in context widgets and add regression coverage for ctx, ctx(u), and context bar.
Closes#193
- add a new Link widget with OSC8 rendering, preview parity, and raw mode behavior
- fix truncation and visible-width calculation to handle ANSI/OSC sequences safely
- bump package version to 2.1.3
- update README recent updates and widget documentation
Resolves#188
* 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#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 <pvvelzen@emico.nl>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* FreeMemory widget:
Description: Shows system memory usage (used/total) in a compact format like Mem: 12.4G/16.0G
Features:
- On macOS: Uses vm_stat to calculate memory like htop (Active + Wired pages)
- On other platforms: Falls back to Node.js os.freemem()/os.totalmem()
- Smart byte formatting (G, M, K, B)
- Supports raw value mode (omits "Mem:" prefix)
- Default color: cyan
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Version bump and README update
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* Add Git Root Dir widget
Add a new widget that displays the git repository root directory name.
- Shows directory name with 📁 icon (e.g., "📁 my-repo")
- Supports rawValue option for icon-free display
- Supports hideNoGit option to hide message when not in a git repo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Change Git Root Dir widget icon to text label
Replace 📁 emoji with "Repo:" text label for better compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove label from Git Root Dir widget
Display only the repository name without any prefix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix GitRootDir root path handling and raw mode
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* Add Session Name widget
Adds a native widget to display the Claude Code session name set via the
/rename command. The widget reads the transcript file and extracts the
customTitle from custom-title entries.
- New SessionName widget with rawValue support
- 9 unit tests
- README documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add category metadata to session name widget
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: add abbreviate home option to Current Working Directory widget
Add a new 'abbreviate home' toggle (h key) that replaces the home
directory path with ~ (e.g., /Users/matt/Projects → ~/Projects).
- Can be combined with segments for paths like ~/.../Projects/my-project
- Mutually exclusive with fish-style abbreviation
- Includes tests for the new functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: correct cwd home abbreviation edge cases
Preserve platform path separators when combining home abbreviation with segments.
Require exact home-directory boundary matching to avoid false substitutions.
Align one-segment abbreviateHome preview with runtime output.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* fix(test): replace vi.mocked with direct mock reference in GitWorktree tests
vi.mocked(execSync) was undefined because the vi.mock factory runs
before imports resolve. Use a top-level vi.fn() reference instead.
* feat(tui): add move mode to LineSelector for reordering lines
Press 'm' to enter move mode, use arrow keys to swap lines,
Enter/Escape to exit. Visual feedback mirrors ItemsEditor pattern
with blue diamond marker and [MOVE MODE] label.
* chore: update bun.lock
* Fix for model in statusLine JSON being passed as string vs object, closes#157, version bump
* fix(test): make GitWorktree execSync mock hoist-safe
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: Add Claude Session ID widget
* Add ClaudeSessionIdWidget to widget registry, add label, support raw mode, fix cross-platform issues by using session ID directly from statusline JSON
---------
Co-authored-by: Marty <marty@croakingtoad.com>
Co-authored-by: Matthew Breedlove <matt@revenite.ai>
* Fix: Dynamic context window calculation for Sonnet 4.5 (1M tokens)
- Create model-context utility with dynamic context window mapping
- Sonnet 4.5 models now use 1M context (800k usable)
- Older models default to 200k context (160k usable)
- Update ContextPercentage and ContextPercentageUsable widgets
- Update renderer.ts flex mode calculations (2 locations)
- Add comprehensive test coverage (14 new tests, 36 total passing)
Fixes incorrect percentage display for Sonnet 4.5:
- Before: 42k tokens showed 21.0% (using 200k denominator)
- After: 42k tokens shows 4.2% (using 1M denominator)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Style: Apply ESLint auto-fixes for consistency
- Standardize indentation to 4 spaces
- Apply formatting rules from eslint.config.js
- No logic changes, formatting only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Refactor: Code review fixes for context window changes
- Fix misleading test name (line 69 of context-percentage.test.ts)
- Strengthen model ID pattern matching (claude-sonnet-4-5 vs sonnet-4-5)
- Standardize export style (inline export for consistency)
All tests passing (19/19 for affected files)
TypeScript and ESLint checks passed
* Enhance CLAUDE.md: Update piped input example for Sonnet 4.5 and add test commands
- Changed piped input example to reflect the new model ID for Claude 4.5
- Added instructions for running tests and tests in watch mode
- Updated context window metrics description to include dynamic model-based context windows
Improves clarity and usability for developers working with the project.
* Fix: Require [1m] suffix for Sonnet 4.5 1M context window detection
Address PR feedback that Sonnet 4.5 only has 1M context on API usage
when the model ID includes the [1m] suffix (long context beta access).
Changes:
- Update getContextConfig() to check for [1m] suffix (case-insensitive)
- Models without suffix now safely default to 200K context
- Add comprehensive test coverage for suffix detection
- Update all test fixtures to use correct model ID format
- Document suffix requirement in CLAUDE.md
This ensures conservative behavior - only models with explicit [1m]
suffix receive 1M context allocation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: Add fish-style path abbreviation to CurrentWorkingDir widget
- Added new toggle option for fish-style path abbreviation
- Keeps home directory as ~, first and last directories complete
- Abbreviates middle directories to first letter only
- Preserves dot for hidden directories (e.g. .config → .c)
- Maintains backward compatibility with segments feature
- Both options are mutually exclusive (fish-style takes precedence)
Example: ~/Documents/Projects/my-project → ~/D/P/my-project
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Modify cwd widget fish-style code to use handleEditorAction instead of renderEditor, misc lint fixes
---------
Co-authored-by: Jishuai <aqianlikuaizaifeng@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>