feat(terminal): honor CCSTATUSLINE_WIDTH env var to override probe#380
Merged
sirmalloc merged 3 commits intoMay 17, 2026
Merged
Conversation
Provide an explicit width override so users can bypass the TTY probe entirely when both ancestor-walk and `tput cols` fall through. This is the fallback case the existing probe cannot solve on its own: Claude Code >= 2.1.139 spawns statusline/hooks without terminal access, and in some configurations (IDE integrations, nested shells, certain agent-mode spawn paths) no ancestor process owns a TTY either. The ancestor walk fails, `tput cols` returns 80, and the multi-line layout truncates regardless of the actual iTerm2/terminal width. PR sirmalloc#377 (`stty -F`/`stty -f`) covers the case where an ancestor does hold a TTY but the legacy `< /dev/tty` form errors with ENOTTY. This patch is complementary -- it handles the case where the ancestor walk finds no TTY at all -- and gives users a knob today while upstream work on passing `terminalWidth` via stdin JSON (sirmalloc#308) lands. Change ------ `src/utils/terminal.ts` -- `probeTerminalWidth` now reads `CCSTATUSLINE_WIDTH` before any platform check or probe. A valid positive integer short-circuits with that value; anything else (missing, empty, non-numeric, zero, negative) falls through to the existing probe logic. Usage ----- Set the env var on the statusLine command in `~/.claude/settings.json`: ```json "statusLine": { "type": "command", "command": "CCSTATUSLINE_WIDTH=200 ccstatusline" } ``` Tests ----- Four new cases in `src/utils/__tests__/terminal.test.ts`: - override short-circuits probing entirely - non-positive override (`0`) falls back to probing - non-numeric override falls back to probing - override applies on Windows where probing is otherwise disabled `bunx vitest run src/utils/__tests__/terminal.test.ts` -> 12/12 pass. Full-suite delta vs `main`: 4 new passing tests, zero new failures (the pre-existing 105 env-specific failures in other suites are unchanged on both branches). `bun run lint` -> clean.
Owner
|
Thanks for this, it'll be published in the next release. |
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.
Summary
Adds an explicit width override so users can bypass the TTY probe entirely when both ancestor-walk and
tput colsfall through. SetCCSTATUSLINE_WIDTH=<cols>on the statusLine command, get exactly that width.Motivation
PR #377 (
stty -F/stty -f) closed #376 by fixing the case where an ancestor process holds a TTY but the legacystty size < /dev/ttyform errors withENOTTY(Claude Code ≥ 2.1.139 spawns statusline/hooks without terminal access). That fix lands the common path.It does not cover the case where no ancestor process owns a TTY at all — observed under some Claude Code agent-mode spawn paths, IDE integrations (Cursor, JetBrains plugin), and nested-shell scenarios. The ancestor walk runs out of TTY-bearing PIDs, the
tput colsfallback returns 80, andflexMode: "full-minus-40"truncates the multi-line layout to 40 columns regardless of the real terminal width.Concretely: on CC 2.1.141 + ccstatusline 2.2.17 + a wide iTerm2, the
terminal-widthwidget reportsTerm: 80in this configuration. The fallback totput colsis the symptom; the absence of any TTY ancestor is the root cause.This patch is complementary to #377 — it adds an explicit user-controlled escape hatch for cases the probe cannot solve on its own, and gives users a knob today while upstream work on passing
terminalWidthvia stdin JSON (#308) lands.Change
src/utils/terminal.ts—probeTerminalWidthreadsCCSTATUSLINE_WIDTHbefore any platform check or probe call. A valid positive integer short-circuits with that value. Anything else (missing, empty, non-numeric, zero, negative) falls through to existing logic — no behavior change for users who don't set it.Usage
In
~/.claude/settings.json:(or via a wrapper script, or any other mechanism that sets the env on the spawned process.)
Test plan
Four new cases in
src/utils/__tests__/terminal.test.ts:execSyncis never called)"0") falls back to probing → returns probed width"wide") falls back to probing → returns probed widthcanDetectTerminalWidth()returnstrueandexecSyncis never called)Full-suite delta vs
main: +4 passing tests, 0 new failures. The 105 pre-existing failures inclaude-settings.test.ts,compaction.test.ts,global-command-resolution.test.ts,ClaudeAccountEmail.test.tsreproduce identically onmainand on this branch — they're env-specific (platform/shell paths) and unrelated to terminal probing.Related
terminalWidthin stdin JSON (Pass terminalWidth in custom command stdin JSON #308)Risk
CCSTATUSLINE_WIDTHget identical probe behavior to today.null).