diffing 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/README.md +52 -18
  2. package/dist/{cli-agent-D71pq2ep.mjs → cli-agent-CLrK54k2.mjs} +2 -2
  3. package/dist/{cli-gh-D5OCnjNe.mjs → cli-gh-8YC1NzyM.mjs} +6 -1
  4. package/dist/cli.mjs +3 -3
  5. package/dist/client/assets/{angular-html-Dh86jUvr.js → angular-html-DdAR2u-k.js} +1 -1
  6. package/dist/client/assets/{angular-ts-Bh4wRJtT.js → angular-ts-Dz_vWKSu.js} +1 -1
  7. package/dist/client/assets/{apl-BSXBHduT.js → apl-BJ5QXrIk.js} +1 -1
  8. package/dist/client/assets/{arc-CRQlhBrV.js → arc-D9erSW6x.js} +1 -1
  9. package/dist/client/assets/{architectureDiagram-3BPJPVTR-BXq3UvEv.js → architectureDiagram-3BPJPVTR-CCQWZLXR.js} +1 -1
  10. package/dist/client/assets/{astro-Bh00klUw.js → astro-BQAej5a5.js} +1 -1
  11. package/dist/client/assets/{blade-CisA3zhm.js → blade-DkAmuwDx.js} +1 -1
  12. package/dist/client/assets/{blockDiagram-GPEHLZMM-Bw-PTAJr.js → blockDiagram-GPEHLZMM-vwjxNybI.js} +1 -1
  13. package/dist/client/assets/{c-D-pHVWrf.js → c-DG5p-ChJ.js} +1 -1
  14. package/dist/client/assets/{c4Diagram-AAUBKEIU-C0XyiqC_.js → c4Diagram-AAUBKEIU-DJ_hVlh4.js} +1 -1
  15. package/dist/client/assets/channel-DmZgR6r0.js +1 -0
  16. package/dist/client/assets/{chunk-2J33WTMH-DekjZXNj.js → chunk-2J33WTMH-CiLowxCo.js} +1 -1
  17. package/dist/client/assets/{chunk-3OPIFGDE-BtROpcL8.js → chunk-3OPIFGDE-H3jjMR5Y.js} +1 -1
  18. package/dist/client/assets/{chunk-4BX2VUAB-C92XLTlx.js → chunk-4BX2VUAB-Dk0dk4n5.js} +1 -1
  19. package/dist/client/assets/{chunk-55IACEB6-CceUgh8N.js → chunk-55IACEB6-nbLiUMJS.js} +1 -1
  20. package/dist/client/assets/{chunk-5ZQYHXKU-DSbYPAe7.js → chunk-5ZQYHXKU-DZ8RgHg8.js} +1 -1
  21. package/dist/client/assets/{chunk-727SXJPM-DVzUJa-9.js → chunk-727SXJPM-DDe5dqJV.js} +1 -1
  22. package/dist/client/assets/{chunk-AQP2D5EJ-6n3Z_IFa.js → chunk-AQP2D5EJ-DmpNclOr.js} +1 -1
  23. package/dist/client/assets/{chunk-BSJP7CBP-BgVLnkxr.js → chunk-BSJP7CBP-BKQKvtIj.js} +1 -1
  24. package/dist/client/assets/{chunk-CSCIHK7Q-CkGMXntp.js → chunk-CSCIHK7Q-D27t4cyv.js} +1 -1
  25. package/dist/client/assets/{chunk-FMBD7UC4-BM8lrLBo.js → chunk-FMBD7UC4-Bu3LA663.js} +1 -1
  26. package/dist/client/assets/{chunk-KSCS5N6A-Bm2pjMQg.js → chunk-KSCS5N6A-Ed5HNXRW.js} +1 -1
  27. package/dist/client/assets/{chunk-L5ZTLDWV-VL17ikXM.js → chunk-L5ZTLDWV-DLjJZgf8.js} +1 -1
  28. package/dist/client/assets/{chunk-LZXEDZCA-B629g67M.js → chunk-LZXEDZCA-B-cs89SM.js} +2 -2
  29. package/dist/client/assets/{chunk-ND2GUHAM-CjZGwhKA.js → chunk-ND2GUHAM-D_kPSuUA.js} +1 -1
  30. package/dist/client/assets/{chunk-NZK2D7GU-DGsLjESY.js → chunk-NZK2D7GU-D1u3pjq-.js} +1 -1
  31. package/dist/client/assets/{chunk-O5CBEL6O-EyUrGY3l.js → chunk-O5CBEL6O-Mt0cnPSf.js} +1 -1
  32. package/dist/client/assets/chunk-QZHKN3VN-BrYnBs7h.js +1 -0
  33. package/dist/client/assets/chunk-WU5MYG2G-CdBcsQs_.js +1 -0
  34. package/dist/client/assets/{chunk-XPW4576I-C2TeAQmQ.js → chunk-XPW4576I-Bt8a8x28.js} +1 -1
  35. package/dist/client/assets/classDiagram-4FO5ZUOK-CCpp3t5M.js +1 -0
  36. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B1aV1sYb.js +1 -0
  37. package/dist/client/assets/{cobol-DsRZMP16.js → cobol-Daidj_5Y.js} +1 -1
  38. package/dist/client/assets/{coffee-DP0-MMsE.js → coffee-DUMdB2Cr.js} +1 -1
  39. package/dist/client/assets/{cose-bilkent-S5V4N54A-DMmK0b0W.js → cose-bilkent-S5V4N54A-DVUDLXie.js} +1 -1
  40. package/dist/client/assets/{cpp-B6XYbbze.js → cpp-C2FeX1Mc.js} +1 -1
  41. package/dist/client/assets/{crystal-dBLPFLMp.js → crystal-D4yb9blJ.js} +1 -1
  42. package/dist/client/assets/{css-tgwuSZL0.js → css-B5cr0U9F.js} +1 -1
  43. package/dist/client/assets/{dagre-BM42HDAG-CgNkf0TR.js → dagre-BM42HDAG-DdZWb-Ee.js} +1 -1
  44. package/dist/client/assets/{diagram-2AECGRRQ-ocAqn0LV.js → diagram-2AECGRRQ-C9DOZt92.js} +1 -1
  45. package/dist/client/assets/{diagram-5GNKFQAL-CB1Yo4Gc.js → diagram-5GNKFQAL-Bbc07UKr.js} +1 -1
  46. package/dist/client/assets/{diagram-KO2AKTUF-B2vpMBRT.js → diagram-KO2AKTUF-C-lUzY3m.js} +1 -1
  47. package/dist/client/assets/{diagram-LMA3HP47-DuxZOaQS.js → diagram-LMA3HP47-D-OjEFhp.js} +1 -1
  48. package/dist/client/assets/{diagram-OG6HWLK6-CkShDmcv.js → diagram-OG6HWLK6-BjtWGvrf.js} +1 -1
  49. package/dist/client/assets/{dist-BgZIvk5w.js → dist-BXZygPdX.js} +1 -1
  50. package/dist/client/assets/{edge-Bokubn8E.js → edge-RCQWcWNp.js} +1 -1
  51. package/dist/client/assets/{elixir-BEzcf3Xg.js → elixir-DwKyVg2X.js} +1 -1
  52. package/dist/client/assets/{elm-vJyLTAER.js → elm-DjR33IVs.js} +1 -1
  53. package/dist/client/assets/{erDiagram-TEJ5UH35-BFV1NQAH.js → erDiagram-TEJ5UH35-C5T4ywLG.js} +1 -1
  54. package/dist/client/assets/{erb-DDkAmjBS.js → erb-BnhUH1Hk.js} +1 -1
  55. package/dist/client/assets/{flowDiagram-I6XJVG4X-DU8xbFdO.js → flowDiagram-I6XJVG4X-BJmjm7Kx.js} +1 -1
  56. package/dist/client/assets/{ganttDiagram-6RSMTGT7-DCb7Qh0c.js → ganttDiagram-6RSMTGT7-DREPnzu5.js} +1 -1
  57. package/dist/client/assets/{git-rebase-DWcifAdK.js → git-rebase-DzXoSDXA.js} +1 -1
  58. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C_Tw-piE.js → gitGraphDiagram-PVQCEYII-DIR4G_-_.js} +1 -1
  59. package/dist/client/assets/{glimmer-js--HDru5ys.js → glimmer-js-HKnZpCn_.js} +1 -1
  60. package/dist/client/assets/{glimmer-ts-DAdXisHh.js → glimmer-ts-DedV7rWs.js} +1 -1
  61. package/dist/client/assets/{glsl-CmIRlJht.js → glsl-Bz-0Alp2.js} +1 -1
  62. package/dist/client/assets/{graphql-tx4-7I3U.js → graphql-DSKkDYCD.js} +1 -1
  63. package/dist/client/assets/{hack-yA0XjhF7.js → hack-CnaHZm8k.js} +1 -1
  64. package/dist/client/assets/{haml-BR5MUE1b.js → haml-huGFYKlj.js} +1 -1
  65. package/dist/client/assets/{handlebars-BPOF7iOf.js → handlebars-CKmgzfWY.js} +1 -1
  66. package/dist/client/assets/{html-BbteRk96.js → html-B9Ih_dUU.js} +1 -1
  67. package/dist/client/assets/{html-derivative-59NNrcMm.js → html-derivative-YabD-M5d.js} +1 -1
  68. package/dist/client/assets/{http-D3odGQI4.js → http-Bdu12JYX.js} +1 -1
  69. package/dist/client/assets/{hurl-BLTj8fPj.js → hurl-twZzDTNs.js} +1 -1
  70. package/dist/client/assets/{index-DHXpO7eS.js → index-BktdZRWB.js} +122 -118
  71. package/dist/client/assets/{index-BZcKS8Sb.css → index-YlwaPTSG.css} +1 -1
  72. package/dist/client/assets/{infoDiagram-5YYISTIA-CI6hJyRl.js → infoDiagram-5YYISTIA-D2ty2R-i.js} +1 -1
  73. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-gMS1P1LQ.js → ishikawaDiagram-YF4QCWOH-Ccnc9xlE.js} +1 -1
  74. package/dist/client/assets/{java-CsViuzs_.js → java-_5trO-p9.js} +1 -1
  75. package/dist/client/assets/{javascript-DQgsl2Dh.js → javascript-BOQn0ikE.js} +1 -1
  76. package/dist/client/assets/{jinja-DQNp2NUA.js → jinja-BgY-0IBz.js} +1 -1
  77. package/dist/client/assets/{jison-CDDOZQdc.js → jison-BLNTmT1_.js} +1 -1
  78. package/dist/client/assets/{journeyDiagram-JHISSGLW-BTQ_Ws_h.js → journeyDiagram-JHISSGLW-W7eWXlw0.js} +1 -1
  79. package/dist/client/assets/{json-DP4TqCuE.js → json-BLbH8rZf.js} +1 -1
  80. package/dist/client/assets/{jsx-Df5hn0Tf.js → jsx-CxteptsJ.js} +1 -1
  81. package/dist/client/assets/{julia--u33yGLi.js → julia-B__Ncp_z.js} +1 -1
  82. package/dist/client/assets/{just-BCpMmSOD.js → just-DBsHUGW1.js} +1 -1
  83. package/dist/client/assets/{kanban-definition-UN3LZRKU-CvqGbLR_.js → kanban-definition-UN3LZRKU-Z_AFL-rd.js} +1 -1
  84. package/dist/client/assets/{latex-D8D4jZGw.js → latex-DFF_0wxo.js} +1 -1
  85. package/dist/client/assets/{line-DBgaS_RW.js → line-aAv8TyOs.js} +1 -1
  86. package/dist/client/assets/{linear-RQVzKNVU.js → linear-BOvEZKH8.js} +1 -1
  87. package/dist/client/assets/{liquid-CkH85f12.js → liquid-kDWCO6d7.js} +1 -1
  88. package/dist/client/assets/{lua-iKoV7WE3.js → lua-CYTFayq-.js} +1 -1
  89. package/dist/client/assets/{marko-N8ScQSqT.js → marko-Dpmz3Pdx.js} +1 -1
  90. package/dist/client/assets/{mdc-BvHTOxsp.js → mdc-BsxHyM1i.js} +1 -1
  91. package/dist/client/assets/{mermaid-parser.core-CwDRwMR7.js → mermaid-parser.core-D8z_CWL1.js} +1 -1
  92. package/dist/client/assets/{mermaid.core-D2LDJgXO.js → mermaid.core-DNKchnly.js} +3 -3
  93. package/dist/client/assets/{mindmap-definition-RKZ34NQL-FRnPh642.js → mindmap-definition-RKZ34NQL-xQKMV4Kw.js} +1 -1
  94. package/dist/client/assets/{nginx-DGgvASuI.js → nginx-CcdTDme-.js} +1 -1
  95. package/dist/client/assets/{nim-D-v9hzvR.js → nim-B5wWDskL.js} +1 -1
  96. package/dist/client/assets/{perl-CG8leJ8K.js → perl-Ce2_iKLz.js} +1 -1
  97. package/dist/client/assets/{php-DvkeSP10.js → php-DuLCFERd.js} +1 -1
  98. package/dist/client/assets/{pieDiagram-4H26LBE5-CepOg38Y.js → pieDiagram-4H26LBE5-CBSCJnUr.js} +1 -1
  99. package/dist/client/assets/{pug-B4T7-xaL.js → pug-BfQJoQj1.js} +1 -1
  100. package/dist/client/assets/{qml-BE6D5Bxn.js → qml-DYeovlVl.js} +1 -1
  101. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DOFAsP60.js → quadrantDiagram-W4KKPZXB-uEcgb0Rm.js} +1 -1
  102. package/dist/client/assets/{r-BKZg9Mcq.js → r-DgHSP56L.js} +1 -1
  103. package/dist/client/assets/{razor-D-02oaxL.js → razor-B00x7W-i.js} +1 -1
  104. package/dist/client/assets/{regexp-BDFvAR1k.js → regexp-CmWVupmd.js} +1 -1
  105. package/dist/client/assets/{requirementDiagram-4Y6WPE33-BBVNH-2W.js → requirementDiagram-4Y6WPE33-Q4yY_ALe.js} +1 -1
  106. package/dist/client/assets/{review-export-D5iIl46_.js → review-export-pcqDKNqx.js} +1 -1
  107. package/dist/client/assets/{rst-BcT26OSj.js → rst-B3VARbTX.js} +1 -1
  108. package/dist/client/assets/{ruby-Cq_YQvFT.js → ruby-CaxKSSbT.js} +1 -1
  109. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BQfCTbBX.js → sankeyDiagram-5OEKKPKP-B-GLzFGa.js} +1 -1
  110. package/dist/client/assets/{sas-DN9oTxKY.js → sas-Ue0rHUIk.js} +1 -1
  111. package/dist/client/assets/{scss-BK_sp3z2.js → scss-BJJ7_L6c.js} +1 -1
  112. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CKAW2eyx.js → sequenceDiagram-3UESZ5HK-DW0em0D_.js} +1 -1
  113. package/dist/client/assets/{shellscript-CvNpOu0J.js → shellscript-C6LkZs1u.js} +1 -1
  114. package/dist/client/assets/{shellsession-8-yj2cJj.js → shellsession-CkZu1e84.js} +1 -1
  115. package/dist/client/assets/{soy-C6Q9atPF.js → soy-CDaZV57J.js} +1 -1
  116. package/dist/client/assets/{sql-CBL3BuHb.js → sql-CLfMGH4x.js} +1 -1
  117. package/dist/client/assets/{src-D-VUWIK5.js → src-C27zxuNO.js} +1 -1
  118. package/dist/client/assets/{stata-B2Q7Vqzu.js → stata-B0kNMHc9.js} +1 -1
  119. package/dist/client/assets/{stateDiagram-AJRCARHV-BGJiv0qO.js → stateDiagram-AJRCARHV-CrO_D3m4.js} +1 -1
  120. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-C9KDGD7R.js +1 -0
  121. package/dist/client/assets/{surrealql-C-A2N8vk.js → surrealql-D9os_yZO.js} +1 -1
  122. package/dist/client/assets/{svelte-VAut_-uy.js → svelte-2SxVToeO.js} +1 -1
  123. package/dist/client/assets/{templ-mUetM--K.js → templ-DzmZB67T.js} +1 -1
  124. package/dist/client/assets/{tex-BT53mWGp.js → tex-BMPk3nHk.js} +1 -1
  125. package/dist/client/assets/{timeline-definition-PNZ67QCA-lVwMt1rk.js → timeline-definition-PNZ67QCA-C9FBevHv.js} +1 -1
  126. package/dist/client/assets/{ts-tags-VkIOkgLN.js → ts-tags-CG14Bplc.js} +1 -1
  127. package/dist/client/assets/{tsx-D_aaGHTf.js → tsx-D6NK461A.js} +1 -1
  128. package/dist/client/assets/{twig-CufwqKkk.js → twig-Agh0j5sD.js} +1 -1
  129. package/dist/client/assets/{typescript-osFD2CEV.js → typescript-_AkeziZ2.js} +1 -1
  130. package/dist/client/assets/{vennDiagram-CIIHVFJN-_K9NtpA5.js → vennDiagram-CIIHVFJN-2H9HfhhR.js} +1 -1
  131. package/dist/client/assets/{vue-Bub1rXmL.js → vue-C1z3QGG9.js} +1 -1
  132. package/dist/client/assets/{vue-html-CN3x2pYg.js → vue-html-C1RMzLZk.js} +1 -1
  133. package/dist/client/assets/{vue-vine-C0csYkGm.js → vue-vine-oOixA6ge.js} +1 -1
  134. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-B2jTMfra.js → wardleyDiagram-YWT4CUSO-BJxrQhTf.js} +1 -1
  135. package/dist/client/assets/{xml-my6OjeGb.js → xml-okuDZ7vq.js} +1 -1
  136. package/dist/client/assets/{xsl-Bx0YVn26.js → xsl-S_n3XrKb.js} +1 -1
  137. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DfZ4YYXU.js → xychartDiagram-2RQKCTM6-BGdee7KG.js} +1 -1
  138. package/dist/client/assets/{yaml-DanwOypk.js → yaml-BoX-kqX1.js} +1 -1
  139. package/dist/client/index.html +2 -2
  140. package/dist/{doctor-q6oA64hm.mjs → doctor-CmP0u7-d.mjs} +1 -1
  141. package/dist/github-BjZZcSKV.mjs +2 -0
  142. package/dist/{github-HfIlIS-J.mjs → github-oCZx5aim.mjs} +270 -29
  143. package/dist/{mcp-eor39qmD.mjs → mcp-CqxXILYL.mjs} +1 -1
  144. package/dist/{server-C105rwQw.mjs → server-CczuXSWo.mjs} +164 -11
  145. package/package.json +3 -3
  146. package/dist/cli-agent-B4hU6Xay.mjs +0 -499
  147. package/dist/cli-agent-B_PHd635.mjs +0 -499
  148. package/dist/cli-agent-BatQgghr.mjs +0 -499
  149. package/dist/cli-agent-BkkRbKqq.mjs +0 -513
  150. package/dist/cli-agent-BlMtx1Tx.mjs +0 -736
  151. package/dist/cli-agent-BwZE05CQ.mjs +0 -499
  152. package/dist/cli-agent-C4Fb90GL.mjs +0 -728
  153. package/dist/cli-agent-CKE1Cvor.mjs +0 -513
  154. package/dist/cli-agent-CLvCYpmH.mjs +0 -499
  155. package/dist/cli-agent-CX8Fa1Ph.mjs +0 -499
  156. package/dist/cli-agent-ChALuNbw.mjs +0 -841
  157. package/dist/cli-agent-KxNAFIPf.mjs +0 -450
  158. package/dist/cli-agent-SILzesQP.mjs +0 -513
  159. package/dist/cli-agent-USzLoAit.mjs +0 -499
  160. package/dist/cli-agent-qBT8clNM.mjs +0 -841
  161. package/dist/cli-gh-6qiblgj7.mjs +0 -150
  162. package/dist/cli-gh-BV5az425.mjs +0 -147
  163. package/dist/cli-gh-Bo6fOHQR.mjs +0 -147
  164. package/dist/cli-gh-CDGSpndZ.mjs +0 -147
  165. package/dist/cli-gh-D1LoWJl-.mjs +0 -147
  166. package/dist/cli-gh-D1sIZ-jX.mjs +0 -147
  167. package/dist/cli-gh-DROAJlHi.mjs +0 -147
  168. package/dist/cli-gh-DgqscIkg.mjs +0 -147
  169. package/dist/cli-gh-DiT8BWwu.mjs +0 -147
  170. package/dist/cli-gh-KjPnyST6.mjs +0 -150
  171. package/dist/cli-gh-abs-IJrz.mjs +0 -147
  172. package/dist/client/assets/channel-CDxgOu-3.js +0 -1
  173. package/dist/client/assets/chunk-QZHKN3VN-DJCeMpP8.js +0 -1
  174. package/dist/client/assets/chunk-WU5MYG2G-BbuOkMaH.js +0 -1
  175. package/dist/client/assets/classDiagram-4FO5ZUOK-D5oJbiED.js +0 -1
  176. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-5MJt5ZxQ.js +0 -1
  177. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CdUgMghp.js +0 -1
  178. package/dist/comment-format-CKTt0fzi.mjs +0 -113
  179. package/dist/comment-format-DG_PAehC.mjs +0 -117
  180. package/dist/github-C9GLNak7.mjs +0 -2
  181. package/dist/mcp-7eXATtez.mjs +0 -1334
  182. package/dist/mcp-B6mCC7D3.mjs +0 -1047
  183. package/dist/mcp-BBk8AIO4.mjs +0 -1334
  184. package/dist/mcp-BJxrW9dS.mjs +0 -1334
  185. package/dist/mcp-BMTZLQuB.mjs +0 -758
  186. package/dist/mcp-BUF2nEL7.mjs +0 -1036
  187. package/dist/mcp-BWeWR4yd.mjs +0 -255
  188. package/dist/mcp-BgZO-iXI.mjs +0 -1047
  189. package/dist/mcp-BhT5GgYF.mjs +0 -1334
  190. package/dist/mcp-Bpx76OGU.mjs +0 -945
  191. package/dist/mcp-BsGdNA88.mjs +0 -1334
  192. package/dist/mcp-BxBm3d5l.mjs +0 -1047
  193. package/dist/mcp-C1T7LI0H.mjs +0 -1036
  194. package/dist/mcp-C4Bjmf9m.mjs +0 -1047
  195. package/dist/mcp-CFxcdEcJ.mjs +0 -733
  196. package/dist/mcp-Ca9QAlJ0.mjs +0 -1334
  197. package/dist/mcp-CphIUJUg.mjs +0 -1047
  198. package/dist/mcp-CtKRXQRC.mjs +0 -1047
  199. package/dist/mcp-CwjThGi2.mjs +0 -913
  200. package/dist/mcp-D4OsB9lt.mjs +0 -1047
  201. package/dist/mcp-DJ2batvt.mjs +0 -913
  202. package/dist/mcp-DNZQvKKF.mjs +0 -298
  203. package/dist/mcp-DO4zfNZX.mjs +0 -298
  204. package/dist/mcp-D_LGvBTw.mjs +0 -1047
  205. package/dist/mcp-Ds_lPX_o.mjs +0 -913
  206. package/dist/plan-format-B6nbAw_c.mjs +0 -132
  207. package/dist/plan-format-Bi46QS0m.mjs +0 -132
  208. package/dist/plan-format-DVnF8xrq.mjs +0 -126
  209. package/dist/plan-format-f62JWFI-.mjs +0 -117
  210. package/dist/plan-format-mSDtsPcC.mjs +0 -132
  211. package/dist/review-export-BoV0884M.mjs +0 -66
  212. package/dist/review-export-CKTI5Od_.mjs +0 -66
  213. package/dist/server-95UE5bgh.mjs +0 -3367
  214. package/dist/server-AisDKkpW.mjs +0 -3227
  215. package/dist/server-B0cS95Lf.mjs +0 -3488
  216. package/dist/server-BUsRhL1B.mjs +0 -3283
  217. package/dist/server-BZBFquG8.mjs +0 -3875
  218. package/dist/server-Bc2m9R5-.mjs +0 -3263
  219. package/dist/server-Bj-6KlK5.mjs +0 -3367
  220. package/dist/server-Bmt57wV5.mjs +0 -3875
  221. package/dist/server-Bpf84Il0.mjs +0 -3367
  222. package/dist/server-C15WRRnS.mjs +0 -3740
  223. package/dist/server-CYSpLbdA.mjs +0 -3360
  224. package/dist/server-ChT2DCaR.mjs +0 -3701
  225. package/dist/server-D0Ni8PKP.mjs +0 -3252
  226. package/dist/server-D2xEbakj.mjs +0 -3874
  227. package/dist/server-DJxysGxV.mjs +0 -3701
  228. package/dist/server-Dov7jbV3.mjs +0 -3367
  229. package/dist/server-TOElOuNP.mjs +0 -3258
  230. package/dist/server-eQ2E4Axo.mjs +0 -3367
  231. package/dist/server-lock-C_wPtEsH.mjs +0 -909
  232. package/dist/server-lock-Cbu3qHdu.mjs +0 -924
  233. package/dist/server-lock-D32inEn9.mjs +0 -924
  234. package/dist/server-lock-D73NKKbn.mjs +0 -842
  235. package/dist/server-lock-DaSx7DjW.mjs +0 -1049
  236. package/dist/server-lock-Ddcat0HF.mjs +0 -851
  237. package/dist/server-lock-Dj9fG9md.mjs +0 -838
  238. package/dist/server-lock-Dq_1CJaF.mjs +0 -1047
  239. package/dist/server-lock-Ujbcgq28.mjs +0 -954
  240. package/dist/update-check-CXeSZANo.mjs +0 -129
  241. package/dist/update-check-DAPFCqpF.mjs +0 -129
@@ -1,7 +1,60 @@
1
- import { execFile } from "node:child_process";
1
+ import { execFile, spawn } from "node:child_process";
2
2
  import { promisify } from "node:util";
3
3
  //#region src/lib/github.ts
4
4
  const execFileAsync = promisify(execFile);
5
+ const GH_REQUEST_TIMEOUT_MS = 45e3;
6
+ const GH_MAX_OUTPUT_BYTES = 20 * 1024 * 1024;
7
+ /** Execute a command with explicit stdin delivery, output limits, and timeout. */
8
+ function execWithInput(command, args, input, timeoutMs = GH_REQUEST_TIMEOUT_MS) {
9
+ return new Promise((resolve, reject) => {
10
+ const child = spawn(command, args, { stdio: [
11
+ "pipe",
12
+ "pipe",
13
+ "pipe"
14
+ ] });
15
+ let stdout = "";
16
+ let stderr = "";
17
+ let settled = false;
18
+ const finish = (error) => {
19
+ if (settled) return;
20
+ settled = true;
21
+ clearTimeout(timer);
22
+ if (error) {
23
+ error.stdout = stdout;
24
+ error.stderr = stderr;
25
+ reject(error);
26
+ } else resolve({
27
+ stdout,
28
+ stderr
29
+ });
30
+ };
31
+ const append = (target, chunk) => {
32
+ const text = chunk.toString();
33
+ if (target === "stdout") stdout += text;
34
+ else stderr += text;
35
+ if (Buffer.byteLength(stdout) + Buffer.byteLength(stderr) > GH_MAX_OUTPUT_BYTES) {
36
+ child.kill("SIGTERM");
37
+ finish(/* @__PURE__ */ new Error("GitHub CLI response exceeded the 20 MB output limit"));
38
+ }
39
+ };
40
+ child.stdout.on("data", (chunk) => append("stdout", chunk));
41
+ child.stderr.on("data", (chunk) => append("stderr", chunk));
42
+ child.on("error", (error) => finish(error));
43
+ child.on("close", (code, signal) => {
44
+ if (settled) return;
45
+ if (code === 0) return finish();
46
+ const error = /* @__PURE__ */ new Error(signal ? `GitHub CLI terminated by ${signal}` : `GitHub CLI exited with code ${code ?? "unknown"}`);
47
+ error.code = code;
48
+ finish(error);
49
+ });
50
+ const timer = setTimeout(() => {
51
+ child.kill("SIGTERM");
52
+ finish(/* @__PURE__ */ new Error(`GitHub CLI request timed out after ${Math.ceil(timeoutMs / 1e3)} seconds`));
53
+ }, timeoutMs);
54
+ child.stdin.on("error", () => {});
55
+ child.stdin.end(input);
56
+ });
57
+ }
5
58
  /**
6
59
  * Probe the `gh` CLI: is it on `$PATH`, and is the user authenticated?
7
60
  * Never throws — returns a permissive `available: false` on any failure.
@@ -141,7 +194,8 @@ async function fetchPrMetadataViaGh(resolved) {
141
194
  login: metaJson.author.login,
142
195
  avatarUrl: metaJson.author.avatarUrl
143
196
  } : null;
144
- const existingComments = await fetchExistingCommentsViaGh(resolved);
197
+ const existingReviews = await fetchExistingReviewsViaGh(resolved);
198
+ const existingComments = await fetchExistingCommentsViaGh(resolved, existingReviews);
145
199
  return {
146
200
  number: metaJson.number,
147
201
  title: metaJson.title,
@@ -155,14 +209,12 @@ async function fetchPrMetadataViaGh(resolved) {
155
209
  owner: resolved.owner,
156
210
  repo: resolved.repo,
157
211
  diff,
158
- existingComments
212
+ existingComments,
213
+ existingReviews
159
214
  };
160
215
  }
161
- async function fetchExistingCommentsViaGh(resolved) {
162
- `${resolved.owner}${resolved.repo}`;
163
- const endpoint = `repos/${resolved.owner}/${resolved.repo}/pulls/${resolved.pullNumber}/comments`;
216
+ async function fetchExistingReviewsViaGh(resolved) {
164
217
  const reviewsEndpoint = `repos/${resolved.owner}/${resolved.repo}/pulls/${resolved.pullNumber}/reviews`;
165
- let reviews = [];
166
218
  try {
167
219
  const { stdout } = await execFileAsync("gh", [
168
220
  "api",
@@ -172,11 +224,38 @@ async function fetchExistingCommentsViaGh(resolved) {
172
224
  encoding: "utf-8",
173
225
  maxBuffer: 20 * 1024 * 1024
174
226
  });
175
- const all = JSON.parse(stdout);
176
- if (Array.isArray(all)) reviews = all;
177
- } catch {}
178
- reviews.sort((a, b) => a.submitted_at < b.submitted_at ? 1 : -1);
179
- const recentReviews = reviews.slice(0, 50);
227
+ const parsed = JSON.parse(stdout);
228
+ if (!Array.isArray(parsed)) return [];
229
+ return parsed.map((review) => {
230
+ const state = String(review.state ?? "").toUpperCase();
231
+ if (![
232
+ "APPROVED",
233
+ "CHANGES_REQUESTED",
234
+ "COMMENTED",
235
+ "PENDING",
236
+ "DISMISSED"
237
+ ].includes(state)) return null;
238
+ return {
239
+ id: review.id,
240
+ author: review.user?.login ? {
241
+ login: review.user.login,
242
+ avatarUrl: review.user.avatar_url
243
+ } : null,
244
+ body: review.body ?? "",
245
+ state,
246
+ submittedAt: review.submitted_at ?? null,
247
+ htmlUrl: review.html_url,
248
+ commitId: review.commit_id
249
+ };
250
+ }).filter((review) => review != null).sort((a, b) => (a.submittedAt ?? "") < (b.submittedAt ?? "") ? 1 : -1).slice(0, 50);
251
+ } catch {
252
+ return [];
253
+ }
254
+ }
255
+ async function fetchExistingCommentsViaGh(resolved, existingReviews) {
256
+ `${resolved.owner}${resolved.repo}`;
257
+ const endpoint = `repos/${resolved.owner}/${resolved.repo}/pulls/${resolved.pullNumber}/comments`;
258
+ const recentReviews = existingReviews ?? await fetchExistingReviewsViaGh(resolved);
180
259
  const reviewStateById = /* @__PURE__ */ new Map();
181
260
  for (const r of recentReviews) reviewStateById.set(r.id, r.state);
182
261
  let commentsRaw = [];
@@ -194,6 +273,7 @@ async function fetchExistingCommentsViaGh(resolved) {
194
273
  } catch {
195
274
  return [];
196
275
  }
276
+ const threadByCommentId = await fetchReviewThreadStateViaGh(resolved);
197
277
  const byId = /* @__PURE__ */ new Map();
198
278
  for (const c of commentsRaw) byId.set(c.id, c);
199
279
  const replyByParent = /* @__PURE__ */ new Map();
@@ -206,6 +286,7 @@ async function fetchExistingCommentsViaGh(resolved) {
206
286
  for (const c of commentsRaw) {
207
287
  if (c.in_reply_to_id) continue;
208
288
  const state = c.pull_request_review_id ? reviewStateById.get(c.pull_request_review_id) ?? null : null;
289
+ const thread = threadByCommentId.get(c.id);
209
290
  tops.push({
210
291
  id: c.id,
211
292
  author: c.user ? {
@@ -215,7 +296,9 @@ async function fetchExistingCommentsViaGh(resolved) {
215
296
  body: c.body ?? "",
216
297
  path: c.path,
217
298
  line: typeof c.line === "number" ? c.line : null,
299
+ startLine: typeof c.start_line === "number" ? c.start_line : null,
218
300
  side: c.side === "LEFT" || c.side === "RIGHT" ? c.side : null,
301
+ startSide: c.start_side === "LEFT" || c.start_side === "RIGHT" ? c.start_side : null,
219
302
  createdAt: c.created_at,
220
303
  updatedAt: c.updated_at,
221
304
  state,
@@ -227,9 +310,15 @@ async function fetchExistingCommentsViaGh(resolved) {
227
310
  } : null,
228
311
  body: r.body ?? "",
229
312
  createdAt: r.created_at,
230
- updatedAt: r.updated_at
313
+ updatedAt: r.updated_at,
314
+ viewerDidAuthor: threadByCommentId.get(r.id)?.viewerDidAuthor
231
315
  })),
232
- isOutdated: Boolean(c.line == null && c.original_line != null || c.position === null && c.original_position != null)
316
+ isOutdated: Boolean(c.line == null && c.original_line != null || c.position === null && c.original_position != null),
317
+ threadId: thread?.id,
318
+ isResolved: thread?.isResolved,
319
+ viewerCanResolve: thread?.viewerCanResolve,
320
+ viewerCanUnresolve: thread?.viewerCanUnresolve,
321
+ viewerDidAuthor: thread?.viewerDidAuthor
233
322
  });
234
323
  }
235
324
  tops.sort((a, b) => {
@@ -238,6 +327,62 @@ async function fetchExistingCommentsViaGh(resolved) {
238
327
  });
239
328
  return tops;
240
329
  }
330
+ /** Fetch thread-only state unavailable from the REST review-comments API. */
331
+ async function fetchReviewThreadStateViaGh(resolved) {
332
+ const query = `
333
+ query ReviewThreads($owner: String!, $repo: String!, $number: Int!, $cursor: String) {
334
+ repository(owner: $owner, name: $repo) {
335
+ pullRequest(number: $number) {
336
+ reviewThreads(first: 100, after: $cursor) {
337
+ nodes {
338
+ id
339
+ isResolved
340
+ viewerCanResolve
341
+ viewerCanUnresolve
342
+ comments(first: 100) { nodes { databaseId viewerDidAuthor } }
343
+ }
344
+ pageInfo { hasNextPage endCursor }
345
+ }
346
+ }
347
+ }
348
+ }
349
+ `;
350
+ const byCommentId = /* @__PURE__ */ new Map();
351
+ let cursor = null;
352
+ try {
353
+ do {
354
+ const { stdout } = await execWithInput("gh", [
355
+ "api",
356
+ "graphql",
357
+ "--input",
358
+ "-"
359
+ ], JSON.stringify({
360
+ query,
361
+ variables: {
362
+ owner: resolved.owner,
363
+ repo: resolved.repo,
364
+ number: resolved.pullNumber,
365
+ cursor
366
+ }
367
+ }));
368
+ const connection = JSON.parse(stdout)?.data?.repository?.pullRequest?.reviewThreads;
369
+ for (const node of connection?.nodes ?? []) {
370
+ const state = {
371
+ id: node.id,
372
+ isResolved: Boolean(node.isResolved),
373
+ viewerCanResolve: Boolean(node.viewerCanResolve),
374
+ viewerCanUnresolve: Boolean(node.viewerCanUnresolve)
375
+ };
376
+ for (const comment of node.comments?.nodes ?? []) if (typeof comment.databaseId === "number") byCommentId.set(comment.databaseId, {
377
+ ...state,
378
+ viewerDidAuthor: Boolean(comment.viewerDidAuthor)
379
+ });
380
+ }
381
+ cursor = connection?.pageInfo?.hasNextPage ? connection.pageInfo.endCursor ?? null : null;
382
+ } while (cursor);
383
+ } catch {}
384
+ return byCommentId;
385
+ }
241
386
  /**
242
387
  * POST the review to GitHub. Prefers `gh api` (uses the user's existing
243
388
  * `gh auth`); falls back to a direct HTTP call with `$GITHUB_TOKEN` when
@@ -338,11 +483,7 @@ async function submitViaGh(input) {
338
483
  "-"
339
484
  ];
340
485
  try {
341
- const { stdout } = await execFileAsync("gh", args, {
342
- encoding: "utf-8",
343
- maxBuffer: 20 * 1024 * 1024,
344
- input: JSON.stringify(payload)
345
- });
486
+ const { stdout } = await execWithInput("gh", args, JSON.stringify(payload));
346
487
  const result = JSON.parse(stdout);
347
488
  return {
348
489
  ok: true,
@@ -370,6 +511,7 @@ async function submitViaToken(input, token) {
370
511
  try {
371
512
  const res = await fetch(url, {
372
513
  method: "POST",
514
+ signal: AbortSignal.timeout(GH_REQUEST_TIMEOUT_MS),
373
515
  headers: {
374
516
  Authorization: `Bearer ${token}`,
375
517
  Accept: "application/vnd.github+json",
@@ -453,7 +595,7 @@ async function replyToPrComment(input) {
453
595
  in_reply_to: input.inReplyTo
454
596
  });
455
597
  try {
456
- const { stdout } = await execFileAsync("gh", [
598
+ const { stdout } = await execWithInput("gh", [
457
599
  "api",
458
600
  "--method",
459
601
  "POST",
@@ -462,14 +604,26 @@ async function replyToPrComment(input) {
462
604
  "Accept: application/vnd.github+json",
463
605
  "--input",
464
606
  "-"
465
- ], {
466
- encoding: "utf-8",
467
- input: payload,
468
- maxBuffer: 5 * 1024 * 1024
469
- });
607
+ ], payload);
608
+ const result = JSON.parse(stdout);
609
+ if (typeof result.id !== "number") return {
610
+ ok: false,
611
+ error: "GitHub reply response did not include a comment id"
612
+ };
613
+ const now = (/* @__PURE__ */ new Date()).toISOString();
470
614
  return {
471
615
  ok: true,
472
- id: JSON.parse(stdout).id
616
+ id: result.id,
617
+ reply: {
618
+ id: result.id,
619
+ author: result.user?.login ? {
620
+ login: result.user.login,
621
+ avatarUrl: result.user.avatar_url
622
+ } : null,
623
+ body: result.body ?? input.body,
624
+ createdAt: result.created_at ?? now,
625
+ updatedAt: result.updated_at ?? result.created_at ?? now
626
+ }
473
627
  };
474
628
  } catch (err) {
475
629
  const msg = err?.stderr || err?.stdout || err?.message || "reply failed";
@@ -479,6 +633,91 @@ async function replyToPrComment(input) {
479
633
  };
480
634
  }
481
635
  }
636
+ async function updatePrReviewComment(input) {
637
+ const endpoint = `repos/${input.resolved.owner}/${input.resolved.repo}/pulls/comments/${input.commentId}`;
638
+ try {
639
+ await execWithInput("gh", [
640
+ "api",
641
+ "--method",
642
+ "PATCH",
643
+ endpoint,
644
+ "-H",
645
+ "Accept: application/vnd.github+json",
646
+ "--input",
647
+ "-"
648
+ ], JSON.stringify({ body: input.body }));
649
+ return { ok: true };
650
+ } catch (error) {
651
+ return {
652
+ ok: false,
653
+ error: githubCommandError(error, "Failed to edit GitHub comment")
654
+ };
655
+ }
656
+ }
657
+ async function deletePrReviewComment(input) {
658
+ const endpoint = `repos/${input.resolved.owner}/${input.resolved.repo}/pulls/comments/${input.commentId}`;
659
+ try {
660
+ await execFileAsync("gh", [
661
+ "api",
662
+ "--method",
663
+ "DELETE",
664
+ endpoint,
665
+ "-H",
666
+ "Accept: application/vnd.github+json"
667
+ ], {
668
+ encoding: "utf-8",
669
+ timeout: GH_REQUEST_TIMEOUT_MS,
670
+ maxBuffer: 5 * 1024 * 1024
671
+ });
672
+ return { ok: true };
673
+ } catch (error) {
674
+ return {
675
+ ok: false,
676
+ error: githubCommandError(error, "Failed to delete GitHub comment")
677
+ };
678
+ }
679
+ }
680
+ async function setPrReviewThreadResolved(input) {
681
+ const query = `
682
+ mutation UpdateReviewThread($threadId: ID!) {
683
+ ${input.resolved ? "resolveReviewThread" : "unresolveReviewThread"}(input: { threadId: $threadId }) {
684
+ thread { id isResolved }
685
+ }
686
+ }
687
+ `;
688
+ try {
689
+ const { stdout } = await execWithInput("gh", [
690
+ "api",
691
+ "graphql",
692
+ "--input",
693
+ "-"
694
+ ], JSON.stringify({
695
+ query,
696
+ variables: { threadId: input.threadId }
697
+ }));
698
+ const parsed = JSON.parse(stdout);
699
+ if (parsed.errors?.length) return {
700
+ ok: false,
701
+ error: parsed.errors.map((item) => item.message).filter(Boolean).join("; ") || "GitHub rejected the thread update"
702
+ };
703
+ return { ok: true };
704
+ } catch (error) {
705
+ return {
706
+ ok: false,
707
+ error: githubCommandError(error, "Failed to update GitHub thread")
708
+ };
709
+ }
710
+ }
711
+ function githubCommandError(error, fallback) {
712
+ const stdout = typeof error?.stdout === "string" ? error.stdout : "";
713
+ try {
714
+ const parsed = JSON.parse(stdout);
715
+ if (parsed.message) return parsed.message;
716
+ const messages = parsed.errors?.map((item) => item.message).filter(Boolean);
717
+ if (messages?.length) return messages.join("; ");
718
+ } catch {}
719
+ return String(error?.stderr || error?.message || fallback).trim().slice(0, 500) || fallback;
720
+ }
482
721
  async function buildPrSession(ref) {
483
722
  const meta = await fetchPrMetadataViaGh(parsePrRef(ref, await detectCwdRepo() ?? void 0));
484
723
  return {
@@ -496,7 +735,8 @@ async function buildPrSession(ref) {
496
735
  changedFiles: meta.changedFiles,
497
736
  diff: meta.diff,
498
737
  comments: [],
499
- existingComments: meta.existingComments
738
+ existingComments: meta.existingComments,
739
+ existingReviews: meta.existingReviews
500
740
  };
501
741
  }
502
742
  /** Refresh `diff` + `existingComments` + head SHA in an existing session. */
@@ -518,8 +758,9 @@ async function refreshPrSession(session) {
518
758
  deletions: meta.deletions,
519
759
  changedFiles: meta.changedFiles,
520
760
  diff: meta.diff,
521
- existingComments: meta.existingComments
761
+ existingComments: meta.existingComments,
762
+ existingReviews: meta.existingReviews
522
763
  };
523
764
  }
524
765
  //#endregion
525
- export { detectGhCli as a, fetchPrMetadataViaGh as c, readGithubToken as d, refreshPrSession as f, detectCwdRepo as i, parseGhAuthStatusUser as l, submitReview as m, buildReviewPayload as n, expandMultiLineComments as o, replyToPrComment as p, decisionToEvent as r, fetchPrChecks as s, buildPrSession as t, parsePrRef as u };
766
+ export { replyToPrComment as _, detectCwdRepo as a, updatePrReviewComment as b, expandMultiLineComments as c, fetchPrChecks as d, fetchPrMetadataViaGh as f, refreshPrSession as g, readGithubToken as h, deletePrReviewComment as i, fetchExistingCommentsViaGh as l, parsePrRef as m, buildReviewPayload as n, detectGhCli as o, parseGhAuthStatusUser as p, decisionToEvent as r, execWithInput as s, buildPrSession as t, fetchExistingReviewsViaGh as u, setPrReviewThreadResolved as v, submitReview as y };
@@ -1,4 +1,4 @@
1
- import { i as buildGitDiffArgs, o as parseDiffOptions, t as startServer } from "./server-C105rwQw.mjs";
1
+ import { i as buildGitDiffArgs, o as parseDiffOptions, t as startServer } from "./server-CczuXSWo.mjs";
2
2
  import { t as formatComments } from "./comment-format-B5AcGcR-.mjs";
3
3
  import { n as formatPlanReview } from "./plan-format-BQyx--mp.mjs";
4
4
  import { a as removeServerLock, i as readServerLock, n as diffScopeKey, o as removeServerLockIfOwned, r as isLockAlive, s as writeServerLock, t as acquireServerStartupLease } from "./server-lock-uqSdDYeR.mjs";
@@ -2,7 +2,7 @@ import { C as isSafePath, S as revertHunk, _ as getUntrackedFilePathsAsync, a as
2
2
  import { a as searchContent, c as trackSelection, i as searchAll, n as saveSettings, o as searchFiles, r as getSearchStatus, s as searchSymbols, t as loadSettings } from "./settings-BVnzGFL7.mjs";
3
3
  import { t as formatComments } from "./comment-format-B5AcGcR-.mjs";
4
4
  import { n as formatPlanReview, r as sectionTitleForLine, t as extractPlanLines } from "./plan-format-BQyx--mp.mjs";
5
- import { f as refreshPrSession, i as detectCwdRepo, m as submitReview, t as buildPrSession, u as parsePrRef } from "./github-HfIlIS-J.mjs";
5
+ import { a as detectCwdRepo, b as updatePrReviewComment, g as refreshPrSession, i as deletePrReviewComment, l as fetchExistingCommentsViaGh, m as parsePrRef, t as buildPrSession, u as fetchExistingReviewsViaGh, v as setPrReviewThreadResolved, y as submitReview } from "./github-oCZx5aim.mjs";
6
6
  import { execFileSync } from "node:child_process";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { dirname, extname, join, resolve } from "node:path";
@@ -2608,12 +2608,49 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2608
2608
  deletions: session.deletions,
2609
2609
  changedFiles: session.changedFiles,
2610
2610
  existingComments: session.existingComments,
2611
+ existingReviews: session.existingReviews ?? [],
2611
2612
  submittedAt: session.submittedAt,
2612
2613
  submittedReviewId: session.submittedReviewId,
2613
2614
  submittedReviewUrl: session.submittedReviewUrl,
2614
2615
  authSource: session.authSource
2615
2616
  });
2616
2617
  });
2618
+ const syncExistingPrReviewData = async (session) => {
2619
+ const resolved = {
2620
+ owner: session.owner,
2621
+ repo: session.repo,
2622
+ pullNumber: session.pullNumber,
2623
+ ref: session.ref
2624
+ };
2625
+ let existingReviews = await fetchExistingReviewsViaGh(resolved);
2626
+ const optimisticReview = session.submittedReviewId == null ? void 0 : session.existingReviews?.find((review) => review.id === session.submittedReviewId);
2627
+ if (optimisticReview && !existingReviews.some((review) => review.id === optimisticReview.id) && session.submittedAt != null && Date.now() - session.submittedAt < 12e4) existingReviews = [optimisticReview, ...existingReviews];
2628
+ const existingComments = await fetchExistingCommentsViaGh(resolved, existingReviews);
2629
+ const comments = session.submittedAt ? (session.comments ?? []).filter((comment) => comment.createdAt > session.submittedAt) : session.comments;
2630
+ const next = {
2631
+ ...session,
2632
+ comments,
2633
+ existingComments,
2634
+ existingReviews
2635
+ };
2636
+ await prStore.set(next);
2637
+ return next;
2638
+ };
2639
+ /** Lightweight bidirectional comment sync (without re-fetching the whole diff). */
2640
+ app.post("/api/gh/comments/sync", async (c) => {
2641
+ if (!prMode) return notInPrMode(c);
2642
+ const session = await prStore.get();
2643
+ if (!session) return notInPrMode(c);
2644
+ try {
2645
+ const next = await syncExistingPrReviewData(session);
2646
+ return c.json({
2647
+ ok: true,
2648
+ count: next.existingComments.length
2649
+ });
2650
+ } catch (error) {
2651
+ return c.json({ error: error?.message ?? "Failed to sync GitHub comments" }, 502);
2652
+ }
2653
+ });
2617
2654
  /** Re-fetch PR metadata (head SHA, diff, existing comments) and persist. */
2618
2655
  app.post("/api/gh/pr/refresh", async (c) => {
2619
2656
  if (!prMode) return notInPrMode(c);
@@ -2621,7 +2658,11 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2621
2658
  if (!session) return notInPrMode(c);
2622
2659
  try {
2623
2660
  const refreshed = await refreshPrSession(session);
2624
- await prStore.set(refreshed);
2661
+ const comments = refreshed.submittedAt ? (refreshed.comments ?? []).filter((comment) => comment.createdAt > refreshed.submittedAt) : refreshed.comments;
2662
+ await prStore.set({
2663
+ ...refreshed,
2664
+ comments
2665
+ });
2625
2666
  return c.json({
2626
2667
  ok: true,
2627
2668
  headSha: refreshed.headSha
@@ -2636,7 +2677,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2636
2677
  const session = await prStore.get();
2637
2678
  if (!session) return notInPrMode(c);
2638
2679
  try {
2639
- const { fetchPrChecks } = await import("./github-C9GLNak7.mjs");
2680
+ const { fetchPrChecks } = await import("./github-BjZZcSKV.mjs");
2640
2681
  const checks = await fetchPrChecks({
2641
2682
  owner: session.owner,
2642
2683
  repo: session.repo,
@@ -2673,7 +2714,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2673
2714
  const text = typeof body.body === "string" ? body.body.trim() : "";
2674
2715
  if (!text) return c.json({ error: "body is required" }, 400);
2675
2716
  try {
2676
- const { replyToPrComment } = await import("./github-C9GLNak7.mjs");
2717
+ const { replyToPrComment } = await import("./github-BjZZcSKV.mjs");
2677
2718
  const result = await replyToPrComment({
2678
2719
  resolved: {
2679
2720
  owner: session.owner,
@@ -2685,16 +2726,95 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2685
2726
  body: text
2686
2727
  });
2687
2728
  if (!result.ok) return c.json({ error: result.error ?? "Reply failed" }, 500);
2688
- const refreshed = await refreshPrSession(session);
2689
- await prStore.set(refreshed);
2729
+ const reply = result.reply;
2730
+ if (reply) {
2731
+ const existingComments = session.existingComments.map((comment) => comment.id === id ? {
2732
+ ...comment,
2733
+ replies: [...comment.replies, reply]
2734
+ } : comment);
2735
+ await prStore.set({
2736
+ ...session,
2737
+ existingComments
2738
+ });
2739
+ }
2690
2740
  return c.json({
2691
2741
  ok: true,
2692
- id: result.id
2742
+ id: result.id,
2743
+ reply
2693
2744
  });
2694
2745
  } catch (err) {
2695
2746
  return c.json({ error: err?.message ?? "Reply failed" }, 500);
2696
2747
  }
2697
2748
  });
2749
+ /** Edit any published review comment or reply. */
2750
+ app.patch("/api/gh/existing-comments/:id", async (c) => {
2751
+ if (!prMode) return notInPrMode(c);
2752
+ const session = await prStore.get();
2753
+ if (!session) return notInPrMode(c);
2754
+ const id = Number(c.req.param("id"));
2755
+ if (!Number.isFinite(id)) return c.json({ error: "Invalid comment id" }, 400);
2756
+ const request = await c.req.json().catch(() => ({}));
2757
+ const text = typeof request.body === "string" ? request.body.trim() : "";
2758
+ if (!text) return c.json({ error: "body is required" }, 400);
2759
+ const result = await updatePrReviewComment({
2760
+ resolved: {
2761
+ owner: session.owner,
2762
+ repo: session.repo,
2763
+ pullNumber: session.pullNumber,
2764
+ ref: session.ref
2765
+ },
2766
+ commentId: id,
2767
+ body: text
2768
+ });
2769
+ if (!result.ok) return c.json({ error: result.error ?? "Edit failed" }, 502);
2770
+ const next = await syncExistingPrReviewData(session);
2771
+ return c.json({
2772
+ ok: true,
2773
+ existingComments: next.existingComments
2774
+ });
2775
+ });
2776
+ /** Delete any published review comment or reply. */
2777
+ app.delete("/api/gh/existing-comments/:id", async (c) => {
2778
+ if (!prMode) return notInPrMode(c);
2779
+ const session = await prStore.get();
2780
+ if (!session) return notInPrMode(c);
2781
+ const id = Number(c.req.param("id"));
2782
+ if (!Number.isFinite(id)) return c.json({ error: "Invalid comment id" }, 400);
2783
+ const result = await deletePrReviewComment({
2784
+ resolved: {
2785
+ owner: session.owner,
2786
+ repo: session.repo,
2787
+ pullNumber: session.pullNumber,
2788
+ ref: session.ref
2789
+ },
2790
+ commentId: id
2791
+ });
2792
+ if (!result.ok) return c.json({ error: result.error ?? "Delete failed" }, 502);
2793
+ const next = await syncExistingPrReviewData(session);
2794
+ return c.json({
2795
+ ok: true,
2796
+ existingComments: next.existingComments
2797
+ });
2798
+ });
2799
+ /** Resolve or reopen a published GitHub review thread. */
2800
+ app.put("/api/gh/review-threads/:threadId", async (c) => {
2801
+ if (!prMode) return notInPrMode(c);
2802
+ const session = await prStore.get();
2803
+ if (!session) return notInPrMode(c);
2804
+ const threadId = c.req.param("threadId");
2805
+ const request = await c.req.json().catch(() => ({}));
2806
+ if (typeof request.resolved !== "boolean") return c.json({ error: "resolved must be a boolean" }, 400);
2807
+ const result = await setPrReviewThreadResolved({
2808
+ threadId,
2809
+ resolved: request.resolved
2810
+ });
2811
+ if (!result.ok) return c.json({ error: result.error ?? "Thread update failed" }, 502);
2812
+ const next = await syncExistingPrReviewData(session);
2813
+ return c.json({
2814
+ ok: true,
2815
+ existingComments: next.existingComments
2816
+ });
2817
+ });
2698
2818
  /** Initialize a PR session from a ref like `1234`, `o/r#42`, or a GitHub URL. */
2699
2819
  app.post("/api/gh/pr/init", async (c) => {
2700
2820
  if (!prMode) return notInPrMode(c);
@@ -2782,13 +2902,16 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2782
2902
  if (!prMode) return notInPrMode(c);
2783
2903
  const id = c.req.param("id");
2784
2904
  const { body, role, model } = await c.req.json();
2905
+ const text = typeof body === "string" ? body.trim() : "";
2906
+ if (!text) return c.json({ error: "body is required" }, 400);
2785
2907
  const session = await prStore.get();
2786
2908
  if (!session) return notInPrMode(c);
2909
+ if (!(session.comments ?? []).some((cm) => cm.id === id)) return c.json({ error: "Comment not found" }, 404);
2787
2910
  const comments = (session.comments ?? []).map((cm) => {
2788
2911
  if (cm.id !== id) return cm;
2789
2912
  const reply = {
2790
2913
  id: crypto.randomUUID(),
2791
- body,
2914
+ body: text,
2792
2915
  createdAt: Date.now(),
2793
2916
  role: role || (model ? "agent" : "user"),
2794
2917
  model: model || void 0
@@ -2814,7 +2937,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2814
2937
  if (decision !== "approve" && decision !== "comment" && decision !== "request-changes" && decision !== "draft") return c.json({ error: "decision must be one of: approve, comment, request-changes, draft" }, 400);
2815
2938
  const generalBody = typeof body.body === "string" ? body.body : "";
2816
2939
  if (body.dryRun === true) {
2817
- const { buildReviewPayload } = await import("./github-C9GLNak7.mjs");
2940
+ const { buildReviewPayload } = await import("./github-BjZZcSKV.mjs");
2818
2941
  const payload = buildReviewPayload({
2819
2942
  decision,
2820
2943
  body: generalBody,
@@ -2840,8 +2963,37 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2840
2963
  comments: session.comments ?? []
2841
2964
  });
2842
2965
  if (result.ok) {
2966
+ let existingComments = session.existingComments;
2967
+ let existingReviews = session.existingReviews ?? [];
2968
+ try {
2969
+ const resolved = {
2970
+ owner: session.owner,
2971
+ repo: session.repo,
2972
+ pullNumber: session.pullNumber,
2973
+ ref: session.ref
2974
+ };
2975
+ existingReviews = await fetchExistingReviewsViaGh(resolved);
2976
+ existingComments = await fetchExistingCommentsViaGh(resolved, existingReviews);
2977
+ } catch {}
2978
+ if (result.reviewId != null && !existingReviews.some((review) => review.id === result.reviewId)) existingReviews = [{
2979
+ id: result.reviewId,
2980
+ author: null,
2981
+ body: generalBody,
2982
+ state: {
2983
+ approve: "APPROVED",
2984
+ "request-changes": "CHANGES_REQUESTED",
2985
+ comment: "COMMENTED",
2986
+ draft: "PENDING"
2987
+ }[decision],
2988
+ submittedAt: (/* @__PURE__ */ new Date()).toISOString(),
2989
+ htmlUrl: result.reviewUrl,
2990
+ commitId: session.headSha
2991
+ }, ...existingReviews];
2843
2992
  const next = {
2844
2993
  ...session,
2994
+ comments: [],
2995
+ existingComments,
2996
+ existingReviews,
2845
2997
  submittedAt: Date.now(),
2846
2998
  submittedReviewId: result.reviewId,
2847
2999
  submittedReviewUrl: result.reviewUrl,
@@ -2849,7 +3001,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2849
3001
  };
2850
3002
  await prStore.set(next);
2851
3003
  }
2852
- return c.json({
3004
+ const responseBody = {
2853
3005
  ok: result.ok,
2854
3006
  reviewId: result.reviewId,
2855
3007
  reviewUrl: result.reviewUrl,
@@ -2857,7 +3009,8 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
2857
3009
  authSource: result.authSource,
2858
3010
  error: result.error,
2859
3011
  dryRun: false
2860
- });
3012
+ };
3013
+ return result.ok ? c.json(responseBody) : c.json(responseBody, 502);
2861
3014
  });
2862
3015
  app.post("/api/review/send", async (c) => {
2863
3016
  const body = await c.req.json().catch(() => ({}));