feat(tui): dock approval gate + two-column diff viewer

Replace the floating approval modal (which blanked the whole UI) with an
opencode-style band that takes the input bar's slot while a gate is
pending: tool/tier/risk header above a side-by-side old|new diff, with
the session output and event stream still visible above it. The band
height adapts to the diff length.

Add a unified-diff parser that aligns removals/additions into split rows
(blank left cell for a create, blank right for a delete) and a
two-column renderer shared by the band preview and the ^x fullscreen
view. Wire plain a/r to approve/reject to match the advertised keys.
This commit is contained in:
2026-06-03 00:17:08 +04:00
parent 6956102cf7
commit 03ccac76c7
6 changed files with 363 additions and 80 deletions
+7
View File
@@ -195,11 +195,18 @@ func (m Model) handleNormalKey(k tea.KeyMsg) (tea.Model, tea.Cmd) {
m.client.Send(protocol.CancelSession(m.selectedID))
}
case "a":
if ds == StateApproval {
return m.decide("APPROVE")
}
if ds == StateInSession {
if s := m.session(m.selectedID); s != nil && s.Pending != nil {
m.approvalDismissed = false
}
}
case "r":
if ds == StateApproval {
return m.decide("REJECT")
}
case "A":
if ds == StateApproval {
return m.autoApprove()