CLI auto-scroll and refresh interval fixes

NousResearch/hermes-agent · cluster 12884 · hermes cli

Data as of

2 open items. Fix merged in #49056. Check it covers your case.

The short answer

2open issues
0open PRs
9items grouped
Known?
Yes. 9 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #49056. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PR #49056. That is separate from the fix event.
Still open
2 issues and 0 PRs.

Multiple issues and fixes address unwanted automatic scrolling to the bottom in CLI/TUI mode, primarily caused by refresh_interval behavior. One unrelated fix handles a UnicodeDecodeError during post-update config migration.

Open issues2

  • Issue#12884[Bug]: The CLI window always automatically rotate to the bottom
  • Issue#53636Fix: CLI auto-scrolls to bottom every second on Termux/Android (cli_refresh_interval=1.0)

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #49056 fix(cli): make idle refresh_interval configurable, default 0 (no auto-scroll)

    merged to main

    files: cli.py, hermes_cli/config.py, scripts/release.py, tests/hermes_cli/test_config.py

    Show the diff
    • cli.py
      @@ -13527,13 +13527,13 @@ def _get_voice_status():
                   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
    • hermes_cli/config.py
      @@ -1581,6 +1581,12 @@ def _ensure_hermes_home_managed(home: Path):
               # TUI busy indicator style: kaomoji (default), emoji, unicode (braille
               # spinner), or ascii.  Live-swappable via `/indicator <style>`.
               "tui_status_indicator": "kaomoji",
      +        # Seconds between prompt_toolkit redraws in the classic CLI when idle.
      +        # 0 = disabled (no background refresh — the pre-0.15.2 behaviour).
      +        # Positive values e.g. 1.0 keep wall-clock status-bar read-outs
      +        # (idle-since-last-turn) ticking but may fight terminal auto-scroll in
      +        # non-fullscreen mode on some emulators (Xshell, iTerm2, etc.).
      +        "cli_refresh_interval": 0,
               "user_message_preview": {  # CLI: how many submitted user-message lines to echo back in scrollback
                   "first_lines": 2,
                   "last_lines": 2,
    • scripts/release.py
      @@ -1531,6 +1531,7 @@
           "[redacted:email]": "erikengervall",  # PR #28774 (firecrawl integration tag)
           "[redacted:email]": "egilewski",  # PR #30432 (MEDIA path traversal fix, GHSA-jmf9-9729-7pp8)
           "[redacted:email]": "McClean-Edison",  # PR #29817 (register_auxiliary_task plugin API)
      +    "[redacted:email]": "OYLFLMH",  # PR #48312 salvage (cli_refresh_interval config, #48309)
           "[redacted:email]": "SamuelZ12",  # PR #7480 (show recap after in-session resume)
           "[redacted:email]": "daizhonggeng",  # PR #9020 (numbered /resume selection)
           "[redacted:email]": "wanwan2qq",  # PR #10215 (strip brackets/quotes from /resume; gateway session-ID lookup)
    • tests/hermes_cli/test_config.py
      @@ -955,6 +955,16 @@ def test_migrate_to_v15_adds_interim_assistant_message_gate(self, tmp_path):
               assert raw["display"]["interim_assistant_messages"] is True
       
       
      +class TestCliRefreshIntervalConfig:
      +    """Test the CLI refresh_interval config default (#48309)."""
      +
      +    def test_default_config_disables_cli_refresh_interval(self):
      +        """cli_refresh_interval defaults to 0 (disabled) to avoid
      +        background redraws that fight terminal auto-scroll-on-output
      +        in non-fullscreen mode (Xshell, iTerm2, Windows Terminal)."""
      +        assert DEFAULT_CONFIG["display"]["cli_refresh_interval"] == 0
      +
      +
       class TestDiscordChannelPromptsConfig:
           def test_default_config_includes_discord_channel_prompts(self):
               assert DEFAULT_CONFIG["discord"]["channel_prompts"] == {}

5 PRs closed without merging

From the close comments: duplicate 2 · done elsewhere 1 · superseded by another PR 1 · other 1

  • #12886 fix(update): handle UnicodeDecodeError in post-update config migration prompt · superseded by another PR → #68497
  • #12982 fix(ui-tui): prevent stickyScroll re-activation after manual scroll-up · other
  • #48319 fix(cli): make refresh_interval configurable, default to 0 (disabled) · duplicate → #48321, #48319
  • #48321 fix(cli): disable idle refresh_interval in non-fullscreen mode to prevent auto-scroll · duplicate → #48319, #48309
  • #74742 fix(ui-tui): prevent stickyScroll re-activation after manual scroll-up · done elsewhere → #75439, #12884
Closed issues · 1
  • Closed#48309cli`: `refresh_interval=1.0` causes terminal auto-scroll-to-bottom in non-fullscreen mode
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.19: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
hermes cli
Merged PRs
#49056
Closed issues
1
Attempts
5 PRs closed without merging
Fix link checked
19 Jun 2026

For your agent

The same facts, typed.