# 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:

```bash
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:

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

Phabricator review comments:

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

Local LLM self-review:

```bash
# 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):

```bash
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:

```text
--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:

```json
[
  {
    "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:

```bash
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](https://marketplace.visualstudio.com/search?target=VSCode&category=Themes) — themes ship as `.vsix` files (zip archives); the JSON is inside under `themes/`
- [`monaco-themes`](https://www.npmjs.com/package/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:

```bash
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.

## License

Licensed under either of:

- Apache License, Version 2.0
- MIT license

See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT).
