diff --git a/hermes_cli/memory_setup.py b/hermes_cli/memory_setup.py index 8b076da2884..86e5e1cd6de 100644 --- a/hermes_cli/memory_setup.py +++ b/hermes_cli/memory_setup.py @@ -51,6 +51,14 @@ def _print_cancelled_setup() -> None: print("\n Cancelled. No changes saved.\n") +def _clear_interactive_transition() -> None: + """Clear stale curses content before entering a follow-up setup screen.""" + if not sys.stdout.isatty(): + return + sys.stdout.write("\033[2J\033[H") + sys.stdout.flush() + + def _prompt(label: str, default: str | None = None, secret: bool = False) -> str: """Prompt for a value with optional default and secret masking.""" suffix = f" [{default}]" if default else "" @@ -276,6 +284,8 @@ def cmd_setup(args) -> None: name, _, provider = providers[selected] + _clear_interactive_transition() + # Install pip dependencies if declared in plugin.yaml _install_dependencies(name) diff --git a/tests/hermes_cli/test_memory_setup.py b/tests/hermes_cli/test_memory_setup.py index b458a1d2d6a..689dc670cb4 100644 --- a/tests/hermes_cli/test_memory_setup.py +++ b/tests/hermes_cli/test_memory_setup.py @@ -76,6 +76,25 @@ def test_cmd_setup_builtin_selection_still_saves_builtin(monkeypatch): save_config.assert_called_once_with(config) +def test_cmd_setup_clears_interactive_picker_before_provider_post_setup(monkeypatch): + events = [] + + class PostSetupProvider: + def post_setup(self, hermes_home, config): + events.append("post_setup") + + monkeypatch.setattr(memory_setup, "_get_available_providers", lambda: [("openviking", "local", PostSetupProvider())]) + monkeypatch.setattr(memory_setup, "_curses_select", lambda *args, **kwargs: events.append("select") or 0) + monkeypatch.setattr(memory_setup, "_clear_interactive_transition", lambda: events.append("clear"), raising=False) + monkeypatch.setattr(memory_setup, "_install_dependencies", lambda name: events.append("install")) + monkeypatch.setattr(memory_setup, "get_hermes_home", lambda: "/tmp/hermes-test") + monkeypatch.setattr("hermes_cli.config.load_config", lambda: {"memory": {}}) + + memory_setup.cmd_setup(SimpleNamespace()) + + assert events == ["select", "clear", "install", "post_setup"] + + def test_cmd_setup_generic_choice_cancel_writes_nothing(tmp_path, monkeypatch): class ChoiceProvider: def __init__(self):