From afd8b883b3303cf5b2b587d6d84bff1bfe3a9a0b Mon Sep 17 00:00:00 2001 From: Teknium Date: Wed, 1 Apr 2026 01:06:43 -0700 Subject: [PATCH] fix(cli): pin entire TUI to bottom of terminal on startup 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 b18e53077546b..64a028ea79b8d 100644 --- a/cli.py +++ b/cli.py @@ -6343,6 +6343,17 @@ def _build_tui_layout_children( 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). @@ -7569,18 +7580,6 @@ def _expand_ref(m): 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.