Skip to content

v0.2.0

Choose a tag to compare

@markerikson markerikson released this 14 Oct 22:16
· 83 commits to main since this release

This major release is a complete rewrite. It replaces the single-call LLM analyzer with a multi-agent review pipeline, adds a local web UI for reading reviews and grouped diffs, saves every run so you can reopen and re-review it, and adds diffloupe diff, a grouped diff viewer that needs no model calls.

Warning

0.1 was my initial intent-only review tool, and no one but me used it :) 0.2 shares almost no code with 0.1. The analyze, pr and summarize commands are gone. DiffLoupe now runs under Bun and drives its agents through OpenCode. See Breaking Changes below.

Changelog

Why the Rewrite

0.1 sent the diff and some nearby files to Claude through TanStack AI and asked for an intent summary, a risk list and an intent check. For large diffs it split the work into two passes or into "flows". It worked, but it was one model reading a diff with very little of the codebase in view. The findings were often guesses that a reviewer could have ruled out by opening one more file.

I'd been building a multi-agent code review pipeline at Replay, and it had done much better on real PRs. 0.2 ports that pipeline into DiffLoupe as the review core and builds a new CLI, server and web UI around it. I also borrowed ideas from a number of other tools along the way (see Inspirations).

Multi-Agent Reviews

diffloupe review now runs in four stages:

  1. Group. The changed files are grouped into review units from links in the code: a name defined in one file and used in another, a test and its source, an import, a shared directory. Generated and lock files are skipped. Docs are listed but not reviewed in depth.
  2. Review. Each unit gets its own reviewer agent. The agent reads the surrounding code with tilth and reports findings with evidence. Up to six reviewers run at once.
  3. Coordinate. A coordinator merges and deduplicates the findings, drops the ones it cannot verify, and checks the change against its stated intent: the PR description, --intent, or the commit messages.
  4. Walk through. A walkthrough pass orders the change into chapters and stops, with a "start here" list.

Every agent runs through OpenCode with a config that DiffLoupe writes for each run. Your own agents, plugins and MCP servers are not used. Your default model and your providers block are.

The default models are Claude Opus 5.5 for the reviewers and the coordinator, and Claude Sonnet 5.5 for the walkthrough and group naming. With those defaults, real runs so far have cost about $0.10 for a one-file commit, about $1 for a small PR, and $4–5 for a large one. Use --max-cost or maxCostUsd to set a limit. The run page and diffloupe runs show what each run cost.

review accepts many more targets than 0.1 did: worktree (the default), staged, any commit (HEAD~2, a SHA, a tag), a..b and a...b ranges, branch:<name>, and pull requests as #123 or a URL. Pull requests are reviewed in a temporary worktree at the PR head, so your checkout is not touched. --headless runs without a server and prints a summary, or the full review with --markdown.

The Web UI

review and diff start a local server, print the run URL, and stream progress to the terminal. The page layout follows pulls.review, and diffs are rendered with @pierre/diffs.

  • A summary at the top, laid out like a GitHub review comment: merge risk and production risk, finding counts, findings grouped by file, whether the change matches its intent, and where to start reading.
  • Groups in the sidebar and down the page, each with a short summary and its own file tree. Under each file in the tree, one row per finding and per walkthrough stop links to its line.
  • Finding cards under the lines they refer to, with explanation, evidence and a suggested fix.
  • Walkthrough stops as separate cards, with a Guide mode in the sidebar for stepping through them in order.
  • Copy on each finding and Copy all put the findings on the clipboard as markdown, ready to paste into a coding agent.
  • Keyboard navigation (j/k files, n/p findings, ]/[ stops, ? for the full list), and browser Back/Forward between the findings you jumped to.
  • While a review runs, the page shows its progress and fills in the file groups as soon as grouping finishes.

The server only accepts loopback hosts and same-origin requests. If a diffloupe serve is already running, review, diff and open use it instead of starting another server.

Saved Runs and Re-Reviews

Each review is saved as a run under ~/.local/share/diffloupe/runs/. diffloupe runs lists runs, and runs show prints one, optionally as markdown. diffloupe open reopens a run in the browser. runs rm and runs prune delete old runs along with their scratch files and pinned refs.

Reviewing the same target again links the new run to the previous one. Findings that were fixed are listed as fixed, and findings that are still open are carried forward instead of being reported again.

diffloupe diff

diffloupe diff shows a target's diff in the web UI, grouped the same way as a review, with no review agents and no credentials. It takes about a second. Grouping reads files from git objects, so no worktree is created. --walkthrough adds the walkthrough guide from one model call.

owner/repo#123 and PR URLs also work outside a clone of that repository. DiffLoupe keeps a blobless copy of the repo under ~/.local/share/diffloupe/repos/ and fetches only the commits and file contents it needs. A diff run page has a Review these changes button that starts a full review of the same commits.

Models, Credentials and doctor

Each stage (review, coordinator, walkthrough) looks up its model on its own: REVIEW_* environment variables, then --model, then the per-repo --config file, then ~/.config/diffloupe/config.json, then the model in your global OpenCode config, then the built-in defaults.

For credentials, DiffLoupe checks each provider's environment variable first, then apiKeys.<provider> in its config, then an API key saved with opencode auth login. OAuth logins such as a Claude subscription are not shared with the agents. If a provider has no credential, the review stops before it starts and names the provider, the stage, and the ways to add one.

diffloupe doctor checks Bun, git, OpenCode, tilth and gh. It prints the model for each stage and where that choice came from, the source of each provider credential, and how much disk the data directory uses.

DiffLoupe no longer loads .env files, so a .env in a repo you review cannot supply or override a key.

Breaking Changes

  • Removed commands: analyze, pr and summarize. Use diffloupe review <target> instead. Pull requests are now a target (#123, a URL, or owner/repo#123 for diff).
  • New requirements: Bun 1.3 or later runs the CLI, even if you install with npm. OpenCode 2.x and tilth are required for reviews. gh is needed only for pull requests.
  • Config: ~/.config/diffloupe/config.json now holds provider, models, effort, apiKeys, maxCostUsd, host and port. The config location honors XDG_CONFIG_HOME.
  • Platforms: developed and tested on Linux and WSL2. macOS should work but has not been tried. Native Windows is not supported; use WSL.

Packaging

The npm package is a self-contained Bun bundle with no runtime dependencies. The web build splits out vendor chunks and drops unused Shiki themes, grammars and WASM.

Inspirations

DiffLoupe borrows ideas from a lot of other tools:

  • pulls.review: the page layout, with grouped files, sticky group panels and per-group file trees
  • Codiff: a diff viewer with walkthroughs
  • @pierre/diffs: the diff renderer
  • Plannotator: the local review server, browser opening and request guards
  • LaReview: flow-based grouping
  • GitHuman: pre-commit review
  • Diffray: validation patterns and confidence scoring
  • Critique: prompt engineering principles
  • CodeRabbit: incremental review

Full Changelog: https://github.com/markerikson/diffloupe/compare/8ece6de31..v0.2.0