Review the diff.
Redline it.
Hand it back to your agent.

nittle opens your local git diff in the browser like a pull request. Comment on exact lines, then hand the comments back to your coding agent as one structured prompt. No forge, no account, no hosted AI.

curl -fsSL https://nittle.dev/install | sh

Windows (PowerShell 7+):pwsh -c "irm https://nittle.dev/install.ps1 | iex"

  • local-first
  • durable review records
  • MCP handoff
  • macOS · Linux · Windows
src/utils/git.ts+18 −4
40 export function resolveRef(ref: string) {
41 const base = ref || "HEAD";
42− return runGit(["rev-parse", base]);
42+ const sha = runGit(["rev-parse", "--verify", base]);
43+ if (!sha) throw new NoSuchRef(base);
youissue

Throws on a fresh repo where HEAD has no commits. Guard the empty case first.

replyresolve
44+ return sha.trim();
45 }
the loop

From diff to approval, on your machine.

  1. inspectRender a live git comparison in the browser.
  2. commentAnchor notes to a line, a range, or a file.
  3. returnCompile the redline into agent-ready feedback.
  4. refreshRe-run the diff after the agent edits.
  5. resolveReply, reopen, and clear threads.
  6. approveSign off on a durable Review Record.
why review

Read the code. Still.

Agents write code faster than you can read it in a terminal. nittle makes the read cheap enough to do every time.

  1. Your name is on the commit.

    When the change breaks in production, the bug is yours, whoever typed it. Read it before it merges.

  2. Unread code is unknown code.

    A diff you skip is code you can't explain later, and you need that picture of the system to decide what to refactor or delete.

  3. Only you know what it's for.

    An agent stops when the tests pass. Intent, naming, boundaries and what shouldn't exist at all still come from you.

  4. Writing got cheap. Reading didn't.

    An agent can produce a 600-line diff in minutes. Deciding whether it's right still takes a person reading it.

see it in action

Watch a review happen.

Open a diff, redline the exact code, and send the feedback straight back to the agent that wrote it.

Review any comparison

Working tree, staged changes, a branch, a commit range, or the whole codebase, rendered in your browser with a file tree and syntax highlighting, not scrolled past in the terminal. Unified or side-by-side, your choice.

nittle show reviews one commit with its message, author and hash above the files, pinned to the full hash so it reopens the same diff later.

Every command and flag
terminal
$ nittle# working tree vs HEAD
$ nittle staged# staged changes only
$ nittle main# this branch vs main
$ nittle v1.0..v1.1# a commit range
$ nittle browse src/# the whole subtree
$ nittle show# the last commit, message and author on top
$ nittle --wait# block until you send feedback

Comment on the exact code

Click a line, or drag across line numbers for a range. Press c on the cursor line if you'd rather keep your hands on the keys. Tag a note nit, issue, question or praise, and press Ctrl+G to suggest the replacement lines. Every note is saved to a durable Review Record that survives restarts and re-runs, and an unsent draft comes back after a reload.

Ranges, threads, and orphans
client/src/lib/api.tsline 88
88+ const res = await fetch(url, opts);
you

No timeout here, so an agent hangs on a dead dev server.

agentaddressed

Added an AbortController with a 10s timeout. Marked addressed; it's yours to resolve.

Close the loop with your agent

Return the whole redline as one prompt, each comment with its file, line and the code around it. Over the local MCP server, Claude Code, Codex or any MCP client fixes the code, replies inline, marks comments addressed and asks for a re-review. You refresh, check the work, and resolve the thread. Agents can't.

No MCP? nittle --wait blocks until you send feedback, then prints the prompt on stdout. Any agent that can run a shell command can drive it.

Wire up the MCP handoff
nittle main --wait > feedback.mdreal output
## Code Review — fix/fetch-timeout → main — 2026-10-29
 
---
 
### client/src/lib/api.ts — Line 88
 
```
86 | export async function getJson(url: string) {
87 | const opts = { headers: JSON_HEADERS };
> 88 | + const res = await fetch(url, opts);
89 | return res.json();
```
 
No timeout here, so an agent hangs on a dead dev server.
 
---
 
### src/utils/git.ts — Line 43
 
```
41 | const base = ref || "HEAD";
42 | const sha = runGit(["rev-parse", "--verify", base]);
> 43 | + if (!sha) throw new NoSuchRef(base);
44 | return sha.trim();
45 | }
```
 
**[issue]** Throws on a fresh repo where HEAD has no commits. Guard the empty case first.
 
---
 
## Summary: 2 comment(s) across 2 file(s)

Triage before you read

A deterministic scorecard flags what deserves your attention: size, untested code, public API and dependency changes, hotspots, and risky leftovers. Files come in review order, grouped by project with dependencies first. Lockfiles and generated code collapse, and moved code is marked. Same diff, same score, no AI. C# is first-class. When the agent sends changes back, files it touched since your last round get a chip, and you can show only what's new.

How the scorecard works
review scorecard412 effective lines
  • mediumSize412 effective lines across 9 files
  • mediumTestsOrders/OrderService.cs: code change with no matching test in this diff
  • highPublic APIUsers/UserService.cs: removed public method `GetUser(int id)`
  • mediumDependenciesApi/Api.csproj: changed dependency Serilog from 3.0.0 to 3.1.1
  • lowHotspotsno frequently changed files
  • lowFlagsno sensitive paths, leftovers, or oversized files

Install nittle

One self-contained binary. It embeds its own web client and needs no checkout, no Node, and no sidecar files. git on your PATH is the only prerequisite.

macOS · Linux
curl -fsSL https://nittle.dev/install | sh
Windows (PowerShell 7+)
pwsh -c "irm https://nittle.dev/install.ps1 | iex"
  • No forge, no database, no hosted AI service.
  • nittle update checks the SHA-256 and swaps the binary in place.
  • Review Records stay in ~/.nittle on your machine.
Run your first review