diff --git a/agent/display.py b/agent/display.py index 0da773395..9ef8c5ebc 100644 --- a/agent/display.py +++ b/agent/display.py @@ -182,9 +182,8 @@ class KawaiiSpinner: frame = self.spinner_frames[self.frame_idx % len(self.spinner_frames)] elapsed = time.time() - self.start_time line = f" {frame} {self.message} ({elapsed:.1f}s)" - # Use \r + ANSI erase-to-EOL in a single write to avoid the - # two-phase clear+redraw that flickers under patch_stdout. - self._write(f"\r\033[K{line}", end='', flush=True) + pad = max(self.last_line_len - len(line), 0) + self._write(f"\r{line}{' ' * pad}", end='', flush=True) self.last_line_len = len(line) self.frame_idx += 1 time.sleep(0.12) @@ -204,7 +203,10 @@ class KawaiiSpinner: self.running = False if self.thread: self.thread.join(timeout=0.5) - self._write('\r\033[K', end='', flush=True) + # Clear the spinner line with spaces instead of \033[K to avoid + # garbled escape codes when prompt_toolkit's patch_stdout is active. + blanks = ' ' * max(self.last_line_len + 5, 40) + self._write(f"\r{blanks}\r", end='', flush=True) if final_message: self._write(f" {final_message}", flush=True) diff --git a/hermes_cli/tools_config.py b/hermes_cli/tools_config.py index c33a29f1f..9ad8202b9 100644 --- a/hermes_cli/tools_config.py +++ b/hermes_cli/tools_config.py @@ -136,9 +136,6 @@ def _prompt_choice(question: str, choices: list, default: int = 0) -> int: def _prompt_toolset_checklist(platform_label: str, enabled: Set[str]) -> Set[str]: """Multi-select checklist of toolsets. Returns set of selected toolset keys.""" - print(color(f"Tools for {platform_label}", Colors.YELLOW)) - print(color(" SPACE to toggle, ENTER to confirm.", Colors.DIM)) - print() labels = [] for ts_key, ts_label, ts_desc in CONFIGURABLE_TOOLSETS: @@ -154,6 +151,12 @@ def _prompt_toolset_checklist(platform_label: str, enabled: Set[str]) -> Set[str menu_items = [f" {label}" for label in labels] + title_lines = [ + f"Tools for {platform_label}", + " SPACE to toggle, ENTER to confirm.", + "", + ] + menu = TerminalMenu( menu_items, multi_select=True, @@ -166,8 +169,8 @@ def _prompt_toolset_checklist(platform_label: str, enabled: Set[str]) -> Set[str menu_cursor_style=("fg_green", "bold"), menu_highlight_style=("fg_green",), cycle_cursor=True, - clear_screen=False, - clear_menu_on_exit=False, + clear_screen=True, + title="\n".join(title_lines), ) menu.show() @@ -181,6 +184,9 @@ def _prompt_toolset_checklist(platform_label: str, enabled: Set[str]) -> Set[str except (ImportError, NotImplementedError): # Fallback: numbered toggle + print(color(f"Tools for {platform_label}", Colors.YELLOW)) + print(color(" SPACE to toggle, ENTER to confirm.", Colors.DIM)) + print() selected = set(pre_selected_indices) while True: for i, label in enumerate(labels):