Skip to content

About

A terminal based code review tool

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

180 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TurboReview

Rust Platform UI

turboreview is a terminal code-review tool for git repositories. Review the working tree or browse the branch's commit history, with a file tree on the left and the selected diff (syntax-highlighted, adjustable context) on the right. Stage files, mark them reviewed, leave line comments — and let an AI coding agent read those comments, fix the code, and respond. It can also debug straight from the diff (breakpoints, stepping, variable inspection, even debugging a past commit) and overlay test coverage.

turboreview screenshot
TurboReview diff

Install

Prerequisites:

  • A recent stable Rust toolchain (cargo) and git. Install Rust via rustup: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh.
  • A C compiler / build toolchain — git2 (libgit2) and libz are built from source. macOS: Xcode Command Line Tools (xcode-select --install). Linux: build-essential and pkg-config.
  • Linux only: X11 clipboard libraries for copy support (arboard), e.g. on Debian/Ubuntu: libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev.
  • A Nerd Font set in your terminal for the file-type glyphs.
  • Optional: the pi coding agent, only for the Pi chat popup (P). Everything else works without it. See Pi chat.

From crates.io

cargo install turboreview

The turboreview binary lands in ~/.cargo/bin — make sure that's on your PATH.

From source

git clone https://github.com/nmbr7/turboreview.git
cd turboreview
cargo install --path .          # installs the release binary to ~/.cargo/bin

Developing

cargo run -- [REPO_PATH]        # run against a repo (defaults to .)
cargo test                      # run the test suite
cargo fmt && cargo clippy       # format + lint

Updating later: re-run cargo install turboreview (add --force to overwrite an older build).

Usage

turboreview [REPO_PATH]   # defaults to the current directory
turboreview --skill       # print the AI-agent guide and exit
turboreview --watch       # stream review comments as JSON lines (for an agent)
turboreview --watch --replay   # ... including comments already open

Run inside (or point at) any git repository.

Layout

Two views, toggled with [ / ]:

  • Changes — the working tree. Left pane has two sections, ▌ Unstaged (N) and ▌ Staged (N), each a collapsible directory tree.
  • Commits — the branch history. Left pane lists commits (short hash, summary, author, date, and per-commit diff stats N files +ins -del). Diff stats are computed lazily for the rows in view. The list loads 50 commits at a time; scroll to the bottom and press L to load the next page. Press Enter on a commit to drill into its changed files (diff vs the commit's first parent); Esc steps back out.

In both views:

  • Left pane — Files. Each file row shows a colored status letter (A added, M modified, D deleted, R renamed), a review tick (✓ reviewed / ○ not), and a Nerd Font file-type icon. The pane can be resized or hidden entirely (see keys).
  • Right pane — Diff. Syntax-highlighted code with a line-number gutter. Added/removed lines are bright with a green/red background; unchanged context lines are dimmed so changes stand out. A line cursor (highlighted row) marks where comments attach. The title shows (ctx N) or (full file). Press v for a side-by-side (split) view — old on the left, new on the right — which is remembered across sessions.
  • Comments pane (toggle with C). An optional third column listing the current scope's comments grouped by status (Open / NeedsInfo / Wontfix / Resolved). Press Enter on a comment to jump to its file and line.

Press ? at any time for an in-app keybinding overlay.

Keys

Key Action
[ / ] switch view (Changes ⇆ Commits)
Tab switch focus across the visible panes
↑/↓ j/k move selection / commit / line cursor in the focused pane
⇧↑/⇧↓ J/K jump (fast scroll) in the focused pane
mouse wheel move the focused pane's cursor
gg / G jump to top / bottom of the focused pane
L load more commits (Commits view, when more history exists)
Enter open commit (straight to its first file's diff) · focus a file's Diff · fold dir · jump to comment
W switch to another worktree of this repo (type to filter, Enter switches)
Ctrl-T review timer: type a duration (up to 99h) and optional label (25 comments, 1 min review, 90s, 1h 30m, 10:00, 1:30:00) or pick a preset (5–45 min). Tab moves to Remind: comma-separated reminders, 5 or 5m left (5 min before the end), every 5 (every 5 min in, at most every 10s: a 15-min timer reminds at 10:00 and 5:00 left), after 10 (10 min in); each rings the bell and shows a notice under the countdown for a few seconds, and new timers start with the last reminders set. The countdown shows at the top middle of the screen (red in the last minute); when it runs out an alarm pops up with a terminal bell (Enter dismiss, r restart, s snooze 5 min; while you are typing a comment, a Pi prompt or a search only Esc dismisses it, and your typing goes on). Ctrl-T while it runs: Space pause, +/- 5 min, r restart, x stop, n new. It keeps running across worktree and repository switches
Ctrl-P find a file or folder (fuzzy; changed files first) and open it: a changed file in its diff, an unchanged one in the all-files list, a folder unfolded in the file list. A query starting with / or ~ browses the whole disk instead (Tab goes into a folder); Enter opens the pick in its own git repository, switching to it
* pin / unpin the selected file (see Pinned files)
' open the Pinned tab: pinned files of every repo, with open comments and changes per repo (Enter opens, d unpins); again closes the right pane
C open the comment-list pane (again closes the right pane): the open view's comments, then those on other reviewed commits (Enter jumps to any of them)
Space / a in the comment pane: resolve / reopen the selected comment · archive it (asks first)
c (comment pane) reply to the selected comment; a reply on a closed comment reopens it
o in the diff: preview the comment on the cursor line, with the code it was originally written against
p show / hide agent responses in the comment pane
u hide / show resolved comments, in the diff and the comment pane
S hide / show outdated comments in the diff (pane still lists them)
Esc step back (Diff → files → commit list) / focus the Files pane
h/l ←/→ scroll the diff horizontally (Diff pane)
+ / - increase / decrease diff context (step 5; + at max → full file)
F toggle full-file view (shortcut; also reachable via +)
v toggle side-by-side (split) vs unified diff (persisted)
d cycle diff style: dim → bright → plain (persisted)
w toggle wrapping of long diff lines (persisted)
H file-history overlay for the selected file's diff
{ / } step to older / newer revision (in the history overlay)
/ search within the current diff
n / N jump to next / previous search match
a fold / unfold all directories in the file tree
O view all tracked files / changed files only
e toggle macro-expanded view of the selected file
z hide / show the file pane (diff goes full-width)
< / > narrow / widen the focused pane (files or the right pane)
c comment on the cursor line (opens a modal input box)
E edit the cursor line / V selection in the file (unstaged only); Ctrl-S writes
←→↑↓ Home End move the cursor in the comment / edit box
s stage the selected file or folder (Unstaged) / unstage it (Staged)
s (Diff pane) stage / unstage the hunk under the cursor, or every hunk a V selection touches
Space toggle the reviewed checkbox on the selected file
R toggle hiding reviewed files
A archive resolved comments in the current scope (asks y / n first)
r refresh everything from disk / git (also applies agent updates)
% toggle test-coverage highlight (LCOV)
M run the configured coverage command, then show it
P open the Pi chat popup (needs pi; see Pi chat)
? show the keybinding help overlay (type to search it)
qq / Ctrl-C quit (press q twice to avoid accidental exits)

Debugging (right pane Debug tab; see Debugging):

Key Action
b toggle a breakpoint on the cursor line (Diff pane)
D launch a debug session (a selected commit in Commits, else worktree)
[ / ] right pane: switch the Comments / Pinned / Debug tab (when focused)
t Debug tab: switch the Vars / Breakpoints view
c/n/i/o continue / step over / step in / step out (Debug focused)
Enter Vars: expand a variable · Breakpoints: jump to it
Space / d Breakpoints tab: enable-disable / delete a breakpoint
h / l scroll the Debug pane horizontally
Ctrl-D in the comment box: attach the stopped call stack to the comment
X end all debug sessions (asks y / n first)

In the comment input box: type freely, Enter for a newline, Ctrl-S to save, Esc to cancel. Saving an empty comment deletes it.

Staging

s on a file in the Unstaged section stages it; on a file in the Staged section it unstages it. Staging only moves changes into or out of the git index — your working-tree files are never modified. (Hunk-level staging is not yet supported.)

Comments

Press c on a diff line to attach a comment. Comments render in a bordered box directly under their line.

Each comment is anchored to its line's content plus the surrounding lines, so it follows the line when the file shifts (e.g. lines inserted above). If a comment can no longer be confidently placed, it is shown as ⚠ outdated rather than lost.

AI-agent review loop

Comments carry a status (open, resolved, wontfix, needs_info) and an optional response. An AI coding agent can close the loop:

  1. Run turboreview --skill to print a guide describing the on-disk schema and workflow. The guide has the agent ask whether to save a pointer to it — as a skill in the agent's skills folder if it has one, otherwise in the repo's CLAUDE.md / AGENTS.md — so later sessions know to read it.
  2. The agent reads the open comments, makes the requested changes, then writes a response and sets the status in the relevant comments.json.
  3. Reopen turboreview — each comment box shows the agent's status badge (✓ resolved, ✗ wontfix, ? needs-info) and its response inline.
  4. The agent leaves its fixes unstaged and stops there. You review the diff and approve before anything is staged or committed — the agent never commits its own fix on your behalf.

Ask the agent to "review my past comments" and it will distil recurring feedback into .turboreview/lessons.md, then read that file at the start of later fix loops so the same review note doesn't have to be written twice.

Live review

You don't have to quit and reopen. While turboreview is running it watches the current scope's comments.json, so when an agent responds you get a notification in the comment pane and the status bar:

● agent resolved 2, needs info on 1 — press r to reload

Nothing moves until you press r — the view never shifts under you mid-read. The banner says only what changed; r applies it.

There is no daemon and no socket: both sides poll the same file. turboreview stats comments.json every ~500ms while you are idle (mtime and length, so two writes in one timestamp tick are still caught).

For the other direction, an agent runs:

turboreview --watch            # one JSON object per line, as comments arrive
turboreview --watch --replay   # plus comments already open when it starts

It streams every scope (the worktree and each reviewed commit) and keeps running, so the agent reads a line at a time instead of polling by hand:

{"kind":"new","scope":"worktree","path":"/repo/.turboreview/comments.json",
 "file":"src/a.rs","line":42,"orig_line":40,"text":"use a const here",
 "line_text":"let x = 2;","hunk":"@@ -1,4 +1,4 @@","stale":false}

kind is new, edited (you reworded it) or reopened (you rejected the fix — the line carries the agent's previous_response). Replies the agent writes are not echoed back, so answering cannot loop. path names the file to write the reply into, which matters because a comment left on a commit belongs to that commit's store, not the worktree's.

Agent review

An agent can review your changes and leave its findings as comments you read in turboreview:

turboreview comment add --file src/a.rs --line 42 --severity bug --author claude --text "…"
turboreview comment list [--commit SHA | --all] [--status open] [--author claude]
turboreview comment reply --id c7f3a1 --status resolved --text "…"

Findings show the agent's name and severity, bugs first. Reply from the comment pane with c; the agent sees your reply (turboreview --watch reports it as replied) and answers in the same thread.

File history & search

Press H on a file's diff to enter the history overlay — it walks the commits that touched that file (newest first). { steps to an older revision, } to a newer one; } past the newest returns to the live diff, and Esc exits. While stepping, the cursor stays on the same line number, the view scrolls to keep it centered, and context is expanded (up to full file) if needed to show that line. Comments made on a past revision are stored in that commit's scope (.turboreview/commits/<sha>/).

Press / to search within the current diff (case-insensitive substring). n and N jump to the next and previous match.

Debugging

turboreview can drive a debugger straight from the diff, using the Debug Adapter Protocol (any DAP adapter: lldb-dap, codelldb, debugpy, …). Configure it under debug in .turboreview/config.json (see docs/debug-config-example.md):

"debug": {
  "adapter": { "command": "lldb-dap", "args": [] },
  "build":   "cargo build",                 // run before launch
  "program": "target/debug/your-binary",    // built binary (relative to source root)
  "args": [], "cwd": ".",
  "source_map": []
}
  • Press b on a diff line to set a breakpoint (a ● shows in the gutter), then D to build + launch. The right pane's Debug tab shows the call stack and the selected frame's variables; ▶ marks the stopped line.

  • Tab to focus the Debug pane, then step with c / n / i / o. Enter expands a structured value (String/Vec/struct/map) to its contents; each variable shows its type and memory address.

  • t switches the Debug pane between Vars and Breakpoints (the breakpoint list: Enter jumps, Space enables/disables, d deletes).

  • Press D to open the launch picker: debug the working tree, a selected commit, attach to a running process, or attach to a remote target.

  • Attach to a process: pick process to open a filterable list of running processes (type to filter by name or pid, Enter to attach).

  • Debug a past commit: pick commit in the Commits view — turboreview checks it out in a throwaway git worktree, builds it there, and debugs that historical binary (cleaned up when the session ends).

  • Remote attach (gdbserver / Docker): pick remote to attach to a running target. Configure it under debug.remote (and use source_map to map the remote source paths to your local checkout):

    "debug": {
      "remote": { "host": "localhost", "port": 1234 },
      "source_map": [["/build/src", "/local/repo/src"]]
    }

    host/port run gdb-remote host:port; for other setups set remote.attach_commands to raw adapter commands instead.

  • Attach a snapshot to a comment: while stopped, press c to comment, then Ctrl-D to attach the current call stack + locals. It's saved with the comment and shown inline, so a reviewer keeps the exact runtime state.

  • O toggles view all files (every tracked file, not just changed ones) so you can open and breakpoint anywhere in the codebase. X ends the session.

Test coverage

Press % to overlay coverage from an LCOV file: a ▌ bar in the gutter is green for covered lines, red for uncovered. The footer shows overall and current-file percentages. Configure the file (and, optionally, a command that generates it) in .turboreview/config.json:

"coverage_file": "coverage/lcov.info",
"coverage_command": "cargo llvm-cov --lcov --output-path coverage/lcov.info"

Press M to run the command and reload. Any tool that emits LCOV works (cargo llvm-cov, tarpaulin, nyc, gcov, …).

Macro-expanded view

Press e to replace the diff with the macro-expanded source of the selected file (read-only, syntax-highlighted); e again restores the diff. It runs a configurable command and shows its stdout. The {module} and {file} placeholders are substituted (module path derived from the src/-relative path):

// crate with both a lib and a bin needs an explicit target:
"expand_command": "cargo expand --lib {module}"

Default is cargo expand {module} (needs nightly + cargo-expand). Switching files leaves the expanded view.

Configure several named commands to get a picker on e:

"expand_commands": [
  { "name": "lib",     "command": "cargo expand --lib {module}" },
  { "name": "example", "command": "cargo expand --example $(basename {file} .rs)" }
]

With one (or none) configured, e runs it directly; with several, it opens a selection popup.

Pinned files

Documents you are reviewing across several repositories can be pinned, and every turboreview instance lists them in the right pane's Pinned tab, grouped by repository.

  • * on a file (Files or Diff pane) pins it; * again unpins it.
  • ' opens the Pinned tab (and focuses it). ' while the Pinned tab shows, or C while the Comments tab shows, closes the right pane; either key on the other tab switches to its own.
  • Enter on a pin opens it. A pin from another repository switches this instance into that repository first (as W does for worktrees), so its comments, reviewed flags and agent handoff all use that repository's .turboreview/. Enter on a repository header just switches there.
  • d unpins (asks y / n first, as does * on a pinned file). The open file is marked ▶; a pinned file gone from disk is red.
  • Each repository header shows what is waiting there: ● N open comments (over every view: working set, commits, ranges, branches), ? N needs info, and ± N changed files with uncommitted changes (.turboreview/ itself left out), or clean. A pin shows its own pending comments (● N) and M when the file has uncommitted changes. The counts are read in the background and refresh every few seconds while the tab shows.

From a shell:

turboreview pin add docs/design.md ../other-repo/RFC.md
turboreview pin            # list, one absolute path per line
turboreview pin rm docs/design.md

Pins live in ~/.turboreview_root/root_config.json (set TURBOREVIEW_ROOT to use another folder), one entry per file with its repository root and its path inside it. Writes are locked, and running instances pick up changes made elsewhere within a second.

Pi chat (optional)

P opens a chat with pi, a coding agent turboreview runs as pi --mode rpc in the open repository. pi is not bundled: install it separately (it needs Node.js 22.19+; tested with pi 1.0.4):

curl -fsSL https://pi.dev/install.sh | sh
# or: npm install -g --ignore-scripts @earendil-works/pi-coding-agent

Without pi, the popup says so and how to get it; nothing else changes.

  • Each prompt starts with a [turboreview context] block describing the screen: the repo, the view and the focused pane; in the commit list the commits around the selection (with stats, any V range) and the selected commit's message and files; an opened commit or range with its commits, message and files; the Branch tab's branch, base and files; the Changes list; File History's revision; an active search; the comment or pin selected. Then the open file: its git diff command, the display mode, the hunk at the cursor, the cursor line or V selection, and its comments. Pi is told how to use turboreview comment to read and answer comments.
  • Replies render as markdown. Tokens show per prompt, with context / session totals and cost in the title.
  • Enter sends, Ctrl-P or /model picks the model (with context size and price per 1M tokens, from pi's catalog), Ctrl-L or /clear starts a new conversation, Esc closes.

Privacy and safety. Prompts, with the code and comments above, go to the model provider pi is set up with. By default pi has all its tools, so it can run shell commands and edit files in the repository; set pi_tools to keep it read-only.

Settings, in ~/.turboreview_root/root_config.json (shared by every instance):

Key / variable Meaning
pi_model model for pi --model (set by the picker); unset: pi's default
pi_tools pi --tools allowlist, e.g. "read,grep,find,ls" for read-only
pi_command the pi executable, when it is not pi on PATH
TURBOREVIEW_PI environment variable; overrides pi_command
PI_CODING_AGENT_DIR pi's own folder (default ~/.pi/agent), read for the model catalog

Review state & storage

Reviewed flags and comments persist under <repo>/.turboreview/:

Path Holds
.turboreview/comments.json · reviewed.json working-tree review (Changes view)
.turboreview/commits/<sha>/comments.json · … per-commit review (Commits view)
.turboreview/comment-log.jsonl append-only activity log (newest last)
.turboreview/archive/comments-archive.jsonl archived resolved comments (repo-wide)
.turboreview/lessons.md recurring review lessons (agent-written)

The comment log records one JSON object per comment add/edit ({path, line, scope, date, action}, where date is a YYYY-MM-DD HH:MM:SS timestamp), so an agent can read the tail to find the latest review activity. Add .turboreview/ to your .gitignore if you don't want it tracked. R hides reviewed files to declutter the list.

Display notes

File-type icons use Nerd Fonts — install a Nerd Font in your terminal for the glyphs to render correctly (otherwise you'll see fallback boxes). Code highlighting uses the bundled Catppuccin Mocha–style dark theme.

About

A terminal based code review tool

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages