@diffohq/diffo 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -200
- package/dist/cli.mjs +2678 -310
- package/dist/client/assets/{abnfDiagram-O67JEVCF-vILxBZcB.js → abnfDiagram-O67JEVCF-BUIFF3Lv.js} +1 -1
- package/dist/client/assets/{arc-KM37zfEu.js → arc-x6Ulf5MI.js} +1 -1
- package/dist/client/assets/architecture-7GRP2DOG-Cx2ezWq8.js +1 -0
- package/dist/client/assets/{architectureDiagram-NJMV4G6O-CCe24XcA.js → architectureDiagram-NJMV4G6O-D25O1A2B.js} +1 -1
- package/dist/client/assets/{blockDiagram-BEXU5L5S-GL2esJ0w.js → blockDiagram-BEXU5L5S-Dy7P3IZw.js} +1 -1
- package/dist/client/assets/{c4Diagram-YGBWAQC7-BcRujrvs.js → c4Diagram-YGBWAQC7-BnE5HTw4.js} +1 -1
- package/dist/client/assets/channel-IK-3bv-L.js +1 -0
- package/dist/client/assets/{chunk-3FUC2YCW-Gj4X9KK9.js → chunk-3FUC2YCW-6C72_i5n.js} +2 -2
- package/dist/client/assets/{chunk-5DYCD2WN-DZs-erj_.js → chunk-5DYCD2WN-B0IgEc5I.js} +1 -1
- package/dist/client/assets/{chunk-742MDFTN-Db1JJZ9G.js → chunk-742MDFTN-BNLZzbxp.js} +1 -1
- package/dist/client/assets/{chunk-7INBJB4K-B_wqJ7Xn.js → chunk-7INBJB4K-K1DkKka3.js} +1 -1
- package/dist/client/assets/{chunk-7M6MHVWA-DuALBizw.js → chunk-7M6MHVWA-B-KIWC1T.js} +1 -1
- package/dist/client/assets/{chunk-7PRAP22T-D9QvZUm3.js → chunk-7PRAP22T-DR6CzDYx.js} +1 -1
- package/dist/client/assets/{chunk-GTNCS2PH-JFHsSpPU.js → chunk-GTNCS2PH-BWkvnYRd.js} +1 -1
- package/dist/client/assets/{chunk-GWA4HPMP-CX_60U9Y.js → chunk-GWA4HPMP-l8NLPoZc.js} +1 -1
- package/dist/client/assets/{chunk-MBY4JIJT-BVqUStmy.js → chunk-MBY4JIJT-k1mwME9y.js} +1 -1
- package/dist/client/assets/{chunk-NETBCI7D-BoSm0O5f.js → chunk-NETBCI7D-DV1F8c_R.js} +1 -1
- package/dist/client/assets/{chunk-O7XYJQB3-DG64mbS_.js → chunk-O7XYJQB3-Bb8gIxaB.js} +1 -1
- package/dist/client/assets/{chunk-UA2S7LBM-BL039fcM.js → chunk-UA2S7LBM-BL7m6fd_.js} +1 -1
- package/dist/client/assets/{chunk-WEXAMYUT-BPFyuzbi.js → chunk-WEXAMYUT-CAnQv1qY.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-BzCs4oPB.js → chunk-XXDRQBXY-DooI1miH.js} +1 -1
- package/dist/client/assets/{chunk-Z7XXMR3K-D9UN9ldM.js → chunk-Z7XXMR3K-DPVaCcdM.js} +1 -1
- package/dist/client/assets/{chunk-ZIGJFQKS-D47UlTiy.js → chunk-ZIGJFQKS-Bz4IWpFy.js} +1 -1
- package/dist/client/assets/{classDiagram-v2-NBCMYWYE-CXeBds6Z.js → classDiagram-v2-NBCMYWYE-Dso7ogb5.js} +1 -1
- package/dist/client/assets/{core-De6Bel6T.js → core-Dy-hJrbg.js} +1 -1
- package/dist/client/assets/{cose-bilkent-JH36ORCC-C5C9BMn5.js → cose-bilkent-JH36ORCC-Baj8S6bg.js} +1 -1
- package/dist/client/assets/{cynefin-OW5HDTMX-TQm3krMs.js → cynefin-OW5HDTMX-BkA1ccYX.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-VND7K2PF-D9L1g2S1.js → cynefinDiagram-VND7K2PF-nyK9OZGN.js} +1 -1
- package/dist/client/assets/{dagre-6A5THRUB-D9iVd0tg.js → dagre-6A5THRUB-BP_dyQLS.js} +1 -1
- package/dist/client/assets/{diagram-22UHCM2B-CD_1yZgj.js → diagram-22UHCM2B-BIt_aIJx.js} +1 -1
- package/dist/client/assets/{diagram-3UASUU5V-BLiXkub3.js → diagram-3UASUU5V-UX2eUwyi.js} +1 -1
- package/dist/client/assets/{diagram-ATOU4E4O-CnXY0tjf.js → diagram-ATOU4E4O-CEYK5oZO.js} +1 -1
- package/dist/client/assets/{diagram-CDSNMT55-BBnDsrf_.js → diagram-CDSNMT55-4uIYrmGp.js} +1 -1
- package/dist/client/assets/{diagram-MLGK6HIB-BUiu4OKD.js → diagram-MLGK6HIB-5BGrc92k.js} +1 -1
- package/dist/client/assets/{diagram-MPIPVDR6-DiI9FWeO.js → diagram-MPIPVDR6-0BG375Nf.js} +1 -1
- package/dist/client/assets/{dist-Co85aeoI.js → dist-hfzhbdYS.js} +1 -1
- package/dist/client/assets/{dist-BWYGCgdo.js → dist-uIEEXDIm.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-ZINNZB2B-Bg_BLedv.js → ebnfDiagram-ZINNZB2B-CnAveRvy.js} +1 -1
- package/dist/client/assets/{elk-276RUBZZ-BO7Zoa7U.js → elk-276RUBZZ-CejJ0q5w.js} +1 -1
- package/dist/client/assets/{engine-oniguruma-DCFwTJLE.js → engine-oniguruma-BpOI5GVJ.js} +1 -1
- package/dist/client/assets/{erDiagram-OPXOYQCR-DjBak3Ld.js → erDiagram-OPXOYQCR-Lg3_iVkX.js} +1 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-Dh34QIVY.js +1 -0
- package/dist/client/assets/flowDiagram-KWPJA3E3-Bcos9jHd.js +1 -0
- package/dist/client/assets/{ganttDiagram-FUAMR5RP-CEn0Np5L.js → ganttDiagram-FUAMR5RP-D5nJpDg8.js} +1 -1
- package/dist/client/assets/{gitGraph-4MIJSDKK-DVMdaaG2.js → gitGraph-4MIJSDKK-BLNIFBUu.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-X574FWY7-B6ZkiY7u.js → gitGraphDiagram-X574FWY7-YHwgA3VE.js} +1 -1
- package/dist/client/assets/index-CE0LasmM.css +1 -0
- package/dist/client/assets/index-DYt1d3uP.js +93 -0
- package/dist/client/assets/{info-A6RAGUB7-Idt2RahI.js → info-A6RAGUB7-Bfa8ErwC.js} +1 -1
- package/dist/client/assets/{infoDiagram-VRGFBTTK-CA8T3csq.js → infoDiagram-VRGFBTTK-Dzp_xQpV.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-DcgLwVJX.js → ishikawaDiagram-OU5B5YK6-Hun-xe-t.js} +1 -1
- package/dist/client/assets/{journeyDiagram-ZHPQQLJL-_AVEW5aE.js → journeyDiagram-ZHPQQLJL-CT5fXqj_.js} +1 -1
- package/dist/client/assets/{kanban-definition-PNTS6WVX-CZ2gNo-B.js → kanban-definition-PNTS6WVX-kFYcpsMx.js} +1 -1
- package/dist/client/assets/{line-CHew3ngr.js → line-Cda_OIfO.js} +1 -1
- package/dist/client/assets/{linear-Baz1Hb3u.js → linear-CDQGk4q-.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-D2BrkwRE.js → mermaid-parser.core-CCoRJPAh.js} +3 -3
- package/dist/client/assets/{mermaid.core-CCFlYVgY.js → mermaid.core-SnjyC0ZV.js} +4 -4
- package/dist/client/assets/{mindmap-definition-NLK3R4M7-BXG9w5sC.js → mindmap-definition-NLK3R4M7-C3oLUr5b.js} +1 -1
- package/dist/client/assets/{packet-AYTQ26CC-BOvg32Rh.js → packet-AYTQ26CC-BT6BgV6a.js} +1 -1
- package/dist/client/assets/{pegDiagram-GJSIUBJH-COukdq7o.js → pegDiagram-GJSIUBJH-OT5BsfLg.js} +1 -1
- package/dist/client/assets/{pie-WAS4IAKB-ChHsdIQV.js → pie-WAS4IAKB-Bou89QXR.js} +1 -1
- package/dist/client/assets/{pieDiagram-5QR66LMP-Deng5oun.js → pieDiagram-5QR66LMP-AzEtJfJu.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-O4NWA36T-DmEJ83mR.js → quadrantDiagram-O4NWA36T-BUKCkyd7.js} +1 -1
- package/dist/client/assets/{radar-RG4KPBEZ-YxcXBiXc.js → radar-RG4KPBEZ-D77V4y6h.js} +1 -1
- package/dist/client/assets/{railroad-74A4TZTK-RkYX7A2D.js → railroad-74A4TZTK-CIYb8bnG.js} +1 -1
- package/dist/client/assets/railroad-abnf-HS5TGJTU-OVikttJY.js +1 -0
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-DPAI1fGw.js +1 -0
- package/dist/client/assets/railroad-peg-WCYAUIDC-CcsZpvwt.js +1 -0
- package/dist/client/assets/{railroadDiagram-XR7U4H2S-uj5HQbYy.js → railroadDiagram-XR7U4H2S-DhUQyIW9.js} +1 -1
- package/dist/client/assets/{requirementDiagram-PLB6GJNP-C_QtkIlI.js → requirementDiagram-PLB6GJNP-5HRstoAa.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-IPEJSGJF-BfxM5TKv.js → sankeyDiagram-IPEJSGJF-sNbgZbEH.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-PO4LG4MO-DXflg1u_.js → sequenceDiagram-PO4LG4MO-B_vIrQ3k.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/client/assets/{src-YTrwJCk8.js → src-BWz11yEV.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-GCMORJYK-BjDmED1Q.js → stateDiagram-v2-GCMORJYK-BnRt6hQF.js} +1 -1
- package/dist/client/assets/{swimlanes-2SLR337P-BAvnQ6KT.js → swimlanes-2SLR337P-CLlJdLDU.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-D6iEiuTl.js +8 -0
- package/dist/client/assets/{timeline-definition-EJHVYXUP-BYemcgr1.js → timeline-definition-EJHVYXUP-sXwAwUmH.js} +1 -1
- package/dist/client/assets/{treeView-Q6P3EWNA-CsuBtqLq.js → treeView-Q6P3EWNA-BmhLEMPr.js} +1 -1
- package/dist/client/assets/{treemap-WGGIJYW6-DUk1Z6g4.js → treemap-WGGIJYW6-D_PGkPFQ.js} +1 -1
- package/dist/client/assets/{usecaseDiagram-POWQR4AR-j1nHXvyL.js → usecaseDiagram-POWQR4AR-GARihMJS.js} +1 -1
- package/dist/client/assets/{vennDiagram-UO4OBE2U-B5eUL-dD.js → vennDiagram-UO4OBE2U-DXSYoTtG.js} +1 -1
- package/dist/client/assets/{wardley-WFR3VGLG-1YjpwPJM.js → wardley-WFR3VGLG-Caebv6bl.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VNRHLVJA-C7laBq5A.js → wardleyDiagram-VNRHLVJA-BnFa4EKC.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PMCCYNJV-BkYPx-ts.js → xychartDiagram-PMCCYNJV-XS2BbOyB.js} +1 -1
- package/dist/client/index.html +2 -2
- package/package.json +4 -2
- package/plugin.json +3 -3
- package/skills/diffo/SKILL.md +7 -4
- package/dist/client/assets/architecture-7GRP2DOG-DzlmD0Wj.js +0 -1
- package/dist/client/assets/channel-BffjfVqs.js +0 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-BA4dpxhq.js +0 -1
- package/dist/client/assets/flowDiagram-KWPJA3E3-BXSGu0Q5.js +0 -1
- package/dist/client/assets/index-6w3rS9cw.js +0 -91
- package/dist/client/assets/index-D934d4yh.css +0 -1
- package/dist/client/assets/railroad-abnf-HS5TGJTU-CYF7Z2Wu.js +0 -1
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-CqV11tet.js +0 -1
- package/dist/client/assets/railroad-peg-WCYAUIDC-CPusJj6I.js +0 -1
- package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-CbFPwcec.js +0 -8
package/README.md
CHANGED
|
@@ -11,76 +11,61 @@
|
|
|
11
11
|
|
|
12
12
|
### The human way to review agent-written code.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Ask your agent for a review. You get the change in **layers**, in the order it should be
|
|
15
|
+
read, and **the agent on the other end of every comment**: it answers on the line and fixes
|
|
16
|
+
while you read. Hand it a pull request instead, and it reads beside you and sends your
|
|
17
|
+
review to GitHub.
|
|
16
18
|
|
|
17
|
-
[Quick start](#quick-start) · [
|
|
19
|
+
[Quick start](#quick-start) · [The conversation](#talk-to-the-agent-on-the-line) · [Layers](#read-it-in-layers) · [Pull requests](#review-a-pull-request) · [Docs](#docs) · [Contributing](#contributing)
|
|
18
20
|
|
|
19
21
|
[](https://github.com/DiffoHQ/diffo/actions/workflows/ci.yml)
|
|
20
22
|
[](https://www.npmjs.com/package/@diffohq/diffo)
|
|
21
23
|
[](LICENSE)
|
|
22
24
|
[](#quick-start)
|
|
23
25
|
[](https://diffohq.github.io/diffo/)
|
|
24
|
-
[](#contributing)
|
|
25
27
|
|
|
26
28
|
</div>
|
|
27
29
|
|
|
28
30
|
<!-- Every clip here is a real recording: a real Claude Code session, a real server, and a
|
|
29
|
-
real changeset under review. The hero
|
|
30
|
-
glance; the
|
|
31
|
+
real changeset under review. The hero and the pull request clip review a small demo
|
|
32
|
+
app, so the diff reads at a glance; the layers clip, and the tutorial, review this
|
|
33
|
+
repo's own changesets. -->
|
|
31
34
|
|
|
32
35
|
<!-- Light-theme only. The clip opens once the session has finished writing the change:
|
|
33
36
|
waiting on the agent is fast-forwarded — the badge in the session's corner says so
|
|
34
37
|
while it runs — and nothing else is cut. -->
|
|
35
|
-
<img alt="One take of the whole loop. A Claude Code session has just written natural-language due dates into a todo app; the reviewer types /diffo, and the session opens a live review and hands over its localhost URL, which opens beside the session. The reviewer leaves a question on the weekday line
|
|
38
|
+
<img alt="One take of the whole loop. A Claude Code session has just written natural-language due dates into a todo app; the reviewer types /diffo, and the session opens a live review and hands over its localhost URL, which opens beside the session. The reviewer leaves a question on the weekday line (a bare weekday always lands next week, should it mean today?) and the agent's answer appears in the thread while they watch." src="docs/assets/loop.gif" width="100%">
|
|
36
39
|
|
|
37
|
-
<p align="center"><sub>The whole loop in one take: type <code>/diffo</code>, read the diff, ask on the line
|
|
40
|
+
<p align="center"><sub>The whole loop in one take: type <code>/diffo</code>, read the diff, ask on the line, and the answer comes back in the thread. Left is a real Claude Code session, right is the real review it opened. Nothing here is a mock-up; the only edit is that waiting on the agent runs fast.</sub></p>
|
|
38
41
|
|
|
39
42
|
---
|
|
40
43
|
|
|
41
44
|
## Quick start
|
|
42
45
|
|
|
43
|
-
Requires **Node >= 24** and **git**.
|
|
44
|
-
|
|
45
|
-
**Have your agent set it up.** Paste this into Claude Code, Cursor, Codex, or whichever
|
|
46
|
-
agent you already use:
|
|
46
|
+
Requires **Node >= 24** and **git**. Paste this into Claude Code, Cursor, Codex, or
|
|
47
|
+
whichever agent you already use:
|
|
47
48
|
|
|
48
49
|
```text
|
|
49
50
|
Run `npx skills add DiffoHQ/diffo --skill diffo -g` and open the diffo review
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
npx skills add DiffoHQ/diffo --skill diffo -g
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Either way, that's the whole install. Then, in any session, say:
|
|
59
|
-
|
|
60
|
-
> **"let's review that"**, or just **`/diffo`**
|
|
61
|
-
|
|
62
|
-
The agent opens a live review of its own work and hands you the URL. Your comments arrive
|
|
63
|
-
in its context, its replies land inline in your threads, and its fixes update the diff
|
|
64
|
-
while you read. That is the clip above, with no URL to ask for.
|
|
65
|
-
|
|
66
|
-
<details>
|
|
67
|
-
<summary><b>Running from a clone instead</b></summary>
|
|
68
|
-
|
|
69
|
-
<br>
|
|
53
|
+
That's the whole install. From then on, one command in any session:
|
|
70
54
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
node dist/cli.mjs setup # or `node dist/cli.mjs` from any repo to review it
|
|
77
|
-
```
|
|
55
|
+
| Run | And the agent reviews |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `/diffo` | what it just wrote, before anything is committed |
|
|
58
|
+
| `/diffo main` | everything since you branched off `main` |
|
|
59
|
+
| `/diffo <PR link>` | a GitHub pull request, checked out in a worktree of its own; your review goes back to GitHub when you finish |
|
|
78
60
|
|
|
79
|
-
|
|
61
|
+
Every time, the agent opens the review and hands you the URL. It all runs on your
|
|
62
|
+
machine, and nothing needs to be committed or pushed first. A pull request needs the
|
|
63
|
+
[GitHub CLI](https://cli.github.com) signed in, and that is the only time Diffo touches
|
|
64
|
+
the network.
|
|
80
65
|
|
|
81
66
|
New here? [**Your first review, end to end**](https://diffohq.github.io/diffo/tutorial) takes about five minutes.
|
|
82
67
|
|
|
83
|
-
##
|
|
68
|
+
## Talk to the agent on the line
|
|
84
69
|
|
|
85
70
|
**We write code with an LLM. We review it alone.**
|
|
86
71
|
|
|
@@ -89,110 +74,59 @@ the thing is right. Reviewing never did. The code lands, the conversation ends,
|
|
|
89
74
|
read four hundred lines by yourself, in a viewer built for a world where whoever wrote it
|
|
90
75
|
had already moved on.
|
|
91
76
|
|
|
92
|
-
Diffo keeps the conversation open through the review.
|
|
93
|
-
|
|
94
|
-
shape needs one. Ask for a change and it makes it, and the diff updates while you read.
|
|
95
|
-
The judgement stays yours. You just stop reading alone.
|
|
96
|
-
|
|
97
|
-
<picture>
|
|
98
|
-
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/hero-dark.gif">
|
|
99
|
-
<img alt="Two windows side by side. The reviewer asks for a change on a line of src/cli.ts; the real Claude Code session on the left makes the edit, and the diff on the right updates while they watch." src="docs/assets/hero.gif" width="100%">
|
|
100
|
-
</picture>
|
|
101
|
-
|
|
102
|
-
<p align="center"><sub>Ask for a change and the agent makes it. The diff updates under you, and the file count falls as those files stop differing.</sub></p>
|
|
103
|
-
|
|
104
|
-
## What you get
|
|
105
|
-
|
|
106
|
-
<table>
|
|
107
|
-
<tr>
|
|
108
|
-
<td width="50%">
|
|
109
|
-
|
|
110
|
-
**A thread is a decision**
|
|
111
|
-
|
|
112
|
-
Each comment is one small call: change this, explain that, leave it alone. Drop it on a
|
|
113
|
-
line or drag down the gutter for a range of them. Mark it a Change or a Question and the
|
|
114
|
-
agent is told which. The review is the sum of those decisions, not a verdict at the end.
|
|
115
|
-
|
|
116
|
-
</td>
|
|
117
|
-
<td width="50%">
|
|
118
|
-
|
|
119
|
-
**Reading, not scrolling**
|
|
120
|
-
|
|
121
|
-
Syntax-highlighted unified and split diffs, word-level marks, keyboard-first movement,
|
|
122
|
-
context expansion, images side by side, lockfiles collapsed. The conventions are GitHub's,
|
|
123
|
-
deliberately: a reviewer shouldn't have to learn a new diff.
|
|
124
|
-
|
|
125
|
-
</td>
|
|
126
|
-
</tr>
|
|
127
|
-
<tr>
|
|
128
|
-
<td width="50%">
|
|
129
|
-
|
|
130
|
-
**Live while you iterate**
|
|
131
|
-
|
|
132
|
-
Fixes land in the diff you are already reading. A hunk you had marked read says *changed
|
|
133
|
-
since you read it* once it's edited, so the second pass stays honest.
|
|
134
|
-
|
|
135
|
-
</td>
|
|
136
|
-
<td width="50%">
|
|
137
|
-
|
|
138
|
-
**Local**
|
|
139
|
-
|
|
140
|
-
One process on your machine, bound to loopback. No account, no telemetry, no cloud, and
|
|
141
|
-
nothing to configure.
|
|
142
|
-
|
|
143
|
-
</td>
|
|
144
|
-
</tr>
|
|
145
|
-
<tr>
|
|
146
|
-
<td width="50%">
|
|
147
|
-
|
|
148
|
-
**It explains itself**
|
|
77
|
+
Diffo keeps the conversation open through the review. The judgement stays yours. You just
|
|
78
|
+
stop reading alone.
|
|
149
79
|
|
|
150
|
-
|
|
151
|
-
one
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
80
|
+
- **Ask on any line.** The agent that wrote the code answers in the thread, with a
|
|
81
|
+
diagram when the shape needs one. Mark a thread a **Question** and it explains; mark it
|
|
82
|
+
a **Change** and it edits, so a question never turns into an unrequested refactor.
|
|
83
|
+
- **Fixes land in the diff you're reading.** The diff updates under your cursor, and a
|
|
84
|
+
hunk you had already read says *changed since you read it*, so the second pass stays
|
|
85
|
+
honest.
|
|
86
|
+
- **A map, not a verdict.** On a multi-file or subtle change the agent opens the review
|
|
87
|
+
with one orienting comment on what the change does. It never pre-reviews: no verdicts,
|
|
88
|
+
nothing is "fine". That judgement is the part it doesn't get to make.
|
|
89
|
+
## Read it in layers
|
|
160
90
|
|
|
161
91
|
A diff arrives alphabetically, which is almost never the order to read it in. Ask, and the
|
|
162
92
|
agent posts **layers**: the change as ordered steps, each with a title, a summary, and its
|
|
163
|
-
files. You read one layer at a time
|
|
164
|
-
posting gathers in a *Since your review* layer,
|
|
165
|
-
|
|
166
|
-
</td>
|
|
167
|
-
</tr>
|
|
168
|
-
</table>
|
|
93
|
+
files. You read one layer at a time, in the order the agent would explain it; `]` steps to
|
|
94
|
+
the next. Anything the agent touches after posting gathers in a *Since your review* layer,
|
|
95
|
+
so nothing hides outside the plan.
|
|
169
96
|
|
|
170
97
|
<picture>
|
|
171
98
|
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/layers-dark.gif">
|
|
172
99
|
<img alt="A 23-file change, every file folded. The header chip reads agent · suggests layers; the reviewer clicks it, eight layers land, and picking the first shows its summary card. ] steps to layers 2 and 3, where the reviewer asks on a line and the agent answers in the thread." src="docs/assets/layers.gif" width="100%">
|
|
173
100
|
</picture>
|
|
174
101
|
|
|
175
|
-
<p align="center"><sub>Layers, in one take: the agent offers an outline, the reviewer asks, and a 23-file change arrives as eight steps to read in order. Three layers in, a question on a line comes back answered in the thread.
|
|
102
|
+
<p align="center"><sub>Layers, in one take: the agent offers an outline, the reviewer asks, and a 23-file change arrives as eight steps to read in order. Three layers in, a question on a line comes back answered in the thread. Only the agent's thinking time is cut.</sub></p>
|
|
176
103
|
|
|
177
|
-
##
|
|
104
|
+
## Review a pull request
|
|
178
105
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
106
|
+
When a pull request lands on *your* desk, give your agent the link. It checks the PR out
|
|
107
|
+
in a worktree of its own, so your checkout is never touched, and opens it as the same
|
|
108
|
+
review: the description and the GitHub threads come with it, and the agent reads beside
|
|
109
|
+
you as a copilot for code it did not write. Every comment has two tabs. **Comment on PR**
|
|
110
|
+
goes to the author, as one review when you finish. **Ask agent** stays on your machine:
|
|
111
|
+
the agent can run the tests and answer with evidence, and it never posts to GitHub.
|
|
182
112
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
| What it's for | **getting the code right** | getting it approved | catching the obvious |
|
|
187
|
-
| Who you work with | **the agent that wrote it** | your teammates | nobody |
|
|
188
|
-
| Where the code is | **uncommitted, on your disk** | pushed to a branch | pushed to a branch |
|
|
189
|
-
| What comes out | **code worth pushing** | an approval and a record | a list of comments |
|
|
113
|
+
<!-- Light-theme only, like the hero. The pull request is a real one on a demo repo
|
|
114
|
+
(DiffoHQ/todo-demo#1), and the review at the end is the one this take submitted. -->
|
|
115
|
+
<img alt="One take of a pull request review. On GitHub, a pull request adds recurring todos to a todo app; in Claude Code the reviewer types /diffo with its link, and the review opens beside the session, the PR's title, author and checks in the header. The agent lays the change out in layers. On the streak check the reviewer asks the agent whether anything done on its due day now counts as late, and the answer comes back in the thread; they leave a comment for GitHub on the same line, submit the review with Request changes, and the review appears on the pull request." src="docs/assets/pr-review.gif" width="100%">
|
|
190
116
|
|
|
191
|
-
|
|
192
|
-
pull request you actually want reviewed. Your judgement is the scarce resource, and this is
|
|
193
|
-
the stage where spending it changes the outcome.
|
|
117
|
+
<p align="center"><sub>A pull request, end to end: hand over the link, read it in layers, ask your agent on a line, leave a comment for the author, and submit to GitHub. A real Claude Code session and a real pull request; the only edit is that waiting on the agent runs fast.</sub></p>
|
|
194
118
|
|
|
195
|
-
|
|
119
|
+
## Where it fits
|
|
120
|
+
|
|
121
|
+
Diffo isn't an AI reviewer. It doesn't grade your diff or leave generated nitpicks: you
|
|
122
|
+
read, and the agent is there to answer, explain, and fix.
|
|
123
|
+
|
|
124
|
+
| | **Diffo** | AI reviewer bot | Plain pull request review |
|
|
125
|
+
| --- | --- | --- | --- |
|
|
126
|
+
| Who reads the code | **you** | a model | you |
|
|
127
|
+
| Who answers your questions | **the agent, in the thread, now** | nobody | the author, when they get to it |
|
|
128
|
+
| When | **while the agent writes, or when the PR lands** | after you push | after you push |
|
|
129
|
+
| What comes out | **fixes in the diff, or a review on GitHub** | a list of comments | a review on GitHub |
|
|
196
130
|
|
|
197
131
|
## How it works
|
|
198
132
|
|
|
@@ -201,17 +135,11 @@ the stage where spending it changes the outcome.
|
|
|
201
135
|
<img alt="Diffo's architecture: your agent writes the code and opens the review; a local Diffo server watches the changeset and serves it to your browser; your comments and Finish review return to the agent through diffo poll, and its answers and fixes land back in the review live." src="assets/how-it-works-light.svg" width="100%">
|
|
202
136
|
</picture>
|
|
203
137
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
| You want to review | Command |
|
|
211
|
-
| --- | --- |
|
|
212
|
-
| Uncommitted work in progress (the default) | `diffo` |
|
|
213
|
-
| Everything since you branched off `main` | `diffo --base main` |
|
|
214
|
-
| A pull request | *not supported yet* |
|
|
138
|
+
One process on your machine, bound to loopback: no account, no cloud, no telemetry, and
|
|
139
|
+
no model API. Diffo spawns no agents of its own; the one you're already talking to stays
|
|
140
|
+
attached through the `diffo` CLI, so your comments land in the session that holds the
|
|
141
|
+
context. The viewer itself is a real diff viewer, unified and split, keyboard-first, with
|
|
142
|
+
GitHub's conventions. The CLI, the flags, and everything under the hood are in the docs.
|
|
215
143
|
|
|
216
144
|
## Docs
|
|
217
145
|
|
|
@@ -219,79 +147,31 @@ cheapest to change.
|
|
|
219
147
|
| --- | --- |
|
|
220
148
|
| [**Your first review**](https://diffohq.github.io/diffo/tutorial) | The whole loop end to end, about five minutes |
|
|
221
149
|
| [**Getting started**](https://diffohq.github.io/diffo/guide/getting-started) | Install, and where each agent gets wired |
|
|
222
|
-
| [**The review loop**](https://diffohq.github.io/diffo/guide/the-loop) | Reading,
|
|
150
|
+
| [**The review loop**](https://diffohq.github.io/diffo/guide/the-loop) | Reading, commenting, and what the agent receives |
|
|
151
|
+
| [**Layers**](https://diffohq.github.io/diffo/guide/layers) | The agent's reading plan: ordered steps, one at a time |
|
|
152
|
+
| [**Reviewing a pull request**](https://diffohq.github.io/diffo/guide/pr-review) | A GitHub PR in a worktree, your agent beside you, your review back on GitHub |
|
|
223
153
|
| [**How it works**](https://diffohq.github.io/diffo/guide/how-it-works) | The components and the server lifecycle |
|
|
224
154
|
| [**The agent side**](https://diffohq.github.io/diffo/agents) | The agent protocol: every command, every payload |
|
|
225
155
|
| [**Architecture**](https://diffohq.github.io/diffo/architecture) | Diff pipeline, delivery queue, SQLite state |
|
|
226
156
|
| [**CLI**](https://diffohq.github.io/diffo/reference/cli) and [**Keyboard shortcuts**](https://diffohq.github.io/diffo/reference/keyboard-shortcuts) | Reference |
|
|
227
157
|
| [**FAQ**](https://diffohq.github.io/diffo/faq) | The short answers |
|
|
228
158
|
|
|
229
|
-
## Under the hood
|
|
230
|
-
|
|
231
|
-
TypeScript on Node >= 24: a [Hono](https://hono.dev) server over loopback serving a React 19
|
|
232
|
-
UI, live updates over server-sent events from one recursive filesystem watch, and state in a
|
|
233
|
-
single SQLite file at `~/.diffo/diffo.db` through the runtime's built-in `node:sqlite`, so
|
|
234
|
-
there is no database to install. **Zero network calls.** 1,143 tests across 63 files.
|
|
235
|
-
|
|
236
|
-
Reviews are scoped per repo **and branch**, and the server is loopback-only, rejecting
|
|
237
|
-
non-loopback `Host` and `Origin` headers so a web page can't reach into your repo through
|
|
238
|
-
it. The full walkthrough is in [**Architecture**](https://diffohq.github.io/diffo/architecture).
|
|
239
|
-
|
|
240
|
-
<details>
|
|
241
|
-
<summary><b>Why read marks survive a live diff</b></summary>
|
|
242
|
-
|
|
243
|
-
<br>
|
|
244
|
-
|
|
245
|
-
Every hunk carries a **content-addressed id**: a hash of its path and changed lines, and
|
|
246
|
-
deliberately not its line numbers. That one decision is what makes the live review honest.
|
|
247
|
-
|
|
248
|
-
- Read marks survive a refresh, because an untouched hunk keeps its id.
|
|
249
|
-
- An edited hunk mints a new id, loses its mark, and says **changed since you read it**. You
|
|
250
|
-
can't accidentally sign off on code you never saw.
|
|
251
|
-
- The ids from your last Finish are a complete record of what existed then, so "what moved
|
|
252
|
-
since I last looked" is a set subtraction, needing no timestamps.
|
|
253
|
-
|
|
254
|
-
</details>
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
159
|
## Open core
|
|
259
160
|
|
|
260
161
|
Everything in this repository is the core, and the core stays Apache-2.0: local review, the
|
|
261
|
-
agent loop, the CLI, the Agent Skill. It works offline, for one
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
we commit to: **anything that runs on your machine for one reviewer is core.**
|
|
266
|
-
|
|
267
|
-
## Status
|
|
268
|
-
|
|
269
|
-
Diffo is pre-1.0: the loop below works end to end — this repo is reviewed with it
|
|
270
|
-
daily — and the edges are still moving. What works today:
|
|
271
|
-
|
|
272
|
-
- [x] [Live review of any changeset](https://diffohq.github.io/diffo/guide/how-it-works): the working tree, or anything since `--base`.
|
|
273
|
-
- [x] [The comment loop](https://diffohq.github.io/diffo/guide/the-loop): threads that reach the session that wrote the code.
|
|
274
|
-
- [x] [Layers](https://diffohq.github.io/diffo/guide/the-loop#read-it-in-layers): the agent's reading plan, one ordered step at a time.
|
|
275
|
-
- [x] [One setup, every agent](https://diffohq.github.io/diffo/guide/getting-started): Claude Code, Codex, Cursor, VS Code, Copilot CLI, Gemini CLI, Amp, Goose, OpenCode.
|
|
276
|
-
- [x] [Reading tools](https://diffohq.github.io/diffo/reference/keyboard-shortcuts): unified and split diffs, word-level marks, coverage tracking.
|
|
162
|
+
agent loop, pull request review, the CLI, the Agent Skill. It works offline, for one
|
|
163
|
+
reviewer, forever, for free. A hosted team tier is planned, and none of it will take an
|
|
164
|
+
existing core feature behind a paywall: **anything that runs on your machine for one
|
|
165
|
+
reviewer is core.**
|
|
277
166
|
|
|
278
167
|
## Contributing
|
|
279
168
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
Local development is `pnpm dev` (server and client together). One hard rule:
|
|
287
|
-
**`skills/diffo/SKILL.md` is generated.** Edit [`src/skill.ts`](src/skill.ts) and run
|
|
288
|
-
`pnpm build:skill`; a test fails if the committed file drifts. That rewrites the repo
|
|
289
|
-
file, not the skill your own agent runs — `pnpm dev:skill --global` installs a separate
|
|
290
|
-
`/diffo-dev` that drives your checkout, alongside the shipped `/diffo`.
|
|
291
|
-
|
|
292
|
-
Details in [CONTRIBUTING.md](CONTRIBUTING.md), plus a [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
293
|
-
and the [CHANGELOG](CHANGELOG.md). First-time contributors sign a [CLA](CLA.md): a bot asks
|
|
294
|
-
on your first pull request, and signing is one reply.
|
|
169
|
+
Diffo is pre-1.0: this repo is reviewed with it daily, and the edges are still moving.
|
|
170
|
+
`pnpm check` runs the five gates CI runs. One hard rule: **`skills/diffo/SKILL.md` is
|
|
171
|
+
generated** from [`src/skill.ts`](src/skill.ts); edit the source and run `pnpm build:skill`.
|
|
172
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) has the rest, with a [Code of Conduct](CODE_OF_CONDUCT.md),
|
|
173
|
+
the [CHANGELOG](CHANGELOG.md), and the [CLA](CLA.md) a bot asks first-time contributors to
|
|
174
|
+
sign, in one reply.
|
|
295
175
|
|
|
296
176
|
Found a security problem? Please don't open a public issue. The
|
|
297
177
|
[Security Policy](SECURITY.md) says where to send it and what's in scope.
|