Skip to content

fix(tui): preserve legacy Alt navigation - #707

Closed
yxlyx wants to merge 1 commit into
fix/537-reset-dropped-input-statefrom
fix/524-alt-navigation-escape
Closed

fix(tui): preserve legacy Alt navigation#707
yxlyx wants to merge 1 commit into
fix/537-reset-dropped-input-statefrom
fix/524-alt-navigation-escape

Conversation

@yxlyx

@yxlyx yxlyx commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Closes #524. This PR is intentionally stacked on #699 and contains one additional commit; once #699 merges, this PR can be retargeted to main without changing its diff.

What changed

  • Decode legacy ESC ESC <CSI> Alt+Left/Right/Up as one navigation event instead of Escape followed by navigation.
  • Preserve framing across every read split, bounded delayed delivery, full-buffer recovery, and dropped-head recovery.
  • Keep genuine lone/double Escape behavior after the ambiguity window and preserve recognizable bracketed prose instead of guessing it is navigation.
  • Add reachable fullscreen-TUI regressions for idle, live turn, background compact/bash/files, overlay, and bracketed-paste trajectories.

Why

Problem / failure mode

Some terminals encode legacy Alt+Arrow as ESC ESC plus CSI. The parser previously emitted the first Escape immediately, so the shared TUI dispatcher could cancel a model turn or background operation, close an overlay, end paste, or arm rewind before processing the arrow. Split and delayed terminal reads made this destructive behavior timing-dependent.

Reason for this approach

The incorrect event originates in the shared input framing path, so the fix keeps the complete legacy sequence ambiguous until it can be decoded once. The bounded stall/recovery state from #699 already tracks live operations and late terminal tails; building on it protects every fullscreen TUI trajectory without adding downstream guards or duplicating #537's broader recovery machinery.

Constraints and trade-offs

The terminal byte stream cannot perfectly distinguish ESC ESC [Ax] as Alt+Up then x] from genuine double Escape followed by literal [Ax]. The implementation uses narrow evidence: exact navigation, split input, and navigation followed by ordinary coalesced text win as navigation; recognizable bracketed prose wins as text; an incomplete sequence beyond the existing ~300 ms idle / ~1 s live window resolves as genuine Escape. This preserves cancellation responsiveness while covering the reported 50–250 ms delivery range.

Rejected alternatives

Verification

  • GRAFF_TUIGUARD_JOBS=1 scripts/eval-tier1.sh — green in 562s.
  • Unit suite: 1860 passed + 1 platform skip (1861 total).
  • TUI suite: 514/514.
  • PTY/tuiguard: 18/18.
  • Formatting, 600-line ceiling, test reachability, build, invariants, and SDK drift checks all passed.
  • Independent implementation, adversarial-test, and final-review agents exercised split/delayed input, coalesced printable keys, [Alice] prose, unmodified and 1;3 CSI forms, all background operation kinds, overlay movement, paste, full-buffer recovery, and genuine Escape behavior. Final review reported no blockers.

Legacy terminals encode Alt+Arrow as ESC ESC followed by CSI. Treating the first Escape as a standalone key cancelled live turns and background operations before the navigation event arrived, especially when reads split or stalled.

Keep complete legacy CSI navigation framed as one event through the parser, bounded stall policy, and dropped-head recovery. Genuine double Escape still resolves after the ambiguity window, while narrow evidence preserves bracketed prose instead of guessing it is navigation. Cover idle, live-turn, compact, bash, files, overlay, and paste trajectories without duplicating the broader #537 recovery work this branch builds on.

Co-Authored-By: Codegraff <blackfloofie@codegraff.com>
cursor Bot pushed a commit that referenced this pull request Sep 1, 2026
SS3 after ESC ESC is Escape, not an arrow. A delivered lone Escape does
not rejoin a later ESC CSI. Folded yxlyx #707 onto the earlier 96b6d4f
subset.

Co-Authored-By: yxlyx <85774423+yxlyx@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Sep 1, 2026
@justrach

justrach commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Folded onto release/v0.0.283 (PR #703) as e674794 — this is the complete CSI-only Alt+arrow framing (ESC ESC [ stays one nav event; SS3 ESC ESC OA stays Escape). Replaces the smaller leftover that was already on the cut.

Leaving this PR open for you to close as superseded.

@justrach

justrach commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Shipped in v0.0.283 via #703 (e674794). Closing as superseded — not merging this branch to main.

@justrach justrach closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants