ctl.sh start only guarded against launchd (macOS). On Linux, with a
systemd-supervised WebUI serving the port and a stale PID file, stop
reported 'stopped', start spawned a bootstrap that died ~2s later on
server.py's 'already responding' check — after the 0.15s aliveness gate
had already printed 'Started' and recorded the doomed PID. Killing the
foreign server by hand then put its supervisor's auto-restart into a
race with ctl.sh's start, ending in a permanent RestartSec crash loop.
- start: refuse when anything answers HTTP(S) on the target port (any
response bytes, matching server.py's abort semantics — a 404 squatter
still dooms our server), and when the hermes-webui systemd unit is
active on our port or mid-auto-restart (activating). Port scoping
mirrors the launchd #3291 over-block fix; overrides:
HERMES_WEBUI_CTL_ALLOW_SYSTEMD_CONFLICT / _ALLOW_PORT_CONFLICT,
unit name via HERMES_WEBUI_SYSTEMD_UNIT.
- start: watch the child through a startup grace window
(HERMES_WEBUI_START_GRACE, default 3s) — report failure and clean the
PID file when it dies during startup; break early once /health answers.
- status/stop: when ctl.sh owns no PID but the port answers, say
'running (not managed by ctl.sh)' with listener diagnostics instead of
'stopped', and never touch the foreign process.
- _pid_listens_on_port: ss fallback for Linux hosts without lsof.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Absorbs #4412 (tomas-forgac) rebased onto fresh master, plus two
Codex-regression-gate fixes: (1) use the scheme that actually answered the
probe for the ready/already-up URL + browser-open, (2) honor an explicit
HERMES_WEBUI_HEALTH_URL override in the WSL autostart probe.
Co-authored-by: tomas-forgac <tomas-forgac@users.noreply.github.com>
Closes#4412
* test(windows): hide test helper console windows (#3706)
* test(windows): use CREATE_NO_WINDOW constant (#3706)
* test(windows): hide test-helper console windows on Windows (#3710fixes#3706)
@rodboev. Long-lived test helper subprocesses (test server, browser-smoke, TLS helper,
ctl helpers) now spawn with CREATE_NO_WINDOW on Windows so a local pytest run doesn't
pop focus-stealing console windows. sys.platform=='win32' guarded → no-op on macOS/Linux
(expands to **{}). Test-only, no production code, no user impact. + CHANGELOG v0.51.301.
---------
Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <[email protected]>
Codex regression gate found the launchd guard blocked ANY ctl.sh start while a
launchd job was live — including a legitimate second instance on a different
port (HERMES_WEBUI_PORT=8788). Now _launchd_webui_pid only treats the launchd
job as a conflict when its PID is actually listening on the requested CTL_PORT
(via a new best-effort _pid_listens_on_port helper using lsof); a different-port
start is allowed. When port ownership can't be determined (no lsof), falls back
to guarding only the default 8787 port so non-default ports are never wrongly
blocked. Adds a different-port-allowed regression test + makes the existing
block test deterministic. Co-authored-by preserved.