@xyit/wellspring 0.0.0-stage → 1.1.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 (464) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +853 -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 +49 -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 +190 -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 +17 -0
  241. package/dist/plugin/install.js +163 -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 +271 -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/package-manager.d.ts +46 -0
  256. package/dist/plugin/package-manager.js +148 -0
  257. package/dist/plugin/package-manager.js.map +1 -0
  258. package/dist/plugin/paths.d.ts +6 -0
  259. package/dist/plugin/paths.js +15 -0
  260. package/dist/plugin/paths.js.map +1 -0
  261. package/dist/plugin/registry.d.ts +17 -0
  262. package/dist/plugin/registry.js +82 -0
  263. package/dist/plugin/registry.js.map +1 -0
  264. package/dist/plugin/runtime.d.ts +9 -0
  265. package/dist/plugin/runtime.js +43 -0
  266. package/dist/plugin/runtime.js.map +1 -0
  267. package/dist/plugin/scaffold.d.ts +13 -0
  268. package/dist/plugin/scaffold.js +132 -0
  269. package/dist/plugin/scaffold.js.map +1 -0
  270. package/dist/plugin/state.d.ts +6 -0
  271. package/dist/plugin/state.js +38 -0
  272. package/dist/plugin/state.js.map +1 -0
  273. package/dist/plugin/zip.d.ts +7 -0
  274. package/dist/plugin/zip.js +138 -0
  275. package/dist/plugin/zip.js.map +1 -0
  276. package/dist/sandbox/audit.d.ts +12 -0
  277. package/dist/sandbox/audit.js +20 -0
  278. package/dist/sandbox/audit.js.map +1 -0
  279. package/dist/sandbox/backends/bwrap.d.ts +28 -0
  280. package/dist/sandbox/backends/bwrap.js +197 -0
  281. package/dist/sandbox/backends/bwrap.js.map +1 -0
  282. package/dist/sandbox/backends/direct.d.ts +7 -0
  283. package/dist/sandbox/backends/direct.js +32 -0
  284. package/dist/sandbox/backends/direct.js.map +1 -0
  285. package/dist/sandbox/bridge-state.d.ts +13 -0
  286. package/dist/sandbox/bridge-state.js +12 -0
  287. package/dist/sandbox/bridge-state.js.map +1 -0
  288. package/dist/sandbox/index.d.ts +5 -0
  289. package/dist/sandbox/index.js +6 -0
  290. package/dist/sandbox/index.js.map +1 -0
  291. package/dist/sandbox/manager.d.ts +8 -0
  292. package/dist/sandbox/manager.js +325 -0
  293. package/dist/sandbox/manager.js.map +1 -0
  294. package/dist/sandbox/memory-limit.d.ts +44 -0
  295. package/dist/sandbox/memory-limit.js +193 -0
  296. package/dist/sandbox/memory-limit.js.map +1 -0
  297. package/dist/sandbox/plugin-client.d.ts +80 -0
  298. package/dist/sandbox/plugin-client.js +1601 -0
  299. package/dist/sandbox/plugin-client.js.map +1 -0
  300. package/dist/sandbox/plugin-host.d.ts +1 -0
  301. package/dist/sandbox/plugin-host.js +1001 -0
  302. package/dist/sandbox/plugin-host.js.map +1 -0
  303. package/dist/sandbox/protocol.d.ts +43 -0
  304. package/dist/sandbox/protocol.js +96 -0
  305. package/dist/sandbox/protocol.js.map +1 -0
  306. package/dist/sandbox/rpc-timeouts.d.ts +28 -0
  307. package/dist/sandbox/rpc-timeouts.js +15 -0
  308. package/dist/sandbox/rpc-timeouts.js.map +1 -0
  309. package/dist/sandbox/supervisor.d.ts +31 -0
  310. package/dist/sandbox/supervisor.js +114 -0
  311. package/dist/sandbox/supervisor.js.map +1 -0
  312. package/dist/sandbox/types.d.ts +124 -0
  313. package/dist/sandbox/types.js +17 -0
  314. package/dist/sandbox/types.js.map +1 -0
  315. package/dist/service/control.d.ts +32 -0
  316. package/dist/service/control.js +117 -0
  317. package/dist/service/control.js.map +1 -0
  318. package/dist/session/compress.d.ts +3 -0
  319. package/dist/session/compress.js +42 -0
  320. package/dist/session/compress.js.map +1 -0
  321. package/dist/session/index.d.ts +4 -0
  322. package/dist/session/index.js +8 -0
  323. package/dist/session/index.js.map +1 -0
  324. package/dist/session/registry.d.ts +4 -0
  325. package/dist/session/registry.js +12 -0
  326. package/dist/session/registry.js.map +1 -0
  327. package/dist/session/replay.d.ts +10 -0
  328. package/dist/session/replay.js +109 -0
  329. package/dist/session/replay.js.map +1 -0
  330. package/dist/session/session.d.ts +40 -0
  331. package/dist/session/session.js +108 -0
  332. package/dist/session/session.js.map +1 -0
  333. package/dist/session/store.d.ts +58 -0
  334. package/dist/session/store.js +382 -0
  335. package/dist/session/store.js.map +1 -0
  336. package/dist/session/types.d.ts +56 -0
  337. package/dist/session/types.js +3 -0
  338. package/dist/session/types.js.map +1 -0
  339. package/dist/workspace/index.d.ts +7 -0
  340. package/dist/workspace/index.js +17 -0
  341. package/dist/workspace/index.js.map +1 -0
  342. package/dist/workspace/registry.d.ts +25 -0
  343. package/dist/workspace/registry.js +293 -0
  344. package/dist/workspace/registry.js.map +1 -0
  345. package/package.json +73 -5
  346. package/scripts/build-node-pty.mjs +55 -0
  347. package/scripts/rewrite-dts.mjs +36 -0
  348. package/scripts/run-tests.mjs +41 -0
  349. package/scripts/verify-sandbox.ts +98 -0
  350. package/src/agent/pending-asks.ts +88 -0
  351. package/src/agent/task-registry.ts +108 -0
  352. package/src/agent/tool-context.ts +47 -0
  353. package/src/agent/usage.ts +170 -0
  354. package/src/api/host/agent.ts +162 -0
  355. package/src/api/host/events.ts +7 -0
  356. package/src/api/host/exec.ts +47 -0
  357. package/src/api/host/fs.ts +33 -0
  358. package/src/api/host/hooks.ts +635 -0
  359. package/src/api/host/host.ts +99 -0
  360. package/src/api/host/http.ts +79 -0
  361. package/src/api/host/index.ts +20 -0
  362. package/src/api/host/models.ts +81 -0
  363. package/src/api/host/network.ts +32 -0
  364. package/src/api/host/plugin.ts +158 -0
  365. package/src/api/host/plugins.ts +59 -0
  366. package/src/api/host/pty.ts +73 -0
  367. package/src/api/host/session.ts +61 -0
  368. package/src/api/host/version.ts +2 -0
  369. package/src/api/host/workspace.ts +51 -0
  370. package/src/api/plugin/http-client.ts +492 -0
  371. package/src/api/plugin/http-protocol.ts +231 -0
  372. package/src/api/result/result.ts +52 -0
  373. package/src/commands/agent-turn.ts +817 -0
  374. package/src/commands/ask-prompt.ts +52 -0
  375. package/src/commands/config.ts +306 -0
  376. package/src/commands/conversation.ts +777 -0
  377. package/src/commands/doctor.ts +92 -0
  378. package/src/commands/exec-approval.ts +91 -0
  379. package/src/commands/help.ts +41 -0
  380. package/src/commands/key.ts +281 -0
  381. package/src/commands/plugin.ts +222 -0
  382. package/src/commands/session.ts +179 -0
  383. package/src/commands/shared.ts +103 -0
  384. package/src/commands/start.ts +88 -0
  385. package/src/commands/stop.ts +24 -0
  386. package/src/commands/version.ts +40 -0
  387. package/src/config/codes.ts +17 -0
  388. package/src/config/credentials.ts +302 -0
  389. package/src/config/defaults.ts +32 -0
  390. package/src/config/index.ts +10 -0
  391. package/src/config/loader.ts +80 -0
  392. package/src/config/providers.ts +133 -0
  393. package/src/config/types.ts +88 -0
  394. package/src/config/validate.ts +458 -0
  395. package/src/display/markdown.ts +137 -0
  396. package/src/display/tool-label.ts +87 -0
  397. package/src/event/event.ts +171 -0
  398. package/src/index.ts +344 -0
  399. package/src/input/codes.ts +21 -0
  400. package/src/input/commands.ts +76 -0
  401. package/src/input/help.ts +60 -0
  402. package/src/input/index.ts +10 -0
  403. package/src/input/parse-options.ts +66 -0
  404. package/src/input/parse.ts +138 -0
  405. package/src/input/types.ts +19 -0
  406. package/src/logger/elog4js.ts +366 -0
  407. package/src/logger/logger.ts +251 -0
  408. package/src/network/index.ts +6 -0
  409. package/src/network/openai.ts +571 -0
  410. package/src/network/proxy.ts +80 -0
  411. package/src/network/web.ts +206 -0
  412. package/src/platform/clipboard.ts +107 -0
  413. package/src/platform/exec.ts +128 -0
  414. package/src/platform/file.ts +235 -0
  415. package/src/platform/index.ts +12 -0
  416. package/src/platform/notification.ts +108 -0
  417. package/src/platform/open-external.ts +132 -0
  418. package/src/platform/os.ts +101 -0
  419. package/src/platform/path.ts +214 -0
  420. package/src/plugin/access-guard.ts +46 -0
  421. package/src/plugin/agent-service.ts +969 -0
  422. package/src/plugin/agent-tools.ts +43 -0
  423. package/src/plugin/capabilities.ts +240 -0
  424. package/src/plugin/console-guard.ts +66 -0
  425. package/src/plugin/data-access.ts +70 -0
  426. package/src/plugin/fs.ts +109 -0
  427. package/src/plugin/host-alias.ts +61 -0
  428. package/src/plugin/index.ts +11 -0
  429. package/src/plugin/install.ts +213 -0
  430. package/src/plugin/loader.ts +952 -0
  431. package/src/plugin/manage.ts +338 -0
  432. package/src/plugin/models-service.ts +383 -0
  433. package/src/plugin/network-service.ts +102 -0
  434. package/src/plugin/package-manager.ts +214 -0
  435. package/src/plugin/paths.ts +19 -0
  436. package/src/plugin/registry.ts +103 -0
  437. package/src/plugin/runtime.ts +57 -0
  438. package/src/plugin/scaffold.ts +158 -0
  439. package/src/plugin/state.ts +52 -0
  440. package/src/plugin/zip.ts +156 -0
  441. package/src/sandbox/audit.ts +38 -0
  442. package/src/sandbox/backends/bwrap.ts +251 -0
  443. package/src/sandbox/backends/direct.ts +43 -0
  444. package/src/sandbox/bridge-state.ts +29 -0
  445. package/src/sandbox/index.ts +5 -0
  446. package/src/sandbox/manager.ts +406 -0
  447. package/src/sandbox/memory-limit.ts +245 -0
  448. package/src/sandbox/plugin-client.ts +1881 -0
  449. package/src/sandbox/plugin-host.ts +1282 -0
  450. package/src/sandbox/protocol.ts +142 -0
  451. package/src/sandbox/pty-bridge.py +154 -0
  452. package/src/sandbox/rpc-timeouts.ts +43 -0
  453. package/src/sandbox/supervisor.ts +172 -0
  454. package/src/sandbox/types.ts +149 -0
  455. package/src/service/control.ts +155 -0
  456. package/src/session/compress.ts +47 -0
  457. package/src/session/index.ts +8 -0
  458. package/src/session/registry.ts +17 -0
  459. package/src/session/replay.ts +132 -0
  460. package/src/session/session.ts +134 -0
  461. package/src/session/store.ts +468 -0
  462. package/src/session/types.ts +61 -0
  463. package/src/workspace/index.ts +21 -0
  464. 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.1.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 scripts/run-tests.mjs",
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,41 @@
1
+ /*
2
+ * 跨平台的测试入口:显式列出 test/ 下的 *.test.ts / *.test.mjs。
3
+ *
4
+ * 不用 `node --test test`:Node 24 不接受目录参数;
5
+ * 也不用 `node --test` 的默认发现规则:不同 Node 版本对 .ts 的发现范围不一致。
6
+ */
7
+
8
+ import { spawnSync } from "node:child_process"
9
+ import { readdirSync } from "node:fs"
10
+ import { join } from "node:path"
11
+ import { fileURLToPath } from "node:url"
12
+
13
+ const TEST_ROOT = fileURLToPath(new URL("../test/", import.meta.url))
14
+
15
+ function collect(dir) {
16
+ const files = []
17
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
18
+ const path = join(dir, entry.name)
19
+ if (entry.isDirectory()) {
20
+ files.push(...collect(path))
21
+ } else if (entry.name.endsWith(".test.ts") || entry.name.endsWith(".test.mjs")) {
22
+ files.push(path)
23
+ }
24
+ }
25
+ return files
26
+ }
27
+
28
+ const files = collect(TEST_ROOT).sort()
29
+ if (files.length === 0) {
30
+ console.error("没有找到测试文件")
31
+ process.exit(1)
32
+ }
33
+ /*
34
+ * 串行跑测试文件:GitHub 的 4 核 runner 上并发跑插件 sandbox 相关文件时,
35
+ * Node 24 会在 InternalCallbackScope 里触发原生断言(异步上下文 id 非 0)。
36
+ * 串行更稳,代价只是几十秒。
37
+ */
38
+ const result = spawnSync(process.execPath, ["--test", "--test-concurrency=1", ...files], {
39
+ stdio: "inherit",
40
+ })
41
+ process.exit(result.status ?? 1)
@@ -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)