README.md
Local Code Review (lcr)
Local code review tool for AI-assisted development. Review uncommitted changes with a GitHub PR-like interface — inline comments, suggestions, questions — then approve (and commit in git, or simply approve in jj) or send feedback to AI for another round. Works with git and Jujutsu (jj) repositories.
Why?
When developing with AI (vibe-coding), AI makes many changes at once. There’s no good way to review those changes and give structured feedback before committing. Diff tools show changes but don’t let you write comments. Chat interfaces take one comment at a time. This tool gives you the full PR review experience locally:
- See diffs like a GitHub PR (unified or split view, syntax highlighted)
- Write inline comments on any line — comments, suggestions, questions
- Approve individual files to stage them for commit
- Toggle between full diff and unstaged-only to focus on what still needs review
- Submit a structured review with all your feedback at once
- Send to AI — export review as JSON/Markdown, copy to clipboard, or send directly to Claude Code via built-in terminal
- Outdated detection — comments are automatically flagged when the underlying code changes
- Approve & commit when you’re satisfied (in jj repos, just approve — changes are autocommitted)
Install
npm install -g local-code-review
Requires Node.js 18+.
Nix / devenv
lcr is also installable as a Nix flake. It builds from source with
pnpm run build and exposes bin/lcr as the lcr executable:
nix run git+https://git.kilimanjaro.io/local-code-review -- /path/to/repo
To add it to a devenv environment, add the source as an
input in devenv.yaml:
inputs:
local-code-review:
url: git+https://git.kilimanjaro.io/local-code-review
and the package in devenv.nix:
{ inputs, pkgs, ... }:
{
packages = [ inputs.local-code-review.packages.${pkgs.system}.default ];
}
lcr uses the git / jj binaries from your environment (they are not
bundled into the package).
Quick Start
cd your-project
lcr
Opens a web UI at http://localhost:5678 showing all uncommitted changes.
Usage
Reviewing a project
Run from inside any git or jj repository:
lcr # Review current directory
lcr /path/to/project # Review a different project
The repository type is auto-detected: if a .jj/ directory is present (and the jj CLI is available), the Jujutsu client is used; otherwise git is used. This works for colocated repos too.
Running multiple instances
Each instance needs its own port:
lcr # First project on default port 5678
PORT=5679 lcr /path/to/other # Second project on port 5679
Review flow
- Browse changed files in the sidebar
- Click the
+button on any line to add a comment - Choose comment type: comment, suggestion, or question
- Add comments across multiple files
- Approve individual files (checkbox in sidebar) — in git repos approved files are staged; in jj repos approval is tracked by the tool
- When done, click Review and choose:
- Request Changes — sends your review to Claude Code for another iteration
- Approve & Commit (git) / Approve (jj) — in git, opens the commit dialog; in jj, moves the
mainbookmark forward to the reviewed change (see Stacked changes below)
Diff scope
- Uncommitted (default) — git: uncommitted changes vs HEAD; jj: changes in the working-copy commit
@vs its parent (jj diff -r @). If@is a merge, jj diffs against the auto-merge of all parents. - Worktree — git: the full branch diff (all commits since the branch diverged from main/master/development, plus uncommitted changes); jj: the diff from the
mainbookmark to the change being viewed
Diff modes
- Full Diff — shows all changes in the current scope (staged + unstaged, or full branch)
- Needs Review — git: shows only unstaged changes; jj: shows only files that haven’t been approved yet
Export options
Click Export in the toolbar:
- Send to Claude Code — sends review to Claude via the built-in terminal
- Copy to Clipboard — paste into any AI chat
- Export as JSON — saves
.lcr-review.jsonin the project root - Export as Markdown — saves
.lcr-review.mdin the project root
Built-in terminal
The tool includes an embedded terminal that runs an interactive Claude session in your project directory. When you click “Request Changes” or “Send to Claude Code”, your review is sent directly to this terminal session. Claude can then make changes, and you can review the next round without leaving the tool.
The terminal uses a WebSocket connection on a separate port (main port + 1000 by default).
Outdated comments
When AI makes changes after you’ve submitted a review, comments on lines that changed are automatically marked as Outdated with a yellow badge. This happens whenever the diff is refreshed, so you can see which of your comments have already been addressed.
File approval
Click the checkbox next to any file in the sidebar to approve it. Approved files are:
- git: staged (git add); jj: tracked as approved in memory (jj has no staging area)
- Shown with a strikethrough in the sidebar
- Excluded from the “Needs Review” diff mode
If an approved file is modified again, its approval status is reset.
Stacked changes (jj)
In jj repositories the sidebar shows a Changes panel below the file tree, listing every change that descends from the main bookmark (newest first). This supports a feature-by-feature session workflow:
- The agent stacks changes on top of
main(squashing as it goes); the panel tracks them and refreshes automatically as work lands. - Click a change to review only that change’s diff against its parents. Selecting is view-only — it does not move your working copy
@, so the agent is never disrupted. - Click Approve to move the
mainbookmark forward to the change you are reviewing, marking the feature as accepted. The view then advances to the next change above it.maincan only move forward. - At the end of the session, push the accepted work yourself, e.g.
jj git push --bookmark main.
The local main bookmark is the source of truth (not trunk()/main@origin), so approvals are reflected immediately, even before you push.
Keyboard shortcuts
| Key | Action |
|---|---|
j / k |
Navigate files |
b |
Toggle sidebar |
Cmd/Ctrl+Enter |
Submit comment / commit |
Escape |
Cancel comment |
Configuration
Environment variables
| Variable | Default | Description |
|---|---|---|
PORT |
5678 |
HTTP server port |
LCR_REPO_DIR |
Current directory | Path to the git or jj repository to review |
VITE_LCR_WS_PORT |
PORT + 1000 |
WebSocket port for the terminal (dev mode only) |
Claude Code integration
The “Send to Claude Code” feature requires Claude Code CLI to be installed. The tool uses whatever model your Claude Code is configured with. To change the default model:
claude config set model claude-sonnet-4-6
# or
claude config set model claude-opus-4-6
Development
Setup
git clone <repo>
cd local-code-review
npm install
npm run dev
The dev server starts at http://localhost:5173 by default.
Testing with another project
Point LCR_REPO_DIR at a different git repository:
LCR_REPO_DIR=/path/to/your/project npm run dev
To run multiple dev instances simultaneously, each needs its own port and WebSocket port:
# Instance 1 (default ports: 5173 + WS on 6173)
LCR_REPO_DIR=/path/to/project-a npm run dev
# Instance 2 (custom ports: 5174 + WS on 6174)
LCR_REPO_DIR=/path/to/project-b VITE_LCR_WS_PORT=6174 npm run dev -- --port 5174
Building
npm run build
Test the production build locally:
node bin/lcr.js /path/to/project
Project structure
src/
lib/
components/ # Svelte UI components (DiffView, FileTree, Terminal, etc.)
server/ # Server-side code (VCS abstraction, git/jj clients, review store, terminal)
stores/ # Svelte stores (files, review, UI state)
types/ # TypeScript interfaces
routes/
api/ # REST API endpoints (diff, comments, export, commit, etc.)
+page.svelte # Main page
bin/
lcr.js # CLI entry point
Notes
- Jujutsu repos are auto-detected by the presence of a
.jj/directory and require thejjCLI onPATH. In jj repos there is no commit step: the working copy is autocommitted, so Approve moves the localmainbookmark forward to the reviewed change (main@originis left untouched) - Comments are stored in memory and reset when the server restarts
- The
.lcr-review.jsonand.lcr-review.mdexport files are created in the project root — add them to.gitignoreif needed - Syntax highlighting is powered by Shiki (same engine as VS Code)
- The terminal feature requires
node-ptywhich needs a C++ compiler to build (usually available by default on macOS/Linux)
License
MIT