@shareai-lab/kode 2.0.2 → 2.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 (343) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +649 -25
  3. package/README.zh-CN.md +579 -0
  4. package/cli-acp.js +3 -17
  5. package/cli.js +5 -7
  6. package/dist/chunks/Doctor-M3J7GRTJ.js +12 -0
  7. package/dist/chunks/LogList-ISWZ6DDD.js +121 -0
  8. package/dist/chunks/LogList-ISWZ6DDD.js.map +7 -0
  9. package/dist/chunks/REPL-RQ6LO6S7.js +56 -0
  10. package/dist/chunks/ResumeConversation-6DMVBEGH.js +56 -0
  11. package/dist/chunks/agentLoader-FCRG3TFJ.js +31 -0
  12. package/dist/{agentsValidate-XP3CFN6F.js → chunks/agentsValidate-PEWMYN4Q.js} +97 -69
  13. package/dist/chunks/agentsValidate-PEWMYN4Q.js.map +7 -0
  14. package/dist/{ask-3G5H5KD5.js → chunks/ask-D7SOHJ6Z.js} +36 -44
  15. package/dist/chunks/ask-D7SOHJ6Z.js.map +7 -0
  16. package/dist/chunks/autoUpdater-CNESBOKO.js +19 -0
  17. package/dist/{chunk-EH34V7CY.js → chunks/chunk-2JN5MY67.js} +12 -14
  18. package/dist/chunks/chunk-2JN5MY67.js.map +7 -0
  19. package/dist/chunks/chunk-2QONJ5MG.js +14 -0
  20. package/dist/chunks/chunk-2QONJ5MG.js.map +7 -0
  21. package/dist/chunks/chunk-2WEXPKHH.js +903 -0
  22. package/dist/chunks/chunk-2WEXPKHH.js.map +7 -0
  23. package/dist/{chunk-K2MI4TPB.js → chunks/chunk-3BYE3ME6.js} +717 -792
  24. package/dist/chunks/chunk-3BYE3ME6.js.map +7 -0
  25. package/dist/chunks/chunk-3JDNWX7W.js +1264 -0
  26. package/dist/chunks/chunk-3JDNWX7W.js.map +7 -0
  27. package/dist/chunks/chunk-3OEJVB5A.js +906 -0
  28. package/dist/chunks/chunk-3OEJVB5A.js.map +7 -0
  29. package/dist/chunks/chunk-3TNIOEBO.js +369 -0
  30. package/dist/chunks/chunk-3TNIOEBO.js.map +7 -0
  31. package/dist/chunks/chunk-4A46ZXMJ.js +67 -0
  32. package/dist/chunks/chunk-4A46ZXMJ.js.map +7 -0
  33. package/dist/{chunk-4GAIJGRH.js → chunks/chunk-4ATBQOFO.js} +107 -55
  34. package/dist/chunks/chunk-4ATBQOFO.js.map +7 -0
  35. package/dist/chunks/chunk-4CRUCZR4.js +0 -0
  36. package/dist/{chunk-54DNHKOD.js → chunks/chunk-4EO6SIQY.js} +32 -75
  37. package/dist/chunks/chunk-4EO6SIQY.js.map +7 -0
  38. package/dist/chunks/chunk-53M46S5I.js +64 -0
  39. package/dist/chunks/chunk-53M46S5I.js.map +7 -0
  40. package/dist/{chunk-JC6NCUG5.js → chunks/chunk-54KOYG5C.js} +0 -2
  41. package/dist/{chunk-EZXMVTDU.js → chunks/chunk-6BAS4WY6.js} +29 -45
  42. package/dist/chunks/chunk-6BAS4WY6.js.map +7 -0
  43. package/dist/{chunk-BHGTA6JQ.js → chunks/chunk-6KRRFSDN.js} +4 -6
  44. package/dist/chunks/chunk-6KRRFSDN.js.map +7 -0
  45. package/dist/chunks/chunk-6LJNZK4K.js +39 -0
  46. package/dist/chunks/chunk-6LJNZK4K.js.map +7 -0
  47. package/dist/chunks/chunk-6ZWEOSEI.js +666 -0
  48. package/dist/chunks/chunk-6ZWEOSEI.js.map +7 -0
  49. package/dist/chunks/chunk-77XDJMBP.js +3326 -0
  50. package/dist/chunks/chunk-77XDJMBP.js.map +7 -0
  51. package/dist/chunks/chunk-7RRW4NTB.js +6454 -0
  52. package/dist/chunks/chunk-7RRW4NTB.js.map +7 -0
  53. package/dist/chunks/chunk-7X3TW4JB.js +4520 -0
  54. package/dist/chunks/chunk-7X3TW4JB.js.map +7 -0
  55. package/dist/chunks/chunk-B3MW3YGY.js +1409 -0
  56. package/dist/chunks/chunk-B3MW3YGY.js.map +7 -0
  57. package/dist/chunks/chunk-BBJFHTBC.js +28 -0
  58. package/dist/chunks/chunk-BBJFHTBC.js.map +7 -0
  59. package/dist/chunks/chunk-BHDHXOXB.js +24 -0
  60. package/dist/chunks/chunk-BHDHXOXB.js.map +7 -0
  61. package/dist/{chunk-OZNRLY3E.js → chunks/chunk-BTA7SZ26.js} +152 -223
  62. package/dist/chunks/chunk-BTA7SZ26.js.map +7 -0
  63. package/dist/chunks/chunk-CDGRYGPZ.js +103 -0
  64. package/dist/chunks/chunk-CDGRYGPZ.js.map +7 -0
  65. package/dist/{chunk-S6HRABTA.js → chunks/chunk-CP6E5UG6.js} +1 -4
  66. package/dist/chunks/chunk-CP6E5UG6.js.map +7 -0
  67. package/dist/{chunk-2PMO2FS2.js → chunks/chunk-DQ4JHXMT.js} +462 -424
  68. package/dist/chunks/chunk-DQ4JHXMT.js.map +7 -0
  69. package/dist/chunks/chunk-DXD76CMV.js +208 -0
  70. package/dist/chunks/chunk-DXD76CMV.js.map +7 -0
  71. package/dist/chunks/chunk-GCQCAXJZ.js +0 -0
  72. package/dist/chunks/chunk-GELCZWMB.js +42 -0
  73. package/dist/chunks/chunk-GELCZWMB.js.map +7 -0
  74. package/dist/{chunk-NQLEUHMS.js → chunks/chunk-HJYOH4HC.js} +23 -18
  75. package/dist/chunks/chunk-HJYOH4HC.js.map +7 -0
  76. package/dist/chunks/chunk-HPYNW6TT.js +744 -0
  77. package/dist/chunks/chunk-HPYNW6TT.js.map +7 -0
  78. package/dist/{chunk-2KWKUXLT.js → chunks/chunk-HRJ3ICQK.js} +59 -55
  79. package/dist/chunks/chunk-HRJ3ICQK.js.map +7 -0
  80. package/dist/{chunk-ZQU3TXLC.js → chunks/chunk-IFCIADS3.js} +571 -573
  81. package/dist/chunks/chunk-IFCIADS3.js.map +7 -0
  82. package/dist/chunks/chunk-IN7XZ7BC.js +27 -0
  83. package/dist/chunks/chunk-IN7XZ7BC.js.map +7 -0
  84. package/dist/chunks/chunk-L7P4M4KW.js +193 -0
  85. package/dist/chunks/chunk-L7P4M4KW.js.map +7 -0
  86. package/dist/chunks/chunk-LB6TCPDI.js +0 -0
  87. package/dist/{chunk-3RUXVV4S.js → chunks/chunk-LOCXPQNJ.js} +1 -4
  88. package/dist/{chunk-3RUXVV4S.js.map → chunks/chunk-LOCXPQNJ.js.map} +2 -2
  89. package/dist/{chunk-IE2CG2TV.js → chunks/chunk-LOD5ZHCI.js} +213 -208
  90. package/dist/chunks/chunk-LOD5ZHCI.js.map +7 -0
  91. package/dist/{chunk-S3J2TLV6.js → chunks/chunk-M7P3QNRU.js} +1 -4
  92. package/dist/{chunk-S3J2TLV6.js.map → chunks/chunk-M7P3QNRU.js.map} +2 -2
  93. package/dist/chunks/chunk-PPHLQVL7.js +4234 -0
  94. package/dist/chunks/chunk-PPHLQVL7.js.map +7 -0
  95. package/dist/{chunk-ABLVTESJ.js → chunks/chunk-QAXE37B5.js} +1 -4
  96. package/dist/chunks/chunk-QAXE37B5.js.map +7 -0
  97. package/dist/chunks/chunk-QHQOBUF6.js +60 -0
  98. package/dist/chunks/chunk-QHQOBUF6.js.map +7 -0
  99. package/dist/{chunk-SRZZFAS7.js → chunks/chunk-RPJXO7GG.js} +241 -214
  100. package/dist/chunks/chunk-RPJXO7GG.js.map +7 -0
  101. package/dist/{chunk-NPFOMITO.js → chunks/chunk-SWQV4KSY.js} +1 -4
  102. package/dist/{chunk-NPFOMITO.js.map → chunks/chunk-SWQV4KSY.js.map} +2 -2
  103. package/dist/chunks/chunk-SZLAPULP.js +28 -0
  104. package/dist/chunks/chunk-SZLAPULP.js.map +7 -0
  105. package/dist/{chunk-SDGKPKDK.js → chunks/chunk-T7RB5V5J.js} +23 -25
  106. package/dist/chunks/chunk-T7RB5V5J.js.map +7 -0
  107. package/dist/{chunk-HN4E4UUQ.js → chunks/chunk-TI2CTTMA.js} +25 -17
  108. package/dist/chunks/chunk-TI2CTTMA.js.map +7 -0
  109. package/dist/{chunk-G6I7XROM.js → chunks/chunk-TNGVRTO5.js} +45 -20
  110. package/dist/chunks/chunk-TNGVRTO5.js.map +7 -0
  111. package/dist/chunks/chunk-TNWB3U5Y.js +2077 -0
  112. package/dist/chunks/chunk-TNWB3U5Y.js.map +7 -0
  113. package/dist/chunks/chunk-U2IHWPCU.js +12 -0
  114. package/dist/chunks/chunk-U2IHWPCU.js.map +7 -0
  115. package/dist/{chunk-KAA5BGMQ.js → chunks/chunk-UNOY3VJ2.js} +1 -4
  116. package/dist/{chunk-KAA5BGMQ.js.map → chunks/chunk-UNOY3VJ2.js.map} +2 -2
  117. package/dist/{chunk-3TXNP6HH.js → chunks/chunk-UVDJL6ZZ.js} +97 -58
  118. package/dist/chunks/chunk-UVDJL6ZZ.js.map +7 -0
  119. package/dist/chunks/chunk-VNCW4C2Z.js +13452 -0
  120. package/dist/chunks/chunk-VNCW4C2Z.js.map +7 -0
  121. package/dist/chunks/chunk-W5EGGA44.js +15 -0
  122. package/dist/chunks/chunk-W5EGGA44.js.map +7 -0
  123. package/dist/chunks/chunk-XR2W3MAM.js +1533 -0
  124. package/dist/chunks/chunk-XR2W3MAM.js.map +7 -0
  125. package/dist/{chunk-QYFKRZQC.js → chunks/chunk-YIO5EBMQ.js} +423 -377
  126. package/dist/chunks/chunk-YIO5EBMQ.js.map +7 -0
  127. package/dist/chunks/chunk-ZBVLKZ5V.js +1062 -0
  128. package/dist/chunks/chunk-ZBVLKZ5V.js.map +7 -0
  129. package/dist/{chunk-E6YNABER.js → chunks/chunk-ZCLTZIVP.js} +1 -4
  130. package/dist/chunks/chunk-ZCLTZIVP.js.map +7 -0
  131. package/dist/chunks/client-SILZNM5N.js +42 -0
  132. package/dist/{config-6ZMBCL23.js → chunks/config-25HRTPSP.js} +48 -10
  133. package/dist/chunks/cost-tracker-Z2UZT2J5.js +28 -0
  134. package/dist/{customCommands-DNEJS3ZU.js → chunks/customCommands-TYMYZRG5.js} +11 -8
  135. package/dist/chunks/engine-MRVF6FK6.js +39 -0
  136. package/dist/{env-OFAXZ3XG.js → chunks/env-TJ5NOBEB.js} +7 -5
  137. package/dist/{kodeAgentSessionId-X6XWQW7B.js → chunks/kodeAgentSessionId-VTNISJ2L.js} +2 -4
  138. package/dist/chunks/kodeAgentSessionLoad-YB2RKBGJ.js +15 -0
  139. package/dist/chunks/kodeAgentSessionResume-DZSIVKVA.js +13 -0
  140. package/dist/chunks/kodeAgentStreamJson-X5PLS2S6.js +11 -0
  141. package/dist/{kodeAgentStreamJsonSession-GRWG3SPE.js → chunks/kodeAgentStreamJsonSession-RDXM4XYF.js} +38 -24
  142. package/dist/chunks/kodeAgentStreamJsonSession-RDXM4XYF.js.map +7 -0
  143. package/dist/{chunk-4RTX4AG4.js → chunks/kodeAgentStructuredStdio-SVGDSB4P.js} +14 -9
  144. package/dist/chunks/kodeAgentStructuredStdio-SVGDSB4P.js.map +7 -0
  145. package/dist/{kodeHooks-TDMXFWSO.js → chunks/kodeHooks-RVKYRJHG.js} +11 -9
  146. package/dist/{llm-XVXWYOHK.js → chunks/llm-62N6T5ZT.js} +1734 -1526
  147. package/dist/chunks/llm-62N6T5ZT.js.map +7 -0
  148. package/dist/chunks/llmLazy-ZUSSE3ZA.js +13 -0
  149. package/dist/{mentionProcessor-YD7YXYGF.js → chunks/mentionProcessor-RJW5UPJD.js} +46 -16
  150. package/dist/chunks/mentionProcessor-RJW5UPJD.js.map +7 -0
  151. package/dist/{messages-OFUJSPRV.js → chunks/messages-EEWWLPHN.js} +2 -6
  152. package/dist/chunks/model-5TIEKQPD.js +37 -0
  153. package/dist/{openai-5G5D5Q4B.js → chunks/openai-XXK3YZG4.js} +13 -10
  154. package/dist/{outputStyles-HLDXFQK3.js → chunks/outputStyles-FAJTXN2A.js} +6 -9
  155. package/dist/chunks/permissions-HO7INPWM.js +27 -0
  156. package/dist/{pluginRuntime-FPTKK6NY.js → chunks/pluginRuntime-C7K5ULK2.js} +31 -48
  157. package/dist/chunks/pluginRuntime-C7K5ULK2.js.map +7 -0
  158. package/dist/chunks/pluginValidation-DAM7WRTC.js +20 -0
  159. package/dist/chunks/registry-XYJXMOA5.js +60 -0
  160. package/dist/chunks/responsesStreaming-JNGE2P3D.js +8 -0
  161. package/dist/chunks/runNonTextPrintMode-SVBLCZQX.js +577 -0
  162. package/dist/chunks/runNonTextPrintMode-SVBLCZQX.js.map +7 -0
  163. package/dist/chunks/server-REXXF5IK.js +46 -0
  164. package/dist/{skillMarketplace-PSNKDINM.js → chunks/skillMarketplace-N4HVHNST.js} +8 -6
  165. package/dist/chunks/src-OROQIWP3.js +44 -0
  166. package/dist/chunks/src-QXLGGMUW.js +1647 -0
  167. package/dist/chunks/src-QXLGGMUW.js.map +7 -0
  168. package/dist/{cli-SRV2INSL.js → chunks/src-SSDT6MVP.js} +2659 -3384
  169. package/dist/chunks/src-SSDT6MVP.js.map +7 -0
  170. package/dist/chunks/theme-YBJUIMWK.js +10 -0
  171. package/dist/{toolPermissionContext-65L65VEZ.js → chunks/toolPermissionContext-MOCTRR7N.js} +2 -4
  172. package/dist/chunks/toolPermissionSettings-EV2EJAXL.js +18 -0
  173. package/dist/chunks/toolPermissionSettings-EV2EJAXL.js.map +7 -0
  174. package/dist/chunks/uuid-6577SO6X.js +7 -0
  175. package/dist/chunks/uuid-6577SO6X.js.map +7 -0
  176. package/dist/chunks/webOnlyMode-ALXX7UQY.js +66 -0
  177. package/dist/chunks/webOnlyMode-ALXX7UQY.js.map +7 -0
  178. package/dist/entrypoints/cli.js +10 -0
  179. package/dist/entrypoints/cli.js.map +7 -0
  180. package/dist/entrypoints/daemon.js +10 -0
  181. package/dist/entrypoints/daemon.js.map +7 -0
  182. package/dist/entrypoints/mcp.js +71 -0
  183. package/dist/entrypoints/mcp.js.map +7 -0
  184. package/dist/index.js +6 -7
  185. package/dist/index.js.map +3 -3
  186. package/dist/sdk/client.cjs +391 -0
  187. package/dist/sdk/client.cjs.map +7 -0
  188. package/dist/sdk/client.js +364 -0
  189. package/dist/sdk/client.js.map +7 -0
  190. package/dist/sdk/core.cjs +19932 -0
  191. package/dist/sdk/core.cjs.map +7 -0
  192. package/dist/sdk/core.js +19893 -0
  193. package/dist/sdk/core.js.map +7 -0
  194. package/dist/sdk/daemon-client.cjs +257 -0
  195. package/dist/sdk/daemon-client.cjs.map +7 -0
  196. package/dist/sdk/daemon-client.js +221 -0
  197. package/dist/sdk/daemon-client.js.map +7 -0
  198. package/dist/sdk/protocol.cjs +170 -0
  199. package/dist/sdk/protocol.cjs.map +7 -0
  200. package/dist/sdk/protocol.js +140 -0
  201. package/dist/sdk/protocol.js.map +7 -0
  202. package/dist/sdk/runtime-node.cjs +236 -0
  203. package/dist/sdk/runtime-node.cjs.map +7 -0
  204. package/dist/sdk/runtime-node.js +222 -0
  205. package/dist/sdk/runtime-node.js.map +7 -0
  206. package/dist/sdk/runtime.cjs +17 -0
  207. package/dist/sdk/runtime.cjs.map +7 -0
  208. package/dist/sdk/runtime.js +0 -0
  209. package/dist/sdk/runtime.js.map +7 -0
  210. package/dist/sdk/tools.cjs +30300 -0
  211. package/dist/sdk/tools.cjs.map +7 -0
  212. package/dist/sdk/tools.js +30282 -0
  213. package/dist/sdk/tools.js.map +7 -0
  214. package/dist/webui/assets/index-5hlfByVS.css +1 -0
  215. package/dist/webui/assets/index-BR9lm1lA.js +82 -0
  216. package/dist/webui/index.html +28 -0
  217. package/package.json +93 -22
  218. package/scripts/binary-utils.cjs +12 -4
  219. package/scripts/cli-acp-wrapper.cjs +3 -17
  220. package/scripts/cli-wrapper.cjs +5 -7
  221. package/scripts/postinstall.js +8 -4
  222. package/dist/REPL-GIU4ZIXM.js +0 -42
  223. package/dist/acp-H3VJ77YG.js +0 -1357
  224. package/dist/acp-H3VJ77YG.js.map +0 -7
  225. package/dist/agentsValidate-XP3CFN6F.js.map +0 -7
  226. package/dist/ask-3G5H5KD5.js.map +0 -7
  227. package/dist/autoUpdater-DNRMJWFQ.js +0 -17
  228. package/dist/chunk-2KWKUXLT.js.map +0 -7
  229. package/dist/chunk-2PMO2FS2.js.map +0 -7
  230. package/dist/chunk-3TXNP6HH.js.map +0 -7
  231. package/dist/chunk-4GAIJGRH.js.map +0 -7
  232. package/dist/chunk-4RTX4AG4.js.map +0 -7
  233. package/dist/chunk-54DNHKOD.js.map +0 -7
  234. package/dist/chunk-67PY5IX6.js +0 -34
  235. package/dist/chunk-67PY5IX6.js.map +0 -7
  236. package/dist/chunk-6DRDLOLP.js +0 -2613
  237. package/dist/chunk-6DRDLOLP.js.map +0 -7
  238. package/dist/chunk-7CQVZNQV.js +0 -1609
  239. package/dist/chunk-7CQVZNQV.js.map +0 -7
  240. package/dist/chunk-ABLVTESJ.js.map +0 -7
  241. package/dist/chunk-AIMIPK4B.js +0 -835
  242. package/dist/chunk-AIMIPK4B.js.map +0 -7
  243. package/dist/chunk-BHGTA6JQ.js.map +0 -7
  244. package/dist/chunk-CIG63V4E.js +0 -72
  245. package/dist/chunk-CIG63V4E.js.map +0 -7
  246. package/dist/chunk-E6YNABER.js.map +0 -7
  247. package/dist/chunk-EH34V7CY.js.map +0 -7
  248. package/dist/chunk-EZXMVTDU.js.map +0 -7
  249. package/dist/chunk-FH5CHM6L.js +0 -148
  250. package/dist/chunk-FH5CHM6L.js.map +0 -7
  251. package/dist/chunk-G6I7XROM.js.map +0 -7
  252. package/dist/chunk-HN4E4UUQ.js.map +0 -7
  253. package/dist/chunk-HSPVVDIW.js +0 -30198
  254. package/dist/chunk-HSPVVDIW.js.map +0 -7
  255. package/dist/chunk-IE2CG2TV.js.map +0 -7
  256. package/dist/chunk-K2MI4TPB.js.map +0 -7
  257. package/dist/chunk-MN77D2F7.js +0 -2931
  258. package/dist/chunk-MN77D2F7.js.map +0 -7
  259. package/dist/chunk-NQLEUHMS.js.map +0 -7
  260. package/dist/chunk-OIFQB3S4.js +0 -515
  261. package/dist/chunk-OIFQB3S4.js.map +0 -7
  262. package/dist/chunk-OWTG2W3A.js +0 -164
  263. package/dist/chunk-OWTG2W3A.js.map +0 -7
  264. package/dist/chunk-OZNRLY3E.js.map +0 -7
  265. package/dist/chunk-QYFKRZQC.js.map +0 -7
  266. package/dist/chunk-S6HRABTA.js.map +0 -7
  267. package/dist/chunk-SDGKPKDK.js.map +0 -7
  268. package/dist/chunk-SRZZFAS7.js.map +0 -7
  269. package/dist/chunk-UKHTVRJM.js +0 -47
  270. package/dist/chunk-UKHTVRJM.js.map +0 -7
  271. package/dist/chunk-UYXEDKOZ.js +0 -24
  272. package/dist/chunk-UYXEDKOZ.js.map +0 -7
  273. package/dist/chunk-VBXVYQYY.js +0 -145
  274. package/dist/chunk-VBXVYQYY.js.map +0 -7
  275. package/dist/chunk-WVHORZQ5.js +0 -17
  276. package/dist/chunk-WVHORZQ5.js.map +0 -7
  277. package/dist/chunk-WWUWDNWW.js +0 -49
  278. package/dist/chunk-WWUWDNWW.js.map +0 -7
  279. package/dist/chunk-Z33T5YN5.js +0 -654
  280. package/dist/chunk-Z33T5YN5.js.map +0 -7
  281. package/dist/chunk-ZQU3TXLC.js.map +0 -7
  282. package/dist/cli-SRV2INSL.js.map +0 -7
  283. package/dist/commands-TWH6PGVG.js +0 -46
  284. package/dist/context-JQIOOI4W.js +0 -30
  285. package/dist/costTracker-6SL26FDB.js +0 -19
  286. package/dist/kodeAgentSessionLoad-6N27AC5K.js +0 -18
  287. package/dist/kodeAgentSessionResume-HUSAEO24.js +0 -16
  288. package/dist/kodeAgentStreamJson-NXFN7TXH.js +0 -13
  289. package/dist/kodeAgentStreamJsonSession-GRWG3SPE.js.map +0 -7
  290. package/dist/kodeAgentStructuredStdio-HGWJT7CU.js +0 -10
  291. package/dist/llm-XVXWYOHK.js.map +0 -7
  292. package/dist/llmLazy-7TD5N7XP.js +0 -15
  293. package/dist/loader-AUXIJTY6.js +0 -28
  294. package/dist/mcp-BXJ3K7NZ.js +0 -49
  295. package/dist/mentionProcessor-YD7YXYGF.js.map +0 -7
  296. package/dist/model-KPYCXWBK.js +0 -30
  297. package/dist/pluginRuntime-FPTKK6NY.js.map +0 -7
  298. package/dist/pluginValidation-DSFXZ4GF.js +0 -17
  299. package/dist/prompts-LWLAJRS2.js +0 -48
  300. package/dist/query-HVPWL27C.js +0 -50
  301. package/dist/responsesStreaming-AW344PQO.js +0 -10
  302. package/dist/ripgrep-YOPCY2GO.js +0 -17
  303. package/dist/state-KNRWP3FO.js +0 -16
  304. package/dist/theme-7S2QN2FO.js +0 -14
  305. package/dist/toolPermissionSettings-GPOBH4IV.js +0 -18
  306. package/dist/tools-FZU2FZBD.js +0 -47
  307. package/dist/userInput-VHNBN2MW.js +0 -311
  308. package/dist/userInput-VHNBN2MW.js.map +0 -7
  309. package/dist/uuid-QN2CNKKN.js +0 -9
  310. /package/dist/{REPL-GIU4ZIXM.js.map → chunks/Doctor-M3J7GRTJ.js.map} +0 -0
  311. /package/dist/{autoUpdater-DNRMJWFQ.js.map → chunks/REPL-RQ6LO6S7.js.map} +0 -0
  312. /package/dist/{chunk-JC6NCUG5.js.map → chunks/ResumeConversation-6DMVBEGH.js.map} +0 -0
  313. /package/dist/{commands-TWH6PGVG.js.map → chunks/agentLoader-FCRG3TFJ.js.map} +0 -0
  314. /package/dist/{config-6ZMBCL23.js.map → chunks/autoUpdater-CNESBOKO.js.map} +0 -0
  315. /package/dist/{context-JQIOOI4W.js.map → chunks/chunk-4CRUCZR4.js.map} +0 -0
  316. /package/dist/{costTracker-6SL26FDB.js.map → chunks/chunk-54KOYG5C.js.map} +0 -0
  317. /package/dist/{customCommands-DNEJS3ZU.js.map → chunks/chunk-GCQCAXJZ.js.map} +0 -0
  318. /package/dist/{env-OFAXZ3XG.js.map → chunks/chunk-LB6TCPDI.js.map} +0 -0
  319. /package/dist/{kodeAgentSessionId-X6XWQW7B.js.map → chunks/client-SILZNM5N.js.map} +0 -0
  320. /package/dist/{kodeAgentSessionLoad-6N27AC5K.js.map → chunks/config-25HRTPSP.js.map} +0 -0
  321. /package/dist/{kodeAgentSessionResume-HUSAEO24.js.map → chunks/cost-tracker-Z2UZT2J5.js.map} +0 -0
  322. /package/dist/{kodeAgentStreamJson-NXFN7TXH.js.map → chunks/customCommands-TYMYZRG5.js.map} +0 -0
  323. /package/dist/{kodeAgentStructuredStdio-HGWJT7CU.js.map → chunks/engine-MRVF6FK6.js.map} +0 -0
  324. /package/dist/{kodeHooks-TDMXFWSO.js.map → chunks/env-TJ5NOBEB.js.map} +0 -0
  325. /package/dist/{llmLazy-7TD5N7XP.js.map → chunks/kodeAgentSessionId-VTNISJ2L.js.map} +0 -0
  326. /package/dist/{loader-AUXIJTY6.js.map → chunks/kodeAgentSessionLoad-YB2RKBGJ.js.map} +0 -0
  327. /package/dist/{mcp-BXJ3K7NZ.js.map → chunks/kodeAgentSessionResume-DZSIVKVA.js.map} +0 -0
  328. /package/dist/{messages-OFUJSPRV.js.map → chunks/kodeAgentStreamJson-X5PLS2S6.js.map} +0 -0
  329. /package/dist/{model-KPYCXWBK.js.map → chunks/kodeHooks-RVKYRJHG.js.map} +0 -0
  330. /package/dist/{openai-5G5D5Q4B.js.map → chunks/llmLazy-ZUSSE3ZA.js.map} +0 -0
  331. /package/dist/{outputStyles-HLDXFQK3.js.map → chunks/messages-EEWWLPHN.js.map} +0 -0
  332. /package/dist/{pluginValidation-DSFXZ4GF.js.map → chunks/model-5TIEKQPD.js.map} +0 -0
  333. /package/dist/{prompts-LWLAJRS2.js.map → chunks/openai-XXK3YZG4.js.map} +0 -0
  334. /package/dist/{query-HVPWL27C.js.map → chunks/outputStyles-FAJTXN2A.js.map} +0 -0
  335. /package/dist/{responsesStreaming-AW344PQO.js.map → chunks/permissions-HO7INPWM.js.map} +0 -0
  336. /package/dist/{ripgrep-YOPCY2GO.js.map → chunks/pluginValidation-DAM7WRTC.js.map} +0 -0
  337. /package/dist/{skillMarketplace-PSNKDINM.js.map → chunks/registry-XYJXMOA5.js.map} +0 -0
  338. /package/dist/{state-KNRWP3FO.js.map → chunks/responsesStreaming-JNGE2P3D.js.map} +0 -0
  339. /package/dist/{theme-7S2QN2FO.js.map → chunks/server-REXXF5IK.js.map} +0 -0
  340. /package/dist/{toolPermissionContext-65L65VEZ.js.map → chunks/skillMarketplace-N4HVHNST.js.map} +0 -0
  341. /package/dist/{toolPermissionSettings-GPOBH4IV.js.map → chunks/src-OROQIWP3.js.map} +0 -0
  342. /package/dist/{tools-FZU2FZBD.js.map → chunks/theme-YBJUIMWK.js.map} +0 -0
  343. /package/dist/{uuid-QN2CNKKN.js.map → chunks/toolPermissionContext-MOCTRR7N.js.map} +0 -0
@@ -0,0 +1,1409 @@
1
+ // packages/runtime/src/shell/BunShell.ts
2
+ import { existsSync as existsSync5 } from "fs";
3
+ import { isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
4
+
5
+ // packages/runtime/src/shell/state.ts
6
+ function createInitialState(cwd) {
7
+ return {
8
+ cwd,
9
+ isAlive: true,
10
+ currentProcess: null,
11
+ abortController: null,
12
+ backgroundProcesses: /* @__PURE__ */ new Map()
13
+ };
14
+ }
15
+
16
+ // packages/runtime/src/shell/exec.ts
17
+ import { spawn } from "node:child_process";
18
+
19
+ // packages/runtime/src/shell/sandboxCommand.ts
20
+ import { existsSync as existsSync2, mkdirSync } from "fs";
21
+ import which from "which";
22
+
23
+ // packages/runtime/src/shell/linuxSandbox.ts
24
+ import { existsSync, realpathSync, statSync } from "fs";
25
+ import { homedir } from "os";
26
+ import { dirname, isAbsolute, resolve } from "path";
27
+ function hasGlobPattern(value) {
28
+ return value.includes("*") || value.includes("?") || value.includes("[") || value.includes("]");
29
+ }
30
+ function normalizeLinuxSandboxPath(input, options) {
31
+ const cwd = options?.cwd ?? process.cwd();
32
+ const homeDir = options?.homeDir ?? homedir();
33
+ let resolved = input;
34
+ if (input === "~") resolved = homeDir;
35
+ else if (input.startsWith("~/")) resolved = homeDir + input.slice(1);
36
+ else if (input.startsWith("./") || input.startsWith("../"))
37
+ resolved = resolve(cwd, input);
38
+ else if (!isAbsolute(input)) resolved = resolve(cwd, input);
39
+ if (hasGlobPattern(resolved)) {
40
+ const prefix = resolved.split(/[*?[\]]/)[0];
41
+ if (prefix && prefix !== "/") {
42
+ const dir = prefix.endsWith("/") ? prefix.slice(0, -1) : dirname(prefix);
43
+ try {
44
+ const real = realpathSync(dir);
45
+ const suffix = resolved.slice(dir.length);
46
+ return real + suffix;
47
+ } catch {
48
+ }
49
+ }
50
+ return resolved;
51
+ }
52
+ try {
53
+ resolved = realpathSync(resolved);
54
+ } catch {
55
+ }
56
+ return resolved;
57
+ }
58
+ function buildLinuxBwrapFilesystemArgs(options) {
59
+ const cwd = options.cwd ?? process.cwd();
60
+ const homeDir = options.homeDir ?? homedir();
61
+ const args = [];
62
+ const writeConfig = options.writeConfig;
63
+ if (writeConfig) {
64
+ args.push("--ro-bind", "/", "/");
65
+ const allowedRoots = [];
66
+ if (existsSync("/tmp/kode")) {
67
+ args.push("--bind", "/tmp/kode", "/tmp/kode");
68
+ allowedRoots.push("/tmp/kode");
69
+ }
70
+ for (const raw of writeConfig.allowOnly ?? []) {
71
+ const resolved = normalizeLinuxSandboxPath(raw, { cwd, homeDir });
72
+ if (resolved.startsWith("/dev/")) continue;
73
+ if (!existsSync(resolved)) continue;
74
+ args.push("--bind", resolved, resolved);
75
+ allowedRoots.push(resolved);
76
+ }
77
+ const denyWithinAllow = [
78
+ ...writeConfig.denyWithinAllow ?? [],
79
+ ...options.extraDenyWithinAllow ?? []
80
+ ];
81
+ for (const raw of denyWithinAllow) {
82
+ const resolved = normalizeLinuxSandboxPath(raw, { cwd, homeDir });
83
+ if (resolved.startsWith("/dev/")) continue;
84
+ if (!existsSync(resolved)) continue;
85
+ const withinAllowed = allowedRoots.some(
86
+ (root) => resolved === root || resolved.startsWith(root + "/")
87
+ );
88
+ if (!withinAllowed) continue;
89
+ args.push("--ro-bind", resolved, resolved);
90
+ }
91
+ } else {
92
+ args.push("--bind", "/", "/");
93
+ }
94
+ const denyRead = [...options.readConfig?.denyOnly ?? []];
95
+ if (existsSync("/etc/ssh/ssh_config.d"))
96
+ denyRead.push("/etc/ssh/ssh_config.d");
97
+ for (const raw of denyRead) {
98
+ const resolved = normalizeLinuxSandboxPath(raw, { cwd, homeDir });
99
+ if (resolved.startsWith("/dev/")) continue;
100
+ if (!existsSync(resolved)) continue;
101
+ if (statSync(resolved).isDirectory()) args.push("--tmpfs", resolved);
102
+ else args.push("--ro-bind", "/dev/null", resolved);
103
+ }
104
+ return args;
105
+ }
106
+ function buildLinuxBwrapCommand(options) {
107
+ const args = [];
108
+ args.push(
109
+ "--die-with-parent",
110
+ "--new-session",
111
+ "--unshare-pid",
112
+ "--unshare-uts",
113
+ "--unshare-ipc"
114
+ );
115
+ if (options.needsNetworkRestriction) args.push("--unshare-net");
116
+ args.push(
117
+ ...buildLinuxBwrapFilesystemArgs({
118
+ cwd: options.cwd,
119
+ homeDir: options.homeDir,
120
+ readConfig: options.readConfig,
121
+ writeConfig: options.writeConfig
122
+ })
123
+ );
124
+ args.push(
125
+ "--dev",
126
+ "/dev",
127
+ "--setenv",
128
+ "SANDBOX_RUNTIME",
129
+ "1",
130
+ "--setenv",
131
+ "TMPDIR",
132
+ "/tmp/kode"
133
+ );
134
+ if (!options.enableWeakerNestedSandbox) args.push("--proc", "/proc");
135
+ args.push("--", options.binShellPath, "-c", options.command);
136
+ return [options.bwrapPath, ...args];
137
+ }
138
+
139
+ // packages/runtime/src/shell/macosSandbox.ts
140
+ import { dirname as dirname2 } from "path";
141
+ function buildSandboxEnvAssignments(options) {
142
+ const httpProxyPort = options?.httpProxyPort;
143
+ const socksProxyPort = options?.socksProxyPort;
144
+ const platform = options?.platform ?? process.platform;
145
+ const env = ["SANDBOX_RUNTIME=1", "TMPDIR=/tmp/kode"];
146
+ if (!httpProxyPort && !socksProxyPort) return env;
147
+ const noProxy = [
148
+ "localhost",
149
+ "127.0.0.1",
150
+ "::1",
151
+ "*.local",
152
+ ".local",
153
+ "169.254.0.0/16",
154
+ "10.0.0.0/8",
155
+ "172.16.0.0/12",
156
+ "192.168.0.0/16"
157
+ ].join(",");
158
+ env.push(`NO_PROXY=${noProxy}`);
159
+ env.push(`no_proxy=${noProxy}`);
160
+ if (httpProxyPort) {
161
+ env.push(`HTTP_PROXY=http://localhost:${httpProxyPort}`);
162
+ env.push(`HTTPS_PROXY=http://localhost:${httpProxyPort}`);
163
+ env.push(`http_proxy=http://localhost:${httpProxyPort}`);
164
+ env.push(`https_proxy=http://localhost:${httpProxyPort}`);
165
+ }
166
+ if (socksProxyPort) {
167
+ env.push(`ALL_PROXY=socks5h://localhost:${socksProxyPort}`);
168
+ env.push(`all_proxy=socks5h://localhost:${socksProxyPort}`);
169
+ if (platform === "darwin") {
170
+ env.push(
171
+ `GIT_SSH_COMMAND="ssh -o ProxyCommand='nc -X 5 -x localhost:${socksProxyPort} %h %p'"`
172
+ );
173
+ }
174
+ env.push(`FTP_PROXY=socks5h://localhost:${socksProxyPort}`);
175
+ env.push(`ftp_proxy=socks5h://localhost:${socksProxyPort}`);
176
+ env.push(`RSYNC_PROXY=localhost:${socksProxyPort}`);
177
+ env.push(
178
+ `DOCKER_HTTP_PROXY=http://localhost:${httpProxyPort || socksProxyPort}`
179
+ );
180
+ env.push(
181
+ `DOCKER_HTTPS_PROXY=http://localhost:${httpProxyPort || socksProxyPort}`
182
+ );
183
+ if (httpProxyPort) {
184
+ env.push("CLOUDSDK_PROXY_TYPE=https");
185
+ env.push("CLOUDSDK_PROXY_ADDRESS=localhost");
186
+ env.push(`CLOUDSDK_PROXY_PORT=${httpProxyPort}`);
187
+ }
188
+ env.push(`GRPC_PROXY=socks5h://localhost:${socksProxyPort}`);
189
+ env.push(`grpc_proxy=socks5h://localhost:${socksProxyPort}`);
190
+ }
191
+ return env;
192
+ }
193
+ function escapeRegexForSandboxGlobPattern(pattern) {
194
+ return "^" + pattern.replace(/[.^$+{}()|\\]/g, "\\$&").replace(/\[([^\]]*?)$/g, "\\[$1").replace(/\*\*\//g, "__GLOBSTAR_SLASH__").replace(/\*\*/g, "__GLOBSTAR__").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/__GLOBSTAR_SLASH__/g, "(.*/)?").replace(/__GLOBSTAR__/g, ".*") + "$";
195
+ }
196
+ function getMacosTmpDirWriteAllowPaths() {
197
+ const tmpdirValue = process.env.TMPDIR;
198
+ if (!tmpdirValue) return [];
199
+ if (!tmpdirValue.match(/^\/(private\/)?var\/folders\/[^/]{2}\/[^/]+\/T\/?$/))
200
+ return [];
201
+ const base = tmpdirValue.replace(/\/T\/?$/, "");
202
+ if (base.startsWith("/private/var/"))
203
+ return [base, base.replace("/private", "")];
204
+ if (base.startsWith("/var/")) return [base, "/private" + base];
205
+ return [base];
206
+ }
207
+ function buildMacosSandboxDenyUnlinkRules(paths, logTag) {
208
+ const lines = [];
209
+ for (const raw of paths) {
210
+ const normalized = normalizeLinuxSandboxPath(raw);
211
+ if (hasGlobPattern(normalized)) {
212
+ const regex = escapeRegexForSandboxGlobPattern(normalized);
213
+ lines.push(
214
+ "(deny file-write-unlink",
215
+ ` (regex ${JSON.stringify(regex)})`,
216
+ ` (with message "${logTag}"))`
217
+ );
218
+ const prefix = normalized.split(/[*?[\]]/)[0];
219
+ if (prefix && prefix !== "/") {
220
+ const literal = prefix.endsWith("/") ? prefix.slice(0, -1) : dirname2(prefix);
221
+ lines.push(
222
+ "(deny file-write-unlink",
223
+ ` (literal ${JSON.stringify(literal)})`,
224
+ ` (with message "${logTag}"))`
225
+ );
226
+ }
227
+ continue;
228
+ }
229
+ lines.push(
230
+ "(deny file-write-unlink",
231
+ ` (subpath ${JSON.stringify(normalized)})`,
232
+ ` (with message "${logTag}"))`
233
+ );
234
+ }
235
+ return lines;
236
+ }
237
+ function buildMacosSandboxFileReadRules(readConfig, logTag) {
238
+ if (!readConfig) return ["(allow file-read*)"];
239
+ const lines = ["(allow file-read*)"];
240
+ for (const raw of readConfig.denyOnly ?? []) {
241
+ const normalized = normalizeLinuxSandboxPath(raw);
242
+ if (hasGlobPattern(normalized)) {
243
+ const regex = escapeRegexForSandboxGlobPattern(normalized);
244
+ lines.push(
245
+ "(deny file-read*",
246
+ ` (regex ${JSON.stringify(regex)})`,
247
+ ` (with message "${logTag}"))`
248
+ );
249
+ } else {
250
+ lines.push(
251
+ "(deny file-read*",
252
+ ` (subpath ${JSON.stringify(normalized)})`,
253
+ ` (with message "${logTag}"))`
254
+ );
255
+ }
256
+ }
257
+ lines.push(
258
+ ...buildMacosSandboxDenyUnlinkRules(readConfig.denyOnly ?? [], logTag)
259
+ );
260
+ return lines;
261
+ }
262
+ function buildMacosSandboxFileWriteRules(writeConfig, logTag) {
263
+ if (!writeConfig) return ["(allow file-write*)"];
264
+ const lines = [];
265
+ lines.push(
266
+ "(allow file-write*",
267
+ ` (literal "/dev/null")`,
268
+ ` (with message "${logTag}"))`
269
+ );
270
+ for (const raw of getMacosTmpDirWriteAllowPaths()) {
271
+ const normalized = normalizeLinuxSandboxPath(raw);
272
+ lines.push(
273
+ "(allow file-write*",
274
+ ` (subpath ${JSON.stringify(normalized)})`,
275
+ ` (with message "${logTag}"))`
276
+ );
277
+ }
278
+ for (const raw of writeConfig.allowOnly ?? []) {
279
+ const normalized = normalizeLinuxSandboxPath(raw);
280
+ if (hasGlobPattern(normalized)) {
281
+ const regex = escapeRegexForSandboxGlobPattern(normalized);
282
+ lines.push(
283
+ "(allow file-write*",
284
+ ` (regex ${JSON.stringify(regex)})`,
285
+ ` (with message "${logTag}"))`
286
+ );
287
+ } else {
288
+ lines.push(
289
+ "(allow file-write*",
290
+ ` (subpath ${JSON.stringify(normalized)})`,
291
+ ` (with message "${logTag}"))`
292
+ );
293
+ }
294
+ }
295
+ for (const raw of writeConfig.denyWithinAllow ?? []) {
296
+ const normalized = normalizeLinuxSandboxPath(raw);
297
+ if (hasGlobPattern(normalized)) {
298
+ const regex = escapeRegexForSandboxGlobPattern(normalized);
299
+ lines.push(
300
+ "(deny file-write*",
301
+ ` (regex ${JSON.stringify(regex)})`,
302
+ ` (with message "${logTag}"))`
303
+ );
304
+ } else {
305
+ lines.push(
306
+ "(deny file-write*",
307
+ ` (subpath ${JSON.stringify(normalized)})`,
308
+ ` (with message "${logTag}"))`
309
+ );
310
+ }
311
+ }
312
+ lines.push(
313
+ ...buildMacosSandboxDenyUnlinkRules(
314
+ writeConfig.denyWithinAllow ?? [],
315
+ logTag
316
+ )
317
+ );
318
+ return lines;
319
+ }
320
+ function buildMacosSandboxExecCommand(options) {
321
+ const logTag = "KODE_SANDBOX";
322
+ const profileLines = [
323
+ "(version 1)",
324
+ `(deny default (with message "${logTag}"))`,
325
+ "",
326
+ "; Kode sandbox-exec profile (reference CLI compatible)",
327
+ "",
328
+ // Keep this permissive enough for typical CLI tools (git, node, etc).
329
+ "(allow process*)",
330
+ "(allow sysctl-read)",
331
+ "(allow mach-lookup)",
332
+ "",
333
+ "; Network"
334
+ ];
335
+ const allowUnixSockets = options.allowUnixSockets ?? [];
336
+ if (!options.needsNetworkRestriction) {
337
+ profileLines.push("(allow network*)");
338
+ } else {
339
+ if (options.allowLocalBinding) {
340
+ profileLines.push('(allow network-bind (local ip "localhost:*"))');
341
+ profileLines.push('(allow network-inbound (local ip "localhost:*"))');
342
+ profileLines.push('(allow network-outbound (local ip "localhost:*"))');
343
+ }
344
+ if (options.allowAllUnixSockets) {
345
+ profileLines.push('(allow network* (subpath "/"))');
346
+ } else if (allowUnixSockets.length > 0) {
347
+ for (const socketPath of allowUnixSockets) {
348
+ const normalized = normalizeLinuxSandboxPath(socketPath);
349
+ profileLines.push(
350
+ `(allow network* (subpath ${JSON.stringify(normalized)}))`
351
+ );
352
+ }
353
+ }
354
+ if (options.httpProxyPort !== void 0) {
355
+ profileLines.push(
356
+ `(allow network-bind (local ip "localhost:${options.httpProxyPort}"))`
357
+ );
358
+ profileLines.push(
359
+ `(allow network-inbound (local ip "localhost:${options.httpProxyPort}"))`
360
+ );
361
+ profileLines.push(
362
+ `(allow network-outbound (remote ip "localhost:${options.httpProxyPort}"))`
363
+ );
364
+ }
365
+ if (options.socksProxyPort !== void 0) {
366
+ profileLines.push(
367
+ `(allow network-bind (local ip "localhost:${options.socksProxyPort}"))`
368
+ );
369
+ profileLines.push(
370
+ `(allow network-inbound (local ip "localhost:${options.socksProxyPort}"))`
371
+ );
372
+ profileLines.push(
373
+ `(allow network-outbound (remote ip "localhost:${options.socksProxyPort}"))`
374
+ );
375
+ }
376
+ }
377
+ profileLines.push("");
378
+ profileLines.push("; File read");
379
+ profileLines.push(
380
+ ...buildMacosSandboxFileReadRules(options.readConfig, logTag)
381
+ );
382
+ profileLines.push("");
383
+ profileLines.push("; File write");
384
+ profileLines.push(
385
+ ...buildMacosSandboxFileWriteRules(options.writeConfig, logTag)
386
+ );
387
+ const profile = profileLines.join("\n");
388
+ const envAssignments = buildSandboxEnvAssignments({
389
+ httpProxyPort: options.httpProxyPort,
390
+ socksProxyPort: options.socksProxyPort,
391
+ platform: "darwin"
392
+ });
393
+ const envPrefix = envAssignments.length ? `export ${envAssignments.join(" ")} && ` : "";
394
+ return [
395
+ options.sandboxExecPath,
396
+ "-p",
397
+ profile,
398
+ options.binShellPath,
399
+ "-c",
400
+ `${envPrefix}${options.command}`
401
+ ];
402
+ }
403
+
404
+ // packages/runtime/src/shell/sandboxCommand.ts
405
+ function maybeAnnotateMacosSandboxStderr(stderr, sandbox) {
406
+ if (!stderr) return stderr;
407
+ if (!sandbox || sandbox.enabled !== true) return stderr;
408
+ const platform = sandbox.__platformOverride ?? process.platform;
409
+ if (platform !== "darwin") return stderr;
410
+ if (stderr.includes("[sandbox]")) return stderr;
411
+ const lower = stderr.toLowerCase();
412
+ const looksLikeSandboxViolation = stderr.includes("KODE_SANDBOX") || lower.includes("sandbox-exec") && (lower.includes("deny") || lower.includes("operation not permitted")) || lower.includes("operation not permitted") && lower.includes("sandbox");
413
+ if (!looksLikeSandboxViolation) return stderr;
414
+ return [
415
+ stderr.trimEnd(),
416
+ "",
417
+ "[sandbox] This failure looks like a macOS sandbox denial. Adjust sandbox settings (e.g. /sandbox or .kode/settings.json) to grant the minimal required access."
418
+ ].join("\n");
419
+ }
420
+ function isSandboxInitFailure(stderr) {
421
+ const s = stderr.toLowerCase();
422
+ return s.includes("bwrap:") || s.includes("bubblewrap") || s.includes("namespace") && s.includes("failed");
423
+ }
424
+ function buildSandboxCommand(options) {
425
+ const sandbox = options.sandbox;
426
+ if (!sandbox.enabled) return null;
427
+ const platform = sandbox.__platformOverride ?? process.platform;
428
+ const needsNetworkRestriction = sandbox.needsNetworkRestriction !== void 0 ? sandbox.needsNetworkRestriction : sandbox.allowNetwork === true ? false : true;
429
+ const writeConfig = sandbox.writeConfig ?? (sandbox.writableRoots && sandbox.writableRoots.length > 0 ? { allowOnly: sandbox.writableRoots.filter(Boolean) } : void 0);
430
+ const readConfig = sandbox.readConfig;
431
+ const hasReadRestrictions = (readConfig?.denyOnly?.length ?? 0) > 0;
432
+ const hasWriteRestrictions = writeConfig !== void 0;
433
+ const hasNetworkRestrictions = needsNetworkRestriction === true;
434
+ if (!hasReadRestrictions && !hasWriteRestrictions && !hasNetworkRestrictions) {
435
+ return null;
436
+ }
437
+ const binShell = sandbox.binShell ?? (which.sync("bash", { nothrow: true }) ? "bash" : "sh");
438
+ const binShellPath = which.sync(binShell, { nothrow: true }) ?? binShell;
439
+ const cwd = sandbox.chdir || options.cwd;
440
+ if (platform === "linux") {
441
+ const bwrapPath = sandbox.__bwrapPathOverride !== void 0 ? sandbox.__bwrapPathOverride : which.sync("bwrap", { nothrow: true }) ?? which.sync("bubblewrap", { nothrow: true });
442
+ if (!bwrapPath) return null;
443
+ try {
444
+ mkdirSync("/tmp/kode", { recursive: true });
445
+ } catch {
446
+ }
447
+ const cmd = buildLinuxBwrapCommand({
448
+ bwrapPath,
449
+ command: options.command,
450
+ needsNetworkRestriction,
451
+ readConfig,
452
+ writeConfig,
453
+ enableWeakerNestedSandbox: sandbox.enableWeakerNestedSandbox,
454
+ binShellPath,
455
+ cwd
456
+ });
457
+ return { cmd };
458
+ }
459
+ if (platform === "darwin") {
460
+ const sandboxExecPath = sandbox.__sandboxExecPathOverride !== void 0 ? sandbox.__sandboxExecPathOverride : existsSync2("/usr/bin/sandbox-exec") ? "/usr/bin/sandbox-exec" : which.sync("sandbox-exec", { nothrow: true });
461
+ if (!sandboxExecPath) return null;
462
+ try {
463
+ mkdirSync("/tmp/kode", { recursive: true });
464
+ } catch {
465
+ }
466
+ try {
467
+ mkdirSync("/private/tmp/kode", { recursive: true });
468
+ } catch {
469
+ }
470
+ return {
471
+ cmd: buildMacosSandboxExecCommand({
472
+ sandboxExecPath,
473
+ binShellPath,
474
+ command: options.command,
475
+ needsNetworkRestriction,
476
+ httpProxyPort: sandbox.httpProxyPort,
477
+ socksProxyPort: sandbox.socksProxyPort,
478
+ allowUnixSockets: sandbox.allowUnixSockets,
479
+ allowAllUnixSockets: sandbox.allowAllUnixSockets,
480
+ allowLocalBinding: sandbox.allowLocalBinding,
481
+ readConfig,
482
+ writeConfig
483
+ })
484
+ };
485
+ }
486
+ return null;
487
+ }
488
+
489
+ // packages/runtime/src/shell/streamReaders.ts
490
+ function logError(error) {
491
+ if (process.env.NODE_ENV === "test") {
492
+ console.error(error);
493
+ }
494
+ }
495
+ function startStreamReader(stream, append) {
496
+ if (!stream) return;
497
+ try {
498
+ stream.setEncoding("utf8");
499
+ } catch {
500
+ }
501
+ stream.on("data", (chunk) => {
502
+ const text = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
503
+ if (text) append(text);
504
+ });
505
+ stream.on("error", (err) => {
506
+ logError(
507
+ `Stream read error: ${err instanceof Error ? err.message : String(err)}`
508
+ );
509
+ });
510
+ }
511
+ function createCancellableTextCollector(stream, options) {
512
+ let text = "";
513
+ const collectText = options?.collectText !== false;
514
+ if (!stream) {
515
+ return {
516
+ getText: () => text,
517
+ done: Promise.resolve(),
518
+ cancel: async () => {
519
+ }
520
+ };
521
+ }
522
+ let doneResolve = null;
523
+ const done = new Promise((resolve3) => {
524
+ doneResolve = resolve3;
525
+ });
526
+ let finished = false;
527
+ let cancelled = false;
528
+ const finish = () => {
529
+ if (finished) return;
530
+ finished = true;
531
+ cleanup();
532
+ doneResolve?.();
533
+ doneResolve = null;
534
+ };
535
+ const onData = (chunk) => {
536
+ const value = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
537
+ if (!value) return;
538
+ if (collectText) text += value;
539
+ options?.onChunk?.(value);
540
+ };
541
+ const onError = (err) => {
542
+ if (!cancelled) {
543
+ logError(
544
+ `Stream read error: ${err instanceof Error ? err.message : String(err)}`
545
+ );
546
+ }
547
+ finish();
548
+ };
549
+ const onEnd = () => finish();
550
+ const onClose = () => finish();
551
+ const hasDestroy = (value) => {
552
+ return typeof value.destroy === "function";
553
+ };
554
+ const cleanup = () => {
555
+ stream.removeListener("data", onData);
556
+ stream.removeListener("error", onError);
557
+ stream.removeListener("end", onEnd);
558
+ stream.removeListener("close", onClose);
559
+ };
560
+ try {
561
+ stream.setEncoding("utf8");
562
+ } catch {
563
+ }
564
+ stream.on("data", onData);
565
+ stream.on("error", onError);
566
+ stream.on("end", onEnd);
567
+ stream.on("close", onClose);
568
+ return {
569
+ getText: () => text,
570
+ done,
571
+ cancel: async () => {
572
+ cancelled = true;
573
+ try {
574
+ if (hasDestroy(stream)) {
575
+ stream.destroy();
576
+ }
577
+ } catch {
578
+ }
579
+ finish();
580
+ }
581
+ };
582
+ }
583
+
584
+ // packages/runtime/src/shell/shellCmd.ts
585
+ import { existsSync as existsSync3 } from "fs";
586
+ function getShellCmdForPlatform(platform, command, env = process.env) {
587
+ if (platform === "win32") {
588
+ const comspec = typeof env.ComSpec === "string" && env.ComSpec.length > 0 ? env.ComSpec : "cmd";
589
+ return [comspec, "/c", command];
590
+ }
591
+ const sh = existsSync3("/bin/sh") ? "/bin/sh" : "sh";
592
+ return [sh, "-c", command];
593
+ }
594
+
595
+ // packages/runtime/src/shell/exec.ts
596
+ function logError2(error) {
597
+ if (process.env.NODE_ENV === "test") {
598
+ console.error(error);
599
+ }
600
+ }
601
+ function normalizeExitCode(exitCode, interrupted) {
602
+ if (typeof exitCode === "number" && Number.isFinite(exitCode)) return exitCode;
603
+ return interrupted ? 143 : 0;
604
+ }
605
+ async function exec(state, command, abortSignal, timeout, options) {
606
+ const DEFAULT_TIMEOUT = 12e4;
607
+ const commandTimeout = timeout ?? DEFAULT_TIMEOUT;
608
+ state.abortController = new AbortController();
609
+ let wasAborted = false;
610
+ const onAbort = () => {
611
+ wasAborted = true;
612
+ try {
613
+ state.abortController?.abort();
614
+ } catch {
615
+ }
616
+ try {
617
+ state.currentProcess?.kill();
618
+ } catch {
619
+ }
620
+ };
621
+ if (abortSignal) {
622
+ abortSignal.addEventListener("abort", onAbort, { once: true });
623
+ }
624
+ const sandbox = options?.sandbox;
625
+ const shouldAttemptSandbox = sandbox?.enabled === true;
626
+ const executionCwd = shouldAttemptSandbox && sandbox?.chdir ? sandbox.chdir : state.cwd;
627
+ const runOnce = async (cmd, cwdOverride) => {
628
+ state.currentProcess = spawn(cmd[0], cmd.slice(1), {
629
+ cwd: cwdOverride ?? executionCwd,
630
+ stdio: ["ignore", "pipe", "pipe"]
631
+ });
632
+ const processRef = state.currentProcess;
633
+ const exitPromise = new Promise((resolve3) => {
634
+ processRef.once("exit", (code) => resolve3({ kind: "exit", code }));
635
+ processRef.once("error", (error) => resolve3({ kind: "error", error }));
636
+ });
637
+ const stdoutCollector = createCancellableTextCollector(processRef.stdout, {
638
+ onChunk: options?.onStdoutChunk
639
+ });
640
+ const stderrCollector = createCancellableTextCollector(processRef.stderr, {
641
+ onChunk: options?.onStderrChunk
642
+ });
643
+ let timeoutHandle = null;
644
+ const timeoutPromise = new Promise((resolve3) => {
645
+ timeoutHandle = setTimeout(() => resolve3("timeout"), commandTimeout);
646
+ });
647
+ const result = await Promise.race([
648
+ exitPromise.then(() => "completed"),
649
+ timeoutPromise
650
+ ]);
651
+ if (timeoutHandle) clearTimeout(timeoutHandle);
652
+ if (result === "timeout") {
653
+ try {
654
+ processRef.kill();
655
+ } catch {
656
+ }
657
+ try {
658
+ state.abortController?.abort();
659
+ } catch {
660
+ }
661
+ try {
662
+ await exitPromise;
663
+ } catch {
664
+ }
665
+ await Promise.race([
666
+ Promise.allSettled([stdoutCollector.done, stderrCollector.done]),
667
+ new Promise((resolve3) => setTimeout(resolve3, 250))
668
+ ]);
669
+ await Promise.allSettled([
670
+ stdoutCollector.cancel(),
671
+ stderrCollector.cancel()
672
+ ]);
673
+ return {
674
+ stdout: "",
675
+ stderr: "Command timed out",
676
+ code: 143,
677
+ interrupted: true
678
+ };
679
+ }
680
+ await Promise.race([
681
+ Promise.allSettled([stdoutCollector.done, stderrCollector.done]),
682
+ new Promise((resolve3) => setTimeout(resolve3, 250))
683
+ ]);
684
+ await Promise.allSettled([
685
+ stdoutCollector.cancel(),
686
+ stderrCollector.cancel()
687
+ ]);
688
+ const stdout = stdoutCollector.getText();
689
+ let stderr = stderrCollector.getText();
690
+ const interrupted = wasAborted || abortSignal?.aborted === true || state.abortController?.signal.aborted === true;
691
+ const exitOutcome = await exitPromise;
692
+ if (exitOutcome.kind === "error") {
693
+ stderr = [stderr, exitOutcome.error.message].filter(Boolean).join("\n");
694
+ }
695
+ let exitCode = exitOutcome.kind === "exit" ? exitOutcome.code : null;
696
+ if (exitOutcome.kind === "error") exitCode = 2;
697
+ return {
698
+ stdout,
699
+ stderr,
700
+ code: normalizeExitCode(exitCode, interrupted),
701
+ interrupted
702
+ };
703
+ };
704
+ try {
705
+ if (shouldAttemptSandbox) {
706
+ const sandboxCmd = buildSandboxCommand({
707
+ command,
708
+ sandbox,
709
+ cwd: state.cwd
710
+ });
711
+ if (!sandboxCmd) {
712
+ if (sandbox?.require) {
713
+ return {
714
+ stdout: "",
715
+ stderr: "System sandbox is required but unavailable (missing bubblewrap or unsupported platform).",
716
+ code: 2,
717
+ interrupted: false
718
+ };
719
+ }
720
+ const fallback = await runOnce(
721
+ getShellCmdForPlatform(process.platform, command, process.env)
722
+ );
723
+ return {
724
+ ...fallback,
725
+ stderr: `[sandbox] unavailable, ran without isolation.
726
+ ${fallback.stderr}`.trim()
727
+ };
728
+ }
729
+ const sandboxed = await runOnce(sandboxCmd.cmd);
730
+ sandboxed.stderr = maybeAnnotateMacosSandboxStderr(
731
+ sandboxed.stderr,
732
+ sandbox
733
+ );
734
+ if (!sandboxed.interrupted && sandboxed.code !== 0 && isSandboxInitFailure(sandboxed.stderr) && !sandbox?.require) {
735
+ const fallback = await runOnce(
736
+ getShellCmdForPlatform(process.platform, command, process.env)
737
+ );
738
+ return {
739
+ ...fallback,
740
+ stderr: `[sandbox] failed to start, ran without isolation.
741
+ ${fallback.stderr}`.trim()
742
+ };
743
+ }
744
+ return sandboxed;
745
+ }
746
+ return await runOnce(
747
+ getShellCmdForPlatform(process.platform, command, process.env)
748
+ );
749
+ } catch (error) {
750
+ if (state.abortController?.signal.aborted) {
751
+ state.currentProcess?.kill();
752
+ return {
753
+ stdout: "",
754
+ stderr: "Command was interrupted",
755
+ code: 143,
756
+ interrupted: true
757
+ };
758
+ }
759
+ const errorStr = error instanceof Error ? error.message : String(error);
760
+ logError2(`Shell execution error: ${errorStr}`);
761
+ return {
762
+ stdout: "",
763
+ stderr: errorStr,
764
+ code: 2,
765
+ interrupted: false
766
+ };
767
+ } finally {
768
+ if (abortSignal) {
769
+ abortSignal.removeEventListener("abort", onAbort);
770
+ }
771
+ state.currentProcess = null;
772
+ state.abortController = null;
773
+ }
774
+ }
775
+
776
+ // packages/runtime/src/shell/execPromotable.ts
777
+ import { spawn as spawn2 } from "node:child_process";
778
+
779
+ // packages/runtime/src/taskOutputStore.ts
780
+ import {
781
+ appendFileSync,
782
+ existsSync as existsSync4,
783
+ mkdirSync as mkdirSync2,
784
+ readFileSync,
785
+ statSync as statSync2,
786
+ writeFileSync
787
+ } from "fs";
788
+ import { dirname as dirname3, join } from "path";
789
+ import { homedir as homedir2 } from "os";
790
+ function getKodeBaseDir() {
791
+ return process.env.KODE_CONFIG_DIR ?? process.env.CLAUDE_CONFIG_DIR ?? join(homedir2(), ".kode");
792
+ }
793
+ function getProjectDir(cwd) {
794
+ return cwd.replace(/[^a-zA-Z0-9]/g, "-");
795
+ }
796
+ var PROJECT_ROOT = process.cwd();
797
+ function getTaskOutputsDir() {
798
+ return join(getKodeBaseDir(), getProjectDir(PROJECT_ROOT), "tasks");
799
+ }
800
+ function getTaskOutputFilePath(taskId) {
801
+ return join(getTaskOutputsDir(), `${taskId}.output`);
802
+ }
803
+ function ensureTaskOutputsDirExists() {
804
+ const dir = getTaskOutputsDir();
805
+ if (existsSync4(dir)) return;
806
+ mkdirSync2(dir, { recursive: true });
807
+ }
808
+ function touchTaskOutputFile(taskId) {
809
+ ensureTaskOutputsDirExists();
810
+ const filePath = getTaskOutputFilePath(taskId);
811
+ if (!existsSync4(filePath)) {
812
+ const parent = dirname3(filePath);
813
+ if (!existsSync4(parent)) mkdirSync2(parent, { recursive: true });
814
+ writeFileSync(filePath, "", "utf8");
815
+ }
816
+ return filePath;
817
+ }
818
+ function appendTaskOutput(taskId, chunk) {
819
+ try {
820
+ ensureTaskOutputsDirExists();
821
+ appendFileSync(getTaskOutputFilePath(taskId), chunk, "utf8");
822
+ } catch {
823
+ }
824
+ }
825
+ function readTaskOutput(taskId) {
826
+ try {
827
+ const filePath = getTaskOutputFilePath(taskId);
828
+ if (!existsSync4(filePath)) return "";
829
+ return readFileSync(filePath, "utf8");
830
+ } catch {
831
+ return "";
832
+ }
833
+ }
834
+
835
+ // packages/runtime/src/shell/ids.ts
836
+ import { randomUUID } from "crypto";
837
+ function makeBackgroundTaskId() {
838
+ return `b${randomUUID().replace(/-/g, "").slice(0, 6)}`;
839
+ }
840
+
841
+ // packages/runtime/src/shell/execPromotable.ts
842
+ function normalizeExitCode2(code, interrupted) {
843
+ if (typeof code === "number" && Number.isFinite(code)) return code;
844
+ return interrupted ? 143 : 0;
845
+ }
846
+ function execPromotable(state, command, abortSignal, timeout, options) {
847
+ const DEFAULT_TIMEOUT = 12e4;
848
+ const commandTimeout = timeout ?? DEFAULT_TIMEOUT;
849
+ const startedAt = Date.now();
850
+ const sandbox = options?.sandbox;
851
+ const shouldAttemptSandbox = sandbox?.enabled === true;
852
+ const executionCwd = shouldAttemptSandbox && sandbox?.chdir ? sandbox.chdir : state.cwd;
853
+ if (abortSignal?.aborted) {
854
+ return {
855
+ get status() {
856
+ return "killed";
857
+ },
858
+ background: () => null,
859
+ kill: () => {
860
+ },
861
+ result: Promise.resolve({
862
+ stdout: "",
863
+ stderr: "Command aborted before execution",
864
+ code: 145,
865
+ interrupted: true
866
+ })
867
+ };
868
+ }
869
+ const sandboxCmd = shouldAttemptSandbox ? buildSandboxCommand({ command, sandbox, cwd: state.cwd }) : null;
870
+ if (shouldAttemptSandbox && sandbox?.require && !sandboxCmd) {
871
+ return {
872
+ get status() {
873
+ return "killed";
874
+ },
875
+ background: () => null,
876
+ kill: () => {
877
+ },
878
+ result: Promise.resolve({
879
+ stdout: "",
880
+ stderr: "System sandbox is required but unavailable (missing bubblewrap or unsupported platform).",
881
+ code: 2,
882
+ interrupted: false
883
+ })
884
+ };
885
+ }
886
+ const cmdToRun = sandboxCmd ? sandboxCmd.cmd : getShellCmdForPlatform(process.platform, command, process.env);
887
+ const internalAbortController = new AbortController();
888
+ state.abortController = internalAbortController;
889
+ let status = "running";
890
+ let backgroundProcess = null;
891
+ let backgroundTaskId = null;
892
+ let stdout = "";
893
+ let stderr = "";
894
+ let wasAborted = false;
895
+ let wasBackgrounded = false;
896
+ let timeoutHandle = null;
897
+ let timedOut = false;
898
+ let onTimeoutCb = null;
899
+ const countNonEmptyLines = (chunk) => chunk.split("\n").filter((line) => line.length > 0).length;
900
+ const spawnedProcess = spawn2(cmdToRun[0], cmdToRun.slice(1), {
901
+ cwd: executionCwd,
902
+ stdio: ["ignore", "pipe", "pipe"]
903
+ });
904
+ state.currentProcess = spawnedProcess;
905
+ const exitPromise = new Promise((resolve3) => {
906
+ spawnedProcess.once("exit", (code) => resolve3({ kind: "exit", code }));
907
+ spawnedProcess.once("error", (error) => resolve3({ kind: "error", error }));
908
+ });
909
+ const onAbort = () => {
910
+ if (status === "backgrounded") return;
911
+ wasAborted = true;
912
+ try {
913
+ internalAbortController.abort();
914
+ } catch {
915
+ }
916
+ try {
917
+ spawnedProcess.kill();
918
+ } catch {
919
+ }
920
+ if (backgroundProcess) backgroundProcess.interrupted = true;
921
+ };
922
+ const clearForegroundGuards = () => {
923
+ if (timeoutHandle) {
924
+ clearTimeout(timeoutHandle);
925
+ timeoutHandle = null;
926
+ }
927
+ if (abortSignal) {
928
+ abortSignal.removeEventListener("abort", onAbort);
929
+ }
930
+ };
931
+ if (abortSignal) {
932
+ abortSignal.addEventListener("abort", onAbort, { once: true });
933
+ if (abortSignal.aborted) onAbort();
934
+ }
935
+ const stdoutCollector = createCancellableTextCollector(
936
+ spawnedProcess.stdout,
937
+ {
938
+ collectText: false,
939
+ onChunk: (chunk) => {
940
+ stdout += chunk;
941
+ options?.onStdoutChunk?.(chunk);
942
+ if (backgroundProcess) {
943
+ backgroundProcess.stdout = stdout;
944
+ appendTaskOutput(backgroundProcess.id, chunk);
945
+ backgroundProcess.stdoutLineCount += countNonEmptyLines(chunk);
946
+ }
947
+ }
948
+ }
949
+ );
950
+ const stderrCollector = createCancellableTextCollector(
951
+ spawnedProcess.stderr,
952
+ {
953
+ collectText: false,
954
+ onChunk: (chunk) => {
955
+ stderr += chunk;
956
+ options?.onStderrChunk?.(chunk);
957
+ if (backgroundProcess) {
958
+ backgroundProcess.stderr = stderr;
959
+ appendTaskOutput(backgroundProcess.id, chunk);
960
+ backgroundProcess.stderrLineCount += countNonEmptyLines(chunk);
961
+ }
962
+ }
963
+ }
964
+ );
965
+ timeoutHandle = setTimeout(() => {
966
+ if (status !== "running") return;
967
+ if (onTimeoutCb) {
968
+ onTimeoutCb(background);
969
+ return;
970
+ }
971
+ timedOut = true;
972
+ try {
973
+ spawnedProcess.kill();
974
+ } catch {
975
+ }
976
+ try {
977
+ internalAbortController.abort();
978
+ } catch {
979
+ }
980
+ }, commandTimeout);
981
+ const background = (bashId) => {
982
+ if (backgroundTaskId) return { bashId: backgroundTaskId };
983
+ if (status !== "running") return null;
984
+ backgroundTaskId = bashId ?? makeBackgroundTaskId();
985
+ const outputFile = touchTaskOutputFile(backgroundTaskId);
986
+ if (stdout) appendTaskOutput(backgroundTaskId, stdout);
987
+ if (stderr) appendTaskOutput(backgroundTaskId, stderr);
988
+ status = "backgrounded";
989
+ wasBackgrounded = true;
990
+ clearForegroundGuards();
991
+ backgroundProcess = {
992
+ id: backgroundTaskId,
993
+ command,
994
+ stdout,
995
+ stderr,
996
+ stdoutCursor: 0,
997
+ stderrCursor: 0,
998
+ stdoutLineCount: countNonEmptyLines(stdout),
999
+ stderrLineCount: countNonEmptyLines(stderr),
1000
+ lastReportedStdoutLines: 0,
1001
+ lastReportedStderrLines: 0,
1002
+ code: null,
1003
+ interrupted: false,
1004
+ killed: false,
1005
+ timedOut: false,
1006
+ completionStatusSentInAttachment: false,
1007
+ notified: false,
1008
+ startedAt,
1009
+ timeoutAt: Number.POSITIVE_INFINITY,
1010
+ process: spawnedProcess,
1011
+ abortController: internalAbortController,
1012
+ timeoutHandle: null,
1013
+ cwd: executionCwd,
1014
+ outputFile
1015
+ };
1016
+ state.backgroundProcesses.set(backgroundTaskId, backgroundProcess);
1017
+ state.currentProcess = null;
1018
+ state.abortController = null;
1019
+ return { bashId: backgroundTaskId };
1020
+ };
1021
+ const kill = () => {
1022
+ status = "killed";
1023
+ try {
1024
+ spawnedProcess.kill();
1025
+ } catch {
1026
+ }
1027
+ try {
1028
+ internalAbortController.abort();
1029
+ } catch {
1030
+ }
1031
+ if (backgroundProcess) {
1032
+ backgroundProcess.interrupted = true;
1033
+ backgroundProcess.killed = true;
1034
+ }
1035
+ };
1036
+ const result = (async () => {
1037
+ try {
1038
+ const exitOutcome = await exitPromise;
1039
+ if (exitOutcome.kind === "error") {
1040
+ stderr = [stderr, exitOutcome.error.message].filter(Boolean).join("\n");
1041
+ }
1042
+ if (status === "running" || status === "backgrounded")
1043
+ status = "completed";
1044
+ if (backgroundProcess) {
1045
+ backgroundProcess.code = exitOutcome.kind === "exit" ? exitOutcome.code ?? 0 : 2;
1046
+ backgroundProcess.interrupted = backgroundProcess.interrupted || wasAborted || internalAbortController.signal.aborted;
1047
+ }
1048
+ if (!wasBackgrounded) {
1049
+ await Promise.race([
1050
+ Promise.allSettled([stdoutCollector.done, stderrCollector.done]),
1051
+ new Promise((resolve3) => setTimeout(resolve3, 250))
1052
+ ]);
1053
+ await Promise.allSettled([
1054
+ stdoutCollector.cancel(),
1055
+ stderrCollector.cancel()
1056
+ ]);
1057
+ }
1058
+ const interrupted = wasAborted || abortSignal?.aborted === true || internalAbortController.signal.aborted === true || timedOut;
1059
+ let code = exitOutcome.kind === "exit" ? exitOutcome.code : null;
1060
+ if (exitOutcome.kind === "error") code = 2;
1061
+ const stderrWithTimeout = timedOut ? [`Command timed out`, stderr].filter(Boolean).join("\n") : stderr;
1062
+ const stderrAnnotated = sandboxCmd ? maybeAnnotateMacosSandboxStderr(stderrWithTimeout, sandbox) : stderrWithTimeout;
1063
+ return {
1064
+ stdout,
1065
+ stderr: stderrAnnotated,
1066
+ code: normalizeExitCode2(code, interrupted),
1067
+ interrupted
1068
+ };
1069
+ } finally {
1070
+ clearForegroundGuards();
1071
+ if (state.currentProcess === spawnedProcess) {
1072
+ state.currentProcess = null;
1073
+ state.abortController = null;
1074
+ }
1075
+ }
1076
+ })();
1077
+ const execHandle = {
1078
+ get status() {
1079
+ return status;
1080
+ },
1081
+ background,
1082
+ kill,
1083
+ result
1084
+ };
1085
+ execHandle.onTimeout = (cb) => {
1086
+ onTimeoutCb = cb;
1087
+ };
1088
+ result.then((r) => {
1089
+ if (!backgroundProcess || !backgroundTaskId) return;
1090
+ backgroundProcess.code = r.code;
1091
+ backgroundProcess.interrupted = r.interrupted;
1092
+ }).catch(() => {
1093
+ if (!backgroundProcess) return;
1094
+ backgroundProcess.code = backgroundProcess.code ?? 2;
1095
+ });
1096
+ return execHandle;
1097
+ }
1098
+
1099
+ // packages/runtime/src/shell/background.ts
1100
+ import { spawn as spawn3 } from "node:child_process";
1101
+ function execInBackground(state, command, timeout, options) {
1102
+ const DEFAULT_TIMEOUT = 12e4;
1103
+ const commandTimeout = timeout ?? DEFAULT_TIMEOUT;
1104
+ const abortController = new AbortController();
1105
+ const sandbox = options?.sandbox;
1106
+ const sandboxCmd = sandbox?.enabled === true ? buildSandboxCommand({ command, sandbox, cwd: state.cwd }) : null;
1107
+ const executionCwd = sandbox?.enabled === true && sandbox?.chdir ? sandbox.chdir : state.cwd;
1108
+ if (sandbox?.enabled === true && sandbox?.require && !sandboxCmd) {
1109
+ throw new Error(
1110
+ "System sandbox is required but unavailable (missing bubblewrap or unsupported platform)."
1111
+ );
1112
+ }
1113
+ const cmdToRun = sandboxCmd ? sandboxCmd.cmd : getShellCmdForPlatform(process.platform, command, process.env);
1114
+ const bashId = makeBackgroundTaskId();
1115
+ const outputFile = touchTaskOutputFile(bashId);
1116
+ const childProcess = spawn3(cmdToRun[0], cmdToRun.slice(1), {
1117
+ cwd: executionCwd,
1118
+ stdio: ["ignore", "pipe", "pipe"]
1119
+ });
1120
+ const exitPromise = new Promise((resolve3) => {
1121
+ childProcess.once("exit", (code) => resolve3({ kind: "exit", code }));
1122
+ childProcess.once("error", (error) => resolve3({ kind: "error", error }));
1123
+ });
1124
+ const timeoutHandle = setTimeout(() => {
1125
+ abortController.abort();
1126
+ backgroundProcess.timedOut = true;
1127
+ childProcess.kill();
1128
+ }, commandTimeout);
1129
+ const backgroundProcess = {
1130
+ id: bashId,
1131
+ command,
1132
+ stdout: "",
1133
+ stderr: "",
1134
+ stdoutCursor: 0,
1135
+ stderrCursor: 0,
1136
+ stdoutLineCount: 0,
1137
+ stderrLineCount: 0,
1138
+ lastReportedStdoutLines: 0,
1139
+ lastReportedStderrLines: 0,
1140
+ code: null,
1141
+ interrupted: false,
1142
+ killed: false,
1143
+ timedOut: false,
1144
+ completionStatusSentInAttachment: false,
1145
+ notified: false,
1146
+ startedAt: Date.now(),
1147
+ timeoutAt: Date.now() + commandTimeout,
1148
+ process: childProcess,
1149
+ abortController,
1150
+ timeoutHandle,
1151
+ cwd: executionCwd,
1152
+ outputFile
1153
+ };
1154
+ const countNonEmptyLines = (chunk) => chunk.split("\n").filter((line) => line.length > 0).length;
1155
+ startStreamReader(childProcess.stdout, (chunk) => {
1156
+ backgroundProcess.stdout += chunk;
1157
+ appendTaskOutput(bashId, chunk);
1158
+ backgroundProcess.stdoutLineCount += countNonEmptyLines(chunk);
1159
+ });
1160
+ startStreamReader(childProcess.stderr, (chunk) => {
1161
+ backgroundProcess.stderr += chunk;
1162
+ appendTaskOutput(bashId, chunk);
1163
+ backgroundProcess.stderrLineCount += countNonEmptyLines(chunk);
1164
+ });
1165
+ exitPromise.then((exitOutcome) => {
1166
+ backgroundProcess.code = exitOutcome.kind === "exit" ? exitOutcome.code ?? 0 : 2;
1167
+ if (exitOutcome.kind === "error") {
1168
+ backgroundProcess.stderr = [
1169
+ backgroundProcess.stderr,
1170
+ exitOutcome.error.message
1171
+ ].filter(Boolean).join("\n");
1172
+ }
1173
+ backgroundProcess.interrupted = backgroundProcess.interrupted || abortController.signal.aborted;
1174
+ if (sandbox?.enabled === true) {
1175
+ backgroundProcess.stderr = maybeAnnotateMacosSandboxStderr(
1176
+ backgroundProcess.stderr,
1177
+ sandbox
1178
+ );
1179
+ }
1180
+ if (backgroundProcess.timeoutHandle) {
1181
+ clearTimeout(backgroundProcess.timeoutHandle);
1182
+ backgroundProcess.timeoutHandle = null;
1183
+ }
1184
+ });
1185
+ state.backgroundProcesses.set(bashId, backgroundProcess);
1186
+ return { bashId };
1187
+ }
1188
+ function getBackgroundOutput(state, shellId) {
1189
+ const proc = state.backgroundProcesses.get(shellId);
1190
+ if (!proc) return null;
1191
+ const running = proc.code === null && !proc.interrupted;
1192
+ return {
1193
+ stdout: proc.stdout,
1194
+ stderr: proc.stderr,
1195
+ code: proc.code,
1196
+ interrupted: proc.interrupted,
1197
+ killed: proc.killed,
1198
+ timedOut: proc.timedOut,
1199
+ running,
1200
+ command: proc.command,
1201
+ cwd: proc.cwd,
1202
+ startedAt: proc.startedAt,
1203
+ timeoutAt: proc.timeoutAt,
1204
+ outputFile: proc.outputFile
1205
+ };
1206
+ }
1207
+ function readBackgroundOutput(state, bashId, options) {
1208
+ const proc = state.backgroundProcesses.get(bashId);
1209
+ if (!proc) return null;
1210
+ const stdoutDelta = proc.stdout.slice(proc.stdoutCursor);
1211
+ const stderrDelta = proc.stderr.slice(proc.stderrCursor);
1212
+ proc.stdoutCursor = proc.stdout.length;
1213
+ proc.stderrCursor = proc.stderr.length;
1214
+ const stdoutLines = stdoutDelta === "" ? 0 : stdoutDelta.split("\n").length;
1215
+ const stderrLines = stderrDelta === "" ? 0 : stderrDelta.split("\n").length;
1216
+ let stdoutToReturn = stdoutDelta;
1217
+ let stderrToReturn = stderrDelta;
1218
+ const filter = options?.filter?.trim();
1219
+ if (filter) {
1220
+ const regex = new RegExp(filter, "i");
1221
+ stdoutToReturn = stdoutDelta.split("\n").filter((line) => regex.test(line)).join("\n");
1222
+ stderrToReturn = stderrDelta.split("\n").filter((line) => regex.test(line)).join("\n");
1223
+ }
1224
+ const status = proc.killed ? "killed" : proc.code === null ? "running" : proc.code === 0 ? "completed" : "failed";
1225
+ return {
1226
+ shellId: bashId,
1227
+ command: proc.command,
1228
+ cwd: proc.cwd,
1229
+ startedAt: proc.startedAt,
1230
+ timeoutAt: proc.timeoutAt,
1231
+ status,
1232
+ exitCode: proc.code,
1233
+ stdout: stdoutToReturn,
1234
+ stderr: stderrToReturn,
1235
+ stdoutLines,
1236
+ stderrLines,
1237
+ ...filter ? { filterPattern: filter } : {}
1238
+ };
1239
+ }
1240
+ function killBackgroundShell(state, shellId) {
1241
+ const proc = state.backgroundProcesses.get(shellId);
1242
+ if (!proc) return false;
1243
+ try {
1244
+ proc.interrupted = true;
1245
+ proc.killed = true;
1246
+ proc.abortController.abort();
1247
+ proc.process.kill();
1248
+ if (proc.timeoutHandle) {
1249
+ clearTimeout(proc.timeoutHandle);
1250
+ proc.timeoutHandle = null;
1251
+ }
1252
+ return true;
1253
+ } catch {
1254
+ return false;
1255
+ }
1256
+ }
1257
+ function listBackgroundShells(state) {
1258
+ return Array.from(state.backgroundProcesses.values());
1259
+ }
1260
+ function flushBashNotifications(state) {
1261
+ const processes = Array.from(state.backgroundProcesses.values());
1262
+ const statusFor = (proc) => proc.killed ? "killed" : proc.code === null ? "running" : proc.code === 0 ? "completed" : "failed";
1263
+ const notifications = [];
1264
+ for (const proc of processes) {
1265
+ if (proc.notified) continue;
1266
+ const status = statusFor(proc);
1267
+ if (status === "running") continue;
1268
+ notifications.push({
1269
+ type: "bash_notification",
1270
+ taskId: proc.id,
1271
+ description: proc.command,
1272
+ outputFile: proc.outputFile || getTaskOutputFilePath(proc.id),
1273
+ status,
1274
+ ...proc.code !== null ? { exitCode: proc.code } : {}
1275
+ });
1276
+ proc.notified = true;
1277
+ }
1278
+ return notifications;
1279
+ }
1280
+ function flushBackgroundShellStatusAttachments(state) {
1281
+ const processes = Array.from(state.backgroundProcesses.values());
1282
+ const statusFor = (proc) => proc.killed ? "killed" : proc.code === null ? "running" : proc.code === 0 ? "completed" : "failed";
1283
+ const progressAttachments = [];
1284
+ for (const proc of processes) {
1285
+ if (statusFor(proc) !== "running") continue;
1286
+ const stdoutDelta = proc.stdoutLineCount - proc.lastReportedStdoutLines;
1287
+ const stderrDelta = proc.stderrLineCount - proc.lastReportedStderrLines;
1288
+ if (stdoutDelta === 0 && stderrDelta === 0) continue;
1289
+ proc.lastReportedStdoutLines = proc.stdoutLineCount;
1290
+ proc.lastReportedStderrLines = proc.stderrLineCount;
1291
+ progressAttachments.push({
1292
+ type: "task_progress",
1293
+ taskId: proc.id,
1294
+ stdoutLineDelta: stdoutDelta,
1295
+ stderrLineDelta: stderrDelta,
1296
+ outputFile: proc.outputFile || getTaskOutputFilePath(proc.id)
1297
+ });
1298
+ }
1299
+ return progressAttachments;
1300
+ }
1301
+
1302
+ // packages/runtime/src/shell/BunShell.ts
1303
+ var BunShell = class _BunShell {
1304
+ state;
1305
+ constructor(cwd) {
1306
+ this.state = createInitialState(cwd);
1307
+ }
1308
+ static instance = null;
1309
+ static restart() {
1310
+ if (_BunShell.instance) {
1311
+ _BunShell.instance.close();
1312
+ _BunShell.instance = null;
1313
+ }
1314
+ }
1315
+ static getInstance() {
1316
+ if (!_BunShell.instance || !_BunShell.instance.state.isAlive) {
1317
+ _BunShell.instance = new _BunShell(process.cwd());
1318
+ }
1319
+ return _BunShell.instance;
1320
+ }
1321
+ static getShellCmdForPlatform(platform, command, env = process.env) {
1322
+ return getShellCmdForPlatform(platform, command, env);
1323
+ }
1324
+ execPromotable(command, abortSignal, timeout, options) {
1325
+ return execPromotable(this.state, command, abortSignal, timeout, options);
1326
+ }
1327
+ async exec(command, abortSignal, timeout, options) {
1328
+ return exec(this.state, command, abortSignal, timeout, options);
1329
+ }
1330
+ execInBackground(command, timeout, options) {
1331
+ return execInBackground(this.state, command, timeout, options);
1332
+ }
1333
+ getBackgroundOutput(shellId) {
1334
+ return getBackgroundOutput(this.state, shellId);
1335
+ }
1336
+ readBackgroundOutput(bashId, options) {
1337
+ return readBackgroundOutput(this.state, bashId, options);
1338
+ }
1339
+ killBackgroundShell(shellId) {
1340
+ return killBackgroundShell(this.state, shellId);
1341
+ }
1342
+ listBackgroundShells() {
1343
+ return listBackgroundShells(this.state);
1344
+ }
1345
+ pwd() {
1346
+ return this.state.cwd;
1347
+ }
1348
+ async setCwd(cwd) {
1349
+ const resolved = isAbsolute2(cwd) ? cwd : resolve2(this.state.cwd, cwd);
1350
+ if (!existsSync5(resolved)) {
1351
+ throw new Error(`Path "${resolved}" does not exist`);
1352
+ }
1353
+ this.state.cwd = resolved;
1354
+ }
1355
+ killChildren() {
1356
+ this.state.abortController?.abort();
1357
+ this.state.currentProcess?.kill();
1358
+ for (const bg of Array.from(this.state.backgroundProcesses.keys())) {
1359
+ killBackgroundShell(this.state, bg);
1360
+ }
1361
+ }
1362
+ close() {
1363
+ this.state.isAlive = false;
1364
+ this.killChildren();
1365
+ }
1366
+ flushBashNotifications() {
1367
+ return flushBashNotifications(this.state);
1368
+ }
1369
+ flushBackgroundShellStatusAttachments() {
1370
+ return flushBackgroundShellStatusAttachments(this.state);
1371
+ }
1372
+ };
1373
+
1374
+ // packages/runtime/src/shell/notifications.ts
1375
+ function renderBackgroundShellStatusAttachment(attachment) {
1376
+ const parts = [];
1377
+ if (attachment.stdoutLineDelta > 0) {
1378
+ const n = attachment.stdoutLineDelta;
1379
+ parts.push(`${n} line${n > 1 ? "s" : ""} of stdout`);
1380
+ }
1381
+ if (attachment.stderrLineDelta > 0) {
1382
+ const n = attachment.stderrLineDelta;
1383
+ parts.push(`${n} line${n > 1 ? "s" : ""} of stderr`);
1384
+ }
1385
+ if (parts.length === 0) return "";
1386
+ return `Background bash ${attachment.taskId} has new output: ${parts.join(", ")}. Read ${attachment.outputFile} to see output.`;
1387
+ }
1388
+ function renderBashNotification(notification) {
1389
+ const status = notification.status;
1390
+ const exitCode = notification.exitCode;
1391
+ const summarySuffix = status === "completed" ? `completed${exitCode !== void 0 ? ` (exit code ${exitCode})` : ""}` : status === "failed" ? `failed${exitCode !== void 0 ? ` with exit code ${exitCode}` : ""}` : "was killed";
1392
+ return [
1393
+ "<bash-notification>",
1394
+ `<shell-id>${notification.taskId}</shell-id>`,
1395
+ `<output-file>${notification.outputFile || getTaskOutputFilePath(notification.taskId)}</output-file>`,
1396
+ `<status>${status}</status>`,
1397
+ `<summary>Background command "${notification.description}" ${summarySuffix}.</summary>`,
1398
+ "Read the output file to retrieve the output.",
1399
+ "</bash-notification>"
1400
+ ].join("\n");
1401
+ }
1402
+
1403
+ export {
1404
+ getTaskOutputFilePath,
1405
+ readTaskOutput,
1406
+ renderBackgroundShellStatusAttachment,
1407
+ renderBashNotification,
1408
+ BunShell
1409
+ };