hermes - 💡(How to fix) Fix fix(tui): clampStdoutDimensions (#35657) breaks TUI layout in Warp terminal

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

clampStdoutDimensions() in ui-tui/src/entry.tsx uses Object.defineProperty to override process.stdout.columns and process.stdout.rows with clamping getters via findDescriptor(), which walks the prototype chain to find the original property descriptor.

Warp's process.stdout object is not a standard Node TTY stream — it's wrapped by Warp's own terminal emulation layer. The Object.defineProperty override changes how Ink reads terminal dimensions, causing the FlexBox layout inside AlternateScreen to miscalculate vertical space allocation. The StatusRule (status bar) and TextInput (prompt) end up at the same Y position in the screen buffer.

Fix Action

Fix / Workaround

The clampStdoutDimensions() approach (patching process.stdout descriptors) is fragile because terminal emulators implement process.stdout differently. Possible alternatives:

  1. Sanitize at read sites instead of patching globally — add a safeColumns()/safeRows() utility and use it in Ink's handleResize and the renderer, leaving process.stdout untouched.
  2. Guard only in the Ink constructor — clamp the values once when Ink reads them (this.terminalColumns = sanitizeDimension(stdout.columns, ...)), without using Object.defineProperty.
  3. Detect Warp and skip the patch — check for Warp-specific env vars (e.g. TERM_PROGRAM) and skip clampStdoutDimensions() in Warp.

Code Example

-import { clampStdoutDimensions } from './lib/terminalDimensions.js'
+// import { clampStdoutDimensions } from './lib/terminalDimensions.js'

-clampStdoutDimensions()
+// clampStdoutDimensions()
RAW_BUFFERClick to expand / collapse

Bug Description

After PR #35657 (b1d34cf6e) was merged, the TUI layout is broken in Warp terminal. The status bar and input prompt are rendered on the same line — the > prompt symbol appears at the beginning of the status bar text, instead of on a separate line below it.

WezTerm and other terminals are not affected — the issue is Warp-specific.

Root Cause

clampStdoutDimensions() in ui-tui/src/entry.tsx uses Object.defineProperty to override process.stdout.columns and process.stdout.rows with clamping getters via findDescriptor(), which walks the prototype chain to find the original property descriptor.

Warp's process.stdout object is not a standard Node TTY stream — it's wrapped by Warp's own terminal emulation layer. The Object.defineProperty override changes how Ink reads terminal dimensions, causing the FlexBox layout inside AlternateScreen to miscalculate vertical space allocation. The StatusRule (status bar) and TextInput (prompt) end up at the same Y position in the screen buffer.

Steps to Reproduce

  1. Use Warp terminal (maximized, not fullscreen)
  2. Run hermes --tui
  3. Observe that the > prompt symbol appears at the start of the status bar line, not on a separate line below

Environment

  • Terminal: Warp (maximized window)
  • Terminal dimensions: cols: 211, rows: 54, isTTY: true (reported correctly)
  • OS: macOS 26.5
  • Hermes version: v0.15.1 (2026.5.29), commit 02d1da49d
  • Comparison: WezTerm renders correctly with the same code

Verification

Commenting out the clampStdoutDimensions() call in entry.tsx (and its import) fixes the layout in Warp:

-import { clampStdoutDimensions } from './lib/terminalDimensions.js'
+// import { clampStdoutDimensions } from './lib/terminalDimensions.js'

-clampStdoutDimensions()
+// clampStdoutDimensions()

After this change + npm run build in ui-tui/, the TUI renders correctly in both Warp and WezTerm.

Suggested Fix

The clampStdoutDimensions() approach (patching process.stdout descriptors) is fragile because terminal emulators implement process.stdout differently. Possible alternatives:

  1. Sanitize at read sites instead of patching globally — add a safeColumns()/safeRows() utility and use it in Ink's handleResize and the renderer, leaving process.stdout untouched.
  2. Guard only in the Ink constructor — clamp the values once when Ink reads them (this.terminalColumns = sanitizeDimension(stdout.columns, ...)), without using Object.defineProperty.
  3. Detect Warp and skip the patch — check for Warp-specific env vars (e.g. TERM_PROGRAM) and skip clampStdoutDimensions() in Warp.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix fix(tui): clampStdoutDimensions (#35657) breaks TUI layout in Warp terminal