Commit Graph

2 Commits

Author SHA1 Message Date
Brooklyn Nicholson 443c104e61 fix(desktop): treat profile=default as this process's own home
_is_other_profile only allowed empty/current, so a ?profile=default
save skipped the session.info broadcast on the process whose config
it just wrote. Compare the resolved target to the process HERMES_HOME.
2026-08-19 01:23:39 -05:00
yoniebans ef9cb96b1a fix(desktop): re-emit session.info when approvals config changes out of band
The desktop settings page saves approvals.mode through REST PUT /api/config
(and the raw editor through PUT /api/config/raw). Enforcement follows the
file immediately, because the approval gate re-reads config per command, but
every live session's YOLO/approval indicator repaints only on a session.info
event, and the REST save emitted nothing. The indicator showed bypass OFF
while approvals.mode=off silently auto-approved every dangerous command, and
switching sessions repainted the stale cached per-session state, making the
toggle look like it flipped itself back. The gateway /approvals slash
command had the same gap.

The config.set RPC handler already re-emits session.info to all live
sessions after a mode flip; give the other writers the same contract:

- tui_gateway/server.py: add broadcast_session_info(), which snapshots
  _sessions under _sessions_lock and re-emits via
  _emit_session_info_for_session. Also call it from the /approvals slash
  mirror when a mode argument was persisted (bare /approvals is read-only).
- hermes_cli/web_server.py: after a REST save that actually changed the
  normalized approvals.mode, call the broadcast through a sys.modules guard
  (no gateway imported means no sessions to notify). The comparison runs on
  the in-memory documents (existing vs merged, parsed vs raw): the settings
  page PUTs the defaulted GET record while disk holds sparse YAML, so a
  block-level compare would broadcast on every autosave, and re-reading
  through the config cache after the save could serve the pre-save document
  on an (mtime_ns, size) key collision. Own-profile saves only: a
  profile-scoped save targets a different HERMES_HOME than this process's
  gateway sessions.

No broadcast on saves that leave the effective mode unchanged, so settings
autosave churn (skin, font, TTS) can't spam session.info.

Scope: reaches sessions of the in-process gateway (hermes serve / hermes
dashboard, the topologies the desktop app talks to). A spawned
tui_gateway.entry child gateway has its own process and _sessions; its TUI
statusbar reconciles each turn via the existing session.info emissions.
2026-08-13 23:52:56 +02:00