The same agent
It wrote the code
Not a bot that read your diff afterwards. The session that made the change is still running, and it still remembers why it made it.
A live review on your machine, wired to the agent that wrote the code — so your comments come back as fixes, in the diff you're still reading.
Not an AI reviewer. It never grades your diff. You read; it answers.
Just read a diff
npx -y @diffohq/diffoOpens your uncommitted work in the browser. No agent needed.
Wire it to your agent
npx skills add DiffoHQ/diffo --skill diffo -gThen say /diffo in any session — Claude Code, Cursor, Codex and six more.

The same agent
Not a bot that read your diff afterwards. The session that made the change is still running, and it still remembers why it made it.
It helps you review
Ask on any line and the answer comes back in your thread. It never grades the diff, never leaves nitpicks, never says anything is “fine”.
On the spot
Ask for a change and the fix lands in the diff you are already reading — before the commit, before the pull request, while it is still cheap.
Ask a question
The comment goes to the session that wrote the code, while it still remembers why. It answers in your thread — and changes nothing, because you asked a question, not for a change.

Ask for a change
It makes the change and the diff updates underneath you. You end up reading the fix itself, on line 15, not a promise that it will be fixed later.

Both are screenshots of one real review, running locally. Nothing here is a mock-up.
The asymmetry
Writing became a conversation: you and the model in the same window, trading context until the thing is right.
Reviewing never did. The code lands, the conversation ends, and you go read four hundred lines by yourself — in a viewer built for a world where whoever wrote it had already moved on.
Diffo keeps the conversation open through the review. Ask what a hunk does and the agent that wrote it answers in the thread. Ask why, and it explains, with a diagram when the shape needs one. Ask for a change and it makes it, and the diff updates while you read. The judgement stays yours. You just stop reading alone.
The loop
On a multi-file or structural change, one guide comment: what the change does, plus a mermaid diagram when the shape is easier to see than to read. No verdicts. Nothing is “fine”.
Syntax-highlighted unified or split diffs, word-level marks, keyboard-first movement, per-file viewed tracking. GitHub's conventions on purpose — you shouldn't have to learn a new diff.
On a line, a range, a file, or the whole changeset. Each thread is a Change or a Question, so a question never turns into an unrequested refactor.
Answers land inline in your threads. Fixes land in the diff you're reading — so you're reading the fix itself, not a promise of one.
What you get
Each comment is one small call: change this, explain that, leave it alone. The review is the sum of those decisions, not a grade at the end.
Fixes land in the diff you're already reading. A hunk you'd marked read says changed since you read it once it's edited, so the second pass stays honest.
Claude Code, Cursor, Codex, VS Code, Copilot CLI, Gemini CLI, Amp, Goose, OpenCode — whichever you already use.
One process on your machine, bound to loopback. No account, no telemetry, no cloud, zero network calls, and nothing to configure.
Where it fits
A pull request is how you hand finished work to someone else. Diffo is the step before that: the loop where you and the agent turn a first draft into something worth another person's time.
| Dimension | Diffo | Pull request review | AI reviewer bot |
|---|---|---|---|
| When | before the PR exists | after you push | after you push |
| What it's for | getting the code right | getting it approved | catching the obvious |
| Who you work with | the agent that wrote it | your teammates | nobody |
| Where the code is | uncommitted, on your disk | pushed to a branch | pushed to a branch |
| What comes out | code worth pushing | an approval and a record | a list of comments |
Under the hood
TypeScript on Node 24: a Hono server over loopback serving a React 19 UI, live updates over server-sent events from one recursive filesystem watch, and state in a single SQLite file through the runtime's built-in node:sqlite — so there is no database to install. The server rejects non-loopback Host and Origin headers, so a web page can't reach into your repo through it.
npx skills add DiffoHQ/diffo --skill diffo -g