eve 0.7.3 → 0.8.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 (349) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +11 -11
  3. package/dist/src/chunks/{use-eve-agent-DErQj5hs.js → use-eve-agent-BSXZSn-R.js} +6 -1
  4. package/dist/src/chunks/{use-eve-agent-DoR8C4i6.js → use-eve-agent-Dlut2Qzt.js} +6 -1
  5. package/dist/src/cli/commands/init.js +1 -1
  6. package/dist/src/cli/dev/tui/blocks.d.ts +1 -1
  7. package/dist/src/cli/dev/tui/blocks.js +8 -7
  8. package/dist/src/cli/dev/tui/command-typeahead.d.ts +13 -3
  9. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  10. package/dist/src/cli/dev/tui/line-editor.d.ts +6 -0
  11. package/dist/src/cli/dev/tui/line-editor.js +1 -1
  12. package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +2 -0
  13. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  14. package/dist/src/cli/dev/tui/runner.d.ts +10 -0
  15. package/dist/src/cli/dev/tui/runner.js +1 -1
  16. package/dist/src/cli/dev/tui/setup-commands.d.ts +11 -7
  17. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  18. package/dist/src/cli/dev/tui/setup-flow.d.ts +72 -10
  19. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  20. package/dist/src/cli/dev/tui/setup-panel.d.ts +91 -39
  21. package/dist/src/cli/dev/tui/setup-panel.js +3 -1
  22. package/dist/src/cli/dev/tui/setup-selection-input.d.ts +48 -0
  23. package/dist/src/cli/dev/tui/setup-selection-input.js +1 -0
  24. package/dist/src/cli/dev/tui/status-line.d.ts +13 -7
  25. package/dist/src/cli/dev/tui/status-line.js +1 -1
  26. package/dist/src/cli/dev/tui/stream-format.d.ts +2 -0
  27. package/dist/src/cli/dev/tui/stream-format.js +2 -2
  28. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +4 -2
  29. package/dist/src/cli/dev/tui/terminal-renderer.js +7 -6
  30. package/dist/src/cli/dev/tui/terminal-text.d.ts +1 -0
  31. package/dist/src/cli/dev/tui/terminal-text.js +1 -1
  32. package/dist/src/cli/dev/tui/theme.d.ts +3 -1
  33. package/dist/src/cli/dev/tui/theme.js +1 -1
  34. package/dist/src/cli/dev/tui/tool-format.d.ts +1 -1
  35. package/dist/src/cli/dev/tui/tool-format.js +2 -2
  36. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  37. package/dist/src/cli/dev/tui/tui.d.ts +6 -0
  38. package/dist/src/cli/dev/tui/tui.js +1 -1
  39. package/dist/src/cli/dev/tui/vercel-status.d.ts +4 -4
  40. package/dist/src/cli/dev/tui/vercel-status.js +1 -1
  41. package/dist/src/cli/run.d.ts +4 -3
  42. package/dist/src/cli/run.js +2 -2
  43. package/dist/src/cli/ui/output.d.ts +1 -0
  44. package/dist/src/cli/ui/output.js +8 -8
  45. package/dist/src/client/client.js +1 -1
  46. package/dist/src/client/session-utils.d.ts +1 -0
  47. package/dist/src/client/session-utils.js +1 -1
  48. package/dist/src/client/session.d.ts +1 -0
  49. package/dist/src/client/session.js +1 -1
  50. package/dist/src/client/types.d.ts +19 -0
  51. package/dist/src/compiled/.vendor-stamp.json +1 -2
  52. package/dist/src/compiler/compile-from-memory.js +1 -1
  53. package/dist/src/compiler/manifest.d.ts +28 -7
  54. package/dist/src/compiler/manifest.js +1 -1
  55. package/dist/src/compiler/normalize-agent-config.js +1 -1
  56. package/dist/src/compiler/normalize-sandbox.js +1 -1
  57. package/dist/src/context/providers/session.js +1 -1
  58. package/dist/src/evals/cli/eval-client.js +1 -1
  59. package/dist/src/execution/durable-session-store.js +1 -1
  60. package/dist/src/execution/sandbox/bash-tool.js +1 -1
  61. package/dist/src/execution/sandbox/bindings/docker-base-setup.d.ts +9 -0
  62. package/dist/src/execution/sandbox/bindings/docker-base-setup.js +2 -0
  63. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +77 -0
  64. package/dist/src/execution/sandbox/bindings/docker-cli.js +2 -0
  65. package/dist/src/execution/sandbox/bindings/docker-container.d.ts +16 -0
  66. package/dist/src/execution/sandbox/bindings/docker-container.js +1 -0
  67. package/dist/src/execution/sandbox/bindings/docker-network.d.ts +8 -0
  68. package/dist/src/execution/sandbox/bindings/docker-network.js +1 -0
  69. package/dist/src/execution/sandbox/bindings/docker-options.d.ts +21 -0
  70. package/dist/src/execution/sandbox/bindings/docker-options.js +1 -0
  71. package/dist/src/execution/sandbox/bindings/docker-session.d.ts +7 -0
  72. package/dist/src/execution/sandbox/bindings/docker-session.js +2 -0
  73. package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +35 -0
  74. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -0
  75. package/dist/src/execution/sandbox/bindings/docker-utils.d.ts +2 -0
  76. package/dist/src/execution/sandbox/bindings/docker-utils.js +1 -0
  77. package/dist/src/execution/sandbox/bindings/docker.d.ts +33 -0
  78. package/dist/src/execution/sandbox/bindings/docker.js +1 -0
  79. package/dist/src/execution/sandbox/bindings/just-bash-runtime.d.ts +30 -0
  80. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -0
  81. package/dist/src/execution/sandbox/bindings/just-bash.d.ts +33 -0
  82. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -0
  83. package/dist/src/execution/sandbox/bindings/local-backend-utils.d.ts +23 -0
  84. package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -0
  85. package/dist/src/execution/sandbox/bindings/local-template-prune.d.ts +16 -0
  86. package/dist/src/execution/sandbox/bindings/local-template-prune.js +1 -0
  87. package/dist/src/execution/sandbox/bindings/local.d.ts +16 -25
  88. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  89. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.d.ts +16 -0
  90. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -0
  91. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.d.ts +21 -0
  92. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +1 -0
  93. package/dist/src/execution/sandbox/bindings/microsandbox-network.d.ts +18 -0
  94. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -0
  95. package/dist/src/execution/sandbox/bindings/microsandbox-options.d.ts +34 -0
  96. package/dist/src/execution/sandbox/bindings/microsandbox-options.js +1 -0
  97. package/dist/src/execution/sandbox/bindings/microsandbox-platform.d.ts +22 -0
  98. package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +178 -0
  99. package/dist/src/execution/sandbox/bindings/microsandbox-process.d.ts +3 -0
  100. package/dist/src/execution/sandbox/bindings/microsandbox-process.js +1 -0
  101. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +75 -0
  102. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -0
  103. package/dist/src/execution/sandbox/bindings/microsandbox-templates.d.ts +13 -0
  104. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -0
  105. package/dist/src/execution/sandbox/bindings/microsandbox.d.ts +22 -0
  106. package/dist/src/execution/sandbox/bindings/microsandbox.js +1 -0
  107. package/dist/src/execution/sandbox/bindings/vercel-create-api.d.ts +20 -0
  108. package/dist/src/execution/sandbox/bindings/vercel-create-api.js +1 -0
  109. package/dist/src/execution/sandbox/bindings/vercel.d.ts +7 -8
  110. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  111. package/dist/src/execution/sandbox/development-cleanup.d.ts +4 -0
  112. package/dist/src/execution/sandbox/development-cleanup.js +1 -0
  113. package/dist/src/execution/sandbox/development-prewarm.d.ts +11 -0
  114. package/dist/src/execution/sandbox/development-prewarm.js +1 -0
  115. package/dist/src/execution/sandbox/development-run.d.ts +8 -0
  116. package/dist/src/execution/sandbox/development-run.js +1 -0
  117. package/dist/src/execution/sandbox/ensure.js +1 -1
  118. package/dist/src/execution/sandbox/grep-tool.js +1 -1
  119. package/dist/src/execution/sandbox/lazy-backend.d.ts +1 -1
  120. package/dist/src/execution/sandbox/logging-session.d.ts +5 -0
  121. package/dist/src/execution/sandbox/logging-session.js +1 -0
  122. package/dist/src/execution/sandbox/prewarm.js +1 -1
  123. package/dist/src/execution/sandbox/template-prewarm-lock.d.ts +8 -0
  124. package/dist/src/execution/sandbox/template-prewarm-lock.js +1 -0
  125. package/dist/src/execution/workflow-steps.js +1 -1
  126. package/dist/src/harness/step-hooks.js +1 -1
  127. package/dist/src/harness/tool-loop.js +1 -1
  128. package/dist/src/internal/application/optional-package-install.d.ts +40 -0
  129. package/dist/src/internal/application/optional-package-install.js +1 -0
  130. package/dist/src/internal/application/package.js +1 -1
  131. package/dist/src/internal/authored-definition/sandbox.d.ts +1 -1
  132. package/dist/src/internal/authored-definition/sandbox.js +1 -1
  133. package/dist/src/internal/authored-module-loader.js +2 -2
  134. package/dist/src/internal/classify-model-routing.d.ts +24 -0
  135. package/dist/src/internal/classify-model-routing.js +1 -0
  136. package/dist/src/internal/nitro/host/channel-routes.js +2 -2
  137. package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.d.ts +5 -2
  138. package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.js +1 -1
  139. package/dist/src/internal/nitro/host/create-application-nitro.d.ts +10 -0
  140. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  141. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  142. package/dist/src/internal/nitro/host/dev-live-virtual-modules.d.ts +15 -0
  143. package/dist/src/internal/nitro/host/dev-live-virtual-modules.js +1 -0
  144. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.d.ts +28 -0
  145. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.js +1 -0
  146. package/dist/src/internal/nitro/host/start-development-server.js +1 -1
  147. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.d.ts +2 -0
  148. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  149. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +4 -0
  150. package/dist/src/internal/nitro/routes/info.js +1 -1
  151. package/dist/src/internal/nitro/routes/runtime-artifacts.js +1 -1
  152. package/dist/src/internal/resolve-model-endpoint-status.d.ts +23 -0
  153. package/dist/src/internal/resolve-model-endpoint-status.js +1 -0
  154. package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
  155. package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +1 -1
  156. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  157. package/dist/src/public/definitions/sandbox-backend.js +1 -1
  158. package/dist/src/public/sandbox/backends/default.d.ts +37 -10
  159. package/dist/src/public/sandbox/backends/default.js +1 -1
  160. package/dist/src/public/sandbox/backends/docker.d.ts +14 -0
  161. package/dist/src/public/sandbox/backends/docker.js +1 -0
  162. package/dist/src/public/sandbox/backends/just-bash.d.ts +17 -0
  163. package/dist/src/public/sandbox/backends/just-bash.js +1 -0
  164. package/dist/src/public/sandbox/backends/microsandbox.d.ts +17 -0
  165. package/dist/src/public/sandbox/backends/microsandbox.js +1 -0
  166. package/dist/src/public/sandbox/backends/vercel.d.ts +5 -2
  167. package/dist/src/public/sandbox/backends/vercel.js +1 -1
  168. package/dist/src/public/sandbox/docker-sandbox.d.ts +45 -0
  169. package/dist/src/public/sandbox/index.d.ts +8 -4
  170. package/dist/src/public/sandbox/index.js +1 -1
  171. package/dist/src/public/sandbox/just-bash-sandbox.d.ts +17 -0
  172. package/dist/src/public/sandbox/just-bash-sandbox.js +1 -0
  173. package/dist/src/public/sandbox/microsandbox-sandbox.d.ts +54 -0
  174. package/dist/src/public/sandbox/microsandbox-sandbox.js +1 -0
  175. package/dist/src/public/sandbox/vercel-sandbox.d.ts +1 -1
  176. package/dist/src/runtime/compiled-artifacts-source.d.ts +11 -0
  177. package/dist/src/runtime/compiled-artifacts-source.js +1 -1
  178. package/dist/src/runtime/resolve-sandbox.js +1 -1
  179. package/dist/src/runtime/sandbox/keys.js +1 -1
  180. package/dist/src/runtime/sandbox/registry.d.ts +2 -2
  181. package/dist/src/runtime/types.d.ts +1 -1
  182. package/dist/src/runtime/workspace/spec.js +1 -1
  183. package/dist/src/setup/boxes/add-channels.d.ts +3 -2
  184. package/dist/src/setup/boxes/add-channels.js +2 -2
  185. package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
  186. package/dist/src/setup/boxes/deploy-project.js +1 -1
  187. package/dist/src/setup/boxes/link-project.js +1 -1
  188. package/dist/src/setup/boxes/resolve-provisioning.d.ts +6 -0
  189. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  190. package/dist/src/setup/boxes/select-model.d.ts +2 -2
  191. package/dist/src/setup/boxes/select-model.js +1 -1
  192. package/dist/src/setup/cli/channel-setup-prompter.d.ts +28 -0
  193. package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
  194. package/dist/src/setup/cli/index.d.ts +2 -2
  195. package/dist/src/setup/cli/index.js +1 -1
  196. package/dist/src/setup/cli/option-row.d.ts +89 -0
  197. package/dist/src/setup/cli/option-row.js +1 -0
  198. package/dist/src/setup/cli/prompt-ui.d.ts +15 -29
  199. package/dist/src/setup/cli/prompt-ui.js +2 -2
  200. package/dist/src/setup/cli/select-component.d.ts +4 -3
  201. package/dist/src/setup/cli/select-component.js +1 -1
  202. package/dist/src/setup/cli/select-state.d.ts +3 -3
  203. package/dist/src/setup/cli/select-state.js +1 -1
  204. package/dist/src/setup/flows/channels.d.ts +29 -14
  205. package/dist/src/setup/flows/channels.js +1 -1
  206. package/dist/src/setup/flows/deploy.d.ts +1 -0
  207. package/dist/src/setup/flows/deploy.js +1 -1
  208. package/dist/src/setup/flows/link.d.ts +1 -0
  209. package/dist/src/setup/flows/link.js +1 -1
  210. package/dist/src/setup/flows/model.d.ts +30 -6
  211. package/dist/src/setup/flows/model.js +1 -1
  212. package/dist/src/setup/flows/vercel.d.ts +4 -1
  213. package/dist/src/setup/flows/vercel.js +2 -2
  214. package/dist/src/setup/index.js +1 -1
  215. package/dist/src/setup/primitives/open-url.d.ts +14 -0
  216. package/dist/src/setup/primitives/open-url.js +1 -0
  217. package/dist/src/setup/primitives/pm/pnpm.d.ts +9 -0
  218. package/dist/src/setup/primitives/pm/pnpm.js +2 -2
  219. package/dist/src/setup/primitives/pm/run.d.ts +12 -4
  220. package/dist/src/setup/primitives/pm/run.js +1 -1
  221. package/dist/src/setup/primitives/pm/types.d.ts +3 -0
  222. package/dist/src/setup/primitives/process-abort.d.ts +7 -0
  223. package/dist/src/setup/primitives/process-abort.js +1 -0
  224. package/dist/src/setup/primitives/run-vercel.d.ts +2 -0
  225. package/dist/src/setup/primitives/run-vercel.js +1 -1
  226. package/dist/src/setup/project-resolution.d.ts +6 -3
  227. package/dist/src/setup/project-resolution.js +1 -1
  228. package/dist/src/setup/prompter.d.ts +63 -6
  229. package/dist/src/setup/prompter.js +1 -1
  230. package/dist/src/setup/run-vercel-link.d.ts +1 -1
  231. package/dist/src/setup/run-vercel-link.js +1 -1
  232. package/dist/src/setup/runner.d.ts +2 -0
  233. package/dist/src/setup/runner.js +1 -1
  234. package/dist/src/setup/scaffold/channels-catalog.d.ts +2 -0
  235. package/dist/src/setup/scaffold/channels-catalog.js +1 -1
  236. package/dist/src/setup/scaffold/create/add-to-project.d.ts +1 -0
  237. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  238. package/dist/src/setup/scaffold/create/project.d.ts +2 -0
  239. package/dist/src/setup/scaffold/create/project.js +6 -3
  240. package/dist/src/setup/scaffold/update/channels.d.ts +2 -0
  241. package/dist/src/setup/scaffold/update/channels.js +3 -3
  242. package/dist/src/setup/slack-connect-lifecycle.d.ts +97 -0
  243. package/dist/src/setup/slack-connect-lifecycle.js +1 -0
  244. package/dist/src/setup/slack-connect.d.ts +51 -0
  245. package/dist/src/setup/slack-connect.js +1 -0
  246. package/dist/src/setup/slackbot.d.ts +60 -47
  247. package/dist/src/setup/slackbot.js +1 -1
  248. package/dist/src/setup/state.d.ts +2 -1
  249. package/dist/src/setup/state.js +1 -1
  250. package/dist/src/setup/step.d.ts +4 -0
  251. package/dist/src/setup/validate-gateway-key.d.ts +30 -0
  252. package/dist/src/setup/validate-gateway-key.js +1 -0
  253. package/dist/src/setup/vercel-project.d.ts +19 -12
  254. package/dist/src/setup/vercel-project.js +1 -1
  255. package/dist/src/shared/agent-definition.d.ts +26 -0
  256. package/dist/src/shared/model-endpoint-status.d.ts +27 -0
  257. package/dist/src/shared/model-endpoint-status.js +1 -0
  258. package/dist/src/shared/sandbox-backend.d.ts +8 -2
  259. package/dist/src/shared/sandbox-definition.d.ts +4 -3
  260. package/dist/src/shared/sandbox-network-policy.d.ts +4 -2
  261. package/dist/src/shared/sandbox-session.d.ts +3 -2
  262. package/dist/src/svelte/index.js +1 -1
  263. package/dist/src/svelte/use-eve-agent.js +1 -1
  264. package/dist/src/vue/index.js +1 -1
  265. package/dist/src/vue/use-eve-agent.js +1 -1
  266. package/{dist/docs/public → docs}/getting-started.mdx +14 -4
  267. package/{dist/docs/public → docs}/guides/deployment.md +3 -3
  268. package/{dist/docs/public → docs}/guides/dev-tui.md +2 -2
  269. package/{dist/docs/public → docs}/reference/cli.md +2 -1
  270. package/{dist/docs/public → docs}/sandbox.mdx +39 -15
  271. package/package.json +11 -1
  272. package/dist/src/compiled/just-bash/LICENSE +0 -201
  273. package/dist/src/compiled/just-bash/index.d.ts +0 -139
  274. package/dist/src/compiled/just-bash/index.js +0 -2200
  275. package/dist/src/compiled/just-bash/network/types.d.ts +0 -155
  276. package/dist/src/public/sandbox/backends/local.d.ts +0 -16
  277. package/dist/src/public/sandbox/backends/local.js +0 -1
  278. package/dist/src/public/sandbox/local-sandbox.d.ts +0 -7
  279. /package/dist/src/public/sandbox/{local-sandbox.js → docker-sandbox.js} +0 -0
  280. /package/{dist/docs/public → docs}/README.md +0 -0
  281. /package/{dist/docs/public → docs}/agent-config.md +0 -0
  282. /package/{dist/docs/public → docs}/channels/custom.mdx +0 -0
  283. /package/{dist/docs/public → docs}/channels/discord.mdx +0 -0
  284. /package/{dist/docs/public → docs}/channels/eve.mdx +0 -0
  285. /package/{dist/docs/public → docs}/channels/github.mdx +0 -0
  286. /package/{dist/docs/public → docs}/channels/linear.mdx +0 -0
  287. /package/{dist/docs/public → docs}/channels/meta.json +0 -0
  288. /package/{dist/docs/public → docs}/channels/overview.mdx +0 -0
  289. /package/{dist/docs/public → docs}/channels/slack.mdx +0 -0
  290. /package/{dist/docs/public → docs}/channels/teams.mdx +0 -0
  291. /package/{dist/docs/public → docs}/channels/telegram.mdx +0 -0
  292. /package/{dist/docs/public → docs}/channels/twilio.mdx +0 -0
  293. /package/{dist/docs/public → docs}/concepts/context-control.md +0 -0
  294. /package/{dist/docs/public → docs}/concepts/default-harness.md +0 -0
  295. /package/{dist/docs/public → docs}/concepts/execution-model-and-durability.md +0 -0
  296. /package/{dist/docs/public → docs}/concepts/meta.json +0 -0
  297. /package/{dist/docs/public → docs}/concepts/security-model.md +0 -0
  298. /package/{dist/docs/public → docs}/concepts/sessions-runs-and-streaming.md +0 -0
  299. /package/{dist/docs/public → docs}/connections.mdx +0 -0
  300. /package/{dist/docs/public → docs}/evals/assertions.mdx +0 -0
  301. /package/{dist/docs/public → docs}/evals/cases.mdx +0 -0
  302. /package/{dist/docs/public → docs}/evals/judge.mdx +0 -0
  303. /package/{dist/docs/public → docs}/evals/meta.json +0 -0
  304. /package/{dist/docs/public → docs}/evals/overview.mdx +0 -0
  305. /package/{dist/docs/public → docs}/evals/reporters.mdx +0 -0
  306. /package/{dist/docs/public → docs}/evals/running.mdx +0 -0
  307. /package/{dist/docs/public → docs}/evals/targets.mdx +0 -0
  308. /package/{dist/docs/public → docs}/guides/auth-and-route-protection.md +0 -0
  309. /package/{dist/docs/public → docs}/guides/client/continuations.mdx +0 -0
  310. /package/{dist/docs/public → docs}/guides/client/messages.mdx +0 -0
  311. /package/{dist/docs/public → docs}/guides/client/meta.json +0 -0
  312. /package/{dist/docs/public → docs}/guides/client/output-schema.mdx +0 -0
  313. /package/{dist/docs/public → docs}/guides/client/overview.mdx +0 -0
  314. /package/{dist/docs/public → docs}/guides/client/streaming.mdx +0 -0
  315. /package/{dist/docs/public → docs}/guides/dynamic-capabilities.md +0 -0
  316. /package/{dist/docs/public → docs}/guides/dynamic-workflows.md +0 -0
  317. /package/{dist/docs/public → docs}/guides/frontend/meta.json +0 -0
  318. /package/{dist/docs/public → docs}/guides/frontend/nextjs.mdx +0 -0
  319. /package/{dist/docs/public → docs}/guides/frontend/nuxt.mdx +0 -0
  320. /package/{dist/docs/public → docs}/guides/frontend/overview.mdx +0 -0
  321. /package/{dist/docs/public → docs}/guides/frontend/sveltekit.mdx +0 -0
  322. /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-svelte.mdx +0 -0
  323. /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-vue.mdx +0 -0
  324. /package/{dist/docs/public → docs}/guides/hooks.md +0 -0
  325. /package/{dist/docs/public → docs}/guides/instrumentation.md +0 -0
  326. /package/{dist/docs/public → docs}/guides/meta.json +0 -0
  327. /package/{dist/docs/public → docs}/guides/remote-agents.md +0 -0
  328. /package/{dist/docs/public → docs}/guides/session-context.md +0 -0
  329. /package/{dist/docs/public → docs}/guides/state.md +0 -0
  330. /package/{dist/docs/public → docs}/instructions.mdx +0 -0
  331. /package/{dist/docs/public → docs}/introduction.md +0 -0
  332. /package/{dist/docs/public → docs}/meta.json +0 -0
  333. /package/{dist/docs/public → docs}/reference/meta.json +0 -0
  334. /package/{dist/docs/public → docs}/reference/project-layout.md +0 -0
  335. /package/{dist/docs/public → docs}/reference/typescript-api.md +0 -0
  336. /package/{dist/docs/public → docs}/schedules.mdx +0 -0
  337. /package/{dist/docs/public → docs}/skills.mdx +0 -0
  338. /package/{dist/docs/public → docs}/subagents.mdx +0 -0
  339. /package/{dist/docs/public → docs}/tools.mdx +0 -0
  340. /package/{dist/docs/public → docs}/tutorial/connect-a-warehouse.mdx +0 -0
  341. /package/{dist/docs/public → docs}/tutorial/first-agent.mdx +0 -0
  342. /package/{dist/docs/public → docs}/tutorial/guard-the-spend.mdx +0 -0
  343. /package/{dist/docs/public → docs}/tutorial/how-it-runs.mdx +0 -0
  344. /package/{dist/docs/public → docs}/tutorial/meta.json +0 -0
  345. /package/{dist/docs/public → docs}/tutorial/query-sample-data.mdx +0 -0
  346. /package/{dist/docs/public → docs}/tutorial/remember-definitions.mdx +0 -0
  347. /package/{dist/docs/public → docs}/tutorial/run-analysis.mdx +0 -0
  348. /package/{dist/docs/public → docs}/tutorial/ship-it.mdx +0 -0
  349. /package/{dist/docs/public → docs}/tutorial/team-playbooks.mdx +0 -0
@@ -0,0 +1,23 @@
1
+ import type { SandboxSeedFile } from "#shared/sandbox-backend.js";
2
+ import type { InternalSandboxSession, SandboxProcess, SandboxRemovePathOptions, SandboxSession, SandboxSpawnOptions } from "#shared/sandbox-session.js";
3
+ export interface FileBackedSandbox {
4
+ readFileBytes(path: string): Promise<Buffer | null>;
5
+ removePath(options: SandboxRemovePathOptions): Promise<void>;
6
+ spawn(options: SandboxSpawnOptions): Promise<SandboxProcess>;
7
+ writeFiles(files: ReadonlyArray<{
8
+ readonly path: string;
9
+ readonly content: Uint8Array;
10
+ }>): Promise<void>;
11
+ }
12
+ export declare function createFileBackedInternalSandboxSession(input: {
13
+ readonly id: string;
14
+ readonly sandbox: FileBackedSandbox;
15
+ }): InternalSandboxSession;
16
+ export declare function resolveWorkspacePath(path: string): string;
17
+ export declare function pathExists(path: string): Promise<boolean>;
18
+ export declare function copyDirectoryAtomically(sourcePath: string, targetPath: string): Promise<void>;
19
+ export declare function touchDirectory(path: string): Promise<void>;
20
+ export declare function resolveLocalBackendTemplateRootPath(cacheDirectory: string, backendCacheName: string, templateKey: string): string;
21
+ export declare function resolveLocalBackendTemplatesDirectory(cacheDirectory: string, backendCacheName: string): string;
22
+ export declare function resolveLocalBackendSessionRootPath(cacheDirectory: string, backendCacheName: string, sessionKey: string): string;
23
+ export declare function writeSandboxSeedFiles(session: Pick<SandboxSession, "writeBinaryFile" | "writeTextFile">, seedFiles: ReadonlyArray<SandboxSeedFile>): Promise<void>;
@@ -0,0 +1 @@
1
+ import{dirname,join}from"node:path";import{access,cp,mkdir,rename,rm,utimes}from"node:fs/promises";import{randomUUID}from"node:crypto";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{bufferToStream,streamToBuffer}from"#execution/sandbox/stream-utils.js";function createFileBackedInternalSandboxSession(e){return{id:e.id,resolvePath:resolveWorkspacePath,async spawn(t){return await e.sandbox.spawn(t)},async readFile(t){let n=await e.sandbox.readFileBytes(t.path);return n===null?null:bufferToStream(n)},async removePath(t){await e.sandbox.removePath(t)},async writeFile(t){let n=await streamToBuffer(t.content);await e.sandbox.writeFiles([{content:n,path:t.path}])}}}function resolveWorkspacePath(e){return e.startsWith(`/`)?e:`${WORKSPACE_ROOT}/${e}`}async function pathExists(e){try{return await access(e),!0}catch{return!1}}async function copyDirectoryAtomically(t,n){let i=`${n}.${randomUUID()}.tmp`;await rm(i,{force:!0,recursive:!0}),await mkdir(dirname(n),{recursive:!0});try{await cp(t,i,{recursive:!0}),await rename(i,n)}catch(e){if(await rm(i,{force:!0,recursive:!0}).catch(()=>{}),await pathExists(n))return;throw e}}async function touchDirectory(e){let t=new Date;await utimes(e,t,t)}function resolveLocalBackendTemplateRootPath(e,n,r){return join(resolveLocalBackendTemplatesDirectory(e,n),r)}function resolveLocalBackendTemplatesDirectory(e,n){return join(e,n,`templates`)}function resolveLocalBackendSessionRootPath(e,n,r){return join(e,n,`sessions`,r)}async function writeSandboxSeedFiles(e,t){for(let n of t)typeof n.content==`string`?await e.writeTextFile({content:n.content,path:n.path}):await e.writeBinaryFile({content:n.content,path:n.path})}export{copyDirectoryAtomically,createFileBackedInternalSandboxSession,pathExists,resolveLocalBackendSessionRootPath,resolveLocalBackendTemplateRootPath,resolveLocalBackendTemplatesDirectory,resolveWorkspacePath,touchDirectory,writeSandboxSeedFiles};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared staleness selection for local sandbox template stores (the
3
+ * just-bash directory cache and the Docker template-image markers).
4
+ *
5
+ * An entry is stale when it is neither among the `retainCount` most
6
+ * recently used entries nor used within the trailing `recentWindowMs`.
7
+ */
8
+ export declare function selectStaleTemplateEntries<T extends {
9
+ readonly mtimeMs: number;
10
+ }>(entries: readonly T[], input: {
11
+ readonly now: number;
12
+ readonly recentWindowMs: number;
13
+ readonly retainCount: number;
14
+ }): T[];
15
+ export declare const LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS: number;
16
+ export declare const LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT = 5;
@@ -0,0 +1 @@
1
+ function selectStaleTemplateEntries(e,t){return[...e].sort((e,t)=>t.mtimeMs-e.mtimeMs).filter((e,n)=>n>=t.retainCount&&t.now-e.mtimeMs>t.recentWindowMs)}const LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS=900*1e3,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT=5;export{LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,selectStaleTemplateEntries};
@@ -1,33 +1,24 @@
1
- import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
2
- import type { LocalSandboxCreateOptions } from "#public/sandbox/local-sandbox.js";
1
+ export { createDockerSandboxBackend, DOCKER_BACKEND_NAME, pruneDockerSandboxTemplates, } from "#execution/sandbox/bindings/docker.js";
2
+ export { isDockerDaemonAvailableSync } from "#execution/sandbox/bindings/docker-cli.js";
3
+ export { createJustBashSandboxBackend, JUST_BASH_BACKEND_NAME, pruneJustBashSandboxTemplates, } from "#execution/sandbox/bindings/just-bash.js";
4
+ export { createMicrosandboxSandboxBackend, MICROSANDBOX_BACKEND_NAME, pruneMicrosandboxTemplates, } from "#execution/sandbox/bindings/microsandbox.js";
5
+ export { isMicrosandboxPlatformSupported } from "#execution/sandbox/bindings/microsandbox-platform.js";
6
+ export { stopDevelopmentSandboxResources } from "#execution/sandbox/development-cleanup.js";
3
7
  /**
4
- * Construction input for {@link createLocalSandboxBackend}. Internal
5
- * the public surface is the `localBackend()` factory under
6
- * `eve/sandbox`.
8
+ * Removes stale local sandbox template state for one application
9
+ * across every local engine: just-bash template directories, Docker
10
+ * template images (tracked through per-app marker files), and
11
+ * microsandbox template snapshots. Docker pruning silently skips when
12
+ * no Docker runtime is reachable so docker-less setups stay quiet.
7
13
  */
8
- export interface CreateLocalSandboxBackendInput {
9
- readonly createOptions?: LocalSandboxCreateOptions;
10
- }
11
- /**
12
- * Creates the local just-bash-backed sandbox backend.
13
- *
14
- * The cache directory is derived from the runtime context's `appRoot`
15
- * on every `create` call so the backend stays stateless and matches
16
- * the framework's per-call dispatch contract.
17
- *
18
- * Accepts `createOptions` for parity with other backends; the local
19
- * backend currently has no consumer-controllable create options so the
20
- * value is reserved for future widening of {@link LocalSandboxCreateOptions}.
21
- */
22
- export declare function createLocalSandboxBackend(_input?: CreateLocalSandboxBackendInput): SandboxBackend;
23
- /**
24
- * Starts best-effort cleanup for stale local just-bash templates without
25
- * delaying `eve dev` startup or rebuild handling.
26
- */
27
- export declare function pruneLocalSandboxTemplatesInBackground(appRoot: string): void;
28
14
  export declare function pruneLocalSandboxTemplates(input: {
29
15
  readonly appRoot: string;
30
16
  readonly now?: number;
31
17
  readonly recentWindowMs?: number;
32
18
  readonly retainCount?: number;
33
19
  }): Promise<void>;
20
+ /**
21
+ * Starts best-effort cleanup for stale local sandbox templates without
22
+ * delaying `eve dev` startup or rebuild handling.
23
+ */
24
+ export declare function pruneLocalSandboxTemplatesInBackground(appRoot: string): void;
@@ -1 +1 @@
1
- import{dirname,join}from"node:path";import"node:fs";import{access,cp,mkdir,readFile,readdir,rename,rm,stat,utimes,writeFile}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{bufferToStream,streamToBuffer}from"#execution/sandbox/stream-utils.js";function createLocalSandboxBackend(t={}){return{name:`local`,async prewarm(t){let n=resolveTemplateRootPath(resolveSandboxCacheDirectory(t.runtimeContext.appRoot),t.templateKey);if(await doesPathExist(n))return await touchDirectory(n),{reused:!0};let r=`${n}.${randomUUID()}.tmp`,a=!1,o=await createBashSandbox({rootPath:r,sessionKey:t.templateKey}),l=buildSandboxSession(createLocalInternalSandboxSession(o),localSetNetworkPolicyUnsupported);try{t.bootstrap!==void 0&&await t.bootstrap({use:async()=>l});for(let e of t.seedFiles)typeof e.content==`string`?await l.writeTextFile({content:e.content,path:e.path}):await l.writeBinaryFile({content:e.content,path:e.path});if(await o.captureState()===null)throw Error(`Failed to capture local sandbox template state for "${t.templateKey}".`);await mkdir(dirname(n),{recursive:!0});try{await rename(r,n),a=!0}catch(e){if(await doesPathExist(n))return{reused:!0};throw e}}finally{await o.dispose(),a||await rm(r,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}},async create(e){let t=resolveSandboxCacheDirectory(e.runtimeContext.appRoot),n=getLocalRootPath(e.existingMetadata)??resolveSessionRootPath(t,e.sessionKey);if(!await doesPathExist(n))if(e.templateKey===null)await mkdir(n,{recursive:!0});else{let r=resolveTemplateRootPath(t,e.templateKey);if(!await doesPathExist(r))throw new SandboxTemplateNotProvisionedError({backendName:`local`,templateKey:e.templateKey});await copyDirectoryAtomically(r,n)}return createHandle(await createBashSandbox({rootPath:n,sessionKey:e.sessionKey}))}}}function pruneLocalSandboxTemplatesInBackground(e){pruneLocalSandboxTemplates({appRoot:e}).catch(e=>{console.warn(`[eve:dev] failed to prune stale local sandbox templates: ${errorMessage(e)}`)})}async function pruneLocalSandboxTemplates(e){let n=resolveTemplatesDirectory(resolveSandboxCacheDirectory(e.appRoot)),r=e.now??Date.now(),i=e.recentWindowMs??9e5,a=e.retainCount??5,s;try{s=await readdir(n,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let u=(await Promise.all(s.filter(e=>e.isDirectory()).map(async e=>{let r=join(n,e.name);return{isTemporary:e.name.endsWith(`.tmp`),mtimeMs:(await stat(r)).mtimeMs,path:r}}))).sort((e,t)=>t.mtimeMs-e.mtimeMs),d=u.filter(e=>!e.isTemporary);await Promise.all([...d.map(async(e,t)=>{t<a||r-e.mtimeMs<=i||await rm(e.path,{force:!0,recursive:!0})}),...u.filter(e=>e.isTemporary).map(async e=>{r-e.mtimeMs<=i||await rm(e.path,{force:!0,recursive:!0})})])}async function copyDirectoryAtomically(t,n){let a=`${n}.${randomUUID()}.tmp`;await rm(a,{force:!0,recursive:!0}),await mkdir(dirname(n),{recursive:!0});try{await cp(t,a,{recursive:!0}),await rename(a,n)}catch(e){if(await rm(a,{force:!0,recursive:!0}).catch(()=>{}),await doesPathExist(n))return;throw e}}async function createBashSandbox(t){let{ReadWriteFs:n,Sandbox:r}=await import(`#compiled/just-bash/index.js`),a=resolveLocalSandboxFilesystemRootPath(t.rootPath),o=resolveLocalSandboxMetadataPath(t.rootPath),s=await readLocalMetadata(o);await mkdir(a,{recursive:!0});let c=new n({allowSymlinks:!0,maxFileReadSize:2**53-1,root:a});await ensureLocalSandboxDirectories(c);let l=await r.create({cwd:WORKSPACE_ROOT,env:s?.env,fs:c,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureState(){return await writeLocalMetadata(o,{env:{...l.bashEnvInstance.getEnv()},version:1}),{rootPath:t.rootPath}},async dispose(){await l.stop()},async readFileBytes(e){let t;try{t=await c.readFileBuffer(e)}catch{return null}return Buffer.from(t)},async removePath(e){await c.rm(e.path,{force:e.force,recursive:e.recursive})},rootPath:t.rootPath,sessionKey:t.sessionKey,async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=e.workingDirectory===void 0?e.command:`( cd ${shellQuote(e.workingDirectory)} && ${e.command} )`;return adaptJustBashCommandToSandboxProcess(await l.runCommand({args:[t],cmd:`eval`,detached:!0,env:e.env,signal:e.abortSignal}))},async writeFiles(t){for(let n of t){let t=dirname(n.path);await c.mkdir(t,{recursive:!0}),await c.writeFile(n.path,n.content)}}}}function adaptJustBashCommandToSandboxProcess(e){let t=new TextEncoder,n,r,i=!1,a,o=new ReadableStream({start(e){n=e}}),s=new ReadableStream({start(e){r=e}});return(async()=>{try{for await(let i of e.logs()){let e=t.encode(i.data);i.type===`stdout`?n?.enqueue(e):r?.enqueue(e)}}catch(e){a=e,n?.error(e),r?.error(e)}finally{i=!0,a===void 0&&(n?.close(),r?.close())}})(),{stdout:o,stderr:s,async wait(){let t=await e.wait();for(;!i;)await new Promise(e=>setTimeout(e,0));if(a!==void 0)throw a;return{exitCode:t.exitCode}},async kill(){await e.kill()}}}async function localSetNetworkPolicyUnsupported(){throw Error(`setNetworkPolicy() is not supported on the local sandbox backend. just-bash applies its network policy only at sandbox creation (no run-time update) and does not run git or other binaries. Use the Vercel backend for credential brokering and egress control.`)}function createHandle(e){let t=buildSandboxSession(createLocalInternalSandboxSession(e),localSetNetworkPolicyUnsupported);return{session:t,useSessionFn:async()=>t,async captureState(){return{backendName:`local`,metadata:await e.captureState()??{},sessionKey:e.sessionKey}},async dispose(){await e.dispose()}}}function createLocalInternalSandboxSession(e){return{id:e.sessionKey,resolvePath:resolveLocalPath,async spawn(t){return await e.spawn(t)},async readFile(t){let n=await e.readFileBytes(t.path);return n===null?null:bufferToStream(n)},async removePath(t){await e.removePath(t)},async writeFile(t){let n=await streamToBuffer(t.content);await e.writeFiles([{content:n,path:t.path}])}}}function resolveLocalPath(e){return e.startsWith(`/`)?e:`${WORKSPACE_ROOT}/${e}`}function resolveTemplateRootPath(e,n){return join(resolveTemplatesDirectory(e),n)}function resolveTemplatesDirectory(e){return join(e,`local`,`templates`)}function resolveSessionRootPath(e,n){return join(e,`local`,`sessions`,n)}function resolveLocalSandboxFilesystemRootPath(e){return join(e,`fs`)}function resolveLocalSandboxMetadataPath(e){return join(e,`metadata.json`)}async function ensureLocalSandboxDirectories(e){await e.mkdir(WORKSPACE_ROOT,{recursive:!0})}async function readLocalMetadata(e){if(!await doesPathExist(e))return null;let t=JSON.parse(await readFile(e,`utf8`));return t.version!==1||!isStringRecord(t.env)?null:{env:t.env,version:1}}async function writeLocalMetadata(t,n){await mkdir(dirname(t),{recursive:!0}),await writeFile(t,`${JSON.stringify(n,null,2)}\n`)}function getLocalRootPath(e){let t=e?.rootPath;return typeof t==`string`?t:void 0}function isStringRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&Object.values(e).every(e=>typeof e==`string`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function touchDirectory(e){let t=new Date;await utimes(e,t,t)}function errorMessage(e){return e instanceof Error?e.message:String(e)}export{createLocalSandboxBackend,pruneLocalSandboxTemplates,pruneLocalSandboxTemplatesInBackground};
1
+ import{DockerDaemonUnavailableError,DockerUnavailableError,isDockerDaemonAvailableSync}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_BACKEND_NAME,createDockerSandboxBackend,pruneDockerSandboxTemplates,pruneDockerSandboxTemplates as pruneDockerSandboxTemplates$1}from"#execution/sandbox/bindings/docker.js";import{JUST_BASH_BACKEND_NAME,createJustBashSandboxBackend,pruneJustBashSandboxTemplates,pruneJustBashSandboxTemplates as pruneJustBashSandboxTemplates$1}from"#execution/sandbox/bindings/just-bash.js";import{MICROSANDBOX_BACKEND_NAME,createMicrosandboxSandboxBackend,pruneMicrosandboxTemplates,pruneMicrosandboxTemplates as pruneMicrosandboxTemplates$1}from"#execution/sandbox/bindings/microsandbox.js";import{isMicrosandboxPlatformSupported}from"#execution/sandbox/bindings/microsandbox-platform.js";import{stopDevelopmentSandboxResources}from"#execution/sandbox/development-cleanup.js";async function pruneLocalSandboxTemplates(t){await Promise.all([pruneJustBashSandboxTemplates$1(t),pruneMicrosandboxTemplates$1(t),pruneDockerSandboxTemplates$1(t).catch(t=>{if(!(t instanceof DockerUnavailableError||t instanceof DockerDaemonUnavailableError))throw t})])}function pruneLocalSandboxTemplatesInBackground(e){pruneLocalSandboxTemplates({appRoot:e}).catch(e=>{console.warn(`[eve:dev] failed to prune stale local sandbox templates: ${errorMessage(e)}`)})}function errorMessage(e){return e instanceof Error?e.message:String(e)}export{DOCKER_BACKEND_NAME,JUST_BASH_BACKEND_NAME,MICROSANDBOX_BACKEND_NAME,createDockerSandboxBackend,createJustBashSandboxBackend,createMicrosandboxSandboxBackend,isDockerDaemonAvailableSync,isMicrosandboxPlatformSupported,pruneDockerSandboxTemplates,pruneJustBashSandboxTemplates,pruneLocalSandboxTemplates,pruneLocalSandboxTemplatesInBackground,pruneMicrosandboxTemplates,stopDevelopmentSandboxResources};
@@ -0,0 +1,16 @@
1
+ import type { ResolvedMicrosandboxOptions } from "#execution/sandbox/bindings/microsandbox-options.js";
2
+ import type { SandboxBackendCreateInput, SandboxBackendHandle, SandboxBackendPrewarmInput, SandboxBackendPrewarmResult } from "#public/definitions/sandbox-backend.js";
3
+ import type { MicrosandboxBootstrapUseOptions, MicrosandboxSessionUseOptions } from "#public/sandbox/microsandbox-sandbox.js";
4
+ export declare function prewarmMicrosandboxTemplate(input: {
5
+ readonly backendName: string;
6
+ readonly options: ResolvedMicrosandboxOptions;
7
+ readonly optionsHash: string;
8
+ readonly prewarmInput: SandboxBackendPrewarmInput<MicrosandboxBootstrapUseOptions>;
9
+ }): Promise<SandboxBackendPrewarmResult>;
10
+ export declare function createMicrosandboxHandle(input: {
11
+ readonly backendName: string;
12
+ readonly createInput: SandboxBackendCreateInput;
13
+ readonly options: ResolvedMicrosandboxOptions;
14
+ readonly optionsHash: string;
15
+ }): Promise<SandboxBackendHandle<MicrosandboxSessionUseOptions>>;
16
+ export declare function clearActiveMicrosandboxSessionHandlesForTest(): void;
@@ -0,0 +1 @@
1
+ import{dirname}from"node:path";import{mkdir,rename,rm}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{withDevelopmentSandboxMetadataPathTag}from"#execution/sandbox/development-run.js";import{createFileBackedInternalSandboxSession,touchDirectory,writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{MICROSANDBOX_METADATA_VERSION,readSessionMetadata,readSessionMetadataRecord,readTemplateMetadata,resolveMicrosandboxMetadataPath,writeTemplateMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{connectMicrosandbox,createPreparedMicrosandbox,createProviderName,doesPathExist,loadMicrosandboxModule,removeSnapshotIfExists,sandboxExists,snapshotExists}from"#execution/sandbox/bindings/microsandbox-runtime.js";import{resolveMicrosandboxSessionRootPath,resolveMicrosandboxTemplateRootPath}from"#execution/sandbox/bindings/microsandbox-templates.js";const activeMicrosandboxSessionHandles=new Map;async function prewarmMicrosandboxTemplate(i){i.prewarmInput.log?.(`loading microsandbox runtime`);let a=await loadMicrosandboxModule({appRoot:i.prewarmInput.runtimeContext.appRoot,log:i.prewarmInput.log,options:i.options}),u=resolveMicrosandboxTemplateRootPath(resolveSandboxCacheDirectory(i.prewarmInput.runtimeContext.appRoot),i.prewarmInput.templateKey),f=resolveMicrosandboxMetadataPath(u);i.prewarmInput.log?.(`checking cached snapshot`);let p=await readTemplateMetadata(f);if(p?.optionsHash===i.optionsHash&&await snapshotExists(a,p.snapshotName))return i.prewarmInput.log?.(`reusing cached snapshot`),await touchDirectory(u),{reused:!0};let h=createProviderName(`eve-sbx-tpl`,i.prewarmInput.templateKey,i.optionsHash),_=`${u}.${randomUUID()}.tmp`,v=createProviderName(`eve-sbx-tpl-tmp`,`${i.prewarmInput.templateKey}:${randomUUID()}`);await removeSnapshotIfExists(a,h),await rm(_,{force:!0,recursive:!0}),await mkdir(_,{recursive:!0}),i.prewarmInput.log?.(`creating template VM from image "${i.options.image}"`);let y=await createPreparedMicrosandbox({log:i.prewarmInput.log,module:a,name:v,networkPolicy:i.options.networkPolicy,options:i.options,sessionKey:i.prewarmInput.templateKey,setupBaseRuntime:!0,tags:void 0}),b=buildSandboxSession(createMicrosandboxInternalSession(y),async e=>{await y.setNetworkPolicy(e)});try{i.prewarmInput.bootstrap!==void 0&&(i.prewarmInput.log?.(`running sandbox bootstrap`),await i.prewarmInput.bootstrap({use:async e=>(e?.networkPolicy!==void 0&&await y.setNetworkPolicy(e.networkPolicy),createLoggingSandboxSession({log:i.prewarmInput.log,session:b}))})),i.prewarmInput.seedFiles.length>0&&i.prewarmInput.log?.(`writing ${i.prewarmInput.seedFiles.length} seed file(s)`),await writeSandboxSeedFiles(b,i.prewarmInput.seedFiles),i.prewarmInput.log?.(`snapshotting template VM`),await y.stopAndSnapshot(h),await writeTemplateMetadata(resolveMicrosandboxMetadataPath(_),{optionsHash:i.optionsHash,snapshotName:h,version:MICROSANDBOX_METADATA_VERSION}),await mkdir(dirname(u),{recursive:!0}),await rm(u,{force:!0,recursive:!0});try{await rename(_,u)}catch(e){if(await doesPathExist(u))return{reused:!0};throw e}}finally{await y.removePersisted(),await rm(_,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}}async function createMicrosandboxHandle(e){let t=await loadMicrosandboxModule({appRoot:e.createInput.runtimeContext.appRoot,options:e.options}),n=resolveSandboxCacheDirectory(e.createInput.runtimeContext.appRoot),r=resolveMicrosandboxSessionRootPath(n,e.createInput.sessionKey),a=createActiveMicrosandboxSessionKey(r,e.optionsHash),o=activeMicrosandboxSessionHandles.get(a);if(o!==void 0)return o;let s=resolveMicrosandboxMetadataPath(r),c=readSessionMetadataRecord(e.createInput.existingMetadata)??await readSessionMetadata(s),l=withDevelopmentSandboxMetadataPathTag(e.createInput.tags,s);if(c?.optionsHash===e.optionsHash&&(await sandboxExists(t,c.sandboxName)||c.stateSnapshotName!==void 0&&await snapshotExists(t,c.stateSnapshotName)))return cacheHandle(a,createHandle(await connectMicrosandbox({metadata:c,metadataPath:s,module:t,options:e.options,sessionKey:e.createInput.sessionKey,tags:l}),e.backendName,e.optionsHash,()=>{activeMicrosandboxSessionHandles.delete(a)}));let d=null;if(e.createInput.templateKey!==null){let r=await readTemplateMetadata(resolveMicrosandboxMetadataPath(resolveMicrosandboxTemplateRootPath(n,e.createInput.templateKey)));if(r===null||r.optionsHash!==e.optionsHash||!await snapshotExists(t,r.snapshotName))throw new SandboxTemplateNotProvisionedError({backendName:e.backendName,templateKey:e.createInput.templateKey});d=r.snapshotName}let m=createProviderName(`eve-sbx-ses`,`${e.createInput.sessionKey}:${randomUUID()}`),g=await createPreparedMicrosandbox({fromSnapshot:d??void 0,module:t,name:m,networkPolicy:e.options.networkPolicy,options:e.options,sessionKey:e.createInput.sessionKey,setupBaseRuntime:d===null,tags:l});return await g.writeMetadata(s,e.optionsHash),cacheHandle(a,createHandle(g,e.backendName,e.optionsHash,()=>{activeMicrosandboxSessionHandles.delete(a)}))}function createHandle(e,t,n,r){return{session:buildSandboxSession(createMicrosandboxInternalSession(e),async t=>{await e.setNetworkPolicy(t)}),useSessionFn:async t=>(t?.networkPolicy!==void 0&&await e.setNetworkPolicy(t.networkPolicy),buildSandboxSession(createMicrosandboxInternalSession(e),async t=>{await e.setNetworkPolicy(t)})),async captureState(){return{backendName:t,metadata:{...await e.captureState(n)},sessionKey:e.id}},async dispose(){r?.(),await e.detach()}}}function createMicrosandboxInternalSession(e){return createFileBackedInternalSandboxSession({id:e.id,sandbox:e})}function createActiveMicrosandboxSessionKey(e,t){return`${e}\0${t}`}function cacheHandle(e,t){return activeMicrosandboxSessionHandles.set(e,t),t}function clearActiveMicrosandboxSessionHandlesForTest(){activeMicrosandboxSessionHandles.clear()}export{clearActiveMicrosandboxSessionHandlesForTest,createMicrosandboxHandle,prewarmMicrosandboxTemplate};
@@ -0,0 +1,21 @@
1
+ import type { SandboxNetworkPolicy } from "#shared/sandbox-network-policy.js";
2
+ export declare const MICROSANDBOX_METADATA_VERSION = 2;
3
+ export declare const MICROSANDBOX_METADATA_FILE_NAME = "metadata.json";
4
+ export interface MicrosandboxTemplateMetadata {
5
+ readonly optionsHash: string;
6
+ readonly snapshotName: string;
7
+ readonly version: typeof MICROSANDBOX_METADATA_VERSION;
8
+ }
9
+ export interface MicrosandboxSessionMetadata {
10
+ readonly networkPolicy?: SandboxNetworkPolicy;
11
+ readonly optionsHash: string;
12
+ readonly sandboxName: string;
13
+ readonly stateSnapshotName?: string;
14
+ readonly version: typeof MICROSANDBOX_METADATA_VERSION;
15
+ }
16
+ export declare function resolveMicrosandboxMetadataPath(rootPath: string): string;
17
+ export declare function readTemplateMetadata(path: string): Promise<MicrosandboxTemplateMetadata | null>;
18
+ export declare function writeTemplateMetadata(path: string, metadata: MicrosandboxTemplateMetadata): Promise<void>;
19
+ export declare function readSessionMetadata(path: string): Promise<MicrosandboxSessionMetadata | null>;
20
+ export declare function readSessionMetadataRecord(value: unknown): MicrosandboxSessionMetadata | null;
21
+ export declare function writeSessionMetadata(path: string, metadata: MicrosandboxSessionMetadata): Promise<void>;
@@ -0,0 +1 @@
1
+ import{dirname,join}from"node:path";import{mkdir,readFile,rename,writeFile}from"node:fs/promises";import{randomUUID}from"node:crypto";const MICROSANDBOX_METADATA_VERSION=2,MICROSANDBOX_METADATA_FILE_NAME=`metadata.json`;function resolveMicrosandboxMetadataPath(e){return join(e,MICROSANDBOX_METADATA_FILE_NAME)}async function readTemplateMetadata(e){let t=await readJsonFile(e);return t?.version!==2||typeof t.optionsHash!=`string`||typeof t.snapshotName!=`string`?null:{optionsHash:t.optionsHash,snapshotName:t.snapshotName,version:2}}async function writeTemplateMetadata(e,t){await writeJsonFileAtomically(e,t)}async function readSessionMetadata(e){return readSessionMetadataRecord(await readJsonFile(e))}function readSessionMetadataRecord(e){return!isRecord(e)||e.version!==2||typeof e.optionsHash!=`string`||typeof e.sandboxName!=`string`?null:{networkPolicy:e.networkPolicy,optionsHash:e.optionsHash,sandboxName:e.sandboxName,stateSnapshotName:typeof e.stateSnapshotName==`string`?e.stateSnapshotName:void 0,version:2}}async function writeSessionMetadata(e,t){await writeJsonFileAtomically(e,t)}async function readJsonFile(e){try{let t=JSON.parse(await readFile(e,`utf8`));return isRecord(t)?t:null}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return null;throw e}}async function writeJsonFileAtomically(t,n){let r=`${t}.${randomUUID()}.tmp`;await mkdir(dirname(t),{recursive:!0}),await writeFile(r,`${JSON.stringify(n,null,2)}\n`),await rename(r,t)}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{MICROSANDBOX_METADATA_FILE_NAME,MICROSANDBOX_METADATA_VERSION,readSessionMetadata,readSessionMetadataRecord,readTemplateMetadata,resolveMicrosandboxMetadataPath,writeSessionMetadata,writeTemplateMetadata};
@@ -0,0 +1,18 @@
1
+ import type { SandboxNetworkPolicy } from "#shared/sandbox-network-policy.js";
2
+ import type { NetworkPolicy as MicrosandboxNetworkPolicy, SandboxBuilder as MicrosandboxSandboxBuilder } from "microsandbox";
3
+ interface MicrosandboxTransformHeaderRule {
4
+ readonly domain: string;
5
+ readonly headers: Readonly<Record<string, string>>;
6
+ readonly match?: unknown;
7
+ readonly placeholderHeaders: Readonly<Record<string, string>>;
8
+ }
9
+ export interface MicrosandboxNetworkPlan {
10
+ readonly disabled: boolean;
11
+ readonly policy: MicrosandboxNetworkPolicy | null;
12
+ readonly transformHeaderRules: readonly MicrosandboxTransformHeaderRule[];
13
+ }
14
+ export declare function applyMicrosandboxNetwork(builder: MicrosandboxSandboxBuilder, networkPolicy: SandboxNetworkPolicy | undefined): MicrosandboxSandboxBuilder;
15
+ export declare function serializeMicrosandboxNetworkPolicyJson(policy: MicrosandboxNetworkPolicy): string;
16
+ export declare function createMicrosandboxNetworkPlan(policy: SandboxNetworkPolicy | undefined): MicrosandboxNetworkPlan;
17
+ export declare function createTransformBrokerEnvironment(plan: MicrosandboxNetworkPlan): Readonly<Record<string, string>>;
18
+ export {};
@@ -0,0 +1 @@
1
+ import{createHash}from"node:crypto";function applyMicrosandboxNetwork(e,t){let n=createMicrosandboxNetworkPlan(t);return n.disabled?e.disableNetwork():n.policy===null&&n.transformHeaderRules.length===0?e:e.network(e=>{let t=e.enabled(!0);if(n.policy!==null&&(t=t.policyJson(serializeMicrosandboxNetworkPolicyJson(n.policy))),n.transformHeaderRules.length===0)return t;t=t.trustHostCAs(!0);for(let e of n.transformHeaderRules)for(let[n,r]of Object.entries(e.headers)){let i=e.placeholderHeaders[n];if(i===void 0)continue;let a=createSecretEnvName(e.domain,n,r);t=t.secret(t=>{let n=t.env(a).value(r).placeholder(i).injectHeaders(!0).injectBasicAuth(!0).injectQuery(!1).injectBody(!1).requireTlsIdentity(!0);return n=e.domain===`*`?n.allowAnyHostDangerous(!0):e.domain.startsWith(`*.`)?n.allowHostPattern(e.domain):n.allowHost(e.domain),n})}return t})}function serializeMicrosandboxNetworkPolicyJson(e){let t={default_egress:e.defaultEgress,default_ingress:e.defaultIngress,rules:e.rules.map(e=>({action:e.action,destination:serializeMicrosandboxNetworkDestination(e.destination),direction:e.direction,ports:e.ports,protocols:e.protocols}))};return JSON.stringify(t)}function createMicrosandboxNetworkPlan(e){if(e===void 0||e===`allow-all`)return{disabled:!1,policy:{defaultEgress:`allow`,defaultIngress:`deny`,rules:[]},transformHeaderRules:[]};if(e===`deny-all`)return{disabled:!0,policy:null,transformHeaderRules:[]};let t=[],n=[],r=normalizeAllowEntries(e.allow),i=r.some(e=>e.domain===`*`),a=i?`allow`:`deny`;for(let n of e.subnets?.deny??[])t.push({action:`deny`,destination:{cidr:n,kind:`cidr`},direction:`egress`,ports:[],protocols:[]});for(let n of e.subnets?.allow??[])t.push({action:`allow`,destination:{cidr:n,kind:`cidr`},direction:`egress`,ports:[],protocols:[]});i||t.push({action:`allow`,destination:{kind:`any`},direction:`egress`,ports:[{start:53,end:53}],protocols:[`udp`,`tcp`]});for(let e of r)if(e.domain!==`*`){t.push({action:`allow`,destination:domainToDestination(e.domain),direction:`egress`,ports:[],protocols:[]});for(let t of e.rules)for(let r of normalizeTransforms(t.transform))Object.keys(r.headers).length!==0&&n.push({domain:e.domain,headers:r.headers,match:t.match,placeholderHeaders:createPlaceholderHeaders(e.domain,r.headers)})}return{disabled:!1,policy:{defaultEgress:a,defaultIngress:`deny`,rules:t},transformHeaderRules:n}}function createTransformBrokerEnvironment(e){if(e.transformHeaderRules.length===0)return{};let t=e.transformHeaderRules.flatMap(e=>Object.entries(e.placeholderHeaders).filter(([e])=>e.toLowerCase()===`authorization`).flatMap(([t,n])=>e.domain===`*`||e.domain.startsWith(`*.`)?[]:[{key:`http.https://${e.domain}/.extraheader`,value:`${t}: ${n}`}])),n={};return t.length>0&&(n.GIT_CONFIG_COUNT=String(t.length),t.forEach((e,t)=>{n[`GIT_CONFIG_KEY_${t}`]=e.key,n[`GIT_CONFIG_VALUE_${t}`]=e.value})),{EVE_MICROSANDBOX_NETWORK_TRANSFORMS:Buffer.from(JSON.stringify(e.transformHeaderRules)).toString(`base64`),...n}}function normalizeAllowEntries(e){return e===void 0?[]:Array.isArray(e)?e.map(e=>({domain:e,rules:[]})):Object.entries(e).map(([e,t])=>({domain:e,rules:Array.isArray(t)?t:[]}))}function normalizeTransforms(e){return e===void 0?[]:e.map(e=>({headers:e.headers??{}}))}function domainToDestination(e){return e.startsWith(`*.`)?{kind:`domainSuffix`,suffix:e.slice(2)}:{domain:e,kind:`domain`}}function serializeMicrosandboxNetworkDestination(e){switch(e.kind){case`any`:return`any`;case`cidr`:return{cidr:e.cidr??``};case`domain`:return{domain:e.domain??``};case`domainSuffix`:return{domain_suffix:e.suffix??``};case`group`:return{group:e.group??``};default:throw Error(`Unsupported microsandbox network destination kind.`)}}function createPlaceholderHeaders(e,t){let n={};for(let[r,i]of Object.entries(t))n[r]=`__EVE_MSB_SECRET_${createStableHash(`${e}:${r}:${i}`).slice(0,24)}__`;return n}function createSecretEnvName(e,t,n){return`EVE_MSB_SECRET_${createStableHash(`${e}:${t}:${n}`).slice(0,24).toUpperCase()}`}function createStableHash(t){return createHash(`sha256`).update(t).digest(`hex`)}export{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment,serializeMicrosandboxNetworkPolicyJson};
@@ -0,0 +1,34 @@
1
+ import type { MicrosandboxCreateOptions } from "#public/sandbox/microsandbox-sandbox.js";
2
+ import type { SandboxNetworkPolicy } from "#shared/sandbox-network-policy.js";
3
+ export declare const MICROSANDBOX_DEFAULT_IMAGE = "ubuntu:26.04";
4
+ export declare const MICROSANDBOX_DEFAULT_CPUS = 1;
5
+ export declare const MICROSANDBOX_DEFAULT_MEMORY_MIB = 1024;
6
+ export declare const MICROSANDBOX_DEFAULT_PULL_POLICY = "if-missing";
7
+ /** User every sandbox command runs as, mirroring hosted Vercel Sandbox. */
8
+ export declare const MICROSANDBOX_USER = "vercel-sandbox";
9
+ /**
10
+ * Fully-defaulted microsandbox backend options consumed by the backend
11
+ * implementation.
12
+ */
13
+ export interface ResolvedMicrosandboxOptions {
14
+ readonly cpus: number;
15
+ readonly env: Readonly<Record<string, string>>;
16
+ readonly image: string;
17
+ readonly memoryMiB: number;
18
+ readonly networkPolicy?: SandboxNetworkPolicy;
19
+ readonly pullPolicy: "always" | "if-missing" | "never";
20
+ readonly setup: {
21
+ readonly autoInstall: boolean;
22
+ readonly skipVerify: boolean;
23
+ };
24
+ }
25
+ /**
26
+ * Applies defaults to `microsandboxBackend(opts)`.
27
+ */
28
+ export declare function resolveMicrosandboxOptions(options: MicrosandboxCreateOptions | undefined): ResolvedMicrosandboxOptions;
29
+ /**
30
+ * The subset of options that participates in template/session
31
+ * compatibility hashing. Setup behavior intentionally stays out: how
32
+ * the runtime got installed must not invalidate captured templates.
33
+ */
34
+ export declare function microsandboxOptionsForHash(options: ResolvedMicrosandboxOptions): Record<string, unknown>;
@@ -0,0 +1 @@
1
+ const MICROSANDBOX_DEFAULT_IMAGE=`ubuntu:26.04`,MICROSANDBOX_DEFAULT_CPUS=1,MICROSANDBOX_DEFAULT_MEMORY_MIB=1024,MICROSANDBOX_DEFAULT_PULL_POLICY=`if-missing`,MICROSANDBOX_USER=`vercel-sandbox`;function resolveMicrosandboxOptions(e){return{cpus:e?.cpus??1,env:e?.env??{},image:e?.image??`ubuntu:26.04`,memoryMiB:e?.memoryMiB??1024,networkPolicy:e?.networkPolicy,pullPolicy:e?.pullPolicy??`if-missing`,setup:{autoInstall:e?.setup?.autoInstall??!0,skipVerify:e?.setup?.skipVerify??!1}}}function microsandboxOptionsForHash(e){return{cpus:e.cpus,env:e.env,image:e.image,memoryMiB:e.memoryMiB,pullPolicy:e.pullPolicy}}export{MICROSANDBOX_DEFAULT_CPUS,MICROSANDBOX_DEFAULT_IMAGE,MICROSANDBOX_DEFAULT_MEMORY_MIB,MICROSANDBOX_DEFAULT_PULL_POLICY,MICROSANDBOX_USER,microsandboxOptionsForHash,resolveMicrosandboxOptions};
@@ -0,0 +1,22 @@
1
+ import type { Sandbox as MicrosandboxSandbox } from "microsandbox";
2
+ /**
3
+ * Synchronously reports whether this host can run microsandbox at all:
4
+ * macOS on Apple Silicon, or Linux (glibc) with KVM available. Used by
5
+ * `defaultBackend()`'s availability chain.
6
+ */
7
+ export declare function isMicrosandboxPlatformSupported(): boolean;
8
+ /**
9
+ * Validates the host before loading the microsandbox package, turning
10
+ * unsupported platforms into actionable errors instead of opaque
11
+ * native-binding resolution failures.
12
+ */
13
+ export declare function assertMicrosandboxPlatformCandidate(): Promise<void>;
14
+ /**
15
+ * One-time setup applied to sandboxes created from the raw base image:
16
+ * installs baseline tools (git, ripgrep, Node 24, pnpm, sudo, …),
17
+ * creates the `vercel-sandbox` user with passwordless sudo, and hands
18
+ * it `/workspace` — mirroring the hosted Vercel Sandbox runtime.
19
+ */
20
+ export declare function ensureMicrosandboxBaseRuntime(sandbox: MicrosandboxSandbox, options?: {
21
+ readonly log?: (message: string) => void;
22
+ }): Promise<void>;
@@ -0,0 +1,178 @@
1
+ import{existsSync}from"node:fs";import{access}from"node:fs/promises";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";function isMicrosandboxPlatformSupported(){return process.platform===`darwin`&&process.arch===`arm64`?!0:process.platform===`linux`&&(process.arch===`x64`||process.arch===`arm64`)&&isGlibcLinux()?process.env.MSB_PATH!==void 0||existsSync(`/dev/kvm`):!1}function isGlibcLinux(){try{return typeof(process.report?.getReport())?.header?.glibcVersionRuntime==`string`}catch{return!1}}async function assertMicrosandboxPlatformCandidate(){if(!(process.platform===`darwin`&&process.arch===`arm64`)){if(process.platform===`linux`&&(process.arch===`x64`||process.arch===`arm64`)){if(!isGlibcLinux())throw Error(`The microsandbox sandbox backend requires a glibc-based Linux distribution; musl hosts are not supported. Use dockerBackend() or vercelSandboxBackend() instead.`);if(process.env.MSB_PATH!==void 0||await doesPathExist(`/dev/kvm`))return;throw Error("The microsandbox sandbox backend requires Linux with KVM enabled. `/dev/kvm` is not available on this host. Enable KVM, set MSB_PATH for a custom runtime, or use dockerBackend() / vercelSandboxBackend().")}throw Error(`The microsandbox sandbox backend supports Linux with KVM or macOS on Apple Silicon. Current host is ${process.platform}/${process.arch}. Use dockerBackend() or vercelSandboxBackend() on this host.`)}}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function ensureMicrosandboxBaseRuntime(e,t={}){let n=await collectMicrosandboxBaseRuntimeOutput(await e.execStreamWith(`bash`,e=>e.args([`-lc`,MICROSANDBOX_BASE_SETUP_SCRIPT]).cwd(`/`).user(`root`)),t.log);if(n.exitCode!==0)throw Error(`Failed to initialize the microsandbox base runtime. ${n.stderr||n.stdout}`.trim())}async function collectMicrosandboxBaseRuntimeOutput(e,t){let n=new TextDecoder,r=new TextDecoder,i=``,a=``,o=``,s=``,c;for await(let l of e)if(l.kind===`stdout`){let e=n.decode(l.data,{stream:!0});i=appendOutput(i,e),o=emitMicrosandboxBaseRuntimeLogs(o+e,t)}else if(l.kind===`stderr`){let e=r.decode(l.data,{stream:!0});a=appendOutput(a,e),s=emitMicrosandboxBaseRuntimeLogs(s+e,t)}else if(l.kind===`exited`){c=l.code;break}let l=n.decode(),u=r.decode();if(l.length>0&&(i=appendOutput(i,l),o=emitMicrosandboxBaseRuntimeLogs(o+l,t)),u.length>0&&(a=appendOutput(a,u),s=emitMicrosandboxBaseRuntimeLogs(s+u,t)),emitMicrosandboxBaseRuntimeLogLine(o,t),emitMicrosandboxBaseRuntimeLogLine(s,t),c===void 0)throw Error(`Microsandbox base runtime setup ended without an exit event.`);return{exitCode:c,stderr:a,stdout:i}}function emitMicrosandboxBaseRuntimeLogs(e,t){let n=e.split(/\r?\n/u),r=n.pop()??``;for(let e of n)emitMicrosandboxBaseRuntimeLogLine(e,t);return r}function emitMicrosandboxBaseRuntimeLogLine(e,t){let n=e.match(/^eve-base-runtime: ?(.*)$/u)?.[1];n!==void 0&&n.length>0&&t?.(n)}function appendOutput(e,t){let n=e+t;return n.length>2e4?n.slice(-2e4):n}const MICROSANDBOX_BASE_SETUP_SCRIPT=`
2
+ set -euo pipefail
3
+
4
+ log_step() {
5
+ printf 'eve-base-runtime: %s\\n' "$*" >&2
6
+ }
7
+
8
+ install_packages() {
9
+ local packages=("$@")
10
+ if [ "\${#packages[@]}" -eq 0 ]; then
11
+ return
12
+ fi
13
+
14
+ if command -v dnf >/dev/null 2>&1; then
15
+ log_step "dnf install: \${packages[*]}"
16
+ dnf install -y "\${packages[@]}"
17
+ return
18
+ fi
19
+
20
+ if command -v microdnf >/dev/null 2>&1; then
21
+ log_step "microdnf install: \${packages[*]}"
22
+ microdnf install -y "\${packages[@]}"
23
+ return
24
+ fi
25
+
26
+ if command -v apt-get >/dev/null 2>&1; then
27
+ export DEBIAN_FRONTEND=noninteractive
28
+ log_step "apt-get update"
29
+ apt-get update
30
+ log_step "apt-get install: \${packages[*]}"
31
+ apt-get install -y --no-install-recommends "\${packages[@]}"
32
+ return
33
+ fi
34
+
35
+ if command -v apk >/dev/null 2>&1; then
36
+ log_step "apk add: \${packages[*]}"
37
+ apk add --no-cache "\${packages[@]}"
38
+ return
39
+ fi
40
+
41
+ echo "No supported package manager found for installing: \${packages[*]}" >&2
42
+ return 1
43
+ }
44
+
45
+ install_nodejs24() {
46
+ log_step "checking Node.js 24"
47
+ if command -v node >/dev/null 2>&1 && node --version | grep -q '^v24\\.'; then
48
+ log_step "Node.js 24 already installed"
49
+ return
50
+ fi
51
+
52
+ if command -v apt-get >/dev/null 2>&1; then
53
+ export DEBIAN_FRONTEND=noninteractive
54
+ log_step "apt-get update for Node.js prerequisites"
55
+ apt-get update
56
+ log_step "apt-get install: ca-certificates curl gnupg"
57
+ apt-get install -y --no-install-recommends ca-certificates curl gnupg
58
+ log_step "download NodeSource signing key"
59
+ mkdir -p /etc/apt/keyrings
60
+ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
61
+ log_step "configure NodeSource Node.js 24 repository"
62
+ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
63
+ log_step "apt-get update for Node.js 24"
64
+ apt-get update
65
+ log_step "apt-get install: nodejs"
66
+ apt-get install -y --no-install-recommends nodejs
67
+ return
68
+ fi
69
+
70
+ log_step "install Node.js 24 packages"
71
+ install_packages nodejs24 nodejs24-npm || install_packages nodejs24 || install_packages nodejs npm
72
+ }
73
+
74
+ install_missing_packages() {
75
+ log_step "checking base packages"
76
+ local packages=()
77
+
78
+ if command -v apt-get >/dev/null 2>&1; then
79
+ command -v sudo >/dev/null 2>&1 || packages+=(sudo)
80
+ command -v git >/dev/null 2>&1 || packages+=(git)
81
+ command -v find >/dev/null 2>&1 || packages+=(findutils)
82
+ command -v gzip >/dev/null 2>&1 || packages+=(gzip)
83
+ command -v tar >/dev/null 2>&1 || packages+=(tar)
84
+ command -v unzip >/dev/null 2>&1 || packages+=(unzip)
85
+ command -v which >/dev/null 2>&1 || packages+=(debianutils)
86
+ command -v ps >/dev/null 2>&1 || packages+=(procps)
87
+ command -v openssl >/dev/null 2>&1 || packages+=(openssl)
88
+ command -v zstd >/dev/null 2>&1 || packages+=(zstd)
89
+ command -v useradd >/dev/null 2>&1 || packages+=(passwd)
90
+ [ -e /etc/ssl/certs/ca-certificates.crt ] || packages+=(ca-certificates)
91
+ elif command -v apk >/dev/null 2>&1; then
92
+ command -v sudo >/dev/null 2>&1 || packages+=(sudo)
93
+ command -v git >/dev/null 2>&1 || packages+=(git)
94
+ command -v find >/dev/null 2>&1 || packages+=(findutils)
95
+ command -v gzip >/dev/null 2>&1 || packages+=(gzip)
96
+ command -v tar >/dev/null 2>&1 || packages+=(tar)
97
+ command -v unzip >/dev/null 2>&1 || packages+=(unzip)
98
+ command -v which >/dev/null 2>&1 || packages+=(which)
99
+ command -v ps >/dev/null 2>&1 || packages+=(procps)
100
+ command -v openssl >/dev/null 2>&1 || packages+=(openssl)
101
+ command -v zstd >/dev/null 2>&1 || packages+=(zstd)
102
+ command -v useradd >/dev/null 2>&1 || packages+=(shadow)
103
+ [ -e /etc/ssl/certs/ca-certificates.crt ] || packages+=(ca-certificates)
104
+ else
105
+ command -v sudo >/dev/null 2>&1 || packages+=(sudo)
106
+ command -v git >/dev/null 2>&1 || packages+=(git)
107
+ command -v find >/dev/null 2>&1 || packages+=(findutils)
108
+ command -v gzip >/dev/null 2>&1 || packages+=(gzip)
109
+ command -v tar >/dev/null 2>&1 || packages+=(tar)
110
+ command -v unzip >/dev/null 2>&1 || packages+=(unzip)
111
+ command -v which >/dev/null 2>&1 || packages+=(which)
112
+ command -v ps >/dev/null 2>&1 || packages+=(procps-ng)
113
+ command -v openssl >/dev/null 2>&1 || packages+=(openssl)
114
+ command -v zstd >/dev/null 2>&1 || packages+=(zstd)
115
+ command -v useradd >/dev/null 2>&1 || packages+=(shadow-utils)
116
+ fi
117
+
118
+ install_packages "\${packages[@]}"
119
+ }
120
+
121
+ install_missing_packages
122
+
123
+ install_nodejs24
124
+
125
+ log_step "checking node binary"
126
+ if ! command -v node >/dev/null 2>&1; then
127
+ for candidate in /usr/bin/node-24 /usr/bin/node24 /usr/bin/nodejs24 /usr/bin/nodejs; do
128
+ if [ -x "$candidate" ]; then
129
+ log_step "link node binary: $candidate"
130
+ ln -sf "$candidate" /usr/local/bin/node
131
+ break
132
+ fi
133
+ done
134
+ fi
135
+
136
+ log_step "checking npm binary"
137
+ if ! command -v npm >/dev/null 2>&1; then
138
+ for candidate in /usr/bin/npm-24 /usr/bin/npm24 /usr/bin/npm; do
139
+ if [ -x "$candidate" ]; then
140
+ log_step "link npm binary: $candidate"
141
+ ln -sf "$candidate" /usr/local/bin/npm
142
+ break
143
+ fi
144
+ done
145
+ fi
146
+
147
+ log_step "verifying Node.js and npm"
148
+ command -v node >/dev/null 2>&1
149
+ node --version | grep -q '^v24\\.'
150
+ command -v npm >/dev/null 2>&1
151
+
152
+ log_step "checking pnpm"
153
+ if ! command -v pnpm >/dev/null 2>&1; then
154
+ log_step "npm install -g pnpm"
155
+ npm install -g pnpm
156
+ fi
157
+
158
+ log_step "checking ripgrep"
159
+ if ! command -v rg >/dev/null 2>&1; then
160
+ log_step "install ripgrep"
161
+ install_packages ripgrep || { install_packages spal-release && install_packages ripgrep; }
162
+ fi
163
+
164
+ log_step "checking sandbox user"
165
+ if ! id -u ${MICROSANDBOX_USER} >/dev/null 2>&1; then
166
+ log_step "create sandbox user: ${MICROSANDBOX_USER}"
167
+ useradd -m -s /bin/bash ${MICROSANDBOX_USER}
168
+ fi
169
+
170
+ log_step "configure passwordless sudo for ${MICROSANDBOX_USER}"
171
+ mkdir -p /etc/sudoers.d
172
+ printf '${MICROSANDBOX_USER} ALL=(ALL) NOPASSWD:ALL\\n' > /etc/sudoers.d/${MICROSANDBOX_USER}
173
+ chmod 0440 /etc/sudoers.d/${MICROSANDBOX_USER}
174
+
175
+ log_step "prepare workspace directory: ${WORKSPACE_ROOT}"
176
+ mkdir -p ${WORKSPACE_ROOT}
177
+ chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${WORKSPACE_ROOT}
178
+ `;export{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime,isMicrosandboxPlatformSupported};
@@ -0,0 +1,3 @@
1
+ import type { SandboxProcess } from "#shared/sandbox-session.js";
2
+ import type { ExecHandle as MicrosandboxExecHandle } from "microsandbox";
3
+ export declare function adaptMicrosandboxExecToSandboxProcess(command: MicrosandboxExecHandle): SandboxProcess;
@@ -0,0 +1 @@
1
+ function adaptMicrosandboxExecToSandboxProcess(e){let t,n,r,i,a,o=new Promise((e,t)=>{i=e,a=t}),s=new ReadableStream({start(e){t=e}}),c=new ReadableStream({start(e){n=e}});return(async()=>{let o=e[Symbol.asyncIterator]();try{for(;;){let e=r===void 0?await o.next():await nextWithTimeout(o,100);if(e===`timeout`||e.done===!0)break;let i=e.value;i.kind===`stdout`?t?.enqueue(i.data):i.kind===`stderr`?n?.enqueue(i.data):i.kind===`exited`&&(r=i.code)}}catch(e){t?.error(e),n?.error(e),a?.(e)}finally{if(o.return?.().catch(()=>{}),r===void 0){let e=Error(`Microsandbox command ended without an exit event.`);t?.error(e),n?.error(e),a?.(e)}else t?.close(),n?.close(),i?.()}})(),{stdout:s,stderr:c,async wait(){return await o,{exitCode:r??0}},async kill(){await e.kill()}}}async function nextWithTimeout(e,t){let n;try{return await Promise.race([e.next(),new Promise(e=>{n=setTimeout(()=>e(`timeout`),t)})])}finally{n!==void 0&&clearTimeout(n)}}export{adaptMicrosandboxExecToSandboxProcess};
@@ -0,0 +1,75 @@
1
+ import { type ResolvedMicrosandboxOptions } from "#execution/sandbox/bindings/microsandbox-options.js";
2
+ import { type MicrosandboxSessionMetadata } from "#execution/sandbox/bindings/microsandbox-metadata.js";
3
+ import type { SandboxBackendTags } from "#public/definitions/sandbox-backend.js";
4
+ import type { SandboxNetworkPolicy } from "#shared/sandbox-network-policy.js";
5
+ import type { SandboxProcess, SandboxRemovePathOptions, SandboxSpawnOptions } from "#shared/sandbox-session.js";
6
+ import type { Sandbox as MicrosandboxSandbox } from "microsandbox";
7
+ export type MicrosandboxModule = typeof import("microsandbox");
8
+ export declare class MicrosandboxVm {
9
+ #private;
10
+ constructor(input: {
11
+ readonly module: MicrosandboxModule;
12
+ readonly options: ResolvedMicrosandboxOptions;
13
+ readonly sessionKey: string;
14
+ readonly tags?: SandboxBackendTags;
15
+ }, sandbox: MicrosandboxSandbox, sandboxName: string, networkPolicy: SandboxNetworkPolicy | undefined, metadataPath?: string, optionsHash?: string, stateSnapshotName?: string);
16
+ get id(): string;
17
+ captureState(optionsHash: string): Promise<MicrosandboxSessionMetadata>;
18
+ detach(): Promise<void>;
19
+ readFileBytes(path: string): Promise<Buffer | null>;
20
+ removePath(options: SandboxRemovePathOptions): Promise<void>;
21
+ removePersisted(): Promise<void>;
22
+ setNetworkPolicy(policy: SandboxNetworkPolicy): Promise<void>;
23
+ spawn(options: SandboxSpawnOptions): Promise<SandboxProcess>;
24
+ stopAndSnapshot(snapshotName: string): Promise<void>;
25
+ writeFiles(files: ReadonlyArray<{
26
+ path: string;
27
+ content: string | Uint8Array;
28
+ }>): Promise<void>;
29
+ writeMetadata(path: string, optionsHash: string): Promise<void>;
30
+ private runInternalCommand;
31
+ }
32
+ export declare function createPreparedMicrosandbox(input: {
33
+ readonly fromSnapshot?: string;
34
+ readonly log?: (message: string) => void;
35
+ readonly module: MicrosandboxModule;
36
+ readonly name: string;
37
+ readonly networkPolicy?: SandboxNetworkPolicy;
38
+ readonly options: ResolvedMicrosandboxOptions;
39
+ readonly sessionKey: string;
40
+ readonly setupBaseRuntime: boolean;
41
+ readonly tags?: SandboxBackendTags;
42
+ }): Promise<MicrosandboxVm>;
43
+ export declare function connectMicrosandbox(input: {
44
+ readonly metadata: MicrosandboxSessionMetadata;
45
+ readonly metadataPath: string;
46
+ readonly module: MicrosandboxModule;
47
+ readonly options: ResolvedMicrosandboxOptions;
48
+ readonly sessionKey: string;
49
+ readonly tags?: SandboxBackendTags;
50
+ }): Promise<MicrosandboxVm>;
51
+ /**
52
+ * Loads the microsandbox npm package and ensures its VM runtime is
53
+ * installed. During `eve dev`, both are installed automatically when
54
+ * missing (unless `setup.autoInstall: false`): the package with the
55
+ * project's package manager, the runtime via microsandbox's installer.
56
+ * Production processes never install — they fail with actionable
57
+ * errors instead.
58
+ */
59
+ export declare function loadMicrosandboxModule(input: {
60
+ readonly appRoot: string;
61
+ readonly log?: (message: string) => void;
62
+ readonly options: ResolvedMicrosandboxOptions;
63
+ }): Promise<MicrosandboxModule>;
64
+ /**
65
+ * Loads microsandbox only when its package and runtime are already
66
+ * present — used by cleanup paths that must never trigger installs.
67
+ */
68
+ export declare function loadMicrosandboxWithoutInstall(): Promise<MicrosandboxModule | null>;
69
+ export declare function stopAndSnapshotMicrosandboxSandbox(module: MicrosandboxModule, sandboxName: string, snapshotName: string): Promise<void>;
70
+ export declare function snapshotExists(module: MicrosandboxModule, snapshotName: string): Promise<boolean>;
71
+ export declare function sandboxExists(module: MicrosandboxModule, sandboxName: string): Promise<boolean>;
72
+ export declare function removeSnapshotIfExists(module: MicrosandboxModule, snapshotName: string): Promise<void>;
73
+ export declare function createProviderName(prefix: string, key: string, extra?: string): string;
74
+ export declare function createStableHash(value: string): string;
75
+ export declare function doesPathExist(path: string): Promise<boolean>;
@@ -0,0 +1 @@
1
+ import{posix}from"node:path";import{access}from"node:fs/promises";import{createHash,randomUUID}from"node:crypto";import{isEveDevEnvironment,loadOptionalEnginePackage}from"#internal/application/optional-package-install.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";const MICROSANDBOX_STOP_TIMEOUT_MS=1e4;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION};let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n,version:MICROSANDBOX_METADATA_VERSION}}async detach(){await this.#i.detach().catch(()=>{})}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a),this.#o!==void 0&&await removeSnapshotIfExists(this.#e.module,this.#o)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),i=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,i);let a=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:a,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=a,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...this.#e.options.env,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(t){let n=this.#i.fs();for(let r of t){let t=posix.dirname(r.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(t)}`,user:MICROSANDBOX_USER}),await n.write(r.path,r.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(r.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,module:e.module,name:e.name,networkPolicy:t,options:e.options,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError(t)||e.metadata.stateSnapshotName===void 0)throw t;return await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists(e.module,e.metadata.stateSnapshotName))throw Error(`Microsandbox session snapshot is missing for sandbox "${e.metadata.sandboxName}".`);let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let i=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await i.writeMetadata(e.metadataPath,e.metadata.optionsHash),i}async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>loadOptionalEnginePackage({appRoot:e.appRoot,autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),missingMessage:"The microsandbox sandbox backend requires the `microsandbox` package, which is not bundled with Eve. Install it in your application (for example `pnpm add -D microsandbox`), or use dockerBackend() / vercelSandboxBackend() instead.",packageName:`microsandbox`}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandboxBackend({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(){try{let e=await import(`microsandbox`);return e.isInstalled()?e:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}async function snapshotExists(e,t){try{return await e.Snapshot.get(t),!0}catch(e){if(isMicrosandboxNotFoundError(e))return!1;throw e}}async function sandboxExists(e,t){try{return await e.Sandbox.get(t),!0}catch(e){if(isMicrosandboxNotFoundError(e))return!1;throw e}}async function removeSnapshotIfExists(e,t){try{await e.Snapshot.remove(t,{force:!0})}catch(e){if(!isMicrosandboxNotFoundError(e))throw e}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs(e.options.env).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);return t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.user!==void 0&&(t=t.user(e.user)),await applyMicrosandboxNetwork(t,e.networkPolicy).create()}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function isMicrosandboxNotFoundError(e){return e instanceof Error?/not found|not exist|no such/i.test(e.message):!1}function isMicrosandboxStillRunningError(e){return e instanceof Error?/still running/i.test(e.message):!1}function isMicrosandboxSnapshotSourceRunningError(e){return e instanceof Error?/snapshot source sandbox .*not stopped|SnapshotSandboxRunning/i.test(e.message):!1}function resolveMicrosandboxLabels(e){return{"eve.backend":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Removes stale microsandbox template metadata directories (and their
3
+ * captured snapshots) for one application.
4
+ */
5
+ export declare function pruneMicrosandboxTemplates(input: {
6
+ readonly appRoot: string;
7
+ readonly now?: number;
8
+ readonly recentWindowMs?: number;
9
+ readonly retainCount?: number;
10
+ }): Promise<void>;
11
+ export declare function resolveMicrosandboxTemplateRootPath(cacheDirectory: string, templateKey: string): string;
12
+ export declare function resolveMicrosandboxTemplatesDirectory(cacheDirectory: string): string;
13
+ export declare function resolveMicrosandboxSessionRootPath(cacheDirectory: string, sessionKey: string): string;
@@ -0,0 +1 @@
1
+ import{join}from"node:path";import"node:fs";import{readdir,rm,stat}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{resolveLocalBackendSessionRootPath,resolveLocalBackendTemplateRootPath,resolveLocalBackendTemplatesDirectory}from"#execution/sandbox/bindings/local-backend-utils.js";import{LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT}from"#execution/sandbox/bindings/local-template-prune.js";import{readTemplateMetadata,resolveMicrosandboxMetadataPath}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{loadMicrosandboxWithoutInstall,removeSnapshotIfExists}from"#execution/sandbox/bindings/microsandbox-runtime.js";const MICROSANDBOX_CACHE_DIRECTORY_NAME=`microsandbox`;async function pruneMicrosandboxTemplates(e){let t=resolveMicrosandboxTemplatesDirectory(resolveSandboxCacheDirectory(e.appRoot)),n=e.now??Date.now(),r=e.recentWindowMs??LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,a=e.retainCount??LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,o=await readMicrosandboxTemplateDirectories(t),s=o.filter(e=>!e.isTemporary);await Promise.all([...s.map(async(e,t)=>{t<a||n-e.mtimeMs<=r||await removeTemplateDirectory(e.path,e.metadata)}),...o.filter(e=>e.isTemporary).map(async e=>{n-e.mtimeMs<=r||await removeTemplateDirectory(e.path,e.metadata)})])}function resolveMicrosandboxTemplateRootPath(e,t){return resolveLocalBackendTemplateRootPath(e,MICROSANDBOX_CACHE_DIRECTORY_NAME,t)}function resolveMicrosandboxTemplatesDirectory(e){return resolveLocalBackendTemplatesDirectory(e,MICROSANDBOX_CACHE_DIRECTORY_NAME)}function resolveMicrosandboxSessionRootPath(e,t){return resolveLocalBackendSessionRootPath(e,MICROSANDBOX_CACHE_DIRECTORY_NAME,t)}async function readMicrosandboxTemplateDirectories(n){let i;try{i=await readdir(n,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return[];throw e}return(await Promise.all(i.filter(e=>e.isDirectory()).map(async t=>{let i=join(n,t.name);return{isTemporary:t.name.endsWith(`.tmp`),metadata:await readTemplateMetadata(resolveMicrosandboxMetadataPath(i)),mtimeMs:(await stat(i)).mtimeMs,path:i}}))).sort((e,t)=>t.mtimeMs-e.mtimeMs)}async function removeTemplateDirectory(e,t){if(await rm(e,{force:!0,recursive:!0}),t===null)return;let r=await loadMicrosandboxWithoutInstall();r!==null&&await removeSnapshotIfExists(r,t.snapshotName)}export{pruneMicrosandboxTemplates,resolveMicrosandboxSessionRootPath,resolveMicrosandboxTemplateRootPath,resolveMicrosandboxTemplatesDirectory};