newcraw 1.0.2 → 1.0.3

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 (220) hide show
  1. package/dist/REPL-CTTH53A7.js +50 -0
  2. package/dist/{acp-J4WDYGRX.js → acp-25PIN25O.js} +69 -40
  3. package/dist/acp-25PIN25O.js.map +7 -0
  4. package/dist/{agentsValidate-UBOER2IN.js → agentsValidate-BXDD54YP.js} +13 -10
  5. package/dist/{agentsValidate-UBOER2IN.js.map → agentsValidate-BXDD54YP.js.map} +1 -1
  6. package/dist/{ask-MGUO3L35.js → ask-EL4XAA5P.js} +62 -52
  7. package/dist/ask-EL4XAA5P.js.map +7 -0
  8. package/dist/{autoUpdater-2GS6LRPK.js → autoUpdater-DKMSJXWW.js} +5 -4
  9. package/dist/{chunk-2C43OXE7.js → chunk-2OVXJBJV.js} +38 -59
  10. package/dist/chunk-2OVXJBJV.js.map +7 -0
  11. package/dist/{chunk-53A4JHFW.js → chunk-3D3C7MRI.js} +23 -4
  12. package/dist/chunk-3D3C7MRI.js.map +7 -0
  13. package/dist/{chunk-VKI7ORIO.js → chunk-3ZQRACCP.js} +37 -18
  14. package/dist/{chunk-VKI7ORIO.js.map → chunk-3ZQRACCP.js.map} +1 -1
  15. package/dist/chunk-4A6CDBDH.js +822 -0
  16. package/dist/chunk-4A6CDBDH.js.map +7 -0
  17. package/dist/{chunk-VQSCECTS.js → chunk-53VETVCP.js} +6 -4
  18. package/dist/{chunk-VQSCECTS.js.map → chunk-53VETVCP.js.map} +1 -1
  19. package/dist/{chunk-WWDVA4NV.js → chunk-6WT3ZRYF.js} +22 -6
  20. package/dist/{chunk-WWDVA4NV.js.map → chunk-6WT3ZRYF.js.map} +1 -1
  21. package/dist/{chunk-RUXIBQ3B.js → chunk-7E2L7EH2.js} +4 -4
  22. package/dist/{chunk-VHS2MZQS.js → chunk-7PWVUHQ2.js} +9 -6
  23. package/dist/{chunk-VHS2MZQS.js.map → chunk-7PWVUHQ2.js.map} +1 -1
  24. package/dist/{chunk-2EFL22PV.js → chunk-ADJ4YEII.js} +7 -3
  25. package/dist/chunk-ADJ4YEII.js.map +7 -0
  26. package/dist/chunk-AKNZJBBU.js +372 -0
  27. package/dist/chunk-AKNZJBBU.js.map +7 -0
  28. package/dist/chunk-ALQSPHXV.js +135 -0
  29. package/dist/chunk-ALQSPHXV.js.map +7 -0
  30. package/dist/{chunk-XS6PU75S.js → chunk-APSIF3YK.js} +1 -1
  31. package/dist/{chunk-IM33F5CM.js → chunk-BMJ5XGFR.js} +1668 -1623
  32. package/dist/chunk-BMJ5XGFR.js.map +7 -0
  33. package/dist/chunk-BQCOSNM3.js +93 -0
  34. package/dist/chunk-BQCOSNM3.js.map +7 -0
  35. package/dist/{chunk-OJIMOLIC.js → chunk-BTCASL4X.js} +3621 -7413
  36. package/dist/chunk-BTCASL4X.js.map +7 -0
  37. package/dist/chunk-CHB5K4GI.js +107 -0
  38. package/dist/chunk-CHB5K4GI.js.map +7 -0
  39. package/dist/{chunk-QH2M65BR.js → chunk-D2FSAFMO.js} +7 -3
  40. package/dist/{chunk-QH2M65BR.js.map → chunk-D2FSAFMO.js.map} +1 -1
  41. package/dist/chunk-D4OZACS2.js +35 -0
  42. package/dist/{chunk-IIFUDVGS.js → chunk-ENLHVQCX.js} +310 -177
  43. package/dist/chunk-ENLHVQCX.js.map +7 -0
  44. package/dist/{chunk-A7X6OCZE.js → chunk-ERKWSZ3K.js} +1 -1
  45. package/dist/{chunk-UYRR6F5S.js → chunk-FSSZHQEJ.js} +9 -3
  46. package/dist/{chunk-UYRR6F5S.js.map → chunk-FSSZHQEJ.js.map} +1 -1
  47. package/dist/chunk-GV73HKJO.js +5473 -0
  48. package/dist/chunk-GV73HKJO.js.map +7 -0
  49. package/dist/{chunk-GZTCXXSS.js → chunk-GZ4BEVMZ.js} +57 -46
  50. package/dist/{chunk-GZTCXXSS.js.map → chunk-GZ4BEVMZ.js.map} +1 -1
  51. package/dist/chunk-HLBLZKZH.js +45 -0
  52. package/dist/chunk-HLBLZKZH.js.map +7 -0
  53. package/dist/chunk-JLVECHVJ.js +36 -0
  54. package/dist/chunk-JLVECHVJ.js.map +7 -0
  55. package/dist/chunk-KNSAVNMD.js +683 -0
  56. package/dist/{chunk-F3COCCAE.js.map → chunk-KNSAVNMD.js.map} +1 -1
  57. package/dist/{chunk-V5U6BHT2.js → chunk-KRN3WHHL.js} +7 -3
  58. package/dist/{chunk-V5U6BHT2.js.map → chunk-KRN3WHHL.js.map} +1 -1
  59. package/dist/{chunk-3LMXSKZ7.js → chunk-NFYAVT54.js} +1 -1
  60. package/dist/chunk-NT7RDVDA.js +33 -0
  61. package/dist/{chunk-KQSHIOZK.js.map → chunk-NT7RDVDA.js.map} +1 -1
  62. package/dist/chunk-NW7WSLD5.js +166 -0
  63. package/dist/{chunk-ZYSVG4X3.js.map → chunk-NW7WSLD5.js.map} +2 -2
  64. package/dist/{chunk-HSJ6HYAO.js → chunk-P52SGBC4.js} +18 -10
  65. package/dist/chunk-P52SGBC4.js.map +7 -0
  66. package/dist/{chunk-XXU2NVOE.js → chunk-PC6QOCGI.js} +30 -6
  67. package/dist/chunk-PC6QOCGI.js.map +7 -0
  68. package/dist/{chunk-N5OHRWG2.js → chunk-QSRXXZO7.js} +4 -2
  69. package/dist/{chunk-N5OHRWG2.js.map → chunk-QSRXXZO7.js.map} +1 -1
  70. package/dist/{chunk-DEF3KFP7.js → chunk-QZFKONA3.js} +4 -2
  71. package/dist/{chunk-DEF3KFP7.js.map → chunk-QZFKONA3.js.map} +1 -1
  72. package/dist/{chunk-JWXQNBBA.js → chunk-RE226X4F.js} +7 -1
  73. package/dist/{chunk-JWXQNBBA.js.map → chunk-RE226X4F.js.map} +1 -1
  74. package/dist/chunk-RF57YWGW.js +88 -0
  75. package/dist/chunk-RF57YWGW.js.map +7 -0
  76. package/dist/chunk-UGBECBIR.js +62 -0
  77. package/dist/chunk-UGBECBIR.js.map +7 -0
  78. package/dist/chunk-UYWZQVH5.js +35 -0
  79. package/dist/chunk-UYWZQVH5.js.map +7 -0
  80. package/dist/{chunk-LOIZNQOU.js → chunk-VHZRJ7RI.js} +9 -3
  81. package/dist/{chunk-LOIZNQOU.js.map → chunk-VHZRJ7RI.js.map} +1 -1
  82. package/dist/{chunk-XMGUQHMF.js → chunk-VSSVN6WG.js} +11 -1
  83. package/dist/chunk-VSSVN6WG.js.map +7 -0
  84. package/dist/{chunk-OZHBEG7U.js → chunk-XV7LPJNT.js} +15 -5
  85. package/dist/{chunk-OZHBEG7U.js.map → chunk-XV7LPJNT.js.map} +1 -1
  86. package/dist/chunk-Y7MDOB3N.js +65 -0
  87. package/dist/chunk-Y7MDOB3N.js.map +7 -0
  88. package/dist/{chunk-BWYKUDJR.js → chunk-ZLAB3Z4G.js} +14 -8
  89. package/dist/{chunk-BWYKUDJR.js.map → chunk-ZLAB3Z4G.js.map} +1 -1
  90. package/dist/{chunk-755HIAI3.js → chunk-ZMO4E7IW.js} +3 -42
  91. package/dist/chunk-ZMO4E7IW.js.map +7 -0
  92. package/dist/{cli-KZGF3FV5.js → cli-Z2BNJWHT.js} +251 -485
  93. package/dist/cli-Z2BNJWHT.js.map +7 -0
  94. package/dist/commands-3Y3OQOXT.js +54 -0
  95. package/dist/{config-GTJWCNPF.js → config-5RS7HDIK.js} +9 -6
  96. package/dist/{context-WF3TTXQU.js → context-XZXRRYKS.js} +8 -7
  97. package/dist/{costTracker-2G3ZI2JF.js → costTracker-VSWW7SRT.js} +3 -2
  98. package/dist/{customCommands-QOWK57EX.js → customCommands-6KDAODFQ.js} +6 -5
  99. package/dist/{env-37BAP7QF.js → env-WIM2DQ4L.js} +10 -7
  100. package/dist/{gateway-IZYO6YFJ.js → gateway-DKHC7H3K.js} +542 -96
  101. package/dist/gateway-DKHC7H3K.js.map +7 -0
  102. package/dist/identity-3KZQQVBG.js +16 -0
  103. package/dist/index.js +8 -6
  104. package/dist/index.js.map +1 -1
  105. package/dist/{kodeAgentSessionId-KTGFX2BE.js → kodeAgentSessionId-4SH24DVH.js} +1 -1
  106. package/dist/{kodeAgentSessionLoad-6F7SJXBC.js → kodeAgentSessionLoad-4S452GGD.js} +6 -5
  107. package/dist/{kodeAgentSessionResume-UEEDRJ3N.js → kodeAgentSessionResume-MSMG4QUR.js} +6 -5
  108. package/dist/{kodeAgentStreamJson-VIXFTYL5.js → kodeAgentStreamJson-4ZKIWKS3.js} +4 -2
  109. package/dist/{kodeAgentStreamJsonSession-XC3IPREZ.js → kodeAgentStreamJsonSession-CYG6MLKP.js} +15 -4
  110. package/dist/kodeAgentStreamJsonSession-CYG6MLKP.js.map +7 -0
  111. package/dist/{kodeAgentStructuredStdio-SI5C7AAD.js → kodeAgentStructuredStdio-5DCUC6V6.js} +3 -3
  112. package/dist/{kodeHooks-V36SHCTC.js → kodeHooks-WX3N6CL6.js} +6 -5
  113. package/dist/{llm-CYUDKJNR.js → llm-V2W4KJIA.js} +239 -57
  114. package/dist/llm-V2W4KJIA.js.map +7 -0
  115. package/dist/{llmLazy-IXVVBRTN.js → llmLazy-I7SO67YA.js} +2 -2
  116. package/dist/{loader-OEJ6C3TN.js → loader-YJGRGJNH.js} +6 -5
  117. package/dist/{mcp-KE3SILMX.js → mcp-WG3RQQCZ.js} +10 -9
  118. package/dist/{mentionProcessor-GAU2WAYB.js → mentionProcessor-PKWDUKTN.js} +14 -7
  119. package/dist/{mentionProcessor-GAU2WAYB.js.map → mentionProcessor-PKWDUKTN.js.map} +1 -1
  120. package/dist/{messages-WCSGGSEU.js → messages-RXHQ6VKL.js} +2 -2
  121. package/dist/{model-4TQIV5J2.js → model-JNWAZGT7.js} +10 -7
  122. package/dist/{openai-KTZV6F7N.js → openai-6NL5UXO7.js} +8 -7
  123. package/dist/{outputStyles-WX5RYQOA.js → outputStyles-BVPXT3MW.js} +6 -5
  124. package/dist/{pluginRuntime-JXMJZ2LC.js → pluginRuntime-XHI3TCRJ.js} +11 -8
  125. package/dist/{pluginRuntime-JXMJZ2LC.js.map → pluginRuntime-XHI3TCRJ.js.map} +1 -1
  126. package/dist/{pluginValidation-JNQZYLUP.js → pluginValidation-WDFL352C.js} +8 -7
  127. package/dist/prompts-C4RUFGX2.js +58 -0
  128. package/dist/query-IA3UKMGR.js +58 -0
  129. package/dist/{responsesStreaming-2AIT6GHG.js → responsesStreaming-JORGEFQC.js} +1 -1
  130. package/dist/{ripgrep-KDPQAMB2.js → ripgrep-BHDXRABJ.js} +5 -4
  131. package/dist/sandbox-QOXESHL4.js +63 -0
  132. package/dist/{skillMarketplace-IXAGP3Q2.js → skillMarketplace-RIAMO2YA.js} +5 -4
  133. package/dist/{state-MSCYLB6Y.js → state-TM2XZQE2.js} +6 -3
  134. package/dist/structuredOutput-KAVFUV2Z.js +9 -0
  135. package/dist/theme-BXUQNXSD.js +15 -0
  136. package/dist/thinking-BCZ4WDT6.js +18 -0
  137. package/dist/{toolPermissionContext-I3IXPVED.js → toolPermissionContext-JCQ5MFUT.js} +1 -1
  138. package/dist/toolPermissionContext-JCQ5MFUT.js.map +7 -0
  139. package/dist/toolPermissionContextState-ILRPUITK.js +24 -0
  140. package/dist/toolPermissionContextState-ILRPUITK.js.map +7 -0
  141. package/dist/{toolPermissionSettings-EUZKGZU2.js → toolPermissionSettings-LNYZ6XFE.js} +9 -8
  142. package/dist/toolPermissionSettings-LNYZ6XFE.js.map +7 -0
  143. package/dist/tools-HIPUGTF5.js +55 -0
  144. package/dist/tools-HIPUGTF5.js.map +7 -0
  145. package/dist/{userInput-LJL4CVOB.js → userInput-I33T2RX2.js} +49 -34
  146. package/dist/{userInput-LJL4CVOB.js.map → userInput-I33T2RX2.js.map} +1 -1
  147. package/dist/{uuid-VA3KVASX.js → uuid-RQH3OZ3W.js} +1 -1
  148. package/dist/uuid-RQH3OZ3W.js.map +7 -0
  149. package/dist/workspace-EP63OB5S.js +21 -0
  150. package/dist/workspace-EP63OB5S.js.map +7 -0
  151. package/package.json +1 -1
  152. package/web/dist/assets/index-XuLVvSQF.js +251 -0
  153. package/web/dist/assets/index-pSid9IlY.css +10 -0
  154. package/web/dist/index.html +2 -2
  155. package/dist/REPL-IAK7ZN2Z.js +0 -42
  156. package/dist/acp-J4WDYGRX.js.map +0 -7
  157. package/dist/ask-MGUO3L35.js.map +0 -7
  158. package/dist/chunk-2C43OXE7.js.map +0 -7
  159. package/dist/chunk-2EFL22PV.js.map +0 -7
  160. package/dist/chunk-53A4JHFW.js.map +0 -7
  161. package/dist/chunk-755HIAI3.js.map +0 -7
  162. package/dist/chunk-AXWJI6N5.js +0 -11
  163. package/dist/chunk-F3COCCAE.js +0 -654
  164. package/dist/chunk-HSJ6HYAO.js.map +0 -7
  165. package/dist/chunk-IIFUDVGS.js.map +0 -7
  166. package/dist/chunk-IM33F5CM.js.map +0 -7
  167. package/dist/chunk-KQSHIOZK.js +0 -24
  168. package/dist/chunk-OJIMOLIC.js.map +0 -7
  169. package/dist/chunk-XMGUQHMF.js.map +0 -7
  170. package/dist/chunk-XXU2NVOE.js.map +0 -7
  171. package/dist/chunk-ZYSVG4X3.js +0 -151
  172. package/dist/cli-KZGF3FV5.js.map +0 -7
  173. package/dist/commands-AVEBLFVS.js +0 -46
  174. package/dist/gateway-IZYO6YFJ.js.map +0 -7
  175. package/dist/kodeAgentStreamJsonSession-XC3IPREZ.js.map +0 -7
  176. package/dist/llm-CYUDKJNR.js.map +0 -7
  177. package/dist/prompts-LE6GK75N.js +0 -48
  178. package/dist/query-GGIP6PWG.js +0 -50
  179. package/dist/theme-GAMFOLBW.js +0 -14
  180. package/dist/tools-3HOUIDM3.js +0 -47
  181. package/web/dist/assets/index-COAJqX1Z.css +0 -1
  182. package/web/dist/assets/index-CzS_4LmC.js +0 -179
  183. /package/dist/{REPL-IAK7ZN2Z.js.map → REPL-CTTH53A7.js.map} +0 -0
  184. /package/dist/{autoUpdater-2GS6LRPK.js.map → autoUpdater-DKMSJXWW.js.map} +0 -0
  185. /package/dist/{chunk-RUXIBQ3B.js.map → chunk-7E2L7EH2.js.map} +0 -0
  186. /package/dist/{chunk-XS6PU75S.js.map → chunk-APSIF3YK.js.map} +0 -0
  187. /package/dist/{chunk-AXWJI6N5.js.map → chunk-D4OZACS2.js.map} +0 -0
  188. /package/dist/{chunk-A7X6OCZE.js.map → chunk-ERKWSZ3K.js.map} +0 -0
  189. /package/dist/{chunk-3LMXSKZ7.js.map → chunk-NFYAVT54.js.map} +0 -0
  190. /package/dist/{commands-AVEBLFVS.js.map → commands-3Y3OQOXT.js.map} +0 -0
  191. /package/dist/{config-GTJWCNPF.js.map → config-5RS7HDIK.js.map} +0 -0
  192. /package/dist/{context-WF3TTXQU.js.map → context-XZXRRYKS.js.map} +0 -0
  193. /package/dist/{costTracker-2G3ZI2JF.js.map → costTracker-VSWW7SRT.js.map} +0 -0
  194. /package/dist/{customCommands-QOWK57EX.js.map → customCommands-6KDAODFQ.js.map} +0 -0
  195. /package/dist/{env-37BAP7QF.js.map → env-WIM2DQ4L.js.map} +0 -0
  196. /package/dist/{kodeAgentSessionId-KTGFX2BE.js.map → identity-3KZQQVBG.js.map} +0 -0
  197. /package/dist/{kodeAgentSessionLoad-6F7SJXBC.js.map → kodeAgentSessionId-4SH24DVH.js.map} +0 -0
  198. /package/dist/{kodeAgentSessionResume-UEEDRJ3N.js.map → kodeAgentSessionLoad-4S452GGD.js.map} +0 -0
  199. /package/dist/{kodeAgentStreamJson-VIXFTYL5.js.map → kodeAgentSessionResume-MSMG4QUR.js.map} +0 -0
  200. /package/dist/{kodeAgentStructuredStdio-SI5C7AAD.js.map → kodeAgentStreamJson-4ZKIWKS3.js.map} +0 -0
  201. /package/dist/{kodeHooks-V36SHCTC.js.map → kodeAgentStructuredStdio-5DCUC6V6.js.map} +0 -0
  202. /package/dist/{llmLazy-IXVVBRTN.js.map → kodeHooks-WX3N6CL6.js.map} +0 -0
  203. /package/dist/{loader-OEJ6C3TN.js.map → llmLazy-I7SO67YA.js.map} +0 -0
  204. /package/dist/{mcp-KE3SILMX.js.map → loader-YJGRGJNH.js.map} +0 -0
  205. /package/dist/{messages-WCSGGSEU.js.map → mcp-WG3RQQCZ.js.map} +0 -0
  206. /package/dist/{model-4TQIV5J2.js.map → messages-RXHQ6VKL.js.map} +0 -0
  207. /package/dist/{openai-KTZV6F7N.js.map → model-JNWAZGT7.js.map} +0 -0
  208. /package/dist/{outputStyles-WX5RYQOA.js.map → openai-6NL5UXO7.js.map} +0 -0
  209. /package/dist/{pluginValidation-JNQZYLUP.js.map → outputStyles-BVPXT3MW.js.map} +0 -0
  210. /package/dist/{prompts-LE6GK75N.js.map → pluginValidation-WDFL352C.js.map} +0 -0
  211. /package/dist/{query-GGIP6PWG.js.map → prompts-C4RUFGX2.js.map} +0 -0
  212. /package/dist/{responsesStreaming-2AIT6GHG.js.map → query-IA3UKMGR.js.map} +0 -0
  213. /package/dist/{ripgrep-KDPQAMB2.js.map → responsesStreaming-JORGEFQC.js.map} +0 -0
  214. /package/dist/{skillMarketplace-IXAGP3Q2.js.map → ripgrep-BHDXRABJ.js.map} +0 -0
  215. /package/dist/{state-MSCYLB6Y.js.map → sandbox-QOXESHL4.js.map} +0 -0
  216. /package/dist/{theme-GAMFOLBW.js.map → skillMarketplace-RIAMO2YA.js.map} +0 -0
  217. /package/dist/{toolPermissionContext-I3IXPVED.js.map → state-TM2XZQE2.js.map} +0 -0
  218. /package/dist/{toolPermissionSettings-EUZKGZU2.js.map → structuredOutput-KAVFUV2Z.js.map} +0 -0
  219. /package/dist/{tools-3HOUIDM3.js.map → theme-BXUQNXSD.js.map} +0 -0
  220. /package/dist/{uuid-VA3KVASX.js.map → thinking-BCZ4WDT6.js.map} +0 -0
@@ -0,0 +1,372 @@
1
+ import { createRequire as __newcrawCreateRequire } from "node:module";
2
+ const require = __newcrawCreateRequire(import.meta.url);
3
+ import {
4
+ Onboarding,
5
+ Select,
6
+ clearTerminal,
7
+ grantReadPermissionForOriginalDir,
8
+ useExitOnCtrlCD
9
+ } from "./chunk-GV73HKJO.js";
10
+ import {
11
+ getMcprcServerStatus
12
+ } from "./chunk-6WT3ZRYF.js";
13
+ import {
14
+ getTheme
15
+ } from "./chunk-QZFKONA3.js";
16
+ import {
17
+ checkHasTrustDialogAccepted,
18
+ getCurrentProjectConfig,
19
+ getGlobalConfig,
20
+ getProjectMcpServerDefinitions,
21
+ init_config,
22
+ saveCurrentProjectConfig,
23
+ saveGlobalConfig
24
+ } from "./chunk-ENLHVQCX.js";
25
+ import {
26
+ getCwd,
27
+ init_state
28
+ } from "./chunk-BMJ5XGFR.js";
29
+ import {
30
+ PRODUCT_COMMAND,
31
+ PRODUCT_NAME,
32
+ init_product
33
+ } from "./chunk-UYWZQVH5.js";
34
+ import {
35
+ MACRO,
36
+ init_macros
37
+ } from "./chunk-NW7WSLD5.js";
38
+
39
+ // src/entrypoints/cli/setupScreens.tsx
40
+ init_macros();
41
+ import React6 from "react";
42
+
43
+ // src/ui/components/TrustDialog.tsx
44
+ import React from "react";
45
+ import { Box, Text, useInput } from "ink";
46
+ init_config();
47
+ init_product();
48
+ init_state();
49
+ import { homedir } from "os";
50
+ function TrustDialog({ onDone }) {
51
+ const theme = getTheme();
52
+ React.useEffect(() => {
53
+ }, []);
54
+ function onChange(value) {
55
+ const config = getCurrentProjectConfig();
56
+ switch (value) {
57
+ case "yes": {
58
+ const isHomeDir = homedir() === getCwd();
59
+ if (!isHomeDir) {
60
+ saveCurrentProjectConfig({
61
+ ...config,
62
+ hasTrustDialogAccepted: true
63
+ });
64
+ }
65
+ onDone();
66
+ break;
67
+ }
68
+ case "no": {
69
+ process.exit(1);
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ const exitState = useExitOnCtrlCD(() => process.exit(0));
75
+ useInput((_input, key) => {
76
+ if (key.escape) {
77
+ process.exit(0);
78
+ return;
79
+ }
80
+ });
81
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
82
+ Box,
83
+ {
84
+ flexDirection: "column",
85
+ gap: 1,
86
+ padding: 1,
87
+ borderStyle: "round",
88
+ borderColor: theme.warning
89
+ },
90
+ /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.warning }, "Do you trust the files in this folder?"),
91
+ /* @__PURE__ */ React.createElement(Text, { bold: true }, process.cwd()),
92
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, null, PRODUCT_NAME, " may read files in this folder. Reading untrusted files may lead to ", PRODUCT_NAME, " to behave in an unexpected ways."), /* @__PURE__ */ React.createElement(Text, null, "With your permission ", PRODUCT_NAME, " may execute files in this folder. Executing untrusted code is unsafe.")),
93
+ /* @__PURE__ */ React.createElement(
94
+ Select,
95
+ {
96
+ options: [
97
+ { label: "Yes, proceed", value: "yes" },
98
+ { label: "No, exit", value: "no" }
99
+ ],
100
+ onChange: (value) => onChange(value)
101
+ }
102
+ )
103
+ ), /* @__PURE__ */ React.createElement(Box, { marginLeft: 3 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, exitState.pending ? /* @__PURE__ */ React.createElement(React.Fragment, null, "Press ", exitState.keyName, " again to exit") : /* @__PURE__ */ React.createElement(React.Fragment, null, "Enter to confirm \xB7 Esc to exit"))));
104
+ }
105
+
106
+ // src/entrypoints/cli/setupScreens.tsx
107
+ init_config();
108
+
109
+ // src/ui/screens/MCPServerApproval.tsx
110
+ import React5 from "react";
111
+ import { render } from "ink";
112
+
113
+ // src/ui/components/MCPServerMultiselectDialog.tsx
114
+ import React3 from "react";
115
+ import { Box as Box2, Text as Text3, useInput as useInput2 } from "ink";
116
+ init_config();
117
+ import { MultiSelect } from "@inkjs/ui";
118
+ import { partition } from "lodash-es";
119
+
120
+ // src/ui/components/MCPServerDialogCopy.tsx
121
+ init_product();
122
+ import React2 from "react";
123
+ import { Text as Text2 } from "ink";
124
+ import Link from "ink-link";
125
+ function MCPServerDialogCopy() {
126
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text2, null, "MCP servers provide additional functionality to ", PRODUCT_NAME, ". They may execute code, make network requests, or access system resources via tool calls. All tool calls will require your explicit approval before execution. For more information, see", " ", /* @__PURE__ */ React2.createElement(Link, { url: "https://github.com/YOUR_USERNAME/newcraw/blob/main/docs/mcp.md" }, "MCP documentation")), /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, "Remember: You can always change these choices later by running `", PRODUCT_COMMAND, " mcp reset-project-choices`"));
127
+ }
128
+
129
+ // src/ui/components/MCPServerMultiselectDialog.tsx
130
+ function MCPServerMultiselectDialog({
131
+ serverNames,
132
+ onDone
133
+ }) {
134
+ const theme = getTheme();
135
+ function onSubmit(selectedServers) {
136
+ const config = getCurrentProjectConfig();
137
+ if (!config.approvedMcprcServers) {
138
+ config.approvedMcprcServers = [];
139
+ }
140
+ if (!config.rejectedMcprcServers) {
141
+ config.rejectedMcprcServers = [];
142
+ }
143
+ const [approvedServers, rejectedServers] = partition(
144
+ serverNames,
145
+ (server) => selectedServers.includes(server)
146
+ );
147
+ config.approvedMcprcServers.push(...approvedServers);
148
+ config.rejectedMcprcServers.push(...rejectedServers);
149
+ saveCurrentProjectConfig(config);
150
+ onDone();
151
+ }
152
+ const exitState = useExitOnCtrlCD(() => process.exit());
153
+ useInput2((_input, key) => {
154
+ if (key.escape) {
155
+ const config = getCurrentProjectConfig();
156
+ if (!config.rejectedMcprcServers) {
157
+ config.rejectedMcprcServers = [];
158
+ }
159
+ for (const server of serverNames) {
160
+ if (!config.rejectedMcprcServers.includes(server)) {
161
+ config.rejectedMcprcServers.push(server);
162
+ }
163
+ }
164
+ saveCurrentProjectConfig(config);
165
+ onDone();
166
+ return;
167
+ }
168
+ });
169
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
170
+ Box2,
171
+ {
172
+ flexDirection: "column",
173
+ gap: 1,
174
+ padding: 1,
175
+ borderStyle: "round",
176
+ borderColor: theme.warning
177
+ },
178
+ /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: theme.warning }, "New MCP Servers Detected"),
179
+ /* @__PURE__ */ React3.createElement(Text3, null, "This project contains an MCP config file (.mcp.json or .mcprc) with", " ", serverNames.length, " MCP servers that require your approval."),
180
+ /* @__PURE__ */ React3.createElement(MCPServerDialogCopy, null),
181
+ /* @__PURE__ */ React3.createElement(Text3, null, "Please select the servers you want to enable:"),
182
+ /* @__PURE__ */ React3.createElement(
183
+ MultiSelect,
184
+ {
185
+ options: serverNames.map((server) => ({
186
+ label: server,
187
+ value: server
188
+ })),
189
+ defaultValue: serverNames,
190
+ onSubmit
191
+ }
192
+ )
193
+ ), /* @__PURE__ */ React3.createElement(Box2, { marginLeft: 3 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, exitState.pending ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, "Press ", exitState.keyName, " again to exit") : /* @__PURE__ */ React3.createElement(React3.Fragment, null, "Space to select \xB7 Enter to confirm \xB7 Esc to reject all"))));
194
+ }
195
+
196
+ // src/ui/components/MCPServerApprovalDialog.tsx
197
+ import React4 from "react";
198
+ import { Box as Box3, Text as Text4, useInput as useInput3 } from "ink";
199
+ init_config();
200
+ function MCPServerApprovalDialog({
201
+ serverName,
202
+ onDone
203
+ }) {
204
+ const theme = getTheme();
205
+ function onChange(value) {
206
+ const config = getCurrentProjectConfig();
207
+ switch (value) {
208
+ case "yes": {
209
+ if (!config.approvedMcprcServers) {
210
+ config.approvedMcprcServers = [];
211
+ }
212
+ if (!config.approvedMcprcServers.includes(serverName)) {
213
+ config.approvedMcprcServers.push(serverName);
214
+ }
215
+ saveCurrentProjectConfig(config);
216
+ onDone();
217
+ break;
218
+ }
219
+ case "no": {
220
+ if (!config.rejectedMcprcServers) {
221
+ config.rejectedMcprcServers = [];
222
+ }
223
+ if (!config.rejectedMcprcServers.includes(serverName)) {
224
+ config.rejectedMcprcServers.push(serverName);
225
+ }
226
+ saveCurrentProjectConfig(config);
227
+ onDone();
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ const exitState = useExitOnCtrlCD(() => process.exit(0));
233
+ useInput3((_input, key) => {
234
+ if (key.escape) {
235
+ onDone();
236
+ return;
237
+ }
238
+ });
239
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
240
+ Box3,
241
+ {
242
+ flexDirection: "column",
243
+ gap: 1,
244
+ padding: 1,
245
+ borderStyle: "round",
246
+ borderColor: theme.warning
247
+ },
248
+ /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: theme.warning }, "New MCP Server Detected"),
249
+ /* @__PURE__ */ React4.createElement(Text4, null, "This project contains an MCP config file (.mcp.json or .mcprc) with an MCP server that requires your approval:"),
250
+ /* @__PURE__ */ React4.createElement(Text4, { bold: true }, serverName),
251
+ /* @__PURE__ */ React4.createElement(MCPServerDialogCopy, null),
252
+ /* @__PURE__ */ React4.createElement(Text4, null, "Do you want to approve this MCP server?"),
253
+ /* @__PURE__ */ React4.createElement(
254
+ Select,
255
+ {
256
+ options: [
257
+ { label: "Yes, approve this server", value: "yes" },
258
+ { label: "No, reject this server", value: "no" }
259
+ ],
260
+ onChange: (value) => onChange(value)
261
+ }
262
+ )
263
+ ), /* @__PURE__ */ React4.createElement(Box3, { marginLeft: 3 }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, exitState.pending ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, "Press ", exitState.keyName, " again to exit") : /* @__PURE__ */ React4.createElement(React4.Fragment, null, "Enter to confirm \xB7 Esc to reject"))));
264
+ }
265
+
266
+ // src/ui/screens/MCPServerApproval.tsx
267
+ init_config();
268
+ async function handleMcprcServerApprovals() {
269
+ const { servers } = getProjectMcpServerDefinitions();
270
+ const pendingServers = Object.keys(servers).filter(
271
+ (serverName) => getMcprcServerStatus(serverName) === "pending"
272
+ );
273
+ if (pendingServers.length === 0) {
274
+ return;
275
+ }
276
+ await new Promise((resolve) => {
277
+ const clearScreenAndResolve = () => {
278
+ process.stdout.write("\x1B[2J\x1B[3J\x1B[H", () => {
279
+ resolve();
280
+ });
281
+ };
282
+ if (pendingServers.length === 1 && pendingServers[0] !== void 0) {
283
+ const result = render(
284
+ /* @__PURE__ */ React5.createElement(
285
+ MCPServerApprovalDialog,
286
+ {
287
+ serverName: pendingServers[0],
288
+ onDone: () => {
289
+ result.unmount?.();
290
+ clearScreenAndResolve();
291
+ }
292
+ }
293
+ ),
294
+ { exitOnCtrlC: false }
295
+ );
296
+ } else {
297
+ const result = render(
298
+ /* @__PURE__ */ React5.createElement(
299
+ MCPServerMultiselectDialog,
300
+ {
301
+ serverNames: pendingServers,
302
+ onDone: () => {
303
+ result.unmount?.();
304
+ clearScreenAndResolve();
305
+ }
306
+ }
307
+ ),
308
+ { exitOnCtrlC: false }
309
+ );
310
+ }
311
+ });
312
+ }
313
+
314
+ // src/entrypoints/cli/setupScreens.tsx
315
+ function completeOnboarding() {
316
+ const config = getGlobalConfig();
317
+ saveGlobalConfig({
318
+ ...config,
319
+ hasCompletedOnboarding: true,
320
+ lastOnboardingVersion: MACRO.VERSION
321
+ });
322
+ }
323
+ async function showSetupScreens(safeMode, print) {
324
+ if (process.env.NODE_ENV === "test") {
325
+ return;
326
+ }
327
+ const config = getGlobalConfig();
328
+ if (!config.theme || !config.hasCompletedOnboarding) {
329
+ await clearTerminal();
330
+ const { render: render2 } = await import("ink");
331
+ await new Promise((resolve) => {
332
+ render2(
333
+ /* @__PURE__ */ React6.createElement(
334
+ Onboarding,
335
+ {
336
+ onDone: async () => {
337
+ completeOnboarding();
338
+ await clearTerminal();
339
+ resolve();
340
+ }
341
+ }
342
+ ),
343
+ {
344
+ exitOnCtrlC: false
345
+ }
346
+ );
347
+ });
348
+ }
349
+ if (!print) {
350
+ if (safeMode) {
351
+ if (!checkHasTrustDialogAccepted()) {
352
+ await new Promise((resolve) => {
353
+ const onDone = () => {
354
+ grantReadPermissionForOriginalDir();
355
+ resolve();
356
+ };
357
+ (async () => {
358
+ const { render: render2 } = await import("ink");
359
+ render2(/* @__PURE__ */ React6.createElement(TrustDialog, { onDone }), {
360
+ exitOnCtrlC: false
361
+ });
362
+ })();
363
+ });
364
+ }
365
+ }
366
+ await handleMcprcServerApprovals();
367
+ }
368
+ }
369
+
370
+ export {
371
+ showSetupScreens
372
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/entrypoints/cli/setupScreens.tsx", "../src/ui/components/TrustDialog.tsx", "../src/ui/screens/MCPServerApproval.tsx", "../src/ui/components/MCPServerMultiselectDialog.tsx", "../src/ui/components/MCPServerDialogCopy.tsx", "../src/ui/components/MCPServerApprovalDialog.tsx"],
4
+ "sourcesContent": ["import React from 'react'\r\n\r\nimport { MACRO } from '@constants/macros'\r\nimport { Onboarding } from '@components/Onboarding'\r\nimport { TrustDialog } from '@components/TrustDialog'\r\nimport {\r\n checkHasTrustDialogAccepted,\r\n getGlobalConfig,\r\n saveGlobalConfig,\r\n} from '@utils/config'\r\nimport { clearTerminal } from '@utils/terminal'\r\nimport { grantReadPermissionForOriginalDir } from '@utils/permissions/filesystem'\r\nimport { handleMcprcServerApprovals } from '@screens/MCPServerApproval'\r\n\r\nexport function completeOnboarding(): void {\r\n const config = getGlobalConfig()\r\n saveGlobalConfig({\r\n ...config,\r\n hasCompletedOnboarding: true,\r\n lastOnboardingVersion: MACRO.VERSION,\r\n })\r\n}\r\n\r\nexport async function showSetupScreens(\r\n safeMode?: boolean,\r\n print?: boolean,\r\n): Promise<void> {\r\n if (process.env.NODE_ENV === 'test') {\r\n return\r\n }\r\n\r\n const config = getGlobalConfig()\r\n if (!config.theme || !config.hasCompletedOnboarding) {\r\n await clearTerminal()\r\n const { render } = await import('ink')\r\n await new Promise<void>(resolve => {\r\n render(\r\n <Onboarding\r\n onDone={async () => {\r\n completeOnboarding()\r\n await clearTerminal()\r\n resolve()\r\n }}\r\n />,\r\n {\r\n exitOnCtrlC: false,\r\n },\r\n )\r\n })\r\n }\r\n\r\n if (!print) {\r\n if (safeMode) {\r\n if (!checkHasTrustDialogAccepted()) {\r\n await new Promise<void>(resolve => {\r\n const onDone = () => {\r\n grantReadPermissionForOriginalDir()\r\n resolve()\r\n }\r\n ;(async () => {\r\n const { render } = await import('ink')\r\n render(<TrustDialog onDone={onDone} />, {\r\n exitOnCtrlC: false,\r\n })\r\n })()\r\n })\r\n }\r\n }\r\n\r\n await handleMcprcServerApprovals()\r\n }\r\n}\r\n", "import React from 'react'\r\nimport { Box, Text, useInput } from 'ink'\r\nimport { getTheme } from '@utils/theme'\r\nimport { Select } from './custom-select/select'\r\nimport {\r\n saveCurrentProjectConfig,\r\n getCurrentProjectConfig,\r\n} from '@utils/config'\r\nimport { PRODUCT_NAME } from '@constants/product'\r\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\r\nimport { homedir } from 'os'\r\nimport { getCwd } from '@utils/state'\r\nimport Link from './Link'\r\n\r\ntype Props = {\r\n onDone(): void\r\n}\r\n\r\nexport function TrustDialog({ onDone }: Props): React.ReactNode {\r\n const theme = getTheme()\r\n React.useEffect(() => {}, [])\r\n\r\n function onChange(value: 'yes' | 'no') {\r\n const config = getCurrentProjectConfig()\r\n switch (value) {\r\n case 'yes': {\r\n const isHomeDir = homedir() === getCwd()\r\n\r\n if (!isHomeDir) {\r\n saveCurrentProjectConfig({\r\n ...config,\r\n hasTrustDialogAccepted: true,\r\n })\r\n }\r\n onDone()\r\n break\r\n }\r\n case 'no': {\r\n process.exit(1)\r\n break\r\n }\r\n }\r\n }\r\n\r\n const exitState = useExitOnCtrlCD(() => process.exit(0))\r\n\r\n useInput((_input, key) => {\r\n if (key.escape) {\r\n process.exit(0)\r\n return\r\n }\r\n })\r\n\r\n return (\r\n <>\r\n <Box\r\n flexDirection=\"column\"\r\n gap={1}\r\n padding={1}\r\n borderStyle=\"round\"\r\n borderColor={theme.warning}\r\n >\r\n <Text bold color={theme.warning}>\r\n Do you trust the files in this folder?\r\n </Text>\r\n <Text bold>{process.cwd()}</Text>\r\n\r\n <Box flexDirection=\"column\" gap={1}>\r\n <Text>\r\n {PRODUCT_NAME} may read files in this folder. Reading untrusted\r\n files may lead to {PRODUCT_NAME} to behave in an unexpected ways.\r\n </Text>\r\n <Text>\r\n With your permission {PRODUCT_NAME} may execute files in this\r\n folder. Executing untrusted code is unsafe.\r\n </Text>\r\n </Box>\r\n\r\n <Select\r\n options={[\r\n { label: 'Yes, proceed', value: 'yes' },\r\n { label: 'No, exit', value: 'no' },\r\n ]}\r\n onChange={value => onChange(value as 'yes' | 'no')}\r\n />\r\n </Box>\r\n <Box marginLeft={3}>\r\n <Text dimColor>\r\n {exitState.pending ? (\r\n <>Press {exitState.keyName} again to exit</>\r\n ) : (\r\n <>Enter to confirm \u00B7 Esc to exit</>\r\n )}\r\n </Text>\r\n </Box>\r\n </>\r\n )\r\n}\r\n", "import React from 'react'\r\nimport { render } from 'ink'\r\nimport { MCPServerMultiselectDialog } from '@components/MCPServerMultiselectDialog'\r\nimport { MCPServerApprovalDialog } from '@components/MCPServerApprovalDialog'\r\nimport { getMcprcServerStatus } from '@services/mcpClient'\r\nimport { getProjectMcpServerDefinitions } from '@utils/config'\r\n\r\nexport async function handleMcprcServerApprovals(): Promise<void> {\r\n const { servers } = getProjectMcpServerDefinitions()\r\n const pendingServers = Object.keys(servers).filter(\r\n serverName => getMcprcServerStatus(serverName) === 'pending',\r\n )\r\n\r\n if (pendingServers.length === 0) {\r\n return\r\n }\r\n\r\n await new Promise<void>(resolve => {\r\n const clearScreenAndResolve = () => {\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H', () => {\r\n resolve()\r\n })\r\n }\r\n\r\n if (pendingServers.length === 1 && pendingServers[0] !== undefined) {\r\n const result = render(\r\n <MCPServerApprovalDialog\r\n serverName={pendingServers[0]}\r\n onDone={() => {\r\n result.unmount?.()\r\n clearScreenAndResolve()\r\n }}\r\n />,\r\n { exitOnCtrlC: false },\r\n )\r\n } else {\r\n const result = render(\r\n <MCPServerMultiselectDialog\r\n serverNames={pendingServers}\r\n onDone={() => {\r\n result.unmount?.()\r\n clearScreenAndResolve()\r\n }}\r\n />,\r\n { exitOnCtrlC: false },\r\n )\r\n }\r\n })\r\n}\r\n\r\n", "import React from 'react'\r\nimport { Box, Text, useInput } from 'ink'\r\nimport { getTheme } from '@utils/theme'\r\nimport { MultiSelect } from '@inkjs/ui'\r\nimport {\r\n saveCurrentProjectConfig,\r\n getCurrentProjectConfig,\r\n} from '@utils/config'\r\nimport { partition } from 'lodash-es'\r\nimport { MCPServerDialogCopy } from './MCPServerDialogCopy'\r\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\r\n\r\ntype Props = {\r\n serverNames: string[]\r\n onDone(): void\r\n}\r\n\r\nexport function MCPServerMultiselectDialog({\r\n serverNames,\r\n onDone,\r\n}: Props): React.ReactNode {\r\n const theme = getTheme()\r\n function onSubmit(selectedServers: string[]) {\r\n const config = getCurrentProjectConfig()\r\n\r\n if (!config.approvedMcprcServers) {\r\n config.approvedMcprcServers = []\r\n }\r\n if (!config.rejectedMcprcServers) {\r\n config.rejectedMcprcServers = []\r\n }\r\n\r\n const [approvedServers, rejectedServers] = partition(serverNames, server =>\r\n selectedServers.includes(server),\r\n )\r\n\r\n config.approvedMcprcServers.push(...approvedServers)\r\n config.rejectedMcprcServers.push(...rejectedServers)\r\n\r\n saveCurrentProjectConfig(config)\r\n onDone()\r\n }\r\n\r\n const exitState = useExitOnCtrlCD(() => process.exit())\r\n\r\n useInput((_input, key) => {\r\n if (key.escape) {\r\n const config = getCurrentProjectConfig()\r\n if (!config.rejectedMcprcServers) {\r\n config.rejectedMcprcServers = []\r\n }\r\n\r\n for (const server of serverNames) {\r\n if (!config.rejectedMcprcServers.includes(server)) {\r\n config.rejectedMcprcServers.push(server)\r\n }\r\n }\r\n\r\n saveCurrentProjectConfig(config)\r\n onDone()\r\n return\r\n }\r\n })\r\n\r\n return (\r\n <>\r\n <Box\r\n flexDirection=\"column\"\r\n gap={1}\r\n padding={1}\r\n borderStyle=\"round\"\r\n borderColor={theme.warning}\r\n >\r\n <Text bold color={theme.warning}>\r\n New MCP Servers Detected\r\n </Text>\r\n <Text>\r\n This project contains an MCP config file (.mcp.json or .mcprc) with{' '}\r\n {serverNames.length} MCP servers that require your approval.\r\n </Text>\r\n <MCPServerDialogCopy />\r\n\r\n <Text>Please select the servers you want to enable:</Text>\r\n\r\n <MultiSelect\r\n options={serverNames.map(server => ({\r\n label: server,\r\n value: server,\r\n }))}\r\n defaultValue={serverNames}\r\n onSubmit={onSubmit}\r\n />\r\n </Box>\r\n <Box marginLeft={3}>\r\n <Text dimColor>\r\n {exitState.pending ? (\r\n <>Press {exitState.keyName} again to exit</>\r\n ) : (\r\n <>Space to select \u00B7 Enter to confirm \u00B7 Esc to reject all</>\r\n )}\r\n </Text>\r\n </Box>\r\n </>\r\n )\r\n}\r\n", "import React from 'react'\r\nimport { Text } from 'ink'\r\nimport Link from 'ink-link'\r\nimport { PRODUCT_NAME, PRODUCT_COMMAND } from '@constants/product'\r\n\r\nexport function MCPServerDialogCopy(): React.ReactNode {\r\n return (\r\n <>\r\n <Text>\r\n MCP servers provide additional functionality to {PRODUCT_NAME}. They may\r\n execute code, make network requests, or access system resources via tool\r\n calls. All tool calls will require your explicit approval before\r\n execution. For more information, see{' '}\r\n <Link url=\"https://github.com/YOUR_USERNAME/newcraw/blob/main/docs/mcp.md\">\r\n MCP documentation\r\n </Link>\r\n </Text>\r\n\r\n <Text dimColor>\r\n Remember: You can always change these choices later by running `\r\n {PRODUCT_COMMAND} mcp reset-project-choices`\r\n </Text>\r\n </>\r\n )\r\n}\r\n", "import React from 'react'\r\nimport { Box, Text, useInput } from 'ink'\r\nimport { getTheme } from '@utils/theme'\r\nimport { Select } from './custom-select/select'\r\nimport {\r\n saveCurrentProjectConfig,\r\n getCurrentProjectConfig,\r\n} from '@utils/config'\r\nimport { MCPServerDialogCopy } from './MCPServerDialogCopy'\r\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\r\n\r\ntype Props = {\r\n serverName: string\r\n onDone(): void\r\n}\r\n\r\nexport function MCPServerApprovalDialog({\r\n serverName,\r\n onDone,\r\n}: Props): React.ReactNode {\r\n const theme = getTheme()\r\n function onChange(value: 'yes' | 'no') {\r\n const config = getCurrentProjectConfig()\r\n switch (value) {\r\n case 'yes': {\r\n if (!config.approvedMcprcServers) {\r\n config.approvedMcprcServers = []\r\n }\r\n if (!config.approvedMcprcServers.includes(serverName)) {\r\n config.approvedMcprcServers.push(serverName)\r\n }\r\n saveCurrentProjectConfig(config)\r\n onDone()\r\n break\r\n }\r\n case 'no': {\r\n if (!config.rejectedMcprcServers) {\r\n config.rejectedMcprcServers = []\r\n }\r\n if (!config.rejectedMcprcServers.includes(serverName)) {\r\n config.rejectedMcprcServers.push(serverName)\r\n }\r\n saveCurrentProjectConfig(config)\r\n onDone()\r\n break\r\n }\r\n }\r\n }\r\n\r\n const exitState = useExitOnCtrlCD(() => process.exit(0))\r\n\r\n useInput((_input, key) => {\r\n if (key.escape) {\r\n onDone()\r\n return\r\n }\r\n })\r\n\r\n return (\r\n <>\r\n <Box\r\n flexDirection=\"column\"\r\n gap={1}\r\n padding={1}\r\n borderStyle=\"round\"\r\n borderColor={theme.warning}\r\n >\r\n <Text bold color={theme.warning}>\r\n New MCP Server Detected\r\n </Text>\r\n <Text>\r\n This project contains an MCP config file (.mcp.json or .mcprc) with an\r\n MCP server that requires your approval:\r\n </Text>\r\n <Text bold>{serverName}</Text>\r\n\r\n <MCPServerDialogCopy />\r\n\r\n <Text>Do you want to approve this MCP server?</Text>\r\n\r\n <Select\r\n options={[\r\n { label: 'Yes, approve this server', value: 'yes' },\r\n { label: 'No, reject this server', value: 'no' },\r\n ]}\r\n onChange={value => onChange(value as 'yes' | 'no')}\r\n />\r\n </Box>\r\n <Box marginLeft={3}>\r\n <Text dimColor>\r\n {exitState.pending ? (\r\n <>Press {exitState.keyName} again to exit</>\r\n ) : (\r\n <>Enter to confirm \u00B7 Esc to reject</>\r\n )}\r\n </Text>\r\n </Box>\r\n </>\r\n )\r\n}\r\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "React", "React", "Box", "Text", "useInput", "React", "Text", "useInput", "React", "Box", "Text", "React", "Box", "Text", "useInput", "useInput", "React", "Box", "Text", "React", "render", "React"]
7
+ }
@@ -0,0 +1,135 @@
1
+ import { createRequire as __newcrawCreateRequire } from "node:module";
2
+ const require = __newcrawCreateRequire(import.meta.url);
3
+ import {
4
+ debug,
5
+ init_debugLogger
6
+ } from "./chunk-GZ4BEVMZ.js";
7
+
8
+ // src/services/ai/healthCheck.ts
9
+ init_debugLogger();
10
+ var healthRegistry = /* @__PURE__ */ new Map();
11
+ var HEALTH_CHECK_INTERVAL_MS = 6e4;
12
+ var FAILURE_THRESHOLD = 3;
13
+ var RECOVERY_CHECK_INTERVAL_MS = 3e4;
14
+ function getProviderHealth(provider) {
15
+ if (!healthRegistry.has(provider)) {
16
+ healthRegistry.set(provider, {
17
+ provider,
18
+ available: true,
19
+ lastCheckedAt: 0,
20
+ consecutiveFailures: 0
21
+ });
22
+ }
23
+ return healthRegistry.get(provider);
24
+ }
25
+ function markProviderSuccess(provider, latencyMs) {
26
+ const health = getProviderHealth(provider);
27
+ health.available = true;
28
+ health.lastCheckedAt = Date.now();
29
+ health.consecutiveFailures = 0;
30
+ health.latencyMs = latencyMs;
31
+ debug.flow("PROVIDER_HEALTH_SUCCESS", {
32
+ provider,
33
+ latencyMs
34
+ });
35
+ }
36
+ function markProviderFailure(provider, error) {
37
+ const health = getProviderHealth(provider);
38
+ health.consecutiveFailures++;
39
+ health.lastErrorAt = Date.now();
40
+ health.lastCheckedAt = Date.now();
41
+ if (health.consecutiveFailures >= FAILURE_THRESHOLD) {
42
+ health.available = false;
43
+ debug.warn("PROVIDER_MARKED_UNAVAILABLE", {
44
+ provider,
45
+ consecutiveFailures: health.consecutiveFailures,
46
+ error
47
+ });
48
+ }
49
+ }
50
+ function isProviderAvailable(provider) {
51
+ const health = getProviderHealth(provider);
52
+ if (health.available) return true;
53
+ if (health.lastCheckedAt && Date.now() - health.lastCheckedAt > RECOVERY_CHECK_INTERVAL_MS) {
54
+ debug.flow("PROVIDER_RECOVERY_CHECK", { provider });
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+ function shouldCheckHealth(provider) {
60
+ const health = getProviderHealth(provider);
61
+ return Date.now() - health.lastCheckedAt > HEALTH_CHECK_INTERVAL_MS;
62
+ }
63
+ function selectAvailableProvider(chain) {
64
+ if (isProviderAvailable(chain.primary)) {
65
+ return chain.primary;
66
+ }
67
+ for (const fallback of chain.fallbacks) {
68
+ if (isProviderAvailable(fallback)) {
69
+ debug.flow("PROVIDER_FAILOVER", {
70
+ from: chain.primary,
71
+ to: fallback
72
+ });
73
+ return fallback;
74
+ }
75
+ }
76
+ debug.warn("ALL_PROVIDERS_UNAVAILABLE", {
77
+ primary: chain.primary,
78
+ fallbacks: chain.fallbacks
79
+ });
80
+ return null;
81
+ }
82
+ var probeInterval = null;
83
+ var registeredProbe = null;
84
+ var PROBE_INTERVAL_MS = 12e4;
85
+ function registerHealthProbe(probe) {
86
+ registeredProbe = probe;
87
+ }
88
+ function startPeriodicHealthCheck(providers) {
89
+ if (probeInterval) return;
90
+ probeInterval = setInterval(async () => {
91
+ if (!registeredProbe) return;
92
+ for (const provider of providers) {
93
+ const health = getProviderHealth(provider);
94
+ if (!health.available || shouldCheckHealth(provider)) {
95
+ try {
96
+ const ok = await registeredProbe(provider);
97
+ if (ok) {
98
+ markProviderSuccess(provider);
99
+ } else {
100
+ markProviderFailure(provider, "probe returned false");
101
+ }
102
+ } catch (err) {
103
+ markProviderFailure(
104
+ provider,
105
+ err instanceof Error ? err.message : String(err)
106
+ );
107
+ }
108
+ }
109
+ }
110
+ }, PROBE_INTERVAL_MS);
111
+ if (probeInterval && typeof probeInterval === "object" && "unref" in probeInterval) {
112
+ probeInterval.unref();
113
+ }
114
+ debug.flow("HEALTH_PROBE_STARTED", {
115
+ providers,
116
+ intervalMs: PROBE_INTERVAL_MS
117
+ });
118
+ }
119
+ function stopPeriodicHealthCheck() {
120
+ if (probeInterval) {
121
+ clearInterval(probeInterval);
122
+ probeInterval = null;
123
+ debug.flow("HEALTH_PROBE_STOPPED", {});
124
+ }
125
+ }
126
+
127
+ export {
128
+ markProviderSuccess,
129
+ markProviderFailure,
130
+ isProviderAvailable,
131
+ selectAvailableProvider,
132
+ registerHealthProbe,
133
+ startPeriodicHealthCheck,
134
+ stopPeriodicHealthCheck
135
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/services/ai/healthCheck.ts"],
4
+ "sourcesContent": ["import { logError } from '@utils/log'\r\nimport { debug as debugLogger } from '@utils/log/debugLogger'\r\n\r\nexport interface ProviderHealth {\r\n provider: string\r\n available: boolean\r\n lastCheckedAt: number\r\n lastErrorAt?: number\r\n consecutiveFailures: number\r\n latencyMs?: number\r\n}\r\n\r\nconst healthRegistry = new Map<string, ProviderHealth>()\r\n\r\nconst HEALTH_CHECK_INTERVAL_MS = 60_000\r\nconst FAILURE_THRESHOLD = 3\r\nconst RECOVERY_CHECK_INTERVAL_MS = 30_000\r\n\r\nexport function getProviderHealth(provider: string): ProviderHealth {\r\n if (!healthRegistry.has(provider)) {\r\n healthRegistry.set(provider, {\r\n provider,\r\n available: true,\r\n lastCheckedAt: 0,\r\n consecutiveFailures: 0,\r\n })\r\n }\r\n return healthRegistry.get(provider)!\r\n}\r\n\r\nexport function markProviderSuccess(provider: string, latencyMs?: number): void {\r\n const health = getProviderHealth(provider)\r\n health.available = true\r\n health.lastCheckedAt = Date.now()\r\n health.consecutiveFailures = 0\r\n health.latencyMs = latencyMs\r\n\r\n debugLogger.flow('PROVIDER_HEALTH_SUCCESS', {\r\n provider,\r\n latencyMs,\r\n })\r\n}\r\n\r\nexport function markProviderFailure(provider: string, error?: string): void {\r\n const health = getProviderHealth(provider)\r\n health.consecutiveFailures++\r\n health.lastErrorAt = Date.now()\r\n health.lastCheckedAt = Date.now()\r\n\r\n if (health.consecutiveFailures >= FAILURE_THRESHOLD) {\r\n health.available = false\r\n debugLogger.warn('PROVIDER_MARKED_UNAVAILABLE', {\r\n provider,\r\n consecutiveFailures: health.consecutiveFailures,\r\n error,\r\n })\r\n }\r\n}\r\n\r\nexport function isProviderAvailable(provider: string): boolean {\r\n const health = getProviderHealth(provider)\r\n\r\n if (health.available) return true\r\n\r\n if (\r\n health.lastCheckedAt &&\r\n Date.now() - health.lastCheckedAt > RECOVERY_CHECK_INTERVAL_MS\r\n ) {\r\n debugLogger.flow('PROVIDER_RECOVERY_CHECK', { provider })\r\n return true\r\n }\r\n\r\n return false\r\n}\r\n\r\nexport function shouldCheckHealth(provider: string): boolean {\r\n const health = getProviderHealth(provider)\r\n return Date.now() - health.lastCheckedAt > HEALTH_CHECK_INTERVAL_MS\r\n}\r\n\r\nexport interface FallbackChain {\r\n primary: string\r\n fallbacks: string[]\r\n}\r\n\r\nexport function selectAvailableProvider(chain: FallbackChain): string | null {\r\n if (isProviderAvailable(chain.primary)) {\r\n return chain.primary\r\n }\r\n\r\n for (const fallback of chain.fallbacks) {\r\n if (isProviderAvailable(fallback)) {\r\n debugLogger.flow('PROVIDER_FAILOVER', {\r\n from: chain.primary,\r\n to: fallback,\r\n })\r\n return fallback\r\n }\r\n }\r\n\r\n debugLogger.warn('ALL_PROVIDERS_UNAVAILABLE', {\r\n primary: chain.primary,\r\n fallbacks: chain.fallbacks,\r\n })\r\n return null\r\n}\r\n\r\nexport function getAllProviderHealth(): ProviderHealth[] {\r\n return Array.from(healthRegistry.values())\r\n}\r\n\r\nexport function resetProviderHealth(provider: string): void {\r\n healthRegistry.delete(provider)\r\n}\r\n\r\nexport function resetAllHealth(): void {\r\n healthRegistry.clear()\r\n}\r\n\r\nexport type ProbeFunction = (provider: string) => Promise<boolean>\r\n\r\nlet probeInterval: ReturnType<typeof setInterval> | null = null\r\nlet registeredProbe: ProbeFunction | null = null\r\nconst PROBE_INTERVAL_MS = 120_000\r\n\r\nexport function registerHealthProbe(probe: ProbeFunction): void {\r\n registeredProbe = probe\r\n}\r\n\r\nexport function startPeriodicHealthCheck(providers: string[]): void {\r\n if (probeInterval) return\r\n\r\n probeInterval = setInterval(async () => {\r\n if (!registeredProbe) return\r\n\r\n for (const provider of providers) {\r\n const health = getProviderHealth(provider)\r\n if (!health.available || shouldCheckHealth(provider)) {\r\n try {\r\n const ok = await registeredProbe(provider)\r\n if (ok) {\r\n markProviderSuccess(provider)\r\n } else {\r\n markProviderFailure(provider, 'probe returned false')\r\n }\r\n } catch (err) {\r\n markProviderFailure(\r\n provider,\r\n err instanceof Error ? err.message : String(err),\r\n )\r\n }\r\n }\r\n }\r\n }, PROBE_INTERVAL_MS)\r\n\r\n if (probeInterval && typeof probeInterval === 'object' && 'unref' in probeInterval) {\r\n probeInterval.unref()\r\n }\r\n\r\n debugLogger.flow('HEALTH_PROBE_STARTED', {\r\n providers,\r\n intervalMs: PROBE_INTERVAL_MS,\r\n })\r\n}\r\n\r\nexport function stopPeriodicHealthCheck(): void {\r\n if (probeInterval) {\r\n clearInterval(probeInterval)\r\n probeInterval = null\r\n debugLogger.flow('HEALTH_PROBE_STOPPED', {})\r\n }\r\n}\r\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -3,7 +3,7 @@ const require = __newcrawCreateRequire(import.meta.url);
3
3
  import {
4
4
  getSessionProjectDir,
5
5
  getSessionProjectsDir
6
- } from "./chunk-XXU2NVOE.js";
6
+ } from "./chunk-PC6QOCGI.js";
7
7
  import {
8
8
  isUuid
9
9
  } from "./chunk-JX5ZQYTQ.js";