@xyit/wellspring 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +829 -2
  3. package/dist/agent/pending-asks.d.ts +20 -0
  4. package/dist/agent/pending-asks.js +70 -0
  5. package/dist/agent/pending-asks.js.map +1 -0
  6. package/dist/agent/task-registry.d.ts +14 -0
  7. package/dist/agent/task-registry.js +80 -0
  8. package/dist/agent/task-registry.js.map +1 -0
  9. package/dist/agent/tool-context.d.ts +30 -0
  10. package/dist/agent/tool-context.js +10 -0
  11. package/dist/agent/tool-context.js.map +1 -0
  12. package/dist/agent/usage.d.ts +40 -0
  13. package/dist/agent/usage.js +122 -0
  14. package/dist/agent/usage.js.map +1 -0
  15. package/dist/api/host/agent.d.ts +165 -0
  16. package/dist/api/host/agent.js +5 -0
  17. package/dist/api/host/agent.js.map +1 -0
  18. package/dist/api/host/events.d.ts +2 -0
  19. package/dist/api/host/events.js +6 -0
  20. package/dist/api/host/events.js.map +1 -0
  21. package/dist/api/host/exec.d.ts +36 -0
  22. package/dist/api/host/exec.js +10 -0
  23. package/dist/api/host/exec.js.map +1 -0
  24. package/dist/api/host/fs.d.ts +24 -0
  25. package/dist/api/host/fs.js +7 -0
  26. package/dist/api/host/fs.js.map +1 -0
  27. package/dist/api/host/hooks.d.ts +210 -0
  28. package/dist/api/host/hooks.js +401 -0
  29. package/dist/api/host/hooks.js.map +1 -0
  30. package/dist/api/host/host.d.ts +36 -0
  31. package/dist/api/host/host.js +53 -0
  32. package/dist/api/host/host.js.map +1 -0
  33. package/dist/api/host/http.d.ts +58 -0
  34. package/dist/api/host/http.js +6 -0
  35. package/dist/api/host/http.js.map +1 -0
  36. package/dist/api/host/index.d.ts +15 -0
  37. package/dist/api/host/index.js +20 -0
  38. package/dist/api/host/index.js.map +1 -0
  39. package/dist/api/host/models.d.ts +65 -0
  40. package/dist/api/host/models.js +8 -0
  41. package/dist/api/host/models.js.map +1 -0
  42. package/dist/api/host/network.d.ts +22 -0
  43. package/dist/api/host/network.js +7 -0
  44. package/dist/api/host/network.js.map +1 -0
  45. package/dist/api/host/plugin.d.ts +138 -0
  46. package/dist/api/host/plugin.js +6 -0
  47. package/dist/api/host/plugin.js.map +1 -0
  48. package/dist/api/host/plugins.d.ts +45 -0
  49. package/dist/api/host/plugins.js +6 -0
  50. package/dist/api/host/plugins.js.map +1 -0
  51. package/dist/api/host/pty.d.ts +55 -0
  52. package/dist/api/host/pty.js +21 -0
  53. package/dist/api/host/pty.js.map +1 -0
  54. package/dist/api/host/session.d.ts +5 -0
  55. package/dist/api/host/session.js +52 -0
  56. package/dist/api/host/session.js.map +1 -0
  57. package/dist/api/host/version.d.ts +2 -0
  58. package/dist/api/host/version.js +3 -0
  59. package/dist/api/host/version.js.map +1 -0
  60. package/dist/api/host/workspace.d.ts +38 -0
  61. package/dist/api/host/workspace.js +9 -0
  62. package/dist/api/host/workspace.js.map +1 -0
  63. package/dist/api/plugin/http-client.d.ts +42 -0
  64. package/dist/api/plugin/http-client.js +364 -0
  65. package/dist/api/plugin/http-client.js.map +1 -0
  66. package/dist/api/plugin/http-protocol.d.ts +152 -0
  67. package/dist/api/plugin/http-protocol.js +49 -0
  68. package/dist/api/plugin/http-protocol.js.map +1 -0
  69. package/dist/api/result/result.d.ts +16 -0
  70. package/dist/api/result/result.js +43 -0
  71. package/dist/api/result/result.js.map +1 -0
  72. package/dist/commands/agent-turn.d.ts +63 -0
  73. package/dist/commands/agent-turn.js +687 -0
  74. package/dist/commands/agent-turn.js.map +1 -0
  75. package/dist/commands/ask-prompt.d.ts +6 -0
  76. package/dist/commands/ask-prompt.js +49 -0
  77. package/dist/commands/ask-prompt.js.map +1 -0
  78. package/dist/commands/config.d.ts +2 -0
  79. package/dist/commands/config.js +283 -0
  80. package/dist/commands/config.js.map +1 -0
  81. package/dist/commands/conversation.d.ts +51 -0
  82. package/dist/commands/conversation.js +630 -0
  83. package/dist/commands/conversation.js.map +1 -0
  84. package/dist/commands/doctor.d.ts +2 -0
  85. package/dist/commands/doctor.js +77 -0
  86. package/dist/commands/doctor.js.map +1 -0
  87. package/dist/commands/exec-approval.d.ts +3 -0
  88. package/dist/commands/exec-approval.js +80 -0
  89. package/dist/commands/exec-approval.js.map +1 -0
  90. package/dist/commands/help.d.ts +2 -0
  91. package/dist/commands/help.js +35 -0
  92. package/dist/commands/help.js.map +1 -0
  93. package/dist/commands/key.d.ts +2 -0
  94. package/dist/commands/key.js +226 -0
  95. package/dist/commands/key.js.map +1 -0
  96. package/dist/commands/plugin.d.ts +2 -0
  97. package/dist/commands/plugin.js +188 -0
  98. package/dist/commands/plugin.js.map +1 -0
  99. package/dist/commands/session.d.ts +2 -0
  100. package/dist/commands/session.js +167 -0
  101. package/dist/commands/session.js.map +1 -0
  102. package/dist/commands/shared.d.ts +35 -0
  103. package/dist/commands/shared.js +66 -0
  104. package/dist/commands/shared.js.map +1 -0
  105. package/dist/commands/start.d.ts +2 -0
  106. package/dist/commands/start.js +75 -0
  107. package/dist/commands/start.js.map +1 -0
  108. package/dist/commands/stop.d.ts +2 -0
  109. package/dist/commands/stop.js +24 -0
  110. package/dist/commands/stop.js.map +1 -0
  111. package/dist/commands/version.d.ts +2 -0
  112. package/dist/commands/version.js +33 -0
  113. package/dist/commands/version.js.map +1 -0
  114. package/dist/config/codes.d.ts +13 -0
  115. package/dist/config/codes.js +15 -0
  116. package/dist/config/codes.js.map +1 -0
  117. package/dist/config/credentials.d.ts +67 -0
  118. package/dist/config/credentials.js +214 -0
  119. package/dist/config/credentials.js.map +1 -0
  120. package/dist/config/defaults.d.ts +5 -0
  121. package/dist/config/defaults.js +31 -0
  122. package/dist/config/defaults.js.map +1 -0
  123. package/dist/config/index.d.ts +5 -0
  124. package/dist/config/index.js +10 -0
  125. package/dist/config/index.js.map +1 -0
  126. package/dist/config/loader.d.ts +10 -0
  127. package/dist/config/loader.js +68 -0
  128. package/dist/config/loader.js.map +1 -0
  129. package/dist/config/providers.d.ts +30 -0
  130. package/dist/config/providers.js +97 -0
  131. package/dist/config/providers.js.map +1 -0
  132. package/dist/config/types.d.ts +75 -0
  133. package/dist/config/types.js +4 -0
  134. package/dist/config/types.js.map +1 -0
  135. package/dist/config/validate.d.ts +4 -0
  136. package/dist/config/validate.js +391 -0
  137. package/dist/config/validate.js.map +1 -0
  138. package/dist/display/markdown.d.ts +7 -0
  139. package/dist/display/markdown.js +116 -0
  140. package/dist/display/markdown.js.map +1 -0
  141. package/dist/display/tool-label.d.ts +6 -0
  142. package/dist/display/tool-label.js +81 -0
  143. package/dist/display/tool-label.js.map +1 -0
  144. package/dist/event/event.d.ts +27 -0
  145. package/dist/event/event.js +152 -0
  146. package/dist/event/event.js.map +1 -0
  147. package/dist/index.d.ts +2 -0
  148. package/dist/index.js +308 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/input/codes.d.ts +15 -0
  151. package/dist/input/codes.js +20 -0
  152. package/dist/input/codes.js.map +1 -0
  153. package/dist/input/commands.d.ts +10 -0
  154. package/dist/input/commands.js +65 -0
  155. package/dist/input/commands.js.map +1 -0
  156. package/dist/input/help.d.ts +8 -0
  157. package/dist/input/help.js +51 -0
  158. package/dist/input/help.js.map +1 -0
  159. package/dist/input/index.d.ts +6 -0
  160. package/dist/input/index.js +10 -0
  161. package/dist/input/index.js.map +1 -0
  162. package/dist/input/parse-options.d.ts +11 -0
  163. package/dist/input/parse-options.js +51 -0
  164. package/dist/input/parse-options.js.map +1 -0
  165. package/dist/input/parse.d.ts +3 -0
  166. package/dist/input/parse.js +119 -0
  167. package/dist/input/parse.js.map +1 -0
  168. package/dist/input/types.d.ts +17 -0
  169. package/dist/input/types.js +2 -0
  170. package/dist/input/types.js.map +1 -0
  171. package/dist/logger/elog4js.d.ts +65 -0
  172. package/dist/logger/elog4js.js +305 -0
  173. package/dist/logger/elog4js.js.map +1 -0
  174. package/dist/logger/logger.d.ts +37 -0
  175. package/dist/logger/logger.js +196 -0
  176. package/dist/logger/logger.js.map +1 -0
  177. package/dist/network/index.d.ts +2 -0
  178. package/dist/network/index.js +6 -0
  179. package/dist/network/index.js.map +1 -0
  180. package/dist/network/openai.d.ts +117 -0
  181. package/dist/network/openai.js +443 -0
  182. package/dist/network/openai.js.map +1 -0
  183. package/dist/network/proxy.d.ts +9 -0
  184. package/dist/network/proxy.js +72 -0
  185. package/dist/network/proxy.js.map +1 -0
  186. package/dist/network/web.d.ts +34 -0
  187. package/dist/network/web.js +152 -0
  188. package/dist/network/web.js.map +1 -0
  189. package/dist/platform/clipboard.d.ts +15 -0
  190. package/dist/platform/clipboard.js +82 -0
  191. package/dist/platform/clipboard.js.map +1 -0
  192. package/dist/platform/exec.d.ts +28 -0
  193. package/dist/platform/exec.js +95 -0
  194. package/dist/platform/exec.js.map +1 -0
  195. package/dist/platform/file.d.ts +38 -0
  196. package/dist/platform/file.js +197 -0
  197. package/dist/platform/file.js.map +1 -0
  198. package/dist/platform/index.d.ts +7 -0
  199. package/dist/platform/index.js +12 -0
  200. package/dist/platform/index.js.map +1 -0
  201. package/dist/platform/notification.d.ts +14 -0
  202. package/dist/platform/notification.js +82 -0
  203. package/dist/platform/notification.js.map +1 -0
  204. package/dist/platform/open-external.d.ts +10 -0
  205. package/dist/platform/open-external.js +105 -0
  206. package/dist/platform/open-external.js.map +1 -0
  207. package/dist/platform/os.d.ts +20 -0
  208. package/dist/platform/os.js +86 -0
  209. package/dist/platform/os.js.map +1 -0
  210. package/dist/platform/path.d.ts +32 -0
  211. package/dist/platform/path.js +154 -0
  212. package/dist/platform/path.js.map +1 -0
  213. package/dist/plugin/access-guard.d.ts +1 -0
  214. package/dist/plugin/access-guard.js +40 -0
  215. package/dist/plugin/access-guard.js.map +1 -0
  216. package/dist/plugin/agent-service.d.ts +25 -0
  217. package/dist/plugin/agent-service.js +809 -0
  218. package/dist/plugin/agent-service.js.map +1 -0
  219. package/dist/plugin/agent-tools.d.ts +12 -0
  220. package/dist/plugin/agent-tools.js +31 -0
  221. package/dist/plugin/agent-tools.js.map +1 -0
  222. package/dist/plugin/capabilities.d.ts +26 -0
  223. package/dist/plugin/capabilities.js +192 -0
  224. package/dist/plugin/capabilities.js.map +1 -0
  225. package/dist/plugin/console-guard.d.ts +2 -0
  226. package/dist/plugin/console-guard.js +52 -0
  227. package/dist/plugin/console-guard.js.map +1 -0
  228. package/dist/plugin/data-access.d.ts +15 -0
  229. package/dist/plugin/data-access.js +57 -0
  230. package/dist/plugin/data-access.js.map +1 -0
  231. package/dist/plugin/fs.d.ts +3 -0
  232. package/dist/plugin/fs.js +93 -0
  233. package/dist/plugin/fs.js.map +1 -0
  234. package/dist/plugin/host-alias.d.ts +2 -0
  235. package/dist/plugin/host-alias.js +57 -0
  236. package/dist/plugin/host-alias.js.map +1 -0
  237. package/dist/plugin/index.d.ts +7 -0
  238. package/dist/plugin/index.js +11 -0
  239. package/dist/plugin/index.js.map +1 -0
  240. package/dist/plugin/install.d.ts +12 -0
  241. package/dist/plugin/install.js +114 -0
  242. package/dist/plugin/install.js.map +1 -0
  243. package/dist/plugin/loader.d.ts +45 -0
  244. package/dist/plugin/loader.js +739 -0
  245. package/dist/plugin/loader.js.map +1 -0
  246. package/dist/plugin/manage.d.ts +31 -0
  247. package/dist/plugin/manage.js +265 -0
  248. package/dist/plugin/manage.js.map +1 -0
  249. package/dist/plugin/models-service.d.ts +15 -0
  250. package/dist/plugin/models-service.js +317 -0
  251. package/dist/plugin/models-service.js.map +1 -0
  252. package/dist/plugin/network-service.d.ts +10 -0
  253. package/dist/plugin/network-service.js +87 -0
  254. package/dist/plugin/network-service.js.map +1 -0
  255. package/dist/plugin/paths.d.ts +6 -0
  256. package/dist/plugin/paths.js +15 -0
  257. package/dist/plugin/paths.js.map +1 -0
  258. package/dist/plugin/registry.d.ts +17 -0
  259. package/dist/plugin/registry.js +82 -0
  260. package/dist/plugin/registry.js.map +1 -0
  261. package/dist/plugin/runtime.d.ts +9 -0
  262. package/dist/plugin/runtime.js +43 -0
  263. package/dist/plugin/runtime.js.map +1 -0
  264. package/dist/plugin/scaffold.d.ts +13 -0
  265. package/dist/plugin/scaffold.js +126 -0
  266. package/dist/plugin/scaffold.js.map +1 -0
  267. package/dist/plugin/state.d.ts +6 -0
  268. package/dist/plugin/state.js +38 -0
  269. package/dist/plugin/state.js.map +1 -0
  270. package/dist/plugin/zip.d.ts +7 -0
  271. package/dist/plugin/zip.js +138 -0
  272. package/dist/plugin/zip.js.map +1 -0
  273. package/dist/sandbox/audit.d.ts +12 -0
  274. package/dist/sandbox/audit.js +20 -0
  275. package/dist/sandbox/audit.js.map +1 -0
  276. package/dist/sandbox/backends/bwrap.d.ts +28 -0
  277. package/dist/sandbox/backends/bwrap.js +197 -0
  278. package/dist/sandbox/backends/bwrap.js.map +1 -0
  279. package/dist/sandbox/backends/direct.d.ts +7 -0
  280. package/dist/sandbox/backends/direct.js +32 -0
  281. package/dist/sandbox/backends/direct.js.map +1 -0
  282. package/dist/sandbox/bridge-state.d.ts +13 -0
  283. package/dist/sandbox/bridge-state.js +12 -0
  284. package/dist/sandbox/bridge-state.js.map +1 -0
  285. package/dist/sandbox/index.d.ts +5 -0
  286. package/dist/sandbox/index.js +6 -0
  287. package/dist/sandbox/index.js.map +1 -0
  288. package/dist/sandbox/manager.d.ts +8 -0
  289. package/dist/sandbox/manager.js +325 -0
  290. package/dist/sandbox/manager.js.map +1 -0
  291. package/dist/sandbox/memory-limit.d.ts +44 -0
  292. package/dist/sandbox/memory-limit.js +193 -0
  293. package/dist/sandbox/memory-limit.js.map +1 -0
  294. package/dist/sandbox/plugin-client.d.ts +80 -0
  295. package/dist/sandbox/plugin-client.js +1601 -0
  296. package/dist/sandbox/plugin-client.js.map +1 -0
  297. package/dist/sandbox/plugin-host.d.ts +1 -0
  298. package/dist/sandbox/plugin-host.js +1001 -0
  299. package/dist/sandbox/plugin-host.js.map +1 -0
  300. package/dist/sandbox/protocol.d.ts +43 -0
  301. package/dist/sandbox/protocol.js +96 -0
  302. package/dist/sandbox/protocol.js.map +1 -0
  303. package/dist/sandbox/rpc-timeouts.d.ts +28 -0
  304. package/dist/sandbox/rpc-timeouts.js +15 -0
  305. package/dist/sandbox/rpc-timeouts.js.map +1 -0
  306. package/dist/sandbox/supervisor.d.ts +31 -0
  307. package/dist/sandbox/supervisor.js +114 -0
  308. package/dist/sandbox/supervisor.js.map +1 -0
  309. package/dist/sandbox/types.d.ts +124 -0
  310. package/dist/sandbox/types.js +17 -0
  311. package/dist/sandbox/types.js.map +1 -0
  312. package/dist/service/control.d.ts +32 -0
  313. package/dist/service/control.js +117 -0
  314. package/dist/service/control.js.map +1 -0
  315. package/dist/session/compress.d.ts +3 -0
  316. package/dist/session/compress.js +42 -0
  317. package/dist/session/compress.js.map +1 -0
  318. package/dist/session/index.d.ts +4 -0
  319. package/dist/session/index.js +8 -0
  320. package/dist/session/index.js.map +1 -0
  321. package/dist/session/registry.d.ts +4 -0
  322. package/dist/session/registry.js +12 -0
  323. package/dist/session/registry.js.map +1 -0
  324. package/dist/session/replay.d.ts +10 -0
  325. package/dist/session/replay.js +109 -0
  326. package/dist/session/replay.js.map +1 -0
  327. package/dist/session/session.d.ts +40 -0
  328. package/dist/session/session.js +108 -0
  329. package/dist/session/session.js.map +1 -0
  330. package/dist/session/store.d.ts +58 -0
  331. package/dist/session/store.js +382 -0
  332. package/dist/session/store.js.map +1 -0
  333. package/dist/session/types.d.ts +56 -0
  334. package/dist/session/types.js +3 -0
  335. package/dist/session/types.js.map +1 -0
  336. package/dist/workspace/index.d.ts +7 -0
  337. package/dist/workspace/index.js +17 -0
  338. package/dist/workspace/index.js.map +1 -0
  339. package/dist/workspace/registry.d.ts +25 -0
  340. package/dist/workspace/registry.js +293 -0
  341. package/dist/workspace/registry.js.map +1 -0
  342. package/package.json +73 -5
  343. package/scripts/build-node-pty.mjs +55 -0
  344. package/scripts/rewrite-dts.mjs +36 -0
  345. package/scripts/verify-sandbox.ts +98 -0
  346. package/src/agent/pending-asks.ts +88 -0
  347. package/src/agent/task-registry.ts +108 -0
  348. package/src/agent/tool-context.ts +47 -0
  349. package/src/agent/usage.ts +170 -0
  350. package/src/api/host/agent.ts +162 -0
  351. package/src/api/host/events.ts +7 -0
  352. package/src/api/host/exec.ts +47 -0
  353. package/src/api/host/fs.ts +33 -0
  354. package/src/api/host/hooks.ts +635 -0
  355. package/src/api/host/host.ts +99 -0
  356. package/src/api/host/http.ts +79 -0
  357. package/src/api/host/index.ts +20 -0
  358. package/src/api/host/models.ts +81 -0
  359. package/src/api/host/network.ts +32 -0
  360. package/src/api/host/plugin.ts +158 -0
  361. package/src/api/host/plugins.ts +55 -0
  362. package/src/api/host/pty.ts +73 -0
  363. package/src/api/host/session.ts +61 -0
  364. package/src/api/host/version.ts +2 -0
  365. package/src/api/host/workspace.ts +51 -0
  366. package/src/api/plugin/http-client.ts +492 -0
  367. package/src/api/plugin/http-protocol.ts +231 -0
  368. package/src/api/result/result.ts +52 -0
  369. package/src/commands/agent-turn.ts +817 -0
  370. package/src/commands/ask-prompt.ts +52 -0
  371. package/src/commands/config.ts +306 -0
  372. package/src/commands/conversation.ts +777 -0
  373. package/src/commands/doctor.ts +92 -0
  374. package/src/commands/exec-approval.ts +91 -0
  375. package/src/commands/help.ts +41 -0
  376. package/src/commands/key.ts +281 -0
  377. package/src/commands/plugin.ts +218 -0
  378. package/src/commands/session.ts +179 -0
  379. package/src/commands/shared.ts +103 -0
  380. package/src/commands/start.ts +88 -0
  381. package/src/commands/stop.ts +24 -0
  382. package/src/commands/version.ts +40 -0
  383. package/src/config/codes.ts +17 -0
  384. package/src/config/credentials.ts +302 -0
  385. package/src/config/defaults.ts +32 -0
  386. package/src/config/index.ts +10 -0
  387. package/src/config/loader.ts +80 -0
  388. package/src/config/providers.ts +133 -0
  389. package/src/config/types.ts +88 -0
  390. package/src/config/validate.ts +458 -0
  391. package/src/display/markdown.ts +137 -0
  392. package/src/display/tool-label.ts +87 -0
  393. package/src/event/event.ts +171 -0
  394. package/src/index.ts +344 -0
  395. package/src/input/codes.ts +21 -0
  396. package/src/input/commands.ts +76 -0
  397. package/src/input/help.ts +60 -0
  398. package/src/input/index.ts +10 -0
  399. package/src/input/parse-options.ts +66 -0
  400. package/src/input/parse.ts +138 -0
  401. package/src/input/types.ts +19 -0
  402. package/src/logger/elog4js.ts +366 -0
  403. package/src/logger/logger.ts +251 -0
  404. package/src/network/index.ts +6 -0
  405. package/src/network/openai.ts +571 -0
  406. package/src/network/proxy.ts +80 -0
  407. package/src/network/web.ts +206 -0
  408. package/src/platform/clipboard.ts +107 -0
  409. package/src/platform/exec.ts +128 -0
  410. package/src/platform/file.ts +235 -0
  411. package/src/platform/index.ts +12 -0
  412. package/src/platform/notification.ts +108 -0
  413. package/src/platform/open-external.ts +132 -0
  414. package/src/platform/os.ts +101 -0
  415. package/src/platform/path.ts +214 -0
  416. package/src/plugin/access-guard.ts +46 -0
  417. package/src/plugin/agent-service.ts +969 -0
  418. package/src/plugin/agent-tools.ts +43 -0
  419. package/src/plugin/capabilities.ts +240 -0
  420. package/src/plugin/console-guard.ts +66 -0
  421. package/src/plugin/data-access.ts +70 -0
  422. package/src/plugin/fs.ts +109 -0
  423. package/src/plugin/host-alias.ts +61 -0
  424. package/src/plugin/index.ts +11 -0
  425. package/src/plugin/install.ts +149 -0
  426. package/src/plugin/loader.ts +952 -0
  427. package/src/plugin/manage.ts +329 -0
  428. package/src/plugin/models-service.ts +383 -0
  429. package/src/plugin/network-service.ts +102 -0
  430. package/src/plugin/paths.ts +19 -0
  431. package/src/plugin/registry.ts +103 -0
  432. package/src/plugin/runtime.ts +57 -0
  433. package/src/plugin/scaffold.ts +152 -0
  434. package/src/plugin/state.ts +52 -0
  435. package/src/plugin/zip.ts +156 -0
  436. package/src/sandbox/audit.ts +38 -0
  437. package/src/sandbox/backends/bwrap.ts +251 -0
  438. package/src/sandbox/backends/direct.ts +43 -0
  439. package/src/sandbox/bridge-state.ts +29 -0
  440. package/src/sandbox/index.ts +5 -0
  441. package/src/sandbox/manager.ts +406 -0
  442. package/src/sandbox/memory-limit.ts +245 -0
  443. package/src/sandbox/plugin-client.ts +1881 -0
  444. package/src/sandbox/plugin-host.ts +1282 -0
  445. package/src/sandbox/protocol.ts +142 -0
  446. package/src/sandbox/pty-bridge.py +154 -0
  447. package/src/sandbox/rpc-timeouts.ts +43 -0
  448. package/src/sandbox/supervisor.ts +172 -0
  449. package/src/sandbox/types.ts +149 -0
  450. package/src/service/control.ts +155 -0
  451. package/src/session/compress.ts +47 -0
  452. package/src/session/index.ts +8 -0
  453. package/src/session/registry.ts +17 -0
  454. package/src/session/replay.ts +132 -0
  455. package/src/session/session.ts +134 -0
  456. package/src/session/store.ts +468 -0
  457. package/src/session/types.ts +61 -0
  458. package/src/workspace/index.ts +21 -0
  459. package/src/workspace/registry.ts +356 -0
@@ -0,0 +1,293 @@
1
+ /*
2
+ * 宿主级工作区注册表。
3
+ *
4
+ * 工作区(用户手动添加的目录)由宿主统一管理,存在 <dataDir>/workspaces.json;
5
+ * 插件通过 `api.workspaces` 读写,不再各自解析别的插件的数据目录。
6
+ *
7
+ * 首次加载时兼容迁移旧版 wellspring-web 插件数据目录里的 workspaces.json:
8
+ * 只读取 id / name / root / createdAt / lastSeenAt 这些索引字段,不碰会话正文与认证数据。
9
+ */
10
+ import { createHash } from "node:crypto";
11
+ import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
12
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path";
13
+ import { getPaths } from "../platform/path.js";
14
+ const REGISTRY_VERSION = 1;
15
+ const REGISTRY_FILE = "workspaces.json";
16
+ const LEGACY_PLUGIN_DIR = "wellspring-web";
17
+ export const MAX_WORKSPACES = 40;
18
+ export const MAX_WORKSPACE_NAME_CHARS = 60;
19
+ export const WORKSPACE_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;
20
+ const states = new Map();
21
+ export function workspaceRegistryFile(paths = getPaths()) {
22
+ return join(paths.dataDir, REGISTRY_FILE);
23
+ }
24
+ export function legacyWorkspaceRegistryFile(paths = getPaths()) {
25
+ return join(paths.dataDir, "plugin-data", LEGACY_PLUGIN_DIR, REGISTRY_FILE);
26
+ }
27
+ /** 由工作目录派生稳定 id(与旧版 wellspring-web 的算法一致,保证会话目录还能对上) */
28
+ export function workspaceIdFor(root) {
29
+ const slug = basename(root)
30
+ .toLowerCase()
31
+ .replace(/[^a-z0-9-]+/g, "-")
32
+ .replace(/^-+|-+$/g, "")
33
+ .slice(0, 24);
34
+ const hash = createHash("sha256").update(root).digest("hex").slice(0, 10);
35
+ return slug === "" ? `workspace-${hash}` : `${slug}-${hash}`;
36
+ }
37
+ export function normalizeWorkspaceName(value) {
38
+ if (typeof value !== "string") {
39
+ return null;
40
+ }
41
+ const name = value
42
+ .replace(/[\u0000-\u001f\u007f]/g, " ")
43
+ .replace(/\s+/g, " ")
44
+ .trim();
45
+ if (name === "" || name.length > MAX_WORKSPACE_NAME_CHARS) {
46
+ return null;
47
+ }
48
+ return name;
49
+ }
50
+ function finiteTimestamp(value, fallback) {
51
+ return typeof value === "number" && Number.isFinite(value) && value >= 0
52
+ ? Math.floor(value)
53
+ : fallback;
54
+ }
55
+ function normalizeEntry(value, fallbackId) {
56
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
57
+ return null;
58
+ }
59
+ const record = value;
60
+ const rootRaw = record["root"];
61
+ if (typeof rootRaw !== "string" || rootRaw.trim() === "") {
62
+ return null;
63
+ }
64
+ const root = resolve(rootRaw.trim());
65
+ const rawId = record["id"];
66
+ const id = typeof rawId === "string" && WORKSPACE_ID.test(rawId) ? rawId : fallbackId;
67
+ const rawName = record["name"];
68
+ const name = normalizeWorkspaceName(rawName) ?? (basename(root) === "" ? "工作区" : basename(root));
69
+ const now = Date.now();
70
+ return {
71
+ id,
72
+ name,
73
+ root,
74
+ createdAt: finiteTimestamp(record["createdAt"], now),
75
+ lastSeenAt: finiteTimestamp(record["lastSeenAt"], now),
76
+ };
77
+ }
78
+ /** 解析注册表文件;接受 { v, workspaces } 与旧版纯数组,非法条目忽略 */
79
+ export function parseWorkspaceEntries(value) {
80
+ let list = value;
81
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
82
+ list = value["workspaces"];
83
+ }
84
+ if (!Array.isArray(list)) {
85
+ return [];
86
+ }
87
+ const entries = [];
88
+ const seenIds = new Set();
89
+ const seenRoots = new Set();
90
+ for (const item of list) {
91
+ if (entries.length >= MAX_WORKSPACES) {
92
+ break;
93
+ }
94
+ const rawRoot = typeof item === "object" && item !== null
95
+ ? item["root"]
96
+ : undefined;
97
+ const fallbackId = typeof rawRoot === "string" ? workspaceIdFor(resolve(rawRoot)) : "";
98
+ const entry = normalizeEntry(item, fallbackId);
99
+ if (entry === null || entry.id === "") {
100
+ continue;
101
+ }
102
+ if (seenIds.has(entry.id) || seenRoots.has(entry.root)) {
103
+ continue;
104
+ }
105
+ seenIds.add(entry.id);
106
+ seenRoots.add(entry.root);
107
+ entries.push(entry);
108
+ }
109
+ return entries;
110
+ }
111
+ function stateFor(paths) {
112
+ const file = workspaceRegistryFile(paths);
113
+ const existing = states.get(file);
114
+ if (existing !== undefined) {
115
+ return existing;
116
+ }
117
+ const state = {
118
+ file,
119
+ legacyFile: legacyWorkspaceRegistryFile(paths),
120
+ workspaces: [],
121
+ loaded: false,
122
+ queue: Promise.resolve(),
123
+ };
124
+ states.set(file, state);
125
+ return state;
126
+ }
127
+ async function readJson(path) {
128
+ const raw = await readFile(path, "utf8");
129
+ return JSON.parse(raw);
130
+ }
131
+ async function writeRegistry(state) {
132
+ await mkdir(dirname(state.file), { recursive: true });
133
+ const payload = { v: REGISTRY_VERSION, workspaces: state.workspaces };
134
+ const temporary = `${state.file}.tmp`;
135
+ await writeFile(temporary, `${JSON.stringify(payload, null, 4)}\n`, "utf8");
136
+ await rename(temporary, state.file);
137
+ }
138
+ /** 注册表文件损坏时挪到 .broken,按空表启动,避免拖垮整个服务 */
139
+ async function quarantine(state) {
140
+ try {
141
+ await rename(state.file, `${state.file}.broken`);
142
+ }
143
+ catch {
144
+ /* 文件可能已经不存在 */
145
+ }
146
+ }
147
+ /** 只导入旧版 wellspring-web 的索引;旧文件损坏就跳过,不影响启动 */
148
+ async function migrateLegacy(state) {
149
+ let raw;
150
+ try {
151
+ raw = await readJson(state.legacyFile);
152
+ }
153
+ catch {
154
+ return;
155
+ }
156
+ const entries = parseWorkspaceEntries(raw);
157
+ if (entries.length === 0) {
158
+ return;
159
+ }
160
+ state.workspaces = entries;
161
+ await writeRegistry(state);
162
+ }
163
+ async function ensureLoaded(state) {
164
+ if (state.loaded) {
165
+ return;
166
+ }
167
+ try {
168
+ const raw = await readJson(state.file);
169
+ state.workspaces = parseWorkspaceEntries(raw);
170
+ }
171
+ catch (error) {
172
+ const missing = typeof error === "object" &&
173
+ error !== null &&
174
+ error.code === "ENOENT";
175
+ if (missing) {
176
+ await migrateLegacy(state);
177
+ }
178
+ else {
179
+ await quarantine(state);
180
+ }
181
+ }
182
+ state.loaded = true;
183
+ }
184
+ function enqueue(state, task) {
185
+ const run = state.queue.then(task, task);
186
+ state.queue = run.catch(() => undefined);
187
+ return run;
188
+ }
189
+ /** 宿主内部:重置内存里的注册表(测试 / 重新配置路径时用) */
190
+ export function resetWorkspaceRegistry(paths) {
191
+ if (paths === undefined) {
192
+ states.clear();
193
+ return;
194
+ }
195
+ states.delete(workspaceRegistryFile(paths));
196
+ }
197
+ export async function listWorkspaces(paths = getPaths()) {
198
+ const state = stateFor(paths);
199
+ await ensureLoaded(state);
200
+ return { workspaces: state.workspaces.map((entry) => ({ ...entry })) };
201
+ }
202
+ function isDirectory(path) {
203
+ return stat(path).then((info) => info.isDirectory(), () => false);
204
+ }
205
+ /** root 必须是已存在的目录;重复添加返回已有记录并刷新 lastSeenAt */
206
+ export async function addWorkspace(options, paths = getPaths()) {
207
+ const rootRaw = typeof options.root === "string" ? options.root.trim() : "";
208
+ if (rootRaw === "") {
209
+ throw new Error("工作区路径不能为空");
210
+ }
211
+ const root = resolve(rootRaw);
212
+ if (!isAbsolute(root)) {
213
+ throw new Error("工作区路径必须是绝对路径");
214
+ }
215
+ if (!(await isDirectory(root))) {
216
+ throw new Error(`工作区目录不存在或不是目录:${root}`);
217
+ }
218
+ const requestedName = normalizeWorkspaceName(options.name);
219
+ if (options.name !== undefined && options.name !== "" && requestedName === null) {
220
+ throw new Error(`工作区名称需要 1-${MAX_WORKSPACE_NAME_CHARS} 个字符`);
221
+ }
222
+ const state = stateFor(paths);
223
+ await ensureLoaded(state);
224
+ return await enqueue(state, async () => {
225
+ const existing = state.workspaces.find((entry) => entry.root === root);
226
+ if (existing !== undefined) {
227
+ const touched = { ...existing, lastSeenAt: Date.now() };
228
+ state.workspaces = state.workspaces.map((entry) => entry.id === existing.id ? touched : entry);
229
+ await writeRegistry(state);
230
+ return { workspace: { ...touched }, duplicate: true };
231
+ }
232
+ if (state.workspaces.length >= MAX_WORKSPACES) {
233
+ throw new Error(`工作区数量已达上限(${MAX_WORKSPACES})`);
234
+ }
235
+ const now = Date.now();
236
+ const entry = {
237
+ id: workspaceIdFor(root),
238
+ name: requestedName ?? (basename(root) === "" ? "工作区" : basename(root)),
239
+ root,
240
+ createdAt: now,
241
+ lastSeenAt: now,
242
+ };
243
+ state.workspaces = [entry, ...state.workspaces];
244
+ await writeRegistry(state);
245
+ return { workspace: { ...entry }, duplicate: false };
246
+ });
247
+ }
248
+ export async function removeWorkspace(id, paths = getPaths()) {
249
+ const state = stateFor(paths);
250
+ await ensureLoaded(state);
251
+ return await enqueue(state, async () => {
252
+ const before = state.workspaces.length;
253
+ state.workspaces = state.workspaces.filter((entry) => entry.id !== id);
254
+ const removed = state.workspaces.length !== before;
255
+ if (removed) {
256
+ await writeRegistry(state);
257
+ }
258
+ return { removed };
259
+ });
260
+ }
261
+ export async function renameWorkspace(id, name, paths = getPaths()) {
262
+ const normalized = normalizeWorkspaceName(name);
263
+ if (normalized === null) {
264
+ throw new Error(`工作区名称需要 1-${MAX_WORKSPACE_NAME_CHARS} 个字符`);
265
+ }
266
+ const state = stateFor(paths);
267
+ await ensureLoaded(state);
268
+ return await enqueue(state, async () => {
269
+ const existing = state.workspaces.find((entry) => entry.id === id);
270
+ if (existing === undefined) {
271
+ return null;
272
+ }
273
+ const updated = { ...existing, name: normalized };
274
+ state.workspaces = state.workspaces.map((entry) => (entry.id === id ? updated : entry));
275
+ await writeRegistry(state);
276
+ return { ...updated };
277
+ });
278
+ }
279
+ export async function touchWorkspace(id, paths = getPaths()) {
280
+ const state = stateFor(paths);
281
+ await ensureLoaded(state);
282
+ return await enqueue(state, async () => {
283
+ const existing = state.workspaces.find((entry) => entry.id === id);
284
+ if (existing === undefined) {
285
+ return null;
286
+ }
287
+ const updated = { ...existing, lastSeenAt: Date.now() };
288
+ state.workspaces = state.workspaces.map((entry) => (entry.id === id ? updated : entry));
289
+ await writeRegistry(state);
290
+ return { ...updated };
291
+ });
292
+ }
293
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/workspace/registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,74 @@
1
1
  {
2
- "name": "@xyit/wellspring",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@xyit/wellspring",
3
+ "version": "1.0.0",
4
+ "description": "Wellspring 源泉 —— 插件式 Agent 平台与 CLI(Plugin-based AI agent platform and CLI)",
5
+ "keywords": [
6
+ "agent",
7
+ "ai",
8
+ "cli",
9
+ "llm",
10
+ "plugin",
11
+ "wellspring"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "xyit-team",
15
+ "bin": {
16
+ "wellspring": "./dist/index.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src",
21
+ "scripts",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "type": "module",
26
+ "main": "dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ },
33
+ "./api/host": {
34
+ "types": "./dist/api/host/index.d.ts",
35
+ "import": "./dist/api/host/index.js"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "scripts": {
43
+ "start": "node src/index.ts",
44
+ "test": "node --test test",
45
+ "typecheck": "tsc --noEmit",
46
+ "format": "oxfmt",
47
+ "format:check": "oxfmt --check",
48
+ "pty:build": "node scripts/build-node-pty.mjs",
49
+ "build:web-ui": "node plugins/wellspring-web/scripts/build-ui.mjs",
50
+ "typecheck:web-ui": "node plugins/wellspring-web/scripts/check-ui.mjs",
51
+ "build": "tsc -p tsconfig.build.json && node scripts/rewrite-dts.mjs",
52
+ "prepack": "npm run build"
53
+ },
54
+ "dependencies": {
55
+ "cli-highlight": "^2.1.11",
56
+ "markdansi": "^0.3.6",
57
+ "openai": "^7.39.0",
58
+ "pino": "^10.4.0",
59
+ "undici": "^8.12.3",
60
+ "ws": "^8.18.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^26.6.5",
64
+ "@types/ws": "^8.5.0",
65
+ "oxfmt": "^0.73.0",
66
+ "typescript": "^7.0.2"
67
+ },
68
+ "optionalDependencies": {
69
+ "node-pty": "^1.0.0"
70
+ },
71
+ "engines": {
72
+ "node": ">=24"
73
+ }
74
+ }
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * 用本机 Node 头文件重建 node-pty 原生模块。
4
+ *
5
+ * node-pty 没有 linux 预编译包,pnpm install 时会走 node-gyp;而 node-gyp 自带的
6
+ * 下载器在设置了 HTTP(S)_PROXY 的环境里与 Node 26 不兼容(安装日志里是
7
+ * "gyp ERR! InvalidArgumentError: invalid onError method"),于是 install 失败。
8
+ * 这里直接使用 Node 安装目录里自带的 include/node 头文件,跳过下载。
9
+ *
10
+ * 用法:pnpm pty:build
11
+ * 没装 node-pty 也没关系:终端会自动退回 python3 的 pty 实现。
12
+ */
13
+
14
+ import { spawnSync } from "node:child_process"
15
+ import { existsSync } from "node:fs"
16
+ import { dirname, join, resolve } from "node:path"
17
+
18
+ const repoRoot = resolve(import.meta.dirname, "..")
19
+ const nodeDir = resolve(dirname(process.execPath), "..")
20
+ const header = join(nodeDir, "include", "node", "node.h")
21
+ if (!existsSync(join(repoRoot, "node_modules", "node-pty"))) {
22
+ console.error("node_modules 里没有 node-pty:先执行 pnpm install。")
23
+ console.error("它不用能装成功也可以——终端会自动退回 python3 的 pty 实现。")
24
+ process.exit(1)
25
+ }
26
+ if (!existsSync(header)) {
27
+ console.error(`找不到 Node 头文件:${header}`)
28
+ console.error("当前 Node 安装没有附带 include/node,无法编译 node-pty。")
29
+ console.error("终端仍可使用:宿主会自动退回 python3 的 pty 实现。")
30
+ process.exit(1)
31
+ }
32
+
33
+ console.log(`使用本地 Node 头文件重建 node-pty:${nodeDir}`)
34
+ const pnpm = process.platform === "win32" ? "pnpm.cmd" : "pnpm"
35
+ const result = spawnSync(pnpm, ["rebuild", "node-pty"], {
36
+ stdio: "inherit",
37
+ env: { ...process.env, npm_config_nodedir: nodeDir },
38
+ })
39
+ if (result.status !== 0) {
40
+ console.error("node-pty 重建失败;终端会自动退回 python3 的 pty 实现。")
41
+ process.exit(result.status ?? 1)
42
+ }
43
+
44
+ try {
45
+ const pty = await import("node-pty")
46
+ if (typeof pty.spawn !== "function") {
47
+ throw new Error("node-pty 没有导出 spawn")
48
+ }
49
+ console.log("node-pty 原生模块可用")
50
+ } catch (error) {
51
+ console.error(
52
+ `node-pty 仍然无法加载:${error instanceof Error ? error.message : String(error)}`,
53
+ )
54
+ process.exit(1)
55
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ * tsc 的 rewriteRelativeImportExtensions 只改 JS,.d.ts 里仍然保留 ".ts"。
3
+ * 声明文件是给消费者 tsc 看的;带 .ts 后缀的相对导入会要求对方打开
4
+ * allowImportingTsExtensions,所以发布前统一改回 .js。
5
+ */
6
+
7
+ import { readdir, readFile, writeFile } from "node:fs/promises"
8
+ import { join } from "node:path"
9
+ import { fileURLToPath } from "node:url"
10
+
11
+ const DIST = fileURLToPath(new URL("../dist/", import.meta.url))
12
+
13
+ async function declarations(dir) {
14
+ const entries = await readdir(dir, { withFileTypes: true })
15
+ const files = []
16
+ for (const entry of entries) {
17
+ const path = join(dir, entry.name)
18
+ if (entry.isDirectory()) {
19
+ files.push(...(await declarations(path)))
20
+ } else if (entry.name.endsWith(".d.ts")) {
21
+ files.push(path)
22
+ }
23
+ }
24
+ return files
25
+ }
26
+
27
+ let rewritten = 0
28
+ for (const file of await declarations(DIST)) {
29
+ const source = await readFile(file, "utf8")
30
+ const next = source.replace(/(["'])(\.{1,2}\/[^"']+)\.ts\1/g, "$1$2.js$1")
31
+ if (next !== source) {
32
+ await writeFile(file, next)
33
+ rewritten += 1
34
+ }
35
+ }
36
+ console.log(`声明文件已重写:${rewritten} 个`)
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * 真实 bwrap 隔离验证脚本。
4
+ * 在允许非特权 user namespace 的 Linux 上运行:node scripts/verify-sandbox.ts
5
+ */
6
+
7
+ import { mkdtemp, rm } from "node:fs/promises"
8
+ import { tmpdir } from "node:os"
9
+ import { join } from "node:path"
10
+
11
+ import { DEFAULT_SETTINGS } from "../src/config/defaults.ts"
12
+ import { getPaths, initPaths } from "../src/platform/path.ts"
13
+ import { SandboxManager } from "../src/sandbox/manager.ts"
14
+
15
+ initPaths()
16
+ const manager = new SandboxManager({
17
+ settings: { ...DEFAULT_SETTINGS.sandbox, mode: "strict", backend: "auto" },
18
+ paths: getPaths(),
19
+ })
20
+
21
+ const probe = await manager.probe()
22
+ console.log("probe:", probe)
23
+ if (!probe.available) {
24
+ console.error("\nbwrap 不可用,先确认:")
25
+ console.error(" unshare -Ur true")
26
+ console.error(" bwrap --unshare-all --ro-bind / / --dev /dev --proc /proc /bin/true")
27
+ console.error(
28
+ "Ubuntu 24.04 可能被 AppArmor 限制:sysctl kernel.apparmor_restrict_unprivileged_userns",
29
+ )
30
+ process.exit(1)
31
+ }
32
+
33
+ const workspace = await mkdtemp(join(tmpdir(), "wellspring-verify-"))
34
+ let failed = 0
35
+
36
+ async function run(
37
+ name: string,
38
+ command: string,
39
+ argv: string[],
40
+ expect: (exitCode: number | null, stdout: string, stderr: string) => boolean,
41
+ ): Promise<void> {
42
+ const result = await manager.runAgentCode({
43
+ command,
44
+ argv,
45
+ workspaceDir: workspace,
46
+ timeoutMs: 15_000,
47
+ })
48
+ const ok = expect(result.exitCode, result.stdout, result.stderr)
49
+ if (!ok) {
50
+ failed += 1
51
+ }
52
+ console.log(`\n[${ok ? "PASS" : "FAIL"}] ${name}`)
53
+ console.log(` exit=${String(result.exitCode)} backend=${result.backend}`)
54
+ console.log(` stdout=${result.stdout.trim()}`)
55
+ if (result.stderr.trim() !== "") {
56
+ console.log(` stderr=${result.stderr.trim()}`)
57
+ }
58
+ }
59
+
60
+ try {
61
+ await run("读取 /etc/shadow 应失败", "/usr/bin/cat", ["/etc/shadow"], (code) => code !== 0)
62
+
63
+ await run(
64
+ "写 workspace 应失败(只读挂载)",
65
+ "/bin/sh",
66
+ ["-c", "echo escape > escape.txt"],
67
+ (code) => code !== 0,
68
+ )
69
+
70
+ await run(
71
+ "写 scratch 应成功",
72
+ "/bin/sh",
73
+ ["-c", 'echo ok > "$SCRATCH/t.txt" && cat "$SCRATCH/t.txt"'],
74
+ (_code, stdout) => stdout.includes("ok"),
75
+ )
76
+
77
+ await run(
78
+ "网络应被拒绝",
79
+ "node",
80
+ [
81
+ "-e",
82
+ "fetch('http://1.1.1.1', {signal: AbortSignal.timeout(2000)}).then(() => { console.log('network-ok'); process.exit(2) }).catch((e) => { console.log('network-blocked:' + e.message); process.exit(0) })",
83
+ ],
84
+ (_code, stdout) => stdout.includes("network-blocked"),
85
+ )
86
+
87
+ await run(
88
+ "读取宿主源码应失败",
89
+ "/usr/bin/cat",
90
+ [join(process.cwd(), "src", "index.ts")],
91
+ (code) => code !== 0,
92
+ )
93
+ } finally {
94
+ await rm(workspace, { recursive: true, force: true })
95
+ }
96
+
97
+ console.log(failed === 0 ? "\n所有 sandbox 检查通过" : `\n${failed} 个检查失败`)
98
+ process.exit(failed === 0 ? 0 : 1)
@@ -0,0 +1,88 @@
1
+ /*
2
+ * Agent 提问:ask 工具把问题交给界面,等待用户回答后把答案还回工具循环。
3
+ * 和提权审批一样是“一轮对话中途停下来等人”的机制,只是不需要权限判断。
4
+ */
5
+
6
+ import { randomUUID } from "node:crypto"
7
+
8
+ /** 等待用户回答的上限;超时后工具返回“没有回答”并继续 */
9
+ export const ASK_TIMEOUT_MS = 5 * 60_000
10
+
11
+ interface PendingAsk {
12
+ readonly sessionId: string
13
+ readonly resolve: (answer: string | null) => void
14
+ readonly timer: NodeJS.Timeout
15
+ }
16
+
17
+ const pending = new Map<string, PendingAsk>()
18
+
19
+ export function createAskId(): string {
20
+ return `ask_${randomUUID()}`
21
+ }
22
+
23
+ /**
24
+ * 登记一个等待回答的问题。answerAsk 先把 answer 交给这个 Promise;
25
+ * 超时兑现 null(用户没回答)。
26
+ */
27
+ export function waitForAsk(input: {
28
+ readonly askId: string
29
+ readonly sessionId: string
30
+ readonly timeoutMs?: number
31
+ }): Promise<string | null> {
32
+ return new Promise<string | null>((resolvePromise) => {
33
+ let settled = false
34
+ let timer: NodeJS.Timeout | null = null
35
+ const finish = (answer: string | null): void => {
36
+ if (settled) {
37
+ return
38
+ }
39
+ settled = true
40
+ if (timer !== null) {
41
+ clearTimeout(timer)
42
+ }
43
+ pending.delete(input.askId)
44
+ resolvePromise(answer)
45
+ }
46
+ timer = setTimeout(() => {
47
+ finish(null)
48
+ }, input.timeoutMs ?? ASK_TIMEOUT_MS)
49
+ pending.set(input.askId, {
50
+ sessionId: input.sessionId,
51
+ resolve: finish,
52
+ timer,
53
+ })
54
+ })
55
+ }
56
+
57
+ /** 用户回答;命中等待中的问题时返回 true */
58
+ export function answerAsk(askId: string, answer: string): boolean {
59
+ const entry = pending.get(askId)
60
+ if (entry === undefined) {
61
+ return false
62
+ }
63
+ entry.resolve(answer)
64
+ return true
65
+ }
66
+
67
+ /** 取消一次等待(工具循环收尾、异常退出时调用) */
68
+ export function cancelAsk(askId: string): void {
69
+ const entry = pending.get(askId)
70
+ if (entry === undefined) {
71
+ return
72
+ }
73
+ entry.resolve(null)
74
+ }
75
+
76
+ /** 会话结束时清掉遗留的等待 */
77
+ export function cancelSessionAsks(sessionId: string): void {
78
+ for (const [askId, entry] of [...pending]) {
79
+ if (entry.sessionId === sessionId) {
80
+ cancelAsk(askId)
81
+ }
82
+ }
83
+ }
84
+
85
+ /** 当前等待回答的数量(测试与诊断用) */
86
+ export function pendingAskCount(): number {
87
+ return pending.size
88
+ }