fix: gateway PID detection fails on Windows (two issues)

- _read_process_cmdline: /proc and 'ps' are unavailable on Windows,
  so process cmdline was always empty. Add psutil fallback (already
  a hard dependency used by _pid_exists in the same module).

- _record_looks_like_gateway: argv paths use backslashes on Windows
  but patterns use forward slashes/dots, so the fallback record check
  always failed. Normalize backslashes to forward slashes before
  matching.

Together these caused get_running_pid() to return None on Windows
even when the gateway process is alive, making the dashboard report
gateway as 'stopped' despite it functioning normally.
This commit is contained in:
Tianyu199509 2026-05-13 23:10:51 -07:00 committed by Teknium
parent 057f5a31d1
commit fd9c1504da

View file

@ -128,6 +128,7 @@ def _read_process_cmdline(pid: int) -> Optional[str]:
On Linux, reads /proc/<pid>/cmdline directly. On macOS and other
platforms without /proc, falls back to ``ps -p <pid> -o command=``.
On Windows (no /proc, no ps), uses psutil.
"""
cmdline_path = Path(f"/proc/{pid}/cmdline")
try:
@ -150,6 +151,16 @@ def _read_process_cmdline(pid: int) -> Optional[str]:
except (OSError, subprocess.TimeoutExpired):
pass
# Windows fallback: psutil (already used by _pid_exists)
try:
import psutil # type: ignore
proc = psutil.Process(pid)
cmdline_parts = proc.cmdline()
if cmdline_parts:
return " ".join(cmdline_parts)
except Exception:
pass
return None
@ -178,7 +189,8 @@ def _record_looks_like_gateway(record: dict[str, Any]) -> bool:
if not isinstance(argv, list) or not argv:
return False
cmdline = " ".join(str(part) for part in argv)
# Normalize Windows backslashes so patterns match cross-platform.
cmdline = " ".join(str(part) for part in argv).replace("\\", "/")
patterns = (
"hermes_cli.main gateway",
"hermes_cli/main.py gateway",