From 996250d17806aec207030f62b383416925ae788e Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 1 Apr 2026 01:41:09 -0700 Subject: [PATCH] fix(cli): pin entire TUI to bottom of terminal on startup (#4412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the per-response padding from PR #4359 (which created a void between short responses and the prompt) with a one-time initial scroll at session start. Prints terminal_height newlines before the banner so the cursor starts at the bottom row — banner, responses, and prompt all appear pinned to the bottom with empty space above, not below. patch_stdout naturally keeps the prompt at the bottom from there, so no per-response padding is needed. --- cli.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/cli.py b/cli.py index 0469d09b4..8c3fd105b 100644 --- a/cli.py +++ b/cli.py @@ -6345,6 +6345,17 @@ class HermesCLI: def run(self): """Run the interactive CLI loop with persistent input at bottom.""" + # Push the entire TUI to the bottom of the terminal so the banner, + # responses, and prompt all appear pinned to the bottom — empty + # space stays above, not below. This prints enough blank lines to + # scroll the cursor to the last row before any content is rendered. + try: + _term_lines = shutil.get_terminal_size().lines + if _term_lines > 2: + print("\n" * (_term_lines - 1), end="", flush=True) + except Exception: + pass + self.show_banner() # One-line Honcho session indicator (TTY-only, not captured by agent). @@ -7571,18 +7582,6 @@ class HermesCLI: self._agent_running = False self._spinner_text = "" - # Push the input prompt toward the bottom of the - # terminal so it doesn't sit mid-screen after short - # responses. patch_stdout renders these newlines - # above the input area, creating visual separation - # and anchoring the prompt near the bottom. - try: - _pad = shutil.get_terminal_size().lines // 2 - if _pad > 2: - _cprint("\n" * _pad) - except Exception: - pass - app.invalidate() # Refresh status line # Continuous voice: auto-restart recording after agent responds.