Bug Description
hermes gateway stop (or work gateway stop) kills gateway processes for ALL profiles, not just the current one.
Root Cause
find_gateway_pids() in hermes_cli/gateway.py (line 31) searches ps aux output for generic patterns like:
hermes_cli.main gateway
hermes gateway
gateway/run.py
These patterns match all gateway processes regardless of which HERMES_HOME/profile they belong to. When multiple profiles are running (e.g. default + work), stopping one kills all of them.
Impact
On macOS, the gateway_command() stop handler (line 1915) correctly uses profile-scoped launchctl stop via launchd_stop() with the right label (ai.hermes.gateway vs ai.hermes.gateway-work). However, it then unconditionally calls kill_gateway_processes() on line 1933, which sweeps ALL gateway PIDs without profile filtering.
Environment
- macOS (launchd)
- Two profiles running: default (
ai.hermes.gateway) and work (ai.hermes.gateway-work)
- Both share the same ProgramArguments pattern, differing only in HERMES_HOME env var
Suggested Fix
find_gateway_pids() should filter by the current HERMES_HOME — either by:
- Checking the process environment variables for the matching HERMES_HOME
- Reading the PID file from
get_hermes_home() / 'gateway.pid' and only targeting that PID
- Comparing the launchd label in the process command line
Option 2 (PID file) is simplest since get_running_pid() from gateway.status already reads the profile-scoped PID file.
Bug Description
hermes gateway stop(orwork gateway stop) kills gateway processes for ALL profiles, not just the current one.Root Cause
find_gateway_pids()inhermes_cli/gateway.py(line 31) searchesps auxoutput for generic patterns like:hermes_cli.main gatewayhermes gatewaygateway/run.pyThese patterns match all gateway processes regardless of which HERMES_HOME/profile they belong to. When multiple profiles are running (e.g. default +
work), stopping one kills all of them.Impact
On macOS, the
gateway_command()stop handler (line 1915) correctly uses profile-scopedlaunchctl stopvialaunchd_stop()with the right label (ai.hermes.gatewayvsai.hermes.gateway-work). However, it then unconditionally callskill_gateway_processes()on line 1933, which sweeps ALL gateway PIDs without profile filtering.Environment
ai.hermes.gateway) and work (ai.hermes.gateway-work)Suggested Fix
find_gateway_pids()should filter by the currentHERMES_HOME— either by:get_hermes_home() / 'gateway.pid'and only targeting that PIDOption 2 (PID file) is simplest since
get_running_pid()fromgateway.statusalready reads the profile-scoped PID file.