Diff Reviewer

An IDE-like /diff for the terminal — a stacked file tree and diff on Local Changes, a side-by-side commit graph and diff on Log.

Overview

/diff is a two-tab reviewer — stacked sections on Local Changes, a side-by-side graph and diff on Log when the terminal is wide enough:

  • Local Changes — file tree stacked above the diff of the selected file, each section a titled rule rather than a boxed pane, collapsed to the changed lines with incremental expand of unchanged context.
  • Log — the git graph/tree (left) | files changed in the selected commit (right).
┌ Diff ─────────────────────────────────────────────────────────┐
│  Local Changes   Log                         (Tab to switch)   │
│  source: working tree ▾                                        │
│ ─ Files  2 files changed ───────────────────────── +16 -7 ──── │
│ › src/foo.ts  +12 -3                                            │
│   README.md   +4  -4                                            │
│ ─ Diff: foo.ts ────────────────────────────────────────────── │
│  12  export function foo() {                                   │
│ ··· 8 lines ─────────────────────────────────────────────────  │
│ -18  const x = old()                                            │
│ +18  const x = new()                                            │
│  Tab tabs · ↑/↓ move · → diff · ← back · ctrl+↑/↓ section · r refresh · Esc close│
└────────────────────────────────────────────────────────────────┘

File tree (Local Changes)

The file list sits above the diff, as a collapsible folder tree rather than a flat list. Files nest under their directories; folders sort first, then files; single-child directory chains compact into one row (like VS Code's compact folders). Folder rows show a caret plus an open/closed icon; file rows show the basename with its per-file +/− stat. When more than one repo is in scope, a per-repo group header sits above its files — collapsible too, so you can fold an entire repo's changes out of the way while keeping its header visible.

Keys: ↑/↓ move, Enter toggles a folder or opens a file, → expands a folder or focuses the diff, ← collapses a folder or focuses the list.

The four sources

The source selector on Local Changes cycles with [/] across three kinds, all feeding the same file-list + diff panes:

  • Working tree — uncommitted changes vs HEAD (the default).
  • Per-turn — one entry per agent turn in the current session.
  • Stash — stash@{0}…stash@{n} from git stash list.

Multi-repo / monorepo grouping

When more than one git repo is in scope, the file list groups per project with a colored swatch, the repo name, file count, and branch:

web   2 files changed · main
  src/foo.ts   +12 -3
  README.md    +4  -4
api   1 file changed  · dev
  src/bar.ts   +1  -0

Scope is the cwd's repo, every /add-dir workspace directory, and nested child repos discovered underneath them — the common monorepo shape where sibling folders each carry their own .git and the parent's git status never sees their changes. Discovery is bounded (max depth 3, max 1 500 directories scanned) and skips node_modules/dist/vendor-style noise. A single repo in scope shows no header at all — the flat list you already know.

Collapse & expand

The diff pane shows only changed lines plus 3 lines of context; unchanged stretches collapse to a ··· N lines marker. Activating a marker reveals ±10 more lines, GitHub-style, pulled from the working-tree file. Untracked files no longer show a placeholder — they render as an all-green synthesized diff, syntax-highlighted like any other file.

Nerd-Font file icons

When your terminal font supports it, a per-file-type icon sits next to every filename in both tabs' file lists. On terminals without Nerd Font glyphs, it falls back to plain ASCII markers — no raw glyph is ever emitted unconditionally. Override with CLAUDIN_NERD_FONT=on / off.

Log tab

The left rail is the real branch/merge topology (git log --graph), not a flat list of commits — authors get stable colors, tags render green, branches/HEAD render amber. In a monorepo, [/] cycle which repo's log is shown. The right pane lists the selected commit's changed files with per-file stats and the commit-wide total; drilling into a file (Enter/→) shows its diff at the third level, through the same rendering path as Local Changes, so theme colors and syntax highlighting match exactly.

┌ Diff ─────────────────────────────────────────────────────────┐
│  Local Changes   Log                         (Tab to switch)   │
│ ┌ Log ───────────────────────┐┌ Files in dca77a5 ───────────┐ │
│ │ ○ feat: @-mention nav  main ││  src/components/x.tsx  +20 -4│ │
│ │ ●  chore: bump deps         ││  src/hooks/y.ts        +3  -1│ │
│ │ ├─╮ Merge branch 'fix'      ││                              │ │
│ │ │ ● fix(ink): vacated rows  ││                              │ │
│ │ ●─╯ feat(bridge): remote    ││                              │ │
│ └────────────────────────────┘└──────────────────────────────┘ │
│  main ⟳ ⊗0 ⚠12     Tab tabs · ↑/↓ commits · → files · Esc close │
└────────────────────────────────────────────────────────────────┘

Navigation

KeyAction
Tabswitch tabs (Local Changes ↔ Log)
↑/↓move selection in the list, or scroll the diff when it's focused
←/→move focus between the file/commit list and the diff — side by side on Log (≥96 cols), stacked above/below on Local Changes; also collapses/expands a folder on Local Changes
ctrl+↑ / ctrl+↓move focus between the stacked sections on Local Changes, without collapsing or expanding a folder
[ / ]cycle the source (Local Changes) or the project (Log, monorepo)
Enteropen a file / toggle a folder (list focus); grow the next collapsed gap (content focus)
v(diff focused) anchor a visual line selection; ↑/↓ extend it, Enter attaches @path#La-Lb to the prompt, Esc cancels
mouse drag over the diffattaches the dragged lines the same way, on release
aexpand the whole file (Local Changes)
u / d, g/Gpage / jump to ends (content focused, split layout)
rmanual refresh
ctrl+gtoggle the reviewer open/closed from anywhere, including from inside the panel
ctrl+→ / ctrl+←step focus into the panel / back out to the prompt
Escclose (from content focus, returns to the list first)

Entry points

/diff stays the canonical command. ctrl+g toggles the same overlay open and closed from anywhere, including from inside the panel — it replaced the older gg chord (a g then a quick second g on an empty prompt).

Local Changes stacks its sections at any terminal width. Log keeps its side-by-side graph/files split down to 96 usable columns; below that it falls back to the same one-at-a-time list-then-detail path, so both tabs stay usable everywhere.