diffing 0.6.2 → 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 +139 -99
- package/dist/apply-suggestion-BAuyCYk6.mjs +54 -0
- package/dist/cli-agent-BlMtx1Tx.mjs +736 -0
- package/dist/cli-agent-C4Fb90GL.mjs +728 -0
- package/dist/cli-agent-ChALuNbw.mjs +841 -0
- package/dist/cli-agent-D71pq2ep.mjs +841 -0
- package/dist/cli-agent-qBT8clNM.mjs +841 -0
- package/dist/cli-gh-6qiblgj7.mjs +150 -0
- package/dist/cli-gh-D5OCnjNe.mjs +150 -0
- package/dist/cli-gh-KjPnyST6.mjs +150 -0
- package/dist/cli.mjs +38 -66
- package/dist/client/assets/{angular-html-Dg8frIKA.js → angular-html-fJEV04aV.js} +1 -1
- package/dist/client/assets/{angular-ts-BgXWv16g.js → angular-ts-xftEy_9y.js} +1 -1
- package/dist/client/assets/{apl-uFl-_xI6.js → apl-DUFfGxuB.js} +1 -1
- package/dist/client/assets/{arc-2DyFlUoQ.js → arc-RVQiB1sa.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Cpo5XnQh.js → architectureDiagram-3BPJPVTR-DgH6newi.js} +1 -1
- package/dist/client/assets/{astro-CsSgohj_.js → astro-B7BLqQNi.js} +1 -1
- package/dist/client/assets/{blade-tmMbmea0.js → blade-CBEg4pSd.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-C2j4VeON.js → blockDiagram-GPEHLZMM-La5y3Fsh.js} +1 -1
- package/dist/client/assets/{c-CYFchk-Y.js → c-WpzQapSy.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-B9Iu60rg.js → c4Diagram-AAUBKEIU-Ut0ZmiTu.js} +1 -1
- package/dist/client/assets/channel-CsxAySTG.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-CYF5wgmI.js → chunk-2J33WTMH-MeV3nUej.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-BsCKEfSk.js → chunk-3OPIFGDE-xRyDWGrg.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-CKaohpWW.js → chunk-4BX2VUAB-BFVyXq5X.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CPg0c8fY.js → chunk-55IACEB6-_oXB-8Yw.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-qstslfP1.js → chunk-5ZQYHXKU-CYUXotxX.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-C1WRwOi2.js → chunk-727SXJPM-hUUwZVvB.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-_jbfFh_H.js → chunk-AQP2D5EJ-DK43jOQq.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CjQkUxwj.js → chunk-BSJP7CBP-CMo_92Fk.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-D4khYgW5.js → chunk-CSCIHK7Q-B_3Ak8tT.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-B1r9As4X.js → chunk-FMBD7UC4-CB3nCgdr.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-XehlazPT.js → chunk-KSCS5N6A-eSZPuByD.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-5KMCRmgT.js → chunk-L5ZTLDWV-BMQsVhiH.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA--x7aE-36.js → chunk-LZXEDZCA-L3ad86Se.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-BcUeNQF6.js → chunk-ND2GUHAM-BUU6Elne.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-HdA4zA81.js → chunk-NZK2D7GU-8UnIsHgz.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-BbkpkgBW.js → chunk-O5CBEL6O-Bt0iBpRT.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-t_dKKAQO.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-B712vNst.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-BrjJtb92.js → chunk-XPW4576I-CiPhy2lR.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-WK8tPFKZ.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DJNeQCV0.js +1 -0
- package/dist/client/assets/{cobol-CbEdzJpe.js → cobol-C6EN1HSS.js} +1 -1
- package/dist/client/assets/{coffee-BYBPPvKf.js → coffee-0fBPy0at.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-C2UlmvWG.js → cose-bilkent-S5V4N54A-B6017ve4.js} +1 -1
- package/dist/client/assets/{cpp-Cy1Wnp8d.js → cpp-Cgd-x8Qm.js} +1 -1
- package/dist/client/assets/{crystal-Bg1sUJya.js → crystal-c3E-pfg5.js} +1 -1
- package/dist/client/assets/{css-C6iyzRBi.js → css-Cv1L9Lkg.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-CLP5IYO3.js → dagre-BM42HDAG-Dq1xDMIS.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Dg8GXMUD.js → diagram-2AECGRRQ-BhzSmI_P.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-D5eskvC7.js → diagram-5GNKFQAL-DQ80iRmT.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-SO-9Apcj.js → diagram-KO2AKTUF-DgFYNuBX.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-Dz15-yRy.js → diagram-LMA3HP47-jRSitpUw.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BuQK0W1m.js → diagram-OG6HWLK6-DW8rasB2.js} +1 -1
- package/dist/client/assets/{dist-CZ555WMx.js → dist-yGGkBCKR.js} +1 -1
- package/dist/client/assets/{edge-CmOR4HCT.js → edge-Bhz1Ui7v.js} +1 -1
- package/dist/client/assets/{elixir-CK9qhOZG.js → elixir-DwVjV4S5.js} +1 -1
- package/dist/client/assets/{elm-DZWlTp8-.js → elm-D_aEQPcR.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-D7vADGZy.js → erDiagram-TEJ5UH35-Cw9JC5D-.js} +1 -1
- package/dist/client/assets/{erb-CTTGdXJ0.js → erb-CWSTVYrU.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-BwcgAtP3.js → flowDiagram-I6XJVG4X-CaMT-5ly.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-kInginE9.js → ganttDiagram-6RSMTGT7-C_676lk4.js} +1 -1
- package/dist/client/assets/{git-rebase-B_sSbVaY.js → git-rebase-YH8g16wO.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C4pDDMLO.js → gitGraphDiagram-PVQCEYII-BGOaoZI0.js} +1 -1
- package/dist/client/assets/{glimmer-js-BaLXlo90.js → glimmer-js-BW02TI5b.js} +1 -1
- package/dist/client/assets/{glimmer-ts-ugNWY62Y.js → glimmer-ts-CI0zXYYJ.js} +1 -1
- package/dist/client/assets/{glsl-CDofiyvf.js → glsl-BPxiz4_T.js} +1 -1
- package/dist/client/assets/{graphql-lRTsx6gb.js → graphql-i9EfBOYT.js} +1 -1
- package/dist/client/assets/{hack-DG646xxf.js → hack-PGwXKmg5.js} +1 -1
- package/dist/client/assets/{haml-CjNyEqTY.js → haml-DJEaRUnh.js} +1 -1
- package/dist/client/assets/{handlebars-DmTlsycc.js → handlebars-BKbKE3mu.js} +1 -1
- package/dist/client/assets/{html-CYKa0iGt.js → html-DUCTVgfz.js} +1 -1
- package/dist/client/assets/{html-derivative-CJrmldEy.js → html-derivative-DEAtKAli.js} +1 -1
- package/dist/client/assets/{http-Dv_sB6KO.js → http-bjFkSEgi.js} +1 -1
- package/dist/client/assets/{hurl-aIa6gC3s.js → hurl-Be_0iFn7.js} +1 -1
- package/dist/client/assets/{index-DLwFuHoH.js → index-Dwcvtw9r.js} +141 -99
- package/dist/client/assets/index-kdpS_WCg.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-DE1yaqeG.js → infoDiagram-5YYISTIA-DEM4xhVR.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-D61KC690.js → ishikawaDiagram-YF4QCWOH-qvVbcu9F.js} +1 -1
- package/dist/client/assets/{java--GCJC5Ht.js → java-DI-eL_a_.js} +1 -1
- package/dist/client/assets/{javascript-CLU-vrsL.js → javascript-C1NsxtXz.js} +1 -1
- package/dist/client/assets/{jinja-DpKxO4hN.js → jinja-CehVuPO9.js} +1 -1
- package/dist/client/assets/{jison-DAzEKgwk.js → jison-f1_yV3M6.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Bt37oidm.js → journeyDiagram-JHISSGLW-B_zXWlKX.js} +1 -1
- package/dist/client/assets/{json-CoxC1kMn.js → json-C5zdLJJF.js} +1 -1
- package/dist/client/assets/{jsx-Bjv8cqXv.js → jsx-B3RrBasc.js} +1 -1
- package/dist/client/assets/{julia-2HI5Piu6.js → julia-Bi0vJ2BX.js} +1 -1
- package/dist/client/assets/{just-AUrPjdB4.js → just-xIhMZsmQ.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-D46QdRYJ.js → kanban-definition-UN3LZRKU-CbD2KWf1.js} +1 -1
- package/dist/client/assets/{latex-DjzDlfkY.js → latex-Dp7jRlke.js} +1 -1
- package/dist/client/assets/{line-D_rKDTVX.js → line-WeunFuQk.js} +1 -1
- package/dist/client/assets/{linear-DCm3ZWOL.js → linear-CDJM1IL7.js} +1 -1
- package/dist/client/assets/{liquid-DZ8JEV93.js → liquid-KVO31g_D.js} +1 -1
- package/dist/client/assets/{lua-iKYCK6sd.js → lua-DhSdSYSx.js} +1 -1
- package/dist/client/assets/{marko-CrhrBZpj.js → marko-ypMfiov0.js} +1 -1
- package/dist/client/assets/{mdc-M6YkRqT_.js → mdc-Co-EpgU8.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-DOlZkAUl.js → mermaid-parser.core-zvabDowq.js} +1 -1
- package/dist/client/assets/{mermaid.core-B5kraaYr.js → mermaid.core-L0zHdHeP.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-CG-S_0Tm.js → mindmap-definition-RKZ34NQL-Dsz4uiiI.js} +1 -1
- package/dist/client/assets/{nginx-DGSv66H3.js → nginx-BFhKPsbv.js} +1 -1
- package/dist/client/assets/{nim-wTb9iFPK.js → nim-DQUznJNh.js} +1 -1
- package/dist/client/assets/{perl-BrLOtih-.js → perl-CK3JJIks.js} +1 -1
- package/dist/client/assets/{php-BpG59zED.js → php-Bjv6uy3B.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BSsvT950.js → pieDiagram-4H26LBE5-Dsd16XxY.js} +1 -1
- package/dist/client/assets/{pug-L7QegceF.js → pug-llyOv0JA.js} +1 -1
- package/dist/client/assets/{qml-Bhe1hZ7B.js → qml-XSU4YlGi.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Bxs1ZIId.js → quadrantDiagram-W4KKPZXB-XwtlgYug.js} +1 -1
- package/dist/client/assets/{r-D1TBw_pw.js → r-C7DDDUty.js} +1 -1
- package/dist/client/assets/{razor-CQm1uFKr.js → razor-CjoCuGIf.js} +1 -1
- package/dist/client/assets/{regexp--jRne08M.js → regexp-C7lVLI_E.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-BvrwIHRn.js → requirementDiagram-4Y6WPE33-rjFkmK7q.js} +1 -1
- package/dist/client/assets/review-export-Dzn9Nrv2.js +7 -0
- package/dist/client/assets/{rst-DojkdR69.js → rst-CoXGYz_Q.js} +1 -1
- package/dist/client/assets/{ruby-CihGsdWE.js → ruby-D0SxUI68.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-ChVx7-uL.js → sankeyDiagram-5OEKKPKP-ULHSBgpO.js} +1 -1
- package/dist/client/assets/{sas-De9KOrSF.js → sas-Dg6lNKUG.js} +1 -1
- package/dist/client/assets/{scss-s1VsrZAM.js → scss-Bor1IW81.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DfGXu7Db.js → sequenceDiagram-3UESZ5HK-PxpMeVqA.js} +1 -1
- package/dist/client/assets/{shellscript-BQarhH5B.js → shellscript-CRyyhEkO.js} +1 -1
- package/dist/client/assets/{shellsession-DudKTKQ_.js → shellsession-DjKLkXA9.js} +1 -1
- package/dist/client/assets/{soy-CQggW1_P.js → soy-C8vE4Bz5.js} +1 -1
- package/dist/client/assets/{sql-CyxjmxEX.js → sql-BrDZX5HK.js} +1 -1
- package/dist/client/assets/{src-Be3tFbq6.js → src-CNmxBaik.js} +1 -1
- package/dist/client/assets/{stata-Baq2oukf.js → stata-b17UrTyn.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-DUsSkWi-.js → stateDiagram-AJRCARHV-BBeJC3ay.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CHWDCBHj.js +1 -0
- package/dist/client/assets/{surrealql-DY_lPQU6.js → surrealql-CsZ116gs.js} +1 -1
- package/dist/client/assets/{svelte-oBaORrzD.js → svelte-D0HiSC98.js} +1 -1
- package/dist/client/assets/{templ-WpkyVGPg.js → templ-wtuCSMmI.js} +1 -1
- package/dist/client/assets/{tex-t_gMyObp.js → tex-DmngvaO4.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DO30eyIk.js → timeline-definition-PNZ67QCA-ChtEFrOv.js} +1 -1
- package/dist/client/assets/{ts-tags-Dn6NjJLA.js → ts-tags-Cu7v6AQx.js} +1 -1
- package/dist/client/assets/{tsx-DDWp_p5y.js → tsx-CQTsVgW0.js} +1 -1
- package/dist/client/assets/{twig-FBY22xUa.js → twig--VG4V71I.js} +1 -1
- package/dist/client/assets/{typescript-BHZBosYe.js → typescript-Dm0_1KTl.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DbE8UKE1.js → vennDiagram-CIIHVFJN-CQSGJn90.js} +1 -1
- package/dist/client/assets/{vue-CrOmWBlh.js → vue-BlytSRgm.js} +1 -1
- package/dist/client/assets/{vue-html-jBuGpXgg.js → vue-html-BFRFxjGG.js} +1 -1
- package/dist/client/assets/{vue-vine-DEzqOkvG.js → vue-vine-B4MbjVZh.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BqhSY5Qs.js → wardleyDiagram-YWT4CUSO-AJu-N2AD.js} +1 -1
- package/dist/client/assets/{xml-DkWImCZV.js → xml-BBYil7Ep.js} +1 -1
- package/dist/client/assets/{xsl-BotuNSYU.js → xsl-DfHxKcnH.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DA2pXGD9.js → xychartDiagram-2RQKCTM6-BOakoiUg.js} +1 -1
- package/dist/client/assets/{yaml-8lMTQUH5.js → yaml-B9aOtJMC.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/comment-format-B5AcGcR-.mjs +118 -0
- package/dist/comment-format-CKTt0fzi.mjs +113 -0
- package/dist/comment-format-DG_PAehC.mjs +117 -0
- package/dist/completions-ZSKYvW06.mjs +126 -0
- package/dist/diff-fingerprint-CWa-soYD.mjs +78 -0
- package/dist/doctor-q6oA64hm.mjs +195 -0
- package/dist/find-tui-binary-CRpbYXLC.mjs +52 -0
- package/dist/git-Czo96ymM.mjs +789 -0
- package/dist/git-DaP_1rVy.mjs +2 -0
- package/dist/github-C9GLNak7.mjs +2 -0
- package/dist/github-HfIlIS-J.mjs +525 -0
- package/dist/mcp-7eXATtez.mjs +1334 -0
- package/dist/mcp-BBk8AIO4.mjs +1334 -0
- package/dist/mcp-BJxrW9dS.mjs +1334 -0
- package/dist/mcp-BhT5GgYF.mjs +1334 -0
- package/dist/mcp-BsGdNA88.mjs +1334 -0
- package/dist/mcp-Ca9QAlJ0.mjs +1334 -0
- package/dist/mcp-eor39qmD.mjs +1352 -0
- package/dist/plan-format-BQyx--mp.mjs +144 -0
- package/dist/plan-format-Bi46QS0m.mjs +132 -0
- package/dist/review-export-BoV0884M.mjs +66 -0
- package/dist/review-export-CKTI5Od_.mjs +66 -0
- package/dist/review-export-DjxKBeIZ.mjs +66 -0
- package/dist/server-AisDKkpW.mjs +3227 -0
- package/dist/server-BUsRhL1B.mjs +3283 -0
- package/dist/server-Bc2m9R5-.mjs +3263 -0
- package/dist/server-C105rwQw.mjs +3283 -0
- package/dist/server-D0Ni8PKP.mjs +3252 -0
- package/dist/server-TOElOuNP.mjs +3258 -0
- package/dist/server-lock-uqSdDYeR.mjs +153 -0
- package/dist/settings-BVnzGFL7.mjs +478 -0
- package/dist/update-check-fe0tR8tx.mjs +129 -0
- package/package.json +1 -1
- package/dist/client/assets/channel-Br3gV-0C.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-yNyHmFLj.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-DOSgjhZV.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BV8x1oiD.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-AibFxRy2.js +0 -1
- package/dist/client/assets/index-CkjX2qPW.css +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DczGQieS.js +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
A local-first code review tool and double-sided bridge designed for the modern AI coding agent workflow. Review AI-generated changes in a high-fidelity, GitHub-like web UI, leave inline comments, and hand them back to your coding agent to fix in real time — and review the agent's **plan** the same way *before* it writes any code, approving, rejecting, or requesting changes on specific lines and sections.
|
|
8
8
|
|
|
9
|
-
<img width="
|
|
9
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/c1e12c28-610e-4d68-abb1-3c8dde58560e" />
|
|
10
|
+
<img width="1604" height="1041" alt="image" src="https://github.com/user-attachments/assets/c1f7a525-6948-4cb6-aa02-17cc29f17210" />
|
|
11
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/95a51403-3bce-453c-a831-43a2834c5ed7" />
|
|
12
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/3e0638e2-f780-4e14-9a44-ef10bf60d5f9" />
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
---
|
|
@@ -31,10 +34,11 @@ Prefer the terminal? Add `--tui` for a native-Rust terminal UI — same review f
|
|
|
31
34
|
diffing --tui
|
|
32
35
|
```
|
|
33
36
|
> [!WARNING]
|
|
34
|
-
> The TUI is **experimental
|
|
35
|
-
>
|
|
36
|
-
>
|
|
37
|
-
>
|
|
37
|
+
> The TUI is **experimental**. The interface, keymap, and `server.json`
|
|
38
|
+
> (`mode: "tui"`) on-disk format may change in a minor release. The web UI is
|
|
39
|
+
> the supported path for production workflows. See
|
|
40
|
+
> [Native Terminal UI (TUI)](#native-terminal-ui-tui) for the full feature set,
|
|
41
|
+
> keymap, and stability notes.
|
|
38
42
|
|
|
39
43
|
### 3. Update
|
|
40
44
|
Check if a new version is available on npm and upgrade instantly via the CLI:
|
|
@@ -48,16 +52,18 @@ diffing update
|
|
|
48
52
|
|
|
49
53
|
A local Hono-powered review server delivers a full-featured GitHub-like code review interface directly in your browser.
|
|
50
54
|
|
|
51
|
-
- **Split / Unified View** —
|
|
55
|
+
- **Split / Unified View** — Side-by-side (`split`) or inline (`unified`) layouts. Set under **Settings → Diff style**, or press `m` to cycle. Diff style is not a toolbar toggle.
|
|
56
|
+
- **Compact toolbar** — Repo + branch, quiet summary chips (files, `+X/−Y`, open comments), Search (`⌘K`), Plans badge, Resolve all, Settings, and **Send review**.
|
|
52
57
|
- **Syntax Highlighting** — Powered by Shiki via `@pierre/diffs`, with high-fidelity highlighting for 200+ languages.
|
|
53
|
-
- **Interactive File Tree** — Hierarchical
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
58
|
+
- **Interactive File Tree** — Hierarchical navigation with collapsible folders, viewed/unviewed tracking, change-type indicators, smart filter chips (**All / Unviewed / Comments / Since last**), multi-select extension filters, and path search.
|
|
59
|
+
- **Icon file-header actions** — Expand context, open in editor, file-level comment, and Viewed — with tooltips; less chrome noise per card.
|
|
60
|
+
- **Status Dashboard (Comment Tracker)** — Bottom panel tracking open, replied, and resolved comments with severity filters and click-to-navigate.
|
|
61
|
+
- **Multi-round review** — Round history popover, “changed since last send” chips, and outdated-comment detection.
|
|
62
|
+
- **Server-Side State & Drafts Persistence** — No browser storage is used. Settings, panel sizes, session state, and comment drafts live under `~/.diffing/` (global settings in `~/.config/diffing/settings.json`).
|
|
63
|
+
- **Dynamic Font Customization** — Google Fonts or local system fonts for UI + mono (see [custom fonts](#a-note-on-custom-fonts)).
|
|
64
|
+
- **Resizable Panels** — Drag-to-resize sidebar (240px–640px) and comment tracker (100px–600px); sizes persisted server-side.
|
|
65
|
+
- **Skeleton Loading Screen** — Full shimmer placeholder UI during initial load.
|
|
66
|
+
- **Image Diff Previews** — Side-by-side comparison for common image formats.
|
|
61
67
|
|
|
62
68
|
---
|
|
63
69
|
|
|
@@ -83,7 +89,8 @@ A local Hono-powered review server delivers a full-featured GitHub-like code rev
|
|
|
83
89
|
- **Instant Switching** — CSS transitions suppressed during theme changes for a snappy, lag-free experience.
|
|
84
90
|
- **Persistent Setting** — Theme choice saved to `~/.config/diffing/settings.json` and restored on next launch.
|
|
85
91
|
|
|
86
|
-
|
|
92
|
+
|
|
93
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/eaa0675c-21d6-4754-8fbd-97ee63a743dc" />
|
|
87
94
|
|
|
88
95
|
|
|
89
96
|
|
|
@@ -103,8 +110,7 @@ Blazing-fast, native fuzzy code search integrated directly into the sidebar sear
|
|
|
103
110
|
- **Graceful Degradation** — If the native Rust binary is unavailable, search reports as unavailable without crashing the server.
|
|
104
111
|
- **Auto-Indexing** — The Rust engine maintains its own file system watcher for real-time index updates as the working tree changes.
|
|
105
112
|
|
|
106
|
-
<img width="
|
|
107
|
-
|
|
113
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/2b2bc001-2d3a-4744-b9d5-a23642f1afba" />
|
|
108
114
|
|
|
109
115
|
---
|
|
110
116
|
|
|
@@ -119,7 +125,7 @@ Full keyboard-driven navigation with vim-like motions and a modal status bar:
|
|
|
119
125
|
| `Ctrl+d` / `Ctrl+u` | Scroll half-page down/up |
|
|
120
126
|
| `g` `g` | Jump to top of diff |
|
|
121
127
|
| `G` | Jump to bottom of diff |
|
|
122
|
-
| `m` | Toggle split/unified view |
|
|
128
|
+
| `m` | Toggle split/unified view (also Settings → Diff style) |
|
|
123
129
|
| `t` | Cycle tab size (2 → 4 → 8) |
|
|
124
130
|
| `w` | Toggle line wrap |
|
|
125
131
|
| `n` | Toggle line numbers |
|
|
@@ -139,11 +145,23 @@ Full keyboard-driven navigation with vim-like motions and a modal status bar:
|
|
|
139
145
|
| `g` `t` | Open theme picker |
|
|
140
146
|
| `Cmd/Ctrl+K` | Open global command palette |
|
|
141
147
|
| `Cmd/Ctrl+,` | Toggle settings panel |
|
|
142
|
-
| `?` | Show shortcuts help modal |
|
|
148
|
+
| `?` / `⌘?` | Show shortcuts help modal |
|
|
149
|
+
|
|
150
|
+
### Plan page extras (when reviewing a plan at `/plan`)
|
|
151
|
+
| Key | Action |
|
|
152
|
+
|-----|--------|
|
|
153
|
+
| `m` | Cycle Source → Read → Split |
|
|
154
|
+
| `z` | Toggle zen reading (switches to Read if needed); Esc also exits zen |
|
|
155
|
+
| `e` | Toggle **live plan edit** (current version; prefers Split + source editor) |
|
|
156
|
+
| `⌘/Ctrl+S` | While editing: flush autosave now |
|
|
157
|
+
| `o` | Toggle Outline (left TOC) |
|
|
158
|
+
| `c` | Toggle Comments map (right rail) |
|
|
159
|
+
| `J` / `K` | Next / previous plan |
|
|
160
|
+
| Esc | Edit mode: open Discard (or exit edit if nothing to discard); else exit zen / dismiss Add-comment chip / close draft |
|
|
143
161
|
|
|
144
162
|
A vim-style status bar at the bottom displays the current mode (NORMAL/INSERT), file path, and a help button. Multi-key sequences use an 800ms key buffer.
|
|
145
163
|
|
|
146
|
-
<img width="
|
|
164
|
+
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/f0971704-65a2-4512-978f-6b6e656b5dda" />
|
|
147
165
|
|
|
148
166
|
|
|
149
167
|
---
|
|
@@ -151,13 +169,13 @@ A vim-style status bar at the bottom displays the current mode (NORMAL/INSERT),
|
|
|
151
169
|
## Native Terminal UI (TUI) — *Experimental*
|
|
152
170
|
|
|
153
171
|
> [!WARNING]
|
|
154
|
-
> The TUI is **experimental
|
|
155
|
-
>
|
|
156
|
-
>
|
|
157
|
-
>
|
|
158
|
-
>
|
|
172
|
+
> The TUI is **experimental**. The interface, keymap, and on-disk format of
|
|
173
|
+
> `server.json` (`mode: "tui"`) may change in a minor release before
|
|
174
|
+
> stabilisation. The web UI is the supported path for production workflows;
|
|
175
|
+
> please open an issue before depending on the TUI for CI / agent automation.
|
|
176
|
+
> The web review flow, plan review, and PR review are unaffected.
|
|
159
177
|
|
|
160
|
-
`diffing --tui` opens an **opt-in native-Rust terminal interface** that mirrors the
|
|
178
|
+
`diffing --tui` opens an **opt-in native-Rust terminal interface** that mirrors the local code-review workflow — no browser or Electron. The renderer and headless tools share one sparse diff index. A random-port loopback API is published through `server.json` with `mode: "tui"` and a per-session capability, so local agents can inspect a large diff without receiving the whole patch.
|
|
161
179
|
|
|
162
180
|
The default `diffing` behaviour is **byte-identical** with and without `--tui` — the TUI is strictly opt-in. If the env cannot support a TUI (piped stdin, CI, no raw mode) or the binary is missing, you get a one-line stderr note and the normal `git diff` output. The web mode is also unaffected by the TUI build; the same `diffing` install serves either.
|
|
163
181
|
|
|
@@ -173,15 +191,26 @@ diffing --tui -- -- src/ # Limit a TUI review to a directory
|
|
|
173
191
|
|
|
174
192
|
**Features**
|
|
175
193
|
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
194
|
+
- **Disk-backed streaming index** — Git output is parsed as bytes into sparse file/hunk/checkpoint metadata. The first partial generation is usable during ingestion; neither the TUI nor an agent needs to retain the full patch in memory.
|
|
195
|
+
- **Viewport-only rendering** — only visible rows are sought, decoded, syntax-highlighted, and converted to terminal cells. Unified and split layouts, horizontal scrolling, wrapping, binary markers, untracked files, and live working-tree refresh are supported.
|
|
196
|
+
- **Vim-style file tree & keymap** — numeric counts plus `j/k`, `gg/G`, `Ctrl-d/u`, `J/K`, `]h/[h`, `]c/[c`, `zz`, `h/l`, `/`, `n/N`, `:`, `Tab`, `v`, `w`, `m`, `t`, and `?`. `Esc` cancels a mode; `q` or `Ctrl-C` quits.
|
|
178
197
|
- **Full comment CRUD** — mirrors `src/lib/comments.ts` byte-for-byte; the comment tracker at the bottom lists open / replied / resolved threads with click-to-jump navigation.
|
|
179
198
|
- **Multi-line `tui-textarea` form** with markdown rendering in the preview pane.
|
|
180
199
|
- **Live updates** via `notify` watcher on `comments.json` and the repo working tree — write a comment in another window and it appears immediately.
|
|
181
|
-
- **Send review & agent handoff** — verdict radios + general-comment popover with a live XML preview.
|
|
200
|
+
- **Send review & agent handoff** — verdict radios + general-comment popover with a live XML preview. `Ctrl-S` persists the review, copies it to the clipboard when available, and immediately wakes every `diffing await-review` waiter. The status bar reports real waiter state.
|
|
201
|
+
- **Headless, token-bounded inspection** — `diffing inspect summary|files|hunks|slice|search` and the equivalent MCP tools page the same index with strict row/byte limits, generation checks, and compact JSON. Every request is loopback-only and requires the session capability.
|
|
182
202
|
- **Cross-platform** — macOS, Linux, and Windows are all first-class. The TUI liveness probe uses `kill(pid, 0)` on Unix and `tasklist /NH /FO CSV` on Windows. Clipboard works on Wayland (`wl-copy`), X11 (`xclip` / `xsel`), macOS (`pbcopy`), and Windows (`clip.exe` / PowerShell `Set-Clipboard`).
|
|
183
203
|
|
|
184
|
-
|
|
204
|
+
The synthetic one-million-line benchmark (50.8 MiB patch) currently reaches a usable partial snapshot in under 1 ms, completes indexing in 47–152 ms, serves viewport reads at 30 µs p95, and peaks at about 54 MiB RSS on the development machine. Run it with `DIFFING_BENCH_LINES=1000000 cargo bench -p diffing-core --bench diff_index`; results vary by machine and filesystem cache.
|
|
205
|
+
|
|
206
|
+
Headless examples:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
diffing inspect summary
|
|
210
|
+
diffing inspect files --limit 100
|
|
211
|
+
diffing inspect slice --file 0 --start 0 --max-lines 120 --max-bytes 262144
|
|
212
|
+
diffing inspect search "unsafe" --limit 25
|
|
213
|
+
```
|
|
185
214
|
|
|
186
215
|
**Building the binary locally**
|
|
187
216
|
|
|
@@ -263,22 +292,34 @@ Bidirectional, event-driven sync between the browser UI and connected AI agents
|
|
|
263
292
|
The `diffing` binary acts as a port-agnostic CLI client. It automatically discovers the running server by reading a local repository lockfile:
|
|
264
293
|
|
|
265
294
|
```bash
|
|
266
|
-
|
|
267
|
-
diffing
|
|
268
|
-
diffing
|
|
269
|
-
diffing
|
|
270
|
-
diffing
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
diffing
|
|
274
|
-
diffing
|
|
275
|
-
diffing
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
diffing plan
|
|
279
|
-
diffing plan
|
|
295
|
+
# Code-review handoff
|
|
296
|
+
diffing await-review # Block until "Send to agent"; print comments as XML
|
|
297
|
+
diffing comments [--open] [--format xml|json|md]
|
|
298
|
+
diffing reply <id> --body "..." # Post an agent response
|
|
299
|
+
diffing resolve <id> # Mark resolved (UI updates live)
|
|
300
|
+
diffing unresolve <id> # Re-open a resolved thread
|
|
301
|
+
diffing comment edit <id> --body "..."
|
|
302
|
+
diffing comment delete <id>
|
|
303
|
+
diffing progress --message "…" [--pct 40] [--model M] # Live progress toast
|
|
304
|
+
diffing url # Active server base URL
|
|
305
|
+
|
|
306
|
+
# Plan review (before any code is written)
|
|
307
|
+
diffing plan submit <file> [--title T] [--model M] [--id <id>] [--wait] [--save-source]
|
|
308
|
+
diffing plan await [--timeout N]
|
|
309
|
+
diffing plan list [--json]
|
|
310
|
+
diffing plan show [<id>] [--json] [--version N]
|
|
311
|
+
diffing plan versions <id> [--json]
|
|
312
|
+
diffing plan reply <commentId> --body "..."
|
|
313
|
+
diffing plan resolve <commentId>
|
|
314
|
+
|
|
315
|
+
# DX
|
|
316
|
+
diffing doctor # Environment / install self-check
|
|
317
|
+
diffing completion <bash|zsh|fish>
|
|
318
|
+
diffing inspect summary|files|hunks|slice|search # Bounded reads from a TUI session
|
|
280
319
|
```
|
|
281
320
|
|
|
321
|
+
Full contracts (flags, exit codes, XML, HTTP): **[docs/cli.md](docs/cli.md)**.
|
|
322
|
+
|
|
282
323
|
### B. Model Context Protocol (MCP) Server
|
|
283
324
|
If your agent supports MCP, configure `diffing` as a stdio server. The MCP is
|
|
284
325
|
self-describing and can start or reuse the loopback review server, so an
|
|
@@ -313,9 +354,13 @@ Run `diffing mcp --help` for setup details. The server initialization
|
|
|
313
354
|
instructions tell an unfamiliar model what to do next, and every tool returns
|
|
314
355
|
both readable text and structured content.
|
|
315
356
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
357
|
+
| Area | Tools |
|
|
358
|
+
|------|-------|
|
|
359
|
+
| Session | `review_session_status`, `start_review_session` |
|
|
360
|
+
| Diff inspection | `get_diff`, `diff_summary`, `diff_files`, `diff_hunks`, `diff_slice`, `diff_search` |
|
|
361
|
+
| Comments | `create_comment`, `list_comments`, `reply_to_comment`, `resolve_comment`, `unresolve_comment`, `edit_comment`, `delete_comment`, `edit_reply`, `delete_reply`, `apply_suggestion`, `resolve_all_comments` |
|
|
362
|
+
| Loop | `await_review`, `report_progress`, `get_review_history` |
|
|
363
|
+
| Plan | `submit_plan`, `await_plan_review`, `list_plans`, `get_plan`, `get_plan_versions`, `get_plan_version`, `reply_to_plan_comment`, `resolve_plan_comment` |
|
|
319
364
|
|
|
320
365
|
Clients that expose MCP prompts can use `review_local_changes` and
|
|
321
366
|
`submit_plan_for_review`; clients that expose resources can read
|
|
@@ -340,7 +385,11 @@ still interpret pasted self-describing XML. The installable `skills/` copies and
|
|
|
340
385
|
repo-local `.agents/skills/` copies are contract-tested to remain identical.
|
|
341
386
|
|
|
342
387
|
### Send Review Popover
|
|
343
|
-
A GitHub-style
|
|
388
|
+
A GitHub-style **Submit review** / **Send to agent** popover: pick a verdict
|
|
389
|
+
(Approve / Request edits / Reject / **Comment only**), optionally add an overall
|
|
390
|
+
note, preview every inline comment (editable/removable), and release every
|
|
391
|
+
waiting agent. Agent waiting state shows as a green dot on the button.
|
|
392
|
+
**Copy comments** serializes the thread set to the agent XML spec.
|
|
344
393
|
|
|
345
394
|
### Port-Agnostic Discovery
|
|
346
395
|
A per-repo lockfile (`server.json`) in `~/.diffing/<repo-hash>/` enables all subcommands and MCP tools to discover the server's port with zero configuration. Stale or crashed server locks are automatically detected and treated as dead via `process.kill(pid, 0)`.
|
|
@@ -355,39 +404,30 @@ A `ReviewSession` class with a monotonic `round` counter and race-guard logic en
|
|
|
355
404
|
Review **any agent plan** — not just code. When an AI agent produces a plan
|
|
356
405
|
(an implementation outline, a design proposal, a migration strategy), `diffing`
|
|
357
406
|
renders the markdown line-by-line so you can comment on specific lines or
|
|
358
|
-
sections and **approve**, **request changes**,
|
|
359
|
-
structured verdict back to the waiting agent. It's the
|
|
360
|
-
releases" handoff, applied *before* any code is written.
|
|
407
|
+
sections and **approve**, **request changes**, **reject**, or **comment only**
|
|
408
|
+
— then hands the structured verdict back to the waiting agent. It's the
|
|
409
|
+
"agent waits, human releases" handoff, applied *before* any code is written.
|
|
361
410
|
|
|
362
411
|
```text
|
|
363
412
|
1. The agent submits a markdown plan and blocks (diffing plan submit … --wait).
|
|
364
|
-
2. You open
|
|
365
|
-
3. You
|
|
366
|
-
4. The agent wakes
|
|
367
|
-
and proceeds, revises-and-resubmits, or stops accordingly.
|
|
413
|
+
2. You open Plans (/plan), read Source / Read / Split, and comment on lines/sections.
|
|
414
|
+
3. You Submit review: Approve / Request changes / Reject / Comment only.
|
|
415
|
+
4. The agent wakes, receives <plan-review> XML, and proceeds, revises, or stops.
|
|
368
416
|
```
|
|
369
417
|
|
|
370
|
-
- **
|
|
371
|
-
|
|
372
|
-
- **
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
- **
|
|
376
|
-
- **
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- **Browse plan versions** —
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
Available from the CLI (`diffing plan versions <id>`, `diffing plan show <id> --version N`),
|
|
384
|
-
MCP (`get_plan_versions`, `get_plan_version`), and the HTTP API
|
|
385
|
-
(`GET /api/plans/:id/versions`, `GET /api/plans/:id/versions/:n`).
|
|
386
|
-
- **Live "Plans" badge** — the diff toolbar shows a badge counting plans awaiting
|
|
387
|
-
your review, with a green dot when an agent is connected and waiting.
|
|
388
|
-
- **Same channels everywhere** — drive it from the CLI (`diffing plan …`), the
|
|
389
|
-
MCP tools (`submit_plan`, `await_plan_review`, …), or the HTTP API
|
|
390
|
-
(`POST /api/plans`, `POST /api/plans/:id/decision`, `GET /api/plan-review/await`).
|
|
418
|
+
- **Source / Read / Split** — always-visible view modes in the plan toolbar (`m` cycles). Read uses full main-column width; **Zen** (`z`) immersive full-width focus (Esc exits).
|
|
419
|
+
- **Live plan edit** — `e` / pencil edits markdown + title on the current version with a Source editor and live Read preview. **Autosave** (`PUT /api/plans/:id`, no version bump); **⌘S** to flush; **Save as new version** (`POST` same id, version bump + decision pending). **Discard** (Esc) restores this session and/or rolls back to the pre-edit original across exit/re-enter. New comments are paused while editing.
|
|
420
|
+
- **Resizable split** — drag the Source|Read divider; double-click resets 50/50. Edit mode uses independent pane scroll so the caret stays put.
|
|
421
|
+
- **Renders any markdown plan** — Source via `@pierre/diffs` when viewing (commentable lines); Read as polished markdown with outline (`o`) and comments map (`c`).
|
|
422
|
+
- **Line, range & section comments** — gutter `+` or select lines (Source); highlight text → Add comment in Read (multiple floating drafts, range steppers, minimize tray, Esc). **Read mode always shows submitted threads inline** under the matching section.
|
|
423
|
+
- **Severity** — optional blocking / nit / question / praise on plan comments (same labels as code review; included in `<plan-review>` handoff XML).
|
|
424
|
+
- **Collapsible threads** — collapse open or resolved cards; collapse the in-card source preview; delete resolved comments and replies.
|
|
425
|
+
- **General comments** — notes scoped to the whole plan.
|
|
426
|
+
- **Four-way verdict** — Approve / Request changes / Reject / Comment only (no file edits). Resubmit with the same id bumps version and re-opens review.
|
|
427
|
+
- **Browse plan versions** — version dropdown, historical banner, comments filtered to the viewed version. CLI / MCP / HTTP as below.
|
|
428
|
+
- **Live "Plans" badge** — toolbar badge for plans awaiting review; green dot when an agent is waiting.
|
|
429
|
+
- **Same channels everywhere** — CLI (`diffing plan …`), MCP (`submit_plan`, `await_plan_review`, …), HTTP (`POST /api/plans`, `PUT /api/plans/:id` for in-page edit, `POST /api/plans/:id/decision`, `GET /api/plan-review/await`).
|
|
430
|
+
- **Scratch outside the tree** — plan sources under `~/.diffing/<repo>/plan-sources/` (`--save-source`); never commit agent plans into the consumer project.
|
|
391
431
|
|
|
392
432
|
### Plan Review XML Specification
|
|
393
433
|
|
|
@@ -404,7 +444,7 @@ self-documenting `<plan-review>` envelope:
|
|
|
404
444
|
## Phase 1
|
|
405
445
|
…full markdown of the plan being reviewed…]]></plan-body>
|
|
406
446
|
<comments>
|
|
407
|
-
<comment id="c1" line="4" section="Phase 1" status="open" created-at="2026-05-29T18:52:29.557Z">
|
|
447
|
+
<comment id="c1" line="4" section="Phase 1" status="open" severity="blocking" created-at="2026-05-29T18:52:29.557Z">
|
|
408
448
|
<context><![CDATA[Do the first thing]]></context>
|
|
409
449
|
<body><![CDATA[Clarify what "the first thing" is.]]></body>
|
|
410
450
|
<replies>
|
|
@@ -416,8 +456,6 @@ self-documenting `<plan-review>` envelope:
|
|
|
416
456
|
</plan-review>
|
|
417
457
|
```
|
|
418
458
|
|
|
419
|
-
<img width="1667" height="1087" alt="image" src="https://github.com/user-attachments/assets/00e884b5-4c90-4a9a-9e24-9ae57d80f3f2" />
|
|
420
|
-
|
|
421
459
|
---
|
|
422
460
|
|
|
423
461
|
## Reviewing a GitHub PR
|
|
@@ -498,13 +536,16 @@ coexist without colliding.
|
|
|
498
536
|
|
|
499
537
|
Rich, real-time comment threads directly on diff lines:
|
|
500
538
|
|
|
501
|
-
- **Inline Threads** — Hover
|
|
502
|
-
- **Multi-Line Comments** —
|
|
503
|
-
- **
|
|
504
|
-
- **
|
|
505
|
-
- **
|
|
506
|
-
- **
|
|
507
|
-
- **
|
|
539
|
+
- **Inline Threads** — Hover the gutter `+` or select lines to open a composer **on that line/side** (additions and deletions). Markdown (GFM + breaks) with syntax-highlighted fences. Threads are collapsible.
|
|
540
|
+
- **Multi-Line Comments** — Drag a line range; the form anchors under the bottom line, with a clear `L12–L15 · new|old` label and **range steppers**. Reverse selection is normalized; range is **inclusive** on the agent handoff (`line="12-15"`).
|
|
541
|
+
- **Severity** — Optional triage labels (design-system dropdown): blocking / nit / question / praise. Stored and emitted on agent handoff XML; MCP `create_comment` accepts `severity`.
|
|
542
|
+
- **File-Level Comments** — Notes scoped to the entire file.
|
|
543
|
+
- **Comment Drafts** — Server-side drafts with TTL under `~/.diffing/` (no browser storage).
|
|
544
|
+
- **Agent Attribution** — Replies carry `role` (`user`/`agent`) and `model`.
|
|
545
|
+
- **Suggestion Application** — `` ```suggestion `` blocks (including multi-line) via **Apply suggestion** / `POST /api/comments/:id/apply-suggestion`.
|
|
546
|
+
- **Bulk resolve** — Toolbar **Resolve all** → `POST /api/comments/resolve-all`.
|
|
547
|
+
- **Agent progress** — Agents can `diffing progress` / `report_progress` for a live toast while working.
|
|
548
|
+
- **Full CRUD** — Create, edit, delete (including resolved plan threads), reply, unresolve — CLI, MCP, and HTTP.
|
|
508
549
|
|
|
509
550
|
---
|
|
510
551
|
|
|
@@ -632,8 +673,10 @@ When review comments are exported or streamed to a waiting agent, they are seria
|
|
|
632
673
|
You are an AI coding assistant receiving a structured list of code review comments to address.
|
|
633
674
|
For each file, review the inline comments and apply the changes requested.
|
|
634
675
|
- Target lines are specified by the "line" attribute (e.g. line="42" for single lines, line="42-45" for multi-line blocks, or line="file" for file-level notes).
|
|
676
|
+
- When line="A-B", the range is INCLUSIVE on that side.
|
|
635
677
|
- "side" indicates whether the comment is on "additions" (new code) or "deletions" (old code).
|
|
636
678
|
- "status" indicates whether the comment is "open" or "resolved". Only address "open" comments.
|
|
679
|
+
- Optional severity="blocking|nit|question|praise": blocking = must fix; nit = optional polish; question = needs an answer; praise = positive (no change required). Omit (or none) = untriaged.
|
|
637
680
|
- The <code> block contains the code context at the reviewed lines.
|
|
638
681
|
- The <body> tag contains the review feedback or request.
|
|
639
682
|
|
|
@@ -650,7 +693,7 @@ When review comments are exported or streamed to a waiting agent, they are seria
|
|
|
650
693
|
|
|
651
694
|
<file path="src/utils/parser.ts">
|
|
652
695
|
<!-- [Example A] Multi-Line Selection Addition Comment -->
|
|
653
|
-
<comment id="c1" line="42-45" side="additions" status="open" created-at="2026-05-24T22:00:00.000Z">
|
|
696
|
+
<comment id="c1" line="42-45" side="additions" status="open" severity="blocking" created-at="2026-05-24T22:00:00.000Z">
|
|
654
697
|
<code><![CDATA[
|
|
655
698
|
+ const parsedToken = tokenize(input);
|
|
656
699
|
+ if (parsedToken.type === 'EOF') {
|
|
@@ -666,7 +709,7 @@ When review comments are exported or streamed to a waiting agent, they are seria
|
|
|
666
709
|
</comment>
|
|
667
710
|
|
|
668
711
|
<!-- [Example B] Whole-File General Comment -->
|
|
669
|
-
<comment id="c2" line="file" side="additions" status="open" created-at="2026-05-24T22:08:00.000Z">
|
|
712
|
+
<comment id="c2" line="file" side="additions" status="open" severity="nit" created-at="2026-05-24T22:08:00.000Z">
|
|
670
713
|
<body><![CDATA[This parser module needs additional unit tests to cover negative bounds.]]></body>
|
|
671
714
|
</comment>
|
|
672
715
|
</file>
|
|
@@ -692,22 +735,19 @@ For advanced features, internal API endpoints, sequence specifications, and conf
|
|
|
692
735
|
|
|
693
736
|
> [!IMPORTANT]
|
|
694
737
|
> Read the [CLI & Protocol Reference Manual](docs/cli.md) for detailed descriptions of:
|
|
695
|
-
> - TTY
|
|
696
|
-
> -
|
|
697
|
-
> -
|
|
698
|
-
> -
|
|
699
|
-
> -
|
|
738
|
+
> - TTY auto-detection and output modes (web / terminal / TUI).
|
|
739
|
+
> - Port-agnostic discovery lockfile (`server.json`) and modes (`web` | `tui` | `gh-pr`).
|
|
740
|
+
> - Full agent CLI surface: `await-review`, `comments`, `reply` / `resolve` / `unresolve`, `comment edit|delete`, `progress`, `plan …`, `gh …`, `inspect`, `doctor`, `completion`, `mcp`.
|
|
741
|
+
> - Complete MCP tool table (session, bounded diff, comment lifecycle, progress, plan).
|
|
742
|
+
> - Monotonic `round` handoff, plan-review XML, and comment XML schemas.
|
|
743
|
+
> - Web API endpoints (`/api/review/await`, `/api/comments`, `/api/plans`, `/api/agent/progress`, …).
|
|
744
|
+
> - Agent guidance: root [`Agents.md`](Agents.md) and installable skills under `skills/`.
|
|
700
745
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
## Landing Page
|
|
746
|
+
Changelog for the latest release: [`CHANGELOG.md`](CHANGELOG.md).
|
|
704
747
|
|
|
705
|
-
<img width="1287" height="6579" alt="screencapture-localhost-3000-2026-05-31-20_57_04" src="https://github.com/user-attachments/assets/a163b00e-a85a-428f-b8d5-2a33ff9fa1eb" />
|
|
706
748
|
|
|
707
749
|
---
|
|
708
750
|
|
|
709
|
-
👉🏻 The project was intially forked from **wong2/diffx**
|
|
710
|
-
|
|
711
751
|
## License
|
|
712
752
|
|
|
713
753
|
MIT
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/lib/apply-suggestion.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extract the first ```suggestion ... ``` fence body from a comment.
|
|
4
|
+
* Returns null when no fence is present.
|
|
5
|
+
*/
|
|
6
|
+
function extractSuggestionBlock(body) {
|
|
7
|
+
const match = body.match(/```suggestion\r?\n([\s\S]*?)```/);
|
|
8
|
+
if (!match) return null;
|
|
9
|
+
return match[1];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Apply a suggestion fence to file content.
|
|
13
|
+
*
|
|
14
|
+
* - Single-line comments replace one line.
|
|
15
|
+
* - Multi-line comments (startLineNumber..lineNumber) replace that span with
|
|
16
|
+
* the suggestion lines (which may be shorter or longer than the span).
|
|
17
|
+
* - Suggestion content is split on any common newline style.
|
|
18
|
+
*/
|
|
19
|
+
function applySuggestionToContent(input) {
|
|
20
|
+
if (input.side !== "additions") return {
|
|
21
|
+
ok: false,
|
|
22
|
+
error: "Suggestions can only be applied to added or modified lines"
|
|
23
|
+
};
|
|
24
|
+
const suggestion = extractSuggestionBlock(input.body);
|
|
25
|
+
if (suggestion === null) return {
|
|
26
|
+
ok: false,
|
|
27
|
+
error: "No suggestion block found in comment body"
|
|
28
|
+
};
|
|
29
|
+
const useCrlf = input.content.includes("\r\n");
|
|
30
|
+
const lines = input.content.split(/\r?\n/);
|
|
31
|
+
const end = input.lineNumber;
|
|
32
|
+
const start = input.startLineNumber && input.startLineNumber > 0 && input.startLineNumber < end ? input.startLineNumber : end;
|
|
33
|
+
if (start < 1 || end < 1) return {
|
|
34
|
+
ok: false,
|
|
35
|
+
error: "Comment line number out of range"
|
|
36
|
+
};
|
|
37
|
+
if (end > lines.length) return {
|
|
38
|
+
ok: false,
|
|
39
|
+
error: "Comment line number out of range"
|
|
40
|
+
};
|
|
41
|
+
const startIdx = start - 1;
|
|
42
|
+
const deleteCount = end - start + 1;
|
|
43
|
+
let suggestionLines = suggestion.split(/\r?\n/);
|
|
44
|
+
if (suggestionLines.length > 1 && suggestionLines[suggestionLines.length - 1] === "") suggestionLines = suggestionLines.slice(0, -1);
|
|
45
|
+
const next = [...lines];
|
|
46
|
+
next.splice(startIdx, deleteCount, ...suggestionLines);
|
|
47
|
+
return {
|
|
48
|
+
ok: true,
|
|
49
|
+
content: next.join(useCrlf ? "\r\n" : "\n"),
|
|
50
|
+
replacedLines: deleteCount
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { applySuggestionToContent };
|