[FEATURE] Re-run statusLine command on terminal resize (SIGWINCH)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
The statusLine command re-runs only on: new assistant message, /compact completion, permission-mode change, vim-mode toggle, and the optional refreshInterval timer (per the "When it updates" section of the statusline docs). Terminal resize is not a trigger.
Since v2.1.153 Claude Code sets COLUMNS/LINES before running the script, which encourages width-adaptive status lines (progress bars, flex layouts, responsive tiers). But when the terminal or pane is resized, the previous render — sized for the old width — stays on screen until the next trigger fires. In an idle session with the default configuration (no refreshInterval), a resized status line stays truncated or wrapped indefinitely; with refreshInterval set, it stays stale for up to the full interval.
The only mitigation today is refreshInterval: 1, which trades a rare event (resize) for constant polling: one subprocess spawn per second per open session, multiplied across tmux/multi-pane fleets — while still leaving up to 1s of visibly broken layout.
Proposed Solution
Treat a terminal dimension change as a status line update trigger: on SIGWINCH (or the equivalent dimension-change detection already used to set COLUMNS/LINES), re-run the statusLine command with the updated values. The existing 300ms debounce and in-flight cancellation semantics can apply unchanged, so rapid drag-resizes batch into one execution.
With this, event-driven configurations (no refreshInterval) stay crisp on resize, and polling configurations can drop back to long intervals.
Alternative Solutions
refreshInterval: 1— works, but worst-case 1s of stale layout plus a ~40ms node spawn every second per open session (measured with a Node-based status line), i.e. continuous CPU churn to catch an event that happens a few times an hour.- Detecting the size from inside the script is impossible by design: output is captured, so
tput cols/ioctl report nothing (documented), and the script only runs when Claude Code invokes it.
Priority
Medium - Would be very helpful
Feature Category
Interactive mode (TUI)
Use Case Example
- Run Claude Code in a tmux/Ghostty split with a width-adaptive status line that sizes meters from
COLUMNS. - Resize the pane (e.g. zoom a split from 220 to 90 columns).
- Today: the status line keeps its 220-column render — clipped or wrapped mid-meter — until the next assistant message or timer tick (10-30s in practice).
- With a resize trigger: one debounced re-run, correct layout within ~350ms, no polling needed.
Additional Context
- Docs "When it updates" lists only new-assistant-message, /compact, permission-mode, vim-mode, and timer triggers;
COLUMNS/LINESsupport (min-version 2.1.153) explicitly directs scripts to be width-aware — resize is the natural missing trigger for that contract. - Observed on Claude Code 2.1.207, macOS (Ghostty + tmux panes).
- A resize-triggered run costs the same as any other trigger (~40ms for a typical Node renderer) and is strictly cheaper than the
refreshInterval: 1workaround it replaces.
3 Comments
Still relevant on 2.1.268.
The docs now tell scripts to read
COLUMNSandLINES, which invites width-adaptive layouts, but the "When it updates" list still has no resize trigger. So a right-anchored segment padded for the old width stays on screen after a drag until the next assistant message.Reproduction:
statusLinecommand that pads toCOLUMNS(printf '%*s' "$COLUMNS" "model"is enough).Scripts cannot work around this from inside the output. Cursor-positioning CSI sequences such as
\e[<col>Gare sanitized (#64565), and leading whitespace is trimmed, so only SGR colors survive.The only workaround today is
refreshInterval: 1, which re-runs the script every second whether or not anything changed. A resize trigger could reuse the existing 300ms debounce, so the script would run once when the drag stops.Still reproducible on 2.1.270, the latest release on npm as of 2026-09-14 (macOS, Terminal.app, native install). Adding measurements of the
refreshIntervalworkaround, and a pointer to where resize handling already exists.What the workaround costs. I use a right-aligned bash status line with
refreshInterval: 5:COLUMNSand the script are fine; the only thing missing is a trigger.Resize handling already exists next door.
subagentStatusLinereceives a documentedcolumnsfield. In the 2.1.270 bundle, the logic that drives it also takes the terminal width as an input, so it re-runs when the width changes. The state changes that trigger a mainstatusLineupdate (token usage, permission mode, vim mode, model, fast mode, effort, thinking, PR status, a new assistant message) don't include the width. Adding it there, behind the existing 300 ms debounce, looks like it would be enough to close this.Still reproducible on 2.1.296 (macOS, native install,
tui: fullscreen). The comments above cover widening; narrowing is worse, because the layout doesn't just sit in the wrong place — it loses content.The status line text is drawn with
wrap: "truncate", which cuts from the end. A line padded to the oldCOLUMNSis wider than the new terminal, so it's truncated from the right with…. With a right-aligned layout, that drops exactly the segments the padding was there to anchor (in my case cache state, model and session cost), while the padding in the middle survives. The row stays like that until the next trigger.Repro:
statusLinecommand that printsleft, then spaces up toCOLUMNS - 4, thenright.left … rightre-laid out at the new width. Actual:left …, andrightis gone until the next assistant message orrefreshIntervaltick.No output-side workaround exists: cursor-positioning CSI is stripped, leading whitespace is trimmed, and right/center alignment was closed as not planned (#64565). So padding to
COLUMNSis the only way to right-align, and it depends on a re-run when the width changes. In 2.1.296 the update triggers are still token usage, permission mode, vim mode, model, fast mode, effort, thinking, PR status and a new assistant message. Adding terminal width there, behind the existing debounce, would fix both directions.