Metadata
| Status | done |
|---|---|
| Assigned | agent-1198 |
| Agent identity | 3184716484e6f0ea08bb13539daf07686ee79d440505f1fdf2de0357707034c3 |
| Created | 2026-04-29T23:44:24.675795821+00:00 |
| Started | 2026-04-29T23:45:13.510412146+00:00 |
| Completed | 2026-04-29T23:58:09.026218310+00:00 |
| Tags | priority-high,bug,tui,ux,input,dialog, eval-scheduled |
| Eval score | 0.76 |
| └ blocking impact | 0.85 |
| └ completeness | 0.68 |
| └ constraint fidelity | 0.55 |
| └ coordination overhead | 0.72 |
| └ correctness | 0.78 |
| └ downstream usability | 0.76 |
| └ efficiency | 0.76 |
| └ intent fidelity | 0.71 |
| └ style adherence | 0.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
- (none)
Log
- 2026-04-29T23:44:24.665100528+00:00 Task paused
- 2026-04-29T23:44:30.132980248+00:00 Task published
- 2026-04-29T23:45:04.758794861+00:00 USER ESCALATION 2026-04-29: 'then it opened claude' The dialog didn't just leak keys to the underlying pane — somewhere in the user's typing of a URL, the dialog interpreted a key as Launch confirmation and OPENED a claude chat (the default executor radio selection), without the user explicitly clicking Launch. This is worse than 'keys leak through.' It's 'modal dialog auto-confirms on unrelated input.' ADDITIONAL VALIDATION: - [ ] No keystroke EXCEPT explicit Enter on the Launch button OR explicit Tab-to-Launch-then-Enter should trigger chat creation - [ ] Specifically: pressing Enter while focus is on a non-actionable widget (e.g. radio row with no input) should NOT launch - [ ] Pressing Spacebar should toggle radio buttons, not launch - [ ] Typing letters (URL chars like h, t, p, :, /) should produce no action when no input field has focus - [ ] Enter / Spacebar / arbitrary letters do NOT confirm-and-launch unless Launch button has focus AND user pressed Enter The combined rule (covers both Bug B keystroke-leak AND the auto-launch issue): Modal dialog: every key event is dispatched ONLY to the focused widget. If the focused widget doesn't claim it, the event is consumed silently (or beeps). Events NEVER fall through to background panes AND never trigger global dialog actions (like Launch) unless they're explicitly bound to those actions in the current focus context. This is a fundamental modal-ness invariant. Worth a smoke scenario that asserts both: 1. Background pane receives zero bytes 2. No chat is launched until explicit Launch button activation
- 2026-04-29T23:45:13.510415923+00:00 Spawned by coordinator --executor claude --model opus
- 2026-04-29T23:45:37.274627018+00:00 Starting investigation: locating new-chat dialog input handler in src/tui/
- 2026-04-29T23:48:08.829424749+00:00 Root cause: vendor_pty_active branch (event.rs:564-616) forwards every keystroke to PTY child stdin without checking input_mode. When launcher opens via [+] click, focused_panel stays RightPanel and chat_pty_mode stays true, so keys go to PTY before reaching handle_launcher_input. Fix: gate vendor_pty_active on InputMode::Normal.
- 2026-04-29T23:56:41.765414367+00:00 Validated: cargo build + cargo test --bin wg pass (3274 tests). Two new regression tests added: launcher_open_does_not_leak_keys_to_underlying_pty (byte-level: child_input_bytes_written stays at 0) and launcher_open_clears_pty_input_routing (input_mode-level guard). cargo install --path . succeeded.
- 2026-04-29T23:57:54.379403169+00:00 Committed: 89ee6993c — 3 files (+196/-1)
- 2026-04-29T23:58:09.026225263+00:00 Task pending eval (agent reported done; awaiting `.evaluate-*` to score)
- 2026-04-30T00:00:18.623405766+00:00 PendingEval → Done (evaluator passed; downstream unblocks)