diffing 0.16.1 → 0.18.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 (165) hide show
  1. package/dist/{cli-agent-Dk0yRtrA.mjs → cli-agent-du9TS34N.mjs} +763 -20
  2. package/dist/{cli-gh-BvoDabKK.mjs → cli-gh-2NEumKQB.mjs} +1 -1
  3. package/dist/cli.mjs +5 -4
  4. package/dist/client/assets/{angular-html-ByeJB0rh.js → angular-html-Des_xD-2.js} +1 -1
  5. package/dist/client/assets/{angular-ts-CiwZGajG.js → angular-ts-FXZjKR0Q.js} +1 -1
  6. package/dist/client/assets/{apl-C8k5a5fk.js → apl-CU0GH5rh.js} +1 -1
  7. package/dist/client/assets/{arc-B8VMoqVr.js → arc-DnvfnvVv.js} +1 -1
  8. package/dist/client/assets/{architectureDiagram-3BPJPVTR-C-ng2xNL.js → architectureDiagram-3BPJPVTR-Cb41y9QS.js} +1 -1
  9. package/dist/client/assets/{astro-BE-h-qpp.js → astro-CUWNJBWq.js} +1 -1
  10. package/dist/client/assets/{blade-D-0BV1wW.js → blade-2PPtLT0e.js} +1 -1
  11. package/dist/client/assets/{blockDiagram-GPEHLZMM-DyAQuONU.js → blockDiagram-GPEHLZMM-BYxsiST2.js} +1 -1
  12. package/dist/client/assets/{c-Dg_Gx29H.js → c-D3K42QQV.js} +1 -1
  13. package/dist/client/assets/{c4Diagram-AAUBKEIU-k5uKTHvm.js → c4Diagram-AAUBKEIU-BU7I7J1w.js} +1 -1
  14. package/dist/client/assets/channel-Cx6nXkw1.js +1 -0
  15. package/dist/client/assets/{chunk-2J33WTMH-Dod_VwYj.js → chunk-2J33WTMH-DQnKNewn.js} +1 -1
  16. package/dist/client/assets/{chunk-3OPIFGDE-B8HMjry-.js → chunk-3OPIFGDE-BE6bYzdw.js} +1 -1
  17. package/dist/client/assets/{chunk-4BX2VUAB-TvkJVIZw.js → chunk-4BX2VUAB-CTw-Pjas.js} +1 -1
  18. package/dist/client/assets/{chunk-55IACEB6-BsXuKAKc.js → chunk-55IACEB6-BBCsXXSw.js} +1 -1
  19. package/dist/client/assets/{chunk-5ZQYHXKU-BI1cj2cZ.js → chunk-5ZQYHXKU-BrM_4KH1.js} +1 -1
  20. package/dist/client/assets/{chunk-727SXJPM-yWQ27Wk0.js → chunk-727SXJPM-B_Vz3jyP.js} +1 -1
  21. package/dist/client/assets/{chunk-AQP2D5EJ-B2BBCtTr.js → chunk-AQP2D5EJ-CHSGbbjn.js} +1 -1
  22. package/dist/client/assets/{chunk-BSJP7CBP-CXXvPXhK.js → chunk-BSJP7CBP-D6jlDOzg.js} +1 -1
  23. package/dist/client/assets/{chunk-CSCIHK7Q-jYiloqyi.js → chunk-CSCIHK7Q-D_02XyF0.js} +1 -1
  24. package/dist/client/assets/{chunk-FMBD7UC4-DZzqIT32.js → chunk-FMBD7UC4-DxbqnfDH.js} +1 -1
  25. package/dist/client/assets/{chunk-KSCS5N6A-krdCf8iG.js → chunk-KSCS5N6A-_Pc1IHYq.js} +1 -1
  26. package/dist/client/assets/{chunk-L5ZTLDWV-0uuTmeZV.js → chunk-L5ZTLDWV-Dj8OTMjE.js} +1 -1
  27. package/dist/client/assets/{chunk-LZXEDZCA-BBfUgD06.js → chunk-LZXEDZCA-DQn_LdxZ.js} +2 -2
  28. package/dist/client/assets/{chunk-ND2GUHAM-jkir4ZKE.js → chunk-ND2GUHAM-BYbHwrXp.js} +1 -1
  29. package/dist/client/assets/{chunk-NZK2D7GU-DMWZNibJ.js → chunk-NZK2D7GU-Bvgyac_1.js} +1 -1
  30. package/dist/client/assets/{chunk-O5CBEL6O-B1e1HGaX.js → chunk-O5CBEL6O-DeRRUqxP.js} +1 -1
  31. package/dist/client/assets/chunk-QZHKN3VN-BkYYlBcO.js +1 -0
  32. package/dist/client/assets/chunk-WU5MYG2G-DyGKxcFl.js +1 -0
  33. package/dist/client/assets/{chunk-XPW4576I-AvbCAUav.js → chunk-XPW4576I-BrtDtomN.js} +1 -1
  34. package/dist/client/assets/classDiagram-4FO5ZUOK-DwPqBLeK.js +1 -0
  35. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Mxl80axQ.js +1 -0
  36. package/dist/client/assets/{cobol-DQnGB_GV.js → cobol-hL9_ibhX.js} +1 -1
  37. package/dist/client/assets/{coffee-CDV5a89x.js → coffee-DFRt5qt1.js} +1 -1
  38. package/dist/client/assets/{cose-bilkent-S5V4N54A-t-mDNRF2.js → cose-bilkent-S5V4N54A-DHCJqbho.js} +1 -1
  39. package/dist/client/assets/{cpp-8G6b-siI.js → cpp-3A0aT-dF.js} +1 -1
  40. package/dist/client/assets/{crystal-CGYCC6FM.js → crystal-BzBxs8w6.js} +1 -1
  41. package/dist/client/assets/{css-nez4R8_Z.js → css-C5lLpDbg.js} +1 -1
  42. package/dist/client/assets/{dagre-BM42HDAG--azesYIg.js → dagre-BM42HDAG-DOuf0bNE.js} +1 -1
  43. package/dist/client/assets/{diagram-2AECGRRQ-4WJ7nKhA.js → diagram-2AECGRRQ-Bd5Jiq1y.js} +1 -1
  44. package/dist/client/assets/{diagram-5GNKFQAL-C7ZGhLXn.js → diagram-5GNKFQAL-DvYLKuEY.js} +1 -1
  45. package/dist/client/assets/{diagram-KO2AKTUF-BobK_rbl.js → diagram-KO2AKTUF-BVvqGAtk.js} +1 -1
  46. package/dist/client/assets/{diagram-LMA3HP47-BOc-OkIS.js → diagram-LMA3HP47-QqHAHEnc.js} +1 -1
  47. package/dist/client/assets/{diagram-OG6HWLK6-BEtLgm86.js → diagram-OG6HWLK6-CkG5SOks.js} +1 -1
  48. package/dist/client/assets/{dist-DPuBwToc.js → dist-Dh8NC3tY.js} +1 -1
  49. package/dist/client/assets/{edge-Z5RMbJQv.js → edge-9n_aVc7U.js} +1 -1
  50. package/dist/client/assets/{edit-CFxbgVPV.js → edit-DlkvWCkd.js} +1 -1
  51. package/dist/client/assets/{elixir-d3C79FQc.js → elixir-C7ssdzaK.js} +1 -1
  52. package/dist/client/assets/{elm-CDAf6Uyn.js → elm-CWs6E90H.js} +1 -1
  53. package/dist/client/assets/{erDiagram-TEJ5UH35-D-pR2GY9.js → erDiagram-TEJ5UH35-CfW0k0ip.js} +1 -1
  54. package/dist/client/assets/{erb-CTJk9FKH.js → erb-CdXoY37D.js} +1 -1
  55. package/dist/client/assets/{flowDiagram-I6XJVG4X-BwMCy2QV.js → flowDiagram-I6XJVG4X-CBKpQpqx.js} +1 -1
  56. package/dist/client/assets/{ganttDiagram-6RSMTGT7-BI1WLJDi.js → ganttDiagram-6RSMTGT7-CS13EpgX.js} +1 -1
  57. package/dist/client/assets/{git-rebase-Dr0-MVoW.js → git-rebase-BSoXZvcc.js} +1 -1
  58. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-CUfW0k1f.js → gitGraphDiagram-PVQCEYII-BN0i9pDL.js} +1 -1
  59. package/dist/client/assets/{glimmer-js-CXhLhyW-.js → glimmer-js-BZMH6HKs.js} +1 -1
  60. package/dist/client/assets/{glimmer-ts-BFAFT-VD.js → glimmer-ts-DXSo27g6.js} +1 -1
  61. package/dist/client/assets/{glsl-D7yanhgY.js → glsl-Cl8JUVz8.js} +1 -1
  62. package/dist/client/assets/{graphql-CpoDxrok.js → graphql-CNR_SNqJ.js} +1 -1
  63. package/dist/client/assets/{hack-BL5fmC4q.js → hack-iAxNUz76.js} +1 -1
  64. package/dist/client/assets/{haml-ClAE6RVM.js → haml-D11gKVlW.js} +1 -1
  65. package/dist/client/assets/{handlebars-nHw91uOv.js → handlebars-BAAs9kjt.js} +1 -1
  66. package/dist/client/assets/{html-BIiOKqgG.js → html-C-zWst2_.js} +1 -1
  67. package/dist/client/assets/{html-derivative-D1nPnuOK.js → html-derivative-Bu6k8r8J.js} +1 -1
  68. package/dist/client/assets/{http-B_QcRZjt.js → http-B_xQ7YQ1.js} +1 -1
  69. package/dist/client/assets/{hurl-CZE0DsD3.js → hurl-B7IYz3qL.js} +1 -1
  70. package/dist/client/assets/index-1GDpp-wO.css +1 -0
  71. package/dist/client/assets/{index-Erqhm7rW.js → index-D_eRtjau.js} +49 -49
  72. package/dist/client/assets/{infoDiagram-5YYISTIA-w2M_OHua.js → infoDiagram-5YYISTIA-Choq89cB.js} +1 -1
  73. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CW_l9PGx.js → ishikawaDiagram-YF4QCWOH-CZY99mk-.js} +1 -1
  74. package/dist/client/assets/{java-CXTqX09w.js → java-BPJVzio0.js} +1 -1
  75. package/dist/client/assets/{javascript-9z9ABBep.js → javascript-DiOMtf_A.js} +1 -1
  76. package/dist/client/assets/{jinja-Cluf_5Bk.js → jinja-l7JM-8PK.js} +1 -1
  77. package/dist/client/assets/{jison-CqCEUtc4.js → jison-CAc6lM-g.js} +1 -1
  78. package/dist/client/assets/{journeyDiagram-JHISSGLW-D-YwusBa.js → journeyDiagram-JHISSGLW-CDbADAMs.js} +1 -1
  79. package/dist/client/assets/{json-BMq_bPP8.js → json-DqZO-AEh.js} +1 -1
  80. package/dist/client/assets/{jsx-Djij59b9.js → jsx-UqnCpKTP.js} +1 -1
  81. package/dist/client/assets/{julia-DybzCMnh.js → julia-DlbfYJz3.js} +1 -1
  82. package/dist/client/assets/{just-4ChcAr9-.js → just-9ze8Wi6d.js} +1 -1
  83. package/dist/client/assets/{kanban-definition-UN3LZRKU-Brvoukmm.js → kanban-definition-UN3LZRKU-DgrkeisF.js} +1 -1
  84. package/dist/client/assets/{latex-CS2TtFXG.js → latex-_9Fzq-E3.js} +1 -1
  85. package/dist/client/assets/{line-CqxM-stA.js → line-b-Rcrqbg.js} +1 -1
  86. package/dist/client/assets/{linear-C7T82059.js → linear-C_RFbWEw.js} +1 -1
  87. package/dist/client/assets/{liquid-84AtYenm.js → liquid-CMiBoRv6.js} +1 -1
  88. package/dist/client/assets/{lua-DJzFx3Cf.js → lua-BzfULkCh.js} +1 -1
  89. package/dist/client/assets/{marko-BLw9BV9E.js → marko-BfcVqnF5.js} +1 -1
  90. package/dist/client/assets/{mdc-BjZejN3b.js → mdc-BKqkdcKC.js} +1 -1
  91. package/dist/client/assets/{mermaid-parser.core-BdiEBAsd.js → mermaid-parser.core-DiJRF2JX.js} +1 -1
  92. package/dist/client/assets/{mermaid.core-BsnKhnrM.js → mermaid.core-2WkwaCuC.js} +3 -3
  93. package/dist/client/assets/{mindmap-definition-RKZ34NQL-CBaIFnbc.js → mindmap-definition-RKZ34NQL-BYxdNWsh.js} +1 -1
  94. package/dist/client/assets/{nginx-DuamCwvX.js → nginx-DiNLSsbI.js} +1 -1
  95. package/dist/client/assets/{nim-Bt8c9-ge.js → nim-CohF0tPX.js} +1 -1
  96. package/dist/client/assets/{perl-D52AfmwC.js → perl-Q-a6BHYR.js} +1 -1
  97. package/dist/client/assets/{php-BBMlJg0_.js → php-DEj4odG7.js} +1 -1
  98. package/dist/client/assets/{pieDiagram-4H26LBE5-BlmPajcA.js → pieDiagram-4H26LBE5-DIMAUXZJ.js} +1 -1
  99. package/dist/client/assets/{pug-DFHmDqEE.js → pug-vqq1Jo-6.js} +1 -1
  100. package/dist/client/assets/{qml-C0333o-g.js → qml-DkOoIH_j.js} +1 -1
  101. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Bqlm_zZk.js → quadrantDiagram-W4KKPZXB-DKoe-k2E.js} +1 -1
  102. package/dist/client/assets/{r-DZFmvIgR.js → r-Cen6c1F0.js} +1 -1
  103. package/dist/client/assets/{razor-BIGLkWzR.js → razor-SY8AQA9t.js} +1 -1
  104. package/dist/client/assets/{regexp-BW6jpgf9.js → regexp-CjphwwlN.js} +1 -1
  105. package/dist/client/assets/{requirementDiagram-4Y6WPE33-B1PrtUeD.js → requirementDiagram-4Y6WPE33-Du9fS-Dw.js} +1 -1
  106. package/dist/client/assets/{review-export-BlgD3bdw.js → review-export-FIT7B1uP.js} +1 -1
  107. package/dist/client/assets/{rst-Cj51ZJaa.js → rst-B79v9bjn.js} +1 -1
  108. package/dist/client/assets/{ruby-lMhGjwpf.js → ruby-Dia4QaOO.js} +1 -1
  109. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-D2HtUNVF.js → sankeyDiagram-5OEKKPKP-CsezsM2Z.js} +1 -1
  110. package/dist/client/assets/{sas-BWSQku7l.js → sas-CYRTwHiQ.js} +1 -1
  111. package/dist/client/assets/{scss-CdRPuhLN.js → scss-DNWCy5-q.js} +1 -1
  112. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-D9SQy0XI.js → sequenceDiagram-3UESZ5HK-CNovbaFC.js} +1 -1
  113. package/dist/client/assets/{shellscript-DOfOBXcj.js → shellscript-BSQLDkAe.js} +1 -1
  114. package/dist/client/assets/{shellsession-7XAOCVni.js → shellsession-CfvHV3oR.js} +1 -1
  115. package/dist/client/assets/{soy-DDnzVRIw.js → soy-DLwu5RtN.js} +1 -1
  116. package/dist/client/assets/{sql-Ba34agKe.js → sql-DlyzTy0P.js} +1 -1
  117. package/dist/client/assets/{src-BO-qT_v_.js → src-DNJJnOd8.js} +1 -1
  118. package/dist/client/assets/{stata-BQlYGHQU.js → stata-Djh-WYVT.js} +1 -1
  119. package/dist/client/assets/{stateDiagram-AJRCARHV-7IEYjFRo.js → stateDiagram-AJRCARHV-cV6R_6CN.js} +1 -1
  120. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-jmBy204V.js +1 -0
  121. package/dist/client/assets/{surrealql-BET1l7SW.js → surrealql-Cu-G0NVH.js} +1 -1
  122. package/dist/client/assets/{svelte-Bd7ZOeQI.js → svelte-CDA2MakI.js} +1 -1
  123. package/dist/client/assets/{templ-BYvRQdOw.js → templ-H2xc1tDE.js} +1 -1
  124. package/dist/client/assets/{tex-CT8DpKxX.js → tex-DJ6mQsYC.js} +1 -1
  125. package/dist/client/assets/{timeline-definition-PNZ67QCA-CurQYWmi.js → timeline-definition-PNZ67QCA-BlCMASdx.js} +1 -1
  126. package/dist/client/assets/{ts-tags-D4iPPwau.js → ts-tags-bYEWgmJO.js} +1 -1
  127. package/dist/client/assets/{tsx-Dgk_Aw-B.js → tsx-CtTBiWFd.js} +1 -1
  128. package/dist/client/assets/{twig-abRNWeh3.js → twig-CgXr9wNF.js} +1 -1
  129. package/dist/client/assets/{typescript-BgR1JqdC.js → typescript-Na7Lj9Vl.js} +1 -1
  130. package/dist/client/assets/{vennDiagram-CIIHVFJN-DbrRBL5S.js → vennDiagram-CIIHVFJN-CvcrIycD.js} +1 -1
  131. package/dist/client/assets/{vue-DSkhKq4Q.js → vue-BtOd_AfK.js} +1 -1
  132. package/dist/client/assets/{vue-html-J0jWoD9X.js → vue-html-CVlcjzDD.js} +1 -1
  133. package/dist/client/assets/{vue-vine-BgX5MC8-.js → vue-vine-k7M6KtfE.js} +1 -1
  134. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DIFXQsoP.js → wardleyDiagram-YWT4CUSO-BUDJvh59.js} +1 -1
  135. package/dist/client/assets/{xml-Ca53xGLB.js → xml-Brz46P3k.js} +1 -1
  136. package/dist/client/assets/{xsl-CNnXclYV.js → xsl-Bh5vdfXi.js} +1 -1
  137. package/dist/client/assets/{xychartDiagram-2RQKCTM6-CmfInPqa.js → xychartDiagram-2RQKCTM6-T2Bb0lF_.js} +1 -1
  138. package/dist/client/assets/{yaml-CjjyUhfg.js → yaml-CRsmB7sL.js} +1 -1
  139. package/dist/client/index.html +2 -2
  140. package/dist/{completions-7YSX1neu.mjs → completions-2aHVTmiJ.mjs} +17 -0
  141. package/dist/completions-CYa5usLb.mjs +2 -0
  142. package/dist/{mcp-BgrRjzn3.mjs → mcp-H7ytYScV.mjs} +430 -23
  143. package/dist/mockup-format-CM3ivHHX.mjs +322 -0
  144. package/dist/native/tui-darwin-arm64/diffing-tui +0 -0
  145. package/dist/native/tui-darwin-x64/diffing-tui +0 -0
  146. package/dist/native/tui-linux-arm64-gnu/diffing-tui +0 -0
  147. package/dist/native/tui-linux-arm64-musl/diffing-tui +0 -0
  148. package/dist/native/tui-linux-x64-gnu/diffing-tui +0 -0
  149. package/dist/native/tui-linux-x64-musl/diffing-tui +0 -0
  150. package/dist/native/tui-win32-x64-msvc/diffing-tui.exe +0 -0
  151. package/dist/{review-export-GW4KNsGN.mjs → review-export-DoST2oPt.mjs} +1 -1
  152. package/dist/{server-Ct9QuV1l.mjs → server-CiE24vh-.mjs} +1842 -53
  153. package/dist/{setup-BnS_rSxK.mjs → setup-BwWZ9Fzq.mjs} +1 -1
  154. package/extensions/pi/index.ts +453 -5
  155. package/package.json +2 -1
  156. package/dist/client/assets/channel-DsuXeLi4.js +0 -1
  157. package/dist/client/assets/chunk-QZHKN3VN-D5b3mBJ2.js +0 -1
  158. package/dist/client/assets/chunk-WU5MYG2G-C1Pa4Y04.js +0 -1
  159. package/dist/client/assets/classDiagram-4FO5ZUOK-DCnVfYt-.js +0 -1
  160. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BPa1Jkt-.js +0 -1
  161. package/dist/client/assets/index-BR6EGJ-g.css +0 -1
  162. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DP6swlL9.js +0 -1
  163. package/dist/completions-5rtfoxB9.mjs +0 -2
  164. package/dist/plan-format-BwJh5JSE.mjs +0 -144
  165. /package/dist/{comment-format-B85NHZnG.mjs → comment-format-D4mCqr7T.mjs} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { S as isGitRepo, h as getRepoRoot } from "./git-BGj31GX-.mjs";
2
2
  import { a as markSetupCompleted, i as loadSettings, n as formatModeLabel, o as resetSetupCompleted, r as isSetupCompleted, s as saveSettings, t as ensureConfigDir } from "./settings-DkPDB_hS.mjs";
3
- import { n as completionFor } from "./completions-7YSX1neu.mjs";
3
+ import { n as completionFor } from "./completions-2aHVTmiJ.mjs";
4
4
  import { a as hintLine, c as stepHeader, i as dim, l as tone, n as box, o as isColorEnabled, r as copyBlock, s as rule, t as bold } from "./terminal-BroplOnw.mjs";
5
5
  import { n as runDoctor, t as formatDoctorReport } from "./doctor-BxTaLqAF.mjs";
6
6
  import { t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-i1o7DBki.mjs";
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Bridges the local-first diffing review loop into pi:
5
5
  * - Structured LLM tools mirroring the diffing MCP surface (status, review
6
- * start, comments, reply/resolve, plan loop, progress, sessions, GH PR).
6
+ * start, comments, reply/resolve, plan loop, mockup loop, progress,
7
+ * sessions, GH PR).
7
8
  * - `/diffing` command to open/reuse the review UI for the current repo.
8
9
  * - Footer status showing the active review session.
9
10
  * - Skill self-heal: keeps `~/.agents/skills/diffing*` as symlinks to the
@@ -20,12 +21,14 @@ import { spawn } from "node:child_process";
20
21
  import {
21
22
  existsSync,
22
23
  lstatSync,
24
+ mkdtempSync,
23
25
  readFileSync,
24
26
  realpathSync,
25
27
  rmSync,
26
28
  symlinkSync,
29
+ writeFileSync,
27
30
  } from "node:fs";
28
- import { homedir } from "node:os";
31
+ import { homedir, tmpdir } from "node:os";
29
32
  import { dirname, join, resolve } from "node:path";
30
33
  import { fileURLToPath } from "node:url";
31
34
  import { StringEnum } from "@earendil-works/pi-ai";
@@ -42,9 +45,11 @@ import { Type } from "typebox";
42
45
  const SKILL_NAMES = [
43
46
  "diffing",
44
47
  "diffing-finish-review",
48
+ "diffing-mockup-review",
45
49
  "diffing-plan-review",
46
50
  "diffing-pr-address",
47
51
  "diffing-pr-read",
52
+ "diffing-release",
48
53
  "diffing-review",
49
54
  "diffing-start-review",
50
55
  ] as const;
@@ -243,12 +248,12 @@ function findCanonicalRoot(cwd: string): string | null {
243
248
  }
244
249
 
245
250
  /**
246
- * Keep the 7 `~/.agents/skills/diffing*` entries as symlinks to the canonical
251
+ * Keep the `~/.agents/skills/diffing*` entries as symlinks to the canonical
247
252
  * checkout's `.agents/skills`. pi dedupes skills by canonical realpath, so
248
253
  * symlinked home entries merge silently with the repo's project skills and no
249
254
  * `[Skill conflicts]` banner appears. Repairs stale real copies left behind by
250
- * `diffing setup skills` / `npx skills add --copy`. Only touches the 7 known
251
- * names; never deletes anything else.
255
+ * `diffing setup skills` / `npx skills add --copy`. Only touches the known
256
+ * names in SKILL_NAMES; never deletes anything else.
252
257
  */
253
258
  function selfHealSkillLinks(canonical: string): void {
254
259
  const homeSkills = join(homedir(), ".agents", "skills");
@@ -815,6 +820,449 @@ export default function (pi: ExtensionAPI) {
815
820
  },
816
821
  });
817
822
 
823
+ pi.registerTool({
824
+ name: "diffing_mockup_submit",
825
+ label: "Diffing Mockup Submit",
826
+ description:
827
+ "Submit HTML mockup screen(s) for visual review. Pass a single html body, a file/dir path, or an inline screens array [{id, html}]. Share the URL and park unless asked to wait. Resubmit with mockupId to bump the version and reset the verdict.",
828
+ parameters: Type.Object({
829
+ html: Type.Optional(
830
+ Type.String({ description: "Single-screen HTML body." }),
831
+ ),
832
+ file: Type.Optional(
833
+ Type.String({
834
+ description:
835
+ "HTML file or directory of screens (never inside the consumer git tree).",
836
+ }),
837
+ ),
838
+ screens: Type.Optional(
839
+ Type.Array(
840
+ Type.Object({
841
+ id: Type.String({ description: "Screen id (slugified)." }),
842
+ html: Type.String({ description: "Screen HTML body." }),
843
+ }),
844
+ {
845
+ description:
846
+ "Multi-screen: array of {id, html}. Mutually exclusive with html/file.",
847
+ },
848
+ ),
849
+ ),
850
+ title: Type.Optional(Type.String()),
851
+ mockupId: Type.Optional(
852
+ Type.String({ description: "Resubmit this id." }),
853
+ ),
854
+ model: Type.Optional(Type.String()),
855
+ source: Type.Optional(Type.String()),
856
+ }),
857
+ async execute(_id, params, _signal, _onUpdate, ctx) {
858
+ const args = ["mockup", "submit"];
859
+ let stdin: string | undefined;
860
+ let cleanup: (() => void) | undefined;
861
+ const screens = Array.isArray(params.screens) ? params.screens : [];
862
+ if (screens.length > 0) {
863
+ const dir = mkdtempSync(join(tmpdir(), "diffing-mockup-"));
864
+ cleanup = () => {
865
+ try {
866
+ rmSync(dir, { recursive: true, force: true });
867
+ } catch {
868
+ // best-effort cleanup of the staging dir
869
+ }
870
+ };
871
+ for (let i = 0; i < screens.length; i++) {
872
+ const id =
873
+ String(screens[i]?.id ?? "")
874
+ .trim()
875
+ .toLowerCase()
876
+ .replace(/\.html?$/i, "")
877
+ .replace(/[^a-z0-9_-]+/g, "-")
878
+ .replace(/^-+|-+$/g, "") || `screen-${i + 1}`;
879
+ const file = join(dir, `${id}.html`);
880
+ writeFileSync(file, String(screens[i]?.html ?? ""), "utf-8");
881
+ args.push("--screen", `${id}=${file}`);
882
+ }
883
+ } else if (params.file) {
884
+ args.push(params.file);
885
+ } else if (params.html !== undefined) {
886
+ args.push("-");
887
+ stdin = params.html;
888
+ } else {
889
+ return textResult(
890
+ "Provide one of html (single screen), file (path/dir), or screens ([{id, html}]).",
891
+ { submitted: false },
892
+ );
893
+ }
894
+ if (params.title) args.push("--title", params.title);
895
+ if (params.mockupId) args.push("--id", params.mockupId);
896
+ if (params.model) args.push("--model", params.model);
897
+ if (params.source) args.push("--source", params.source);
898
+ try {
899
+ const result = await runDiffing(args, ctx.cwd, { stdin });
900
+ const stdout = result.stdout.trim();
901
+ const stderr = result.stderr.trim();
902
+ if (result.exitCode !== 0) {
903
+ return textResult(describe(result, "diffing mockup submit"), {
904
+ submitted: false,
905
+ exitCode: result.exitCode,
906
+ stderr,
907
+ });
908
+ }
909
+ return textResult(`${stdout}\n${stderr}`.trim() || "(submitted)", {
910
+ submitted: true,
911
+ mockupId: stdout || undefined,
912
+ url: stderr || undefined,
913
+ });
914
+ } finally {
915
+ cleanup?.();
916
+ }
917
+ },
918
+ });
919
+
920
+ pi.registerTool({
921
+ name: "diffing_mockup_await",
922
+ label: "Diffing Mockup Await",
923
+ description:
924
+ "Sync wait for a mockup verdict. Prefer park after submit unless asked to wait.",
925
+ parameters: Type.Object({
926
+ timeout: Type.Optional(
927
+ Type.Number({ description: "Seconds to wait. Default 25." }),
928
+ ),
929
+ }),
930
+ async execute(_id, params, signal, _onUpdate, ctx) {
931
+ const timeout = params.timeout ?? 25;
932
+ const result = await runDiffing(
933
+ ["mockup", "await", "-t", String(timeout)],
934
+ ctx.cwd,
935
+ { signal },
936
+ );
937
+ if (result.exitCode === 2) {
938
+ return textResult(
939
+ `No mockup verdict within ${timeout}s (park). Share the mockup URL and end your turn.`,
940
+ { parked: true, exitCode: result.exitCode },
941
+ );
942
+ }
943
+ return textResult(describe(result, "diffing mockup await"), {
944
+ parked: false,
945
+ exitCode: result.exitCode,
946
+ stderr: result.stderr.trim() || undefined,
947
+ });
948
+ },
949
+ });
950
+
951
+ pi.registerTool({
952
+ name: "diffing_mockup_reply",
953
+ label: "Diffing Mockup Reply",
954
+ description: "Reply to a mockup comment thread.",
955
+ parameters: Type.Object({
956
+ commentId: Type.String(),
957
+ body: Type.String(),
958
+ model: Type.Optional(Type.String()),
959
+ }),
960
+ async execute(_id, params, _signal, _onUpdate, ctx) {
961
+ const result = await runDiffing(
962
+ [
963
+ "mockup",
964
+ "reply",
965
+ params.commentId,
966
+ "-",
967
+ "--model",
968
+ modelName(ctx, params.model),
969
+ ],
970
+ ctx.cwd,
971
+ { stdin: params.body },
972
+ );
973
+ return textResult(
974
+ describe(result, `diffing mockup reply ${params.commentId}`),
975
+ {
976
+ exitCode: result.exitCode,
977
+ stderr: result.stderr.trim() || undefined,
978
+ },
979
+ );
980
+ },
981
+ });
982
+
983
+ pi.registerTool({
984
+ name: "diffing_mockup_resolve",
985
+ label: "Diffing Mockup Resolve",
986
+ description: "Mark a mockup comment resolved.",
987
+ parameters: Type.Object({
988
+ commentId: Type.String(),
989
+ }),
990
+ async execute(_id, params, _signal, _onUpdate, ctx) {
991
+ const result = await runDiffing(
992
+ ["mockup", "resolve", params.commentId],
993
+ ctx.cwd,
994
+ );
995
+ return textResult(
996
+ describe(result, `diffing mockup resolve ${params.commentId}`),
997
+ {
998
+ exitCode: result.exitCode,
999
+ stderr: result.stderr.trim() || undefined,
1000
+ },
1001
+ );
1002
+ },
1003
+ });
1004
+
1005
+ pi.registerTool({
1006
+ name: "diffing_mockup_list",
1007
+ label: "Diffing Mockup List",
1008
+ description:
1009
+ "List submitted HTML mockups for this repo (id, decision, version, screen count, open comments, title).",
1010
+ parameters: Type.Object({
1011
+ json: Type.Optional(
1012
+ Type.Boolean({ description: "Emit raw JSON. Default: false." }),
1013
+ ),
1014
+ }),
1015
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1016
+ const args = ["mockup", "list"];
1017
+ if (params.json) args.push("--json");
1018
+ const result = await runDiffing(args, ctx.cwd);
1019
+ return textResult(describe(result, "diffing mockup list"), {
1020
+ exitCode: result.exitCode,
1021
+ stderr: result.stderr.trim() || undefined,
1022
+ });
1023
+ },
1024
+ });
1025
+
1026
+ pi.registerTool({
1027
+ name: "diffing_mockup_show",
1028
+ label: "Diffing Mockup Show",
1029
+ description:
1030
+ "Fetch one mockup by id (defaults to the latest), including screens and comments. Prefer diffing_mockup_inspect for bounded reads.",
1031
+ parameters: Type.Object({
1032
+ mockupId: Type.Optional(
1033
+ Type.String({ description: "Mockup id. Default: latest." }),
1034
+ ),
1035
+ version: Type.Optional(
1036
+ Type.Number({ description: "Historical version to render." }),
1037
+ ),
1038
+ json: Type.Optional(
1039
+ Type.Boolean({ description: "Emit raw JSON. Default: false." }),
1040
+ ),
1041
+ }),
1042
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1043
+ const args = ["mockup", "show"];
1044
+ if (params.mockupId) args.push(params.mockupId);
1045
+ if (params.version !== undefined)
1046
+ args.push("--version", String(params.version));
1047
+ if (params.json) args.push("--json");
1048
+ const result = await runDiffing(args, ctx.cwd);
1049
+ return textResult(describe(result, "diffing mockup show"), {
1050
+ exitCode: result.exitCode,
1051
+ stderr: result.stderr.trim() || undefined,
1052
+ });
1053
+ },
1054
+ });
1055
+
1056
+ pi.registerTool({
1057
+ name: "diffing_mockup_versions",
1058
+ label: "Diffing Mockup Versions",
1059
+ description: "List version snapshots for a mockup.",
1060
+ parameters: Type.Object({
1061
+ mockupId: Type.String({ description: "Mockup id." }),
1062
+ json: Type.Optional(
1063
+ Type.Boolean({ description: "Emit raw JSON. Default: false." }),
1064
+ ),
1065
+ }),
1066
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1067
+ const args = ["mockup", "versions", params.mockupId];
1068
+ if (params.json) args.push("--json");
1069
+ const result = await runDiffing(args, ctx.cwd);
1070
+ return textResult(describe(result, "diffing mockup versions"), {
1071
+ exitCode: result.exitCode,
1072
+ stderr: result.stderr.trim() || undefined,
1073
+ });
1074
+ },
1075
+ });
1076
+
1077
+ pi.registerTool({
1078
+ name: "diffing_mockup_inspect",
1079
+ label: "Diffing Mockup Inspect",
1080
+ description:
1081
+ "Read compact, bounded mockup data without transferring screen HTML. view=summary (headline stats), comments (paged comment list), comment (one thread), screen (screen source). Filter by comment scope: status, screenId, viewport (desktop|tablet|mobile), version. context=none|anchor|source controls anchor detail. Prefer this over diffing_mockup_show.",
1082
+ parameters: Type.Object({
1083
+ view: StringEnum(["summary", "comments", "comment", "screen"] as const, {
1084
+ description: "What to read. Default: summary.",
1085
+ default: "summary",
1086
+ }),
1087
+ mockupId: Type.Optional(
1088
+ Type.String({ description: "Mockup id. Default: latest." }),
1089
+ ),
1090
+ status: Type.Optional(
1091
+ StringEnum(["open", "resolved"] as const, {
1092
+ description: "Filter comments by status.",
1093
+ }),
1094
+ ),
1095
+ screenId: Type.Optional(
1096
+ Type.String({ description: "Filter by screen id." }),
1097
+ ),
1098
+ viewport: Type.Optional(
1099
+ StringEnum(["desktop", "tablet", "mobile"] as const, {
1100
+ description: "Filter by viewport.",
1101
+ }),
1102
+ ),
1103
+ version: Type.Optional(
1104
+ Type.Number({
1105
+ description:
1106
+ "Filter comments by the mockup version they were created on.",
1107
+ }),
1108
+ ),
1109
+ commentId: Type.Optional(
1110
+ Type.String({ description: "For view=comment: the thread id." }),
1111
+ ),
1112
+ cursor: Type.Optional(Type.Number({ description: "Pagination cursor." })),
1113
+ limit: Type.Optional(
1114
+ Type.Number({ description: "Max results per page." }),
1115
+ ),
1116
+ context: Type.Optional(
1117
+ StringEnum(["none", "anchor", "source"] as const, {
1118
+ description:
1119
+ "Anchor detail: none, anchor (locators), source (+contextHtml). Default: anchor.",
1120
+ default: "anchor",
1121
+ }),
1122
+ ),
1123
+ pretty: Type.Optional(
1124
+ Type.Boolean({ description: "Indent JSON output." }),
1125
+ ),
1126
+ }),
1127
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1128
+ const args = ["mockup", "inspect", params.view ?? "summary"];
1129
+ if (params.mockupId) args.push(params.mockupId);
1130
+ if (params.status) args.push("--status", params.status);
1131
+ if (params.screenId) args.push("--screen", params.screenId);
1132
+ if (params.viewport) args.push("--viewport", params.viewport);
1133
+ if (params.version !== undefined)
1134
+ args.push("--version", String(params.version));
1135
+ if (params.commentId) args.push("--id", params.commentId);
1136
+ if (params.cursor !== undefined)
1137
+ args.push("--cursor", String(params.cursor));
1138
+ if (params.limit !== undefined)
1139
+ args.push("--limit", String(params.limit));
1140
+ if (params.context) args.push("--context", params.context);
1141
+ if (params.pretty) args.push("--pretty");
1142
+ const result = await runDiffing(args, ctx.cwd);
1143
+ return textResult(describe(result, "diffing mockup inspect"), {
1144
+ exitCode: result.exitCode,
1145
+ stderr: result.stderr.trim() || undefined,
1146
+ });
1147
+ },
1148
+ });
1149
+
1150
+ pi.registerTool({
1151
+ name: "diffing_mockup_screen",
1152
+ label: "Diffing Mockup Screen",
1153
+ description:
1154
+ "One-screen revision of an HTML mockup. action=upsert adds/replaces a screen (html or file), remove deletes a screen, patch replaces the first exact occurrence of text with replacement. Every success bumps the mockup version; pass expectedVersion to guard racing edits (409 version-mismatch, nothing applied). For multi-screen revisions, resubmit via diffing_mockup_submit with the same mockupId.",
1155
+ parameters: Type.Object({
1156
+ action: StringEnum(["upsert", "remove", "patch"] as const, {
1157
+ description: "Revision op.",
1158
+ }),
1159
+ mockupId: Type.String({ description: "Mockup id." }),
1160
+ screenId: Type.String({ description: "Screen id." }),
1161
+ html: Type.Optional(
1162
+ Type.String({
1163
+ description: "For upsert: inline screen HTML (alternative to file).",
1164
+ }),
1165
+ ),
1166
+ file: Type.Optional(
1167
+ Type.String({
1168
+ description: "For upsert: HTML file path; '-' for stdin.",
1169
+ }),
1170
+ ),
1171
+ label: Type.Optional(
1172
+ Type.String({ description: "For upsert: optional screen label." }),
1173
+ ),
1174
+ text: Type.Optional(
1175
+ Type.String({
1176
+ description: "For patch: exact text to replace (first occurrence).",
1177
+ }),
1178
+ ),
1179
+ replacement: Type.Optional(
1180
+ Type.String({ description: "For patch: replacement text." }),
1181
+ ),
1182
+ expectedVersion: Type.Optional(
1183
+ Type.Number({
1184
+ description: "Guard: current mockup version. 409 on mismatch.",
1185
+ }),
1186
+ ),
1187
+ }),
1188
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1189
+ const args = [
1190
+ "mockup",
1191
+ "screen",
1192
+ params.action,
1193
+ params.mockupId,
1194
+ params.screenId,
1195
+ ];
1196
+ let stdin: string | undefined;
1197
+ if (params.action === "upsert") {
1198
+ if (params.file) args.push("--file", params.file);
1199
+ else if (params.html !== undefined) {
1200
+ args.push("--file", "-");
1201
+ stdin = params.html;
1202
+ }
1203
+ if (params.label) args.push("--label", params.label);
1204
+ } else if (params.action === "patch") {
1205
+ if (params.text !== undefined) args.push("--text", params.text);
1206
+ if (params.replacement !== undefined)
1207
+ args.push("--replacement", params.replacement);
1208
+ }
1209
+ if (params.expectedVersion !== undefined)
1210
+ args.push("--expected-version", String(params.expectedVersion));
1211
+ const result = await runDiffing(args, ctx.cwd, { stdin });
1212
+ return textResult(describe(result, "diffing mockup screen"), {
1213
+ exitCode: result.exitCode,
1214
+ stderr: result.stderr.trim() || undefined,
1215
+ });
1216
+ },
1217
+ });
1218
+
1219
+ pi.registerTool({
1220
+ name: "diffing_mockup_threads",
1221
+ label: "Diffing Mockup Threads",
1222
+ description:
1223
+ "Atomic single-op mockup thread mutation: reply (agent answer), edit (comment body or a reply), delete (comment or reply), resolve, unresolve. Thread ops never bump the mockup version. For several ops, call once per op; each call is validated before apply.",
1224
+ parameters: Type.Object({
1225
+ action: StringEnum(
1226
+ ["reply", "edit", "delete", "resolve", "unresolve"] as const,
1227
+ { description: "Thread op." },
1228
+ ),
1229
+ commentId: Type.String({ description: "Comment thread id." }),
1230
+ replyId: Type.Optional(
1231
+ Type.String({
1232
+ description:
1233
+ "For edit/delete: target a reply instead of the comment.",
1234
+ }),
1235
+ ),
1236
+ body: Type.Optional(
1237
+ Type.String({ description: "For reply/edit: markdown body." }),
1238
+ ),
1239
+ model: Type.Optional(
1240
+ Type.String({
1241
+ description:
1242
+ "For reply: authoring model. Defaults to the active model.",
1243
+ }),
1244
+ ),
1245
+ mockupId: Type.Optional(
1246
+ Type.String({
1247
+ description:
1248
+ "Owning mockup id (auto-detected from commentId when omitted).",
1249
+ }),
1250
+ ),
1251
+ }),
1252
+ async execute(_id, params, _signal, _onUpdate, ctx) {
1253
+ const args = ["mockup", "threads", params.action, params.commentId];
1254
+ if (params.replyId) args.push(params.replyId);
1255
+ if (params.body !== undefined) args.push("--body", params.body);
1256
+ if (params.model) args.push("--model", modelName(ctx, params.model));
1257
+ if (params.mockupId) args.push("--id", params.mockupId);
1258
+ const result = await runDiffing(args, ctx.cwd);
1259
+ return textResult(describe(result, "diffing mockup threads"), {
1260
+ exitCode: result.exitCode,
1261
+ stderr: result.stderr.trim() || undefined,
1262
+ });
1263
+ },
1264
+ });
1265
+
818
1266
  pi.registerTool({
819
1267
  name: "diffing_url",
820
1268
  label: "Diffing URL",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffing",
3
- "version": "0.16.1",
3
+ "version": "0.18.0",
4
4
  "description": "local-first CLI for reviewing, navigating, and discussing git diffs with AI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -56,6 +56,7 @@
56
56
  "verify:release-bundle": "node scripts/verify-tui-bundle.mjs",
57
57
  "prepublishOnly": "pnpm run verify:release-bundle",
58
58
  "version-packages": "changeset version",
59
+ "release": "node scripts/release.mjs",
59
60
  "docs:dev": "pnpm --dir site dev",
60
61
  "docs:build": "pnpm --dir site build",
61
62
  "docs:preview": "pnpm --dir site preview"
@@ -1 +0,0 @@
1
- import{at as e,ot as t}from"./chunk-CSCIHK7Q-jYiloqyi.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
@@ -1 +0,0 @@
1
- import{h as e}from"./src-BO-qT_v_.js";var t=class{constructor(e){this.init=e,this.records=this.init()}static{e(this,`ImperativeState`)}reset(){this.records=this.init()}};export{t};
@@ -1 +0,0 @@
1
- import{h as e,p as t}from"./src-BO-qT_v_.js";import{x as n}from"./chunk-CSCIHK7Q-jYiloqyi.js";var r=e(e=>{let{securityLevel:r}=n(),i=t(`body`);return r===`sandbox`&&(i=t((t(`#i${e}`).node()?.contentDocument??document).body)),i.select(`#${e}`)},`selectSvgElement`);export{r as t};
@@ -1 +0,0 @@
1
- import{h as e}from"./src-BO-qT_v_.js";import"./chunk-CSCIHK7Q-jYiloqyi.js";import"./chunk-5ZQYHXKU-BI1cj2cZ.js";import"./chunk-O5CBEL6O-B1e1HGaX.js";import"./chunk-FMBD7UC4-DZzqIT32.js";import"./chunk-BSJP7CBP-CXXvPXhK.js";import"./chunk-L5ZTLDWV-0uuTmeZV.js";import"./chunk-ND2GUHAM-jkir4ZKE.js";import"./chunk-55IACEB6-BsXuKAKc.js";import"./chunk-2J33WTMH-Dod_VwYj.js";import"./chunk-NZK2D7GU-DMWZNibJ.js";import"./chunk-3OPIFGDE-B8HMjry-.js";import"./chunk-KSCS5N6A-krdCf8iG.js";import"./chunk-LZXEDZCA-BBfUgD06.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-yWQ27Wk0.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import{h as e}from"./src-BO-qT_v_.js";import"./chunk-CSCIHK7Q-jYiloqyi.js";import"./chunk-5ZQYHXKU-BI1cj2cZ.js";import"./chunk-O5CBEL6O-B1e1HGaX.js";import"./chunk-FMBD7UC4-DZzqIT32.js";import"./chunk-BSJP7CBP-CXXvPXhK.js";import"./chunk-L5ZTLDWV-0uuTmeZV.js";import"./chunk-ND2GUHAM-jkir4ZKE.js";import"./chunk-55IACEB6-BsXuKAKc.js";import"./chunk-2J33WTMH-Dod_VwYj.js";import"./chunk-NZK2D7GU-DMWZNibJ.js";import"./chunk-3OPIFGDE-B8HMjry-.js";import"./chunk-KSCS5N6A-krdCf8iG.js";import"./chunk-LZXEDZCA-BBfUgD06.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-yWQ27Wk0.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};