feat(detail): interactive git file & diff viewer in task detail view#620
Draft
bborn wants to merge 3 commits into
Draft
feat(detail): interactive git file & diff viewer in task detail view#620bborn wants to merge 3 commits into
bborn wants to merge 3 commits into
Conversation
Press `v` in the task detail view to open a keyboard-driven, read-only viewer of what the task's agent changed — without leaving the TUI: - A changed-file tree (left) scoped to the task's worktree, listing files the branch changed vs its base (merge-base of the source/default branch), including committed, staged, unstaged, and untracked files. - A content pane (the existing viewport) showing the selected file's unified diff with chroma syntax highlighting; `tab` toggles to a rendered view of the working-tree file, with glamour-rendered markdown for .md files. - up/down navigate files, j/k/wheel scroll the diff, esc closes. The viewer renders entirely inside the existing detail box, so the tmux claude/shell panes and their layout are untouched. All content writes go through setViewportContent() and every bit of viewer display state is folded into viewSignature(), so the View() render cache stays correct. File-list and per-file content loading happen on goroutines (matching the existing async pane-setup pattern) to keep the UI thread responsive on large diffs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
Turn the read-only diff viewer into an interactive review surface that loops feedback straight back to the task's live agent — no PR round-trip. - A vim-style line cursor in diff mode (j/k); the cursor line is where a comment anchors. File/rendered mode keeps j/k as scroll. - `c` opens an inline comment input (anchored to the current file + the quoted diff line); comments accumulate per task and show a count badge. - `s` composes the collected comments into one structured message and sends it to the executor's tmux pane (m.claudePaneID, since the detail view joins that pane into the UI session). When no agent is running (e.g. a done task) it falls back to copying the review to the clipboard so nothing is lost. All new state (cursor, comments, input, status) is folded into viewSignature() so the View() render cache stays correct, and the comment input is routed like the other live text inputs in app.go (with the viewer's async result messages exempted by type). Adds atotto/clipboard as a direct dep. Tests cover compose/clipboard/cursor/anchor/input flow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
The new `v` diff/file review viewer is rendered inline in the TUI pane (chroma + glamour) and has no native GUI/web-API equivalent, so the GUI-covers-TUI parity test must treat it as intentionally TUI-only — mirroring the existing SpotlightSync entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.







What
A keyboard-driven, git-aware file & diff viewer in the task detail view (
vto open), now with an interactive review layer that loops feedback back to the task's live agent — no PR round-trip.Read-only viewer
tabtoggles a rendered view of the working-tree file, with glamour-rendered markdown for.mdfiles.↑/↓navigate files,j/k/wheel scroll,esccloses.Interactive review
▌) in diff mode (j/k);copens an inline comment anchored to the current file + the quoted diff line.scomposes them into one structured message and sends it to the executor's tmux pane (claudePaneID), so the live agent addresses them in the worktree. When no agent is running (e.g. a done task), it falls back to the clipboard.Why it's safe for the detail view
setViewportContent(), and every bit of viewer + review state (active, selected, cursor, comments, input, status) is folded intoviewSignature(), so theView()render cache stays correct.setupPanesAsync); the comment input is routed like the other live text inputs in app.go, with the viewer's async result messages exempted by type.tmux send-keys -t <claudePaneID> -l …(the persisted pane id, since the detail view joins that pane into the UI session) — the same primitive as the existingexecutor.SendLiteralTextToPanenudge.Files
internal/ui/diffviewer.go(new) — viewer + review state, git helpers, async loaders, chroma/glamour rendering, line cursor, comment compose + send/clipboard.internal/ui/diffviewer_test.go(new) — helpers, git-integration (temp repo), DetailModel integration, compose/cursor/anchor/comment-input/clipboard, cache-signature.internal/ui/detail.go—difffield;viewSignature/View/renderContent/renderHelp/viewport-width/Updatewiring.internal/ui/app.go—vkeybinding + viewer/comment-input key routing.go.mod—alecthomas/chroma/v2andatotto/clipboardpromoted to direct deps.Verification
go build ./...,go vet,gofmt -l,go test ./internal/ui/+./internal/executor/, andgolangci-lint run(v2.8.0, matching CI) — all green. Full QA with screenshots posted as PR comments (isolated-instance TUI + VHS, no live daemon touched).🤖 Generated with Claude Code