feat(dashboard): add --stop and --status flags (#17840)

`hermes dashboard` is a long-lived foreground server that users often
start and forget about, sometimes in a shell they've since closed.  We
didn't have a way to stop it — users had to find the PID manually.

Adds two lifecycle flags that reuse the same detection + termination
path the post-`hermes update` cleanup (PR #17832) uses:

  hermes dashboard --status
    List running hermes dashboard processes with PID + cmdline.
    Exit 0, informational.

  hermes dashboard --stop
    Terminate all running dashboards (3s grace then force-kill survivors).
    Exit 0 if none remain, 1 if any couldn't be stopped.
    Windows uses `taskkill /F` as before.

Both flags short-circuit before any fastapi/uvicorn import so they work
even on installations where the dashboard extras aren't installed —
useful when you're cleaning up after uninstalling.

The kill helper gained an optional `reason=...` param so the output
reads "(requested via --stop)" instead of the post-update-specific
"running backend no longer matches the updated frontend" wording.

E2E: `hermes dashboard --status` with nothing running prints the
empty message; with a fake `hermes dashboard ...` cmdline spawned via
`exec -a`, `--status` lists it, `--stop` terminates it (exit -15),
and a follow-up `--status` returns empty.
This commit is contained in:
Teknium 2026-04-30 02:30:20 -07:00 committed by GitHub
parent 2facea7f71
commit 0ad4f55aa8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 263 additions and 13 deletions

View file

@ -189,7 +189,7 @@ class TestKillStaleDashboardPosix:
assert not any(sig == _signal.SIGKILL for _, sig in killed_signals)
out = capsys.readouterr().out
assert "Stopping 2 stale dashboard" in out
assert "Stopping 2 dashboard" in out
assert "✓ stopped PID 12345" in out
assert "✓ stopped PID 12346" in out
assert "Restart the dashboard" in out