@wardby/cli 0.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 (412) hide show
  1. package/.env.example +131 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +2 -0
  4. package/README.md +282 -0
  5. package/bin/wardby.js +3 -0
  6. package/deploy/local/docker-compose.yml +19 -0
  7. package/dist/claude-coding-worker/driver.d.ts +70 -0
  8. package/dist/claude-coding-worker/driver.js +128 -0
  9. package/dist/claude-coding-worker/main.d.ts +2 -0
  10. package/dist/claude-coding-worker/main.js +41 -0
  11. package/dist/claude-coding-worker/sdk.d.ts +4 -0
  12. package/dist/claude-coding-worker/sdk.js +43 -0
  13. package/dist/claude-coding-worker/tool-relay.d.ts +1 -0
  14. package/dist/claude-coding-worker/tool-relay.js +9 -0
  15. package/dist/cli-help.d.ts +1 -0
  16. package/dist/cli-help.js +20 -0
  17. package/dist/cli.d.ts +18 -0
  18. package/dist/cli.js +629 -0
  19. package/dist/coding/observability.d.ts +59 -0
  20. package/dist/coding/observability.js +77 -0
  21. package/dist/coding/profile.d.ts +88 -0
  22. package/dist/coding/profile.js +137 -0
  23. package/dist/coding/protocol.d.ts +345 -0
  24. package/dist/coding/protocol.js +445 -0
  25. package/dist/coding/provider.d.ts +4 -0
  26. package/dist/coding/provider.js +18 -0
  27. package/dist/coding-proxy/main.d.ts +1 -0
  28. package/dist/coding-proxy/main.js +51 -0
  29. package/dist/coding-worker/artifact.d.ts +16 -0
  30. package/dist/coding-worker/artifact.js +37 -0
  31. package/dist/coding-worker/driver.d.ts +46 -0
  32. package/dist/coding-worker/driver.js +158 -0
  33. package/dist/coding-worker/errors.d.ts +1 -0
  34. package/dist/coding-worker/errors.js +23 -0
  35. package/dist/coding-worker/isolation-probe.d.ts +1 -0
  36. package/dist/coding-worker/isolation-probe.js +146 -0
  37. package/dist/coding-worker/keeper.d.ts +4 -0
  38. package/dist/coding-worker/keeper.js +29 -0
  39. package/dist/coding-worker/main.d.ts +2 -0
  40. package/dist/coding-worker/main.js +43 -0
  41. package/dist/coding-worker/sdk.d.ts +26 -0
  42. package/dist/coding-worker/sdk.js +28 -0
  43. package/dist/coding-worker/types.d.ts +64 -0
  44. package/dist/coding-worker/types.js +1 -0
  45. package/dist/config/providers.d.ts +158 -0
  46. package/dist/config/providers.js +162 -0
  47. package/dist/core/budget-groups.d.ts +72 -0
  48. package/dist/core/budget-groups.js +149 -0
  49. package/dist/core/budget.d.ts +63 -0
  50. package/dist/core/budget.js +69 -0
  51. package/dist/core/coding-queue.d.ts +32 -0
  52. package/dist/core/coding-queue.js +54 -0
  53. package/dist/core/cron.d.ts +31 -0
  54. package/dist/core/cron.js +43 -0
  55. package/dist/core/datastores.d.ts +41 -0
  56. package/dist/core/datastores.js +105 -0
  57. package/dist/core/db.d.ts +2 -0
  58. package/dist/core/db.js +2 -0
  59. package/dist/core/dispatch.d.ts +81 -0
  60. package/dist/core/dispatch.js +184 -0
  61. package/dist/core/engine-native.d.ts +29 -0
  62. package/dist/core/engine-native.js +259 -0
  63. package/dist/core/http-runtime.d.ts +7 -0
  64. package/dist/core/http-runtime.js +101 -0
  65. package/dist/core/lease.d.ts +13 -0
  66. package/dist/core/lease.js +22 -0
  67. package/dist/core/logger.d.ts +13 -0
  68. package/dist/core/logger.js +45 -0
  69. package/dist/core/memory-tools.d.ts +11 -0
  70. package/dist/core/memory-tools.js +122 -0
  71. package/dist/core/reconciler.d.ts +45 -0
  72. package/dist/core/reconciler.js +152 -0
  73. package/dist/core/runner.d.ts +87 -0
  74. package/dist/core/runner.js +529 -0
  75. package/dist/core/scheduler.d.ts +47 -0
  76. package/dist/core/scheduler.js +121 -0
  77. package/dist/core/secrets.d.ts +46 -0
  78. package/dist/core/secrets.js +100 -0
  79. package/dist/core/subagent-memory-tools.d.ts +18 -0
  80. package/dist/core/subagent-memory-tools.js +121 -0
  81. package/dist/core/timing.d.ts +7 -0
  82. package/dist/core/timing.js +7 -0
  83. package/dist/core/webhooks.d.ts +23 -0
  84. package/dist/core/webhooks.js +113 -0
  85. package/dist/env.d.ts +11 -0
  86. package/dist/env.js +13 -0
  87. package/dist/import/budgets.d.ts +16 -0
  88. package/dist/import/budgets.js +21 -0
  89. package/dist/import/bundle.d.ts +16 -0
  90. package/dist/import/bundle.js +61 -0
  91. package/dist/import/cli-args.d.ts +2 -0
  92. package/dist/import/cli-args.js +44 -0
  93. package/dist/import/create.d.ts +34 -0
  94. package/dist/import/create.js +363 -0
  95. package/dist/import/index.d.ts +25 -0
  96. package/dist/import/index.js +130 -0
  97. package/dist/import/model-gate.d.ts +1 -0
  98. package/dist/import/model-gate.js +3 -0
  99. package/dist/import/neutral-schema.d.ts +369 -0
  100. package/dist/import/neutral-schema.js +109 -0
  101. package/dist/import/preflight.d.ts +41 -0
  102. package/dist/import/preflight.js +71 -0
  103. package/dist/import/report.d.ts +5 -0
  104. package/dist/import/report.js +98 -0
  105. package/dist/import/tool-scan.d.ts +8 -0
  106. package/dist/import/tool-scan.js +20 -0
  107. package/dist/mcp/auth/ownership.d.ts +113 -0
  108. package/dist/mcp/auth/ownership.js +87 -0
  109. package/dist/mcp/auth/principal.d.ts +9 -0
  110. package/dist/mcp/auth/principal.js +9 -0
  111. package/dist/mcp/auth/resource-server.d.ts +47 -0
  112. package/dist/mcp/auth/resource-server.js +82 -0
  113. package/dist/mcp/auth/self-hosted/browser.d.ts +3 -0
  114. package/dist/mcp/auth/self-hosted/browser.js +273 -0
  115. package/dist/mcp/auth/self-hosted/cli.d.ts +2 -0
  116. package/dist/mcp/auth/self-hosted/cli.js +39 -0
  117. package/dist/mcp/auth/self-hosted/credentials.d.ts +58 -0
  118. package/dist/mcp/auth/self-hosted/credentials.js +106 -0
  119. package/dist/mcp/auth/self-hosted/rate-limit.d.ts +13 -0
  120. package/dist/mcp/auth/self-hosted/rate-limit.js +20 -0
  121. package/dist/mcp/auth/self-hosted/session.d.ts +36 -0
  122. package/dist/mcp/auth/self-hosted/session.js +110 -0
  123. package/dist/mcp/capabilities.d.ts +11 -0
  124. package/dist/mcp/capabilities.js +10 -0
  125. package/dist/mcp/context.d.ts +46 -0
  126. package/dist/mcp/context.js +1 -0
  127. package/dist/mcp/errors.d.ts +13 -0
  128. package/dist/mcp/errors.js +22 -0
  129. package/dist/mcp/index.d.ts +32 -0
  130. package/dist/mcp/index.js +187 -0
  131. package/dist/mcp/jsonrpc.d.ts +8 -0
  132. package/dist/mcp/jsonrpc.js +1 -0
  133. package/dist/mcp/server.d.ts +107 -0
  134. package/dist/mcp/server.js +203 -0
  135. package/dist/mcp/tasks/manager.d.ts +63 -0
  136. package/dist/mcp/tasks/manager.js +103 -0
  137. package/dist/mcp/tools/agents.d.ts +2 -0
  138. package/dist/mcp/tools/agents.js +375 -0
  139. package/dist/mcp/tools/budget-groups.d.ts +2 -0
  140. package/dist/mcp/tools/budget-groups.js +136 -0
  141. package/dist/mcp/tools/datastore.d.ts +2 -0
  142. package/dist/mcp/tools/datastore.js +217 -0
  143. package/dist/mcp/tools/memory.d.ts +3 -0
  144. package/dist/mcp/tools/memory.js +60 -0
  145. package/dist/mcp/tools/models.d.ts +8 -0
  146. package/dist/mcp/tools/models.js +15 -0
  147. package/dist/mcp/tools/runs.d.ts +2 -0
  148. package/dist/mcp/tools/runs.js +61 -0
  149. package/dist/mcp/tools/scheduling.d.ts +2 -0
  150. package/dist/mcp/tools/scheduling.js +48 -0
  151. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -0
  152. package/dist/mcp/tools/secret-elicitation-form.js +93 -0
  153. package/dist/mcp/tools/secret-elicitation-server.d.ts +5 -0
  154. package/dist/mcp/tools/secret-elicitation-server.js +57 -0
  155. package/dist/mcp/tools/secret-elicitation.d.ts +38 -0
  156. package/dist/mcp/tools/secret-elicitation.js +52 -0
  157. package/dist/mcp/tools/secrets.d.ts +13 -0
  158. package/dist/mcp/tools/secrets.js +124 -0
  159. package/dist/mcp/tools/subagents.d.ts +2 -0
  160. package/dist/mcp/tools/subagents.js +133 -0
  161. package/dist/mcp/tools/text-result.d.ts +6 -0
  162. package/dist/mcp/tools/text-result.js +3 -0
  163. package/dist/mcp/tools/tools.d.ts +2 -0
  164. package/dist/mcp/tools/tools.js +211 -0
  165. package/dist/mcp/tools/trigger.d.ts +2 -0
  166. package/dist/mcp/tools/trigger.js +120 -0
  167. package/dist/mcp/tools/webhooks.d.ts +2 -0
  168. package/dist/mcp/tools/webhooks.js +34 -0
  169. package/dist/mcp/transport/http-limits.d.ts +17 -0
  170. package/dist/mcp/transport/http-limits.js +92 -0
  171. package/dist/mcp/transport/stdio.d.ts +23 -0
  172. package/dist/mcp/transport/stdio.js +6 -0
  173. package/dist/mcp/transport/streamable-http.d.ts +34 -0
  174. package/dist/mcp/transport/streamable-http.js +158 -0
  175. package/dist/mcp/unattended-schedules.d.ts +15 -0
  176. package/dist/mcp/unattended-schedules.js +21 -0
  177. package/dist/mcp/webhooks/ingress.d.ts +17 -0
  178. package/dist/mcp/webhooks/ingress.js +33 -0
  179. package/dist/observability/config.d.ts +6 -0
  180. package/dist/observability/config.js +20 -0
  181. package/dist/observability/metrics-server.d.ts +11 -0
  182. package/dist/observability/metrics-server.js +47 -0
  183. package/dist/observability/metrics.d.ts +36 -0
  184. package/dist/observability/metrics.js +158 -0
  185. package/dist/providers/auth/authorization-server.d.ts +41 -0
  186. package/dist/providers/auth/authorization-server.js +1 -0
  187. package/dist/providers/auth/delegating.d.ts +44 -0
  188. package/dist/providers/auth/delegating.js +105 -0
  189. package/dist/providers/auth/index.d.ts +11 -0
  190. package/dist/providers/auth/index.js +20 -0
  191. package/dist/providers/auth/release-gate.d.ts +1 -0
  192. package/dist/providers/auth/release-gate.js +4 -0
  193. package/dist/providers/auth/self-hosted.d.ts +78 -0
  194. package/dist/providers/auth/self-hosted.js +377 -0
  195. package/dist/providers/auth/subject.d.ts +1 -0
  196. package/dist/providers/auth/subject.js +6 -0
  197. package/dist/providers/auth/types.d.ts +63 -0
  198. package/dist/providers/auth/types.js +22 -0
  199. package/dist/providers/coding-proxy/deny-port.d.ts +5 -0
  200. package/dist/providers/coding-proxy/deny-port.js +45 -0
  201. package/dist/providers/coding-proxy/environment-credentials.d.ts +7 -0
  202. package/dist/providers/coding-proxy/environment-credentials.js +16 -0
  203. package/dist/providers/coding-proxy/index.d.ts +7 -0
  204. package/dist/providers/coding-proxy/index.js +7 -0
  205. package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -0
  206. package/dist/providers/coding-proxy/memory-ledger.js +103 -0
  207. package/dist/providers/coding-proxy/metering.d.ts +20 -0
  208. package/dist/providers/coding-proxy/metering.js +161 -0
  209. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -0
  210. package/dist/providers/coding-proxy/prisma-ledger.js +213 -0
  211. package/dist/providers/coding-proxy/proxy.d.ts +75 -0
  212. package/dist/providers/coding-proxy/proxy.js +721 -0
  213. package/dist/providers/coding-proxy/runtime.d.ts +18 -0
  214. package/dist/providers/coding-proxy/runtime.js +39 -0
  215. package/dist/providers/coding-proxy/secure-fetch.d.ts +9 -0
  216. package/dist/providers/coding-proxy/secure-fetch.js +72 -0
  217. package/dist/providers/coding-proxy/server.d.ts +17 -0
  218. package/dist/providers/coding-proxy/server.js +139 -0
  219. package/dist/providers/coding-proxy/types.d.ts +99 -0
  220. package/dist/providers/coding-proxy/types.js +1 -0
  221. package/dist/providers/datastore/index.d.ts +2 -0
  222. package/dist/providers/datastore/index.js +2 -0
  223. package/dist/providers/datastore/postgres.d.ts +20 -0
  224. package/dist/providers/datastore/postgres.js +130 -0
  225. package/dist/providers/datastore/scoped.d.ts +10 -0
  226. package/dist/providers/datastore/scoped.js +46 -0
  227. package/dist/providers/datastore/types.d.ts +31 -0
  228. package/dist/providers/datastore/types.js +7 -0
  229. package/dist/providers/email/types.d.ts +46 -0
  230. package/dist/providers/email/types.js +8 -0
  231. package/dist/providers/engine/index.d.ts +1 -0
  232. package/dist/providers/engine/index.js +1 -0
  233. package/dist/providers/engine/types.d.ts +67 -0
  234. package/dist/providers/engine/types.js +16 -0
  235. package/dist/providers/executor/build.d.ts +6 -0
  236. package/dist/providers/executor/build.js +15 -0
  237. package/dist/providers/executor/composition.d.ts +14 -0
  238. package/dist/providers/executor/composition.js +123 -0
  239. package/dist/providers/executor/container.d.ts +184 -0
  240. package/dist/providers/executor/container.js +936 -0
  241. package/dist/providers/executor/dbos-status.d.ts +50 -0
  242. package/dist/providers/executor/dbos-status.js +64 -0
  243. package/dist/providers/executor/dbos.d.ts +53 -0
  244. package/dist/providers/executor/dbos.js +269 -0
  245. package/dist/providers/executor/in-process.d.ts +18 -0
  246. package/dist/providers/executor/in-process.js +38 -0
  247. package/dist/providers/executor/index.d.ts +8 -0
  248. package/dist/providers/executor/index.js +8 -0
  249. package/dist/providers/executor/routing.d.ts +48 -0
  250. package/dist/providers/executor/routing.js +70 -0
  251. package/dist/providers/executor/types.d.ts +55 -0
  252. package/dist/providers/executor/types.js +1 -0
  253. package/dist/providers/index.d.ts +43 -0
  254. package/dist/providers/index.js +18 -0
  255. package/dist/providers/jobs/docker-isolation.d.ts +166 -0
  256. package/dist/providers/jobs/docker-isolation.js +724 -0
  257. package/dist/providers/jobs/docker.d.ts +127 -0
  258. package/dist/providers/jobs/docker.js +1027 -0
  259. package/dist/providers/jobs/fake-kubernetes-api.d.ts +98 -0
  260. package/dist/providers/jobs/fake-kubernetes-api.js +142 -0
  261. package/dist/providers/jobs/fake.d.ts +23 -0
  262. package/dist/providers/jobs/fake.js +132 -0
  263. package/dist/providers/jobs/kubernetes-api.d.ts +60 -0
  264. package/dist/providers/jobs/kubernetes-api.js +20 -0
  265. package/dist/providers/jobs/kubernetes-client.d.ts +36 -0
  266. package/dist/providers/jobs/kubernetes-client.js +171 -0
  267. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +49 -0
  268. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +141 -0
  269. package/dist/providers/jobs/kubernetes-isolation.d.ts +147 -0
  270. package/dist/providers/jobs/kubernetes-isolation.js +607 -0
  271. package/dist/providers/jobs/kubernetes-platform.d.ts +177 -0
  272. package/dist/providers/jobs/kubernetes-platform.js +280 -0
  273. package/dist/providers/jobs/kubernetes-preflight.d.ts +59 -0
  274. package/dist/providers/jobs/kubernetes-preflight.js +339 -0
  275. package/dist/providers/jobs/kubernetes-witness.d.ts +10 -0
  276. package/dist/providers/jobs/kubernetes-witness.js +193 -0
  277. package/dist/providers/jobs/kubernetes.d.ts +127 -0
  278. package/dist/providers/jobs/kubernetes.js +874 -0
  279. package/dist/providers/jobs/safe-extract.d.ts +9 -0
  280. package/dist/providers/jobs/safe-extract.js +325 -0
  281. package/dist/providers/jobs/types.d.ts +78 -0
  282. package/dist/providers/jobs/types.js +6 -0
  283. package/dist/providers/jobs/workspace-swap.d.ts +2 -0
  284. package/dist/providers/jobs/workspace-swap.js +47 -0
  285. package/dist/providers/llm/anthropic.d.ts +13 -0
  286. package/dist/providers/llm/anthropic.js +21 -0
  287. package/dist/providers/llm/bedrock.d.ts +19 -0
  288. package/dist/providers/llm/bedrock.js +33 -0
  289. package/dist/providers/llm/claude-messages.d.ts +106 -0
  290. package/dist/providers/llm/claude-messages.js +157 -0
  291. package/dist/providers/llm/claude-provider.d.ts +40 -0
  292. package/dist/providers/llm/claude-provider.js +31 -0
  293. package/dist/providers/llm/index.d.ts +10 -0
  294. package/dist/providers/llm/index.js +10 -0
  295. package/dist/providers/llm/openai.d.ts +23 -0
  296. package/dist/providers/llm/openai.js +156 -0
  297. package/dist/providers/llm/pricing-anthropic.d.ts +4 -0
  298. package/dist/providers/llm/pricing-anthropic.js +30 -0
  299. package/dist/providers/llm/pricing-bedrock-claude.d.ts +12 -0
  300. package/dist/providers/llm/pricing-bedrock-claude.js +37 -0
  301. package/dist/providers/llm/pricing-core.d.ts +26 -0
  302. package/dist/providers/llm/pricing-core.js +17 -0
  303. package/dist/providers/llm/pricing.d.ts +30 -0
  304. package/dist/providers/llm/pricing.js +74 -0
  305. package/dist/providers/llm/registration.d.ts +8 -0
  306. package/dist/providers/llm/registration.js +39 -0
  307. package/dist/providers/llm/routing.d.ts +25 -0
  308. package/dist/providers/llm/routing.js +32 -0
  309. package/dist/providers/llm/types.d.ts +85 -0
  310. package/dist/providers/llm/types.js +12 -0
  311. package/dist/providers/memory/index.d.ts +2 -0
  312. package/dist/providers/memory/index.js +2 -0
  313. package/dist/providers/memory/postgres.d.ts +20 -0
  314. package/dist/providers/memory/postgres.js +72 -0
  315. package/dist/providers/memory/types.d.ts +32 -0
  316. package/dist/providers/memory/types.js +17 -0
  317. package/dist/providers/secrets/app-key.d.ts +8 -0
  318. package/dist/providers/secrets/app-key.js +50 -0
  319. package/dist/providers/secrets/index.d.ts +10 -0
  320. package/dist/providers/secrets/index.js +13 -0
  321. package/dist/providers/secrets/transfer-envelope.d.ts +12 -0
  322. package/dist/providers/secrets/transfer-envelope.js +35 -0
  323. package/dist/providers/secrets/types.d.ts +18 -0
  324. package/dist/providers/secrets/types.js +12 -0
  325. package/dist/providers/storage/types.d.ts +18 -0
  326. package/dist/providers/storage/types.js +7 -0
  327. package/dist/providers/vcs/git.d.ts +105 -0
  328. package/dist/providers/vcs/git.js +710 -0
  329. package/dist/providers/vcs/github.d.ts +105 -0
  330. package/dist/providers/vcs/github.js +394 -0
  331. package/dist/providers/vcs/index.d.ts +6 -0
  332. package/dist/providers/vcs/index.js +26 -0
  333. package/dist/providers/vcs/types.d.ts +118 -0
  334. package/dist/providers/vcs/types.js +1 -0
  335. package/dist/sandbox/bounded-json.d.ts +2 -0
  336. package/dist/sandbox/bounded-json.js +36 -0
  337. package/dist/sandbox/bridge.d.ts +15 -0
  338. package/dist/sandbox/bridge.js +78 -0
  339. package/dist/sandbox/eval-core.d.ts +37 -0
  340. package/dist/sandbox/eval-core.js +159 -0
  341. package/dist/sandbox/fetch-policy.d.ts +24 -0
  342. package/dist/sandbox/fetch-policy.js +96 -0
  343. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +5 -0
  344. package/dist/sandbox/generated/zod.bundle.js +1 -0
  345. package/dist/sandbox/host-functions.d.ts +29 -0
  346. package/dist/sandbox/host-functions.js +168 -0
  347. package/dist/sandbox/limits.d.ts +39 -0
  348. package/dist/sandbox/limits.js +39 -0
  349. package/dist/sandbox/parser-worker/__fixtures__/crash.d.ts +1 -0
  350. package/dist/sandbox/parser-worker/__fixtures__/crash.js +6 -0
  351. package/dist/sandbox/parser-worker/__fixtures__/echo.d.ts +1 -0
  352. package/dist/sandbox/parser-worker/__fixtures__/echo.js +5 -0
  353. package/dist/sandbox/parser-worker/__fixtures__/reject.d.ts +1 -0
  354. package/dist/sandbox/parser-worker/__fixtures__/reject.js +5 -0
  355. package/dist/sandbox/parser-worker/__fixtures__/spin-forever.d.ts +1 -0
  356. package/dist/sandbox/parser-worker/__fixtures__/spin-forever.js +11 -0
  357. package/dist/sandbox/parser-worker/pool.d.ts +13 -0
  358. package/dist/sandbox/parser-worker/pool.js +111 -0
  359. package/dist/sandbox/parser-worker/worker.d.ts +14 -0
  360. package/dist/sandbox/parser-worker/worker.js +63 -0
  361. package/dist/sandbox/pii-redaction.d.ts +1 -0
  362. package/dist/sandbox/pii-redaction.js +29 -0
  363. package/dist/sandbox/prelude.d.ts +26 -0
  364. package/dist/sandbox/prelude.js +408 -0
  365. package/dist/sandbox/quickjs-module.d.ts +13 -0
  366. package/dist/sandbox/quickjs-module.js +19 -0
  367. package/dist/sandbox/run-in-sandbox.d.ts +34 -0
  368. package/dist/sandbox/run-in-sandbox.js +53 -0
  369. package/dist/sandbox/safe-fetch.d.ts +26 -0
  370. package/dist/sandbox/safe-fetch.js +140 -0
  371. package/dist/sandbox/tool-capabilities.d.ts +66 -0
  372. package/dist/sandbox/tool-capabilities.js +103 -0
  373. package/dist/sandbox/zod-params.d.ts +22 -0
  374. package/dist/sandbox/zod-params.js +60 -0
  375. package/dist/serve.d.ts +14 -0
  376. package/dist/serve.js +54 -0
  377. package/dist/wardby-bin.d.ts +2 -0
  378. package/dist/wardby-bin.js +20 -0
  379. package/package.json +123 -0
  380. package/prisma/migrations/20260905000000_init/migration.sql +34 -0
  381. package/prisma/migrations/20260905010000_scheduler_durability/migration.sql +31 -0
  382. package/prisma/migrations/20260905020000_tools_multiturn/migration.sql +47 -0
  383. package/prisma/migrations/20260905030000_cache_tool_json_schema/migration.sql +13 -0
  384. package/prisma/migrations/20260906000000_mcp_phase4/migration.sql +115 -0
  385. package/prisma/migrations/20260906010000_run_final_text/migration.sql +7 -0
  386. package/prisma/migrations/20260906020000_run_turns/migration.sql +6 -0
  387. package/prisma/migrations/20260906030000_task_principal_id/migration.sql +5 -0
  388. package/prisma/migrations/20260906040000_secure_self_hosted_oauth/migration.sql +67 -0
  389. package/prisma/migrations/20260906050000_phase5_coding_agents/migration.sql +52 -0
  390. package/prisma/migrations/20260906060000_tool_capability_scoping/migration.sql +22 -0
  391. package/prisma/migrations/20260906070000_datastore_pii_flag/migration.sql +6 -0
  392. package/prisma/migrations/20260906080000_secret_elicitation_outcomes/migration.sql +13 -0
  393. package/prisma/migrations/20260907010000_coding_proxy_ledger/migration.sql +57 -0
  394. package/prisma/migrations/20260907020000_budget_groups/migration.sql +24 -0
  395. package/prisma/migrations/20260907030000_coding_webhook_task_override/migration.sql +4 -0
  396. package/prisma/migrations/20260908010000_run_execution_backend/migration.sql +2 -0
  397. package/prisma/migrations/20260908020000_coding_run_audit_metadata/migration.sql +7 -0
  398. package/prisma/migrations/20260910010000_agent_secret_bound_name/migration.sql +16 -0
  399. package/prisma/migrations/20260911010000_coding_worker_toolchains/migration.sql +5 -0
  400. package/prisma/migrations/20260912010000_coding_provider_contract/migration.sql +24 -0
  401. package/prisma/migrations/20260912020000_coding_proxy_protocol/migration.sql +10 -0
  402. package/prisma/migrations/20260912030000_agent_memory/migration.sql +18 -0
  403. package/prisma/migrations/20260912040000_named_shared_datastores/migration.sql +68 -0
  404. package/prisma/migrations/20260913000000_run_trigger_webhook/migration.sql +2 -0
  405. package/prisma/migrations/20260913010000_agent_sub_agent/migration.sql +32 -0
  406. package/prisma/migrations/20260913020000_run_task_override/migration.sql +5 -0
  407. package/prisma/migrations/20260913030000_coding_run_root/migration.sql +11 -0
  408. package/prisma/migrations/20260922010000_coding_run_queued_at/migration.sql +8 -0
  409. package/prisma/migrations/20260922020000_coding_workspace_disk/migration.sql +8 -0
  410. package/prisma/migrations/migration_lock.toml +3 -0
  411. package/prisma/schema.prisma +723 -0
  412. package/scripts/git-askpass.sh +11 -0
@@ -0,0 +1,408 @@
1
+ /**
2
+ * The sandbox's Medium host API surface, evaluated once per invocation
3
+ * before the tool's own code. Everything here is either:
4
+ * - pure computation (Buffer, TextEncoder/Decoder, URL/URLSearchParams,
5
+ * atob/btoa, AbortController, Blob, FormData, formatDate) — no host call
6
+ * needed, so these are plain JS classes/functions; or
7
+ * - a thin wrapper over one of the low-level `__bridge_*` functions
8
+ * registered by host-functions.ts (fetch, datastore, parsers, sleep,
9
+ * console, crypto) — every one of those is JSON-string in, JSON-string
10
+ * (or thrown error) out, per bridge.ts.
11
+ *
12
+ * Known, deliberate simplifications (documented, not silent):
13
+ * - `crypto.randomUUID`/`getRandomValues` are ASYNC here (must `await`),
14
+ * unlike the real synchronous Web Crypto API — true randomness needs a
15
+ * real host entropy source, which means crossing the bridge.
16
+ * - `AbortController`/`AbortSignal` are a real but "cosmetic" polyfill: a
17
+ * signal can be checked/thrown-on synchronously, but aborting it does
18
+ * not cancel an in-flight host `fetch` already underway. The per-
19
+ * invocation wall-time cap is the actual backstop for a hung call.
20
+ * - `FormData` is a real data structure but `fetch` does not encode it as
21
+ * multipart/form-data — a tool needing genuine multipart upload isn't
22
+ * fully supported yet.
23
+ *
24
+ * Nothing else is reachable: no `process`, no filesystem, no host `require`.
25
+ */
26
+ export const SANDBOX_PRELUDE = String.raw `
27
+ "use strict";
28
+
29
+ // ---- base64 / hex codecs (pure; shared by Buffer, atob/btoa, fetch bodies) ----
30
+
31
+ const __B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
32
+
33
+ function __bytesToBase64(bytes) {
34
+ let out = "";
35
+ for (let i = 0; i < bytes.length; i += 3) {
36
+ const b0 = bytes[i];
37
+ const b1 = i + 1 < bytes.length ? bytes[i + 1] : undefined;
38
+ const b2 = i + 2 < bytes.length ? bytes[i + 2] : undefined;
39
+ out += __B64_CHARS[b0 >> 2];
40
+ out += __B64_CHARS[((b0 & 0x03) << 4) | (b1 === undefined ? 0 : b1 >> 4)];
41
+ out += b1 === undefined ? "=" : __B64_CHARS[((b1 & 0x0f) << 2) | (b2 === undefined ? 0 : b2 >> 6)];
42
+ out += b2 === undefined ? "=" : __B64_CHARS[b2 & 0x3f];
43
+ }
44
+ return out;
45
+ }
46
+
47
+ function __base64ToBytes(b64) {
48
+ const clean = String(b64).replace(/[^A-Za-z0-9+/]/g, "");
49
+ const bytes = [];
50
+ for (let i = 0; i < clean.length; i += 4) {
51
+ const c0 = __B64_CHARS.indexOf(clean[i]);
52
+ const c1 = __B64_CHARS.indexOf(clean[i + 1]);
53
+ const c2 = __B64_CHARS.indexOf(clean[i + 2]);
54
+ const c3 = __B64_CHARS.indexOf(clean[i + 3]);
55
+ bytes.push((c0 << 2) | (c1 >> 4));
56
+ if (c2 >= 0) bytes.push(((c1 & 0x0f) << 4) | (c2 >> 2));
57
+ if (c3 >= 0) bytes.push(((c2 & 0x03) << 6) | c3);
58
+ }
59
+ return new Uint8Array(bytes);
60
+ }
61
+
62
+ function __bytesToHex(bytes) {
63
+ let out = "";
64
+ for (let i = 0; i < bytes.length; i++) out += bytes[i].toString(16).padStart(2, "0");
65
+ return out;
66
+ }
67
+
68
+ function __hexToBytes(hex) {
69
+ const clean = String(hex).replace(/[^0-9a-fA-F]/g, "");
70
+ const bytes = new Uint8Array(clean.length / 2);
71
+ for (let i = 0; i < bytes.length; i++) bytes[i] = parseInt(clean.substr(i * 2, 2), 16);
72
+ return bytes;
73
+ }
74
+
75
+ // ---- UTF-8 (pure; TextEncoder/TextDecoder + Buffer('utf8')) ----
76
+
77
+ function __utf8Encode(str) {
78
+ const bytes = [];
79
+ for (const ch of String(str)) {
80
+ let cp = ch.codePointAt(0);
81
+ if (cp < 0x80) {
82
+ bytes.push(cp);
83
+ } else if (cp < 0x800) {
84
+ bytes.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));
85
+ } else if (cp < 0x10000) {
86
+ bytes.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
87
+ } else {
88
+ bytes.push(
89
+ 0xf0 | (cp >> 18),
90
+ 0x80 | ((cp >> 12) & 0x3f),
91
+ 0x80 | ((cp >> 6) & 0x3f),
92
+ 0x80 | (cp & 0x3f),
93
+ );
94
+ }
95
+ }
96
+ return new Uint8Array(bytes);
97
+ }
98
+
99
+ function __utf8Decode(bytes) {
100
+ const arr = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
101
+ let out = "";
102
+ let i = 0;
103
+ while (i < arr.length) {
104
+ const b0 = arr[i];
105
+ let cp, len;
106
+ if (b0 < 0x80) { cp = b0; len = 1; }
107
+ else if ((b0 & 0xe0) === 0xc0) { cp = b0 & 0x1f; len = 2; }
108
+ else if ((b0 & 0xf0) === 0xe0) { cp = b0 & 0x0f; len = 3; }
109
+ else if ((b0 & 0xf8) === 0xf0) { cp = b0 & 0x07; len = 4; }
110
+ else { cp = 0xfffd; len = 1; }
111
+ for (let k = 1; k < len && i + k < arr.length; k++) cp = (cp << 6) | (arr[i + k] & 0x3f);
112
+ out += String.fromCodePoint(cp);
113
+ i += len;
114
+ }
115
+ return out;
116
+ }
117
+
118
+ class TextEncoder {
119
+ encode(str) { return __utf8Encode(str ?? ""); }
120
+ }
121
+ class TextDecoder {
122
+ constructor(encoding) { this.encoding = encoding || "utf-8"; }
123
+ decode(bytes) { return bytes ? __utf8Decode(bytes) : ""; }
124
+ }
125
+ globalThis.TextEncoder = TextEncoder;
126
+ globalThis.TextDecoder = TextDecoder;
127
+
128
+ // ---- atob / btoa (pure) ----
129
+
130
+ globalThis.btoa = (str) => __bytesToBase64(Uint8Array.from(String(str), (c) => c.charCodeAt(0) & 0xff));
131
+ globalThis.atob = (b64) => {
132
+ const bytes = __base64ToBytes(b64);
133
+ let out = "";
134
+ for (let i = 0; i < bytes.length; i++) out += String.fromCharCode(bytes[i]);
135
+ return out;
136
+ };
137
+
138
+ // ---- Buffer (minimal; utf8/base64/hex only) ----
139
+
140
+ class Buffer extends Uint8Array {
141
+ static from(data, encoding) {
142
+ if (typeof data === "string") {
143
+ if (encoding === "base64") return new Buffer(__base64ToBytes(data));
144
+ if (encoding === "hex") return new Buffer(__hexToBytes(data));
145
+ return new Buffer(__utf8Encode(data));
146
+ }
147
+ return new Buffer(data);
148
+ }
149
+ static isBuffer(x) { return x instanceof Buffer; }
150
+ static byteLength(data, encoding) { return Buffer.from(data, encoding).length; }
151
+ toString(encoding) {
152
+ if (encoding === "base64") return __bytesToBase64(this);
153
+ if (encoding === "hex") return __bytesToHex(this);
154
+ return __utf8Decode(this);
155
+ }
156
+ }
157
+ globalThis.Buffer = Buffer;
158
+
159
+ // ---- URL / URLSearchParams (pure) ----
160
+
161
+ class URLSearchParams {
162
+ constructor(init) {
163
+ this._entries = [];
164
+ if (typeof init === "string") {
165
+ const s = init.startsWith("?") ? init.slice(1) : init;
166
+ for (const pair of s.split("&")) {
167
+ if (!pair) continue;
168
+ // Split on the *first* "=" only — a value containing "=" (e.g. a
169
+ // base64/JWT token) must not be truncated at a later "=".
170
+ const eqIndex = pair.indexOf("=");
171
+ const k = eqIndex === -1 ? pair : pair.slice(0, eqIndex);
172
+ const v = eqIndex === -1 ? "" : pair.slice(eqIndex + 1);
173
+ this._entries.push([decodeURIComponent(k), decodeURIComponent(v)]);
174
+ }
175
+ } else if (init && typeof init === "object") {
176
+ for (const [k, v] of (init instanceof URLSearchParams ? init._entries : Object.entries(init))) {
177
+ this._entries.push([String(k), String(v)]);
178
+ }
179
+ }
180
+ }
181
+ append(k, v) { this._entries.push([String(k), String(v)]); }
182
+ set(k, v) { this._entries = this._entries.filter(([key]) => key !== String(k)); this._entries.push([String(k), String(v)]); }
183
+ get(k) { const e = this._entries.find(([key]) => key === String(k)); return e ? e[1] : null; }
184
+ getAll(k) { return this._entries.filter(([key]) => key === String(k)).map(([, v]) => v); }
185
+ has(k) { return this._entries.some(([key]) => key === String(k)); }
186
+ delete(k) { this._entries = this._entries.filter(([key]) => key !== String(k)); }
187
+ entries() { return this._entries[Symbol.iterator](); }
188
+ forEach(fn) { this._entries.forEach(([k, v]) => fn(v, k)); }
189
+ toString() { return this._entries.map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v)).join("&"); }
190
+ [Symbol.iterator]() { return this._entries[Symbol.iterator](); }
191
+ }
192
+ globalThis.URLSearchParams = URLSearchParams;
193
+
194
+ const __URL_RE = /^([a-zA-Z][a-zA-Z0-9+.-]*:)\/\/(?:([^@/]*)@)?([^/:?#]*)(?::(\d+))?([^?#]*)(\?[^#]*)?(#.*)?$/;
195
+
196
+ class URL {
197
+ constructor(input, base) {
198
+ let full = String(input);
199
+ if (base && !__URL_RE.test(full)) {
200
+ const b = String(base).replace(/\/[^/]*$/, "/");
201
+ full = full.startsWith("/") ? new URL(base).origin + full : b + full;
202
+ }
203
+ const m = __URL_RE.exec(full);
204
+ if (!m) throw new TypeError("Invalid URL: " + input);
205
+ this.protocol = m[1];
206
+ this.username = "";
207
+ this.password = "";
208
+ this.host = m[3] + (m[4] ? ":" + m[4] : "");
209
+ this.hostname = m[3];
210
+ this.port = m[4] || "";
211
+ this.pathname = m[5] || "/";
212
+ this.search = m[6] || "";
213
+ this.hash = m[7] || "";
214
+ this.searchParams = new URLSearchParams(this.search);
215
+ this.origin = this.protocol + "//" + this.host;
216
+ }
217
+ toString() {
218
+ const q = this.searchParams.toString();
219
+ return this.origin + this.pathname + (q ? "?" + q : "") + this.hash;
220
+ }
221
+ get href() { return this.toString(); }
222
+ }
223
+ globalThis.URL = URL;
224
+
225
+ // ---- AbortController / AbortSignal (real but "cosmetic" — see module docstring) ----
226
+
227
+ class AbortSignal {
228
+ constructor() { this.aborted = false; this._listeners = []; }
229
+ addEventListener(type, cb) { if (type === "abort") this._listeners.push(cb); }
230
+ removeEventListener(type, cb) { this._listeners = this._listeners.filter((l) => l !== cb); }
231
+ throwIfAborted() { if (this.aborted) throw new Error("AbortError: signal is aborted"); }
232
+ }
233
+ class AbortController {
234
+ constructor() { this.signal = new AbortSignal(); }
235
+ abort() {
236
+ if (this.signal.aborted) return;
237
+ this.signal.aborted = true;
238
+ this.signal._listeners.forEach((cb) => { try { cb(); } catch (_e) { /* ignore listener errors */ } });
239
+ }
240
+ }
241
+ globalThis.AbortController = AbortController;
242
+ globalThis.AbortSignal = AbortSignal;
243
+
244
+ // ---- Blob / FormData (pure; see module docstring re: fetch body encoding) ----
245
+
246
+ class Blob {
247
+ constructor(parts, options) {
248
+ this._text = (parts || []).map((p) => (typeof p === "string" ? p : __utf8Decode(p))).join("");
249
+ this.type = (options && options.type) || "";
250
+ this.size = __utf8Encode(this._text).length;
251
+ }
252
+ async text() { return this._text; }
253
+ async arrayBuffer() { return __utf8Encode(this._text).buffer; }
254
+ }
255
+ globalThis.Blob = Blob;
256
+
257
+ class FormData {
258
+ constructor() { this._entries = []; }
259
+ append(k, v) { this._entries.push([String(k), v]); }
260
+ set(k, v) { this._entries = this._entries.filter(([key]) => key !== String(k)); this._entries.push([String(k), v]); }
261
+ get(k) { const e = this._entries.find(([key]) => key === String(k)); return e ? e[1] : null; }
262
+ getAll(k) { return this._entries.filter(([key]) => key === String(k)).map(([, v]) => v); }
263
+ has(k) { return this._entries.some(([key]) => key === String(k)); }
264
+ delete(k) { this._entries = this._entries.filter(([key]) => key !== String(k)); }
265
+ entries() { return this._entries[Symbol.iterator](); }
266
+ [Symbol.iterator]() { return this._entries[Symbol.iterator](); }
267
+ }
268
+ globalThis.FormData = FormData;
269
+
270
+ // ---- formatDate (pure; minimal token replacement, no ICU) ----
271
+
272
+ globalThis.formatDate = (date, pattern) => {
273
+ const d = date instanceof Date ? date : new Date(date);
274
+ const pad = (n, len) => String(n).padStart(len || 2, "0");
275
+ const tokens = {
276
+ YYYY: d.getUTCFullYear(),
277
+ MM: pad(d.getUTCMonth() + 1),
278
+ DD: pad(d.getUTCDate()),
279
+ HH: pad(d.getUTCHours()),
280
+ mm: pad(d.getUTCMinutes()),
281
+ ss: pad(d.getUTCSeconds()),
282
+ };
283
+ return String(pattern || "YYYY-MM-DD").replace(/YYYY|MM|DD|HH|mm|ss/g, (t) => tokens[t]);
284
+ };
285
+
286
+ // ---- console (bridged; fire-and-forget) ----
287
+
288
+ function __safeArgs(args) {
289
+ try {
290
+ return JSON.parse(JSON.stringify(args));
291
+ } catch (_e) {
292
+ return args.map((a) => String(a));
293
+ }
294
+ }
295
+ globalThis.console = {
296
+ log: (...args) => { __bridge_console(JSON.stringify(["log", __safeArgs(args)])); },
297
+ info: (...args) => { __bridge_console(JSON.stringify(["log", __safeArgs(args)])); },
298
+ debug: (...args) => { __bridge_console(JSON.stringify(["log", __safeArgs(args)])); },
299
+ warn: (...args) => { __bridge_console(JSON.stringify(["warn", __safeArgs(args)])); },
300
+ error: (...args) => { __bridge_console(JSON.stringify(["error", __safeArgs(args)])); },
301
+ };
302
+
303
+ // ---- setTimeout / clearTimeout (callback never crosses the bridge — only
304
+ // a delay does; the callback is invoked entirely inside the sandbox once
305
+ // the awaited host sleep promise resolves) ----
306
+
307
+ let __timeoutCounter = 0;
308
+ const __cancelledTimeouts = new Set();
309
+ globalThis.setTimeout = (fn, ms, ...args) => {
310
+ const id = ++__timeoutCounter;
311
+ (async () => {
312
+ await __bridge_sleep(JSON.stringify([ms || 0]));
313
+ if (__cancelledTimeouts.has(id)) { __cancelledTimeouts.delete(id); return; }
314
+ try { fn(...args); } catch (e) { console.error("setTimeout callback error:", e && e.message); }
315
+ })();
316
+ return id;
317
+ };
318
+ globalThis.clearTimeout = (id) => { __cancelledTimeouts.add(id); };
319
+ globalThis.clearInterval = globalThis.clearTimeout;
320
+
321
+ // ---- crypto (bridged; ASYNC — see module docstring) ----
322
+
323
+ globalThis.crypto = {
324
+ randomUUID: async () => JSON.parse(await __bridge_randomUUID("[]")),
325
+ getRandomValues: async (typedArray) => {
326
+ const bytes = JSON.parse(await __bridge_randomBytes(JSON.stringify([typedArray.length])));
327
+ typedArray.set(bytes);
328
+ return typedArray;
329
+ },
330
+ };
331
+
332
+ // ---- fetch (bridged) ----
333
+
334
+ globalThis.fetch = async (url, init) => {
335
+ if (init && init.signal && init.signal.aborted) {
336
+ throw new Error("AbortError: fetch aborted before starting");
337
+ }
338
+ let body = init && init.body;
339
+ if (body !== undefined && typeof body !== "string") {
340
+ if (body instanceof Blob) body = await body.text();
341
+ else body = JSON.stringify(body);
342
+ }
343
+ const raw = await __bridge_fetch(
344
+ JSON.stringify([String(url), { method: (init && init.method) || "GET", headers: (init && init.headers) || {}, body }]),
345
+ );
346
+ const data = JSON.parse(raw);
347
+ const headersLower = {};
348
+ for (const k of Object.keys(data.headers || {})) headersLower[k.toLowerCase()] = data.headers[k];
349
+ return {
350
+ ok: data.ok,
351
+ status: data.status,
352
+ statusText: data.statusText,
353
+ url: data.url,
354
+ headers: { get: (name) => headersLower[String(name).toLowerCase()] ?? null },
355
+ json: async () => JSON.parse(__utf8Decode(__base64ToBytes(data.bodyBase64))),
356
+ text: async () => __utf8Decode(__base64ToBytes(data.bodyBase64)),
357
+ arrayBuffer: async () => __base64ToBytes(data.bodyBase64).buffer,
358
+ };
359
+ };
360
+
361
+ // ---- datastore (bridged; scoped per agent by the host, not the sandbox) ----
362
+
363
+ globalThis.datastore = {
364
+ get: async (key) => JSON.parse(await __bridge_datastoreGet(JSON.stringify([key]))),
365
+ set: async (key, value, opts) => { await __bridge_datastoreSet(JSON.stringify([key, value, opts])); },
366
+ delete: async (key) => { await __bridge_datastoreDelete(JSON.stringify([key])); },
367
+ list: async (prefix) => JSON.parse(await __bridge_datastoreList(JSON.stringify([prefix === undefined ? null : prefix]))),
368
+ };
369
+
370
+ // ---- sharedDatastore (bridged; boundName-addressed, capability-scoped by the host) ----
371
+
372
+ globalThis.sharedDatastore = {
373
+ get: async (boundName, key) => JSON.parse(await __bridge_sharedDatastoreGet(JSON.stringify([boundName, key]))),
374
+ set: async (boundName, key, value, opts) => {
375
+ await __bridge_sharedDatastoreSet(JSON.stringify([boundName, key, value, opts]));
376
+ },
377
+ delete: async (boundName, key) => { await __bridge_sharedDatastoreDelete(JSON.stringify([boundName, key])); },
378
+ list: async (boundName, prefix) =>
379
+ JSON.parse(await __bridge_sharedDatastoreList(JSON.stringify([boundName, prefix === undefined ? null : prefix]))),
380
+ };
381
+
382
+ // ---- secrets (bridged; decrypt-on-demand, scoped per agent by the host) ----
383
+
384
+ globalThis.secrets = {
385
+ get: async (name) => {
386
+ const raw = JSON.parse(await __bridge_secretsGet(JSON.stringify([name])));
387
+ return raw === null ? undefined : raw;
388
+ },
389
+ };
390
+
391
+ // ---- parsers (bridged; real parser libraries run host-side) ----
392
+
393
+ globalThis.parseHTML = async (html) => JSON.parse(await __bridge_parseHTML(JSON.stringify([String(html)])));
394
+ globalThis.parseCSV = async (csv, options) => JSON.parse(await __bridge_parseCSV(JSON.stringify([String(csv), options || null])));
395
+ globalThis.parseXML = async (xml, options) => JSON.parse(await __bridge_parseXML(JSON.stringify([String(xml), options || null])));
396
+
397
+ // ---- email placeholders (roadmap-deferred) ----
398
+
399
+ // Roadmap placeholders: the Full host surface will implement these; until
400
+ // then they exist so migrated tools import faithfully and fail loudly only
401
+ // when actually called (not silently dropped at import). npmLockUpdate is
402
+ // deliberately NOT provided — it is not on the roadmap.
403
+ const __unimplemented = (name) => () => {
404
+ throw new Error(name + " is not implemented in this build");
405
+ };
406
+ globalThis.sendEmail = __unimplemented("sendEmail");
407
+ globalThis.getInboundEmail = __unimplemented("getInboundEmail");
408
+ `;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Lazy singleton for the compiled QuickJS WASM module. Compiling/loading the
3
+ * WASM binary is the expensive one-time cost; a fresh `QuickJSRuntime` +
4
+ * `QuickJSContext` per tool invocation (cheap) is what actually gives each
5
+ * call its isolation — see run-in-sandbox.ts.
6
+ *
7
+ * Deliberately the plain sync variant, not asyncify: host async calls are
8
+ * bridged via the documented deferred-promise + `executePendingJobs` pump
9
+ * pattern (bridge.ts), which works with the smaller, faster sync build and
10
+ * doesn't depend on Asyncify's WASM-stack-suspension behavior.
11
+ */
12
+ import { type QuickJSWASMModule } from "quickjs-emscripten";
13
+ export declare function getQuickJsModule(): Promise<QuickJSWASMModule>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lazy singleton for the compiled QuickJS WASM module. Compiling/loading the
3
+ * WASM binary is the expensive one-time cost; a fresh `QuickJSRuntime` +
4
+ * `QuickJSContext` per tool invocation (cheap) is what actually gives each
5
+ * call its isolation — see run-in-sandbox.ts.
6
+ *
7
+ * Deliberately the plain sync variant, not asyncify: host async calls are
8
+ * bridged via the documented deferred-promise + `executePendingJobs` pump
9
+ * pattern (bridge.ts), which works with the smaller, faster sync build and
10
+ * doesn't depend on Asyncify's WASM-stack-suspension behavior.
11
+ */
12
+ import { newQuickJSWASMModule } from "quickjs-emscripten";
13
+ let modulePromise;
14
+ export function getQuickJsModule() {
15
+ if (!modulePromise) {
16
+ modulePromise = newQuickJSWASMModule();
17
+ }
18
+ return modulePromise;
19
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Orchestrates one sandboxed tool invocation: full host API (fetch,
3
+ * datastore, parsers, etc.) installed, fresh runtime/context per call
4
+ * (isolation — no state bleeds between calls; persistent state is the
5
+ * datastore's job). Never lets a tool failure escape as anything other
6
+ * than a structured `SandboxResult` — a throw, timeout, memory
7
+ * exhaustion, or non-serializable return all fail *that call* cleanly
8
+ * instead of crashing the run or the host process.
9
+ */
10
+ import { type SandboxLimits, type SandboxResult } from "./eval-core.js";
11
+ import type { Datastore } from "../providers/datastore/types.js";
12
+ import type { SecretsAccessor } from "../core/secrets.js";
13
+ import type { SharedDatastoreAccessor } from "../core/datastores.js";
14
+ import type { Logger } from "../core/logger.js";
15
+ export type { SandboxErrorKind, SandboxLimits, SandboxResult } from "./eval-core.js";
16
+ export interface SandboxInvocation {
17
+ /** The tool body source. Runs as an async function body receiving `params`. */
18
+ code: string;
19
+ params: unknown;
20
+ agentId: string;
21
+ datastore: Datastore;
22
+ sharedDatastore: SharedDatastoreAccessor;
23
+ /** Used only to tag forwarded console output and error messages. */
24
+ toolName: string;
25
+ /** Overrides the default limits (limits.ts) — mainly for fast, deterministic tests. */
26
+ limits?: Partial<SandboxLimits>;
27
+ /** Omitted for a dry run (no real agent) — secrets.get always resolves undefined. */
28
+ secrets?: SecretsAccessor;
29
+ /** Overrides the default shared logger — mainly for tests that need to capture forwarded console output. */
30
+ logger?: Logger;
31
+ /** Forwarded to installHostFunctions — which hosts this tool attachment may fetch. Omitted/empty = no outbound fetch at all; a literal "*" element lifts the restriction. */
32
+ allowedFetchHosts?: string[];
33
+ }
34
+ export declare function runInSandbox(invocation: SandboxInvocation): Promise<SandboxResult>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Orchestrates one sandboxed tool invocation: full host API (fetch,
3
+ * datastore, parsers, etc.) installed, fresh runtime/context per call
4
+ * (isolation — no state bleeds between calls; persistent state is the
5
+ * datastore's job). Never lets a tool failure escape as anything other
6
+ * than a structured `SandboxResult` — a throw, timeout, memory
7
+ * exhaustion, or non-serializable return all fail *that call* cleanly
8
+ * instead of crashing the run or the host process.
9
+ */
10
+ import { installHostFunctions } from "./host-functions.js";
11
+ import { SANDBOX_PRELUDE } from "./prelude.js";
12
+ import { evalToJson, NON_SERIALIZABLE_MARKER } from "./eval-core.js";
13
+ import { boundedJson, boundedString } from "./bounded-json.js";
14
+ import { BRIDGE_INPUT_BYTES } from "./limits.js";
15
+ export async function runInSandbox(invocation) {
16
+ let params;
17
+ try {
18
+ boundedString(invocation.code, BRIDGE_INPUT_BYTES);
19
+ params = boundedJson(invocation.params, BRIDGE_INPUT_BYTES);
20
+ }
21
+ catch {
22
+ return { ok: false, errorKind: "memory", errorMessage: "Sandbox invocation input limit exceeded." };
23
+ }
24
+ // The final JSON.stringify is wrapped separately so a serialization
25
+ // failure (e.g. a circular reference) is tagged distinctly from the tool
26
+ // body itself throwing — both "fail cleanly", but the caller should be
27
+ // able to tell "your tool has a bug" from "your tool's result can't
28
+ // cross the boundary" apart.
29
+ const code = `${SANDBOX_PRELUDE}
30
+ (async () => {
31
+ const params = ${params};
32
+ const __result = await (async (params) => {
33
+ ${invocation.code}
34
+ })(params);
35
+ try {
36
+ return JSON.stringify(__result === undefined ? null : __result);
37
+ } catch (__serializeErr) {
38
+ throw new Error("${NON_SERIALIZABLE_MARKER}" + (__serializeErr && __serializeErr.message));
39
+ }
40
+ })()`;
41
+ return evalToJson(code, invocation.limits, (context, runtime, signal) => {
42
+ installHostFunctions(context, runtime, {
43
+ agentId: invocation.agentId,
44
+ datastore: invocation.datastore,
45
+ sharedDatastore: invocation.sharedDatastore,
46
+ logTag: invocation.toolName,
47
+ secrets: invocation.secrets,
48
+ logger: invocation.logger,
49
+ allowedFetchHosts: invocation.allowedFetchHosts,
50
+ signal,
51
+ });
52
+ });
53
+ }
@@ -0,0 +1,26 @@
1
+ import { type IncomingMessage } from "node:http";
2
+ import type { LookupFunction } from "node:net";
3
+ import { resolveDestination, type FetchPolicyOptions } from "./fetch-policy.js";
4
+ type Destination = Awaited<ReturnType<typeof resolveDestination>>;
5
+ export interface SafeFetchInit {
6
+ method?: string;
7
+ headers?: Record<string, string>;
8
+ body?: string;
9
+ }
10
+ export declare function pinnedLookup(destination: Destination): LookupFunction;
11
+ export declare function requestPinned(destination: Destination, init: SafeFetchInit, signal: AbortSignal): Promise<IncomingMessage>;
12
+ export interface SafeFetchOptions extends FetchPolicyOptions {
13
+ signal?: AbortSignal;
14
+ connect?: typeof requestPinned;
15
+ }
16
+ export declare function safeFetch(input: string, init?: SafeFetchInit, options?: SafeFetchOptions): Promise<{
17
+ ok: boolean;
18
+ status: number;
19
+ statusText: string;
20
+ url: string;
21
+ headers: {
22
+ [k: string]: string;
23
+ };
24
+ bodyBase64: string;
25
+ }>;
26
+ export {};