diffing 0.6.0 → 0.7.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.
Files changed (196) hide show
  1. package/README.md +138 -100
  2. package/dist/apply-suggestion-BAuyCYk6.mjs +54 -0
  3. package/dist/cli-agent-BkkRbKqq.mjs +513 -0
  4. package/dist/cli-agent-BlMtx1Tx.mjs +736 -0
  5. package/dist/cli-agent-C4Fb90GL.mjs +728 -0
  6. package/dist/cli-agent-ChALuNbw.mjs +841 -0
  7. package/dist/cli-agent-D71pq2ep.mjs +841 -0
  8. package/dist/cli-agent-qBT8clNM.mjs +841 -0
  9. package/dist/cli-gh-6qiblgj7.mjs +150 -0
  10. package/dist/cli-gh-D5OCnjNe.mjs +150 -0
  11. package/dist/cli-gh-DgqscIkg.mjs +147 -0
  12. package/dist/cli-gh-KjPnyST6.mjs +150 -0
  13. package/dist/cli.mjs +38 -66
  14. package/dist/client/assets/{angular-html-BotC7B4-.js → angular-html-Dh86jUvr.js} +1 -1
  15. package/dist/client/assets/{angular-ts-DQTHeTJm.js → angular-ts-Bh4wRJtT.js} +1 -1
  16. package/dist/client/assets/{apl-Bwz5Dpd_.js → apl-BSXBHduT.js} +1 -1
  17. package/dist/client/assets/{arc-D-TSgv-7.js → arc-CRQlhBrV.js} +1 -1
  18. package/dist/client/assets/{architectureDiagram-3BPJPVTR-DLe25t8t.js → architectureDiagram-3BPJPVTR-BXq3UvEv.js} +1 -1
  19. package/dist/client/assets/{astro-DjkoD2fR.js → astro-Bh00klUw.js} +1 -1
  20. package/dist/client/assets/{blade-Cap2uJIA.js → blade-CisA3zhm.js} +1 -1
  21. package/dist/client/assets/{blockDiagram-GPEHLZMM-B-bihLYO.js → blockDiagram-GPEHLZMM-Bw-PTAJr.js} +1 -1
  22. package/dist/client/assets/{c-C7JoAATL.js → c-D-pHVWrf.js} +1 -1
  23. package/dist/client/assets/{c4Diagram-AAUBKEIU-CoCcjXEC.js → c4Diagram-AAUBKEIU-C0XyiqC_.js} +1 -1
  24. package/dist/client/assets/channel-CDxgOu-3.js +1 -0
  25. package/dist/client/assets/{chunk-2J33WTMH-Sm_uQrGq.js → chunk-2J33WTMH-DekjZXNj.js} +1 -1
  26. package/dist/client/assets/{chunk-3OPIFGDE-Ct83Sp4P.js → chunk-3OPIFGDE-BtROpcL8.js} +1 -1
  27. package/dist/client/assets/{chunk-4BX2VUAB-DrqChk1a.js → chunk-4BX2VUAB-C92XLTlx.js} +1 -1
  28. package/dist/client/assets/{chunk-55IACEB6-CodeFb9E.js → chunk-55IACEB6-CceUgh8N.js} +1 -1
  29. package/dist/client/assets/{chunk-5ZQYHXKU-CpEx4dmS.js → chunk-5ZQYHXKU-DSbYPAe7.js} +1 -1
  30. package/dist/client/assets/{chunk-727SXJPM-D3U6TUmk.js → chunk-727SXJPM-DVzUJa-9.js} +1 -1
  31. package/dist/client/assets/{chunk-AQP2D5EJ-Dr-_DyBy.js → chunk-AQP2D5EJ-6n3Z_IFa.js} +1 -1
  32. package/dist/client/assets/{chunk-BSJP7CBP-Bnyml8mU.js → chunk-BSJP7CBP-BgVLnkxr.js} +1 -1
  33. package/dist/client/assets/{chunk-CSCIHK7Q-BJSFGTlk.js → chunk-CSCIHK7Q-CkGMXntp.js} +1 -1
  34. package/dist/client/assets/{chunk-FMBD7UC4-BqiwDIwx.js → chunk-FMBD7UC4-BM8lrLBo.js} +1 -1
  35. package/dist/client/assets/{chunk-KSCS5N6A-D-H-HBRn.js → chunk-KSCS5N6A-Bm2pjMQg.js} +1 -1
  36. package/dist/client/assets/{chunk-L5ZTLDWV-CVMSAF7h.js → chunk-L5ZTLDWV-VL17ikXM.js} +1 -1
  37. package/dist/client/assets/{chunk-LZXEDZCA-BQsF6HF3.js → chunk-LZXEDZCA-B629g67M.js} +2 -2
  38. package/dist/client/assets/{chunk-ND2GUHAM-eoM20ySO.js → chunk-ND2GUHAM-CjZGwhKA.js} +1 -1
  39. package/dist/client/assets/{chunk-NZK2D7GU-B1iU0i4a.js → chunk-NZK2D7GU-DGsLjESY.js} +1 -1
  40. package/dist/client/assets/{chunk-O5CBEL6O-CcIPuHUC.js → chunk-O5CBEL6O-EyUrGY3l.js} +1 -1
  41. package/dist/client/assets/chunk-QZHKN3VN-DJCeMpP8.js +1 -0
  42. package/dist/client/assets/chunk-WU5MYG2G-BbuOkMaH.js +1 -0
  43. package/dist/client/assets/{chunk-XPW4576I-jSj3E63-.js → chunk-XPW4576I-C2TeAQmQ.js} +1 -1
  44. package/dist/client/assets/classDiagram-4FO5ZUOK-D5oJbiED.js +1 -0
  45. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-5MJt5ZxQ.js +1 -0
  46. package/dist/client/assets/{cobol-DkiK_msx.js → cobol-DsRZMP16.js} +1 -1
  47. package/dist/client/assets/{coffee-f7z4wIqP.js → coffee-DP0-MMsE.js} +1 -1
  48. package/dist/client/assets/{cose-bilkent-S5V4N54A-Dikk-RXu.js → cose-bilkent-S5V4N54A-DMmK0b0W.js} +1 -1
  49. package/dist/client/assets/{cpp-DB_FV8ps.js → cpp-B6XYbbze.js} +1 -1
  50. package/dist/client/assets/{crystal-BRBnyZFz.js → crystal-dBLPFLMp.js} +1 -1
  51. package/dist/client/assets/{css-GpNBLqRF.js → css-tgwuSZL0.js} +1 -1
  52. package/dist/client/assets/{dagre-BM42HDAG-tErJNBcm.js → dagre-BM42HDAG-CgNkf0TR.js} +1 -1
  53. package/dist/client/assets/{diagram-2AECGRRQ-D0-DgitC.js → diagram-2AECGRRQ-ocAqn0LV.js} +1 -1
  54. package/dist/client/assets/{diagram-5GNKFQAL-DqMjQTtW.js → diagram-5GNKFQAL-CB1Yo4Gc.js} +1 -1
  55. package/dist/client/assets/{diagram-KO2AKTUF-CP7V9tqS.js → diagram-KO2AKTUF-B2vpMBRT.js} +1 -1
  56. package/dist/client/assets/{diagram-LMA3HP47-tCGdsz4p.js → diagram-LMA3HP47-DuxZOaQS.js} +1 -1
  57. package/dist/client/assets/{diagram-OG6HWLK6-DtDnaqso.js → diagram-OG6HWLK6-CkShDmcv.js} +1 -1
  58. package/dist/client/assets/{dist-B5Eb-OKZ.js → dist-BgZIvk5w.js} +1 -1
  59. package/dist/client/assets/{edge-DqnWvViE.js → edge-Bokubn8E.js} +1 -1
  60. package/dist/client/assets/{elixir-BSuxOIIa.js → elixir-BEzcf3Xg.js} +1 -1
  61. package/dist/client/assets/{elm-B6U1Is0L.js → elm-vJyLTAER.js} +1 -1
  62. package/dist/client/assets/{erDiagram-TEJ5UH35-C5S0U2x3.js → erDiagram-TEJ5UH35-BFV1NQAH.js} +1 -1
  63. package/dist/client/assets/{erb-kK3QM18H.js → erb-DDkAmjBS.js} +1 -1
  64. package/dist/client/assets/{flowDiagram-I6XJVG4X-NNqmBYk2.js → flowDiagram-I6XJVG4X-DU8xbFdO.js} +1 -1
  65. package/dist/client/assets/{ganttDiagram-6RSMTGT7-8ng09X8S.js → ganttDiagram-6RSMTGT7-DCb7Qh0c.js} +1 -1
  66. package/dist/client/assets/{git-rebase-BDKTWtxr.js → git-rebase-DWcifAdK.js} +1 -1
  67. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-D_HBvwVl.js → gitGraphDiagram-PVQCEYII-C_Tw-piE.js} +1 -1
  68. package/dist/client/assets/{glimmer-js-BthGlRra.js → glimmer-js--HDru5ys.js} +1 -1
  69. package/dist/client/assets/{glimmer-ts-CS8Z9z2h.js → glimmer-ts-DAdXisHh.js} +1 -1
  70. package/dist/client/assets/{glsl-C5ERhU2v.js → glsl-CmIRlJht.js} +1 -1
  71. package/dist/client/assets/{graphql-sfgTqbIp.js → graphql-tx4-7I3U.js} +1 -1
  72. package/dist/client/assets/{hack-EeOmOf4N.js → hack-yA0XjhF7.js} +1 -1
  73. package/dist/client/assets/{haml-DVf5-Ndq.js → haml-BR5MUE1b.js} +1 -1
  74. package/dist/client/assets/{handlebars-BSLgW49o.js → handlebars-BPOF7iOf.js} +1 -1
  75. package/dist/client/assets/{html-DoOSf-hz.js → html-BbteRk96.js} +1 -1
  76. package/dist/client/assets/{html-derivative-BM0DLd1Z.js → html-derivative-59NNrcMm.js} +1 -1
  77. package/dist/client/assets/{http-d2p18QI6.js → http-D3odGQI4.js} +1 -1
  78. package/dist/client/assets/{hurl-CH2I2f66.js → hurl-BLTj8fPj.js} +1 -1
  79. package/dist/client/assets/index-BZcKS8Sb.css +1 -0
  80. package/dist/client/assets/{index-CJI1E0bV.js → index-DHXpO7eS.js} +137 -104
  81. package/dist/client/assets/{infoDiagram-5YYISTIA-Cgg2FsCN.js → infoDiagram-5YYISTIA-CI6hJyRl.js} +1 -1
  82. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-pYRQFecr.js → ishikawaDiagram-YF4QCWOH-gMS1P1LQ.js} +1 -1
  83. package/dist/client/assets/{java-BFiqhlWm.js → java-CsViuzs_.js} +1 -1
  84. package/dist/client/assets/{javascript-YWa7zRPZ.js → javascript-DQgsl2Dh.js} +1 -1
  85. package/dist/client/assets/{jinja-h_UdmDAn.js → jinja-DQNp2NUA.js} +1 -1
  86. package/dist/client/assets/{jison-cOvcjPYz.js → jison-CDDOZQdc.js} +1 -1
  87. package/dist/client/assets/{journeyDiagram-JHISSGLW-D3EBlW7m.js → journeyDiagram-JHISSGLW-BTQ_Ws_h.js} +1 -1
  88. package/dist/client/assets/{json-DT0GjoRi.js → json-DP4TqCuE.js} +1 -1
  89. package/dist/client/assets/{jsx-BaYjgZVH.js → jsx-Df5hn0Tf.js} +1 -1
  90. package/dist/client/assets/{julia-Cg36ySxC.js → julia--u33yGLi.js} +1 -1
  91. package/dist/client/assets/{just-KYC4U1y4.js → just-BCpMmSOD.js} +1 -1
  92. package/dist/client/assets/{kanban-definition-UN3LZRKU-DA42mt4M.js → kanban-definition-UN3LZRKU-CvqGbLR_.js} +1 -1
  93. package/dist/client/assets/{latex-DpuXxlsH.js → latex-D8D4jZGw.js} +1 -1
  94. package/dist/client/assets/{line-D91vf_Yl.js → line-DBgaS_RW.js} +1 -1
  95. package/dist/client/assets/{linear-CL7WzrL5.js → linear-RQVzKNVU.js} +1 -1
  96. package/dist/client/assets/{liquid-Dua3sjBU.js → liquid-CkH85f12.js} +1 -1
  97. package/dist/client/assets/{lua-CpDMEbOh.js → lua-iKoV7WE3.js} +1 -1
  98. package/dist/client/assets/{marko-rM0rxrJ5.js → marko-N8ScQSqT.js} +1 -1
  99. package/dist/client/assets/{mdc-D-E4W6ne.js → mdc-BvHTOxsp.js} +1 -1
  100. package/dist/client/assets/{mermaid-parser.core-BLQDdrsf.js → mermaid-parser.core-CwDRwMR7.js} +1 -1
  101. package/dist/client/assets/{mermaid.core-BBR2Otc_.js → mermaid.core-D2LDJgXO.js} +3 -3
  102. package/dist/client/assets/{mindmap-definition-RKZ34NQL-DMrApv-_.js → mindmap-definition-RKZ34NQL-FRnPh642.js} +1 -1
  103. package/dist/client/assets/{nginx-wZWgcQLM.js → nginx-DGgvASuI.js} +1 -1
  104. package/dist/client/assets/{nim-Bh7OZsZh.js → nim-D-v9hzvR.js} +1 -1
  105. package/dist/client/assets/{perl-DtEqNC_V.js → perl-CG8leJ8K.js} +1 -1
  106. package/dist/client/assets/{php-DX7bHce8.js → php-DvkeSP10.js} +1 -1
  107. package/dist/client/assets/{pieDiagram-4H26LBE5-B2f9_PO6.js → pieDiagram-4H26LBE5-CepOg38Y.js} +1 -1
  108. package/dist/client/assets/{pug-r67inScB.js → pug-B4T7-xaL.js} +1 -1
  109. package/dist/client/assets/{qml-f1bOqUwX.js → qml-BE6D5Bxn.js} +1 -1
  110. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DgdKno5G.js → quadrantDiagram-W4KKPZXB-DOFAsP60.js} +1 -1
  111. package/dist/client/assets/{r-Cpm-_vkr.js → r-BKZg9Mcq.js} +1 -1
  112. package/dist/client/assets/{razor-CEymfLfo.js → razor-D-02oaxL.js} +1 -1
  113. package/dist/client/assets/{regexp-DCnAJwuE.js → regexp-BDFvAR1k.js} +1 -1
  114. package/dist/client/assets/{requirementDiagram-4Y6WPE33-BIRl56-J.js → requirementDiagram-4Y6WPE33-BBVNH-2W.js} +1 -1
  115. package/dist/client/assets/review-export-D5iIl46_.js +7 -0
  116. package/dist/client/assets/{rst-Cm1M2uc8.js → rst-BcT26OSj.js} +1 -1
  117. package/dist/client/assets/{ruby-B49kkGT0.js → ruby-Cq_YQvFT.js} +1 -1
  118. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-7XZZmV9N.js → sankeyDiagram-5OEKKPKP-BQfCTbBX.js} +1 -1
  119. package/dist/client/assets/{sas-BOXC9Iq4.js → sas-DN9oTxKY.js} +1 -1
  120. package/dist/client/assets/{scss-DU2HGWZP.js → scss-BK_sp3z2.js} +1 -1
  121. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CtIjo3i9.js → sequenceDiagram-3UESZ5HK-CKAW2eyx.js} +1 -1
  122. package/dist/client/assets/{shellscript-YFjx1NBH.js → shellscript-CvNpOu0J.js} +1 -1
  123. package/dist/client/assets/{shellsession-4zfyiKm-.js → shellsession-8-yj2cJj.js} +1 -1
  124. package/dist/client/assets/{soy-CRExh-ql.js → soy-C6Q9atPF.js} +1 -1
  125. package/dist/client/assets/{sql-2Iw6Ta1F.js → sql-CBL3BuHb.js} +1 -1
  126. package/dist/client/assets/{src-Dn3_YOHM.js → src-D-VUWIK5.js} +1 -1
  127. package/dist/client/assets/{stata-DflAcpzB.js → stata-B2Q7Vqzu.js} +1 -1
  128. package/dist/client/assets/{stateDiagram-AJRCARHV-D_w9F0BN.js → stateDiagram-AJRCARHV-BGJiv0qO.js} +1 -1
  129. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CdUgMghp.js +1 -0
  130. package/dist/client/assets/{surrealql-CMprrxj1.js → surrealql-C-A2N8vk.js} +1 -1
  131. package/dist/client/assets/{svelte-Bb_Bxt4a.js → svelte-VAut_-uy.js} +1 -1
  132. package/dist/client/assets/{templ-MJ_5gYAf.js → templ-mUetM--K.js} +1 -1
  133. package/dist/client/assets/{tex-BQ33E56K.js → tex-BT53mWGp.js} +1 -1
  134. package/dist/client/assets/{timeline-definition-PNZ67QCA-BzgsTjf8.js → timeline-definition-PNZ67QCA-lVwMt1rk.js} +1 -1
  135. package/dist/client/assets/{ts-tags-Cddttr6f.js → ts-tags-VkIOkgLN.js} +1 -1
  136. package/dist/client/assets/{tsx-BFchi_eS.js → tsx-D_aaGHTf.js} +1 -1
  137. package/dist/client/assets/{twig-CA8ssIYI.js → twig-CufwqKkk.js} +1 -1
  138. package/dist/client/assets/{typescript-tdiTR9sY.js → typescript-osFD2CEV.js} +1 -1
  139. package/dist/client/assets/{vennDiagram-CIIHVFJN-CMjPo4Qf.js → vennDiagram-CIIHVFJN-_K9NtpA5.js} +1 -1
  140. package/dist/client/assets/{vue-BbZNP0Rd.js → vue-Bub1rXmL.js} +1 -1
  141. package/dist/client/assets/{vue-html-02g5ipYx.js → vue-html-CN3x2pYg.js} +1 -1
  142. package/dist/client/assets/{vue-vine-9lCbaeLR.js → vue-vine-C0csYkGm.js} +1 -1
  143. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Cy6qwCgU.js → wardleyDiagram-YWT4CUSO-B2jTMfra.js} +1 -1
  144. package/dist/client/assets/{xml-BPPCB2P8.js → xml-my6OjeGb.js} +1 -1
  145. package/dist/client/assets/{xsl-1-u1Beet.js → xsl-Bx0YVn26.js} +1 -1
  146. package/dist/client/assets/{xychartDiagram-2RQKCTM6-q9ysdRiS.js → xychartDiagram-2RQKCTM6-DfZ4YYXU.js} +1 -1
  147. package/dist/client/assets/{yaml-79W-bav7.js → yaml-DanwOypk.js} +1 -1
  148. package/dist/client/favicon.svg +40 -0
  149. package/dist/client/index.html +7 -3
  150. package/dist/comment-format-B5AcGcR-.mjs +118 -0
  151. package/dist/comment-format-CKTt0fzi.mjs +113 -0
  152. package/dist/comment-format-DG_PAehC.mjs +117 -0
  153. package/dist/completions-ZSKYvW06.mjs +126 -0
  154. package/dist/diff-fingerprint-CWa-soYD.mjs +78 -0
  155. package/dist/doctor-q6oA64hm.mjs +195 -0
  156. package/dist/find-tui-binary-CRpbYXLC.mjs +52 -0
  157. package/dist/git-Czo96ymM.mjs +789 -0
  158. package/dist/git-DaP_1rVy.mjs +2 -0
  159. package/dist/github-C9GLNak7.mjs +2 -0
  160. package/dist/github-HfIlIS-J.mjs +525 -0
  161. package/dist/mcp-7eXATtez.mjs +1334 -0
  162. package/dist/mcp-BBk8AIO4.mjs +1334 -0
  163. package/dist/mcp-BJxrW9dS.mjs +1334 -0
  164. package/dist/mcp-BgZO-iXI.mjs +1047 -0
  165. package/dist/mcp-BhT5GgYF.mjs +1334 -0
  166. package/dist/mcp-BsGdNA88.mjs +1334 -0
  167. package/dist/mcp-BxBm3d5l.mjs +1047 -0
  168. package/dist/mcp-Ca9QAlJ0.mjs +1334 -0
  169. package/dist/mcp-CphIUJUg.mjs +1047 -0
  170. package/dist/mcp-eor39qmD.mjs +1352 -0
  171. package/dist/plan-format-BQyx--mp.mjs +144 -0
  172. package/dist/plan-format-Bi46QS0m.mjs +132 -0
  173. package/dist/review-export-BoV0884M.mjs +66 -0
  174. package/dist/review-export-CKTI5Od_.mjs +66 -0
  175. package/dist/review-export-DjxKBeIZ.mjs +66 -0
  176. package/dist/server-AisDKkpW.mjs +3227 -0
  177. package/dist/server-BUsRhL1B.mjs +3283 -0
  178. package/dist/server-BZBFquG8.mjs +3875 -0
  179. package/dist/server-Bc2m9R5-.mjs +3263 -0
  180. package/dist/server-Bmt57wV5.mjs +3875 -0
  181. package/dist/server-C105rwQw.mjs +3283 -0
  182. package/dist/server-D0Ni8PKP.mjs +3252 -0
  183. package/dist/server-D2xEbakj.mjs +3874 -0
  184. package/dist/server-TOElOuNP.mjs +3258 -0
  185. package/dist/server-lock-DaSx7DjW.mjs +1049 -0
  186. package/dist/server-lock-uqSdDYeR.mjs +153 -0
  187. package/dist/settings-BVnzGFL7.mjs +478 -0
  188. package/dist/update-check-fe0tR8tx.mjs +129 -0
  189. package/package.json +1 -1
  190. package/dist/client/assets/channel-h7e2aSOW.js +0 -1
  191. package/dist/client/assets/chunk-QZHKN3VN-HzjMGBiA.js +0 -1
  192. package/dist/client/assets/chunk-WU5MYG2G-D_yZ0nqc.js +0 -1
  193. package/dist/client/assets/classDiagram-4FO5ZUOK-eToeXGJV.js +0 -1
  194. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-D_EfzX89.js +0 -1
  195. package/dist/client/assets/index-Ct9zZxJ5.css +0 -1
  196. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Brvg0TWH.js +0 -1
package/README.md CHANGED
@@ -1,9 +1,13 @@
1
1
  # diffing
2
2
 
3
- 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.
3
+ <p align="center">
4
+ <img src="public/favicon.svg" alt="diffing brand icon" width="72" height="72" />
5
+ </p>
4
6
 
5
- <img width="1667" height="1087" alt="image" src="https://github.com/user-attachments/assets/52dcd2af-fc85-44ba-a679-4609e667c6f4" />
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.
6
8
 
9
+ <img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/c1e12c28-610e-4d68-abb1-3c8dde58560e" />
10
+ <img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/95a51403-3bce-453c-a831-43a2834c5ed7" />
7
11
 
8
12
  ---
9
13
 
@@ -27,10 +31,11 @@ Prefer the terminal? Add `--tui` for a native-Rust terminal UI — same review f
27
31
  diffing --tui
28
32
  ```
29
33
  > [!WARNING]
30
- > The TUI is **experimental** in v0.3.0. The interface, keymap, and
31
- > `server.json` (`mode: "tui"`) on-disk format may change in a minor
32
- > release. The web UI is the supported path for production workflows.
33
- > See [Native Terminal UI (TUI)](#native-terminal-ui-tui) for the full feature set, keymap, and stability notes.
34
+ > The TUI is **experimental**. The interface, keymap, and `server.json`
35
+ > (`mode: "tui"`) on-disk format may change in a minor release. The web UI is
36
+ > the supported path for production workflows. See
37
+ > [Native Terminal UI (TUI)](#native-terminal-ui-tui) for the full feature set,
38
+ > keymap, and stability notes.
34
39
 
35
40
  ### 3. Update
36
41
  Check if a new version is available on npm and upgrade instantly via the CLI:
@@ -44,16 +49,18 @@ diffing update
44
49
 
45
50
  A local Hono-powered review server delivers a full-featured GitHub-like code review interface directly in your browser.
46
51
 
47
- - **Split / Unified View** — Toggle between side-by-side (`split`) and inline (`unified`) diff layouts via toolbar or keyboard shortcut `m`.
52
+ - **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.
53
+ - **Compact toolbar** — Repo + branch, quiet summary chips (files, `+X/−Y`, open comments), Search (`⌘K`), Plans badge, Resolve all, Settings, and **Send review**.
48
54
  - **Syntax Highlighting** — Powered by Shiki via `@pierre/diffs`, with high-fidelity highlighting for 200+ languages.
49
- - **Interactive File Tree** — Hierarchical file navigation sidebar with collapsible folders, viewed/unviewed tracking, and change-type indicators (added, modified, deleted).
50
- - **Status Dashboard (Comment Tracker)** — Bottom panel tracking open, replied, and resolved comments with filter tabs and click-to-navigate references to the relevant file and line.
51
- - **Git Diff Stats** — Toolbar displays repo name, branch, file count, and additions/deletions (`+X/-Y`) computed from the patch.
52
- - **Server-Side State & Drafts Persistence** — No browser storage is used. All settings, UI panels sizing, session states, and comment drafts are securely stored and persisted server-side in the project's global `.diffing` directory (and global settings inside `~/.config/diffing/settings.json`).
53
- - **Dynamic Font Customization** — Pick any [Google Fonts](https://fonts.google.com/) family or locally-installed system font for both UI typography and monospace code rendering, configurable via the settings font picker. Google-hosted families are fetched automatically as web fonts and render everywhere; local fonts are applied by name (see the [note on custom fonts](#a-note-on-custom-fonts)).
54
- - **Resizable Panels** — Drag-to-resize sidebar (240px–640px) and comment tracker panel (100px–600px). Panel states are instantly saved server-side for absolute consistency across browser sessions.
55
- - **Skeleton Loading Screen** — Full shimmer placeholder UI for toolbar, sidebar, search, tree nodes, and file diffs during initial load.
56
- - **Image Diff Previews** — Visual side-by-side comparison for added, changed, and deleted image files (PNG, JPEG, GIF, WebP, SVG, BMP, ICO, AVIF).
55
+ - **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.
56
+ - **Icon file-header actions** — Expand context, open in editor, file-level comment, and Viewed with tooltips; less chrome noise per card.
57
+ - **Status Dashboard (Comment Tracker)** — Bottom panel tracking open, replied, and resolved comments with severity filters and click-to-navigate.
58
+ - **Multi-round review** — Round history popover, “changed since last send” chips, and outdated-comment detection.
59
+ - **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`).
60
+ - **Dynamic Font Customization** — Google Fonts or local system fonts for UI + mono (see [custom fonts](#a-note-on-custom-fonts)).
61
+ - **Resizable Panels** — Drag-to-resize sidebar (240px–640px) and comment tracker (100px–600px); sizes persisted server-side.
62
+ - **Skeleton Loading Screen** — Full shimmer placeholder UI during initial load.
63
+ - **Image Diff Previews** — Side-by-side comparison for common image formats.
57
64
 
58
65
  ---
59
66
 
@@ -79,7 +86,8 @@ A local Hono-powered review server delivers a full-featured GitHub-like code rev
79
86
  - **Instant Switching** — CSS transitions suppressed during theme changes for a snappy, lag-free experience.
80
87
  - **Persistent Setting** — Theme choice saved to `~/.config/diffing/settings.json` and restored on next launch.
81
88
 
82
- <img width="1667" height="1087" alt="image" src="https://github.com/user-attachments/assets/6e4a4552-fef2-4002-8b8f-b544c95c4c26" />
89
+
90
+ <img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/eaa0675c-21d6-4754-8fbd-97ee63a743dc" />
83
91
 
84
92
 
85
93
 
@@ -99,8 +107,7 @@ Blazing-fast, native fuzzy code search integrated directly into the sidebar sear
99
107
  - **Graceful Degradation** — If the native Rust binary is unavailable, search reports as unavailable without crashing the server.
100
108
  - **Auto-Indexing** — The Rust engine maintains its own file system watcher for real-time index updates as the working tree changes.
101
109
 
102
- <img width="1840" height="1196" alt="image" src="https://github.com/user-attachments/assets/0830b770-3c7f-44a1-b8ff-a70b2b34144a" />
103
-
110
+ <img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/2b2bc001-2d3a-4744-b9d5-a23642f1afba" />
104
111
 
105
112
  ---
106
113
 
@@ -115,7 +122,7 @@ Full keyboard-driven navigation with vim-like motions and a modal status bar:
115
122
  | `Ctrl+d` / `Ctrl+u` | Scroll half-page down/up |
116
123
  | `g` `g` | Jump to top of diff |
117
124
  | `G` | Jump to bottom of diff |
118
- | `m` | Toggle split/unified view |
125
+ | `m` | Toggle split/unified view (also Settings → Diff style) |
119
126
  | `t` | Cycle tab size (2 → 4 → 8) |
120
127
  | `w` | Toggle line wrap |
121
128
  | `n` | Toggle line numbers |
@@ -135,11 +142,21 @@ Full keyboard-driven navigation with vim-like motions and a modal status bar:
135
142
  | `g` `t` | Open theme picker |
136
143
  | `Cmd/Ctrl+K` | Open global command palette |
137
144
  | `Cmd/Ctrl+,` | Toggle settings panel |
138
- | `?` | Show shortcuts help modal |
145
+ | `?` / `⌘?` | Show shortcuts help modal |
146
+
147
+ ### Plan page extras (when reviewing a plan at `/plan`)
148
+ | Key | Action |
149
+ |-----|--------|
150
+ | `m` | Cycle Source → Read → Split |
151
+ | `z` | Toggle zen reading (switches to Read if needed); Esc also exits zen |
152
+ | `o` | Toggle Outline (left TOC) |
153
+ | `c` | Toggle Comments map (right rail) |
154
+ | `J` / `K` | Next / previous plan |
155
+ | Esc | Exit zen / dismiss Add-comment chip / close draft |
139
156
 
140
157
  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.
141
158
 
142
- <img width="1840" height="1196" alt="image" src="https://github.com/user-attachments/assets/d230d020-4fb2-475a-a8a0-0ae11bb271ff" />
159
+ <img width="1624" height="1061" alt="image" src="https://github.com/user-attachments/assets/f0971704-65a2-4512-978f-6b6e656b5dda" />
143
160
 
144
161
 
145
162
  ---
@@ -147,13 +164,13 @@ A vim-style status bar at the bottom displays the current mode (NORMAL/INSERT),
147
164
  ## Native Terminal UI (TUI) — *Experimental*
148
165
 
149
166
  > [!WARNING]
150
- > The TUI is **experimental** in v0.3.0. The interface, keymap, and on-disk
151
- > format of `server.json` (`mode: "tui"`) may change in a minor release
152
- > before stabilisation. The web UI is the supported path for production
153
- > workflows; please open an issue before depending on the TUI for CI / agent
154
- > automation. The web review flow, plan review, and PR review are unaffected.
167
+ > The TUI is **experimental**. The interface, keymap, and on-disk format of
168
+ > `server.json` (`mode: "tui"`) may change in a minor release before
169
+ > stabilisation. The web UI is the supported path for production workflows;
170
+ > please open an issue before depending on the TUI for CI / agent automation.
171
+ > The web review flow, plan review, and PR review are unaffected.
155
172
 
156
- `diffing --tui` opens an **opt-in native-Rust terminal interface** that mirrors the web review dashboard — no browser, no Electron, no port. It's a leaf renderer in a new `crates/diffing-tui/` binary: the Node CLI is still the single source of truth for arg parsing, lockfile discovery, and agent handoff, and the TUI reads the same `~/.diffing/<repo>/*` state on disk and writes a `server.json` with `mode: "tui"`.
173
+ `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.
157
174
 
158
175
  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.
159
176
 
@@ -169,15 +186,26 @@ diffing --tui -- -- src/ # Limit a TUI review to a directory
169
186
 
170
187
  **Features**
171
188
 
172
- - **Unified diff render** with a virtualised file card, syntect highlighter, and the same 8 Shiki-compatible colour themes as the web UI.
173
- - **Vim-style file tree & keymap** `j/k/gg/G/J/K/Tab/w/t/m/?/` motions, plus `c` (new comment), `e/r/x` (edit / reply / resolve), `]`/`[` (next / previous thread), `?` (help).
189
+ - **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.
190
+ - **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.
191
+ - **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.
174
192
  - **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.
175
193
  - **Multi-line `tui-textarea` form** with markdown rendering in the preview pane.
176
194
  - **Live updates** via `notify` watcher on `comments.json` and the repo working tree — write a comment in another window and it appears immediately.
177
- - **Send review & agent handoff** — verdict radios + general-comment popover with a live XML preview. Submits via the same `format_comments` envelope as the web UI, copies to clipboard (`pbcopy` / `wl-copy` / `xclip` / `xsel` / `clip.exe`), and persists `pending-review.xml`. The agent-status indicator in the status bar mirrors the web UI's "Send to agent" connection dot.
195
+ - **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.
196
+ - **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.
178
197
  - **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`).
179
198
 
180
- **Caveat** the TUI's "Send to agent" writes the review to disk + clipboard but does not actively unblock a long-polling `diffing await-review`; that requires a Node-side change in a follow-up. The web UI's send button remains the supported native handoff path. The `pending-review.xml` is still produced and the review session is still round-incremented only the long-poll wake-up is missing.
199
+ 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.
200
+
201
+ Headless examples:
202
+
203
+ ```bash
204
+ diffing inspect summary
205
+ diffing inspect files --limit 100
206
+ diffing inspect slice --file 0 --start 0 --max-lines 120 --max-bytes 262144
207
+ diffing inspect search "unsafe" --limit 25
208
+ ```
181
209
 
182
210
  **Building the binary locally**
183
211
 
@@ -259,22 +287,34 @@ Bidirectional, event-driven sync between the browser UI and connected AI agents
259
287
  The `diffing` binary acts as a port-agnostic CLI client. It automatically discovers the running server by reading a local repository lockfile:
260
288
 
261
289
  ```bash
262
- diffing await-review # Block process until you click "Send to agent"; outputs comments as XML
263
- diffing comments [--open] [--json] # One-shot query of the comments database
264
- diffing reply <id> --body "..." # Post an agent response or explanation
265
- diffing resolve <id> # Mark a comment resolved, updating the UI live
266
- diffing url # Retrieve the active server base URL
267
-
268
- # Plan review (review a markdown plan before any code is written)
269
- diffing plan submit <file> [--title T] [--model M] [--id <id>] [--wait] # Submit/resubmit a plan; prints its id
270
- diffing plan await [--timeout N] # Block until the human approves/rejects/requests-changes; outputs the verdict XML
271
- diffing plan list [--json] # List submitted plans with their verdicts
272
- diffing plan show [<id>] [--json] [--version N] # Show one plan as <plan-review> XML (latest if omitted; use --version to read a historical body)
273
- diffing plan versions <id> [--json] # List every submitted version of a plan, oldest-first (current marked with `*`)
274
- diffing plan reply <commentId> --body "..." # Reply to an inline plan comment
275
- diffing plan resolve <commentId> # Mark a plan comment resolved
290
+ # Code-review handoff
291
+ diffing await-review # Block until "Send to agent"; print comments as XML
292
+ diffing comments [--open] [--format xml|json|md]
293
+ diffing reply <id> --body "..." # Post an agent response
294
+ diffing resolve <id> # Mark resolved (UI updates live)
295
+ diffing unresolve <id> # Re-open a resolved thread
296
+ diffing comment edit <id> --body "..."
297
+ diffing comment delete <id>
298
+ diffing progress --message "…" [--pct 40] [--model M] # Live progress toast
299
+ diffing url # Active server base URL
300
+
301
+ # Plan review (before any code is written)
302
+ diffing plan submit <file> [--title T] [--model M] [--id <id>] [--wait] [--save-source]
303
+ diffing plan await [--timeout N]
304
+ diffing plan list [--json]
305
+ diffing plan show [<id>] [--json] [--version N]
306
+ diffing plan versions <id> [--json]
307
+ diffing plan reply <commentId> --body "..."
308
+ diffing plan resolve <commentId>
309
+
310
+ # DX
311
+ diffing doctor # Environment / install self-check
312
+ diffing completion <bash|zsh|fish>
313
+ diffing inspect summary|files|hunks|slice|search # Bounded reads from a TUI session
276
314
  ```
277
315
 
316
+ Full contracts (flags, exit codes, XML, HTTP): **[docs/cli.md](docs/cli.md)**.
317
+
278
318
  ### B. Model Context Protocol (MCP) Server
279
319
  If your agent supports MCP, configure `diffing` as a stdio server. The MCP is
280
320
  self-describing and can start or reuse the loopback review server, so an
@@ -309,9 +349,13 @@ Run `diffing mcp --help` for setup details. The server initialization
309
349
  instructions tell an unfamiliar model what to do next, and every tool returns
310
350
  both readable text and structured content.
311
351
 
312
- - Session: `review_session_status`, `start_review_session`
313
- - Local review: `get_diff`, `create_comment`, `await_review`, `list_comments`, `reply_to_comment`, `resolve_comment`
314
- - Plan review: `submit_plan`, `await_plan_review`, `list_plans`, `get_plan`, `get_plan_versions`, `get_plan_version`, `reply_to_plan_comment`, `resolve_plan_comment`
352
+ | Area | Tools |
353
+ |------|-------|
354
+ | Session | `review_session_status`, `start_review_session` |
355
+ | Diff inspection | `get_diff`, `diff_summary`, `diff_files`, `diff_hunks`, `diff_slice`, `diff_search` |
356
+ | 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` |
357
+ | Loop | `await_review`, `report_progress`, `get_review_history` |
358
+ | Plan | `submit_plan`, `await_plan_review`, `list_plans`, `get_plan`, `get_plan_versions`, `get_plan_version`, `reply_to_plan_comment`, `resolve_plan_comment` |
315
359
 
316
360
  Clients that expose MCP prompts can use `review_local_changes` and
317
361
  `submit_plan_for_review`; clients that expose resources can read
@@ -336,7 +380,11 @@ still interpret pasted self-describing XML. The installable `skills/` copies and
336
380
  repo-local `.agents/skills/` copies are contract-tested to remain identical.
337
381
 
338
382
  ### Send Review Popover
339
- A GitHub-style "finish your review" popover with inline editing of each comment, an optional general/overall comment, and a visual indicator when an agent is waiting. The **"Copy comments"** toolbar button serializes all comments to the XML spec and copies them to the clipboard.
383
+ A GitHub-style **Submit review** / **Send to agent** popover: pick a verdict
384
+ (Approve / Request edits / Reject / **Comment only**), optionally add an overall
385
+ note, preview every inline comment (editable/removable), and release every
386
+ waiting agent. Agent waiting state shows as a green dot on the button.
387
+ **Copy comments** serializes the thread set to the agent XML spec.
340
388
 
341
389
  ### Port-Agnostic Discovery
342
390
  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)`.
@@ -351,39 +399,29 @@ A `ReviewSession` class with a monotonic `round` counter and race-guard logic en
351
399
  Review **any agent plan** — not just code. When an AI agent produces a plan
352
400
  (an implementation outline, a design proposal, a migration strategy), `diffing`
353
401
  renders the markdown line-by-line so you can comment on specific lines or
354
- sections and **approve**, **request changes**, or **reject** it then hands the
355
- structured verdict back to the waiting agent. It's the "agent waits, human
356
- releases" handoff, applied *before* any code is written.
402
+ sections and **approve**, **request changes**, **reject**, or **comment only**
403
+ — then hands the structured verdict back to the waiting agent. It's the
404
+ "agent waits, human releases" handoff, applied *before* any code is written.
357
405
 
358
406
  ```text
359
407
  1. The agent submits a markdown plan and blocks (diffing plan submit … --wait).
360
- 2. You open the "Plans" tab, read the plan, and comment on lines/sections.
361
- 3. You click Approve / Request changes / Reject (with an optional overall note).
362
- 4. The agent wakes instantly, receives the verdict + comments as <plan-review> XML,
363
- and proceeds, revises-and-resubmits, or stops accordingly.
408
+ 2. You open Plans (/plan), read Source / Read / Split, and comment on lines/sections.
409
+ 3. You Submit review: Approve / Request changes / Reject / Comment only.
410
+ 4. The agent wakes, receives <plan-review> XML, and proceeds, revises, or stops.
364
411
  ```
365
412
 
366
- - **Renders any markdown plan** — the plan body is shown via `@pierre/diffs` with
367
- full syntax highlighting and line numbers, so it's addressable like a diff.
368
- - **Line, range & section comments** — hover the gutter `+` or select a line range
369
- to comment; each comment auto-captures its enclosing markdown heading (section)
370
- and the exact anchored text for the agent.
371
- - **General comments** — attach notes scoped to the whole plan.
372
- - **Three-way verdict** — Approve / Request changes / Reject, GitHub-style, with
373
- an optional overall comment. Resubmitting a revised plan (same id) bumps the
374
- version and re-opens it for review.
375
- - **Browse plan versions** — every submitted body is kept on disk, oldest-first.
376
- A version dropdown next to the `v{n}` chip switches the viewer to any past
377
- version; comments are filtered to those anchored to the version you're
378
- reading; a "viewing v{N} of v{M}" banner makes the historical context obvious.
379
- Available from the CLI (`diffing plan versions <id>`, `diffing plan show <id> --version N`),
380
- MCP (`get_plan_versions`, `get_plan_version`), and the HTTP API
381
- (`GET /api/plans/:id/versions`, `GET /api/plans/:id/versions/:n`).
382
- - **Live "Plans" badge** — the diff toolbar shows a badge counting plans awaiting
383
- your review, with a green dot when an agent is connected and waiting.
384
- - **Same channels everywhere** — drive it from the CLI (`diffing plan …`), the
385
- MCP tools (`submit_plan`, `await_plan_review`, …), or the HTTP API
386
- (`POST /api/plans`, `POST /api/plans/:id/decision`, `GET /api/plan-review/await`).
413
+ - **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).
414
+ - **Resizable split** drag the Source|Read divider; double-click resets 50/50.
415
+ - **Renders any markdown plan** — Source via `@pierre/diffs` (commentable lines); Read as polished markdown with outline (`o`) and comments map (`c`).
416
+ - **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.
417
+ - **Severity** optional blocking / nit / question / praise on plan comments (same labels as code review; included in `<plan-review>` handoff XML).
418
+ - **Collapsible threads** — collapse open or resolved cards; collapse the in-card source preview; delete resolved comments and replies.
419
+ - **General comments** — notes scoped to the whole plan.
420
+ - **Four-way verdict** Approve / Request changes / Reject / Comment only (no file edits). Resubmit with the same id bumps version and re-opens review.
421
+ - **Browse plan versions** — version dropdown, historical banner, comments filtered to the viewed version. CLI / MCP / HTTP as below.
422
+ - **Live "Plans" badge** — toolbar badge for plans awaiting review; green dot when an agent is waiting.
423
+ - **Same channels everywhere** CLI (`diffing plan …`), MCP (`submit_plan`, `await_plan_review`, …), HTTP (`POST /api/plans`, `POST /api/plans/:id/decision`, `GET /api/plan-review/await`).
424
+ - **Scratch outside the tree** plan sources under `~/.diffing/<repo>/plan-sources/` (`--save-source`); never commit agent plans into the consumer project.
387
425
 
388
426
  ### Plan Review XML Specification
389
427
 
@@ -400,7 +438,7 @@ self-documenting `<plan-review>` envelope:
400
438
  ## Phase 1
401
439
  …full markdown of the plan being reviewed…]]></plan-body>
402
440
  <comments>
403
- <comment id="c1" line="4" section="Phase 1" status="open" created-at="2026-05-29T18:52:29.557Z">
441
+ <comment id="c1" line="4" section="Phase 1" status="open" severity="blocking" created-at="2026-05-29T18:52:29.557Z">
404
442
  <context><![CDATA[Do the first thing]]></context>
405
443
  <body><![CDATA[Clarify what "the first thing" is.]]></body>
406
444
  <replies>
@@ -412,8 +450,6 @@ self-documenting `<plan-review>` envelope:
412
450
  </plan-review>
413
451
  ```
414
452
 
415
- <img width="1667" height="1087" alt="image" src="https://github.com/user-attachments/assets/00e884b5-4c90-4a9a-9e24-9ae57d80f3f2" />
416
-
417
453
  ---
418
454
 
419
455
  ## Reviewing a GitHub PR
@@ -494,13 +530,16 @@ coexist without colliding.
494
530
 
495
531
  Rich, real-time comment threads directly on diff lines:
496
532
 
497
- - **Inline Threads** — Hover and click the `+` button on any addition or deletion line to start a thread. Supports markdown (GFM + line breaks) with syntax-highlighted fenced code blocks.
498
- - **Multi-Line Comments** — Select a line range to comment on an entire block of code.
499
- - **File-Level Comments** — Add general comments scoped to the entire file without targeting a specific line.
500
- - **Comment Drafts** — Draft system (`diffing-draft-*` keys) with 7-day TTL, stored in the global `.diffing` folder so drafts survive page refreshes without any browser storage footprint.
501
- - **Agent Attribution** — Replies carry `role` (`user`/`agent`) and the agent's `model` name for clear attribution.
502
- - **Suggestion Application** — Parse `` ```suggestion `` code blocks from comment bodies and apply them to the file in one click via `POST /api/comments/:id/apply-suggestion`.
503
- - **Full CRUD API** — REST endpoints for creating, reading, updating, and deleting comments and replies.
533
+ - **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.
534
+ - **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"`).
535
+ - **Severity** — Optional triage labels (design-system dropdown): blocking / nit / question / praise. Stored and emitted on agent handoff XML; MCP `create_comment` accepts `severity`.
536
+ - **File-Level Comments** — Notes scoped to the entire file.
537
+ - **Comment Drafts** — Server-side drafts with TTL under `~/.diffing/` (no browser storage).
538
+ - **Agent Attribution** — Replies carry `role` (`user`/`agent`) and `model`.
539
+ - **Suggestion Application** — `` ```suggestion `` blocks (including multi-line) via **Apply suggestion** / `POST /api/comments/:id/apply-suggestion`.
540
+ - **Bulk resolve** — Toolbar **Resolve all** → `POST /api/comments/resolve-all`.
541
+ - **Agent progress** — Agents can `diffing progress` / `report_progress` for a live toast while working.
542
+ - **Full CRUD** — Create, edit, delete (including resolved plan threads), reply, unresolve — CLI, MCP, and HTTP.
504
543
 
505
544
  ---
506
545
 
@@ -628,8 +667,10 @@ When review comments are exported or streamed to a waiting agent, they are seria
628
667
  You are an AI coding assistant receiving a structured list of code review comments to address.
629
668
  For each file, review the inline comments and apply the changes requested.
630
669
  - 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).
670
+ - When line="A-B", the range is INCLUSIVE on that side.
631
671
  - "side" indicates whether the comment is on "additions" (new code) or "deletions" (old code).
632
672
  - "status" indicates whether the comment is "open" or "resolved". Only address "open" comments.
673
+ - 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.
633
674
  - The <code> block contains the code context at the reviewed lines.
634
675
  - The <body> tag contains the review feedback or request.
635
676
 
@@ -646,7 +687,7 @@ When review comments are exported or streamed to a waiting agent, they are seria
646
687
 
647
688
  <file path="src/utils/parser.ts">
648
689
  <!-- [Example A] Multi-Line Selection Addition Comment -->
649
- <comment id="c1" line="42-45" side="additions" status="open" created-at="2026-05-24T22:00:00.000Z">
690
+ <comment id="c1" line="42-45" side="additions" status="open" severity="blocking" created-at="2026-05-24T22:00:00.000Z">
650
691
  <code><![CDATA[
651
692
  + const parsedToken = tokenize(input);
652
693
  + if (parsedToken.type === 'EOF') {
@@ -662,7 +703,7 @@ When review comments are exported or streamed to a waiting agent, they are seria
662
703
  </comment>
663
704
 
664
705
  <!-- [Example B] Whole-File General Comment -->
665
- <comment id="c2" line="file" side="additions" status="open" created-at="2026-05-24T22:08:00.000Z">
706
+ <comment id="c2" line="file" side="additions" status="open" severity="nit" created-at="2026-05-24T22:08:00.000Z">
666
707
  <body><![CDATA[This parser module needs additional unit tests to cover negative bounds.]]></body>
667
708
  </comment>
668
709
  </file>
@@ -688,22 +729,19 @@ For advanced features, internal API endpoints, sequence specifications, and conf
688
729
 
689
730
  > [!IMPORTANT]
690
731
  > Read the [CLI & Protocol Reference Manual](docs/cli.md) for detailed descriptions of:
691
- > - TTY Auto-Detection and Output Mode resolution.
692
- > - The port-agnostic discovery lockfile mechanics.
693
- > - Monotonic sequence `round` synchronization for race-free polling.
694
- > - Full Web API endpoints schema (`GET /api/review/await`, `POST /api/comments`, etc.).
695
- > - Custom git config shell aliases.
696
-
697
- ---
732
+ > - TTY auto-detection and output modes (web / terminal / TUI).
733
+ > - Port-agnostic discovery lockfile (`server.json`) and modes (`web` | `tui` | `gh-pr`).
734
+ > - Full agent CLI surface: `await-review`, `comments`, `reply` / `resolve` / `unresolve`, `comment edit|delete`, `progress`, `plan …`, `gh …`, `inspect`, `doctor`, `completion`, `mcp`.
735
+ > - Complete MCP tool table (session, bounded diff, comment lifecycle, progress, plan).
736
+ > - Monotonic `round` handoff, plan-review XML, and comment XML schemas.
737
+ > - Web API endpoints (`/api/review/await`, `/api/comments`, `/api/plans`, `/api/agent/progress`, …).
738
+ > - Agent guidance: root [`Agents.md`](Agents.md) and installable skills under `skills/`.
698
739
 
699
- ## Landing Page
740
+ Changelog for the latest release: [`CHANGELOG.md`](CHANGELOG.md) (current package version **0.7.0**).
700
741
 
701
- <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" />
702
742
 
703
743
  ---
704
744
 
705
- 👉🏻 The project was intially forked from **wong2/diffx**
706
-
707
745
  ## License
708
746
 
709
747
  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 };