diffing 0.11.0 → 0.13.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 +56 -801
- package/dist/{cli-agent-DkwGxuy2.mjs → cli-agent-Cx2k0Ki7.mjs} +236 -59
- package/dist/{cli-gh-D0NfKpOp.mjs → cli-gh-BQuQpV-s.mjs} +24 -14
- package/dist/cli.mjs +69 -26
- package/dist/client/assets/{angular-html-Dl53kkiy.js → angular-html-gcUdctE_.js} +1 -1
- package/dist/client/assets/{angular-ts-wNJFFkey.js → angular-ts-BkjLgJJH.js} +1 -1
- package/dist/client/assets/{apl-BxtQST-h.js → apl-BtuEza96.js} +1 -1
- package/dist/client/assets/{arc-CBmZuzPB.js → arc-yk_3cjs2.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-CEci_K9f.js → architectureDiagram-3BPJPVTR-DDVXPdzY.js} +1 -1
- package/dist/client/assets/{astro-BpADD5rh.js → astro-DfUNgEjV.js} +1 -1
- package/dist/client/assets/{blade-B4I5SQmP.js → blade-uv3PNTww.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-DcKhDtnE.js → blockDiagram-GPEHLZMM-DlMLqbfD.js} +1 -1
- package/dist/client/assets/{c-C3VtOgg8.js → c-DcsMh0kd.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CaHozoxF.js → c4Diagram-AAUBKEIU-C4ZZJAMJ.js} +1 -1
- package/dist/client/assets/channel-CPOnEOhs.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-tvuzKhdK.js → chunk-2J33WTMH-CwkSvLT8.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-D_nBoD9w.js → chunk-3OPIFGDE-s6UH12Df.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-yHPdy1G8.js → chunk-4BX2VUAB-wGjYymx_.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-yXpL8wjV.js → chunk-55IACEB6-DObbP11Q.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-DZ5cvCDV.js → chunk-5ZQYHXKU-DwbkzQEJ.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CJjgOWmY.js → chunk-727SXJPM-DzoJfly4.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CQYQKXSE.js → chunk-AQP2D5EJ-f1kNxYS3.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CP_f908b.js → chunk-BSJP7CBP-CTBkVJEp.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-tcgA8jR0.js → chunk-CSCIHK7Q-C6dvEyPX.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DlpmhBYg.js → chunk-FMBD7UC4-C166WZ7L.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BkfieXpV.js → chunk-KSCS5N6A-CaVyQHxA.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-BjVXSZnt.js → chunk-L5ZTLDWV-CdW7usF5.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CaAWmy4Q.js → chunk-LZXEDZCA-imRCFVGq.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-kWh41zUn.js → chunk-ND2GUHAM-BJCVPOgO.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-CDrIi44_.js → chunk-NZK2D7GU-DodLkks9.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-CbNGK3Te.js → chunk-O5CBEL6O-DYxYE_dt.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-7sNTyEOs.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-DluN2oZF.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-Cca0fTtG.js → chunk-XPW4576I-DkPXlA-y.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CHofrzZI.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B8fKe5FS.js +1 -0
- package/dist/client/assets/{cobol-j-6eG2UQ.js → cobol-B5tSUxVN.js} +1 -1
- package/dist/client/assets/{coffee-CZLH0dtt.js → coffee-B2Q8w4Zu.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DlxESVex.js → cose-bilkent-S5V4N54A-Bg2tspSU.js} +1 -1
- package/dist/client/assets/{cpp-j6Bp24RI.js → cpp-CfzAEc1z.js} +1 -1
- package/dist/client/assets/{crystal-DW7wcFUs.js → crystal-BDxAjW7-.js} +1 -1
- package/dist/client/assets/{css-C43BDU2i.js → css-nC3_RAjk.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-BaemEJFh.js → dagre-BM42HDAG-BZiNHe27.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BaM-bkJ3.js → diagram-2AECGRRQ-D3Vd2itQ.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BOH04DJO.js → diagram-5GNKFQAL-D44Rm6ep.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BP5MyqDZ.js → diagram-KO2AKTUF-DwoQejb5.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-Dt4gKMYF.js → diagram-LMA3HP47-C1eaDL4X.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-DoT1VshN.js → diagram-OG6HWLK6-BtBJHHnj.js} +1 -1
- package/dist/client/assets/{dist-DEAxvC4F.js → dist-DUBmiUQf.js} +1 -1
- package/dist/client/assets/{edge-D9ySFlnD.js → edge-WCfPDabs.js} +1 -1
- package/dist/client/assets/{elixir-CoJz_LQ5.js → elixir-CazmTZo9.js} +1 -1
- package/dist/client/assets/{elm-CvedWh_e.js → elm-CTqaOirp.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CMP78FsQ.js → erDiagram-TEJ5UH35-CqjpbNDt.js} +1 -1
- package/dist/client/assets/{erb-lD_yYZsm.js → erb-CK9x36t2.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-Dp0s5BFj.js → flowDiagram-I6XJVG4X-CSHJZmlA.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-GmSG31U-.js → ganttDiagram-6RSMTGT7-D6KxkDpI.js} +1 -1
- package/dist/client/assets/{git-rebase-DwZABzof.js → git-rebase-Bn8xQDxV.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C1SXShag.js → gitGraphDiagram-PVQCEYII-ZGSlrHF5.js} +1 -1
- package/dist/client/assets/{glimmer-js-CWcs3w1Z.js → glimmer-js-h7wFfOLo.js} +1 -1
- package/dist/client/assets/{glimmer-ts-CrzGN4lJ.js → glimmer-ts-vlZuiamP.js} +1 -1
- package/dist/client/assets/{glsl-DRCtwX7h.js → glsl-CNutENPV.js} +1 -1
- package/dist/client/assets/{graphql-rpmrismS.js → graphql-BfddKr9j.js} +1 -1
- package/dist/client/assets/{hack-Ba02RnuQ.js → hack-BkYH75Gx.js} +1 -1
- package/dist/client/assets/{haml-BHBACStm.js → haml-CM-xW5RI.js} +1 -1
- package/dist/client/assets/{handlebars-BtlQ1SCa.js → handlebars-CklcCbzf.js} +1 -1
- package/dist/client/assets/{html-BkVU3Dge.js → html-bltTcC3c.js} +1 -1
- package/dist/client/assets/{html-derivative-DoK92vwi.js → html-derivative-C4R1a7Nf.js} +1 -1
- package/dist/client/assets/{http-CJAwKSPH.js → http-B6uXoDkp.js} +1 -1
- package/dist/client/assets/{hurl-kaX5jwuN.js → hurl-gquKVFPU.js} +1 -1
- package/dist/client/assets/{index-D8hOoJCg.css → index-BsuX6HVI.css} +1 -1
- package/dist/client/assets/{index-BHeNiC07.js → index-yhKiqbkK.js} +154 -154
- package/dist/client/assets/{infoDiagram-5YYISTIA-B0i3BlNR.js → infoDiagram-5YYISTIA-DCQv5BKv.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BN8sEei4.js → ishikawaDiagram-YF4QCWOH-BqXC35qz.js} +1 -1
- package/dist/client/assets/{java-BvrigIoq.js → java-DZLUJ7qo.js} +1 -1
- package/dist/client/assets/{javascript-DZkPTYAi.js → javascript-CayXc7uP.js} +1 -1
- package/dist/client/assets/{jinja-Ceg7ui1S.js → jinja-CQQUTC0y.js} +1 -1
- package/dist/client/assets/{jison-iE1GaOyN.js → jison-CvzuCn2x.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CE6O3NhU.js → journeyDiagram-JHISSGLW-bRlSO5Sv.js} +1 -1
- package/dist/client/assets/{json-C0j8rEcg.js → json-BsMA0GaP.js} +1 -1
- package/dist/client/assets/{jsx-B7eXljgz.js → jsx-Dbxr4aPH.js} +1 -1
- package/dist/client/assets/{julia-DMDw0aMP.js → julia-CZ38GzHV.js} +1 -1
- package/dist/client/assets/{just-BryMKRJ_.js → just-BQwFLV1D.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-j-aU6Yzp.js → kanban-definition-UN3LZRKU-BVjoqA0y.js} +1 -1
- package/dist/client/assets/{latex-BNC9-sjr.js → latex-BGyrMdgQ.js} +1 -1
- package/dist/client/assets/{line-CyEqpEDp.js → line-DacHFvZH.js} +1 -1
- package/dist/client/assets/{linear-CXeaA9km.js → linear-BPGHNTSb.js} +1 -1
- package/dist/client/assets/{liquid-D-fQw-oJ.js → liquid-CiA2vjOH.js} +1 -1
- package/dist/client/assets/{lua-CD2aJ_rS.js → lua-D9k3fxwM.js} +1 -1
- package/dist/client/assets/{marko-BQ37hu6z.js → marko-CwBH4-2T.js} +1 -1
- package/dist/client/assets/{mdc-B5NUi3zZ.js → mdc-D4WuuVvw.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BxHF_XbX.js → mermaid-parser.core-DuXqm2Gp.js} +1 -1
- package/dist/client/assets/{mermaid.core-BUtaf4P1.js → mermaid.core-DRh_KVT1.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-D13tPu2o.js → mindmap-definition-RKZ34NQL-C5wytjbD.js} +1 -1
- package/dist/client/assets/{nginx-1W1E03Rg.js → nginx-DHMa03ia.js} +1 -1
- package/dist/client/assets/{nim-C5A88bFP.js → nim-8gK3mQXD.js} +1 -1
- package/dist/client/assets/{perl-BYoP0wNt.js → perl-DqXBmOB_.js} +1 -1
- package/dist/client/assets/{php-CFxna09e.js → php-CruAnpl2.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-CHL7Ml5w.js → pieDiagram-4H26LBE5-Cv2Csp1M.js} +1 -1
- package/dist/client/assets/{pug-BR4JgWAk.js → pug-C7a5y4Mi.js} +1 -1
- package/dist/client/assets/{qml-D1U1EFEe.js → qml-mgWY__NW.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-BnYtv-HY.js → quadrantDiagram-W4KKPZXB-DHQIHzFU.js} +1 -1
- package/dist/client/assets/{r-ChE6X060.js → r-Do5QoKdS.js} +1 -1
- package/dist/client/assets/{razor-B5iVfQMe.js → razor-BqdDbm9d.js} +1 -1
- package/dist/client/assets/{regexp-Dz2drUIf.js → regexp-CNMlPqVr.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-D8QEGLKB.js → requirementDiagram-4Y6WPE33-rUeJykKo.js} +1 -1
- package/dist/client/assets/{review-export-CvFFbCAB.js → review-export-BgwyN8Ky.js} +1 -1
- package/dist/client/assets/{rst-DZM3RGRs.js → rst-PYCtADQ2.js} +1 -1
- package/dist/client/assets/{ruby-DkXnm-J8.js → ruby-B8JdoeHE.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-wVaks6lB.js → sankeyDiagram-5OEKKPKP-Bsga6dQU.js} +1 -1
- package/dist/client/assets/{sas-DMbpc71c.js → sas-kIev4j3d.js} +1 -1
- package/dist/client/assets/{scss-IwVMMp22.js → scss-cf-rl7q3.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Cg31TB-R.js → sequenceDiagram-3UESZ5HK-BVcwcOB2.js} +1 -1
- package/dist/client/assets/{shellscript-CIStAKx3.js → shellscript-BHMFbkaV.js} +1 -1
- package/dist/client/assets/{shellsession-uLtzHhlo.js → shellsession-y_3kBnoK.js} +1 -1
- package/dist/client/assets/{soy-BkxBYigm.js → soy-Coc7dfRW.js} +1 -1
- package/dist/client/assets/{sql-Ba9y9EvJ.js → sql-CsZYO19m.js} +1 -1
- package/dist/client/assets/{src-9MKexpFu.js → src-ujohT29p.js} +1 -1
- package/dist/client/assets/{stata-CrPCbiIZ.js → stata-BFa4m_Eh.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-BbvNjVF6.js → stateDiagram-AJRCARHV-DBElJIPe.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BocZ498b.js +1 -0
- package/dist/client/assets/{surrealql-Dvip5u_o.js → surrealql-DlwfRFnC.js} +1 -1
- package/dist/client/assets/{svelte-xBLD60Zd.js → svelte-RrLklQOZ.js} +1 -1
- package/dist/client/assets/{templ-CWv68xbP.js → templ-BDbBg7z2.js} +1 -1
- package/dist/client/assets/{tex-CHqz-fYs.js → tex-BeAp-Hqv.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CWKkJ3QZ.js → timeline-definition-PNZ67QCA-Det2OiYV.js} +1 -1
- package/dist/client/assets/{ts-tags-DS82EDuE.js → ts-tags-Dz-1CFmn.js} +1 -1
- package/dist/client/assets/{tsx-B2GBjp2F.js → tsx-Dfi08w8H.js} +1 -1
- package/dist/client/assets/{twig-CC8x9pG0.js → twig-BfzYY6Hd.js} +1 -1
- package/dist/client/assets/{typescript-g7i13lnC.js → typescript-6FNAPG3Z.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-OLItKWeg.js → vennDiagram-CIIHVFJN-DhH4H0vl.js} +1 -1
- package/dist/client/assets/{vue-rFbe7luB.js → vue-DTPedjqE.js} +1 -1
- package/dist/client/assets/{vue-html-D9GQtYub.js → vue-html-B4sC29Oj.js} +1 -1
- package/dist/client/assets/{vue-vine-mrNtQtY5.js → vue-vine-BWzpqJ4r.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Dy1yfeb4.js → wardleyDiagram-YWT4CUSO-BC8K10yP.js} +1 -1
- package/dist/client/assets/{xml-CHfMjyAM.js → xml-BK8ACjht.js} +1 -1
- package/dist/client/assets/{xsl-BFkNSogJ.js → xsl-rjlrbfou.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DfSnfjVL.js → xychartDiagram-2RQKCTM6-DwcVZiB5.js} +1 -1
- package/dist/client/assets/{yaml-BfSgHc04.js → yaml-DM6lgMhS.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/completions-5rtfoxB9.mjs +2 -0
- package/dist/{completions-BO2DUM-8.mjs → completions-7YSX1neu.mjs} +7 -1
- package/dist/{doctor-D0Y3kOY7.mjs → doctor-BMfx7_GY.mjs} +16 -14
- package/dist/doctor-BRr5IWHe.mjs +2 -0
- package/dist/{find-tui-binary-B71xiwWu.mjs → find-tui-binary-DGspwyvd.mjs} +56 -25
- package/dist/{git-Czo96ymM.mjs → git-BGj31GX-.mjs} +71 -7
- package/dist/git-CfDSkUcE.mjs +2 -0
- package/dist/{github-CErBub2y.mjs → github-BLrnsozP.mjs} +1 -1
- package/dist/{github-DBsZ0h_l.mjs → github-DbAFoB92.mjs} +3 -3
- package/dist/{github-attachments-plDeB0iE.mjs → github-attachments-fNCKYL-Z.mjs} +2 -2
- package/dist/{mcp-DtVrMR2S.mjs → mcp-Bi551clR.mjs} +33 -30
- package/dist/native/tui-darwin-arm64/diffing-tui +0 -0
- package/dist/native/tui-darwin-x64/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-musl/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-musl/diffing-tui +0 -0
- package/dist/native/tui-win32-x64-msvc/diffing-tui.exe +0 -0
- package/dist/{search-BMPY_ZW8.mjs → search-3R2E5xxr.mjs} +16 -1
- package/dist/{search-BO9Im7eu.mjs → search-CQ4nsjBX.mjs} +1 -1
- package/dist/{server-j0PnTVX1.mjs → server-B9NVZu7l.mjs} +174 -46
- package/dist/{server-lock-CY0_1mcS.mjs → server-lock-BNI8FKV1.mjs} +175 -23
- package/dist/{session-conflict-C6V9ZKo7.mjs → session-conflict-CB0IErdn.mjs} +8 -7
- package/dist/{session-manager-CYNchhVA.mjs → session-manager-656aJXFE.mjs} +2 -2
- package/dist/session-url-B8TrGGeE.mjs +33 -0
- package/dist/{settings-yK0GYpbn.mjs → settings-DkPDB_hS.mjs} +32 -4
- package/dist/setup-BiwX7vdd.mjs +446 -0
- package/dist/setup-first-run-DyT0PlOZ.mjs +2 -0
- package/dist/setup-first-run-i1o7DBki.mjs +74 -0
- package/dist/terminal-BroplOnw.mjs +116 -0
- package/dist/{tui-search-bridge-Bfb2ktdA.mjs → tui-search-bridge-fFKqX4Fi.mjs} +3 -3
- package/dist/{update-check-Copcz9eb.mjs → update-check-ISaw61qS.mjs} +16 -15
- package/package.json +11 -3
- package/scripts/postinstall.mjs +52 -0
- package/dist/client/assets/channel-Ct4-oSQN.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-BXhKFVX7.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-_EwuC51_.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-C8bdx9R4.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B26wrQuH.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-B5BbZkU5.js +0 -1
- package/dist/git-DaP_1rVy.mjs +0 -2
- /package/dist/{apply-suggestion-CHYnw68I.mjs → apply-suggestion-BsR_8FXW.mjs} +0 -0
- /package/dist/{diff-fingerprint-BgR0tu1o.mjs → diff-fingerprint-BL5jNHnP.mjs} +0 -0
- /package/dist/{handoff-LAFtmnHf.mjs → handoff-DcShCxWJ.mjs} +0 -0
- /package/dist/{review-export-B63eRAVa.mjs → review-export-GW4KNsGN.mjs} +0 -0
package/README.md
CHANGED
|
@@ -4,847 +4,102 @@
|
|
|
4
4
|
<img src="public/favicon.svg" alt="diffing brand icon" width="72" height="72" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Local-first CLI for reviewing git diffs with humans and AI agents.**
|
|
8
8
|
|
|
9
|
-
|
|
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" />
|
|
9
|
+
Open your changes in a GitHub-like web UI (or an experimental native TUI), leave inline comments, hand them to your coding agent over CLI/MCP, and review **implementation plans** the same way before any code is written. Everything binds to loopback by default — no account, no cloud.
|
|
13
10
|
|
|
11
|
+
**npm:** [npmjs.com/package/diffing](https://www.npmjs.com/package/diffing) · **Docs:** [ahmedragab20.github.io/diffing](https://ahmedragab20.github.io/diffing/) · **Agents:** [llms.txt](https://ahmedragab20.github.io/diffing/llms.txt)
|
|
14
12
|
|
|
15
13
|
---
|
|
16
14
|
|
|
17
|
-
## Quick
|
|
15
|
+
## Quick start
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
Install `diffing` globally via npm:
|
|
21
|
-
```bash
|
|
22
|
-
npm install -g diffing
|
|
23
|
-
```
|
|
17
|
+
**Requirements:** Node.js 20+, `git` on your PATH.
|
|
24
18
|
|
|
25
|
-
### 2. Run
|
|
26
|
-
Launch it within any active git repository:
|
|
27
19
|
```bash
|
|
28
|
-
diffing
|
|
29
|
-
|
|
30
|
-
With the initial web preference, this spins up a local server, establishes an active repository watcher, and opens your default browser to an interactive code review dashboard. Use `diffing mode tui` to make the native review TUI the interactive default instead.
|
|
31
|
-
|
|
32
|
-
Prefer the terminal? The global npm install includes the native binary for the
|
|
33
|
-
current platform. Use `view` for a focused read-only diff browser, or `--tui`
|
|
34
|
-
for the full review flow without a browser:
|
|
20
|
+
npm install -g diffing
|
|
21
|
+
# or: pnpm add -g diffing
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
diffing
|
|
39
|
-
diffing mode tui # Make the full TUI the interactive default
|
|
23
|
+
diffing setup # first-time wizard (skills, MCP, doctor)
|
|
24
|
+
cd your-repo
|
|
25
|
+
diffing # preferred interactive UI (web by default)
|
|
40
26
|
```
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
> The TUI is **experimental**. The interface, keymap, and `server.json`
|
|
44
|
-
> (`mode: "tui"`) on-disk format may change in a minor release. The web UI is
|
|
45
|
-
> the supported path for production workflows. Native executables are
|
|
46
|
-
> installed through optional platform packages, with source builds and
|
|
47
|
-
> separately installed `$PATH` binaries available as fallbacks. See
|
|
48
|
-
> [Native Terminal UI (TUI)](#native-terminal-ui-tui) for the full feature set,
|
|
49
|
-
> keymap, and stability notes.
|
|
28
|
+
Useful variants:
|
|
50
29
|
|
|
51
|
-
### 3. Update
|
|
52
|
-
Check if a new version is available on npm and upgrade instantly via the CLI:
|
|
53
30
|
```bash
|
|
31
|
+
diffing --staged
|
|
32
|
+
diffing main..feature
|
|
33
|
+
diffing view # read-only native diff browser
|
|
34
|
+
diffing --tui # full native review TUI (experimental)
|
|
35
|
+
diffing mode tui # make TUI the interactive default
|
|
54
36
|
diffing update
|
|
55
37
|
```
|
|
56
38
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
## Web UI Review Dashboard
|
|
60
|
-
|
|
61
|
-
A local Hono-powered review server delivers a full-featured GitHub-like code review interface directly in your browser.
|
|
62
|
-
|
|
63
|
-
- **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.
|
|
64
|
-
- **Compact toolbar** — Repo + branch, quiet summary chips (files, `+X/−Y`, open comments), Search (`⌘K`), Plans badge, Resolve all, Settings, and **Send review**.
|
|
65
|
-
- **Syntax Highlighting** — Powered by Shiki via `@pierre/diffs`, with high-fidelity highlighting for 200+ languages.
|
|
66
|
-
- **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.
|
|
67
|
-
- **Icon file-header actions** — Expand context, open in editor, file-level comment, and Viewed — with tooltips; less chrome noise per card.
|
|
68
|
-
- **Status Dashboard (Comment Tracker)** — Bottom panel tracking open, replied, and resolved comments with severity filters and click-to-navigate.
|
|
69
|
-
- **Multi-round review** — Round history popover, “changed since last send” chips, and outdated-comment detection.
|
|
70
|
-
- **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`).
|
|
71
|
-
- **Dynamic Font Customization** — Google Fonts or local system fonts for UI + mono (see [custom fonts](#a-note-on-custom-fonts)).
|
|
72
|
-
- **Resizable Panels** — Drag-to-resize sidebar (240px–640px) and comment tracker (100px–600px); sizes persisted server-side.
|
|
73
|
-
- **Skeleton Loading Screen** — Full shimmer placeholder UI during initial load.
|
|
74
|
-
- **Image Diff Previews** — Side-by-side comparison for common image formats.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Themes
|
|
79
|
-
|
|
80
|
-
42+ built-in themes powered by Shiki, with instant switching and live preview.
|
|
81
|
-
|
|
82
|
-
| Category | Themes |
|
|
83
|
-
|----------|--------|
|
|
84
|
-
| GitHub Family | GitHub Dark, GitHub Light, GitHub Dark Dimmed, GitHub Dark High Contrast |
|
|
85
|
-
| Popular Dark | Dracula, One Dark Pro, Monokai, Synthwave '84, Material Theme (Ocean/Palenight/Darker) |
|
|
86
|
-
| Tokyo Night | Tokyo Night, Tokyo Night Storm, Tokyo Night Light |
|
|
87
|
-
| Catppuccin | Mocha, Frappe, Macchiato, Latte |
|
|
88
|
-
| Nord Family | Nord |
|
|
89
|
-
| Nightfox Family | Nightfox, Nordfox, Duskfox, Terafox, Carbonfox, Dayfox, Dawnfox |
|
|
90
|
-
| Rose Pine | Rose Pine, Rose Pine Dawn, Rose Pine Moon |
|
|
91
|
-
| Solarized | Solarized Dark, Solarized Light |
|
|
92
|
-
| VS Code | Dark+, Light+, Dark Modern, Light Modern |
|
|
93
|
-
| Others | Andromeeda, Aurora X, Houston, Laserwave, Min Dark/Light, Night Owl, One Light, Plastic, Poimandres, Slack (Dark/Ochre), Vesper, Vitesse Dark/Light, Ayu Dark/Light |
|
|
94
|
-
|
|
95
|
-
- **Searchable Theme Modal** — Press `g` `t` or use the toolbar to open a categorized, searchable theme picker with color swatches and live preview.
|
|
96
|
-
- **Dark/Light Dual Mode** — Each theme maps to corresponding dark and light Shiki themes for accurate syntax highlighting in both modes.
|
|
97
|
-
- **Instant Switching** — CSS transitions suppressed during theme changes for a snappy, lag-free experience.
|
|
98
|
-
- **Persistent Setting** — Theme choice saved to `~/.config/diffing/settings.json` and restored on next launch.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/eaa0675c-21d6-4754-8fbd-97ee63a743dc" />
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Rust-Powered Code Search (powered by fff)
|
|
108
|
-
|
|
109
|
-
Blazing-fast, native fuzzy code search integrated directly into the sidebar search palette via `@ff-labs/fff-node`:
|
|
110
|
-
|
|
111
|
-
- **Fuzzy File Search** (`Files` scope) — Error-tolerant fuzzy matching on workspace paths using a native Rust engine.
|
|
112
|
-
- **Codebase Grep** (`Text` scope) — Instant case-insensitive text search with full **Regular Expression** support.
|
|
113
|
-
- **Syntactic Symbol Search** (`Symbols` scope) — Finds function declarations, class headers, type definitions, and variable assignments across JavaScript, TypeScript, Go, Rust, and Python (17+ language patterns).
|
|
114
|
-
- **Unified "All" Search** — Concurrent search across files, text, and symbols with automatic deduplication.
|
|
115
|
-
- **Frecency Ranking** — SQLite-backed history database remembers which files you open for specific queries, floating high-value results to the top.
|
|
116
|
-
- **"Changed Only" Filter** — Restricts search scope exclusively to files changed in the active git diff.
|
|
117
|
-
- **Git Status Chips** — Search results display git status indicators (modified, untracked, added, deleted, renamed).
|
|
118
|
-
- **Graceful Degradation** — If the native Rust binary is unavailable, search reports as unavailable without crashing the server.
|
|
119
|
-
- **Auto-Indexing** — The Rust engine maintains its own file system watcher for real-time index updates as the working tree changes.
|
|
120
|
-
|
|
121
|
-
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/2b2bc001-2d3a-4744-b9d5-a23642f1afba" />
|
|
39
|
+
TTY opens the interactive UI. Pipe or redirect prints a unified patch like `git diff`.
|
|
122
40
|
|
|
123
41
|
---
|
|
124
42
|
|
|
125
|
-
##
|
|
126
|
-
|
|
127
|
-
Full keyboard-driven navigation with vim-like motions and a modal status bar:
|
|
128
|
-
|
|
129
|
-
### Scrolling & Diffs
|
|
130
|
-
| Key | Action |
|
|
131
|
-
|-----|--------|
|
|
132
|
-
| `j` / `k` | Scroll down/up by 100px |
|
|
133
|
-
| `Ctrl+d` / `Ctrl+u` | Scroll half-page down/up |
|
|
134
|
-
| `g` `g` | Jump to top of diff |
|
|
135
|
-
| `G` | Jump to bottom of diff |
|
|
136
|
-
| `m` | Toggle split/unified view (also Settings → Diff style) |
|
|
137
|
-
| `t` | Cycle tab size (2 → 4 → 8) |
|
|
138
|
-
| `w` | Toggle line wrap |
|
|
139
|
-
| `n` | Toggle line numbers |
|
|
140
|
-
| `i` | Cycle diff indicators |
|
|
141
|
-
| `I` | Cycle inline diff type |
|
|
142
|
-
| `Cmd+Shift+P` | Toggle preview mode in comments |
|
|
143
|
-
|
|
144
|
-
### File Navigation & UI
|
|
145
|
-
| Key | Action |
|
|
146
|
-
|-----|--------|
|
|
147
|
-
| `J` / `K` | Jump to next/previous file |
|
|
148
|
-
| `v` | Toggle file viewed/unviewed |
|
|
149
|
-
| `b` | Toggle sidebar visibility |
|
|
150
|
-
| `/` | Open text search |
|
|
151
|
-
| `s` | Open symbol search |
|
|
152
|
-
| `g` `v` | Open file browser |
|
|
153
|
-
| `g` `t` | Open theme picker |
|
|
154
|
-
| `Cmd/Ctrl+K` | Open global command palette |
|
|
155
|
-
| `Cmd/Ctrl+,` | Toggle settings panel |
|
|
156
|
-
| `?` / `⌘?` | Show shortcuts help modal |
|
|
157
|
-
|
|
158
|
-
### Plan page extras (when reviewing a plan at `/plan`)
|
|
159
|
-
| Key | Action |
|
|
160
|
-
|-----|--------|
|
|
161
|
-
| `m` | Cycle Source → Read → Split |
|
|
162
|
-
| `z` | Toggle zen reading (switches to Read if needed); Esc also exits zen |
|
|
163
|
-
| `e` | Toggle **live plan edit** (current version; prefers Split + source editor) |
|
|
164
|
-
| `⌘/Ctrl+S` | While editing: flush autosave now |
|
|
165
|
-
| `o` | Toggle Outline (left TOC) |
|
|
166
|
-
| `c` | Toggle Comments map (right rail) |
|
|
167
|
-
| `J` / `K` | Next / previous plan |
|
|
168
|
-
| Esc | Edit mode: open Discard (or exit edit if nothing to discard); else exit zen / dismiss Add-comment chip / close draft |
|
|
169
|
-
|
|
170
|
-
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.
|
|
43
|
+
## What you get
|
|
171
44
|
|
|
172
|
-
|
|
45
|
+
| Area | Highlights |
|
|
46
|
+
|------|------------|
|
|
47
|
+
| **Review UI** | Split/unified diffs, inline comments + severity, suggestions, image diffs, themes (52), search |
|
|
48
|
+
| **Agents** | `await-review`, reply/resolve, progress, MCP (**37** tools), skills via `npx skills add ahmedragab20/diffing` |
|
|
49
|
+
| **Plan review** | Submit markdown → human verdict → approved / changes-requested / rejected |
|
|
50
|
+
| **GitHub PR** | Local PR sessions (`--gh-pr`), bounded inspect, optional authorized publish |
|
|
51
|
+
| **Sessions** | Concurrent web/TUI/PR reviews; `diffing sessions` task manager |
|
|
52
|
+
| **Local-first** | `127.0.0.1`, random free port, state under `~/.diffing/` |
|
|
173
53
|
|
|
54
|
+
> **TUI is experimental.** Web is the supported production path. See [docs](https://ahmedragab20.github.io/diffing/docs/guides/tui/).
|
|
174
55
|
|
|
175
56
|
---
|
|
176
57
|
|
|
177
|
-
##
|
|
178
|
-
|
|
179
|
-
> [!WARNING]
|
|
180
|
-
> The TUI is **experimental**. The interface, keymap, and on-disk format of
|
|
181
|
-
> `server.json` (`mode: "tui"`) may change in a minor release before
|
|
182
|
-
> stabilisation. The web UI is the supported path for production workflows;
|
|
183
|
-
> please open an issue before depending on the TUI for CI / agent automation.
|
|
184
|
-
> The web review flow, plan review, and PR review are unaffected.
|
|
185
|
-
|
|
186
|
-
> [!IMPORTANT]
|
|
187
|
-
> Native binaries are published as optional, platform-specific npm packages
|
|
188
|
-
> for macOS, Windows, and glibc/musl Linux. The main package never compiles Rust
|
|
189
|
-
> during installation and never installs a binary for the wrong platform. A
|
|
190
|
-
> source build and `$PATH` remain supported fallbacks.
|
|
191
|
-
|
|
192
|
-
`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. Review sessions publish a capability-scoped loopback API through the per-repository session registry; web and TUI reviews can run concurrently, while `server.json` points agent commands at the selected active session. Read-only viewers do not register a review session.
|
|
193
|
-
|
|
194
|
-
For everyday diff browsing, `diffing view` opens the same renderer as a
|
|
195
|
-
smaller read-only experience: continuous virtualized changes, a compact file
|
|
196
|
-
rail, change map, syntax highlighting, mouse/vim navigation, split/unified
|
|
197
|
-
layout, wrapping, and themes. In both viewer and review modes, `/` opens the
|
|
198
|
-
web UI's fff-powered `All`, `Files`, `Text`, and `Symbols` search with the same
|
|
199
|
-
result totals, frecency, and
|
|
200
|
-
syntax-highlighted preview; `f` opens directly in file search. The viewer
|
|
201
|
-
hides comments, viewed state, and agent handoff. Search starts diff-local and
|
|
202
|
-
`Ctrl-G` opts into the whole repository. Viewer and review sessions share the
|
|
203
|
-
persisted language-intelligence preference (Auto by default).
|
|
204
|
-
|
|
205
|
-
Its diff-first **Gridline** design system derives a tonal canvas, quiet
|
|
206
|
-
surfaces, diff fills, selection, gutters, and syntax roles from every web
|
|
207
|
-
theme. A compact header always identifies the repository and whether the TUI
|
|
208
|
-
is showing working-tree, staged, revision-range, or commit changes. The focused
|
|
209
|
-
viewer removes review actions and the duplicate file banner; the review
|
|
210
|
-
surface keeps a restrained command row for handoff.
|
|
211
|
-
Changed paths render as a compact hierarchical tree, semantic backgrounds
|
|
212
|
-
span the full row, and the bottom command strip gives keys more weight than
|
|
213
|
-
their descriptions. Empty review drawers collapse automatically. Wide
|
|
214
|
-
terminals can show files, diff, and review together; medium layouts place an
|
|
215
|
-
active review below the diff; compact layouts show one focused workspace at a
|
|
216
|
-
time. Press `,` for persisted Settings, including **Single file** versus
|
|
217
|
-
virtualized **Continuous files**, split/unified layout, wrap, tab size, line
|
|
218
|
-
numbers, mouse input, file-sidebar visibility and width, review drawer,
|
|
219
|
-
optional language intelligence, and theme. Press `b` to toggle the sidebar
|
|
220
|
-
without opening Settings. Disabling mouse input releases terminal mouse
|
|
221
|
-
capture and removes hover, click, drag, and wheel handling until it is
|
|
222
|
-
re-enabled from the keyboard.
|
|
223
|
-
|
|
224
|
-
The [Gridline TUI design-system contract](docs/tui-design-system.md) documents
|
|
225
|
-
the semantic tokens, density metrics, focus rules, component recipes, theme
|
|
226
|
-
invariants, and contributor checklist used by the native renderer.
|
|
227
|
-
|
|
228
|
-
The TUI is opt-in through `--tui` or the persistent `diffing mode tui` preference. If the environment 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 same `diffing` install serves either web or TUI mode.
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
diffing view # Focused read-only working-tree diff
|
|
232
|
-
diffing view --staged # Focused staged diff
|
|
233
|
-
diffing view main..feature # Focused branch comparison
|
|
234
|
-
diffing --tui # Open the current working tree in the TUI
|
|
235
|
-
diffing --tui --staged # Review staged changes in the TUI
|
|
236
|
-
diffing --tui HEAD~3 # Review working tree vs. 3 commits ago
|
|
237
|
-
diffing --tui main..feature # Compare two branches in the TUI
|
|
238
|
-
diffing --tui -- -- src/ # Limit a TUI review to a directory
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
**Stack** — Rust 1.78+ workspace (`crates/diffing-core/` shared lib + `crates/diffing-tui/` binary), `ratatui` + `crossterm` for rendering, `syntect` with the `two-face` grammar catalog for syntax highlighting, and `notify-debouncer-full` for live updates.
|
|
242
|
-
|
|
243
|
-
**Features**
|
|
244
|
-
|
|
245
|
-
- **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.
|
|
246
|
-
- **Retained, viewport-only rendering** — visible rows are sought into a bounded overscan window, decoded with per-line byte caps, theme-aware syntax-highlighted, and retained as terminal cells. Cursor, hover, and selection are cheap overlays; nearby scrolls reuse the same surface. Split mode pairs deletion/addition runs and highlights changed tokens within the pair. Terminal colors automatically degrade from truecolor to ANSI-256 or monochrome. Per-file tab widths follow nested `.editorconfig` files.
|
|
247
|
-
- **Focused navigation** — `Enter`/`+` progressively expand Git context and `-` collapses it; live refresh restores the selected source line and its viewport position; the file rail shows compact `+N -N` stats. In viewer mode, `e` safely suspends the alternate screen, opens the focused line in `$VISUAL`/`$EDITOR`, then restores the TUI.
|
|
248
|
-
- **Terminal-native image diffs** — `i` opens exact Git before/after blobs with side-by-side, individual, and pixel-difference modes plus fit, zoom, and pan. PNG, GIF, BMP, and ICO decode in-process; JPEG, WebP, AVIF, and SVG use a bounded ImageMagick/ffmpeg fallback when installed. Truecolor half-block rendering degrades to ANSI-256 and monochrome without requiring Kitty, iTerm, or Sixel support.
|
|
249
|
-
- **Optional local language intelligence** — viewer and review modes share the persisted setting. Auto mode lazily discovers an existing `rust-analyzer`, `typescript-language-server`, `pyright-langserver`, `gopls`, or `clangd`; diffing never downloads a server or sends source off-machine.
|
|
250
|
-
- **Vim-style file tree & keymap** — numeric counts plus `j/k`, `gg/G`, `Ctrl-d/u`, `J/K`, `]h/[h`, `]c/[c`, `zz`, `h/l`, `gh`, `gd`, `/`, `n/N`, `f`, `a`, `:`, `Tab`, `v`, `b`, `w`, `m`, `i`, `t`, `,`, and `?`. `Esc` cancels a mode; `q` or `Ctrl-C` quits. Sidebar visibility and width, single/continuous file display, mouse input, and language intelligence are changed from Settings.
|
|
251
|
-
- **Review-complete comments** — line, same-side range, and file-level threads share the web JSON schema, including severity. The drawer filters open/replied/resolved and blocking/question/nit/praise threads; the diff gutter distinguishes their states without relying on color alone.
|
|
252
|
-
- **Complete text-entry and thread UX** — bracketed paste, cursor-aware single-line fields, multi-line `tui-textarea` comment/reply forms, explicit Save/Reply/Cancel controls, and a scrollable full-thread overlay with jump/edit/reply/resolve actions.
|
|
253
|
-
- **Live updates** via `notify` watcher on `comments.json` and the repo working tree — write a comment in another window and it appears immediately.
|
|
254
|
-
- **Send review & agent handoff** — compact verdict + general-comment popover with an unviewed-files guard. `Ctrl-S` persists the review, copies its XML payload to the clipboard when available, and immediately wakes every `diffing await-review` waiter. Waiting-agent state appears only while a waiter is active.
|
|
255
|
-
- **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.
|
|
256
|
-
- **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`).
|
|
257
|
-
|
|
258
|
-
The synthetic one-million-line index benchmark (50.8 MiB patch) currently reaches a usable partial snapshot in under 1 ms, completes indexing in about 50 ms, and serves viewport reads at 32 µs p95 on the development machine. Run it with `DIFFING_BENCH_LINES=1000000 cargo bench -p diffing-core --bench diff_index`.
|
|
259
|
-
|
|
260
|
-
The production-renderer contract paints a 240×80 terminal over one million diff lines. On the same machine, warm redraw, cursor movement, and adjacent scrolling are about 0.10–0.11 ms p95; random jumps are about 2.4 ms p95. Repeated redraw, cursor, annotation, split, and wrap paths allocate zero bytes, while a cold wrapped 2 MiB source line remains bounded at about 2 ms and 1.3 MiB of allocation. Run it with `DIFFING_RENDER_BENCH_LINES=1000000 cargo bench -p diffing-tui --bench render_diff`; results vary by machine and filesystem cache.
|
|
261
|
-
|
|
262
|
-
Headless examples:
|
|
58
|
+
## Agent one-liners
|
|
263
59
|
|
|
264
60
|
```bash
|
|
265
|
-
diffing
|
|
266
|
-
diffing
|
|
267
|
-
diffing
|
|
268
|
-
diffing
|
|
61
|
+
diffing # human reviews in browser
|
|
62
|
+
diffing url # share link; async park by default
|
|
63
|
+
diffing await-review # only when human is reviewing now
|
|
64
|
+
diffing comments --open
|
|
65
|
+
diffing reply <id> --body "…" --model "your-model"
|
|
66
|
+
diffing resolve <id>
|
|
67
|
+
diffing plan submit PLAN.md --model "your-model"
|
|
68
|
+
diffing mcp
|
|
269
69
|
```
|
|
270
70
|
|
|
271
|
-
**
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
pnpm build:tui:debug # debug build → target/debug/diffing-tui
|
|
275
|
-
pnpm build:tui # release build → target/release/diffing-tui
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
The CLI auto-discovers the binary in the following search order: sibling of
|
|
279
|
-
`dist/cli.mjs`, `target/release/`, `target/debug/`, the matching optional
|
|
280
|
-
native npm package, `bin/`, then `$PATH`. A
|
|
281
|
-
`cargo build -p diffing-tui` debug workflow is supported out of the box; you
|
|
282
|
-
do not need a release build just to use the TUI locally. The sibling and
|
|
283
|
-
`bin/` locations remain useful for manual installations. A CLI run from this source
|
|
284
|
-
checkout discovers the binary under `target/`; `npm install -g diffing`
|
|
285
|
-
automatically installs and resolves the matching native package for global use.
|
|
71
|
+
Full agent protocol, exit codes, and MCP catalog: **[Documentation](https://ahmedragab20.github.io/diffing/docs/)** · in-repo [AGENTS.md](./AGENTS.md).
|
|
286
72
|
|
|
287
73
|
---
|
|
288
74
|
|
|
289
|
-
##
|
|
290
|
-
|
|
291
|
-
Every time you launch `diffing` in the terminal, it serves a highly polished, interactive greeting before the browser opens:
|
|
292
|
-
- **256-Color Monochromatic Palettes** — Beautifully rendered box outlines across 6 monochromatic themes (Cyan, Green, Magenta, Yellow, Blue, Orange) with custom faint, base, glow, and text hues.
|
|
293
|
-
- **Dynamic Startup Animations** — Instantly runs one of 6 terminal-based micro-animations (Typewriter, Wave Reveal, Slide-In, Pulse Border, Glitch Noise, Matrix Rain) underneath the local server URL.
|
|
294
|
-
- **Motivational Developer Quotes** — Settles to display one of 30 curated, funny, philosophical, or motivational developer quotes to kick off your review session.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Performance & Speed
|
|
299
|
-
|
|
300
|
-
Built from the ground up for a fast, fluid experience—even in large repositories:
|
|
75
|
+
## Documentation
|
|
301
76
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Real-Time Communication
|
|
316
|
-
|
|
317
|
-
Bidirectional, event-driven sync between the browser UI and connected AI agents via Server-Sent Events (SSE):
|
|
318
|
-
|
|
319
|
-
```text
|
|
320
|
-
┌──────────────┐ SSE (change/comments/agent-status) ┌──────────────┐
|
|
321
|
-
│ │◄───────────────────────────────────────────►│ │
|
|
322
|
-
│ Browser │ │ AI Agent │
|
|
323
|
-
│ UI │ ┌─────────────────────────────┐ │ (CLI/MCP) │
|
|
324
|
-
│ │ │ comments.json │ │ │
|
|
325
|
-
│ │ │ (FileCommentStore on disk) │ │ │
|
|
326
|
-
└──────┬───────┘ └──────────┬──────────────────┘ └──────┬───────┘
|
|
327
|
-
│ user writes comment │ │
|
|
328
|
-
│ ──────────────────────► │ fs.watch detects change │
|
|
329
|
-
│ │ ───────────────────────────────► │
|
|
330
|
-
│ │ agent posts reply │
|
|
331
|
-
│ SSE broadcasts toast │ ◄────────────────────────────── │
|
|
332
|
-
│ ◄───────────────────────│ │
|
|
333
|
-
```
|
|
77
|
+
| | |
|
|
78
|
+
|--|--|
|
|
79
|
+
| Getting started | https://ahmedragab20.github.io/diffing/docs/getting-started/ |
|
|
80
|
+
| Agent handoff | https://ahmedragab20.github.io/diffing/docs/guides/agent-handoff/ |
|
|
81
|
+
| Plan review | https://ahmedragab20.github.io/diffing/docs/guides/plan-review/ |
|
|
82
|
+
| CLI reference | https://ahmedragab20.github.io/diffing/docs/reference/cli/ |
|
|
83
|
+
| MCP tools | https://ahmedragab20.github.io/diffing/docs/reference/mcp/ |
|
|
84
|
+
| Keyboard | https://ahmedragab20.github.io/diffing/docs/reference/keyboard/ |
|
|
85
|
+
| Design (Gridline) | https://ahmedragab20.github.io/diffing/docs/design/gridline/ |
|
|
86
|
+
| llms.txt | https://ahmedragab20.github.io/diffing/llms.txt |
|
|
334
87
|
|
|
335
|
-
|
|
336
|
-
- **File System Watcher** — `fs.watch` on repo root (recursive, 200ms debounce) triggers live diff refresh on working tree changes. Skips `.git`, `node_modules`, `dist`, and `.changeset`.
|
|
337
|
-
- **Comment Store Watcher** — `fs.watch` on `comments.json` (120ms debounce) broadcasts updates when agents or humans write comments externally.
|
|
338
|
-
- **Agent Activity Toasts** — Real-time toast notifications when an agent posts a reply, showing model name, file path, and body preview. Clickable to jump to the file; auto-dismisses after 8 seconds.
|
|
339
|
-
- **Agent Status Indicator** — Green dot on the "Send to agent" button when an agent process is connected and waiting (via SSE `agent-status` events).
|
|
340
|
-
- **Bidirectional Sync** — User adds comments in UI → saved to `comments.json` → watcher → SSE broadcast → agent picks up. Agent posts reply → written to `comments.json` → watcher → SSE → UI toast.
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## AI Agent Collaboration (Handoff Protocol)
|
|
345
|
-
|
|
346
|
-
`diffing` solves the friction of copy-pasting code review notes into LLM chat boxes. It establishes an **"agent waits, human releases"** pipeline using a robust, port-agnostic lockfile mechanism.
|
|
347
|
-
|
|
348
|
-
```text
|
|
349
|
-
1. The agent runs a blocking command/tool and enters sleep mode.
|
|
350
|
-
2. You review code in your browser, leave inline comments, and click "Send to agent".
|
|
351
|
-
3. The agent wakes up instantly, receives comments as structured XML, applies edits, and posts replies.
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### A. CLI Integration (For any terminal-based agent)
|
|
355
|
-
The `diffing` binary acts as a port-agnostic CLI client. It automatically discovers the running server by reading a local repository lockfile:
|
|
88
|
+
Local site preview (contributors):
|
|
356
89
|
|
|
357
90
|
```bash
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
diffing comments [--open] [--format xml|json|md]
|
|
361
|
-
diffing reply <id> --body "..." # Post an agent response
|
|
362
|
-
diffing resolve <id> # Mark resolved (UI updates live)
|
|
363
|
-
diffing unresolve <id> # Re-open a resolved thread
|
|
364
|
-
diffing comment edit <id> --body "..."
|
|
365
|
-
diffing comment delete <id>
|
|
366
|
-
diffing progress --message "…" [--pct 40] [--model M] # Live progress toast
|
|
367
|
-
diffing url # Active server base URL
|
|
368
|
-
diffing sessions # List every live web/TUI/PR session
|
|
369
|
-
diffing sessions use <id> # Retarget agent commands
|
|
370
|
-
diffing sessions stop <id>|active|all
|
|
371
|
-
|
|
372
|
-
# Plan review (before any code is written)
|
|
373
|
-
diffing plan submit <file> [--title T] [--model M] [--id <id>] [--wait] [--save-source]
|
|
374
|
-
diffing plan await [--timeout N]
|
|
375
|
-
diffing plan list [--json]
|
|
376
|
-
diffing plan show [<id>] [--json] [--version N]
|
|
377
|
-
diffing plan versions <id> [--json]
|
|
378
|
-
diffing plan reply <commentId> --body "..."
|
|
379
|
-
diffing plan resolve <commentId>
|
|
380
|
-
|
|
381
|
-
# DX
|
|
382
|
-
diffing doctor # Environment / install self-check
|
|
383
|
-
diffing completion <bash|zsh|fish>
|
|
384
|
-
diffing inspect summary|files|hunks|slice|search # Bounded reads from a TUI session
|
|
91
|
+
pnpm --dir site install --ignore-workspace
|
|
92
|
+
pnpm docs:dev
|
|
385
93
|
```
|
|
386
94
|
|
|
387
|
-
Full contracts (flags, exit codes, XML, HTTP): **[docs/cli.md](docs/cli.md)**.
|
|
388
|
-
|
|
389
|
-
### B. Model Context Protocol (MCP) Server
|
|
390
|
-
If your agent supports MCP, configure `diffing` as a stdio server. The MCP is
|
|
391
|
-
self-describing and can start or reuse the loopback review server, so an
|
|
392
|
-
MCP-only agent does not need to know a port or fall back to raw HTTP:
|
|
393
|
-
|
|
394
|
-
```json
|
|
395
|
-
{
|
|
396
|
-
"mcpServers": {
|
|
397
|
-
"diffing": {
|
|
398
|
-
"command": "diffing",
|
|
399
|
-
"args": ["mcp"]
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
Global/desktop clients that do not launch MCP from the workspace should bind it
|
|
406
|
-
to one repository explicitly:
|
|
407
|
-
|
|
408
|
-
```json
|
|
409
|
-
{
|
|
410
|
-
"mcpServers": {
|
|
411
|
-
"diffing": {
|
|
412
|
-
"command": "diffing",
|
|
413
|
-
"args": ["mcp", "--repo", "/absolute/path/to/repository"]
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Run `diffing mcp --help` for setup details. The server initialization
|
|
420
|
-
instructions tell an unfamiliar model what to do next, and every tool returns
|
|
421
|
-
both readable text and structured content.
|
|
422
|
-
|
|
423
|
-
| Area | Tools |
|
|
424
|
-
|------|-------|
|
|
425
|
-
| Session | `review_session_status`, `start_review_session` |
|
|
426
|
-
| Diff inspection | `get_diff`, `diff_summary`, `diff_files`, `diff_hunks`, `diff_slice`, `diff_search` |
|
|
427
|
-
| 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` |
|
|
428
|
-
| Loop | `await_review`, `report_progress`, `get_review_history` |
|
|
429
|
-
| Plan | `submit_plan`, `await_plan_review`, `list_plans`, `get_plan`, `get_plan_versions`, `get_plan_version`, `reply_to_plan_comment`, `resolve_plan_comment` |
|
|
430
|
-
|
|
431
|
-
Clients that expose MCP prompts can use `review_local_changes` and
|
|
432
|
-
`submit_plan_for_review`; clients that expose resources can read
|
|
433
|
-
`diffing://agent-guide`. Essential guidance is also present in initialization
|
|
434
|
-
instructions and tool descriptions because prompt/resource support varies.
|
|
435
|
-
|
|
436
|
-
### C. Agent Skills
|
|
437
|
-
You can install diffing skills directly into your AI coding assistant:
|
|
438
|
-
```bash
|
|
439
|
-
npx skills add ahmedragab20/diffing
|
|
440
|
-
```
|
|
441
|
-
Installs five portable, natural-language-triggered workflows:
|
|
442
|
-
|
|
443
|
-
1. **`diffing`** — Detects MCP/CLI/offline capabilities and routes the request.
|
|
444
|
-
2. **`diffing-start-review`** — Starts or reuses the review session and returns its URL.
|
|
445
|
-
3. **`diffing-finish-review`** — Waits for human feedback, applies clear requests, and synchronizes replies/resolutions live.
|
|
446
|
-
4. **`diffing-review`** — Inspects the full local diff and posts actionable inline findings.
|
|
447
|
-
5. **`diffing-plan-review`** — Gates implementation on a reviewed plan and deterministic verdict handling.
|
|
448
|
-
|
|
449
|
-
The skills prefer native MCP tools, fall back to the port-agnostic CLI, and can
|
|
450
|
-
still interpret pasted self-describing XML. The installable `skills/` copies and
|
|
451
|
-
repo-local `.agents/skills/` copies are contract-tested to remain identical.
|
|
452
|
-
|
|
453
|
-
### Send Review Popover
|
|
454
|
-
A GitHub-style **Submit review** / **Send to agent** popover: pick a verdict
|
|
455
|
-
(Approve / Request edits / Reject / **Comment only**), optionally add an overall
|
|
456
|
-
note, preview every inline comment (editable/removable), and release every
|
|
457
|
-
waiting agent. Agent waiting state shows as a green dot on the button.
|
|
458
|
-
**Copy comments** serializes the thread set to the agent XML spec.
|
|
459
|
-
|
|
460
|
-
### Port-Agnostic Discovery
|
|
461
|
-
A per-repo registry in `~/.diffing/<repo-hash>/sessions/` tracks every live review. `server.json` points subcommands and MCP tools at the active session with zero port configuration; stale records are pruned and another live session is elected automatically.
|
|
462
|
-
|
|
463
|
-
### Monotonic Round Sequencing
|
|
464
|
-
A `ReviewSession` class with a monotonic `round` counter and race-guard logic ensures that if a "Send to agent" lands between polling intervals, the cached payload is delivered immediately. Multiple agents can block on the same review session simultaneously—all are released together on send.
|
|
465
|
-
|
|
466
95
|
---
|
|
467
96
|
|
|
468
|
-
##
|
|
469
|
-
|
|
470
|
-
Review **any agent plan** — not just code. When an AI agent produces a plan
|
|
471
|
-
(an implementation outline, a design proposal, a migration strategy), `diffing`
|
|
472
|
-
renders the markdown line-by-line so you can comment on specific lines or
|
|
473
|
-
sections and **approve**, **request changes**, **reject**, or **comment only**
|
|
474
|
-
— then hands the structured verdict back to the waiting agent. It's the
|
|
475
|
-
"agent waits, human releases" handoff, applied *before* any code is written.
|
|
476
|
-
|
|
477
|
-
```text
|
|
478
|
-
1. The agent submits a markdown plan and blocks (diffing plan submit … --wait).
|
|
479
|
-
2. You open Plans (/plan), read Source / Read / Split, and comment on lines/sections.
|
|
480
|
-
3. You Submit review: Approve / Request changes / Reject / Comment only.
|
|
481
|
-
4. The agent wakes, receives <plan-review> XML, and proceeds, revises, or stops.
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
- **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).
|
|
485
|
-
- **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.
|
|
486
|
-
- **Resizable split** — drag the Source|Read divider; double-click resets 50/50. Edit mode uses independent pane scroll so the caret stays put.
|
|
487
|
-
- **Renders any markdown plan** — Source via `@pierre/diffs` when viewing (commentable lines); Read as polished markdown with outline (`o`) and comments map (`c`).
|
|
488
|
-
- **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.
|
|
489
|
-
- **Severity** — optional blocking / nit / question / praise on plan comments (same labels as code review; included in `<plan-review>` handoff XML).
|
|
490
|
-
- **Collapsible threads** — collapse open or resolved cards; collapse the in-card source preview; delete resolved comments and replies.
|
|
491
|
-
- **General comments** — notes scoped to the whole plan.
|
|
492
|
-
- **Four-way verdict** — Approve / Request changes / Reject / Comment only (no file edits). Resubmit with the same id bumps version and re-opens review.
|
|
493
|
-
- **Browse plan versions** — version dropdown, historical banner, comments filtered to the viewed version. CLI / MCP / HTTP as below.
|
|
494
|
-
- **Live "Plans" badge** — toolbar badge for plans awaiting review; green dot when an agent is waiting.
|
|
495
|
-
- **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`).
|
|
496
|
-
- **Scratch outside the tree** — plan sources under `~/.diffing/<repo>/plan-sources/` (`--save-source`); never commit agent plans into the consumer project.
|
|
497
|
-
|
|
498
|
-
### Plan Review XML Specification
|
|
499
|
-
|
|
500
|
-
When a plan verdict is handed to a waiting agent, it is serialized into a
|
|
501
|
-
self-documenting `<plan-review>` envelope:
|
|
97
|
+
## Links
|
|
502
98
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
<plan id="…" title="…" version="2" decision="changes-requested" decided-at="2026-05-29T18:52:56.053Z">
|
|
507
|
-
<decision-summary><![CDATA[The reviewer REQUESTED CHANGES. Revise the plan…]]></decision-summary>
|
|
508
|
-
<decision-comment><![CDATA[Tighten the Phase 2 scope.]]></decision-comment>
|
|
509
|
-
<plan-body><![CDATA[# My Plan
|
|
510
|
-
## Phase 1
|
|
511
|
-
…full markdown of the plan being reviewed…]]></plan-body>
|
|
512
|
-
<comments>
|
|
513
|
-
<comment id="c1" line="4" section="Phase 1" status="open" severity="blocking" created-at="2026-05-29T18:52:29.557Z">
|
|
514
|
-
<context><![CDATA[Do the first thing]]></context>
|
|
515
|
-
<body><![CDATA[Clarify what "the first thing" is.]]></body>
|
|
516
|
-
<replies>
|
|
517
|
-
<reply id="r1" created-at="…" role="agent" model="claude-opus-4-8"><![CDATA[Will do — splitting into 1a/1b.]]></reply>
|
|
518
|
-
</replies>
|
|
519
|
-
</comment>
|
|
520
|
-
</comments>
|
|
521
|
-
</plan>
|
|
522
|
-
</plan-review>
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
## Reviewing a GitHub PR
|
|
528
|
-
|
|
529
|
-
`diffing` can open a GitHub PR in the same diff UI you use for the working
|
|
530
|
-
tree, and push your review back to GitHub when you're done. The "Send to
|
|
531
|
-
agent" handoff is **structurally absent** in PR mode — there's no way to
|
|
532
|
-
accidentally route a PR review to a coding agent.
|
|
533
|
-
|
|
534
|
-
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/c581f93d-92bc-44dc-ba7c-3d673395f39f" />
|
|
535
|
-
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/efb894d8-2815-445e-b587-8397074e6ef2" />
|
|
536
|
-
<img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/6906b216-a1c2-44e0-85c4-6fadad6245de" />
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
```text
|
|
540
|
-
# All of these open PR #1234 in the current repo:
|
|
541
|
-
diffing "gh pr 1234"
|
|
542
|
-
diffing --gh-pr 1234
|
|
543
|
-
|
|
544
|
-
# Full URL form:
|
|
545
|
-
diffing "gh pr https://github.com/ahmedragab20/diffing/pull/1234"
|
|
546
|
-
diffing --gh-pr https://github.com/ahmedragab20/diffing/pull/1234
|
|
547
|
-
|
|
548
|
-
# owner/repo#N shorthand (skips the cwd-repo check):
|
|
549
|
-
diffing "gh pr ahmedragab20/diffing#1234"
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
PR mode uses the same review shell as a local diff: file tree and filters,
|
|
553
|
-
search, themes, fonts, density and diff settings, viewed-file tracking,
|
|
554
|
-
keyboard shortcuts, inline composers, and live check status. PR metadata stays
|
|
555
|
-
in a compact overview above the diff instead of crowding the action toolbar.
|
|
556
|
-
|
|
557
|
-
Published GitHub conversations are anchored directly beneath their diff lines.
|
|
558
|
-
Replies, edits, deletions, resolve, and reopen actions are sent to GitHub, while
|
|
559
|
-
changes made on GitHub are pulled into `diffing` on refresh, window focus, and a
|
|
560
|
-
30-second background interval. Outdated or otherwise unanchorable threads fall
|
|
561
|
-
back to the file-level context area. GitHub suggestion fences render as
|
|
562
|
-
before/after previews instead of raw Markdown.
|
|
563
|
-
|
|
564
|
-
Submitted review events are separate from inline threads. A review-activity
|
|
565
|
-
card walks the latest approval, request-changes, comment-only, pending, and
|
|
566
|
-
dismissed reviews, including the author, verdict, timestamp, overall Markdown
|
|
567
|
-
comment, and a link to the GitHub review. This includes reviews submitted from
|
|
568
|
-
either `diffing` or GitHub.
|
|
569
|
-
|
|
570
|
-
When you click **Submit to GitHub**, `diffing` builds a `POST
|
|
571
|
-
/repos/{owner}/{repo}/pulls/{pull_number}/reviews` payload and POSTs it
|
|
572
|
-
to GitHub. Multi-line selections use GitHub's native `start_line` / `line`
|
|
573
|
-
range anchors. Existing published conversations and review events are **never
|
|
574
|
-
re-POSTed** — only the local drafts in the current review are submitted.
|
|
575
|
-
|
|
576
|
-
The submit panel supports **Approve**, **Comment**, **Request changes**, and
|
|
577
|
-
**Save as draft**. After a successful submission, local drafts are promoted to
|
|
578
|
-
published GitHub conversations and the overall comment appears immediately in
|
|
579
|
-
review activity. Submission feedback is page-local: dismissing it or reloading
|
|
580
|
-
the page does not resurrect an old success toast.
|
|
581
|
-
|
|
582
|
-
### Headless subcommands
|
|
583
|
-
|
|
584
|
-
For CI / agent use, the same flow is exposed as a `gh` subcommand with no
|
|
585
|
-
UI:
|
|
586
|
-
|
|
587
|
-
```text
|
|
588
|
-
# Submit the current in-progress review to GitHub.
|
|
589
|
-
diffing gh pr-review --decision request-changes --body "Please address the range"
|
|
590
|
-
|
|
591
|
-
# Refresh and dump PR metadata, published threads, and review activity as JSON.
|
|
592
|
-
diffing gh pr-fetch 1234
|
|
593
|
-
|
|
594
|
-
# List the PR-mode comments in this diffing session (mirrors `diffing comments`).
|
|
595
|
-
diffing gh pr-list-comments
|
|
596
|
-
|
|
597
|
-
# Show the active PR session (ref, owner/repo#n, comment count, submitted status).
|
|
598
|
-
diffing gh status
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
### Authentication
|
|
602
|
-
|
|
603
|
-
The submit path uses the same precedence as the rest of the GitHub
|
|
604
|
-
ecosystem:
|
|
605
|
-
|
|
606
|
-
1. **`gh` CLI** — preferred; uses your existing `gh auth login` session.
|
|
607
|
-
2. **Token env var** — `$GH_TOKEN`, then `$GITHUB_TOKEN`, then
|
|
608
|
-
`$GITHUB_API_TOKEN` (any of the three).
|
|
609
|
-
3. If neither is available, the submit fails with a clear one-line
|
|
610
|
-
message telling you to run `gh auth login` or set `$GITHUB_TOKEN`.
|
|
611
|
-
|
|
612
|
-
The `gh` binary is used to open and refresh PR metadata, synchronize reviews
|
|
613
|
-
and threads, query checks, and (preferably) submit. The diff itself is rendered
|
|
614
|
-
locally from the cached session; an already-open session remains readable when
|
|
615
|
-
GitHub is temporarily unavailable, while synchronization and submission require
|
|
616
|
-
GitHub access.
|
|
617
|
-
|
|
618
|
-
### Storage
|
|
619
|
-
|
|
620
|
-
PR-mode state lives in `pr-session.json` (in the per-repo
|
|
621
|
-
`~/.diffing/<repo>-<hash>/` directory) — a separate file from
|
|
622
|
-
`comments.json` and `plans.json`, so a local review and a PR review can
|
|
623
|
-
coexist without colliding. It stores the cached patch, local drafts, published
|
|
624
|
-
thread state, review-level activity, and the latest submission metadata; no
|
|
625
|
-
browser storage is used.
|
|
626
|
-
|
|
627
|
-
---
|
|
628
|
-
|
|
629
|
-
## Inline Comment System
|
|
630
|
-
|
|
631
|
-
Rich, real-time comment threads directly on diff lines:
|
|
632
|
-
|
|
633
|
-
- **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.
|
|
634
|
-
- **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"`).
|
|
635
|
-
- **Severity** — Optional triage labels (design-system dropdown): blocking / nit / question / praise. Stored and emitted on agent handoff XML; MCP `create_comment` accepts `severity`.
|
|
636
|
-
- **File-Level Comments** — Notes scoped to the entire file.
|
|
637
|
-
- **Comment Drafts** — Server-side drafts with TTL under `~/.diffing/` (no browser storage).
|
|
638
|
-
- **Agent Attribution** — Replies carry `role` (`user`/`agent`) and `model`.
|
|
639
|
-
- **Suggestion Application** — `` ```suggestion `` blocks (including multi-line) via **Apply suggestion** / `POST /api/comments/:id/apply-suggestion`.
|
|
640
|
-
- **Bulk resolve** — Toolbar **Resolve all** → `POST /api/comments/resolve-all`.
|
|
641
|
-
- **Agent progress** — Agents can `diffing progress` / `report_progress` for a live toast while working.
|
|
642
|
-
- **Full CRUD** — Create, edit, delete (including resolved plan threads), reply, unresolve — CLI, MCP, and HTTP.
|
|
643
|
-
|
|
644
|
-
---
|
|
645
|
-
|
|
646
|
-
## Inline Diff Viewer Settings
|
|
647
|
-
|
|
648
|
-
Fine-grained control over how diffs are rendered:
|
|
649
|
-
|
|
650
|
-
| Setting | Options | Description |
|
|
651
|
-
|---------|---------|-------------|
|
|
652
|
-
| **Inline Diff Type** | `word` (default), `word-alt`, `char`, `none` | Pinpoint exactly what changed inside a modified line |
|
|
653
|
-
| **Diff Indicators** | `classic` (+/−), `bars`, `none` | Gutter markers for added and deleted lines |
|
|
654
|
-
| **Line Numbers** | on / off | Toggle gutter line numbers |
|
|
655
|
-
| **Line Wrap** | on / off | Soft-wrap long lines instead of horizontal scrolling |
|
|
656
|
-
| **Hunk Separators** | `simple`, `metadata`, `line-info`, `line-info-basic` | Style of the separator bar between diff hunks |
|
|
657
|
-
| **Line Hover Highlight** | `both`, `line`, `number`, `disabled` | Which element highlights on hover |
|
|
658
|
-
| **Font Size** | 11px – 16px | Configure globally |
|
|
659
|
-
| **UI Font** | Any system or Google font (default Geist Mono) | Customize typography for the Web UI layout |
|
|
660
|
-
| **Mono Font** | Any system or Google font (default JetBrains Mono) | Customize typography for code/diff block displays |
|
|
661
|
-
| **Tab Size** | 2 / 4 / 8 | Default tab width (overridden per-file by EditorConfig) |
|
|
662
|
-
| **Expandable Context** | `expandContextByDefault`, `collapsedContextThreshold` (default 10 lines), `expansionLineCount` (default 20) | Control how collapsed context regions behave |
|
|
663
|
-
| **Haptic & Sound Feedback** | on / off | Tactile feedback via `web-haptics` and synthesized audio cues (click, toggle, navigate, open, close, resolve, send, error) |
|
|
664
|
-
|
|
665
|
-
All settings persist to `~/.config/diffing/settings.json` and the UI updates are wrapped in `useTransition` for non-blocking responsiveness.
|
|
666
|
-
|
|
667
|
-
#### A note on custom fonts
|
|
668
|
-
|
|
669
|
-
Google-hosted families (e.g. `Fira Code`, `Source Code Pro`, `IBM Plex Mono`, `Roboto Mono`) are fetched automatically as web fonts and render in any browser. A **locally-installed** font — a Nerd Font, or a commercial font like `Dank Mono` — is applied by name and renders only if it is installed on your machine **and** your browser allows pages to use local fonts.
|
|
670
|
-
|
|
671
|
-
Privacy-hardened browsers block this: **Brave**, with Shields / "Block fingerprinting" enabled (the default), refuses to render uncommon local fonts as an anti-fingerprinting measure, so the selection silently falls back to the default monospace even though it is installed. To use a local-only font there, either pick a Google-hosted equivalent, or open **Shields** for the diffing site, set fingerprinting to *Allow all*, and reload.
|
|
672
|
-
|
|
673
|
-
---
|
|
674
|
-
|
|
675
|
-
## Merge Conflict Resolution
|
|
676
|
-
|
|
677
|
-
When your repository is in a merge state (`.git/MERGE_HEAD` detected):
|
|
678
|
-
|
|
679
|
-
- **Conflict Banner** — A prominent warning banner appears in the toolbar indicating the repo is in a merge conflict state.
|
|
680
|
-
- **`UnresolvedFile` Rendering** — Conflicted files are rendered using `@pierre/diffs`'s `UnresolvedFile` component with color-coded conflict markers.
|
|
681
|
-
- **Custom Action Buttons** — For each conflict region, choose **Accept Current**, **Accept Incoming**, or **Accept Both**.
|
|
682
|
-
- **Save & Stage** — After resolving all conflicts in a file, click **Save & Stage** to write the resolved content and `git add` it in one step.
|
|
683
|
-
- **Merge Status API** — `GET /api/merge-status` returns conflict state and lists conflicted files via `git diff --name-only --diff-filter=U`.
|
|
684
|
-
|
|
685
|
-
---
|
|
686
|
-
|
|
687
|
-
## Hunk Revert & History
|
|
688
|
-
|
|
689
|
-
- **Revert Individual Hunks** — Undo a single hunk from the working tree via `POST /api/revert-hunk` using `git apply --reverse`.
|
|
690
|
-
- **Blame & History** — View `git blame` for deleted lines and recent commit history for any file via `GET /api/hunk-history`, showing who authored deleted code and when.
|
|
691
|
-
|
|
692
|
-
---
|
|
693
|
-
|
|
694
|
-
## Advanced Git Operations
|
|
695
|
-
|
|
696
|
-
- **File Open in IDE** — Open any repo file in VS Code, Zed, Vim, Neovim, or the system default editor via `POST /api/open-file`. Configurable in settings.
|
|
697
|
-
- **File Save & Stage** — Write file contents to disk and optionally `git add` in one call via `POST /api/save-file`.
|
|
698
|
-
- **Repository File Lister** — `GET /api/repo-files` lists all known files (tracked + untracked, respecting `.gitignore`).
|
|
699
|
-
- **File Content Retrieval** — `GET /api/file-content` and `GET /api/file-text` return old (HEAD) or new (working tree) file versions as binary buffers or JSON text.
|
|
700
|
-
- **EditorConfig Integration** — Respects your local `.editorconfig` rules (`tab_width`, `indent_size`) for accurate, per-file tab sizing that overrides the default setting.
|
|
701
|
-
|
|
702
|
-
---
|
|
703
|
-
|
|
704
|
-
## Git Diff Drop-in Compatibility
|
|
705
|
-
|
|
706
|
-
`diffing` is designed as a **seamless, full drop-in replacement for `git diff`**. It features a comprehensive option parser that understands standard git revisions, options, and pathspecs, forwarding them directly to your local git engine.
|
|
707
|
-
|
|
708
|
-
Whether you are comparing branches, reviewing staged changes, or filtering specific directories, simply swap `git diff` for `diffing` to instantly elevate your review into a premium, interactive browser interface:
|
|
709
|
-
|
|
710
|
-
```bash
|
|
711
|
-
diffing # Review working tree changes in the browser UI
|
|
712
|
-
diffing --staged # Review staged changes (drop-in for git diff --staged)
|
|
713
|
-
diffing HEAD~3 # Review working tree changes against 3 commits ago
|
|
714
|
-
diffing main..feature # Compare two branches (drop-in for git diff main..feature)
|
|
715
|
-
diffing -- --cached -- src/ # Staged changes specifically in the src/ directory
|
|
716
|
-
```
|
|
717
|
-
|
|
718
|
-
### Intelligent Output Modes (TTY Auto-Detection)
|
|
719
|
-
To integrate flawlessly with your existing developer shell workflows, build pipelines, and command scripts, `diffing` automatically resolves the optimal output mode based on how stdout is directed:
|
|
720
|
-
- **Preferred interactive mode (Web by default)**: In an interactive terminal, `diffing` starts the saved `web` or `tui` mode. Use `diffing mode <web|tui>` to inspect or change the user-level preference.
|
|
721
|
-
- **Terminal Mode (Default for pipes, redirects, or non-TTY)**: When output is piped (e.g. `diffing | grep "const"`) or redirected to a file, it falls back to behave **exactly like `git diff`**, streaming clean, standard unified diff patch text directly to standard output and exiting.
|
|
722
|
-
|
|
723
|
-
Explicit `--web`, `--tui`, `--view`, and `--terminal` flags override the saved preference. The preference does not change the web default for GitHub PR reviews.
|
|
724
|
-
|
|
725
|
-
> [!TIP]
|
|
726
|
-
> Any standard output control or format-related flags (such as `--raw`, `--numstat`, `--stat`, `--exit-code`, `--quiet`, or `-o`) will automatically force Terminal Mode fallback.
|
|
727
|
-
|
|
728
|
-
> [!TIP]
|
|
729
|
-
> For a full list of all git option categories (algorithms, whitespace ignoring, context lines, word-level diffs, moved/copied detection, and path filtering) supported by `diffing`, see the [CLI Reference Manual](docs/cli.md).
|
|
730
|
-
|
|
731
|
-
### `diffing show` — Review a Commit's Changes (Drop-in for `git show`)
|
|
732
|
-
|
|
733
|
-
`diffing <sha>` runs `git diff <sha>`, which means "diff between `<sha>` and the working tree" — not the changes that commit introduced. If the working tree matches `<sha>`, the patch is empty and the file list renders blank.
|
|
734
|
-
|
|
735
|
-
To review the changes **of** a commit, use the new `show` subcommand. It mirrors `git show` and surfaces each commit's metadata (subject, author, date, message body) above the diff in the web UI:
|
|
736
|
-
|
|
737
|
-
```bash
|
|
738
|
-
diffing show HEAD # Review the tip commit's metadata + diff
|
|
739
|
-
diffing show HEAD~3..HEAD # Review the last 3 commits as a series
|
|
740
|
-
diffing show v1.0 # The commit a tag points to
|
|
741
|
-
diffing show abc123 def456 # Two specific commits, oldest-first
|
|
742
|
-
diffing show HEAD -- src/ # Limit a commit review to a directory
|
|
743
|
-
diffing show HEAD~2..HEAD --terminal # Stream `git show` to your terminal
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
`show` accepts every form `git show` understands (single commit, range, tag, branch tip, multiple SHAs) and is strictly opt-in — `diffing <sha>` keeps its current `git diff <sha>` semantics so existing muscle memory and scripts are unaffected.
|
|
747
|
-
|
|
748
|
-
---
|
|
749
|
-
|
|
750
|
-
## Integration & Configuration
|
|
751
|
-
|
|
752
|
-
- **Persistent User Settings** — Settings saved to `~/.config/diffing/settings.json`, loaded on startup, synced to server via `PUT /api/settings`.
|
|
753
|
-
- **Default Review Mode** — `diffing mode web` or `diffing mode tui` changes the interactive default without affecting pipes or explicit mode flags.
|
|
754
|
-
- **Custom Host/Port** — `--host 0.0.0.0` exposes the review dashboard to the local network; `--port <port>` overrides random port selection.
|
|
755
|
-
- **`--no-open` Flag** — Prevents auto-browser opening on server start.
|
|
756
|
-
- **Git Config Alias** — Register `diffing` as `git review` via `~/.gitconfig`.
|
|
757
|
-
- **Shell Aliases** — `.zshrc`/`.bashrc` examples: `gd="diffing"`, `gds="diffing --staged"`, `gda="diffing & diffing await-review"`.
|
|
758
|
-
- **Configurable Browser & IDE** — Choose which browser to auto-open (Chrome, Firefox, Edge, Brave, or system default) and which IDE to use for file opening (VS Code, Zed, Vim, Neovim, or system default).
|
|
759
|
-
- **Graceful Shutdown** — `SIGINT`/`SIGTERM` handlers remove the server lockfile on exit.
|
|
760
|
-
|
|
761
|
-
---
|
|
762
|
-
|
|
763
|
-
## Comment XML Specification
|
|
764
|
-
|
|
765
|
-
When review comments are exported or streamed to a waiting agent, they are serialized into an optimized, self-documenting XML structure equipped with CDATA blocks:
|
|
766
|
-
|
|
767
|
-
```xml
|
|
768
|
-
<code-review-comments>
|
|
769
|
-
<instructions>
|
|
770
|
-
You are an AI coding assistant receiving a structured list of code review comments to address.
|
|
771
|
-
For each file, review the inline comments and apply the changes requested.
|
|
772
|
-
- 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).
|
|
773
|
-
- When line="A-B", the range is INCLUSIVE on that side.
|
|
774
|
-
- "side" indicates whether the comment is on "additions" (new code) or "deletions" (old code).
|
|
775
|
-
- "status" indicates whether the comment is "open" or "resolved". Only address "open" comments.
|
|
776
|
-
- 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.
|
|
777
|
-
- The <code> block contains the code context at the reviewed lines.
|
|
778
|
-
- The <body> tag contains the review feedback or request.
|
|
779
|
-
|
|
780
|
-
HOW TO REPLY OR MARK AS RESOLVED:
|
|
781
|
-
- Prefer using the diffing CLI or MCP server tools (reply_to_comment / resolve_comment).
|
|
782
|
-
- CLI: `diffing reply <id> --body "..."`
|
|
783
|
-
- CLI: `diffing resolve <id>`
|
|
784
|
-
</instructions>
|
|
785
|
-
|
|
786
|
-
<!-- [Optional] High-Level General Review Comment -->
|
|
787
|
-
<general-comment>
|
|
788
|
-
<![CDATA[Please refactor the parsing module to improve reliability.]]>
|
|
789
|
-
</general-comment>
|
|
790
|
-
|
|
791
|
-
<file path="src/utils/parser.ts">
|
|
792
|
-
<!-- [Example A] Multi-Line Selection Addition Comment -->
|
|
793
|
-
<comment id="c1" line="42-45" side="additions" status="open" severity="blocking" created-at="2026-05-24T22:00:00.000Z">
|
|
794
|
-
<code><![CDATA[
|
|
795
|
-
+ const parsedToken = tokenize(input);
|
|
796
|
-
+ if (parsedToken.type === 'EOF') {
|
|
797
|
-
+ return null;
|
|
798
|
-
+ }
|
|
799
|
-
]]></code>
|
|
800
|
-
<body><![CDATA[Refactor this tokenization block to check for undefined inputs as well.]]></body>
|
|
801
|
-
<replies>
|
|
802
|
-
<reply id="r1" created-at="2026-05-24T22:05:00.000Z" role="agent" model="claude-3-5-sonnet">
|
|
803
|
-
<![CDATA[I agree, I will add a guard clause for undefined.]]>
|
|
804
|
-
</reply>
|
|
805
|
-
</replies>
|
|
806
|
-
</comment>
|
|
807
|
-
|
|
808
|
-
<!-- [Example B] Whole-File General Comment -->
|
|
809
|
-
<comment id="c2" line="file" side="additions" status="open" severity="nit" created-at="2026-05-24T22:08:00.000Z">
|
|
810
|
-
<body><![CDATA[This parser module needs additional unit tests to cover negative bounds.]]></body>
|
|
811
|
-
</comment>
|
|
812
|
-
</file>
|
|
813
|
-
</code-review-comments>
|
|
814
|
-
```
|
|
815
|
-
|
|
816
|
-
---
|
|
817
|
-
|
|
818
|
-
## Security
|
|
819
|
-
|
|
820
|
-
- **Path Traversal Prevention** — All file operations validate paths against the repository root, rejecting `..`, null bytes, absolute paths, and URL-encoded bypass attempts.
|
|
821
|
-
- **403 Forbidden Responses** — File operations (`open-file`, `save-file`, `revert-hunk`, `hunk-history`) reject paths outside the repo root.
|
|
822
|
-
- **Attachment Isolation** — Uploaded attachments are restricted to `~/.diffing/<repo>/attachments/`.
|
|
823
|
-
- **Client Directory Isolation** — Static file serving resolves against the client directory and rejects paths outside it.
|
|
824
|
-
- **XSS Prevention** — HTML is escaped before markdown rendering; `marked` is used for safe HTML generation.
|
|
825
|
-
- **Repo Path Verification** — `repo_path.txt` is written to storage directories for cross-checking.
|
|
826
|
-
|
|
827
|
-
---
|
|
828
|
-
|
|
829
|
-
## Deep-Dive Documentation
|
|
830
|
-
|
|
831
|
-
For advanced features, internal API endpoints, sequence specifications, and configuration parameters, explore the complete guide:
|
|
832
|
-
|
|
833
|
-
> [!IMPORTANT]
|
|
834
|
-
> Read the [CLI & Protocol Reference Manual](docs/cli.md) for detailed descriptions of:
|
|
835
|
-
> - TTY auto-detection and output modes (web / terminal / TUI).
|
|
836
|
-
> - Port-agnostic discovery lockfile (`server.json`) and modes (`web` | `tui` | `gh-pr`).
|
|
837
|
-
> - Full agent CLI surface: `await-review`, `comments`, `reply` / `resolve` / `unresolve`, `comment edit|delete`, `progress`, `plan …`, `gh …`, `inspect`, `doctor`, `completion`, `mcp`.
|
|
838
|
-
> - Complete MCP tool table (session, bounded diff, comment lifecycle, progress, plan).
|
|
839
|
-
> - Monotonic `round` handoff, plan-review XML, and comment XML schemas.
|
|
840
|
-
> - Web API endpoints (`/api/review/await`, `/api/comments`, `/api/plans`, `/api/agent/progress`, …).
|
|
841
|
-
> - Agent guidance: root [`Agents.md`](Agents.md) and installable skills under `skills/`.
|
|
842
|
-
|
|
843
|
-
Changelog for the latest release: [`CHANGELOG.md`](CHANGELOG.md).
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
---
|
|
99
|
+
- **npm:** https://www.npmjs.com/package/diffing
|
|
100
|
+
- **GitHub:** https://github.com/ahmedragab20/diffing
|
|
101
|
+
- **Docs:** https://ahmedragab20.github.io/diffing/
|
|
847
102
|
|
|
848
103
|
## License
|
|
849
104
|
|
|
850
|
-
MIT
|
|
105
|
+
MIT · [github.com/ahmedragab20/diffing](https://github.com/ahmedragab20/diffing)
|