fix(cli): preserve startup banner on terminal resize

Recover from SIGWINCH without clearing the physical screen or scrollback
buffer. The startup banner and tool summary are printed before
prompt_toolkit owns the live chrome, so they live in normal terminal
scrollback. Calling erase_screen() + \x1b[3J] on every resize removed
that UI permanently — _replay_output_history cannot reconstruct it
because the banner was never added to _OUTPUT_HISTORY.

Instead, just reset prompt_toolkit's renderer cache and invalidate so
the next incremental redraw starts from a clean slate, then let the
original on_resize handler recalculate layout for the new terminal
size. This matches the behaviour of bash/zsh/fish on SIGWINCH.

Fixes NousResearch/hermes-agent#22999
This commit is contained in:
vominh1919 2026-05-10 14:09:22 +07:00 committed by Teknium
parent 59da8ec4ec
commit e2b2d48610
2 changed files with 36 additions and 18 deletions

24
cli.py
View file

@ -2703,9 +2703,27 @@ class HermesCLI:
pass
def _recover_after_resize(self, app, original_on_resize) -> None:
"""Recover a resized classic CLI without desynchronizing cursor state."""
self._clear_prompt_toolkit_screen(app, rebuild_scrollback=True)
_replay_output_history()
"""Recover a resized classic CLI without desynchronizing cursor state.
Unlike _force_full_redraw, we do NOT clear the physical screen or
scrollback here. The startup banner and tool summary are printed
before prompt_toolkit owns the live chrome, so they live in normal
terminal scrollback. Erasing the screen on SIGWINCH removes that
startup UI and ``_replay_output_history`` cannot reconstruct it
(the banner was never added to ``_OUTPUT_HISTORY``).
Instead we just reset prompt_toolkit's renderer cache so the next
incremental redraw starts from a clean slate, then let
``original_on_resize`` recalculate layout for the new size.
"""
try:
app.renderer.reset(leave_alternate_screen=False)
except Exception:
pass
try:
app.invalidate()
except Exception:
pass
original_on_resize()
def _schedule_resize_recovery(self, app, original_on_resize, delay: float = 0.12) -> None: