Metadata
| Status | done |
|---|---|
| Assigned | agent-1185 |
| Agent identity | f51439356729d112a6c404803d88015d5b44832c6c584c62b96732b63c2b0c7e |
| Created | 2026-04-29T21:12:26.432434053+00:00 |
| Started | 2026-04-29T21:13:17.411914212+00:00 |
| Completed | 2026-04-29T21:39:53.274292772+00:00 |
| Tags | priority-high,fix,tui,pty,chat, eval-scheduled |
| Eval score | 0.82 |
| └ blocking impact | 0.82 |
| └ completeness | 0.80 |
| └ constraint fidelity | 0.85 |
| └ coordination overhead | 0.88 |
| └ correctness | 0.85 |
| └ downstream usability | 0.85 |
| └ efficiency | 0.85 |
| └ intent fidelity | 0.89 |
| └ style adherence | 0.88 |
Description
Description
With implement-tmux-wrapped landed, chats spawn inside tmux sessions. When the user scrolls (touch scroll, mouse wheel, eventually keyboard scroll mode), tmux currently autonomously enters copy mode and re-emits its scroll-position view. Our vt100::Parser then reads that re-emitted stream and renders garbled output after the first few lines.
User report 2026-04-29: 'But really, it should be sending like a tmux command saying, hey, scroll up tmux. Scroll down. That would be the most natural thing to do. In reality, it's totally busted. It's garbled. I just checked after the first few lines.'
Architecture choice (the fix)
Today (broken):
user input (touch/wheel)
→ tmux mouse-mode autonomously enters copy mode
→ tmux re-emits scrolled view via copy-mode escape sequences
→ our vt100::Parser chokes on copy-mode sequences
→ garbled render after first ~few lines
Fix:
user input (touch/wheel/PgUp-PgDn/scroll-mode-keys)
→ wg captures at the chat-pane input layer
→ wg sends `tmux copy-mode -t <session>; send-keys -X cursor-up N` (or cursor-down, page-up, page-down)
→ tmux scrolls + emits clean post-scroll view
→ vt100::Parser reads cleanly
→ render is correct
The principle: wg is the single owner of 'when to scroll and by how much.' Tmux just executes scroll commands wg sends. tmux's autonomous mouse-driven copy-mode entry is disabled (or its events are intercepted before tmux acts on them).
Implementation steps
- Disable tmux's autonomous mouse mode for chat sessions: at sync_tmux_settings (per fix-wg-owns task), set
mouse offfor wg-chat-* sessions. This stops tmux from autonomously responding to mouse events; we'll route them ourselves. - Capture mouse events at the chat-pane layer: mouse wheel + touch events come into wg as crossterm MouseEventKind::ScrollUp / ScrollDown (or pixel-precise variants). Capture them.
- Send tmux scroll commands: for each scroll event, shell out (or use tmux control-mode) with:
tmux copy-mode -t <session>(enter copy mode if not in it)tmux send-keys -t <session> -X cursor-up(or cursor-down, page-up, page-down depending on the input)- Tmux executes the scroll and emits the new view
- Exit copy mode on user typing: when the user types into the chat (any non-scroll input), send
tmux send-keys -t <session> -X cancelto exit copy mode and return to live input mode. - Smoke verify the rendering chain: with the new architecture, capture vt100::Parser's input stream during a scroll. Confirm the bytes don't trigger the garble pattern (no duplicated lines, no wrong-column rendering).
Validation
- Failing test: pre-fix, touch-scroll a tmux-wrapped claude chat with multi-screen scrollback, render reflects garble pattern (duplicated/wrong content). Post-fix, render is clean.
- Mouse wheel: scrolls cleanly (closes fix-mouse-wheel-3 if this fix obsoletes that task)
- Touch scroll: scrolls cleanly (no garble)
- PgUp / PgDn (if/when implement-tui-scroll's keyboard mode lands): same
- Typing into the chat after scrolling: exits copy mode automatically, input goes to inner app
- No regression of implement-tmux-wrapped's persistence (tmux session still survives TUI exit)
- cargo build + cargo test pass
- Permanent smoke scenario: programmatically issue scroll input + capture rendered output; assert no garble pattern (compare against expected scrolled content from JSONL chat-history). This task id in owners.
- cargo install --path . was run before claiming done
Closes / supersedes
This fix probably obsoletes:
- fix-mouse-wheel-3 (different mechanism but same end-result: wheel scrolls cleanly)
- The 'touch scroll garbles' issue identified here
If this fix lands cleanly, abandon those tasks as superseded. If it doesn't, fall back to those targeted fixes.
Process note
The recurring 'scrollback gets garbled' pattern across multiple tasks today (fix-tui-pty, fix-pty-scrollback, fix-scrollback-reflow, the touch-scroll garble) is rooted in vt100::Parser handling escape sequences from various sources (raw vendor CLIs, alt-screen-mode codex, now tmux's copy mode). Each new source has been a new vt100 surface to debug. The architectural answer (wg owns scroll, tmux just executes, vt100 only sees clean post-scroll renders) is materially cleaner than continuing to patch vt100 against each new sequence class.
Depends on
Required by
- (none)
Log
- 2026-04-29T21:12:26.344201156+00:00 Task paused
- 2026-04-29T21:12:38.245031318+00:00 Task published
- 2026-04-29T21:13:11.026466984+00:00 Lightweight assignment: agent=Careful Programmer (f5143935), exec_mode=full, context_scope=task, reason=Careful Programmer (0.78 score, 352 tasks) matches the correctness-critical architectural rework: TUI input capture, tmux command generation, vt100 parser integration, and rendering verification all require precision and careful sequencing.
- 2026-04-29T21:13:17.411920975+00:00 Spawned by coordinator --executor claude --model opus
- 2026-04-29T21:13:31.965865576+00:00 Starting work — reading prior tmux-wrapped/scroll context
- 2026-04-29T21:26:36.631820172+00:00 Implemented: PtyPane.scroll_up/down routes via tmux copy-mode when wrapped; send_key/send_text auto-cancel copy-mode; mouse mode explicitly off; 2 new pty_pane unit tests pass; new smoke scenario chat_scroll_via_drives_tmux_copy_mode passes.
- 2026-04-29T21:30:34.349370396+00:00 Committed: 8437e7892 — pushed to remote
- 2026-04-29T21:39:43.424598175+00:00 Rebased on main (after fix-wg-owns + fix-mouse-wheel-3 landed). Merged with apply_session_options for mouse-off; dropped redundant in_tmux_copy_mode field, use tmux_scroll_lines (fix-mouse-wheel-3). Tests: 3261 passed; new send_key_cancels_tmux_copy_mode test; smoke chat_scroll_via_drives_tmux_copy_mode passes. Commit: 1911f210e
- 2026-04-29T21:39:53.274295567+00:00 Task pending eval (agent reported done; awaiting `.evaluate-*` to score)
- 2026-04-29T21:41:38.668928908+00:00 PendingEval → Done (evaluator passed; downstream unblocks)