Skip to content

padenot/lrv

Repository files navigation

lrv

lrv is a local review UI for unified diffs. It reads a diff from stdin, --cmd, or --file, opens a browser UI backed by Monaco, and prints submitted comments to stdout as JSON or text. It can also show comments from a phabricator revision, or review comments generated by another tool.

Its purpose is to easily show the diff created by an AI agent to a human, that can comment on it. The comments are fed back to the agent.

Users

Install:

cargo binstall lrv
# or
cargo install lrv

lrv supports three review workflows:

  1. Review local code changes.
  2. Review existing Phabricator comments inline.
  3. Run a local LLM self-review first, then show those generated comments to the author.

Local changes:

git diff | lrv
git diff --staged | lrv
git show HEAD | lrv
lrv --cmd "jj diff --git"
lrv --file changes.patch

Phabricator review comments:

PHABRICATOR_API_KEY=... git show HEAD | lrv --phab-revision D123456

Local LLM self-review:

# The driving agent reviews the diff first and writes review-notes.json.
git diff > /tmp/lrv.diff
lrv --file /tmp/lrv.diff --review-notes-file review-notes.json

To review a commit series (all commits in a branch at once):

lrv --series "trunk()..@"          # jj revset
lrv --series "main..HEAD"          # git range
lrv --series "HEAD~5..HEAD"        # last 5 commits

The UI shows a commit strip for navigating between commits. Comments track which commit they belong to and are grouped per commit in the output.

Useful flags:

--series <RANGE>   Review a jj revset or git range as a commit series
--no-open          Don't auto-open a browser
--format text      Print comments as text instead of JSON
--title "..."      Show a custom title in the header
--review-notes-file notes.json
                  Render pre-existing review notes inline with the diff;
                  can be repeated
--phab-revision D123456
                  Render Phabricator review comments inline with the diff
--config-dir       Print the config directory path and exit
--bind <ADDR>      Bind a specific address (default: 127.0.0.1)
--public           Bind on all interfaces
--tailscale        Also bind detected Tailscale IPv4 addresses

Network exposure:

  • By default, lrv binds to 127.0.0.1, so only your machine can reach it.
  • In practice, lrv --tailscale usually listens on both 127.0.0.1:<port> and your local Tailscale 100.x.y.z:<port>.
  • lrv --public --tailscale usually listens on 0.0.0.0:<port> plus any detected Tailscale 100.x.y.z:<port>.
  • --public, --bind 0.0.0.0, and --tailscale expose the review UI and diff contents over plain HTTP with no auth.
  • Only use those flags on trusted private networks or Tailscale peers you trust.

Notes:

  • Submitted comments are written to stdout, so you can pipe or capture them.
  • Review notes are display-only annotations. They reserve space below the target line in the diff and are not included in submitted review output. --review-notes-file accepts a JSON array of objects with file, line, side, and body; optional fields include author, date, source_url, and commit_idx.
  • For a local LLM pre-review, the agent should review the diff before starting lrv, write its findings as review notes JSON, and pass that file with --review-notes-file. The author can then Address, Reply, or Ignore those local reviewer comments in the UI before submitting.
  • Phabricator notes use PHABRICATOR_API_KEY or PHABRICATOR_TOKEN; set PHABRICATOR_BASE_URL or pass --phab-base-url for non-Mozilla instances.
  • lrv --version prints the current version and can warn if a newer release exists.

Review notes JSON shape:

[
  {
    "file": "src/file.rs",
    "line": 42,
    "side": "new",
    "body": "Comment text shown inline.",
    "author": "Local LLM review"
  }
]

Customization

Settings (theme, font, view mode) are saved to ~/.config/lrv/config.toml.

Custom themes

lrv ships with GitHub, Solarized, Firefox DevTools, and the built-in Monaco themes. To add your own, drop any VS Code theme JSON file into the themes/ subdirectory of your lrv config directory:

mkdir -p "$(lrv --config-dir)/themes"
cp my-theme.json "$(lrv --config-dir)/themes/"

lrv --config-dir prints the platform-correct path (~/.config/lrv on Linux, ~/Library/Application Support/lrv on macOS, %APPDATA%\lrv on Windows).

The theme appears in the Settings dialog under Custom on the next launch. VS Code themes are widely available:

  • VS Code Marketplace — themes ship as .vsix files (zip archives); the JSON is inside under themes/
  • monaco-themes npm package — 30+ themes already in Monaco format

Development

Prerequisites:

  • Rust toolchain
  • Node.js + npm
  • just
  • Playwright Firefox for e2e: just setup-e2e

Main workflows:

just build
just test-unit
just test-e2e
just ci

cargo build / cargo run will rebuild the embedded web bundle automatically when frontend inputs change. You can still run npm run build:web directly if you only want to rebuild the frontend bundle.

Frontend

The browser UI uses Monaco for the file-by-file diff editor. The stacked diff view and the sidebar file tree are intentionally delegated to Pierre's components:

  • @pierre/diffs renders the stacked diff. It is loaded lazily only when stacked mode is opened, and syntax highlighting runs through the library worker asset.
  • @pierre/trees renders the sidebar file tree.

Keep the Monaco path separate from the stacked path. Changes to file selection, review note placement, comment rendering, or theme variables may need updates in both modes.

License

Licensed under either of:

  • Apache License, Version 2.0
  • MIT license

See LICENSE-APACHE and LICENSE-MIT.

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors