hermes-agent/tui_gateway
0xbyt4 2af0848f3c fix(tui): ignore SIGPIPE so stderr back-pressure can't kill the gateway
Crash-log stack trace (tui_gateway_crash.log) from the user's session
pinned the regression: SIGPIPE arrived while main thread was blocked on
for-raw-in-sys.stdin — i.e., a background thread (debug print to stderr,
most likely from HERMES_VOICE_DEBUG=1) wrote to a pipe whose buffer the
TUI hadn't drained yet, and SIG_DFL promptly killed the process.

Two fixes that together restore CLI parity:

- entry.py: SIGPIPE → SIG_IGN instead of the _log_signal handler that
  then exited. With SIG_IGN, Python raises BrokenPipeError on the
  offending write, which write_json already handles with a clean exit
  via _log_exit. SIGTERM / SIGHUP still route through _log_signal so
  real termination signals remain diagnosable.

- hermes_cli/voice.py:_debug: wrap the stderr print in a BrokenPipeError
  / OSError try/except. This runs from daemon threads (silence callback,
  TTS playback, beep), so a broken stderr must not escape and ride up
  into the main event loop.

Verified by spawning the gateway subprocess locally:
  voice.toggle status → 200 OK, process stays alive, clean exit on
  stdin close logs "reason=stdin EOF" instead of a silent reap.
2026-04-23 16:18:15 -07:00
..
__init__.py feat: new tui based on ink 2026-04-02 19:07:53 -05:00
entry.py fix(tui): ignore SIGPIPE so stderr back-pressure can't kill the gateway 2026-04-23 16:18:15 -07:00
render.py tui: inherit Python-side rendering via gateway bridge 2026-04-05 18:50:41 -05:00
server.py chore(tui): dump gateway crash traces to ~/.hermes/logs/tui_gateway_crash.log 2026-04-23 16:18:15 -07:00
slash_worker.py feat: personality 2026-04-08 00:15:15 -04:00