core/tools/process: skip host TTY restore when no PTY closed

This commit is contained in:
2026-07-18 16:14:19 +08:00
parent c8a0aeda8d
commit 896dc98d20
2 changed files with 21 additions and 5 deletions
+7 -5
View File
@@ -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:
+14
View File
@@ -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