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.
- package/CHANGELOG.md +45 -0
- package/README.md +11 -11
- package/dist/src/chunks/{use-eve-agent-DErQj5hs.js → use-eve-agent-BSXZSn-R.js} +6 -1
- package/dist/src/chunks/{use-eve-agent-DoR8C4i6.js → use-eve-agent-Dlut2Qzt.js} +6 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/blocks.d.ts +1 -1
- package/dist/src/cli/dev/tui/blocks.js +8 -7
- package/dist/src/cli/dev/tui/command-typeahead.d.ts +13 -3
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/line-editor.d.ts +6 -0
- package/dist/src/cli/dev/tui/line-editor.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +2 -0
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +10 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +11 -7
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +72 -10
- package/dist/src/cli/dev/tui/setup-issues.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.d.ts +91 -39
- package/dist/src/cli/dev/tui/setup-panel.js +3 -1
- package/dist/src/cli/dev/tui/setup-selection-input.d.ts +48 -0
- package/dist/src/cli/dev/tui/setup-selection-input.js +1 -0
- package/dist/src/cli/dev/tui/status-line.d.ts +13 -7
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/stream-format.d.ts +2 -0
- package/dist/src/cli/dev/tui/stream-format.js +2 -2
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +4 -2
- package/dist/src/cli/dev/tui/terminal-renderer.js +7 -6
- package/dist/src/cli/dev/tui/terminal-text.d.ts +1 -0
- package/dist/src/cli/dev/tui/terminal-text.js +1 -1
- package/dist/src/cli/dev/tui/theme.d.ts +3 -1
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tool-format.d.ts +1 -1
- package/dist/src/cli/dev/tui/tool-format.js +2 -2
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +6 -0
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/tui/vercel-status.d.ts +4 -4
- package/dist/src/cli/dev/tui/vercel-status.js +1 -1
- package/dist/src/cli/run.d.ts +4 -3
- package/dist/src/cli/run.js +2 -2
- package/dist/src/cli/ui/output.d.ts +1 -0
- package/dist/src/cli/ui/output.js +8 -8
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/session-utils.d.ts +1 -0
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +1 -0
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +19 -0
- package/dist/src/compiled/.vendor-stamp.json +1 -2
- package/dist/src/compiler/compile-from-memory.js +1 -1
- package/dist/src/compiler/manifest.d.ts +28 -7
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-sandbox.js +1 -1
- package/dist/src/context/providers/session.js +1 -1
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/execution/durable-session-store.js +1 -1
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-base-setup.d.ts +9 -0
- package/dist/src/execution/sandbox/bindings/docker-base-setup.js +2 -0
- package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +77 -0
- package/dist/src/execution/sandbox/bindings/docker-cli.js +2 -0
- package/dist/src/execution/sandbox/bindings/docker-container.d.ts +16 -0
- package/dist/src/execution/sandbox/bindings/docker-container.js +1 -0
- package/dist/src/execution/sandbox/bindings/docker-network.d.ts +8 -0
- package/dist/src/execution/sandbox/bindings/docker-network.js +1 -0
- package/dist/src/execution/sandbox/bindings/docker-options.d.ts +21 -0
- package/dist/src/execution/sandbox/bindings/docker-options.js +1 -0
- package/dist/src/execution/sandbox/bindings/docker-session.d.ts +7 -0
- package/dist/src/execution/sandbox/bindings/docker-session.js +2 -0
- package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +35 -0
- package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -0
- package/dist/src/execution/sandbox/bindings/docker-utils.d.ts +2 -0
- package/dist/src/execution/sandbox/bindings/docker-utils.js +1 -0
- package/dist/src/execution/sandbox/bindings/docker.d.ts +33 -0
- package/dist/src/execution/sandbox/bindings/docker.js +1 -0
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.d.ts +30 -0
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -0
- package/dist/src/execution/sandbox/bindings/just-bash.d.ts +33 -0
- package/dist/src/execution/sandbox/bindings/just-bash.js +1 -0
- package/dist/src/execution/sandbox/bindings/local-backend-utils.d.ts +23 -0
- package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -0
- package/dist/src/execution/sandbox/bindings/local-template-prune.d.ts +16 -0
- package/dist/src/execution/sandbox/bindings/local-template-prune.js +1 -0
- package/dist/src/execution/sandbox/bindings/local.d.ts +16 -25
- package/dist/src/execution/sandbox/bindings/local.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.d.ts +16 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-metadata.d.ts +21 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-network.d.ts +18 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-options.d.ts +34 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-options.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-platform.d.ts +22 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +178 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-process.d.ts +3 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-process.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +75 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-templates.d.ts +13 -0
- package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -0
- package/dist/src/execution/sandbox/bindings/microsandbox.d.ts +22 -0
- package/dist/src/execution/sandbox/bindings/microsandbox.js +1 -0
- package/dist/src/execution/sandbox/bindings/vercel-create-api.d.ts +20 -0
- package/dist/src/execution/sandbox/bindings/vercel-create-api.js +1 -0
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +7 -8
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/development-cleanup.d.ts +4 -0
- package/dist/src/execution/sandbox/development-cleanup.js +1 -0
- package/dist/src/execution/sandbox/development-prewarm.d.ts +11 -0
- package/dist/src/execution/sandbox/development-prewarm.js +1 -0
- package/dist/src/execution/sandbox/development-run.d.ts +8 -0
- package/dist/src/execution/sandbox/development-run.js +1 -0
- package/dist/src/execution/sandbox/ensure.js +1 -1
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/lazy-backend.d.ts +1 -1
- package/dist/src/execution/sandbox/logging-session.d.ts +5 -0
- package/dist/src/execution/sandbox/logging-session.js +1 -0
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/sandbox/template-prewarm-lock.d.ts +8 -0
- package/dist/src/execution/sandbox/template-prewarm-lock.js +1 -0
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/optional-package-install.d.ts +40 -0
- package/dist/src/internal/application/optional-package-install.js +1 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/sandbox.d.ts +1 -1
- package/dist/src/internal/authored-definition/sandbox.js +1 -1
- package/dist/src/internal/authored-module-loader.js +2 -2
- package/dist/src/internal/classify-model-routing.d.ts +24 -0
- package/dist/src/internal/classify-model-routing.js +1 -0
- package/dist/src/internal/nitro/host/channel-routes.js +2 -2
- package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.d.ts +5 -2
- package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.d.ts +10 -0
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/dev-live-virtual-modules.d.ts +15 -0
- package/dist/src/internal/nitro/host/dev-live-virtual-modules.js +1 -0
- package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.d.ts +28 -0
- package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.js +1 -0
- package/dist/src/internal/nitro/host/start-development-server.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.d.ts +2 -0
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +4 -0
- package/dist/src/internal/nitro/routes/info.js +1 -1
- package/dist/src/internal/nitro/routes/runtime-artifacts.js +1 -1
- package/dist/src/internal/resolve-model-endpoint-status.d.ts +23 -0
- package/dist/src/internal/resolve-model-endpoint-status.js +1 -0
- package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/public/definitions/sandbox-backend.js +1 -1
- package/dist/src/public/sandbox/backends/default.d.ts +37 -10
- package/dist/src/public/sandbox/backends/default.js +1 -1
- package/dist/src/public/sandbox/backends/docker.d.ts +14 -0
- package/dist/src/public/sandbox/backends/docker.js +1 -0
- package/dist/src/public/sandbox/backends/just-bash.d.ts +17 -0
- package/dist/src/public/sandbox/backends/just-bash.js +1 -0
- package/dist/src/public/sandbox/backends/microsandbox.d.ts +17 -0
- package/dist/src/public/sandbox/backends/microsandbox.js +1 -0
- package/dist/src/public/sandbox/backends/vercel.d.ts +5 -2
- package/dist/src/public/sandbox/backends/vercel.js +1 -1
- package/dist/src/public/sandbox/docker-sandbox.d.ts +45 -0
- package/dist/src/public/sandbox/index.d.ts +8 -4
- package/dist/src/public/sandbox/index.js +1 -1
- package/dist/src/public/sandbox/just-bash-sandbox.d.ts +17 -0
- package/dist/src/public/sandbox/just-bash-sandbox.js +1 -0
- package/dist/src/public/sandbox/microsandbox-sandbox.d.ts +54 -0
- package/dist/src/public/sandbox/microsandbox-sandbox.js +1 -0
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +1 -1
- package/dist/src/runtime/compiled-artifacts-source.d.ts +11 -0
- package/dist/src/runtime/compiled-artifacts-source.js +1 -1
- package/dist/src/runtime/resolve-sandbox.js +1 -1
- package/dist/src/runtime/sandbox/keys.js +1 -1
- package/dist/src/runtime/sandbox/registry.d.ts +2 -2
- package/dist/src/runtime/types.d.ts +1 -1
- package/dist/src/runtime/workspace/spec.js +1 -1
- package/dist/src/setup/boxes/add-channels.d.ts +3 -2
- package/dist/src/setup/boxes/add-channels.js +2 -2
- package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
- package/dist/src/setup/boxes/deploy-project.js +1 -1
- package/dist/src/setup/boxes/link-project.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.d.ts +6 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/boxes/select-model.d.ts +2 -2
- package/dist/src/setup/boxes/select-model.js +1 -1
- package/dist/src/setup/cli/channel-setup-prompter.d.ts +28 -0
- package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
- package/dist/src/setup/cli/index.d.ts +2 -2
- package/dist/src/setup/cli/index.js +1 -1
- package/dist/src/setup/cli/option-row.d.ts +89 -0
- package/dist/src/setup/cli/option-row.js +1 -0
- package/dist/src/setup/cli/prompt-ui.d.ts +15 -29
- package/dist/src/setup/cli/prompt-ui.js +2 -2
- package/dist/src/setup/cli/select-component.d.ts +4 -3
- package/dist/src/setup/cli/select-component.js +1 -1
- package/dist/src/setup/cli/select-state.d.ts +3 -3
- package/dist/src/setup/cli/select-state.js +1 -1
- package/dist/src/setup/flows/channels.d.ts +29 -14
- package/dist/src/setup/flows/channels.js +1 -1
- package/dist/src/setup/flows/deploy.d.ts +1 -0
- package/dist/src/setup/flows/deploy.js +1 -1
- package/dist/src/setup/flows/link.d.ts +1 -0
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/flows/model.d.ts +30 -6
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/vercel.d.ts +4 -1
- package/dist/src/setup/flows/vercel.js +2 -2
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/primitives/open-url.d.ts +14 -0
- package/dist/src/setup/primitives/open-url.js +1 -0
- package/dist/src/setup/primitives/pm/pnpm.d.ts +9 -0
- package/dist/src/setup/primitives/pm/pnpm.js +2 -2
- package/dist/src/setup/primitives/pm/run.d.ts +12 -4
- package/dist/src/setup/primitives/pm/run.js +1 -1
- package/dist/src/setup/primitives/pm/types.d.ts +3 -0
- package/dist/src/setup/primitives/process-abort.d.ts +7 -0
- package/dist/src/setup/primitives/process-abort.js +1 -0
- package/dist/src/setup/primitives/run-vercel.d.ts +2 -0
- package/dist/src/setup/primitives/run-vercel.js +1 -1
- package/dist/src/setup/project-resolution.d.ts +6 -3
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/prompter.d.ts +63 -6
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/run-vercel-link.d.ts +1 -1
- package/dist/src/setup/run-vercel-link.js +1 -1
- package/dist/src/setup/runner.d.ts +2 -0
- package/dist/src/setup/runner.js +1 -1
- package/dist/src/setup/scaffold/channels-catalog.d.ts +2 -0
- package/dist/src/setup/scaffold/channels-catalog.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.d.ts +1 -0
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.d.ts +2 -0
- package/dist/src/setup/scaffold/create/project.js +6 -3
- package/dist/src/setup/scaffold/update/channels.d.ts +2 -0
- package/dist/src/setup/scaffold/update/channels.js +3 -3
- package/dist/src/setup/slack-connect-lifecycle.d.ts +97 -0
- package/dist/src/setup/slack-connect-lifecycle.js +1 -0
- package/dist/src/setup/slack-connect.d.ts +51 -0
- package/dist/src/setup/slack-connect.js +1 -0
- package/dist/src/setup/slackbot.d.ts +60 -47
- package/dist/src/setup/slackbot.js +1 -1
- package/dist/src/setup/state.d.ts +2 -1
- package/dist/src/setup/state.js +1 -1
- package/dist/src/setup/step.d.ts +4 -0
- package/dist/src/setup/validate-gateway-key.d.ts +30 -0
- package/dist/src/setup/validate-gateway-key.js +1 -0
- package/dist/src/setup/vercel-project.d.ts +19 -12
- package/dist/src/setup/vercel-project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +26 -0
- package/dist/src/shared/model-endpoint-status.d.ts +27 -0
- package/dist/src/shared/model-endpoint-status.js +1 -0
- package/dist/src/shared/sandbox-backend.d.ts +8 -2
- package/dist/src/shared/sandbox-definition.d.ts +4 -3
- package/dist/src/shared/sandbox-network-policy.d.ts +4 -2
- package/dist/src/shared/sandbox-session.d.ts +3 -2
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/{dist/docs/public → docs}/getting-started.mdx +14 -4
- package/{dist/docs/public → docs}/guides/deployment.md +3 -3
- package/{dist/docs/public → docs}/guides/dev-tui.md +2 -2
- package/{dist/docs/public → docs}/reference/cli.md +2 -1
- package/{dist/docs/public → docs}/sandbox.mdx +39 -15
- package/package.json +11 -1
- package/dist/src/compiled/just-bash/LICENSE +0 -201
- package/dist/src/compiled/just-bash/index.d.ts +0 -139
- package/dist/src/compiled/just-bash/index.js +0 -2200
- package/dist/src/compiled/just-bash/network/types.d.ts +0 -155
- package/dist/src/public/sandbox/backends/local.d.ts +0 -16
- package/dist/src/public/sandbox/backends/local.js +0 -1
- package/dist/src/public/sandbox/local-sandbox.d.ts +0 -7
- /package/dist/src/public/sandbox/{local-sandbox.js → docker-sandbox.js} +0 -0
- /package/{dist/docs/public → docs}/README.md +0 -0
- /package/{dist/docs/public → docs}/agent-config.md +0 -0
- /package/{dist/docs/public → docs}/channels/custom.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/discord.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/eve.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/github.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/linear.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/meta.json +0 -0
- /package/{dist/docs/public → docs}/channels/overview.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/slack.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/teams.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/telegram.mdx +0 -0
- /package/{dist/docs/public → docs}/channels/twilio.mdx +0 -0
- /package/{dist/docs/public → docs}/concepts/context-control.md +0 -0
- /package/{dist/docs/public → docs}/concepts/default-harness.md +0 -0
- /package/{dist/docs/public → docs}/concepts/execution-model-and-durability.md +0 -0
- /package/{dist/docs/public → docs}/concepts/meta.json +0 -0
- /package/{dist/docs/public → docs}/concepts/security-model.md +0 -0
- /package/{dist/docs/public → docs}/concepts/sessions-runs-and-streaming.md +0 -0
- /package/{dist/docs/public → docs}/connections.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/assertions.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/cases.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/judge.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/meta.json +0 -0
- /package/{dist/docs/public → docs}/evals/overview.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/reporters.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/running.mdx +0 -0
- /package/{dist/docs/public → docs}/evals/targets.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/auth-and-route-protection.md +0 -0
- /package/{dist/docs/public → docs}/guides/client/continuations.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/client/messages.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/client/meta.json +0 -0
- /package/{dist/docs/public → docs}/guides/client/output-schema.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/client/overview.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/client/streaming.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/dynamic-capabilities.md +0 -0
- /package/{dist/docs/public → docs}/guides/dynamic-workflows.md +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/meta.json +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/nextjs.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/nuxt.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/overview.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/sveltekit.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-svelte.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-vue.mdx +0 -0
- /package/{dist/docs/public → docs}/guides/hooks.md +0 -0
- /package/{dist/docs/public → docs}/guides/instrumentation.md +0 -0
- /package/{dist/docs/public → docs}/guides/meta.json +0 -0
- /package/{dist/docs/public → docs}/guides/remote-agents.md +0 -0
- /package/{dist/docs/public → docs}/guides/session-context.md +0 -0
- /package/{dist/docs/public → docs}/guides/state.md +0 -0
- /package/{dist/docs/public → docs}/instructions.mdx +0 -0
- /package/{dist/docs/public → docs}/introduction.md +0 -0
- /package/{dist/docs/public → docs}/meta.json +0 -0
- /package/{dist/docs/public → docs}/reference/meta.json +0 -0
- /package/{dist/docs/public → docs}/reference/project-layout.md +0 -0
- /package/{dist/docs/public → docs}/reference/typescript-api.md +0 -0
- /package/{dist/docs/public → docs}/schedules.mdx +0 -0
- /package/{dist/docs/public → docs}/skills.mdx +0 -0
- /package/{dist/docs/public → docs}/subagents.mdx +0 -0
- /package/{dist/docs/public → docs}/tools.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/connect-a-warehouse.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/first-agent.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/guard-the-spend.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/how-it-runs.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/meta.json +0 -0
- /package/{dist/docs/public → docs}/tutorial/query-sample-data.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/remember-definitions.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/run-analysis.mdx +0 -0
- /package/{dist/docs/public → docs}/tutorial/ship-it.mdx +0 -0
- /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
|
-
|
|
2
|
-
|
|
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
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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{
|
|
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 @@
|
|
|
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};
|