Skip to content

feat(widgets): add a Fast Mode widget - #754

Merged
sirmalloc merged 2 commits into
sirmalloc:mainfrom
eric-engberg:feat/fast-mode-widget
Oct 29, 2026
Merged

sirmalloc merged 2 commits into
sirmalloc:mainfrom
eric-engberg:feat/fast-mode-widget

Conversation

@eric-engberg

Copy link
Copy Markdown
Contributor

What

A Fast Mode widget shows whether Claude Code's fast mode is on. By default it renders ⚡ on or ⚡ off; f cycles to an icon with a state dot (⚡ ◉ / ⚡ ○), plain text (on / off) and fast on / fast off, and n swaps in Nerd Font flash icons. Its hide option, "when fast mode is off", leaves only the on state on the line.

Why

Claude Code reports fast mode in the status line payload, but nothing in ccstatusline showed it:

{ "model": { "id": "claude-opus-4-6", "display_name": "Opus 4.6" }, "fast_mode": true }

Fast mode changes how quickly and expensively a session runs, and it's easy to lose track of after toggling it with /fast. The status line is the natural place to see it, next to the model and effort.

How

  • src/widgets/FastMode.ts follows Voice Status: the same shared format-options helpers for f and n, the same raw value behavior (only the label part goes: on / off, or the state dot or icon in the icon format), and the same Nerd Font rules (n is offered only where an icon shows). The Nerd Font pair is nf-md-flash / nf-md-flash_off.
  • The hide option uses the existing hideable-state mechanism (h in the line editor), off by default, so the widget shows both states unless you choose otherwise.
  • It reads fast_mode from the payload only: no settings files, no transcript, no subprocess. Without the field (older Claude Code versions), it renders nothing.
  • fast_mode is added to StatusJSONSchema as an optional, nullable boolean. A malformed value is dropped instead of failing validation, since a schema failure blanks the whole status line for a field only this widget reads.
  • The TUI preview shows the on state, as Voice Status does.
  • Docs: a Fast Mode entry in the widget list and its keys in the shortcuts list (docs/USAGE.md).

Demo

Adding Fast Mode with the picker's search, then cycling its formats with f (icon, text, word, back to icon plus text) and turning on the Nerd Font icon with n. The preview shows the widget's sample, on.

Powerline

Adding Fast Mode and cycling its formats, Powerline mode

Plain

Adding Fast Mode and cycling its formats, plain mode

Piped through the real CLI with fast_mode true, false and absent. Line 1 uses the default format; line 2 uses fast on/off with "when fast mode is off" checked, so it drops out when fast mode is off. VHS's terminal draws ⚡ as a narrow text glyph, so it looks followed by an extra space here; terminals that draw it as an emoji (iTerm2, Terminal.app, Ghostty, kitty, WezTerm) show ⚡ on.

Powerline

Fast Mode with fast_mode true, false and absent, Powerline mode

Plain

Fast Mode with fast_mode true, false and absent, plain mode

Testing

  • bun run lint passes; bun test: 3213 pass, 0 fail across 179 files.
  • New tests: src/widgets/__tests__/FastMode.test.ts (metadata, keybinds, every format on and off with and without the Nerd Font icon, raw value in every format, hide when off, preview, missing or null fast_mode) and three StatusJSON tests (true, null, and a malformed value dropped while the rest of the payload parses).
  • Under Node (Vitest 5, Node 26.10.0): the new and related test files pass, 60 of 60. The full suite fails the same 186 tests in the same 18 files as main (all from spying on Node built-ins); no new failing files.
  • Built CLI under Bun 1.4.2 and Node 26.10.0: with the baseline configs, all runtimes agree and match main in plain and Powerline modes; with a Fast Mode config and fast_mode true and false, all runtimes agree byte for byte (⚡ on / ⚡ off, and the hidden-when-off widget drops out). The TUI opens and exits cleanly under both.

Claude Code reports whether fast mode is on in the status line payload
(fast_mode), but nothing showed it. Fast Mode renders it like Voice
Status: icon plus text (⚡ on / ⚡ off) by default, an icon with a state
dot, plain text, or "fast on/off", with optional Nerd Font flash icons.
It can hide while fast mode is off, and renders nothing when the payload
has no fast_mode (older Claude Code).

A malformed fast_mode is dropped instead of failing the payload, so the
rest of the status line still renders.
@sirmalloc
sirmalloc merged commit 5369c7c into sirmalloc:main Oct 29, 2026
3 checks passed
axisrow added a commit to axisrow/ccstatusline that referenced this pull request Oct 29, 2026
sirmalloc#755 live picker preview, sirmalloc#754 fast mode widget, sirmalloc#753 thinking-effort test stub, sirmalloc#752 transcript block fallback fixes, sirmalloc#751 editor keys no longer pause on global install lookup, sirmalloc#750 git cache TTL starts after the run, sirmalloc#749 npx cache skip, sirmalloc#747 Block Usage hides at 100% and swaps with Block Reset Timer)

Conflict policy: upstream infra wins, fork features ported on top. Joins:
sirmalloc#750 stamps the git cache after the run while keeping the fork's execGit
hardening/env snapshot and daemon prefetch bookkeeping; sirmalloc#752's
isApiErrorMessage guard lands in the fork's shared collectTimestampFromLine
(sync + async twins), upstream's duplicate getActivityTimestamp dropped;
sirmalloc#747 adds SESSION_AT_LIMIT alongside the fork's zero hide state
(BlockResetTimer keeps zero + under-limit via isAtSessionLimit, SessionUsage
is no-data/zero/at-limit); sirmalloc#755 replaces the fork's picker window + "Showing
X-Y of N" note with upstream's renderWindowedList/getPickerMaxVisible and
live preview (markers ↑/↓ N more cover the counts); sirmalloc#751's installationState
useMemo replaces the fork's inline lookups, the fork's mainMenuIndex helper
is kept.

Co-Authored-By: Claude Code <noreply@anthropic.com>
pcvelz added a commit to pcvelz/ccstatusline-usage that referenced this pull request Oct 29, 2026
Upstream: Extra Usage Limit widget (sirmalloc#756), live widget preview while picking (sirmalloc#755), Fast Mode widget (sirmalloc#754), transcript block fallback fixes (sirmalloc#752), editor keys on a global install (sirmalloc#751), git cache TTL (sirmalloc#750), npx cached copy skip (sirmalloc#749), Block Usage hide at 100% (sirmalloc#747), Block Reset Timer hide until 100% (sirmalloc#697), fish-style branch abbreviation (sirmalloc#614), jj detached HEAD (sirmalloc#705), hooks save warning (sirmalloc#703), dev reload (sirmalloc#700), merge ends at a hidden widget (sirmalloc#698), Block Forecast and Block Limit Timer widgets (sirmalloc#699), contributor guide (sirmalloc#706), POSIX path case fix (sirmalloc#707), whitespace-distinct conflict filenames (sirmalloc#709), Quick Start reorder (sirmalloc#715), bunx launch guidance (sirmalloc#714), jj diff summary counts (sirmalloc#711), powerline manual separators (sirmalloc#713), keychain credential by account (sirmalloc#532), Keychain probe timeout (sirmalloc#760), usage cache scoped per CLAUDE_CONFIG_DIR (sirmalloc#266), test isolation (sirmalloc#717, sirmalloc#753), dev-dependency bumps (sirmalloc#745)

Conflicts resolved per the standard-resolution table; fork deletions re-applied.

Hand edits outside conflicts:
- src/utils/global-command-resolution.ts: fork-rename (ccstatusline@ -> ccstatusline-usage@ in upstream's new bunx pattern)
- src/utils/__tests__/global-package-manager.test.ts: fork-rename (package dir ccstatusline-usage in upstream's new tests)
- src/utils/usage-fetch.ts: compat fix - cacheUsageData gained a fetchedAtMs arg (upstream sirmalloc#266); adapted the fork-only fetchFreshUsageData call site
- src/utils/__tests__/usage-fetch.test.ts: compat fixes - cache/lock now hashed per CLAUDE_CONFIG_DIR (usageFilePath helper) in four fork tests; upstream fableUsage renamed to fork's weeklyFableUsage; seedUsageCache takes TokenHome
- src/utils/__tests__/usage-prefetch.test.ts: compat fix - mockFetchUsageData renamed to upstream's mockFetchUsage in cleanly-merged tests
- README.md: took upstream's Quick Start move (sirmalloc#715) and dropped the fork's old copy; fork-rename of its ccstatusline@ specifiers; links to fork-deleted docs (docs/USAGE.md, docs/WINDOWS.md) replaced with the fork's inline text
- CONTRIBUTING.md: links to the fork-deleted docs/DEVELOPMENT.md pointed at the README Development section
- docs/test-retirements.md: ledger entries for the 12 upstream test renames (sirmalloc#697, sirmalloc#698, sirmalloc#700, sirmalloc#705, sirmalloc#713, sirmalloc#760)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants