From 419ab6da28fc5895573f699ae245c681ff3467d2 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 26 Sep 2026 23:48:12 +0530 Subject: [PATCH] fix(gateway): name the display-wake stall in the launchd wrapper docstring; gate the macOS wrapper test with the platforms marker The do shell script wait also stalls external-display wake on macOS 27 (#123595), not only idle CPU; the JXA system() wait removes both. The new lifecycle test used a bare sys.platform skipif, which the OS lanes never import; use @pytest.mark.platforms("macos") so the macOS lane runs it. --- hermes_cli/gateway_launchd.py | 3 ++- tests/hermes_cli/test_gateway_service.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hermes_cli/gateway_launchd.py b/hermes_cli/gateway_launchd.py index bf0c9442d6..5b6ab34465 100644 --- a/hermes_cli/gateway_launchd.py +++ b/hermes_cli/gateway_launchd.py @@ -226,7 +226,8 @@ def launchd_program_arguments(command: list[str], stdout_log: Path, stderr_log: executable). Standard Additions' ``do shell script`` polls WindowServer for a user-cancel event while it waits. - That is appropriate for a short interactive script but burns CPU for the gateway's process lifetime. + That is appropriate for a short interactive script but, for the gateway's process lifetime, burns CPU + and keeps a WindowServer event connection busy (external-display wake stalls ~10s on macOS 27, #123595). JXA calling libc ``system()`` waits in the kernel instead while retaining osascript as the responsible process. The shell's ``exec`` keeps the gateway in the launchd job's process group, so ``launchctl bootout`` / ``kickstart -k`` still deliver SIGTERM to it. stdout/stderr are appended inside the shell diff --git a/tests/hermes_cli/test_gateway_service.py b/tests/hermes_cli/test_gateway_service.py index 4454580bac..bf8f8b3bfe 100644 --- a/tests/hermes_cli/test_gateway_service.py +++ b/tests/hermes_cli/test_gateway_service.py @@ -1782,7 +1782,7 @@ class TestProfileArg: # The wrapper's own ps line must never be taken for the gateway (stop/status would signal osascript). assert status.looks_like_gateway_command_line(" ".join(program_args)) is False - @pytest.mark.skipif(sys.platform != "darwin", reason="osascript is macOS-only") + @pytest.mark.platforms("macos") def test_launchd_osascript_wrapper_preserves_process_group_and_exit_status(self, tmp_path): """The non-polling JXA wait keeps lifecycle signals and KeepAlive failure semantics intact.""" stdout_log = tmp_path / "stdout.log"