Skip to content

fix(tui): register shell hooks and discover plugins at TUI gateway startup#56729

Open
dante32683 wants to merge 1 commit into
NousResearch:mainfrom
dante32683:fix/tui-shell-hook-registration
Open

fix(tui): register shell hooks and discover plugins at TUI gateway startup#56729
dante32683 wants to merge 1 commit into
NousResearch:mainfrom
dante32683:fix/tui-shell-hook-registration

Conversation

@dante32683

Copy link
Copy Markdown

What changed

tui_gateway/entry.py::main() now calls discover_plugins() and agent.shell_hooks.register_from_config() at startup, mirroring the equivalent calls already present in gateway/run.py.

Why

ui-tui's gatewayClient.ts spawns this module directly as a subprocess (spawn(python, ['-m', 'tui_gateway.entry'], ...)), bypassing hermes_cli/main.py's _prepare_agent_startup entirely. That function is the only place discover_plugins() and register_from_config() normally run for CLI-driven agent turns (hermes chat, hermes --tui launched via the CLI arg parser). The gateway process (gateway/run.py) has its own equivalent startup calls for the same reason (it also doesn't go through _prepare_agent_startup), but tui_gateway/entry.py had neither — confirmed via grep, zero hits for either call in the file before this change.

Net effect: shell hooks configured under hooks: in cli-config.yaml silently never registered for anyone using the TUI surface (desktop app or hermes --tui), even though the exact same config works fine for plain CLI chat and the gateway.

Approach

Mirrors gateway/run.py's pattern exactly:

  • discover_plugins() runs first (plugin-defined hooks need discovery to have happened before registration).
  • register_from_config(load_config(), accept_hooks=False)accept_hooks stays False here just like the gateway path; the three opt-in channels (--accept-hooks doesn't apply to this surface, but HERMES_ACCEPT_HOOKS env var and hooks_auto_accept: true in config) are still resolved inside register_from_config itself.
  • Unlike the gateway (which has no TTY), this process nominally could have one, but its stdin is always the JSON-RPC pipe to the TUI frontend, not a real TTY — _prompt_and_record's sys.stdin.isatty() check already handles this safely (returns False, no prompt, just a logged warning), so no interactive-prompt-corrupting-the-protocol risk.
  • Both calls are wrapped in their own try/except (logged, non-fatal), consistent with every other startup call in this file and with gateway/run.py's handling of the same two calls.

Test plan

  • Added tests/tui_gateway/test_entry_shell_hook_registration.py:
    • Asserts main() calls discover_plugins() once and register_from_config() once with the loaded config and accept_hooks=False.
    • Asserts a register_from_config exception doesn't propagate out of main() (startup must not be blocked by a hook-registration failure).
  • Ran the full tests/tui_gateway/ suite locally (261 tests, 23 files) — all green, no regressions.
  • Ran scripts/run_tests.sh against the new file plus the two other entry.py-adjacent test files — all passing.

Fixes the TUI shell-hooks gap noted in passing during an internal audit of Hermes's three startup paths (CLI / gateway / TUI) for this exact call.

…artup

ui-tui's gatewayClient spawns tui_gateway/entry.py directly as a
subprocess (python -m tui_gateway.entry), bypassing
hermes_cli/main.py's _prepare_agent_startup entirely — the only place
discover_plugins() and register_from_config() normally run for
CLI-driven agent turns. gateway/run.py has its own equivalent startup
calls for the same reason, but entry.py had neither, so shell hooks
configured under `hooks:` in cli-config.yaml silently never registered
for anyone using the TUI (desktop app or `hermes --tui`).

Mirrors gateway/run.py's calls: accept_hooks stays False and is
resolved from env/config inside register_from_config, whose TTY
consent prompt already safely no-ops when stdin isn't a TTY (always
true here, since stdin is the JSON-RPC pipe to the TUI).
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/tui Terminal UI (ui-tui/ + tui_gateway/) duplicate This issue or pull request already exists labels Jul 2, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #24237 — both add the identical discover_plugins() + register_from_config(load_config(), accept_hooks=False) block to tui_gateway/entry.py::main() at the same location. #24237 is the earliest open version (superset of hooks-only #13854, adds plugin discovery). Related cluster: #13854, #34112. Maintainer picks the canonical PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants