@diffohq/diffo 0.7.0 → 0.9.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 +79 -204
- package/dist/cli.mjs +462 -4
- package/dist/client/assets/{abnfDiagram-O67JEVCF-1LPV7Bta.js → abnfDiagram-O67JEVCF-Dh4is2Nj.js} +1 -1
- package/dist/client/assets/{arc-B6fobjtY.js → arc-CMN0Gb1g.js} +1 -1
- package/dist/client/assets/architecture-7GRP2DOG-DaIFNiR2.js +1 -0
- package/dist/client/assets/{architectureDiagram-NJMV4G6O-CTN0gguk.js → architectureDiagram-NJMV4G6O-DxVGDSE1.js} +1 -1
- package/dist/client/assets/{blockDiagram-BEXU5L5S-DTR5PHKV.js → blockDiagram-BEXU5L5S-T1F9hSwZ.js} +1 -1
- package/dist/client/assets/{c4Diagram-YGBWAQC7-NGxq4JmF.js → c4Diagram-YGBWAQC7-DC6zwYuX.js} +1 -1
- package/dist/client/assets/channel-Ci5ZF5xD.js +1 -0
- package/dist/client/assets/{chunk-3FUC2YCW-DA-Lgw5Q.js → chunk-3FUC2YCW-D0PAoCRl.js} +2 -2
- package/dist/client/assets/{chunk-5DYCD2WN-DcE0aMs7.js → chunk-5DYCD2WN-NqHzOtt0.js} +1 -1
- package/dist/client/assets/{chunk-742MDFTN-CyTGvDWd.js → chunk-742MDFTN-B9Y5HHB7.js} +1 -1
- package/dist/client/assets/{chunk-7INBJB4K-Dd4mQ9Jx.js → chunk-7INBJB4K-CBOWlj91.js} +1 -1
- package/dist/client/assets/{chunk-7M6MHVWA-CTU7JU3x.js → chunk-7M6MHVWA-D2dZ_rQI.js} +1 -1
- package/dist/client/assets/{chunk-7PRAP22T-BF_GNhON.js → chunk-7PRAP22T-7dilu8x-.js} +1 -1
- package/dist/client/assets/{chunk-GTNCS2PH-Bu7kc4uW.js → chunk-GTNCS2PH-at0ENjhB.js} +1 -1
- package/dist/client/assets/{chunk-GWA4HPMP-DOeikbS_.js → chunk-GWA4HPMP-C06n_37U.js} +1 -1
- package/dist/client/assets/{chunk-MBY4JIJT-BMMqnoVS.js → chunk-MBY4JIJT-DuowBunG.js} +1 -1
- package/dist/client/assets/{chunk-NETBCI7D-YxbfsgLs.js → chunk-NETBCI7D-ClNA7QFH.js} +1 -1
- package/dist/client/assets/{chunk-O7XYJQB3-B5lrUf5i.js → chunk-O7XYJQB3-BjcjInBL.js} +1 -1
- package/dist/client/assets/{chunk-UA2S7LBM-BDaXVsL8.js → chunk-UA2S7LBM-B-PAn1hd.js} +1 -1
- package/dist/client/assets/{chunk-WEXAMYUT-DxlWoHYQ.js → chunk-WEXAMYUT-Br84uK4B.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-Cp47KzsC.js → chunk-XXDRQBXY-BbBZykgX.js} +1 -1
- package/dist/client/assets/{chunk-Z7XXMR3K-CESnPXew.js → chunk-Z7XXMR3K-CQ-grwfe.js} +1 -1
- package/dist/client/assets/{chunk-ZIGJFQKS-CNWS7Wkq.js → chunk-ZIGJFQKS-CLwfE-hs.js} +1 -1
- package/dist/client/assets/{classDiagram-v2-NBCMYWYE-BceAVX_T.js → classDiagram-v2-NBCMYWYE-DD-bcOHO.js} +1 -1
- package/dist/client/assets/{core-Br-4vljZ.js → core-BADyutHL.js} +1 -1
- package/dist/client/assets/{cose-bilkent-JH36ORCC-D__9SuyS.js → cose-bilkent-JH36ORCC-fuMg3J_l.js} +1 -1
- package/dist/client/assets/{cynefin-OW5HDTMX-DgTdpSz6.js → cynefin-OW5HDTMX-DwFXJ_x8.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-VND7K2PF-CWEqRTNF.js → cynefinDiagram-VND7K2PF-cGL_k8gj.js} +1 -1
- package/dist/client/assets/{dagre-6A5THRUB-B3HGDOgj.js → dagre-6A5THRUB-BetgCBn9.js} +1 -1
- package/dist/client/assets/{diagram-22UHCM2B-Ce04XJcX.js → diagram-22UHCM2B-C7qT2Ix2.js} +1 -1
- package/dist/client/assets/{diagram-3UASUU5V-Bp5Chgzw.js → diagram-3UASUU5V-DGUO9DWV.js} +1 -1
- package/dist/client/assets/{diagram-ATOU4E4O-BmKaDuB5.js → diagram-ATOU4E4O-f520gjx5.js} +1 -1
- package/dist/client/assets/{diagram-CDSNMT55-DrSDVwyB.js → diagram-CDSNMT55-Dhrm4GzB.js} +1 -1
- package/dist/client/assets/{diagram-MLGK6HIB-8AyH2eMG.js → diagram-MLGK6HIB-Di0aRiuU.js} +1 -1
- package/dist/client/assets/{diagram-MPIPVDR6-C9AcuOld.js → diagram-MPIPVDR6-BHhVZUxI.js} +1 -1
- package/dist/client/assets/{dist-CVtr89jj.js → dist-CbdYocyN.js} +1 -1
- package/dist/client/assets/{dist-Cdc7REqJ.js → dist-Cezvykkn.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-ZINNZB2B-DX6ekwEH.js → ebnfDiagram-ZINNZB2B-CQA0eib_.js} +1 -1
- package/dist/client/assets/{elk-276RUBZZ-Cm9uWHa7.js → elk-276RUBZZ-CZKKVSu0.js} +1 -1
- package/dist/client/assets/{engine-oniguruma-DbGd6VkA.js → engine-oniguruma-B68c_YAs.js} +1 -1
- package/dist/client/assets/{erDiagram-OPXOYQCR-CaUHiYv4.js → erDiagram-OPXOYQCR-DcNnfq_S.js} +1 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-C61pKQjq.js +1 -0
- package/dist/client/assets/flowDiagram-KWPJA3E3-BolWtw3C.js +1 -0
- package/dist/client/assets/{ganttDiagram-FUAMR5RP-DL6UN0sq.js → ganttDiagram-FUAMR5RP-Dteh33ci.js} +1 -1
- package/dist/client/assets/{gitGraph-4MIJSDKK-CsKV1QJN.js → gitGraph-4MIJSDKK-DMTE1jTV.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-X574FWY7-D8Snpa_F.js → gitGraphDiagram-X574FWY7-EV_0IPok.js} +1 -1
- package/dist/client/assets/index-B__poZ2b.js +93 -0
- package/dist/client/assets/{index-CE0LasmM.css → index-CL4K6Y07.css} +1 -1
- package/dist/client/assets/{info-A6RAGUB7-BxOCsCG2.js → info-A6RAGUB7-WkHzxEDS.js} +1 -1
- package/dist/client/assets/{infoDiagram-VRGFBTTK-CfW5lEnk.js → infoDiagram-VRGFBTTK-BcH5U5G2.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-B4gbggT_.js → ishikawaDiagram-OU5B5YK6-Z8vZnj1l.js} +1 -1
- package/dist/client/assets/{journeyDiagram-ZHPQQLJL-IWmYxrcn.js → journeyDiagram-ZHPQQLJL-Cn-m-UYg.js} +1 -1
- package/dist/client/assets/{kanban-definition-PNTS6WVX-CbaKE2PB.js → kanban-definition-PNTS6WVX-DLOrUOML.js} +1 -1
- package/dist/client/assets/{line-BtA026Ya.js → line-DhKwT3E3.js} +1 -1
- package/dist/client/assets/{linear-B5Crnel0.js → linear-DvwuMCFu.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BPmT-0j3.js → mermaid-parser.core-CwcOI9nG.js} +3 -3
- package/dist/client/assets/{mermaid.core-BTblV3B-.js → mermaid.core-BabKb2iQ.js} +4 -4
- package/dist/client/assets/{mindmap-definition-NLK3R4M7-CIB2jRud.js → mindmap-definition-NLK3R4M7-D7wpNtz6.js} +1 -1
- package/dist/client/assets/{packet-AYTQ26CC-BWwlCBfL.js → packet-AYTQ26CC-BJablqte.js} +1 -1
- package/dist/client/assets/{pegDiagram-GJSIUBJH-DhOZCJeC.js → pegDiagram-GJSIUBJH-EAlXAkUz.js} +1 -1
- package/dist/client/assets/{pie-WAS4IAKB-BYPEomkb.js → pie-WAS4IAKB-BAAbtIiO.js} +1 -1
- package/dist/client/assets/{pieDiagram-5QR66LMP-BPMuMrQa.js → pieDiagram-5QR66LMP-b1pYP4ES.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-O4NWA36T-CNiAZ4Fx.js → quadrantDiagram-O4NWA36T-B_LJNNdE.js} +1 -1
- package/dist/client/assets/{radar-RG4KPBEZ-D4cJCxoB.js → radar-RG4KPBEZ-BKldNRRC.js} +1 -1
- package/dist/client/assets/{railroad-74A4TZTK-GypTiD9-.js → railroad-74A4TZTK-LvULpHpQ.js} +1 -1
- package/dist/client/assets/railroad-abnf-HS5TGJTU-CORGw4Le.js +1 -0
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-BXCX4hkl.js +1 -0
- package/dist/client/assets/railroad-peg-WCYAUIDC-C6BQUpjn.js +1 -0
- package/dist/client/assets/{railroadDiagram-XR7U4H2S-C9onf3MB.js → railroadDiagram-XR7U4H2S-kp6LeaeM.js} +1 -1
- package/dist/client/assets/{requirementDiagram-PLB6GJNP-BAtMHH1O.js → requirementDiagram-PLB6GJNP-Br-OgP6b.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-IPEJSGJF-ByIBebPb.js → sankeyDiagram-IPEJSGJF-DSIbAxcK.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-PO4LG4MO-CZWeGbVd.js → sequenceDiagram-PO4LG4MO-uVv8u8VI.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/client/assets/{src-3ZsKiqdK.js → src-Bmfs-TFn.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-GCMORJYK-BLS3Ppqp.js → stateDiagram-v2-GCMORJYK-Crql1z4d.js} +1 -1
- package/dist/client/assets/{swimlanes-2SLR337P-VfJv1Azt.js → swimlanes-2SLR337P-CnpU7AM-.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-Crca2YKi.js +8 -0
- package/dist/client/assets/{timeline-definition-EJHVYXUP-CFsTCeFJ.js → timeline-definition-EJHVYXUP-CqzGi-Sd.js} +1 -1
- package/dist/client/assets/{treeView-Q6P3EWNA-BcU2cd9W.js → treeView-Q6P3EWNA-N_EzEUvg.js} +1 -1
- package/dist/client/assets/{treemap-WGGIJYW6-BKWQgOsJ.js → treemap-WGGIJYW6-BYeVgP-v.js} +1 -1
- package/dist/client/assets/{usecaseDiagram-POWQR4AR-CaDVH5UF.js → usecaseDiagram-POWQR4AR-Dyeq2Zcy.js} +1 -1
- package/dist/client/assets/{vennDiagram-UO4OBE2U-BD60NU6D.js → vennDiagram-UO4OBE2U-CuCjJaOo.js} +1 -1
- package/dist/client/assets/{wardley-WFR3VGLG-CGRKLXxQ.js → wardley-WFR3VGLG-AV0-dO_Z.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VNRHLVJA-BNSajOpz.js → wardleyDiagram-VNRHLVJA-f0dVm2LA.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PMCCYNJV-Bw7XhF-N.js → xychartDiagram-PMCCYNJV-BNjSW7P1.js} +1 -1
- package/dist/client/index.html +2 -2
- package/package.json +4 -2
- package/plugin.json +3 -3
- package/dist/client/assets/architecture-7GRP2DOG-WcOrmKkC.js +0 -1
- package/dist/client/assets/channel-DhaDDyGS.js +0 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-n7NgJYAj.js +0 -1
- package/dist/client/assets/flowDiagram-KWPJA3E3-B-DNn9sz.js +0 -1
- package/dist/client/assets/index-CEiheKtN.js +0 -91
- package/dist/client/assets/railroad-abnf-HS5TGJTU-CJCTFtWl.js +0 -1
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-DEndv2ed.js +0 -1
- package/dist/client/assets/railroad-peg-WCYAUIDC-BJQI82cq.js +0 -1
- package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-CsAstSgi.js +0 -8
package/README.md
CHANGED
|
@@ -11,23 +11,26 @@
|
|
|
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
|
|
@@ -40,47 +43,30 @@ come back as fixes.
|
|
|
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. Otherwise the only thing that leaves your
|
|
64
|
+
machine is two small anonymous usage events per review, [listed in full](https://diffohq.github.io/diffo/telemetry)
|
|
65
|
+
and off with `diffo telemetry off`.
|
|
80
66
|
|
|
81
67
|
New here? [**Your first review, end to end**](https://diffohq.github.io/diffo/tutorial) takes about five minutes.
|
|
82
68
|
|
|
83
|
-
##
|
|
69
|
+
## Talk to the agent on the line
|
|
84
70
|
|
|
85
71
|
**We write code with an LLM. We review it alone.**
|
|
86
72
|
|
|
@@ -89,115 +75,59 @@ the thing is right. Reviewing never did. The code lands, the conversation ends,
|
|
|
89
75
|
read four hundred lines by yourself, in a viewer built for a world where whoever wrote it
|
|
90
76
|
had already moved on.
|
|
91
77
|
|
|
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**
|
|
78
|
+
Diffo keeps the conversation open through the review. The judgement stays yours. You just
|
|
79
|
+
stop reading alone.
|
|
149
80
|
|
|
150
|
-
|
|
151
|
-
one
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
81
|
+
- **Ask on any line.** The agent that wrote the code answers in the thread, with a
|
|
82
|
+
diagram when the shape needs one. Mark a thread a **Question** and it explains; mark it
|
|
83
|
+
a **Change** and it edits, so a question never turns into an unrequested refactor.
|
|
84
|
+
- **Fixes land in the diff you're reading.** The diff updates under your cursor, and a
|
|
85
|
+
hunk you had already read says *changed since you read it*, so the second pass stays
|
|
86
|
+
honest.
|
|
87
|
+
- **A map, not a verdict.** On a multi-file or subtle change the agent opens the review
|
|
88
|
+
with one orienting comment on what the change does. It never pre-reviews: no verdicts,
|
|
89
|
+
nothing is "fine". That judgement is the part it doesn't get to make.
|
|
90
|
+
## Read it in layers
|
|
160
91
|
|
|
161
92
|
A diff arrives alphabetically, which is almost never the order to read it in. Ask, and the
|
|
162
93
|
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>
|
|
94
|
+
files. You read one layer at a time, in the order the agent would explain it; `]` steps to
|
|
95
|
+
the next. Anything the agent touches after posting gathers in a *Since your review* layer,
|
|
96
|
+
so nothing hides outside the plan.
|
|
169
97
|
|
|
170
98
|
<picture>
|
|
171
99
|
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/layers-dark.gif">
|
|
172
100
|
<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
101
|
</picture>
|
|
174
102
|
|
|
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.
|
|
103
|
+
<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
104
|
|
|
177
|
-
##
|
|
105
|
+
## Review a pull request
|
|
178
106
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
107
|
+
When a pull request lands on *your* desk, give your agent the link. It checks the PR out
|
|
108
|
+
in a worktree of its own, so your checkout is never touched, and opens it as the same
|
|
109
|
+
review: the description and the GitHub threads come with it, and the agent reads beside
|
|
110
|
+
you as a copilot for code it did not write. Every comment has two tabs. **Comment on PR**
|
|
111
|
+
goes to the author, as one review when you finish. **Ask agent** stays on your machine:
|
|
112
|
+
the agent can run the tests and answer with evidence, and it never posts to GitHub.
|
|
182
113
|
|
|
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 |
|
|
114
|
+
<!-- Light-theme only, like the hero. The pull request is a real one on a demo repo
|
|
115
|
+
(DiffoHQ/todo-demo#1), and the review at the end is the one this take submitted. -->
|
|
116
|
+
<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
117
|
|
|
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.
|
|
118
|
+
<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
119
|
|
|
195
|
-
|
|
196
|
-
opens it in a worktree of its own, imports its conversation, puts your agent beside you as
|
|
197
|
-
a copilot for code it did not write, and submits your review to GitHub when you finish.
|
|
198
|
-
[Reviewing a pull request](https://diffohq.github.io/diffo/guide/pr-review) has the loop.
|
|
120
|
+
## Where it fits
|
|
199
121
|
|
|
200
|
-
|
|
122
|
+
Diffo isn't an AI reviewer. It doesn't grade your diff or leave generated nitpicks: you
|
|
123
|
+
read, and the agent is there to answer, explain, and fix.
|
|
124
|
+
|
|
125
|
+
| | **Diffo** | AI reviewer bot | Plain pull request review |
|
|
126
|
+
| --- | --- | --- | --- |
|
|
127
|
+
| Who reads the code | **you** | a model | you |
|
|
128
|
+
| Who answers your questions | **the agent, in the thread, now** | nobody | the author, when they get to it |
|
|
129
|
+
| When | **while the agent writes, or when the PR lands** | after you push | after you push |
|
|
130
|
+
| What comes out | **fixes in the diff, or a review on GitHub** | a list of comments | a review on GitHub |
|
|
201
131
|
|
|
202
132
|
## How it works
|
|
203
133
|
|
|
@@ -206,17 +136,12 @@ a copilot for code it did not write, and submits your review to GitHub when you
|
|
|
206
136
|
<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%">
|
|
207
137
|
</picture>
|
|
208
138
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
| You want to review | Command |
|
|
216
|
-
| --- | --- |
|
|
217
|
-
| Uncommitted work in progress (the default) | `diffo` |
|
|
218
|
-
| Everything since you branched off `main` | `diffo --base main` |
|
|
219
|
-
| A pull request | *not supported yet* |
|
|
139
|
+
One process on your machine, bound to loopback: no account, no cloud, and no model API.
|
|
140
|
+
The one thing it reports is [anonymous usage data](https://diffohq.github.io/diffo/telemetry),
|
|
141
|
+
two events per review, never code or paths, off with one command. Diffo spawns no agents
|
|
142
|
+
of its own; the one you're already talking to stays attached through the `diffo` CLI, so
|
|
143
|
+
your comments land in the session that holds the context. The viewer itself is a real diff viewer, unified and split, keyboard-first, with
|
|
144
|
+
GitHub's conventions. The CLI, the flags, and everything under the hood are in the docs.
|
|
220
145
|
|
|
221
146
|
## Docs
|
|
222
147
|
|
|
@@ -224,81 +149,31 @@ cheapest to change.
|
|
|
224
149
|
| --- | --- |
|
|
225
150
|
| [**Your first review**](https://diffohq.github.io/diffo/tutorial) | The whole loop end to end, about five minutes |
|
|
226
151
|
| [**Getting started**](https://diffohq.github.io/diffo/guide/getting-started) | Install, and where each agent gets wired |
|
|
227
|
-
| [**The review loop**](https://diffohq.github.io/diffo/guide/the-loop) | Reading,
|
|
152
|
+
| [**The review loop**](https://diffohq.github.io/diffo/guide/the-loop) | Reading, commenting, and what the agent receives |
|
|
153
|
+
| [**Layers**](https://diffohq.github.io/diffo/guide/layers) | The agent's reading plan: ordered steps, one at a time |
|
|
154
|
+
| [**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 |
|
|
228
155
|
| [**How it works**](https://diffohq.github.io/diffo/guide/how-it-works) | The components and the server lifecycle |
|
|
229
156
|
| [**The agent side**](https://diffohq.github.io/diffo/agents) | The agent protocol: every command, every payload |
|
|
230
157
|
| [**Architecture**](https://diffohq.github.io/diffo/architecture) | Diff pipeline, delivery queue, SQLite state |
|
|
231
158
|
| [**CLI**](https://diffohq.github.io/diffo/reference/cli) and [**Keyboard shortcuts**](https://diffohq.github.io/diffo/reference/keyboard-shortcuts) | Reference |
|
|
232
159
|
| [**FAQ**](https://diffohq.github.io/diffo/faq) | The short answers |
|
|
233
160
|
|
|
234
|
-
## Under the hood
|
|
235
|
-
|
|
236
|
-
TypeScript on Node >= 24: a [Hono](https://hono.dev) server over loopback serving a React 19
|
|
237
|
-
UI, live updates over server-sent events from one recursive filesystem watch, and state in a
|
|
238
|
-
single SQLite file at `~/.diffo/diffo.db` through the runtime's built-in `node:sqlite`, so
|
|
239
|
-
there is no database to install. **No network calls of its own**: a pull request review
|
|
240
|
-
talks to GitHub only through your `gh`. 1,307 tests across 70 files.
|
|
241
|
-
|
|
242
|
-
Reviews are scoped per repo **and branch**, and the server is loopback-only, rejecting
|
|
243
|
-
non-loopback `Host` and `Origin` headers so a web page can't reach into your repo through
|
|
244
|
-
it. The full walkthrough is in [**Architecture**](https://diffohq.github.io/diffo/architecture).
|
|
245
|
-
|
|
246
|
-
<details>
|
|
247
|
-
<summary><b>Why read marks survive a live diff</b></summary>
|
|
248
|
-
|
|
249
|
-
<br>
|
|
250
|
-
|
|
251
|
-
Every hunk carries a **content-addressed id**: a hash of its path and changed lines, and
|
|
252
|
-
deliberately not its line numbers. That one decision is what makes the live review honest.
|
|
253
|
-
|
|
254
|
-
- Read marks survive a refresh, because an untouched hunk keeps its id.
|
|
255
|
-
- An edited hunk mints a new id, loses its mark, and says **changed since you read it**. You
|
|
256
|
-
can't accidentally sign off on code you never saw.
|
|
257
|
-
- The ids from your last Finish are a complete record of what existed then, so "what moved
|
|
258
|
-
since I last looked" is a set subtraction, needing no timestamps.
|
|
259
|
-
|
|
260
|
-
</details>
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
161
|
## Open core
|
|
265
162
|
|
|
266
163
|
Everything in this repository is the core, and the core stays Apache-2.0: local review, the
|
|
267
|
-
agent loop, the CLI, the Agent Skill. It works offline, for one
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
we commit to: **anything that runs on your machine for one reviewer is core.**
|
|
272
|
-
|
|
273
|
-
## Status
|
|
274
|
-
|
|
275
|
-
Diffo is pre-1.0: the loop below works end to end (this repo is reviewed with it
|
|
276
|
-
daily) and the edges are still moving. What works today:
|
|
277
|
-
|
|
278
|
-
- [x] [Live review of any changeset](https://diffohq.github.io/diffo/guide/how-it-works): the working tree, or anything since `--base`.
|
|
279
|
-
- [x] [The comment loop](https://diffohq.github.io/diffo/guide/the-loop): threads that reach the session that wrote the code.
|
|
280
|
-
- [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.
|
|
281
|
-
- [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.
|
|
282
|
-
- [x] [Reading tools](https://diffohq.github.io/diffo/reference/keyboard-shortcuts): unified and split diffs, word-level marks, coverage tracking.
|
|
283
|
-
- [x] [Pull request review](https://diffohq.github.io/diffo/guide/pr-review): `diffo <PR URL>` reviews a GitHub PR in a worktree of its own, with the conversation imported and your review submitted from Diffo.
|
|
164
|
+
agent loop, pull request review, the CLI, the Agent Skill. It works offline, for one
|
|
165
|
+
reviewer, forever, for free. A hosted team tier is planned, and none of it will take an
|
|
166
|
+
existing core feature behind a paywall: **anything that runs on your machine for one
|
|
167
|
+
reviewer is core.**
|
|
284
168
|
|
|
285
169
|
## Contributing
|
|
286
170
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
Local development is `pnpm dev` (server and client together). One hard rule:
|
|
294
|
-
**`skills/diffo/SKILL.md` is generated.** Edit [`src/skill.ts`](src/skill.ts) and run
|
|
295
|
-
`pnpm build:skill`; a test fails if the committed file drifts. That rewrites the repo
|
|
296
|
-
file, not the skill your own agent runs; `pnpm dev:skill --global` installs a separate
|
|
297
|
-
`/diffo-dev` that drives your checkout, alongside the shipped `/diffo`.
|
|
298
|
-
|
|
299
|
-
Details in [CONTRIBUTING.md](CONTRIBUTING.md), plus a [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
300
|
-
and the [CHANGELOG](CHANGELOG.md). First-time contributors sign a [CLA](CLA.md): a bot asks
|
|
301
|
-
on your first pull request, and signing is one reply.
|
|
171
|
+
Diffo is pre-1.0: this repo is reviewed with it daily, and the edges are still moving.
|
|
172
|
+
`pnpm check` runs the five gates CI runs. One hard rule: **`skills/diffo/SKILL.md` is
|
|
173
|
+
generated** from [`src/skill.ts`](src/skill.ts); edit the source and run `pnpm build:skill`.
|
|
174
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) has the rest, with a [Code of Conduct](CODE_OF_CONDUCT.md),
|
|
175
|
+
the [CHANGELOG](CHANGELOG.md), and the [CLA](CLA.md) a bot asks first-time contributors to
|
|
176
|
+
sign, in one reply.
|
|
302
177
|
|
|
303
178
|
Found a security problem? Please don't open a public issue. The
|
|
304
179
|
[Security Policy](SECURITY.md) says where to send it and what's in scope.
|