Skip to content

fix(tui): pass through Ctrl/Cmd+L so the dashboard redraw byte never inserts a stray 'l' - #87474

Open
jazzzzmaybe wants to merge 1 commit into
NousResearch:mainfrom
jazzzzmaybe:fix/ctrl-l-redraw
Open

fix(tui): pass through Ctrl/Cmd+L so the dashboard redraw byte never inserts a stray 'l'#87474
jazzzzmaybe wants to merge 1 commit into
NousResearch:mainfrom
jazzzzmaybe:fix/ctrl-l-redraw

Conversation

@jazzzzmaybe

Copy link
Copy Markdown

Summary

Fixes #87069 — the dashboard Chat tab inserted a stray l into the composer on every session switch.

Root cause: PtySession.attach() injects a raw Ctrl-L byte (0x0c) to force a TUI repaint on keep-alive PTY reattach (#86332 / #68071). The Ink keypress parser maps that byte to a ctrl+l key event which reaches both listeners — the global hotkey handler (which redraws but doesn't stop propagation) and the composer's TextInput, which falls through to the generic insert branch and types a literal l.

Change

One line: add isAction(key, input, 'l') to shouldPassThroughToGlobalHandler so the composer ignores the redraw keypress, mirroring the global handler's own isAction(key, ch, 'l') check in useInputHandlers.ts. Unmodified l still types normally; the existing ctrl+c/x/o pass-through entries are untouched.

Test plan

  • cd ui-tui && npx tsc --noEmit
  • cd ui-tui && npx vitest run src/__tests__/textInputPassThrough.test.ts (7 passed)
  • cd ui-tui && npx vitest run src/__tests__/textInput (107 passed)
  • Manual: with the composer focused, Ctrl+L no longer inserts l; typing l normally is unaffected.

Related

@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

fix(tui): pass through Ctrl/Cmd+L so the dashboard redraw byte never inserts a stray 'l'

No blocking issues found. A few minor observations:

  1. Test only pins the Ctrl half (ui-tui/src/__tests__/textInputPassThrough.test.ts): isAction(key, input, 'l') is isActionMod(key) && input.toLowerCase() === 'l', which on macOS covers Cmd+L — the "Cmd" half the PR title advertises. An explicit meta/super case (like key({ meta: true })) would pin that path so a future change to isActionMod can't silently drop it.

  2. Two rule shapes coexist in the same boolean (ui-tui/src/components/textInput.tsx): the sibling entries (key.ctrl && input === 'c'/'x'/'o') are explicit ctrl-only checks, while the new entry uses isAction (modifier-inclusive). A later contributor adding e.g. Ctrl+K may copy the wrong shape, making some keys meta-inclusive and others not. Not blocking — worth a comment noting the intent.

  3. Redraw path: the fix routes Ctrl+L to the global handler, which is right for the embedded dashboard (xterm.js) case. Worth a quick manual check in the plain hermes --tui on a terminal where Ctrl+L previously reached the composer as a literal 'l' — the pass-through should now reach the terminal's redraw instead of the input.

@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/) labels Aug 16, 2026
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/) 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.

[Dashboard Chat] Stray "l" inserted into the composer on every session switch (Ctrl-L force-redraw byte leaks into TextInput)

3 participants