fix(cli): route /sessions and /history through prompt_toolkit-safe printing

Bare print() output is swallowed by patch_stdout while an interactive
prompt_toolkit Application owns the terminal, so /sessions and /history
rendered nothing. Route those emissions through _cprint (prompt_toolkit's
native renderer) when an app is running, and fall back to print otherwise.

Fixes #36815
This commit is contained in:
redactdeveloper 2026-07-01 01:10:48 -07:00 committed by Teknium
parent 081c91c147
commit b94397fe76
2 changed files with 77 additions and 23 deletions

View file

@ -1,3 +1,4 @@
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from cli import HermesCLI
@ -38,6 +39,39 @@ class TestCliResumeCommand:
assert "/resume 2" in output
assert "/resume <session title>" in output
def test_show_recent_sessions_uses_prompt_toolkit_safe_print(self):
cli_obj = _make_cli()
cli_obj._list_recent_sessions = MagicMock(return_value=[
{"id": "sess_002", "title": "Coding", "preview": "build feature", "last_active": None},
])
running_app = SimpleNamespace(_is_running=True)
with (
patch("prompt_toolkit.application.get_app_or_none", return_value=running_app),
patch("cli._cprint") as mock_cprint,
):
shown = cli_obj._show_recent_sessions(reason="sessions")
assert shown is True
printed = "\n".join(call.args[0] for call in mock_cprint.call_args_list)
assert "Recent sessions" in printed
assert "Coding" in printed
def test_show_history_uses_prompt_toolkit_safe_print(self):
cli_obj = _make_cli()
cli_obj.conversation_history = [{"role": "user", "content": "Hello"}]
running_app = SimpleNamespace(_is_running=True)
with (
patch("prompt_toolkit.application.get_app_or_none", return_value=running_app),
patch("cli._cprint") as mock_cprint,
):
cli_obj.show_history()
printed = "\n".join(call.args[0] for call in mock_cprint.call_args_list)
assert "Conversation History" in printed
assert "Hello" in printed
def test_handle_resume_by_index_switches_to_numbered_session(self):
cli_obj = _make_cli()
cli_obj._list_recent_sessions = MagicMock(return_value=[