From 896dc98d20a7faac52ea974ba0edfae98707e0d5 Mon Sep 17 00:00:00 2001 From: worldmozara Date: Sat, 18 Jul 2026 16:14:19 +0800 Subject: [PATCH] core/tools/process: skip host TTY restore when no PTY closed --- src/plyngent/tools/process/pty_session.py | 12 +++++++----- tests/test_tools/test_process.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/plyngent/tools/process/pty_session.py b/src/plyngent/tools/process/pty_session.py index 27de518..62897ab 100644 --- a/src/plyngent/tools/process/pty_session.py +++ b/src/plyngent/tools/process/pty_session.py @@ -330,7 +330,7 @@ class PtyManager: message="unknown session", ) if session.closed: - restore_host_terminal() + # No host restore: no child was torn down this call. return PtyCloseResult( session_id=session_id, closed=True, @@ -387,14 +387,16 @@ class PtyManager: @classmethod def close_all(cls) -> None: - """Close every session (each close restores the host TTY best-effort).""" + """Close every open session. + + Host TTY restore runs only when at least one session was actually closed + (via :meth:`close`). Empty registry is a no-op — important so Ctrl-D / + chat exit does not flash-reset the terminal when no PTY was used. + """ with cls._lock: ids = list(cls._sessions.keys()) for session_id in ids: _ = cls.close(session_id) - # Extra restore if the registry was already empty. - if not ids: - restore_host_terminal() def format_read_result(result: PtyReadResult) -> str: diff --git a/tests/test_tools/test_process.py b/tests/test_tools/test_process.py index 2d36c0a..c663fe9 100644 --- a/tests/test_tools/test_process.py +++ b/tests/test_tools/test_process.py @@ -321,6 +321,20 @@ def test_sanitize_pty_output_escapes_csi() -> None: assert "hello" in safe +def test_close_all_empty_does_not_restore(monkeypatch: pytest.MonkeyPatch) -> None: + """Ctrl-D / chat exit calls close_all with no sessions — must not flash TTY.""" + import plyngent.tools.process.pty_session as ps + + calls: list[int] = [] + + def fake_restore() -> None: + calls.append(1) + + monkeypatch.setattr(ps, "restore_host_terminal", fake_restore) + PtyManager.close_all() + assert calls == [] + + def test_restore_host_terminal_noop_when_not_tty(monkeypatch: pytest.MonkeyPatch) -> None: import sys