* feat: add a global minimalist mode that defaults widgets to raw mode
Adds the foundational plumbing for a global minimalist mode toggle:
- RenderContext.minimalist flag (optional boolean)
- Settings.minimalistMode field (default false, Zod-managed)
- Threads the flag from settings into RenderContext at render time in
both piped mode (ccstatusline.ts) and TUI preview (StatusLinePreview.tsx)
Adds an (m) keybind to the Global Overrides TUI menu to toggle minimalist
mode on/off. The setting is persisted immediately via onUpdate, and the
preview reflects the change in real time via the RenderContext flag.
When minimalist mode is active, the renderer forces rawValue: true on all
widgets before calling render(), stripping decorative labels and prefixes
globally. No per-widget changes needed.
* fix: keep strict settings literals for minimalist mode
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: fzf when adding widgets
Adds fuzzy matching to the widget picker as a fallback when the query
has no exact substring match anywhere.
Characters must appear in order but need not be adjacent; matches are
scored by span, consecutive runs, and word boundaries, and ranked below
all exact matches.
Selection now resets to the top-ranked result on every keystroke instead
of staying pinned to the previously-selected widget type.
Matched characters are highlighted in the picker list: yellow-bold for
unselected rows, green-bold for the selected row.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: prefer widget picker initialisms over incidental matches
Give display-name initialism matches their own ranking path so abbreviation searches like tw, tc, ti, and to select the intended widget instead of description or type fallbacks. Keep picker highlighting aligned with the ranking logic and add regressions for the reported fuzzy-match cases.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: use native rate_limits field from Claude Code 2.1.80
Claude Code 2.1.80 now sends rate_limits in the statusline JSON input
with five_hour and seven_day windows (used_percentage + resets_at).
When present, usage widgets consume this data directly instead of
fetching from the Anthropic API. Falls back to the API fetch for
older Claude Code versions that don't send rate_limits.
Also updates the example payload to match the real 2.1.80 format.
* fix: revert example payload to use placeholder values
* chore: align test values with example payload
* fix: Fallback to API usage query if any of the rate limit fields are missing
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: add hyperlink support to GitBranch and GitRootDir widgets
- GitBranch: toggle (l)ink wraps branch name in OSC 8 link to
github.com/owner/repo/tree/<branch>; only activates for GitHub
remotes, falls back to plain text otherwise
- GitRootDir: toggle (l)ink wraps project root name in OSC 8
cursor://file/<path> link to open the directory in Cursor
- Add shared src/utils/hyperlink.ts with renderOsc8Link and
parseGitHubBaseUrl helpers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Improve git and IDE hyperlink handling
- encode GitHub branch refs so reserved characters do not break branch links
- accept ssh:// and credentialed GitHub remotes when building GitHub URLs
- replace the Cursor-only repo root toggle with IDE link modes for VS Code and Cursor
- build IDE file links from encoded paths so Windows, spaces, #, and UNC paths work
- reuse the shared OSC-8 hyperlink renderer from the Link widget
- add focused coverage for hyperlink parsing and the updated git widgets
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: add vim-mode widget
Adds a new status line widget that displays the current vim mode when
Claude Code's vim mode is enabled.
Claude Code includes a `vim` field in the status hook JSON when vim mode
is active. The widget reads this field and renders a compact indicator.
When vim mode is not enabled, the widget returns null and hides itself.
Five display formats are supported via metadata.format:
- icon-dash-letter (default): -N / -I
- icon-letter: N / I
- icon: icon only
- letter: N / I
- word: NORMAL / INSERT
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix vim mode defaults and editor toggles
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* fix(timer): show days in formatUsageDuration for durations >= 24h
Durations of 24+ hours now display a days component instead of
raw hours (e.g. "1d 12hr 30m" instead of "36hr 30m"). Applies to
both normal and compact formats. Fixes#210.
* refactor(timer): simplify formatUsageDuration and show 0m for zero duration
Unify compact/normal branches into a single code path differing only
in hour label and separator. Zero duration now displays "0m" instead
of "0hr"/"0h".
* Add weekly reset hours toggle
Default weekly reset timers to day-based formatting while adding an hours-only toggle and keeping preview text aligned with live rendering.
Also move custom keybind visibility back into widgets and clear disabled toggle metadata when those options become unavailable in the editor.
Supersedes #235Closes#235
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
Adds a new "thinking-effort" widget that shows the current
thinking effort level (low, medium, high) in the status bar.
Data source priority:
1. StatusJSON "thinking.effort" field (from Claude Code status hook)
2. "thinkingMode" key in ~/.claude/settings.json (user fallback)
Usage in config:
{ "type": "thinking-effort", "color": "magenta" }
Closes#209
Changes:
- src/types/StatusJSON.ts: add optional "thinking" field
- src/widgets/ThinkingEffort.ts: new widget implementation
- src/widgets/index.ts: export ThinkingEffortWidget
- src/utils/widget-manifest.ts: register "thinking-effort" type
- src/widgets/__tests__/ThinkingEffort.test.ts: 13 unit tests
Co-authored-by: GitHub User <user@example.com>
* feat(timer): add compact time format option for timer widgets
Add an optional compact display mode (s key) to BlockTimer, BlockResetTimer,
and WeeklyResetTimer that renders durations as '5h30m' instead of '5hr 30m'.
- Add `compact` boolean parameter to `formatUsageDuration`
- Add `isUsageCompact` / `toggleUsageCompact` helpers in usage-display.ts
- Add `toggle-compact` action and `s` keybind across all three timer widgets
- Preview text reflects compact format when flag is set
- Editor modifier text shows 'compact' when flag is enabled
- Tests cover compact format output, keybind exposure, and toggle behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix compact timer widget editor state
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat(list): add custom list component
* feat(list): add sublabel and disabled options for list items
* Refactor TUI menu screens onto shared List component
Replace the remaining menu-style terminal and powerline screens with the shared List component so they share navigation, descriptions, back-row behavior, disabled states, and confirm dialog rendering.
This migrates TerminalOptionsMenu, TerminalWidthMenu, PowerlineSetup, PowerlineThemeSelector, and ConfirmDialog, and adds focused tests for the extracted menu builders and Ink-level regressions.
It also fixes two regressions uncovered during manual testing: PowerlineThemeSelector now memoizes theme data and List selection callbacks so live theme preview no longer triggers a maximum update depth loop, and TerminalWidthMenu now restores focus to the active full-until-compact row after returning from threshold entry instead of resetting to the first item.
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* feat: Add Skills widget with cross-platform hook framework
Replaces bash/jq hook with a built-in --hook CLI handler that works
on all platforms. Widgets can declare hooks via getHooks() which are
auto-synced to Claude settings when the statusline config is saved.
* feat: tighten hook lifecycle and upgrade skills widget
Notes:\n- Hook sync now follows saved-state semantics: installing statusline syncs hooks from saved ccstatusline settings on disk, and uninstall always removes all ccstatusline-managed hooks.\n- syncWidgetHooks always strips managed hooks first, including when statusline.command is missing, then persists cleanup.\n- Skills metrics storage path is now ~/.cache/ccstatusline/skills/skills-<sessionId>.jsonl.\n- Skills unique list ordering is now most-recent-first.\n- Skills widget updates: view toggle on (v), hide-when-empty toggle on (h), explicit empty outputs when not hidden, and new list-only (l)imit editor option where 0 means unlimited (default).\n- Added list-limit custom editor flow and list-only keybind visibility in ItemsEditor.\n- Maintained Node 14 compatibility by avoiding Array.prototype.at in skills metrics parsing.\n- Added/updated regression tests for hook sync/install/uninstall behavior, skills metrics path/order, Skills widget rendering/editing, and items-editor custom keybind handling.
* chore: bump version to 2.2.1 and update release notes
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* Add Dependabot configuration for npm and GitHub Actions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: use bun ecosystem and add Dependabot cooldowns
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* fix: support bare repo worktrees in GitWorktree widget
The GitWorktree widget now correctly detects worktrees from bare
repositories. Previously, it only checked for `.git/worktrees/` in
the path, but bare repos store worktree metadata at
`<bare-repo>/worktrees/<name>` without the `.git` prefix.
This adds an additional check for `/worktrees/` pattern when the
`.git/worktrees/` pattern isn't found.
Fixes detection for setups like:
- Bare repo at: /path/to/repo (contains objects/, refs/, HEAD, etc.)
- Worktree at: /path/to/repo/trees/feature-x
- Git dir: /path/to/repo/worktrees/feature-x
* chore: remove accidental npm lockfile from PR branch
* chore: bump version to 2.1.10 and update recent updates
---------
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>
* Add GitHub CI workflow for lint, test, and build
Runs on push to main and PRs. Uses Bun with dependency caching.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Remove branch filter on push trigger to run CI on all branches
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Use bun test in CI test job
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Matthew Breedlove <sirmalloc@gmail.com>