by umputun
TUI for reviewing diffs, files, and documents with inline annotations
# Add to your Claude Code skills
git clone https://github.com/umputun/revdiffTUI for reviewing diffs, files, and documents with inline annotations. Outputs structured annotations to stdout on quit, making it easy to pipe results into AI agents, scripts, or other tools.
Built for a specific use case: reviewing code changes, plans, and documents without leaving a terminal-based AI coding session (e.g., Claude Code). Just enough UI to navigate diffs and files, annotate specific lines, and return the results to the calling process - no more, no less.
v↪ continuation markers, toggle with wLB/ search within diff with n/N match navigation@): browse all annotations across files, jump to any annotationNo comments yet. Be the first to share your thoughts!
?) showing all keybindings organized by section--all-files, filter with --exclude--only files outside a git repo (or not in any diff) are shown as context-only with full annotation support--stdin, optionally naming it with --stdin-name--dump-keys
git (used to generate diffs; optional when using --only or --stdin)Homebrew (macOS/Linux):
brew install umputun/apps/revdiff
Go install:
go install github.com/umputun/revdiff/cmd/revdiff@latest
Binary releases: download from GitHub Releases (deb, rpm, archives for linux/darwin amd64/arm64).
revdiff ships with a Claude Code plugin for interactive code review directly from a Claude session. The plugin launches revdiff as a terminal overlay, captures annotations, and feeds them back to Claude for processing.
The plugin requires one of the following terminals since Claude Code itself cannot display interactive TUI applications - the overlay runs revdiff in a separate terminal layer on top of the current session:
| Terminal | Overlay method | Detection |
|----------|---------------|-----------|
| tmux | display-popup (blocks until quit) | $TMUX env var |
| kitty | kitty @ launch --type=overlay | $KITTY_LISTEN_ON env var |
| wezterm | wezterm cli split-pane | $WEZTERM_PANE env var |
| Kaku | kaku cli split-pane (same API as wezterm) | $WEZTERM_PANE env var |
| cmux | cmux new-split + cmux send | $CMUX_SURFACE_ID env var |
| ghostty | AppleScript split + zoom (macOS only) | $TERM_PROGRAM + AppleScript probe |
| iTerm2 | osascript split pane (macOS only) | $ITERM_SESSION_ID env var |
| Emacs vterm | New frame via emacsclient | $INSIDE_EMACS env var |
Priority: tmux → kitty → wezterm/Kaku → cmux → ghostty → iTerm2 → Emacs vterm (first detected wins). If none are available, the plugin exits with an error.
Note: cmux is detected before ghostty because cmux also sets
$TERM_PROGRAM=ghostty. The cmux block uses the cmux CLI (new-split+send --surface) instead of Ghostty's AppleScript API.
Note: iTerm2 uses a split pane (vertical or horizontal, auto-detected from terminal dimensions) rather than a full-screen overlay. The iTerm2 AppleScript API does not expose a zoom command, so the split view shares screen space with the invoking session.
Install:
# add marketplace and install
/plugin marketplace add umputun/revdiff
/plugin install revdiff@umputun-revdiff
Use with /revdiff command:
/revdiff -- smart detection: uncommitted, last commit, or branch diff
/revdiff HEAD~1 -- review last commit
/revdiff main -- review current branch against main
/revdiff --staged -- review staged changes only
/revdiff HEAD~3 -- review last 3 commits
Use with free text (no slash command needed):
"review diff" -- smart detection, same as /revdiff
"review diff HEAD~1" -- last commit
"review diff against main" -- branch diff
"review changes from last 2 days" -- Claude resolves the ref automatically
"revdiff for staged changes" -- staged only
When no ref is provided, the plugin detects what to review automatically:
The plugin includes built-in reference documentation and can answer questions about revdiff usage, available themes, keybindings, and configuration options. It can also create or modify the local config file (~/.config/revdiff/config) on request:
"what chroma themes does revdiff support?"
"switch revdiff to dracula theme"
"what are the revdiff keybindings?"
"set tree width to 3 in revdiff config"
The plugin supports the full review loop: annotate → plan → fix → re-review until no more annotations remain.
A separate revdiff-planning plugin automatically opens revdiff when Claude exits plan mode, letting you annotate the plan before approving it. If you add annotations, Claude revises the plan and asks again — looping until you're satisfied.
/plugin install revdiff-planning@umputun-revdiff
This plugin is independent from the main revdiff plugin and does not conflict with other planning plugins (e.g., planning from cc-thingz).
The structured stdout output works with any tool that can read text:
# capture annotations for processing
annotations=$(revdiff main)
if [ -n "$annotations" ]; then
echo "$annotations" | your-tool
fi
revdiff [OPTIONS] [base] [against]
Positional arguments support several forms:
revdiff — uncommitted changesrevdiff HEAD~3 — diff a single ref against the working treerevdiff main feature — diff between two refsrevdiff main..feature — same as above, using git's dot-dot syntaxrevdiff main...feature — changes since feature diverged from main| Option | Description | Default |
|--------|-------------|---------|
| base | Git ref to diff against | uncommitted changes |
| against | Second git ref for two-ref diff | |
| --staged | Show staged changes, env: REVDIFF_STAGED | false |
| --tree-width | File tree panel width in units (1-10), env: REVDIFF_TREE_WIDTH | 2 |
| --tab-width | Number of spaces per tab character, env: REVDIFF_TAB_WIDTH | 4 |
| --no-colors | Disable all colors including syntax highlighting, env: REVDIFF_NO_COLORS | false |
| --no-status-bar | Hide the status bar, env: REVDIFF_NO_STATUS_BAR | false |
| --wrap | Enable line wrapping in diff view, env: REVDIFF_WRAP | false |
| --collapsed | Start in collapsed diff mode, env: REVDIFF_COLLAPSED | false |
| --line-numbers | Show line numbers in diff gutter, env: REVDIFF_LINE_NUMBERS | false |
| --blame | Show git blame gutter on startup, env: REVDIFF_BLAME | false |
| --no-confirm-discard | Skip confirmation when discarding annotations with Q, env: REVDIFF_NO_CONFIRM_DISCARD | false |
| --chroma-style | Chroma color theme for syntax highlighting, env: REVDIFF_CHROMA_STYLE | catppuccin-macchiato |
| --theme | Load color theme from ~/.config/revdiff/themes/, env: REVDIFF_THEME | |
| --dump-theme | Print currently resolved colors as theme file to stdout and exit | |
| --list-themes | Print available theme names to stdout and exit | |
| --init-themes | Write bundled theme files to themes dir and exit | |
| -A, --all-files | Browse all git-tracked files, not just diffs | false |
| --stdin | Review stdin as a scratch buffer (piped or redirected input only) | false |
| --stdin-name | Synthetic file name for stdin content; enables extension-based highlighting/TOC | scratch-buffer |
| -X, --exclude | Exclude files matching prefix, may be repeated, env: REVDIFF_EXCLUDE (comma-separated) | |
| -F, `--only