Include terminal width in statusLine JSON payload

Resolved 💬 2 comments Opened Apr 22, 2026 by carlospinto4p Closed Apr 22, 2026

Summary

The JSON payload passed to custom statusLine scripts on stdin does not include terminal width, which makes width-aware rendering (progress bars, truncation, adaptive layout) unreliable on a large class of setups. The sibling subagentStatusLine schema already receives a columns field — this request is to surface the same value in the main statusLine payload.

Affected environments

Any configuration where the statusline subprocess has no console/TTY it can query:

  • JetBrains IDE terminals (JediTerm — PyCharm, IntelliJ, WebStorm, RubyMine, etc.) on Windows
  • WSL statusline scripts whose host terminal isn't reachable through the WSL boundary
  • tmux / screen inside a wrapped shell
  • Any piped / redirected invocation

Reproduction

On Windows, run Claude Code inside PyCharm's embedded Git Bash. From a subprocess spawned under the same contract as the statusline command (stdin piped with JSON), every documented width-detection API fails:

| Method | Result |
| --- | --- |
| [Console]::WindowWidth (PowerShell) | throws Invalid handle |
| mode.com con | returns stub 120 |
| AttachConsole walking ancestors | fails — no Windows console in the chain |
| stty size </dev/tty from bash | /dev/tty: No such device or address |
| tput cols | returns stale terminfo default 80 |
| $env:COLUMNS / $env:LINES | unset by JediTerm |
| JediTerm env vars (TERMINAL_EMULATOR, TERM_SESSION_ID) | present, but no width field |

Root cause: claude is launched by an interactive shell that does know its pty size, but that information is never propagated to the pipe-connected subprocesses invoked for the statusline. The information exists on the Claude Code side — it's just not in the JSON contract.

Proposed change

Add terminal dimensions to the main statusLine JSON, mirroring what subagentStatusLine already receives:

{
  "model": { ... },
  "workspace": { ... },
  "context_window": { ... },
  "terminal": {
    "columns": 180,
    "rows": 48
  }
}

A top-level columns field would work too, but a nested terminal block leaves room for future additions (e.g., is_tty, color_depth) without further schema churn.

Why it matters

Without this field, custom statusline authors have three choices, all unpleasant:

  1. Hardcode a width (overflow or underfill on resize)
  2. Require users to maintain a manual config file with their column count (current workaround in my setup — ~/.claude/statusline-width.conf)
  3. Add a PROMPT_COMMAND / PowerShell-profile hook that writes the live width to disk on every prompt — works but requires pressing Enter after a resize, and adds an install-side step that the "custom statusline" feature otherwise advertises as unnecessary

All three degrade the "install and forget" UX. The columns field already flows through internally for subagentStatusLine, so surfacing it in the parent schema should be a small schema addition.

References

  • Docs: https://code.claude.com/docs/en/statusline.mdsubagentStatusLine.columns is documented; main statusLine input schema has no equivalent
  • My investigation and current workaround: a statusline skill that reads ~/.claude/statusline-width.conf as a manual override, which would become obsolete once terminal.columns lands

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗