feat(tui-go): transcript free-scroll + help overlay + event filter

Three TUI-polish items.

- OUTPUT free-scroll: PgUp/PgDn (and ^u/^d half-page) scroll the transcript
  back through history; esc snaps to tail-follow. outputScroll is clamped
  against outputViewport(), which mirrors View/renderMain geometry, so the
  edges land exactly (no dead presses unwinding an overshoot). routerRows
  split into buildTranscriptRows (full render) + windowing so the handler
  measures the same content. Tests cover the clamp + the fits-in-panel no-op.
- Help overlay: `?` (or the "help" palette command) opens a keybinding
  cheat-sheet grouped by context (session / overlays / approval band) — the
  non-palette keys especially. Any key dismisses it.
- Event-inspector filter: `/` filters the event list by a case-insensitive
  substring of type/detail (currentEvents applies it); `c` clears, esc stops
  editing then closes. Fresh per open. EVENTS side panel stays unfiltered.

go build / vet / test green; rendered help + filtered inspector via
cmd/preview (help, events-filter kinds).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 05:41:38 +00:00
parent f14a83c026
commit 531910d38a
6 changed files with 309 additions and 28 deletions
+21
View File
@@ -184,6 +184,27 @@ func PreviewFrame(kind string, w, h int) string {
s.LastEventAt = nowMillis() - 3000
}
case "help":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.overlay = OverlayHelp
case "events-filter":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.Events = sampleEvents()
}
m.overlay = OverlayEventInspector
m.eventFilter = "tool"
m.eventFilterTyping = true
case "grants":
m.connected = true
m.currentModel = "llama-cpp:default"