feat(tui-go): in-session right panel cycles events / changes / off (d)

Press d (or the "panel" palette command) in-session to cycle the right panel:
- events  — the live event stream (default, unchanged)
- changes — a token-usage line (tokens + turns, summed from the transcript's
            TurnMetrics) over a git-status-style list of files the session has
            written, each with summed +/− from its diff. ^x still opens the full
            diff.
- off     — hide the panel; the output transcript takes the full width.

changesRows derives everything from data already in the model (router-turn
metrics + the tool entries' unified diffs), so no new protocol. Footer + ? help
updated; "changes" preview kind added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 14:47:23 +00:00
parent cde0c33031
commit 6c792b83e2
6 changed files with 95 additions and 3 deletions
+13
View File
@@ -310,6 +310,11 @@ func (m Model) handleNormalKey(k tea.KeyMsg) (tea.Model, tea.Cmd) {
if ds == StateIdle {
m.cycleLauncherWf()
}
case "d":
// In-session: cycle the right panel (events → changes → off).
if ds == StateInSession {
m.cycleRightPanel()
}
case "l":
if ds != StateIdle {
m.sessionEntered = false
@@ -1090,6 +1095,7 @@ func paletteCommands() []paletteCmd {
{"grants", "G", "grants", "view / revoke standing grants"},
{"statusbar", "", "status bar", "show / hide status-bar segments"},
{"rail", "", "idle rail", "show / hide the idle status + keys rail"},
{"panel", "d", "right panel", "in-session: events → changes → off"},
{"actions", "", "inline actions", "show / hide tool & action rows in output"},
{"help", "?", "help", "keybinding cheat-sheet"},
{"mode", "s", "toggle mode", "switch chat / steering"},
@@ -1140,6 +1146,8 @@ func (m Model) execPalette(id string) (tea.Model, tea.Cmd) {
m.sbIndex = 0
case "rail":
m.railHidden = !m.railHidden
case "panel":
m.cycleRightPanel()
case "actions":
m.toggleInlineActions()
case "help":
@@ -1187,6 +1195,11 @@ func (m *Model) cycleLauncherWf() {
m.launcherWf = (m.launcherWf + 1) % (len(m.workflows) + 1)
}
// cycleRightPanel advances the in-session right panel: events → changes → off → events.
func (m *Model) cycleRightPanel() {
m.rightPanel = (m.rightPanel + 1) % 3
}
func (m *Model) cycleChatMode() {
if m.chatMode == ChatModeChat {
m.chatMode = ChatModeSteering