diff --git a/cli.py b/cli.py index f6a9393d34a..e0a8676ceee 100644 --- a/cli.py +++ b/cli.py @@ -13527,13 +13527,13 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin): style=style, full_screen=False, mouse_support=False, - # The status bar contains wall-clock read-outs (live prompt elapsed - # and idle-since-last-turn). Once a turn finishes there may be no - # further events to invalidate the app, so prompt_toolkit would keep - # rendering the first post-turn value (usually ``✓ 0s``) forever. - # A low-rate refresh keeps the clock honest without reintroducing a - # custom repaint thread or touching conversation state. - refresh_interval=1.0, + # Read from display.cli_refresh_interval (default 0 = disabled). + # When non-zero, prompt_toolkit redraws the UI on this cadence + # during idle, keeping wall-clock status-bar read-outs ticking. + # Set to 0 to suppress background redraws entirely — avoids + # fighting terminal auto-scroll in non-fullscreen mode (Xshell, + # iTerm2, Windows Terminal). See #48309. + refresh_interval=float(CLI_CONFIG.get("display", {}).get("cli_refresh_interval", 0)), # Erase the live bottom chrome (status bar, input box, separator # rules) on exit instead of freezing a final copy into scrollback. # Without this, prompt_toolkit's render_as_done teardown repaints diff --git a/hermes_cli/config.py b/hermes_cli/config.py index c81df25c03b..3b12cacb37b 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -1581,6 +1581,12 @@ DEFAULT_CONFIG = { # TUI busy indicator style: kaomoji (default), emoji, unicode (braille # spinner), or ascii. Live-swappable via `/indicator