Skip to content

fix(tui): stabilize resize and IME rendering#30775

Open
energypantry wants to merge 1 commit into
NousResearch:mainfrom
energypantry:fix/tui-resize-ime-rendering
Open

fix(tui): stabilize resize and IME rendering#30775
energypantry wants to merge 1 commit into
NousResearch:mainfrom
energypantry:fix/tui-resize-ime-rendering

Conversation

@energypantry

@energypantry energypantry commented May 23, 2026

Copy link
Copy Markdown

Fixes #18449
Refs #5221
Refs #24137

Summary

This patch tightens several related TUI rendering paths that can leave the visible transcript or composer in an inconsistent state after terminal resize or IME-heavy input.

  • add a second delayed alt-screen resize heal so late terminal reflow artifacts are cleared after the first repaint
  • separate rendered input layout from native terminal cursor layout for Apple Terminal pending-wrap/IME preedit behavior
  • make virtual transcript height estimates use the same wrap-ansi semantics as rendered text, including CJK/mixed-width text
  • pass terminal row count into virtual history so sticky tail ranges mount enough rows immediately after resize, before ScrollBox measurement catches up
  • compute ScrollBox scroll height from descendant extents, not only the wrapper Yoga height, so oversized transcript rows are not clipped after resize
  • keep virtual transcript rows/spacers from flex-shrinking, preventing resize from poisoning measured row heights with viewport-sized values

Why

The existing fixes cover pieces of the problem, but resize and IME paths can still diverge:

  • rapid or late terminal resize can leave stale physical cells after Hermes believes the screen is clean
  • Apple Terminal IME preedit can render at the wrong position when the native cursor is parked in a pending-wrap column
  • virtual transcript rows can under-mount after resize when the viewport height changes before measurement state catches up
  • mixed CJK + long token text can be underestimated if height estimates count JS chars instead of terminal cells/wrap behavior
  • after a completed response, reversing terminal width changes or scrolling away/back could expose blank/clipped tail content because ScrollBox treated an overflowing child as only viewport-height

Manual verification

I reproduced the issue locally in a Chinese-language workflow using Apple Terminal with Chinese/CJK mixed output and long Chinese input containing ASCII skill names. Before this patch, resizing the terminal could truncate the visible transcript tail, and submitted Chinese input could leave stale/overlapping text in the composer area. I also reproduced the later post-response case where output looks correct until the terminal is resized in the opposite direction or scrolled away/back to the bottom. After rebuilding and restarting the local Hermes TUI, the same Chinese environment no longer reproduces those rendering artifacts: output remains visible after terminal resize, reverse resize, and scroll-back-to-bottom, and Chinese/mixed-width submitted input no longer overlaps the prompt/composer area.

Tests

  • npm test -- --run packages/hermes-ink/src/ink/scrollbox-overflow.test.tsx src/__tests__/virtualHistoryOffsetCache.test.ts src/__tests__/virtualHeights.test.ts src/__tests__/textInputWrap.test.ts src/__tests__/textInputFastEcho.test.ts src/__tests__/cursorDriftRegression.test.ts packages/hermes-ink/src/ink/terminal.test.ts packages/hermes-ink/src/ink/log-update.test.ts
  • npx prettier --check ui-tui/src/hooks/useVirtualHistory.ts ui-tui/src/app/useMainApp.ts ui-tui/src/__tests__/virtualHistoryOffsetCache.test.ts ui-tui/src/lib/virtualHeights.ts ui-tui/src/lib/inputMetrics.ts ui-tui/src/components/textInput.tsx ui-tui/src/components/appLayout.tsx ui-tui/packages/hermes-ink/src/ink/ink.tsx ui-tui/packages/hermes-ink/src/ink/components/ScrollBox.tsx ui-tui/packages/hermes-ink/src/ink/render-node-to-output.ts ui-tui/packages/hermes-ink/src/ink/scrollbox-overflow.test.tsx
  • npm run build

Note: npm run type-check still fails on pre-existing packages/hermes-ink/src/utils/execFileNoThrow.ts Node overload errors unrelated to this patch.

@energypantry energypantry marked this pull request as ready for review May 23, 2026 06:29
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(ui-tui): rapid terminal resize can still leave corrupted glyphs / scattered letters

2 participants