fix-new-chat-2

Fix: new-chat dialog leaks keystrokes to underlying chat panes when no Custom field exists for the focused row

Metadata

Statusdone
Assignedagent-1198
Agent identity3184716484e6f0ea08bb13539daf07686ee79d440505f1fdf2de0357707034c3
Created2026-04-29T23:44:24.675795821+00:00
Started2026-04-29T23:45:13.510412146+00:00
Completed2026-04-29T23:58:09.026218310+00:00
Tagspriority-high,bug,tui,ux,input,dialog, eval-scheduled
Eval score0.76
└ blocking impact0.85
└ completeness0.68
└ constraint fidelity0.55
└ coordination overhead0.72
└ correctness0.78
└ downstream usability0.76
└ efficiency0.76
└ intent fidelity0.71
└ style adherence0.82

Description

Description

The new-chat dialog has a Custom field for Model (○ Custom: [enter value]) but NOT for Endpoint (just shows No endpoints registered. wg endpoint add ... to add one.). When the user, expecting symmetric behavior, types a custom URL into the Endpoint area, those keystrokes are NOT consumed by the dialog. Instead they leak through the modal and reach an underlying chat-pane PTY, where they're sent to the running chat agent.

User report 2026-04-29: 'when i tried to enter the custom URL it entered it here!' — referring to keystrokes appearing in a different chat-tab conversation instead of the dialog.

Two distinct bugs in this report

Bug A: Endpoint section has no Custom URL field

Tracked in fix-new-chat (already filed). When that lands, users can type a URL inline and the dialog will accept it. Out of scope for THIS task.

Bug B: Modal dialog doesn't consume all keyboard input (this task)

Independent of A. While the new-chat dialog is open, ANY keystroke not bound to a dialog action should be either consumed (no-op) or beep — NEVER forwarded to background chat panes. A modal dialog by definition captures input.

The current behavior: keystrokes the dialog doesn't recognize (because no input field on the focused row accepts them) fall through to whatever pane is in focus underneath. That's broken modal-ness.

Fix scope (Bug B only — A is fix-new-chat)

  • Identify the dialog's input-event handler in src/tui/
  • Ensure ALL key events while the dialog is open are intercepted at the dialog layer
  • Unrecognized keys should be no-op (or visual-feedback like a brief flash) — never delegated to background panes
  • Same for mouse events: clicks outside the dialog should be either a) close the dialog, or b) consumed; should NOT click-through to underlying panes

Validation

  • Failing test: open new-chat dialog with a chat tab in focus underneath. Type a string of arbitrary keys. Pre-fix: those keys appear in the chat tab's PTY child stdin. Post-fix: zero bytes reach any background pane's stdin.
  • Same test with mouse clicks outside the dialog rectangle
  • No regression: keys that ARE bound to dialog actions (Tab to switch field, Enter to submit, Esc to cancel, arrow keys to navigate radio options) still work
  • Combined with fix-new-chat: a user typing a URL into the (newly-added) Endpoint Custom field types ONLY into that field, with no leak
  • cargo build + cargo test pass
  • Permanent smoke scenario: programmatic key-event injection while dialog is open, assert background pane receives zero input bytes
  • cargo install --path . was run before claiming done

Process note

This is the same input-routing failure mode as the wheel→arrow-keys regression earlier today: events being forwarded to PTY child stdin when they should be consumed at the outer layer. Same byte-level smoke pattern (assert input_bytes_written = 0 on the relevant PtyPane during the test) catches this regression class going forward.

Depends on

Required by

Log