@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,356 @@
1
+ /*
2
+ * 宿主级工作区注册表。
3
+ *
4
+ * 工作区(用户手动添加的目录)由宿主统一管理,存在 <dataDir>/workspaces.json;
5
+ * 插件通过 `api.workspaces` 读写,不再各自解析别的插件的数据目录。
6
+ *
7
+ * 首次加载时兼容迁移旧版 wellspring-web 插件数据目录里的 workspaces.json:
8
+ * 只读取 id / name / root / createdAt / lastSeenAt 这些索引字段,不碰会话正文与认证数据。
9
+ */
10
+
11
+ import { createHash } from "node:crypto"
12
+ import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises"
13
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path"
14
+
15
+ import type { ResolvedPaths } from "../platform/path.ts"
16
+ import { getPaths } from "../platform/path.ts"
17
+ import type {
18
+ HostWorkspaceAddResult,
19
+ HostWorkspaceEntry,
20
+ HostWorkspaceListResult,
21
+ } from "../api/host/workspace.ts"
22
+
23
+ const REGISTRY_VERSION = 1
24
+ const REGISTRY_FILE = "workspaces.json"
25
+ const LEGACY_PLUGIN_DIR = "wellspring-web"
26
+
27
+ export const MAX_WORKSPACES = 40
28
+ export const MAX_WORKSPACE_NAME_CHARS = 60
29
+ export const WORKSPACE_ID = /^[a-z0-9][a-z0-9-]{0,63}$/
30
+
31
+ interface RegistryFile {
32
+ readonly v: number
33
+ readonly workspaces: readonly HostWorkspaceEntry[]
34
+ }
35
+
36
+ interface RegistryState {
37
+ readonly file: string
38
+ readonly legacyFile: string
39
+ workspaces: HostWorkspaceEntry[]
40
+ loaded: boolean
41
+ queue: Promise<unknown>
42
+ }
43
+
44
+ const states = new Map<string, RegistryState>()
45
+
46
+ export function workspaceRegistryFile(paths: ResolvedPaths = getPaths()): string {
47
+ return join(paths.dataDir, REGISTRY_FILE)
48
+ }
49
+
50
+ export function legacyWorkspaceRegistryFile(paths: ResolvedPaths = getPaths()): string {
51
+ return join(paths.dataDir, "plugin-data", LEGACY_PLUGIN_DIR, REGISTRY_FILE)
52
+ }
53
+
54
+ /** 由工作目录派生稳定 id(与旧版 wellspring-web 的算法一致,保证会话目录还能对上) */
55
+ export function workspaceIdFor(root: string): string {
56
+ const slug = basename(root)
57
+ .toLowerCase()
58
+ .replace(/[^a-z0-9-]+/g, "-")
59
+ .replace(/^-+|-+$/g, "")
60
+ .slice(0, 24)
61
+ const hash = createHash("sha256").update(root).digest("hex").slice(0, 10)
62
+ return slug === "" ? `workspace-${hash}` : `${slug}-${hash}`
63
+ }
64
+
65
+ export function normalizeWorkspaceName(value: unknown): string | null {
66
+ if (typeof value !== "string") {
67
+ return null
68
+ }
69
+ const name = value
70
+ .replace(/[\u0000-\u001f\u007f]/g, " ")
71
+ .replace(/\s+/g, " ")
72
+ .trim()
73
+ if (name === "" || name.length > MAX_WORKSPACE_NAME_CHARS) {
74
+ return null
75
+ }
76
+ return name
77
+ }
78
+
79
+ function finiteTimestamp(value: unknown, fallback: number): number {
80
+ return typeof value === "number" && Number.isFinite(value) && value >= 0
81
+ ? Math.floor(value)
82
+ : fallback
83
+ }
84
+
85
+ function normalizeEntry(value: unknown, fallbackId: string): HostWorkspaceEntry | null {
86
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
87
+ return null
88
+ }
89
+ const record = value as Record<string, unknown>
90
+ const rootRaw = record["root"]
91
+ if (typeof rootRaw !== "string" || rootRaw.trim() === "") {
92
+ return null
93
+ }
94
+ const root = resolve(rootRaw.trim())
95
+ const rawId = record["id"]
96
+ const id = typeof rawId === "string" && WORKSPACE_ID.test(rawId) ? rawId : fallbackId
97
+ const rawName = record["name"]
98
+ const name =
99
+ normalizeWorkspaceName(rawName) ?? (basename(root) === "" ? "工作区" : basename(root))
100
+ const now = Date.now()
101
+ return {
102
+ id,
103
+ name,
104
+ root,
105
+ createdAt: finiteTimestamp(record["createdAt"], now),
106
+ lastSeenAt: finiteTimestamp(record["lastSeenAt"], now),
107
+ }
108
+ }
109
+
110
+ /** 解析注册表文件;接受 { v, workspaces } 与旧版纯数组,非法条目忽略 */
111
+ export function parseWorkspaceEntries(value: unknown): HostWorkspaceEntry[] {
112
+ let list: unknown = value
113
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
114
+ list = (value as Record<string, unknown>)["workspaces"]
115
+ }
116
+ if (!Array.isArray(list)) {
117
+ return []
118
+ }
119
+ const entries: HostWorkspaceEntry[] = []
120
+ const seenIds = new Set<string>()
121
+ const seenRoots = new Set<string>()
122
+ for (const item of list) {
123
+ if (entries.length >= MAX_WORKSPACES) {
124
+ break
125
+ }
126
+ const rawRoot =
127
+ typeof item === "object" && item !== null
128
+ ? (item as Record<string, unknown>)["root"]
129
+ : undefined
130
+ const fallbackId = typeof rawRoot === "string" ? workspaceIdFor(resolve(rawRoot)) : ""
131
+ const entry = normalizeEntry(item, fallbackId)
132
+ if (entry === null || entry.id === "") {
133
+ continue
134
+ }
135
+ if (seenIds.has(entry.id) || seenRoots.has(entry.root)) {
136
+ continue
137
+ }
138
+ seenIds.add(entry.id)
139
+ seenRoots.add(entry.root)
140
+ entries.push(entry)
141
+ }
142
+ return entries
143
+ }
144
+
145
+ function stateFor(paths: ResolvedPaths): RegistryState {
146
+ const file = workspaceRegistryFile(paths)
147
+ const existing = states.get(file)
148
+ if (existing !== undefined) {
149
+ return existing
150
+ }
151
+ const state: RegistryState = {
152
+ file,
153
+ legacyFile: legacyWorkspaceRegistryFile(paths),
154
+ workspaces: [],
155
+ loaded: false,
156
+ queue: Promise.resolve(),
157
+ }
158
+ states.set(file, state)
159
+ return state
160
+ }
161
+
162
+ async function readJson(path: string): Promise<unknown> {
163
+ const raw = await readFile(path, "utf8")
164
+ return JSON.parse(raw)
165
+ }
166
+
167
+ async function writeRegistry(state: RegistryState): Promise<void> {
168
+ await mkdir(dirname(state.file), { recursive: true })
169
+ const payload: RegistryFile = { v: REGISTRY_VERSION, workspaces: state.workspaces }
170
+ const temporary = `${state.file}.tmp`
171
+ await writeFile(temporary, `${JSON.stringify(payload, null, 4)}\n`, "utf8")
172
+ await rename(temporary, state.file)
173
+ }
174
+
175
+ /** 注册表文件损坏时挪到 .broken,按空表启动,避免拖垮整个服务 */
176
+ async function quarantine(state: RegistryState): Promise<void> {
177
+ try {
178
+ await rename(state.file, `${state.file}.broken`)
179
+ } catch {
180
+ /* 文件可能已经不存在 */
181
+ }
182
+ }
183
+
184
+ /** 只导入旧版 wellspring-web 的索引;旧文件损坏就跳过,不影响启动 */
185
+ async function migrateLegacy(state: RegistryState): Promise<void> {
186
+ let raw: unknown
187
+ try {
188
+ raw = await readJson(state.legacyFile)
189
+ } catch {
190
+ return
191
+ }
192
+ const entries = parseWorkspaceEntries(raw)
193
+ if (entries.length === 0) {
194
+ return
195
+ }
196
+ state.workspaces = entries
197
+ await writeRegistry(state)
198
+ }
199
+
200
+ async function ensureLoaded(state: RegistryState): Promise<void> {
201
+ if (state.loaded) {
202
+ return
203
+ }
204
+ try {
205
+ const raw = await readJson(state.file)
206
+ state.workspaces = parseWorkspaceEntries(raw)
207
+ } catch (error) {
208
+ const missing =
209
+ typeof error === "object" &&
210
+ error !== null &&
211
+ (error as NodeJS.ErrnoException).code === "ENOENT"
212
+ if (missing) {
213
+ await migrateLegacy(state)
214
+ } else {
215
+ await quarantine(state)
216
+ }
217
+ }
218
+ state.loaded = true
219
+ }
220
+
221
+ function enqueue<T>(state: RegistryState, task: () => Promise<T>): Promise<T> {
222
+ const run = state.queue.then(task, task)
223
+ state.queue = run.catch(() => undefined)
224
+ return run
225
+ }
226
+
227
+ /** 宿主内部:重置内存里的注册表(测试 / 重新配置路径时用) */
228
+ export function resetWorkspaceRegistry(paths?: ResolvedPaths): void {
229
+ if (paths === undefined) {
230
+ states.clear()
231
+ return
232
+ }
233
+ states.delete(workspaceRegistryFile(paths))
234
+ }
235
+
236
+ export async function listWorkspaces(
237
+ paths: ResolvedPaths = getPaths(),
238
+ ): Promise<HostWorkspaceListResult> {
239
+ const state = stateFor(paths)
240
+ await ensureLoaded(state)
241
+ return { workspaces: state.workspaces.map((entry) => ({ ...entry })) }
242
+ }
243
+
244
+ function isDirectory(path: string): Promise<boolean> {
245
+ return stat(path).then(
246
+ (info) => info.isDirectory(),
247
+ () => false,
248
+ )
249
+ }
250
+
251
+ /** root 必须是已存在的目录;重复添加返回已有记录并刷新 lastSeenAt */
252
+ export async function addWorkspace(
253
+ options: { readonly root: string; readonly name?: string },
254
+ paths: ResolvedPaths = getPaths(),
255
+ ): Promise<HostWorkspaceAddResult> {
256
+ const rootRaw = typeof options.root === "string" ? options.root.trim() : ""
257
+ if (rootRaw === "") {
258
+ throw new Error("工作区路径不能为空")
259
+ }
260
+ const root = resolve(rootRaw)
261
+ if (!isAbsolute(root)) {
262
+ throw new Error("工作区路径必须是绝对路径")
263
+ }
264
+ if (!(await isDirectory(root))) {
265
+ throw new Error(`工作区目录不存在或不是目录:${root}`)
266
+ }
267
+ const requestedName = normalizeWorkspaceName(options.name)
268
+ if (options.name !== undefined && options.name !== "" && requestedName === null) {
269
+ throw new Error(`工作区名称需要 1-${MAX_WORKSPACE_NAME_CHARS} 个字符`)
270
+ }
271
+ const state = stateFor(paths)
272
+ await ensureLoaded(state)
273
+ return await enqueue(state, async () => {
274
+ const existing = state.workspaces.find((entry) => entry.root === root)
275
+ if (existing !== undefined) {
276
+ const touched: HostWorkspaceEntry = { ...existing, lastSeenAt: Date.now() }
277
+ state.workspaces = state.workspaces.map((entry) =>
278
+ entry.id === existing.id ? touched : entry,
279
+ )
280
+ await writeRegistry(state)
281
+ return { workspace: { ...touched }, duplicate: true }
282
+ }
283
+ if (state.workspaces.length >= MAX_WORKSPACES) {
284
+ throw new Error(`工作区数量已达上限(${MAX_WORKSPACES})`)
285
+ }
286
+ const now = Date.now()
287
+ const entry: HostWorkspaceEntry = {
288
+ id: workspaceIdFor(root),
289
+ name: requestedName ?? (basename(root) === "" ? "工作区" : basename(root)),
290
+ root,
291
+ createdAt: now,
292
+ lastSeenAt: now,
293
+ }
294
+ state.workspaces = [entry, ...state.workspaces]
295
+ await writeRegistry(state)
296
+ return { workspace: { ...entry }, duplicate: false }
297
+ })
298
+ }
299
+
300
+ export async function removeWorkspace(
301
+ id: string,
302
+ paths: ResolvedPaths = getPaths(),
303
+ ): Promise<{ readonly removed: boolean }> {
304
+ const state = stateFor(paths)
305
+ await ensureLoaded(state)
306
+ return await enqueue(state, async () => {
307
+ const before = state.workspaces.length
308
+ state.workspaces = state.workspaces.filter((entry) => entry.id !== id)
309
+ const removed = state.workspaces.length !== before
310
+ if (removed) {
311
+ await writeRegistry(state)
312
+ }
313
+ return { removed }
314
+ })
315
+ }
316
+
317
+ export async function renameWorkspace(
318
+ id: string,
319
+ name: string,
320
+ paths: ResolvedPaths = getPaths(),
321
+ ): Promise<HostWorkspaceEntry | null> {
322
+ const normalized = normalizeWorkspaceName(name)
323
+ if (normalized === null) {
324
+ throw new Error(`工作区名称需要 1-${MAX_WORKSPACE_NAME_CHARS} 个字符`)
325
+ }
326
+ const state = stateFor(paths)
327
+ await ensureLoaded(state)
328
+ return await enqueue(state, async () => {
329
+ const existing = state.workspaces.find((entry) => entry.id === id)
330
+ if (existing === undefined) {
331
+ return null
332
+ }
333
+ const updated: HostWorkspaceEntry = { ...existing, name: normalized }
334
+ state.workspaces = state.workspaces.map((entry) => (entry.id === id ? updated : entry))
335
+ await writeRegistry(state)
336
+ return { ...updated }
337
+ })
338
+ }
339
+
340
+ export async function touchWorkspace(
341
+ id: string,
342
+ paths: ResolvedPaths = getPaths(),
343
+ ): Promise<HostWorkspaceEntry | null> {
344
+ const state = stateFor(paths)
345
+ await ensureLoaded(state)
346
+ return await enqueue(state, async () => {
347
+ const existing = state.workspaces.find((entry) => entry.id === id)
348
+ if (existing === undefined) {
349
+ return null
350
+ }
351
+ const updated: HostWorkspaceEntry = { ...existing, lastSeenAt: Date.now() }
352
+ state.workspaces = state.workspaces.map((entry) => (entry.id === id ? updated : entry))
353
+ await writeRegistry(state)
354
+ return { ...updated }
355
+ })
356
+ }