Skip to content

fix(cli): preserve resize renderer state - #33649

Closed
H-Ali13381 wants to merge 1 commit into
NousResearch:mainfrom
H-Ali13381:fix/tui-resize-classic-cli
Closed

fix(cli): preserve resize renderer state#33649
H-Ali13381 wants to merge 1 commit into
NousResearch:mainfrom
H-Ali13381:fix/tui-resize-classic-cli

Conversation

@H-Ali13381

@H-Ali13381 H-Ali13381 commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Classic prompt_toolkit CLI resize recovery could leave stale prompt/input glyphs after narrowing the terminal. The artifacts were visual terminal cells, not text inserted into the prompt buffer.

This patch keeps prompt_toolkit's renderer cursor cache intact until its original resize handler runs, and factors the input-height estimate into a tested helper that matches prompt_toolkit's prompt wrapping behavior.

Problem

Hermes wrapped prompt_toolkit's resize handler to recover from footer/input artifacts. The wrapper reset the renderer and invalidated the app before calling prompt_toolkit's original resize handler.

That order is unsafe: prompt_toolkit's Application._on_resize() begins by erasing the current rendered screen from the renderer's cached cursor position. If Hermes resets that renderer state first, prompt_toolkit can lose the live prompt origin and stale prompt glyphs can remain after a narrow resize.

The input-height estimator had a related narrow-terminal issue: it subtracted prompt width from every wrapped row and replaced very small widths with a fake wide fallback. prompt_toolkit's BeforeInput prompt only consumes cells on logical line 0; wrapped continuation rows use the full terminal width.

What changed

  • Let prompt_toolkit's original resize handler run with renderer cursor state intact.
  • Keep resize status-bar suppression so footer/status chrome does not get redrawn into scrollback immediately after column shrink.
  • Add _estimate_tui_input_height() for classic CLI input-height calculation.
  • Use prompt_toolkit cell widths for wide characters.
  • Count prompt width only on logical line 0.
  • Clamp transient zero-column terminal reports to one cell instead of substituting a fake wide width.
  • Replace duplicated test-local input-height logic with direct regression tests for the shared helper.

Compatibility notes

  • This is scoped to the classic prompt_toolkit CLI path.
  • The Ink/React hermes --tui path is not changed.
  • Explicit full-screen redraw behavior remains unchanged; _force_full_redraw() still resets renderer state after clearing the screen.
  • Resize recovery still avoids clearing the physical screen or scrollback, preserving the startup banner and prior output.

Test plan

  • RED check: with only the new tests applied, targeted tests failed as expected:
    • resize test observed renderer_reset, invalidate, original_resize instead of only original_resize
    • input-height tests failed because _estimate_tui_input_height() did not exist
  • python -m py_compile cli.py
  • targeted regression nodes: 4 passed
  • canonical focused runner:
    • scripts/run_tests.sh tests/cli/test_cli_force_redraw.py tests/cli/test_cli_status_bar.py tests/cli/test_cli_terminal_response_sanitizer.py
    • 63 tests passed, 0 failed
  • git diff --check

Manual smoke test

Launch the classic CLI, type or paste a long single-line prompt without submitting, resize the terminal narrow enough that the input wraps, then resize wider/narrower again.

Expected:

  • no duplicated prompt glyphs or separators;
  • input remains visible and wraps normally;
  • bottom input area is not clipped;
  • startup banner/scrollback is not cleared by resize.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard labels May 28, 2026
@H-Ali13381
H-Ali13381 force-pushed the fix/tui-resize-classic-cli branch from b2658f8 to 2e989a5 Compare June 2, 2026 05:11
@H-Ali13381

Copy link
Copy Markdown
Contributor Author

CI note: the current red check appears unrelated to this resize PR.

The only failing job is test (5), specifically:

tests/agent/test_minimax_provider.py::TestMinimaxM3StaleCacheGuard::test_stale_m3_cache_dropped_and_reresolves_to_1m

It fails with:

assert 512000 == 1000000

I reproduced the same failure on the current upstream main head (272c2f30aa60d6d98b2c97dde6ba42a9231d4f56) with:

scripts/run_tests.sh tests/agent/test_minimax_provider.py

So this looks like inherited upstream metadata/test drift: the test expects MiniMax-M3 to re-resolve to 1_000_000, while the current provider-aware models.dev path returns 512000 for MiniMax-M3. The PR branch itself is rebased onto current main and only changes the classic CLI resize files:

  • cli.py
  • tests/cli/test_cli_force_redraw.py
  • tests/cli/test_cli_status_bar.py

Local focused verification for this resize change passed:

scripts/run_tests.sh tests/cli/test_cli_force_redraw.py tests/cli/test_cli_status_bar.py tests/cli/test_cli_terminal_response_sanitizer.py

Result: 63 tests passed, 0 failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants