hermes-agent/ui-tui/src/__tests__
brooklyn! 1997b3baf8
feat(tui): support attaching to an existing gateway (#21978)
* feat(tui): support attaching to an existing gateway

Allow the TUI gateway client to connect via HERMES_TUI_GATEWAY_URL while preserving spawned gateway fallback, and mirror event frames to sidecar feeds so dashboard tool activity remains visible.

* review(copilot): redact attach URLs and gate stale transport exits

Strip query strings (and any user info) from gateway / sidecar URLs before logging or surfacing them in `gateway.start_timeout`, so attach tokens never leak into the TUI log tail or activity feed. Also gate the spawned-proc and websocket close handlers on transport identity so a stale child or socket cannot clear a freshly-started ready timer or reject newly-issued pending requests during reconnect.

* review(copilot): tighten transport restart and shutdown lifecycle

Reject any in-flight RPCs in resetStartupState so callers do not hang on promises issued to the previous transport when start() swaps a child or socket. Have kill() explicitly reject pending so attach-mode promises drain after an intentional shutdown, and reattach when HERMES_TUI_GATEWAY_URL rotates between requests instead of silently keeping the old session. Fold the spawned child error path through handleTransportExit so a failed spawn clears the startup timer and emits a single exit event. Also null the websocket reference before calling close so the identity guard correctly tags stale close events on real WebSocket timing. Locks the new behaviors in with regression tests for kill, URL rotation, and stale-pending cleanup.

* review(copilot): swallow stray ws connect rejection and isolate test env

Attach a no-op catch handler on the websocket connect promise so an unobserved connect-error / early-close rejection cannot surface as an unhandled promise rejection in Node when no request is currently racing the open. Snapshot HERMES_TUI_GATEWAY_URL / HERMES_TUI_SIDECAR_URL in beforeEach and restore them in afterEach so vitest runs that set those env vars beforehand do not get permanently cleared.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* review(copilot): hoist wire decoder and harden redact fallback

Reuse a single module-level TextDecoder for binary websocket frames so high-frequency attach-mode traffic does not allocate one per message. Strengthen the redactUrl fallback so embedded user:pass@ credentials are also masked when the WHATWG URL parser rejects the input, and pin the new behavior with a regression test that drives a malformed bearer URL through the gateway-stderr publish path.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* review(copilot): force redact fallback path with deterministic fixture

Replace the "%zz" user-info fixture, which WHATWG URL actually accepts in recent Node and silently routed the test back through the structured-URL branch, with a port-99999 fixture that the parser rejects across Node versions. Add a pre-flight `expect(() => new URL(fixture)).toThrow()` assertion so a future URL-parser change can never silently bypass `redactUrl()`'s fallback again.

* review(copilot): sanitize websocket constructor failures

Avoid logging raw WebSocket constructor error messages because some implementations include the full input URL, including token-bearing query strings. Log the redacted gateway or sidecar URL with the error class instead, and add regression coverage for constructor-throw paths on both attach and sidecar sockets.

* review(self): restart transport on attach-mode transition

Route runtime HERMES_TUI_GATEWAY_URL changes through start() so switching from spawned-gateway mode to attach mode also tears down the previously spawned Python child instead of leaving it alive. Keep the existing fast-fail behavior for pending RPCs. Also make constructor-failure logging fully generic after the redacted URL, avoiding even implementation-specific error class text in the log tail.

* review(copilot): use websocket wording for attach close errors

When the attached websocket closes, reject pending RPCs with an explicit websocket-closed reason instead of the spawned-process oriented `gateway exited` wording. Add coverage to ensure close code 1011 surfaces as `gateway websocket closed (1011)`.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-08 12:12:38 -07:00
..
asCommandDispatch.test.ts fix(tui): slash.exec _pending_input commands, tool ANSI, terminal title 2026-04-18 09:30:48 -07:00
clipboard.test.ts fix(tui): improve clipboard copy fallbacks 2026-05-05 03:59:00 -07:00
constants.test.ts test(tui): tighten redraw hotkey review follow-ups 2026-04-27 12:30:40 -05:00
createGatewayEventHandler.test.ts feat(tui): render self-improvement review summaries in the transcript 2026-04-30 14:07:22 -07:00
createSlashHandler.test.ts fix(tui): close slash parity gaps with CLI (#20339) 2026-05-05 15:42:39 -05:00
details.test.ts fix(tui): apply details mode live 2026-04-26 13:34:33 -05:00
emoji.test.ts fix(tui): inject VS16 so text-default emoji render as color glyphs 2026-04-21 15:52:39 -05:00
forceTruecolor.test.ts fix(tui): normalize legacy Terminal.app colors (#17695) 2026-04-29 20:13:49 -07:00
gatewayClient.test.ts feat(tui): support attaching to an existing gateway (#21978) 2026-05-08 12:12:38 -07:00
markdown.test.ts feat(latex): latex in tui 2026-04-28 19:08:11 -04:00
mathUnicode.test.ts fix: account for latex 2026-04-28 21:20:43 -04:00
messages.test.ts fix(tui): preserve prompt separator width (#19340) 2026-05-04 09:58:40 -07:00
osc52.test.ts fix(tui): raise picker selection contrast with inverse + bold 2026-04-21 14:31:21 -05:00
paths.test.ts feat(tui): append git branch to cwd label in status bar 2026-04-18 17:17:05 -05:00
platform.test.ts fix(tui): respect voice.record_key config (supersedes #19028, #19339) (#19835) 2026-05-04 15:49:28 -07:00
precisionWheel.test.ts fix(tui): steady transcript scrollbar (#20917) 2026-05-06 14:50:31 -07:00
providers.test.ts chore(tui): /clean pass — inline one-off locals, tighten ConfirmPrompt 2026-04-19 07:55:38 -05:00
reasoning.test.ts fix(tui): filter thinking status noise 2026-04-26 13:59:56 -05:00
rpc.test.ts fix(ui-tui): surface RPC errors and guard invalid gateway responses 2026-04-13 14:17:52 -05:00
scroll.test.ts fix(tui): refresh scroll height at cached bottom 2026-05-07 05:48:19 -07:00
slashParity.test.ts test(tui): skip slash parity matrix when Python registry is unavailable 2026-04-27 13:19:11 -05:00
stateIsolation.test.ts fix(tui): isolate turn state from app render 2026-04-26 15:40:38 -05:00
statusBarTicker.test.ts feat(tui): segment turns with rule above non-first user msgs; trim ticker dead space (#21846) 2026-05-08 05:12:09 -07:00
streamingMarkdown.test.ts Merge remote-tracking branch 'origin/main' into fix/markdown 2026-04-28 22:01:02 -04:00
subagentTree.test.ts style(debug): add missing blank line between LogSnapshot and helpers 2026-04-22 16:34:05 -05:00
syntax.test.ts fix(tui): restore macOS copy behavior and theme polish (#17131) 2026-04-28 18:47:14 -05:00
terminalModes.test.ts fix(tui): tighten SGR fragment matching 2026-04-30 17:50:49 -05:00
terminalParity.test.ts fix(tui): restore macOS copy behavior and theme polish (#17131) 2026-04-28 18:47:14 -05:00
terminalSetup.test.ts style(tui): apply npm run fix 2026-04-28 22:18:26 -05:00
text.test.ts perf(tui): cache stringWidth/wrapText/sliceAnsi + skip-slice when line fits clip 2026-04-26 19:28:09 -05:00
textInputLineNav.test.ts fix(tui): up-arrow inside a multi-line buffer moves cursor, not history 2026-04-21 18:31:35 -05:00
textInputPassThrough.test.ts fix(tui): respect voice.record_key config (supersedes #19028, #19339) (#19835) 2026-05-04 15:49:28 -07:00
textInputWrap.test.ts fix(tui): word-wrap composer input (#17651) 2026-04-29 16:55:49 -07:00
theme.test.ts fix(tui): honor skin highlight colors (#20895) 2026-05-06 14:01:56 -07:00
turnStore.test.ts chore(tui): remove dead branch cleanup code 2026-04-26 21:54:24 -05:00
useCompletion.test.ts fix(tui): complete absolute paths as paths 2026-05-04 16:14:40 -07:00
useComposerState.test.ts fix(tui): raise picker selection contrast with inverse + bold 2026-04-21 14:31:21 -05:00
useConfigSync.test.ts fix(tui): respect voice.record_key config (supersedes #19028, #19339) (#19835) 2026-05-04 15:49:28 -07:00
useInputHandlers.test.ts fix(tui): restore voice push-to-talk parity (#20897) 2026-05-06 15:49:59 -07:00
useQueue.test.ts fix(tui): copilot review on #16707 — naming, label consistency, esc priority 2026-04-27 15:37:54 -05:00
useSessionLifecycle.test.ts fix(tui): report actual session on exit 2026-04-27 08:52:12 -07:00
useVirtualHistoryHeights.test.ts perf(tui): lazily seed virtual history heights (#16523) 2026-04-27 07:55:45 -07:00
viewport.test.ts fix(tui): stabilize sticky prompt tracking 2026-04-28 22:10:40 -05:00
viewportStore.test.ts fix(tui): steady transcript scrollbar (#20917) 2026-05-06 14:50:31 -07:00
virtualHeights.test.ts feat(tui): segment turns with rule above non-first user msgs; trim ticker dead space (#21846) 2026-05-08 05:12:09 -07:00
virtualHistoryClamp.test.ts fix(tui): stabilize live progress rendering 2026-04-26 15:23:43 -05:00
virtualHistoryOffsetCache.test.ts fix(tui): refresh virtual offsets after row resize (#20898) 2026-05-06 13:54:46 -07:00
wheelAccel.test.ts chore(tui): /clean recent perf work — KISS/DRY pass 2026-04-26 20:38:47 -05:00