diffing 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +56 -801
  2. package/dist/{cli-agent-DkwGxuy2.mjs → cli-agent-Cx2k0Ki7.mjs} +236 -59
  3. package/dist/{cli-gh-D0NfKpOp.mjs → cli-gh-BQuQpV-s.mjs} +24 -14
  4. package/dist/cli.mjs +69 -26
  5. package/dist/client/assets/{angular-html-Dl53kkiy.js → angular-html-gcUdctE_.js} +1 -1
  6. package/dist/client/assets/{angular-ts-wNJFFkey.js → angular-ts-BkjLgJJH.js} +1 -1
  7. package/dist/client/assets/{apl-BxtQST-h.js → apl-BtuEza96.js} +1 -1
  8. package/dist/client/assets/{arc-CBmZuzPB.js → arc-yk_3cjs2.js} +1 -1
  9. package/dist/client/assets/{architectureDiagram-3BPJPVTR-CEci_K9f.js → architectureDiagram-3BPJPVTR-DDVXPdzY.js} +1 -1
  10. package/dist/client/assets/{astro-BpADD5rh.js → astro-DfUNgEjV.js} +1 -1
  11. package/dist/client/assets/{blade-B4I5SQmP.js → blade-uv3PNTww.js} +1 -1
  12. package/dist/client/assets/{blockDiagram-GPEHLZMM-DcKhDtnE.js → blockDiagram-GPEHLZMM-DlMLqbfD.js} +1 -1
  13. package/dist/client/assets/{c-C3VtOgg8.js → c-DcsMh0kd.js} +1 -1
  14. package/dist/client/assets/{c4Diagram-AAUBKEIU-CaHozoxF.js → c4Diagram-AAUBKEIU-C4ZZJAMJ.js} +1 -1
  15. package/dist/client/assets/channel-CPOnEOhs.js +1 -0
  16. package/dist/client/assets/{chunk-2J33WTMH-tvuzKhdK.js → chunk-2J33WTMH-CwkSvLT8.js} +1 -1
  17. package/dist/client/assets/{chunk-3OPIFGDE-D_nBoD9w.js → chunk-3OPIFGDE-s6UH12Df.js} +1 -1
  18. package/dist/client/assets/{chunk-4BX2VUAB-yHPdy1G8.js → chunk-4BX2VUAB-wGjYymx_.js} +1 -1
  19. package/dist/client/assets/{chunk-55IACEB6-yXpL8wjV.js → chunk-55IACEB6-DObbP11Q.js} +1 -1
  20. package/dist/client/assets/{chunk-5ZQYHXKU-DZ5cvCDV.js → chunk-5ZQYHXKU-DwbkzQEJ.js} +1 -1
  21. package/dist/client/assets/{chunk-727SXJPM-CJjgOWmY.js → chunk-727SXJPM-DzoJfly4.js} +1 -1
  22. package/dist/client/assets/{chunk-AQP2D5EJ-CQYQKXSE.js → chunk-AQP2D5EJ-f1kNxYS3.js} +1 -1
  23. package/dist/client/assets/{chunk-BSJP7CBP-CP_f908b.js → chunk-BSJP7CBP-CTBkVJEp.js} +1 -1
  24. package/dist/client/assets/{chunk-CSCIHK7Q-tcgA8jR0.js → chunk-CSCIHK7Q-C6dvEyPX.js} +1 -1
  25. package/dist/client/assets/{chunk-FMBD7UC4-DlpmhBYg.js → chunk-FMBD7UC4-C166WZ7L.js} +1 -1
  26. package/dist/client/assets/{chunk-KSCS5N6A-BkfieXpV.js → chunk-KSCS5N6A-CaVyQHxA.js} +1 -1
  27. package/dist/client/assets/{chunk-L5ZTLDWV-BjVXSZnt.js → chunk-L5ZTLDWV-CdW7usF5.js} +1 -1
  28. package/dist/client/assets/{chunk-LZXEDZCA-CaAWmy4Q.js → chunk-LZXEDZCA-imRCFVGq.js} +2 -2
  29. package/dist/client/assets/{chunk-ND2GUHAM-kWh41zUn.js → chunk-ND2GUHAM-BJCVPOgO.js} +1 -1
  30. package/dist/client/assets/{chunk-NZK2D7GU-CDrIi44_.js → chunk-NZK2D7GU-DodLkks9.js} +1 -1
  31. package/dist/client/assets/{chunk-O5CBEL6O-CbNGK3Te.js → chunk-O5CBEL6O-DYxYE_dt.js} +1 -1
  32. package/dist/client/assets/chunk-QZHKN3VN-7sNTyEOs.js +1 -0
  33. package/dist/client/assets/chunk-WU5MYG2G-DluN2oZF.js +1 -0
  34. package/dist/client/assets/{chunk-XPW4576I-Cca0fTtG.js → chunk-XPW4576I-DkPXlA-y.js} +1 -1
  35. package/dist/client/assets/classDiagram-4FO5ZUOK-CHofrzZI.js +1 -0
  36. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B8fKe5FS.js +1 -0
  37. package/dist/client/assets/{cobol-j-6eG2UQ.js → cobol-B5tSUxVN.js} +1 -1
  38. package/dist/client/assets/{coffee-CZLH0dtt.js → coffee-B2Q8w4Zu.js} +1 -1
  39. package/dist/client/assets/{cose-bilkent-S5V4N54A-DlxESVex.js → cose-bilkent-S5V4N54A-Bg2tspSU.js} +1 -1
  40. package/dist/client/assets/{cpp-j6Bp24RI.js → cpp-CfzAEc1z.js} +1 -1
  41. package/dist/client/assets/{crystal-DW7wcFUs.js → crystal-BDxAjW7-.js} +1 -1
  42. package/dist/client/assets/{css-C43BDU2i.js → css-nC3_RAjk.js} +1 -1
  43. package/dist/client/assets/{dagre-BM42HDAG-BaemEJFh.js → dagre-BM42HDAG-BZiNHe27.js} +1 -1
  44. package/dist/client/assets/{diagram-2AECGRRQ-BaM-bkJ3.js → diagram-2AECGRRQ-D3Vd2itQ.js} +1 -1
  45. package/dist/client/assets/{diagram-5GNKFQAL-BOH04DJO.js → diagram-5GNKFQAL-D44Rm6ep.js} +1 -1
  46. package/dist/client/assets/{diagram-KO2AKTUF-BP5MyqDZ.js → diagram-KO2AKTUF-DwoQejb5.js} +1 -1
  47. package/dist/client/assets/{diagram-LMA3HP47-Dt4gKMYF.js → diagram-LMA3HP47-C1eaDL4X.js} +1 -1
  48. package/dist/client/assets/{diagram-OG6HWLK6-DoT1VshN.js → diagram-OG6HWLK6-BtBJHHnj.js} +1 -1
  49. package/dist/client/assets/{dist-DEAxvC4F.js → dist-DUBmiUQf.js} +1 -1
  50. package/dist/client/assets/{edge-D9ySFlnD.js → edge-WCfPDabs.js} +1 -1
  51. package/dist/client/assets/{elixir-CoJz_LQ5.js → elixir-CazmTZo9.js} +1 -1
  52. package/dist/client/assets/{elm-CvedWh_e.js → elm-CTqaOirp.js} +1 -1
  53. package/dist/client/assets/{erDiagram-TEJ5UH35-CMP78FsQ.js → erDiagram-TEJ5UH35-CqjpbNDt.js} +1 -1
  54. package/dist/client/assets/{erb-lD_yYZsm.js → erb-CK9x36t2.js} +1 -1
  55. package/dist/client/assets/{flowDiagram-I6XJVG4X-Dp0s5BFj.js → flowDiagram-I6XJVG4X-CSHJZmlA.js} +1 -1
  56. package/dist/client/assets/{ganttDiagram-6RSMTGT7-GmSG31U-.js → ganttDiagram-6RSMTGT7-D6KxkDpI.js} +1 -1
  57. package/dist/client/assets/{git-rebase-DwZABzof.js → git-rebase-Bn8xQDxV.js} +1 -1
  58. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C1SXShag.js → gitGraphDiagram-PVQCEYII-ZGSlrHF5.js} +1 -1
  59. package/dist/client/assets/{glimmer-js-CWcs3w1Z.js → glimmer-js-h7wFfOLo.js} +1 -1
  60. package/dist/client/assets/{glimmer-ts-CrzGN4lJ.js → glimmer-ts-vlZuiamP.js} +1 -1
  61. package/dist/client/assets/{glsl-DRCtwX7h.js → glsl-CNutENPV.js} +1 -1
  62. package/dist/client/assets/{graphql-rpmrismS.js → graphql-BfddKr9j.js} +1 -1
  63. package/dist/client/assets/{hack-Ba02RnuQ.js → hack-BkYH75Gx.js} +1 -1
  64. package/dist/client/assets/{haml-BHBACStm.js → haml-CM-xW5RI.js} +1 -1
  65. package/dist/client/assets/{handlebars-BtlQ1SCa.js → handlebars-CklcCbzf.js} +1 -1
  66. package/dist/client/assets/{html-BkVU3Dge.js → html-bltTcC3c.js} +1 -1
  67. package/dist/client/assets/{html-derivative-DoK92vwi.js → html-derivative-C4R1a7Nf.js} +1 -1
  68. package/dist/client/assets/{http-CJAwKSPH.js → http-B6uXoDkp.js} +1 -1
  69. package/dist/client/assets/{hurl-kaX5jwuN.js → hurl-gquKVFPU.js} +1 -1
  70. package/dist/client/assets/{index-D8hOoJCg.css → index-BsuX6HVI.css} +1 -1
  71. package/dist/client/assets/{index-BHeNiC07.js → index-yhKiqbkK.js} +154 -154
  72. package/dist/client/assets/{infoDiagram-5YYISTIA-B0i3BlNR.js → infoDiagram-5YYISTIA-DCQv5BKv.js} +1 -1
  73. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BN8sEei4.js → ishikawaDiagram-YF4QCWOH-BqXC35qz.js} +1 -1
  74. package/dist/client/assets/{java-BvrigIoq.js → java-DZLUJ7qo.js} +1 -1
  75. package/dist/client/assets/{javascript-DZkPTYAi.js → javascript-CayXc7uP.js} +1 -1
  76. package/dist/client/assets/{jinja-Ceg7ui1S.js → jinja-CQQUTC0y.js} +1 -1
  77. package/dist/client/assets/{jison-iE1GaOyN.js → jison-CvzuCn2x.js} +1 -1
  78. package/dist/client/assets/{journeyDiagram-JHISSGLW-CE6O3NhU.js → journeyDiagram-JHISSGLW-bRlSO5Sv.js} +1 -1
  79. package/dist/client/assets/{json-C0j8rEcg.js → json-BsMA0GaP.js} +1 -1
  80. package/dist/client/assets/{jsx-B7eXljgz.js → jsx-Dbxr4aPH.js} +1 -1
  81. package/dist/client/assets/{julia-DMDw0aMP.js → julia-CZ38GzHV.js} +1 -1
  82. package/dist/client/assets/{just-BryMKRJ_.js → just-BQwFLV1D.js} +1 -1
  83. package/dist/client/assets/{kanban-definition-UN3LZRKU-j-aU6Yzp.js → kanban-definition-UN3LZRKU-BVjoqA0y.js} +1 -1
  84. package/dist/client/assets/{latex-BNC9-sjr.js → latex-BGyrMdgQ.js} +1 -1
  85. package/dist/client/assets/{line-CyEqpEDp.js → line-DacHFvZH.js} +1 -1
  86. package/dist/client/assets/{linear-CXeaA9km.js → linear-BPGHNTSb.js} +1 -1
  87. package/dist/client/assets/{liquid-D-fQw-oJ.js → liquid-CiA2vjOH.js} +1 -1
  88. package/dist/client/assets/{lua-CD2aJ_rS.js → lua-D9k3fxwM.js} +1 -1
  89. package/dist/client/assets/{marko-BQ37hu6z.js → marko-CwBH4-2T.js} +1 -1
  90. package/dist/client/assets/{mdc-B5NUi3zZ.js → mdc-D4WuuVvw.js} +1 -1
  91. package/dist/client/assets/{mermaid-parser.core-BxHF_XbX.js → mermaid-parser.core-DuXqm2Gp.js} +1 -1
  92. package/dist/client/assets/{mermaid.core-BUtaf4P1.js → mermaid.core-DRh_KVT1.js} +3 -3
  93. package/dist/client/assets/{mindmap-definition-RKZ34NQL-D13tPu2o.js → mindmap-definition-RKZ34NQL-C5wytjbD.js} +1 -1
  94. package/dist/client/assets/{nginx-1W1E03Rg.js → nginx-DHMa03ia.js} +1 -1
  95. package/dist/client/assets/{nim-C5A88bFP.js → nim-8gK3mQXD.js} +1 -1
  96. package/dist/client/assets/{perl-BYoP0wNt.js → perl-DqXBmOB_.js} +1 -1
  97. package/dist/client/assets/{php-CFxna09e.js → php-CruAnpl2.js} +1 -1
  98. package/dist/client/assets/{pieDiagram-4H26LBE5-CHL7Ml5w.js → pieDiagram-4H26LBE5-Cv2Csp1M.js} +1 -1
  99. package/dist/client/assets/{pug-BR4JgWAk.js → pug-C7a5y4Mi.js} +1 -1
  100. package/dist/client/assets/{qml-D1U1EFEe.js → qml-mgWY__NW.js} +1 -1
  101. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-BnYtv-HY.js → quadrantDiagram-W4KKPZXB-DHQIHzFU.js} +1 -1
  102. package/dist/client/assets/{r-ChE6X060.js → r-Do5QoKdS.js} +1 -1
  103. package/dist/client/assets/{razor-B5iVfQMe.js → razor-BqdDbm9d.js} +1 -1
  104. package/dist/client/assets/{regexp-Dz2drUIf.js → regexp-CNMlPqVr.js} +1 -1
  105. package/dist/client/assets/{requirementDiagram-4Y6WPE33-D8QEGLKB.js → requirementDiagram-4Y6WPE33-rUeJykKo.js} +1 -1
  106. package/dist/client/assets/{review-export-CvFFbCAB.js → review-export-BgwyN8Ky.js} +1 -1
  107. package/dist/client/assets/{rst-DZM3RGRs.js → rst-PYCtADQ2.js} +1 -1
  108. package/dist/client/assets/{ruby-DkXnm-J8.js → ruby-B8JdoeHE.js} +1 -1
  109. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-wVaks6lB.js → sankeyDiagram-5OEKKPKP-Bsga6dQU.js} +1 -1
  110. package/dist/client/assets/{sas-DMbpc71c.js → sas-kIev4j3d.js} +1 -1
  111. package/dist/client/assets/{scss-IwVMMp22.js → scss-cf-rl7q3.js} +1 -1
  112. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Cg31TB-R.js → sequenceDiagram-3UESZ5HK-BVcwcOB2.js} +1 -1
  113. package/dist/client/assets/{shellscript-CIStAKx3.js → shellscript-BHMFbkaV.js} +1 -1
  114. package/dist/client/assets/{shellsession-uLtzHhlo.js → shellsession-y_3kBnoK.js} +1 -1
  115. package/dist/client/assets/{soy-BkxBYigm.js → soy-Coc7dfRW.js} +1 -1
  116. package/dist/client/assets/{sql-Ba9y9EvJ.js → sql-CsZYO19m.js} +1 -1
  117. package/dist/client/assets/{src-9MKexpFu.js → src-ujohT29p.js} +1 -1
  118. package/dist/client/assets/{stata-CrPCbiIZ.js → stata-BFa4m_Eh.js} +1 -1
  119. package/dist/client/assets/{stateDiagram-AJRCARHV-BbvNjVF6.js → stateDiagram-AJRCARHV-DBElJIPe.js} +1 -1
  120. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BocZ498b.js +1 -0
  121. package/dist/client/assets/{surrealql-Dvip5u_o.js → surrealql-DlwfRFnC.js} +1 -1
  122. package/dist/client/assets/{svelte-xBLD60Zd.js → svelte-RrLklQOZ.js} +1 -1
  123. package/dist/client/assets/{templ-CWv68xbP.js → templ-BDbBg7z2.js} +1 -1
  124. package/dist/client/assets/{tex-CHqz-fYs.js → tex-BeAp-Hqv.js} +1 -1
  125. package/dist/client/assets/{timeline-definition-PNZ67QCA-CWKkJ3QZ.js → timeline-definition-PNZ67QCA-Det2OiYV.js} +1 -1
  126. package/dist/client/assets/{ts-tags-DS82EDuE.js → ts-tags-Dz-1CFmn.js} +1 -1
  127. package/dist/client/assets/{tsx-B2GBjp2F.js → tsx-Dfi08w8H.js} +1 -1
  128. package/dist/client/assets/{twig-CC8x9pG0.js → twig-BfzYY6Hd.js} +1 -1
  129. package/dist/client/assets/{typescript-g7i13lnC.js → typescript-6FNAPG3Z.js} +1 -1
  130. package/dist/client/assets/{vennDiagram-CIIHVFJN-OLItKWeg.js → vennDiagram-CIIHVFJN-DhH4H0vl.js} +1 -1
  131. package/dist/client/assets/{vue-rFbe7luB.js → vue-DTPedjqE.js} +1 -1
  132. package/dist/client/assets/{vue-html-D9GQtYub.js → vue-html-B4sC29Oj.js} +1 -1
  133. package/dist/client/assets/{vue-vine-mrNtQtY5.js → vue-vine-BWzpqJ4r.js} +1 -1
  134. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Dy1yfeb4.js → wardleyDiagram-YWT4CUSO-BC8K10yP.js} +1 -1
  135. package/dist/client/assets/{xml-CHfMjyAM.js → xml-BK8ACjht.js} +1 -1
  136. package/dist/client/assets/{xsl-BFkNSogJ.js → xsl-rjlrbfou.js} +1 -1
  137. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DfSnfjVL.js → xychartDiagram-2RQKCTM6-DwcVZiB5.js} +1 -1
  138. package/dist/client/assets/{yaml-BfSgHc04.js → yaml-DM6lgMhS.js} +1 -1
  139. package/dist/client/index.html +2 -2
  140. package/dist/completions-5rtfoxB9.mjs +2 -0
  141. package/dist/{completions-BO2DUM-8.mjs → completions-7YSX1neu.mjs} +7 -1
  142. package/dist/{doctor-D0Y3kOY7.mjs → doctor-BMfx7_GY.mjs} +16 -14
  143. package/dist/doctor-BRr5IWHe.mjs +2 -0
  144. package/dist/{find-tui-binary-B71xiwWu.mjs → find-tui-binary-DGspwyvd.mjs} +56 -25
  145. package/dist/{git-Czo96ymM.mjs → git-BGj31GX-.mjs} +71 -7
  146. package/dist/git-CfDSkUcE.mjs +2 -0
  147. package/dist/{github-CErBub2y.mjs → github-BLrnsozP.mjs} +1 -1
  148. package/dist/{github-DBsZ0h_l.mjs → github-DbAFoB92.mjs} +3 -3
  149. package/dist/{github-attachments-plDeB0iE.mjs → github-attachments-fNCKYL-Z.mjs} +2 -2
  150. package/dist/{mcp-DtVrMR2S.mjs → mcp-Bi551clR.mjs} +33 -30
  151. package/dist/native/tui-darwin-arm64/diffing-tui +0 -0
  152. package/dist/native/tui-darwin-x64/diffing-tui +0 -0
  153. package/dist/native/tui-linux-arm64-gnu/diffing-tui +0 -0
  154. package/dist/native/tui-linux-arm64-musl/diffing-tui +0 -0
  155. package/dist/native/tui-linux-x64-gnu/diffing-tui +0 -0
  156. package/dist/native/tui-linux-x64-musl/diffing-tui +0 -0
  157. package/dist/native/tui-win32-x64-msvc/diffing-tui.exe +0 -0
  158. package/dist/{search-BMPY_ZW8.mjs → search-3R2E5xxr.mjs} +16 -1
  159. package/dist/{search-BO9Im7eu.mjs → search-CQ4nsjBX.mjs} +1 -1
  160. package/dist/{server-j0PnTVX1.mjs → server-B9NVZu7l.mjs} +174 -46
  161. package/dist/{server-lock-CY0_1mcS.mjs → server-lock-BNI8FKV1.mjs} +175 -23
  162. package/dist/{session-conflict-C6V9ZKo7.mjs → session-conflict-CB0IErdn.mjs} +8 -7
  163. package/dist/{session-manager-CYNchhVA.mjs → session-manager-656aJXFE.mjs} +2 -2
  164. package/dist/session-url-B8TrGGeE.mjs +33 -0
  165. package/dist/{settings-yK0GYpbn.mjs → settings-DkPDB_hS.mjs} +32 -4
  166. package/dist/setup-BiwX7vdd.mjs +446 -0
  167. package/dist/setup-first-run-DyT0PlOZ.mjs +2 -0
  168. package/dist/setup-first-run-i1o7DBki.mjs +74 -0
  169. package/dist/terminal-BroplOnw.mjs +116 -0
  170. package/dist/{tui-search-bridge-Bfb2ktdA.mjs → tui-search-bridge-fFKqX4Fi.mjs} +3 -3
  171. package/dist/{update-check-Copcz9eb.mjs → update-check-ISaw61qS.mjs} +16 -15
  172. package/package.json +11 -3
  173. package/scripts/postinstall.mjs +52 -0
  174. package/dist/client/assets/channel-Ct4-oSQN.js +0 -1
  175. package/dist/client/assets/chunk-QZHKN3VN-BXhKFVX7.js +0 -1
  176. package/dist/client/assets/chunk-WU5MYG2G-_EwuC51_.js +0 -1
  177. package/dist/client/assets/classDiagram-4FO5ZUOK-C8bdx9R4.js +0 -1
  178. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B26wrQuH.js +0 -1
  179. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-B5BbZkU5.js +0 -1
  180. package/dist/git-DaP_1rVy.mjs +0 -2
  181. /package/dist/{apply-suggestion-CHYnw68I.mjs → apply-suggestion-BsR_8FXW.mjs} +0 -0
  182. /package/dist/{diff-fingerprint-BgR0tu1o.mjs → diff-fingerprint-BL5jNHnP.mjs} +0 -0
  183. /package/dist/{handoff-LAFtmnHf.mjs → handoff-DcShCxWJ.mjs} +0 -0
  184. /package/dist/{review-export-B63eRAVa.mjs → review-export-GW4KNsGN.mjs} +0 -0
@@ -0,0 +1,446 @@
1
+ import { S as isGitRepo, h as getRepoRoot } from "./git-BGj31GX-.mjs";
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";
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
+ import { n as runDoctor, t as formatDoctorReport } from "./doctor-BMfx7_GY.mjs";
6
+ import { t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-i1o7DBki.mjs";
7
+ import { execFileSync, spawn } from "node:child_process";
8
+ import { fileURLToPath } from "node:url";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { homedir, platform } from "node:os";
12
+ import { stdin, stdout } from "node:process";
13
+ import { createInterface } from "node:readline/promises";
14
+ //#region src/lib/setup-mcp.ts
15
+ const DIFFING_SERVER_KEY = "diffing";
16
+ function buildDiffingMcpEntry(repoPath) {
17
+ if (repoPath) return {
18
+ command: "diffing",
19
+ args: [
20
+ "mcp",
21
+ "--repo",
22
+ repoPath
23
+ ]
24
+ };
25
+ return {
26
+ command: "diffing",
27
+ args: ["mcp"]
28
+ };
29
+ }
30
+ function formatMcpSnippet(entry) {
31
+ return JSON.stringify({ mcpServers: { [DIFFING_SERVER_KEY]: entry } }, null, 2);
32
+ }
33
+ function detectGlobalMcpClients(home = homedir()) {
34
+ const clients = [];
35
+ const cursor = join(home, ".cursor", "mcp.json");
36
+ clients.push({
37
+ id: "cursor",
38
+ label: "Cursor",
39
+ path: cursor,
40
+ scope: "global"
41
+ });
42
+ const claude = claudeDesktopConfigPath(home);
43
+ if (claude) clients.push({
44
+ id: "claude-desktop",
45
+ label: "Claude Desktop",
46
+ path: claude,
47
+ scope: "global"
48
+ });
49
+ return clients;
50
+ }
51
+ function projectMcpPath(cwd) {
52
+ return join(cwd, ".cursor", "mcp.json");
53
+ }
54
+ function claudeDesktopConfigPath(home) {
55
+ const os = platform();
56
+ if (os === "darwin") return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
57
+ if (os === "win32") {
58
+ const appData = process.env.APPDATA;
59
+ if (!appData) return null;
60
+ return join(appData, "Claude", "claude_desktop_config.json");
61
+ }
62
+ return join(home, ".config", "Claude", "claude_desktop_config.json");
63
+ }
64
+ function readMcpConfig(path) {
65
+ if (!existsSync(path)) return {};
66
+ try {
67
+ return JSON.parse(readFileSync(path, "utf-8"));
68
+ } catch {
69
+ return {};
70
+ }
71
+ }
72
+ /** Merge only `mcpServers.diffing`; preserve every other server and top-level key. */
73
+ function mergeDiffingMcpConfig(existing, entry) {
74
+ const servers = { ...existing.mcpServers ?? {} };
75
+ servers[DIFFING_SERVER_KEY] = entry;
76
+ return {
77
+ ...existing,
78
+ mcpServers: servers
79
+ };
80
+ }
81
+ function backupMcpConfig(path, backupsRoot = join(homedir(), ".diffing", "backups")) {
82
+ if (!existsSync(path)) return null;
83
+ mkdirSync(backupsRoot, { recursive: true });
84
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
85
+ const backupPath = join(backupsRoot, `${path.replaceAll(/[/\\:]/g, "_")}.${stamp}.json`);
86
+ copyFileSync(path, backupPath);
87
+ return backupPath;
88
+ }
89
+ function writeMcpConfig(target, entry, options) {
90
+ const merged = mergeDiffingMcpConfig(readMcpConfig(target.path), entry);
91
+ const created = !existsSync(target.path);
92
+ if (options?.dryRun) return {
93
+ path: target.path,
94
+ written: false,
95
+ backupPath: null,
96
+ created
97
+ };
98
+ mkdirSync(join(target.path, ".."), { recursive: true });
99
+ const backupPath = backupMcpConfig(target.path, options?.backupsRoot);
100
+ writeFileSync(target.path, `${JSON.stringify(merged, null, 2)}\n`, "utf-8");
101
+ return {
102
+ path: target.path,
103
+ written: true,
104
+ backupPath,
105
+ created
106
+ };
107
+ }
108
+ function writeGlobalMcpConfigs(entry, options) {
109
+ return detectGlobalMcpClients(options?.home).map((target) => writeMcpConfig(target, entry, options));
110
+ }
111
+ function writeProjectMcpConfig(cwd, entry, options) {
112
+ return writeMcpConfig({
113
+ id: "cursor-project",
114
+ label: "Cursor (project)",
115
+ path: projectMcpPath(cwd),
116
+ scope: "project"
117
+ }, entry, options);
118
+ }
119
+ //#endregion
120
+ //#region src/lib/setup-skills.ts
121
+ const SKILLS_PACKAGE = "ahmedragab20/diffing";
122
+ function buildSkillsInstallCommand() {
123
+ return {
124
+ command: "npx",
125
+ args: [
126
+ "skills",
127
+ "add",
128
+ SKILLS_PACKAGE
129
+ ]
130
+ };
131
+ }
132
+ function formatSkillsInstallCommand() {
133
+ const { command, args } = buildSkillsInstallCommand();
134
+ return [command, ...args].join(" ");
135
+ }
136
+ function runSkillsInstall(options = {}) {
137
+ if (options.dryRun) return Promise.resolve(0);
138
+ const { command, args } = buildSkillsInstallCommand();
139
+ return new Promise((resolve) => {
140
+ const child = spawn(command, args, {
141
+ cwd: options.cwd ?? process.cwd(),
142
+ env: options.env ?? process.env,
143
+ stdio: "inherit",
144
+ shell: process.platform === "win32"
145
+ });
146
+ child.on("error", () => resolve(1));
147
+ child.on("exit", (code) => resolve(code ?? 1));
148
+ });
149
+ }
150
+ //#endregion
151
+ //#region src/lib/setup.ts
152
+ const SETUP_STEPS = 6;
153
+ function packageVersion(cliImportMetaUrl) {
154
+ const candidates = [];
155
+ if (cliImportMetaUrl) {
156
+ const base = dirname(fileURLToPath(cliImportMetaUrl));
157
+ candidates.push(resolve(base, "..", "package.json"), resolve(base, "..", "..", "package.json"));
158
+ }
159
+ candidates.push(resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json"));
160
+ for (const path of candidates) try {
161
+ const pkg = JSON.parse(readFileSync(path, "utf-8"));
162
+ if (pkg.version) return pkg.version;
163
+ } catch {}
164
+ return "unknown";
165
+ }
166
+ function gitOnPath() {
167
+ try {
168
+ execFileSync("git", ["--version"], { stdio: [
169
+ "ignore",
170
+ "ignore",
171
+ "ignore"
172
+ ] });
173
+ return true;
174
+ } catch {
175
+ return false;
176
+ }
177
+ }
178
+ function nodeVersionOk() {
179
+ const major = Number(process.versions.node.split(".")[0]);
180
+ return Number.isFinite(major) && major >= 20;
181
+ }
182
+ function printStep(step, title, color) {
183
+ console.log("");
184
+ console.log(stepHeader(step, SETUP_STEPS, title, { color }));
185
+ }
186
+ async function askYesNo(question, defaultYes, interactive, color) {
187
+ if (!interactive || !process.stdin.isTTY) return defaultYes;
188
+ const rl = createInterface({
189
+ input: stdin,
190
+ output: stdout
191
+ });
192
+ try {
193
+ const suffix = defaultYes ? `[${bold("Y", color)}/${bold("n", color)}]` : `[${bold("y", color)}/${bold("N", color)}]`;
194
+ console.log(hintLine([
195
+ {
196
+ key: "Y",
197
+ label: "yes"
198
+ },
199
+ {
200
+ key: "n",
201
+ label: "no"
202
+ },
203
+ {
204
+ key: "?",
205
+ label: "help"
206
+ }
207
+ ], { color }));
208
+ while (true) {
209
+ const answer = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();
210
+ if (!answer) return defaultYes;
211
+ if (answer === "?" || answer === "help") {
212
+ console.log(dim("Answer y/yes or n/no; Enter accepts the default in brackets.", color));
213
+ continue;
214
+ }
215
+ if (answer === "y" || answer === "yes") return true;
216
+ if (answer === "n" || answer === "no") return false;
217
+ console.log(dim("Please answer y or n (or ? for help).", color));
218
+ }
219
+ } finally {
220
+ rl.close();
221
+ }
222
+ }
223
+ async function askDefaultMode(interactive, color) {
224
+ if (!interactive || !process.stdin.isTTY) return;
225
+ const current = loadSettings().defaultMode;
226
+ console.log("");
227
+ console.log(tone("info", "Default interactive mode:", { color }));
228
+ console.log(` ${bold("Web", color)} ${dim("— browser review UI (supported)", color)}`);
229
+ console.log(` ${bold("TUI", color)} ${dim("— native terminal UI (experimental)", color)}`);
230
+ console.log(dim(`Current: ${formatModeLabel(current)}`, color));
231
+ if (await askYesNo(`Switch to TUI?`, false, interactive, color)) {
232
+ saveSettings({ defaultMode: "tui" });
233
+ console.log(tone("ok", "Default mode set to TUI", { color }));
234
+ return;
235
+ }
236
+ if (!await askYesNo("Keep Web as the default interactive mode?", true, interactive, color)) {
237
+ saveSettings({ defaultMode: "tui" });
238
+ console.log(tone("ok", "Default mode set to TUI", { color }));
239
+ }
240
+ }
241
+ function runSetupCheck(options = {}) {
242
+ const cwd = options.cwd ?? process.cwd();
243
+ const messages = [];
244
+ const nodeOk = nodeVersionOk();
245
+ if (!nodeOk) messages.push(`Node.js >= 20 required (found ${process.versions.node})`);
246
+ const gitOk = gitOnPath();
247
+ if (!gitOk) messages.push("git not found on PATH");
248
+ const inGitRepo = isGitRepo();
249
+ if (!inGitRepo) messages.push(`${cwd} is not inside a Git repository (setup can continue)`);
250
+ ensureConfigDir();
251
+ const configDirReady = true;
252
+ const setupCompleted = isSetupCompleted();
253
+ return {
254
+ ok: nodeOk && gitOk && configDirReady,
255
+ nodeOk,
256
+ gitOk,
257
+ inGitRepo,
258
+ setupCompleted,
259
+ configDirReady,
260
+ messages
261
+ };
262
+ }
263
+ async function runSetup(options = {}) {
264
+ const cwd = options.cwd ?? process.cwd();
265
+ const interactive = options.interactive ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
266
+ const color = interactive && isColorEnabled();
267
+ const version = packageVersion(options.cliImportMetaUrl);
268
+ if (options.reset) {
269
+ resetSetupCompleted();
270
+ console.log(tone("ok", "Setup marker cleared. Run `diffing setup` to configure again.", { color }));
271
+ return 0;
272
+ }
273
+ const preflight = runSetupCheck({ cwd });
274
+ if (options.check) {
275
+ printCheckReport(preflight, version, color);
276
+ return preflight.ok ? 0 : 1;
277
+ }
278
+ console.log(box("diffing setup", [dim(`v${version} — first-time configuration wizard`, color)], { color }));
279
+ printStep(1, "Environment", color);
280
+ if (!preflight.nodeOk) {
281
+ console.error(tone("error", `Node.js >= 20 required (found ${process.versions.node})`, { color }));
282
+ return 1;
283
+ }
284
+ if (!preflight.gitOk) {
285
+ console.error(tone("error", "git not found on PATH — install git and retry.", { color }));
286
+ return 1;
287
+ }
288
+ ensureConfigDir();
289
+ console.log(tone("ok", "Config directory ready (~/.config/diffing/)", { color }));
290
+ if (preflight.inGitRepo) try {
291
+ console.log(tone("ok", `Git repository: ${getRepoRoot()}`, { color }));
292
+ } catch {
293
+ console.log(tone("warn", "Not inside a Git repository — review commands need a repo later", { color }));
294
+ }
295
+ else console.log(tone("warn", "Not inside a Git repository — you can still finish setup", { color }));
296
+ if (options.skillsOnly) return runSkillsStep(options, interactive, color, 5);
297
+ if (options.mcpOnly) return runMcpStep(cwd, options, interactive, preflight.inGitRepo, color, 6);
298
+ printStep(2, "Environment checks", color);
299
+ console.log(dim("Running `diffing doctor`…", color));
300
+ const doctor = await runDoctor({
301
+ cwd,
302
+ cliImportMetaUrl: options.cliImportMetaUrl
303
+ });
304
+ console.log(formatDoctorReport(doctor, { color }));
305
+ printStep(3, "Default mode", color);
306
+ if (!options.yes) await askDefaultMode(interactive, color);
307
+ else console.log(tone("ok", `Default mode: ${formatModeLabel(loadSettings().defaultMode)} (unchanged)`, { color }));
308
+ printStep(4, "Shell completions", color);
309
+ await runCompletionsStep(options, interactive, color);
310
+ printStep(5, "Agent skills", color);
311
+ const skillsCode = await runSkillsStep(options, interactive, color, 5);
312
+ if (skillsCode !== 0) return skillsCode;
313
+ printStep(6, "MCP registration", color);
314
+ const mcpCode = await runMcpStep(cwd, options, interactive, preflight.inGitRepo, color, 6);
315
+ if (mcpCode !== 0) return mcpCode;
316
+ markSetupCompleted();
317
+ printDoneChecklist(preflight.inGitRepo, cwd, color);
318
+ return 0;
319
+ }
320
+ async function runSkillsStep(options, interactive, color, _step) {
321
+ const cmd = formatSkillsInstallCommand();
322
+ if (!(options.yes || await askYesNo(`Install agent skills via \`${cmd}\`?`, true, interactive, color))) {
323
+ console.log(dim("Skipped skills install.", color));
324
+ return 0;
325
+ }
326
+ if (options.yes && !process.stdin.isTTY) console.log(dim(`Running: ${cmd}`, color));
327
+ const code = await runSkillsInstall({ cwd: options.cwd });
328
+ if (code === 0) console.log(tone("ok", "Skills installed (or already present)", { color }));
329
+ else {
330
+ console.error(tone("error", `Skills install exited with code ${code}`, { color }));
331
+ console.error(dim(` You can retry manually: ${cmd}`, color));
332
+ return options.yes ? 0 : code;
333
+ }
334
+ return 0;
335
+ }
336
+ async function runMcpStep(cwd, options, interactive, inGitRepo, color, _step) {
337
+ let repoPath;
338
+ if (inGitRepo) try {
339
+ repoPath = getRepoRoot();
340
+ } catch {
341
+ repoPath = void 0;
342
+ }
343
+ const entry = buildDiffingMcpEntry(repoPath);
344
+ const snippet = formatMcpSnippet(entry);
345
+ if (options.writeMcp || options.writeProjectMcp) {
346
+ if (options.writeMcp) {
347
+ const results = writeGlobalMcpConfigs(entry);
348
+ for (const r of results) if (r.written) {
349
+ const backup = r.backupPath ? ` (backup: ${r.backupPath})` : "";
350
+ console.log(tone("ok", `Wrote MCP config: ${r.path}${backup}`, { color }));
351
+ }
352
+ }
353
+ if (options.writeProjectMcp) {
354
+ const r = writeProjectMcpConfig(cwd, entry);
355
+ const backup = r.backupPath ? ` (backup: ${r.backupPath})` : "";
356
+ console.log(tone("ok", `Wrote project MCP config: ${r.path}${backup}`, { color }));
357
+ }
358
+ return 0;
359
+ }
360
+ console.log(tone("info", "MCP registration (paste into your agent client):", { color }));
361
+ console.log(copyBlock("Copy MCP JSON", snippet, { color }));
362
+ const detected = detectGlobalMcpClients().filter((c) => c.id === "cursor" || c.id === "claude-desktop");
363
+ if (detected.length > 0) {
364
+ console.log("");
365
+ console.log(tone("info", "Detected clients:", { color }));
366
+ for (const c of detected) console.log(dim(` • ${c.label}: ${c.path}`, color));
367
+ }
368
+ if (options.yes) {
369
+ console.log(dim("\n(--yes prints MCP JSON only; pass --write-mcp to merge into IDE configs)", color));
370
+ return 0;
371
+ }
372
+ if (await askYesNo("Write diffing MCP entry to global IDE configs?", false, interactive, color)) writeGlobalMcpConfigs(entry).forEach((r) => {
373
+ if (r.written) console.log(tone("ok", `Wrote ${r.path}`, { color }));
374
+ });
375
+ if (await askYesNo("Also write project-local .cursor/mcp.json in the current directory?", false, interactive, color)) {
376
+ const r = writeProjectMcpConfig(cwd, entry);
377
+ if (r.written) console.log(tone("ok", `Wrote ${r.path}`, { color }));
378
+ }
379
+ return 0;
380
+ }
381
+ async function runCompletionsStep(options, interactive, color) {
382
+ const shells = [
383
+ "bash",
384
+ "zsh",
385
+ "fish"
386
+ ];
387
+ if (options.writeCompletions) {
388
+ for (const shell of shells) {
389
+ const script = completionFor(shell);
390
+ if (script) console.log(copyBlock(`${shell} completion`, script, { color }));
391
+ }
392
+ return;
393
+ }
394
+ if (options.yes) {
395
+ console.log(dim("Shell completions: run `diffing completion <bash|zsh|fish>` and append to your shell rc.", color));
396
+ return;
397
+ }
398
+ if (!await askYesNo("Print shell completion scripts?", false, interactive, color)) return;
399
+ for (const shell of shells) {
400
+ const script = completionFor(shell);
401
+ if (script) console.log(copyBlock(`${shell} completion`, script, { color }));
402
+ }
403
+ }
404
+ function printCheckReport(result, version, color) {
405
+ console.log(box("diffing setup --check", [dim(`v${version}`, color)], { color }));
406
+ console.log(rule({ color }));
407
+ console.log(result.nodeOk ? tone("ok", "Node.js >= 20", { color }) : tone("error", "Node.js >= 20", { color }));
408
+ console.log(result.gitOk ? tone("ok", "git on PATH", { color }) : tone("error", "git on PATH", { color }));
409
+ console.log(result.configDirReady ? tone("ok", "~/.config/diffing/", { color }) : tone("error", "config dir", { color }));
410
+ console.log(result.inGitRepo ? tone("ok", "inside Git repository", { color }) : tone("warn", "not in a Git repository", { color }));
411
+ console.log(result.setupCompleted ? tone("ok", "setup completed previously", { color }) : tone("warn", "setup not completed", { color }));
412
+ for (const msg of result.messages) console.log(dim(` ${msg}`, color));
413
+ }
414
+ function printDoneChecklist(inGitRepo, cwd, color) {
415
+ const nextSteps = inGitRepo ? ["diffing Open the review UI", "diffing doctor Re-run diagnostics anytime"] : ["cd <your-repo> && diffing", `# current directory: ${cwd}`];
416
+ console.log(box("Setup complete", [
417
+ tone("ok", "Settings saved", { color }),
418
+ tone("ok", "Environment checked (`diffing doctor`)", { color }),
419
+ "",
420
+ tone("info", "Next steps:", { color }),
421
+ ...nextSteps.map((line) => ` ${line}`),
422
+ "",
423
+ `Docs: ${DOCS_GETTING_STARTED_URL}`,
424
+ dim("CLI reference: docs/cli.md", color)
425
+ ], { color }));
426
+ }
427
+ async function handleFirstRunGate(options) {
428
+ const { shouldOfferFirstRunSetup, promptFirstRunSetup, DOCS_GETTING_STARTED_URL } = await import("./setup-first-run-DyT0PlOZ.mjs");
429
+ if (!shouldOfferFirstRunSetup({ skipSetup: options.skipSetup })) return;
430
+ while (true) {
431
+ const choice = await promptFirstRunSetup();
432
+ if (choice === "skip") return;
433
+ if (choice === "docs") {
434
+ console.log(`\nGetting started: ${DOCS_GETTING_STARTED_URL}\n`);
435
+ continue;
436
+ }
437
+ const code = await runSetup({
438
+ cliImportMetaUrl: options.cliImportMetaUrl,
439
+ interactive: true
440
+ });
441
+ if (code !== 0) process.exit(code);
442
+ return;
443
+ }
444
+ }
445
+ //#endregion
446
+ export { handleFirstRunGate, runSetup };
@@ -0,0 +1,2 @@
1
+ import { a as shouldOfferFirstRunSetup, i as promptFirstRunSetup, t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-i1o7DBki.mjs";
2
+ export { DOCS_GETTING_STARTED_URL, promptFirstRunSetup, shouldOfferFirstRunSetup };
@@ -0,0 +1,74 @@
1
+ import { r as isSetupCompleted } from "./settings-DkPDB_hS.mjs";
2
+ import { a as hintLine, i as dim, n as box, o as isColorEnabled } from "./terminal-BroplOnw.mjs";
3
+ import { stdin, stdout } from "node:process";
4
+ import { createInterface } from "node:readline/promises";
5
+ //#region src/lib/setup-first-run.ts
6
+ const DOCS_GETTING_STARTED_URL = "https://github.com/ahmedragab20/diffing/blob/main/docs/getting-started.md";
7
+ function isCiEnvironment(env = process.env) {
8
+ return Boolean(env.CI || env.CONTINUOUS_INTEGRATION || env.BUILD_NUMBER || env.GITHUB_ACTIONS || env.GITLAB_CI || env.CIRCLECI || env.JENKINS_URL);
9
+ }
10
+ function shouldOfferFirstRunSetup(options = {}) {
11
+ const env = options.env ?? process.env;
12
+ const tty = options.isTTY ?? Boolean(process.stdout.isTTY);
13
+ const stdinTty = options.isStdinTTY ?? Boolean(process.stdin.isTTY);
14
+ if (options.skipSetup) return false;
15
+ if (!tty || !stdinTty) return false;
16
+ if (isCiEnvironment(env)) return false;
17
+ return !(options.setupCompleted ?? isSetupCompleted());
18
+ }
19
+ function formatFirstRunWelcome(options = {}) {
20
+ const color = options.color ?? isColorEnabled();
21
+ return box("diffing", [
22
+ "Welcome — local-first code review for git diffs and AI handoff.",
23
+ "",
24
+ hintLine([
25
+ {
26
+ key: "Y",
27
+ label: "Run setup now"
28
+ },
29
+ {
30
+ key: "n",
31
+ label: "Skip"
32
+ },
33
+ {
34
+ key: "?",
35
+ label: "Docs"
36
+ }
37
+ ], { color }),
38
+ dim(`Getting started: ${DOCS_GETTING_STARTED_URL}`, color)
39
+ ], { color });
40
+ }
41
+ async function promptFirstRunSetup(write = (line) => stdout.write(line)) {
42
+ const color = isColorEnabled();
43
+ write(formatFirstRunWelcome({ color }));
44
+ const rl = createInterface({
45
+ input: stdin,
46
+ output: stdout
47
+ });
48
+ try {
49
+ while (true) {
50
+ const answer = (await rl.question("> ")).trim().toLowerCase();
51
+ if (!answer || answer === "y" || answer === "yes") return "run";
52
+ if (answer === "n" || answer === "no") return "skip";
53
+ if (answer === "?" || answer === "docs" || answer === "help") return "docs";
54
+ write(hintLine([
55
+ {
56
+ key: "Y",
57
+ label: "yes"
58
+ },
59
+ {
60
+ key: "n",
61
+ label: "no"
62
+ },
63
+ {
64
+ key: "?",
65
+ label: "help"
66
+ }
67
+ ], { color }) + "\n");
68
+ }
69
+ } finally {
70
+ rl.close();
71
+ }
72
+ }
73
+ //#endregion
74
+ export { shouldOfferFirstRunSetup as a, promptFirstRunSetup as i, formatFirstRunWelcome as n, isCiEnvironment as r, DOCS_GETTING_STARTED_URL as t };
@@ -0,0 +1,116 @@
1
+ import { stdout } from "node:process";
2
+ //#region src/lib/terminal.ts
3
+ const reset = "\x1B[0m";
4
+ const GOLD = 220;
5
+ const OK = 82;
6
+ const OK_BRIGHT = 118;
7
+ const WARN = 214;
8
+ const WARN_BRIGHT = 220;
9
+ const ERROR = 196;
10
+ const INFO = 75;
11
+ /** Whether ANSI styling is allowed (TTY, no NO_COLOR, TERM≠dumb). */
12
+ function isColorEnabled(stream = stdout) {
13
+ if (!stream.isTTY) return false;
14
+ if (process.env.NO_COLOR !== void 0) return false;
15
+ if (process.env.TERM === "dumb") return false;
16
+ return true;
17
+ }
18
+ function fg256(code, enabled = isColorEnabled()) {
19
+ return enabled ? `\x1b[38;5;${code}m` : "";
20
+ }
21
+ function bold(text, enabled = isColorEnabled()) {
22
+ return enabled ? `\x1b[1m${text}${reset}` : text;
23
+ }
24
+ function dim(text, enabled = isColorEnabled()) {
25
+ return enabled ? `\x1b[2m${text}${reset}` : text;
26
+ }
27
+ function stripAnsi(str) {
28
+ return str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
29
+ }
30
+ function borderColor(enabled) {
31
+ return fg256(GOLD, enabled);
32
+ }
33
+ function visibleLength(text) {
34
+ return stripAnsi(text).length;
35
+ }
36
+ function padRow(content, innerWidth) {
37
+ const pad = Math.max(0, innerWidth - visibleLength(content));
38
+ return content + " ".repeat(pad);
39
+ }
40
+ /** Gold Unicode box (╭─╮╰─╯│) with optional title row. */
41
+ function box(title, lines, options = {}) {
42
+ const color = options.color ?? isColorEnabled();
43
+ const innerWidth = options.width ?? 62;
44
+ const border = borderColor(color);
45
+ const r = color ? reset : "";
46
+ const top = `${border}╭${"─".repeat(innerWidth)}╮${r}`;
47
+ const bottom = `${border}╰${"─".repeat(innerWidth)}╯${r}`;
48
+ const side = `${border}│${r}`;
49
+ const body = [];
50
+ if (title) {
51
+ body.push(padRow(bold(title, color), innerWidth - 4));
52
+ if (lines.length > 0) body.push("");
53
+ }
54
+ body.push(...lines);
55
+ return [
56
+ "",
57
+ top,
58
+ ...body.map((line) => {
59
+ if (!line) return `${side} ${" ".repeat(innerWidth - 4)} ${side}`;
60
+ return `${side} ${padRow(line, innerWidth - 4)} ${side}`;
61
+ }),
62
+ bottom,
63
+ ""
64
+ ].join("\n");
65
+ }
66
+ /** Horizontal gold rule. */
67
+ function rule(options = {}) {
68
+ const color = options.color ?? isColorEnabled();
69
+ const border = borderColor(color);
70
+ const r = color ? reset : "";
71
+ return `${border}${"─".repeat(40)}${r}`;
72
+ }
73
+ const TONE_ICON = {
74
+ ok: "✓",
75
+ warn: "!",
76
+ error: "✗",
77
+ info: "▌"
78
+ };
79
+ const TONE_COLOR = {
80
+ ok: OK,
81
+ warn: WARN,
82
+ error: ERROR,
83
+ info: INFO
84
+ };
85
+ /** Semantic status line with icon and 256-color foreground. */
86
+ function tone(level, text, options = {}) {
87
+ const color = options.color ?? isColorEnabled();
88
+ const icon = TONE_ICON[level];
89
+ if (!color) return `${icon} ${text}`;
90
+ const accent = fg256(level === "ok" && text.includes("Overall: OK") ? OK_BRIGHT : TONE_COLOR[level], true);
91
+ return `${level === "warn" ? fg256(WARN_BRIGHT, true) : accent}${icon}${reset} ${accent}${text}${reset}`;
92
+ }
93
+ /** Faint hint row: bold keys with dim labels (e.g. Y yes · n no). */
94
+ function hintLine(parts, options = {}) {
95
+ const color = options.color ?? isColorEnabled();
96
+ const sep = color ? dim(" · ", true) : " · ";
97
+ return parts.map(({ key, label }) => {
98
+ return `${bold(key, color)} ${color ? dim(label, true) : label}`;
99
+ }).join(sep);
100
+ }
101
+ /** Step focus rail: ▌ Step 2/5 · Title */
102
+ function stepHeader(step, total, title, options = {}) {
103
+ if (!(options.color ?? isColorEnabled())) return `Step ${step}/${total} · ${title}`;
104
+ const rail = fg256(INFO, true);
105
+ const label = fg256(INFO, true);
106
+ const r = reset;
107
+ return `${rail}▌${r} ${label}Step ${step}/${total}${r} ${dim("·", true)} ${title}`;
108
+ }
109
+ /** Bordered “copy me” block with dim label above content lines. */
110
+ function copyBlock(label, content, options = {}) {
111
+ const color = options.color ?? isColorEnabled();
112
+ const lines = content.trimEnd().split("\n");
113
+ return box(void 0, [color ? dim(label, true) : label, ...lines], options);
114
+ }
115
+ //#endregion
116
+ export { hintLine as a, stepHeader as c, dim as i, tone as l, box as n, isColorEnabled as o, copyBlock as r, rule as s, bold as t };
@@ -1,4 +1,4 @@
1
- import { o as getFileContent } from "./git-Czo96ymM.mjs";
1
+ import { s as getFileContent } from "./git-BGj31GX-.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { createServer } from "node:http";
4
4
  //#region src/lib/tui-search-bridge.ts
@@ -26,7 +26,7 @@ async function readJson(request) {
26
26
  return JSON.parse(Buffer.concat(chunks).toString("utf8"));
27
27
  }
28
28
  async function runSearch(body) {
29
- const { searchAll, searchContent, searchFiles, searchSymbols } = await import("./search-BO9Im7eu.mjs");
29
+ const { searchAll, searchContent, searchFiles, searchSymbols } = await import("./search-CQ4nsjBX.mjs");
30
30
  const scope = body.scope ?? "all";
31
31
  const query = typeof body.query === "string" ? body.query : "";
32
32
  const limit = typeof body.limit === "number" ? body.limit : void 0;
@@ -100,7 +100,7 @@ async function startTuiSearchBridge() {
100
100
  if (request.method === "POST" && request.url === "/track") {
101
101
  const body = await readJson(request);
102
102
  if (typeof body.path === "string") {
103
- const { trackSelection } = await import("./search-BO9Im7eu.mjs");
103
+ const { trackSelection } = await import("./search-CQ4nsjBX.mjs");
104
104
  await trackSelection(typeof body.query === "string" ? body.query : "", body.path);
105
105
  }
106
106
  sendJson(response, 200, { ok: true });