Diff review
Feature docs index · Mission Control
Review changes
Click Diff on Mission Control's right rail. Diff replaces the conversation body while keeping the prompt and rail. The three columns use 20% for folders, files and comments, 40% for Original, and 40% for Diff. Folders remain expanded. Select Activity or Summary to return to the conversation.
Original shows HEAD; Diff compares it with current worktree content, including the combined effect of staged and unstaged changes and non-ignored untracked files. There is no separate index comparison. Before the first commit, the original is empty. Review does not stage, discard, or edit source files.
Files show themed W (newly written), E (edited), and D (deleted) labels and colors. Full rewrites of existing files and file-type changes count as E; renames appear as D at the old path and W at the new path. Selected filenames keep the selection colors; their status labels stay colored. Files retained only for comments have no change label.
Original has one line-number column. Diff (old → new) has two compact columns: unchanged lines show both numbers, removals show only the old number, and additions show only the new number. Each column fits its source length.
While Diff is selected, a background worker refreshes after a one-second pause between completed reads. This is not a guarantee that external edits appear within one second. The selected file is retained when still present. Outside a Git worktree, the page reports an error.
The Diff tab shows a colored dot instead of a file count when a background scan finds changes you have not viewed, including changes already present at startup. Opening Diff clears it; updates while Diff is open stay acknowledged. Unchanged or failed scans do not create a notification. Detection uses bounded source reads, so edits within omitted sources may not be detected.
If the view appears stuck, click Refresh · F5 at the bottom of Files or press F5 while Diff is selected. This discards cached snapshots and highlighting and scans the worktree again within the limits below. An existing comment save finishes first; open drafts and file selection are retained. F5 also works inside a comment dialog.
| Control | Action |
|---|---|
Tab / Shift-Tab | Cycle Prompt, Files, Original, Diff forwards/backwards. |
Alt+1 / Alt+2 / Alt+3 | Select Activity, Summary, or Diff (outside dialogs). |
Up / Down | Move through files/comments or lines in the focused column. |
Enter in Files | Open a selected comment. File selection displays its source. |
Enter in Original or Diff | Add or edit a comment on the selected line. Removed lines use the original side. |
Esc | Return to Prompt, or cancel an open comment dialog before saving starts. |
| Click | Select a file or open a saved comment. In Original or Diff, the first click selects a line and shows [ + ]; a second click on that line opens its comment dialog. |
| Mouse wheel | Scroll the hovered pane without changing focus or the selected line. Original and Diff scroll together using corresponding source lines. |
Shift + mouse wheel | Scroll horizontally in the hovered pane: wheel down moves right, wheel up moves left. Native horizontal-wheel/trackpad events also work. |
The comment dialog is nine rows tall (or smaller to fit the terminal). Its text field wraps and scrolls to keep the cursor visible. Enter inserts a newline; Alt+S saves and Esc cancels. Existing comments also support Alt+R to resolve or reopen. Alt+D discards a new draft or deletes an existing comment; Delete and Backspace only edit text. Actions appear as inline shortcut hints, not buttons, and Tab does not switch actions. Saving runs in the background; the dialog closes after a successful write and stays open on failure. Once a write starts, dialog cancellation is disabled.
Comments and provider visibility
Comments belong to the worktree, not the session. They survive restarts and session changes. Storage is JSON under $MC_HOME/state/diff-review/<hash>.json; the hash comes from the canonical Git worktree root, not the launch subdirectory or shared Git directory. Linked worktrees therefore have separate comments.
Writes use a cross-process lock and atomic replacement. On Unix, the review directory uses 0700 and comment files use 0600. Storage rejects symlink files and directories. These files are not encrypted.
On refresh, comments follow matching line text, using neighboring lines to help find the location. Missing or ambiguous anchors mark a comment stale. Stale status stays set even if a later refresh finds a match; editing text or resolving/reopening does not reset it. Comments remain accessible when their file disappears or leaves the current diff. Check a stale comment's location before acting on it; delete and recreate it to establish a new anchor.
Saving a comment does not send a provider request. Review context is opt-in: root user prompts and queued steering include it only with a standalone #diff-changes tag. Unresolved comments include stale comments and their original anchors. Resolved or deleted comments are excluded from future expansions.
Add #diff-changes to a prompt or steering message to include only unresolved comments: each comment's ID, path, side, line, original anchor, stale status, and text. No changed code, hunks, or file list is included. With no unresolved comments, the result is No unresolved Diff comments.:
Address these review notes. #diff-changes
The tag uses the review backend, not a bash command. It loads saved comments and reanchors their files without scanning the worktree's changed-file list. Selecting autocomplete only inserts the tag. Tag failures report an error. Subagent and internal prompts do not expand this tag or load worktree comments.
Submitted transcript cards show the expanded prompt, including comments or expansion errors, for both initial input and steering. The same text is sent to the provider and persisted in session history. Resolving or deleting a comment does not remove copies already sent to the provider or saved in earlier session messages. Avoid putting secrets in comments or their source anchors.
Limits and notices
- The changed-file scan includes at most 128 files. Stored comments can retain additional file entries.
- Each original/current source is limited to 128 KiB, with a shared 4 MiB source budget per snapshot. Oversized sources are omitted, not presented as complete.
- Syntax highlighting runs progressively on the worker, preserving parser state and sharing time between Original and Diff. Unfinished highlighting continues automatically; source stays visible while it catches up. Added and removed lines retain themed diff colors.
- All three panes use shared themed vertical and horizontal scrollbars. Horizontal positions are independent; changing files resets the source panes to the left edge. Line-number gutters fit the source length. Colored
[•]markers identify comments; resolved comments show[✓]. - Provider comment context is bounded to 64 KiB of text, followed by a truncation notice when needed.
- Each worktree stores at most 256 comments, with nonblank text up to 8 KiB per comment and a 1 MiB JSON store limit.
- Binary/non-UTF-8 files, symlinks, submodules, and other non-regular files are unsupported. Omitted files/sources and read failures have explicit notices; new comments cannot be saved on omitted source.
- Git operations have a three-second timeout per command within a shared five-second scan deadline, and honor cancellation. Refresh and context errors are reported rather than treated as an empty, successful review.
Implementation: src/diff_review.rs, src/diff_review/, src/tui/diff/, and src/agent/prompt_injections.rs.