Conversation
Add a disabled-by-default remote TUI bridge that can mirror and control live TUI sessions from a separate client without stealing the local TUI transport. The bridge uses explicit config/env enablement, loopback-first defaults, token validation for non-loopback binds, host/origin checks, and a bridge-scoped RPC allowlist. Also add reconnect hydration from the display journal, active-turn peer prompt handling, and regression coverage across backend gateway and TUI event handling paths.
Refresh PR NousResearch#35993 without rewriting branch history. Resolves current main conflicts while preserving the remote bridge behavior and mobile-control additions.
teknium1
reviewed
Jul 13, 2026
teknium1
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for the substantial opt-in bridge work. It needs a targeted salvage onto current main rather than a direct application.
Problems
- The PR’s
prompt.submitbusy path returns4009unless its new interrupt option is set. Current main routes busy submits through_handle_busy_submitattui_gateway/server.py:8447-8452specifically to avoid dropping mid-turn prompts. The remote peer flow must be composed with that current path. tui_gateway/remote_bridge.py:163-178andcli-config.yaml.example:916-921make the enable flag, host, port, path, and origins publicHERMES_*overrides.AGENTS.md:102-107requires those non-secret behavioral settings to live inconfig.yaml.
Suggested changes
- Preserve
_handle_busy_submitsemantics and add peer-fanout coverage for its queued/default busy path. - Remove public non-secret environment overrides; keep bridge behavior in
tui_remote_bridgeconfig, with only credential handling separated as appropriate.
Automated hermes-sweeper review.
| node = {} | ||
|
|
||
| enabled = _cfg_bool(node, "enabled", False) | ||
| env_enabled = ( |
Collaborator
There was a problem hiding this comment.
This introduces public HERMES_* controls for a feature flag and behavioral settings (host, port, path, origins). AGENTS.md:102-107 requires those to be configured through config.yaml; keep the direct environment mechanism only for credentials or an internal child-process handoff.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds an opt-in remote TUI bridge listener so a separate client can attach to live TUI sessions without taking ownership away from the local terminal UI.
The bridge is intentionally conservative:
/api/wsbehaviorIt also handles the TUI-side live-session edge cases needed for mobile/remote control:
Related Issue
No dedicated tracking issue yet.
Related but separate open PRs:
/api/wsattach hardening. This PR is complementary; it adds an opt-in in-process listener for a running TUI gateway.Type of Change
Changes Made
tui_gateway/remote_bridge.py: add the optional remote bridge listener, token/host/origin validation, and bridge method allowlist wiring.tui_gateway/ws.py: make RPC method allowlisting caller-scoped so bridge policy does not regress dashboard/api/wsclients.tui_gateway/server.py: add remote transport fanout, bridge lifecycle handling, display-journal reconnect hydration, and peer prompt handling during active turns.tui_gateway/entry.py: start the bridge listener from TUI gateway config when enabled.hermes_cli/config.pyandcli-config.yaml.example: document remote bridge config/env defaults.tools/approval.py: preserve bridge/client context through approval flows.ui-tui/src/app/*andui-tui/src/gatewayTypes.ts: handle bridge gateway events and peer prompt/turn-boundary behavior in the TUI client.tests/tui_gateway/test_remote_bridge.py,tests/test_tui_gateway_server.py, andui-tui/src/__tests__/createGatewayEventHandler.test.ts: add backend and frontend regression coverage.How to Test
Focused checks run from
~/Code/hermes-tui-remote-bridge:Python compile check:
Config parse check:
Focused backend tests:
Result:
211 tests passed, 0 failed.Focused TUI tests:
npm --prefix ui-tui test -- createGatewayEventHandlerResult:
53 tests passed.Windows-footgun check:
Result:
No Windows footguns found.Whitespace check:
Result: clean.
Full-suite note: I also tried
scripts/run_tests.shacross the whole repository. It does not currently complete in this local checkout because unrelated files fail outside this PR's diff, mostly from missing optional/local dependencies (acp,websockets,ptyprocess) and local environment-sensitive tests. None of the full-suite failing files intersect this PR's changed file list. The focused backend/frontend suites above cover the changed TUI gateway and bridge paths.Checklist
Code
pytest tests/ -qand all tests pass — full suite attempted locally but blocked by unrelated environment/dependency failures; see note aboveDocumentation & Housekeeping
cli-config.yaml.examplefor the new config keysCONTRIBUTING.md/AGENTS.mdupdates are N/AScreenshots / Logs
No screenshots; this is backend bridge plumbing plus TUI event handling. Focused command output is summarized in the test plan above.