fix(cli): recover classic CLI output after resize#20444
Merged
Conversation
29206394
pushed a commit
to 29206394/hermes-agent
that referenced
this pull request
May 8, 2026
_resize_clear_ghosts (introduced in NousResearch#20444) replays _OUTPUT_HISTORY after every SIGWINCH to recover conversation content lost by the screen clear. This causes a jarring "re-streaming" effect — all recent output lines, including streaming tokens and spinner frames, are reprinted in rapid succession whenever the user maximizes/restores the terminal window (Command+Enter on macOS). Change _recover_after_resize to only clear the screen + reset the renderer, without replaying output history. prompt_toolkit's native _on_resize handler redraws the input area and status bar cleanly. Users who want to see conversation history restored after resize can still press Ctrl+L (/redraw), which calls _force_full_redraw (that path still includes _replay_output_history). Fixes the symptom reported in NousResearch#19280 where resize recovery replays entire conversation as if it were streaming from the beginning.
This was referenced May 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes classic CLI redraw behavior after terminal resize. The prompt_toolkit footer/status chrome was being stamped into normal terminal scrollback during resize storms, and Ctrl+L or
/redrawcould leave the screen blank because previous output was not rebuildable.This change keeps a bounded Hermes-owned output history for the classic CLI, debounces resize recovery, suppresses status/footer invalidates while resize recovery is pending, and rebuilds scrollback from that history after the terminal size settles. The resumed-history panel is stored as a structured renderable history entry so it is re-rendered at the current terminal width instead of replayed as stale terminal bytes.
Related Issue
Related to #19280.
Type of Change
Changes Made
cli.py: add bounded replay history for classic CLI output, including structured renderable entries for resize-aware resume panels.cli.py: debounce resize recovery and suppress footer/status invalidates while resize recovery is pending.cli.py: rebuild terminal scrollback from Hermes-owned history after resize, then repaint the live prompt/footer once at the settled size.hermes_cli/config.py: adddisplay.persistent_outputanddisplay.persistent_output_max_linesdefaults for the replay buffer.tests/cli/test_cli_force_redraw.py: cover redraw ordering, resize debounce behavior, and invalidate suppression during resize recovery.tests/cli/test_cprint_bg_thread.py: cover output-history recording, replay, suppression, and structured render entries.tests/cli/test_resume_display.py: cover storing the resumed-history panel as a resize-aware replay entry.How to Test
Targeted tests run locally:
HERMES_TEST_WORKERS=1 scripts/run_tests.sh tests/cli/test_resume_display.py tests/cli/test_cli_force_redraw.py tests/cli/test_cprint_bg_thread.py tests/cli/test_cli_init.py tests/cli/test_cli_status_bar.py -q→ 115 passedHERMES_TEST_WORKERS=1 scripts/run_tests.sh tests/hermes_cli/test_config_drift.py -q→ 1 passedFull suite run after opening draft PR:
scripts/run_tests.sh→ failed: 49 failed, 19874 passed, 51 skipped, 230 warnings in 614.31stests/gateway/test_approve_deny_commands.py,tests/cron/test_cron_script.py,tests/agent/test_auxiliary_client.py,tests/agent/test_bedrock_1m_context.py,tests/gateway/test_dingtalk.py,tests/hermes_cli/test_update_gateway_restart.py,tests/tools/test_browser_chromium_check.py,tests/tools/test_delegate.py, andtests/tui_gateway/test_goal_command.py.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
Manual reproduction involved Windows Terminal resizing of the classic CLI with a resumed session and live status/footer updates. Targeted and full-suite test output is summarized above.