fix(tui): blitz closeout — input wrap parity, shift-tab yolo, bottom statusline

- input wrap: add <Text wrap="wrap-char"> mode that drives wrap-ansi with
  wordWrap:false, and align cursorLayout/offsetFromPosition to that same
  boundary (w=cols, trailing-cell overflow). Word-wrap's whitespace
  reshuffle was causing the cursor to jump a word left/right on each
  keystroke near the right edge — blitz row 9
- shift-tab: toggle per-session yolo without submitting a turn (mirrors
  Claude Code's in-place dangerously-approve); slash /yolo still works
  for discoverability — blitz row 5 sub-item 11
- statusline: lift StatusRule out of ComposerPane to a new StatusRulePane
  anchored at the bottom of AppLayout, below the input — blitz row 5
  sub-item 12
This commit is contained in:
Brooklyn Nicholson 2026-04-22 13:28:44 -05:00
parent 88564ad8bc
commit 7027ce42ef
8 changed files with 140 additions and 24 deletions

View file

@ -3,6 +3,7 @@ import { useStore } from '@nanostores/react'
import type {
ApprovalRespondResponse,
ConfigSetResponse,
SecretRespondResponse,
SudoRespondResponse,
VoiceRecordResponse
@ -377,6 +378,16 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
return cActions.openEditor()
}
// Shift-Tab toggles per-session yolo without submitting a turn — mirrors
// Claude Code's in-place dangerously-approve toggle. Slash /yolo keeps
// working for discoverability; this just skips the inference round-trip
// when you only want to flip the flag mid-flow (blitz #5 sub-item 11).
if (key.shift && key.tab && !cState.completions.length) {
return void gateway
.rpc<ConfigSetResponse>('config.set', { key: 'yolo', session_id: live.sid })
.then(r => actions.sys(`yolo ${r?.value === '1' ? 'on' : 'off'}`))
}
if (key.tab && cState.completions.length) {
const row = cState.completions[cState.compIdx]