Repository navigation
fix(tui): stop editor keys pausing on a global ccstatusline install - #751
Merged
Merged
Conversation
When Claude Code runs the global `ccstatusline` command (a pinned install, which is the install menu's default, or a self-managed one), App looked that command up in its render body. The lookup runs `which -a`, `npm prefix -g` and `bun pm bin -g` synchronously, and a pinned install runs `which` and the bin-dir lookup again for the relaunch path. The label editor's live preview and every widget edit redraw App, so each of those keys blocked the TUI for a quarter to half a second on macOS. Keys pressed meanwhile reached Ink as one read, which it parses as a single key or none: of six quick backspaces, two or three took effect. Run the lookups in a memo keyed on what they depend on: the saved installation metadata, Claude's status line command and the install state. They now run once loading finishes, and again after an install, update or uninstall from the TUI, since each changes one of those. The screens show the same thing. Ctrl+S and Check for Updates still look the command up when pressed.
getCurrentInstallation took an isClaudeInstalled flag that switched between two behaviours: with ccstatusline installed in Claude Code, the saved metadata stands in until the status line command is read; otherwise the command alone is classified. Each caller already holds that state, so each now picks: classifyInstalledStatusLine for the installed case, classifyInstallation otherwise. Check for Updates passes the saved metadata as settings?.installation instead of special-casing missing settings, since no saved metadata already classifies the command alone.
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)
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.
What
When Claude Code runs the global
ccstatuslinecommand (a pinned install, which is the install menu's default, or a self-managed one), most keys in the line editor paused the TUI for a quarter to half a second, and keys pressed during the pause could be lost. The TUI now looks up the global command once, and again only when the installation changes, instead of on every redraw.Why (evidence)
Applooked up the global command in its render body.inspectActiveGlobalCommand()runswhich -a ccstatusline,npm prefix -gandbun pm bin -gwithexecFileSync. For a pinned install,getPinnedGlobalRelaunchCommand()also runswhich -aand the bin-dir lookup again, even when no version mismatch is shown.npm prefix -galone takes about 170 ms. The label editor's live preview (#710), every widget edit (r,m,d, move-mode arrows, accepting a label) and every screen change redrawApp, so each of those keys waited for 3 to 5 subprocesses before the preview, and the next key, were handled.Measured in a real pty on macOS (Node 26, Bun 1.4.2). The setup is a scratch HOME with a fake bun global install, and real npm and bun answer the lookups:
r)Keys that arrive during a pause reach Ink in one read. Ink 6.2 parses a read of several backspaces as no key, and several arrows as one. With a pinned install, 6 backspaces 60 ms apart deleted 2-3 characters, and 6 ↓ in move mode moved the widget 2 places.
How
useMemokeyed on what they depend on: the saved installation metadata, Claude Code's status line command, the installed state, and whether loading has finished.classifyInstalledStatusLine()when Claude Code runs ccstatusline andclassifyInstallation()otherwise.What the screens show doesn't change. With pinned, self-managed and version-mismatch setups, Main Menu, Manage Installation and the mismatch screen render byte-for-byte as on
main.Demo
Relabelling Model and Context Length with a pinned global install. Before: backspaces pressed during a pause are dropped, so the old labels aren't fully cleared ("MoChatting with", "Ctcontext used:"). After: every key lands as typed.
Powerline
Before:
After:
Plain
Before:
After:
Testing
mainunder Bun and Node).bun test: 3171 pass, 0 fail.bun run lint: clean.App.test.tsunder Node (vitest): 30/30 (27/27 onmain).dist/under Bun 1.4.2 and Node 26.10.0: piped renders agree and matchmain; the TUI opens and exits.