Skip to content

feat(terminal): read COLUMNS from Claude Code before probing - #612

Closed
lancemarks wants to merge 1 commit into
sirmalloc:mainfrom
lancemarks:feat/read-columns-env
Closed

lancemarks wants to merge 1 commit into
sirmalloc:mainfrom
lancemarks:feat/read-columns-env

Conversation

@lancemarks

Copy link
Copy Markdown
Contributor

Summary

Claude Code 2.1.153+ sets COLUMNS and LINES to the current terminal size when it runs the status line (changelog, docs: "Sizing output to the terminal"). getTerminalWidth() now reads COLUMNS right after the CCSTATUSLINE_WIDTH override, so on current Claude Code the ancestor walk never runs.

Motivation

Change

src/utils/terminal.ts: after the override block, a positive-integer COLUMNS is memoized and returned. Order is now:

  1. CCSTATUSLINE_WIDTH (explicit user override still wins)
  2. COLUMNS
  3. session "no TTY" cache
  4. native /proc probe → ps/stty walk → tput cols

COLUMNS goes before the cache so that a stale cached "no TTY" result can't hide a real width. Missing, empty, 0, or non-numeric values fall through to the existing path, the same way #380 handles bad input.

LINES is deliberately not read, since nothing in ccstatusline uses terminal height yet.

Test plan

Six new cases in src/utils/__tests__/terminal.test.ts (COLUMNS is also cleared in setup/teardown so an ambient value can't leak into the probe tests):

  • COLUMNS short-circuits probing (no execFileSync calls)
  • CCSTATUSLINE_WIDTH beats COLUMNS
  • COLUMNS=0 / COLUMNS=wide fall back to probing
  • COLUMNS applies on Windows
  • COLUMNS wins over a cached session "no TTY" without touching the cache
$ bun test
 2364 pass
 0 fail
$ bun run lint   # clean

The three behavior cases fail against main, and the fallback and precedence cases pass on both.

Risk

  • If someone exports COLUMNS in their shell rc and runs Claude Code older than 2.1.153, the status line inherits that fixed value where the probe used to find the live width. This is the same trust tput cols (the existing last fallback) already gives COLUMNS through ncurses, and CCSTATUSLINE_WIDTH still overrides it.
  • The TUI reads process.stdout.columns and never calls this path, so it's unchanged.

Claude Code 2.1.153+ sets COLUMNS (and LINES) to the terminal size when it
runs the status line. Reading it after CCSTATUSLINE_WIDTH and before the
session cache skips the ps/stty ancestor walk on macOS/BSD and gives
Windows a width without an override. Invalid values fall through to probing.
@eric-engberg

Copy link
Copy Markdown
Contributor

In case it's useful: #331 is working on the Windows side of the same problem, with a PowerShell probe that reads the console width from the claude.exe ancestor. It doesn't depend on COLUMNS, so it would also cover older Claude Code versions on Windows, and it handles the TUI side too (a process.stdout.columns path, and removing the Items Editor warning about width detection). The two look like they could fit together, with COLUMNS first and that probe as a fallback.

@jcmecham

jcmecham commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Confirmed working on Windows.

Setup: Windows 11 (10.0.26200), Windows Terminal 1.24.12741.0, Claude Code 2.1.301, Node 22.20.0, this branch at 3a314da, built with bun run build.

  • Claude Code passes COLUMNS on Windows. I logged the env from a status line command: COLUMNS/LINES are set (e.g. 209/51), while process.stdout.columns is undefined, so COLUMNS is the only width source there.
  • This branch: with flex separators on both lines, each line fills the terminal and the right-hand groups follow the window edge on resize. src/utils/__tests__/terminal.test.ts passes (28/28) on Windows.
  • main (bed8501), same config: no width is detected, and both flex separators fall back to |, so the lines stay packed to the left.

I've closed #331 in favor of this.

@sirmalloc

Copy link
Copy Markdown
Owner

Incorporated into #765 and merged.

@sirmalloc sirmalloc closed this Oct 30, 2026
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.

4 participants