eve 0.8.2 → 0.8.3

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # eve
2
2
 
3
+ ## 0.8.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 2480caa: Prepare hosted Vercel sandboxes with Eve's baseline runtime setup before authored bootstrap code runs, matching the local Docker setup path more closely. The hosted and Docker baseline now includes Python 3 alongside Node 24, npm, Bash, ripgrep, and other setup tools.
8
+ - 1611f4a: Avoid probing unused sandbox backends during `eve dev` shutdown. Development cleanup now only stops Docker or microsandbox resources for backends that actually initialized during the current dev run.
9
+ - 1d1a234: `eve init` now pins `ai` via `overrides`/`resolutions` in the generated `package.json`. Without it, `npm` and `yarn` reject the prerelease `ai` against `@vercel/connect`'s `^6 || ^7` peer range and fail the first install with `ERESOLVE`.
10
+
3
11
  ## 0.8.2
4
12
 
5
13
  ### Patch Changes
@@ -3,7 +3,7 @@
3
3
  * (template builds and template-less sessions). Runs under `/bin/sh`
4
4
  * because `bash` may not exist yet: ensures `/workspace`, installs
5
5
  * `bash` (hard requirement — every command runs via `bash -lc` for
6
- * parity with the Vercel backend), installs/verifies Node 24/npm, and
7
- * best-effort installs `ripgrep`.
6
+ * parity with the Vercel backend), installs/verifies Node 24/npm,
7
+ * installs/verifies Python 3, and best-effort installs `ripgrep`.
8
8
  */
9
9
  export declare function buildDockerBaseSetupScript(): string;
@@ -1,2 +1,2 @@
1
- import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";function buildDockerBaseSetupScript(){return[`set -e`,`mkdir -p ${WORKSPACE_ROOT}`,`if command -v apt-get >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; fi`,`if ! command -v bash >/dev/null 2>&1; then`,` if command -v dnf >/dev/null 2>&1; then dnf install -y bash >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y bash >/dev/null 2>&1 || true;`,` elif command -v apt-get >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 && apt-get install -y --no-install-recommends bash >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache bash >/dev/null 2>&1 || true;`,` fi`,`fi`,`command -v bash >/dev/null 2>&1 || { echo "the sandbox image must provide bash (or a package manager able to install it)" >&2; exit 70; }`,`if ! command -v node >/dev/null 2>&1 || ! node --version | grep -q "^v24\\."; then`,` if command -v apt-get >/dev/null 2>&1; then`,` apt-get update >/dev/null 2>&1`,` apt-get install -y --no-install-recommends ca-certificates curl gnupg >/dev/null 2>&1`,` mkdir -p /etc/apt/keyrings`,` curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg`,` 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`,` apt-get update >/dev/null 2>&1`,` apt-get install -y --no-install-recommends nodejs >/dev/null 2>&1`,` elif command -v dnf >/dev/null 2>&1; then dnf install -y nodejs24 nodejs24-npm >/dev/null 2>&1 || dnf install -y nodejs24 >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y nodejs24 nodejs24-npm >/dev/null 2>&1 || microdnf install -y nodejs24 >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache nodejs npm >/dev/null 2>&1 || true;`,` fi`,`fi`,`command -v node >/dev/null 2>&1 && node --version | grep -q "^v24\\." || { echo "the sandbox image must provide Node 24" >&2; exit 70; }`,`command -v npm >/dev/null 2>&1 || { echo "the sandbox image must provide npm" >&2; exit 70; }`,`if ! command -v rg >/dev/null 2>&1; then`,` if command -v dnf >/dev/null 2>&1; then dnf install -y ripgrep >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y ripgrep >/dev/null 2>&1 || true;`,` elif command -v apt-get >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 && apt-get install -y --no-install-recommends ripgrep >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache ripgrep >/dev/null 2>&1 || true;`,` fi`,`fi`].join(`
1
+ import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";function buildDockerBaseSetupScript(){return[`set -e`,`mkdir -p ${WORKSPACE_ROOT}`,`ensure_apt_signature_verifier() {`,` gpgv_path="$(command -v gpgv || true)"`,` if [ -n "$gpgv_path" ] && [ "$gpgv_path" != /usr/bin/gpgv ] && [ ! -x /usr/bin/gpgv ]; then ln -sf "$gpgv_path" /usr/bin/gpgv || true; fi`,` [ -x /usr/bin/gpgv ] && /usr/bin/gpgv --version >/dev/null 2>&1 && return 0`,` apt-get install -y --reinstall --no-install-recommends gpgv || return 1`,` [ -x /usr/bin/gpgv ] && /usr/bin/gpgv --version >/dev/null 2>&1 || return 1`,`}`,`install_node24_from_tarball() {`,` command -v curl >/dev/null 2>&1 || { echo "curl is required to install Node.js 24 from nodejs.org" >&2; return 1; }`,` command -v tar >/dev/null 2>&1 || { echo "tar is required to install Node.js 24 from nodejs.org" >&2; return 1; }`,` command -v gzip >/dev/null 2>&1 || { echo "gzip is required to install Node.js 24 from nodejs.org" >&2; return 1; }`,` command -v sha256sum >/dev/null 2>&1 || { echo "sha256sum is required to verify Node.js 24 from nodejs.org" >&2; return 1; }`,` case "$(uname -m)" in`,` x86_64|amd64) node_arch=x64 ;;`,` aarch64|arm64) node_arch=arm64 ;;`,` *) echo "unsupported architecture for Node.js 24 tarball: $(uname -m)" >&2; return 1 ;;`,` esac`,` node_tmp="$(mktemp -d)" || return 1`,` node_shasums="$node_tmp/SHASUMS256.txt"`,` curl -fsSL -o "$node_shasums" https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt || return 1`,` node_archive="$(grep -E " node-v24\\.[^ ]+-linux-\${node_arch}\\.tar\\.gz$" "$node_shasums" | head -n 1 | awk '{print $2}')"`,` [ -n "$node_archive" ] || { echo "could not find Node.js 24 linux-$node_arch tarball" >&2; return 1; }`,` node_expected="$(awk -v file="$node_archive" '$2 == file { print $1; exit }' "$node_shasums")"`,` [ -n "$node_expected" ] || { echo "could not find checksum for $node_archive" >&2; return 1; }`,` curl -fsSL -o "$node_tmp/$node_archive" "https://nodejs.org/dist/latest-v24.x/$node_archive" || return 1`,` node_actual="$(sha256sum "$node_tmp/$node_archive" | awk '{print $1}')"`,` [ "$node_actual" = "$node_expected" ] || { echo "checksum mismatch for $node_archive" >&2; return 1; }`,` tar -xzf "$node_tmp/$node_archive" -C "$node_tmp" || return 1`,' node_dir="${node_archive%.tar.gz}"',` cp -a "$node_tmp/$node_dir/." /usr/local/ || return 1`,` for node_bin in node npm npx corepack; do [ -x "/usr/local/bin/$node_bin" ] && ln -sf "/usr/local/bin/$node_bin" "/usr/bin/$node_bin" 2>/dev/null || true; done`,` rm -rf "$node_tmp"`,`}`,`install_node24_with_apt() {`,` ensure_apt_signature_verifier || return 1`,` apt-get update || return 1`,` apt-get install -y --no-install-recommends ca-certificates curl gnupg gpgv || return 1`,` mkdir -p /etc/apt/keyrings || return 1`,` rm -f /etc/apt/keyrings/nodesource.gpg || return 1`,` curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --batch --yes --dearmor -o /etc/apt/keyrings/nodesource.gpg || return 1`,` 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 || return 1`,` apt-get update || return 1`,` apt-get install -y --no-install-recommends nodejs || return 1`,`}`,`if command -v apt-get >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; ensure_apt_signature_verifier || true; fi`,`if ! command -v bash >/dev/null 2>&1; then`,` if command -v dnf >/dev/null 2>&1; then dnf install -y bash >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y bash >/dev/null 2>&1 || true;`,` elif command -v apt-get >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 && apt-get install -y --no-install-recommends bash >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache bash >/dev/null 2>&1 || true;`,` fi`,`fi`,`command -v bash >/dev/null 2>&1 || { echo "the sandbox image must provide bash (or a package manager able to install it)" >&2; exit 70; }`,`if ! command -v node >/dev/null 2>&1 || ! node --version | grep -q "^v24\\."; then`,` if command -v apt-get >/dev/null 2>&1; then`,` if install_node24_with_apt; then`,` :`,` else`,` echo "apt Node.js 24 install failed; trying official Node.js tarball" >&2`,` fi`,` elif command -v dnf >/dev/null 2>&1; then dnf install -y nodejs24 nodejs24-npm >/dev/null 2>&1 || dnf install -y nodejs24 >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y nodejs24 nodejs24-npm >/dev/null 2>&1 || microdnf install -y nodejs24 >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache nodejs npm >/dev/null 2>&1 || true;`,` fi`,` command -v node >/dev/null 2>&1 && node --version | grep -q "^v24\\." || install_node24_from_tarball || true`,`fi`,`command -v node >/dev/null 2>&1 && node --version | grep -q "^v24\\." || { echo "the sandbox image must provide Node 24" >&2; exit 70; }`,`command -v npm >/dev/null 2>&1 || { echo "the sandbox image must provide npm" >&2; exit 70; }`,`if ! command -v python3 >/dev/null 2>&1; then`,` if command -v dnf >/dev/null 2>&1; then dnf install -y python3 >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y python3 >/dev/null 2>&1 || true;`,` elif command -v apt-get >/dev/null 2>&1; then ensure_apt_signature_verifier && apt-get update && apt-get install -y --no-install-recommends python3 python-is-python3;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache python3 >/dev/null 2>&1 || true;`,` fi`,`fi`,`command -v python3 >/dev/null 2>&1 || { echo "the sandbox image must provide Python 3" >&2; exit 70; }`,`if ! command -v rg >/dev/null 2>&1; then`,` if command -v dnf >/dev/null 2>&1; then dnf install -y ripgrep >/dev/null 2>&1 || true;`,` elif command -v microdnf >/dev/null 2>&1; then microdnf install -y ripgrep >/dev/null 2>&1 || true;`,` elif command -v apt-get >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 && apt-get install -y --no-install-recommends ripgrep >/dev/null 2>&1 || true;`,` elif command -v apk >/dev/null 2>&1; then apk add --no-cache ripgrep >/dev/null 2>&1 || true;`,` fi`,`fi`].join(`
2
2
  `)}export{buildDockerBaseSetupScript};
@@ -1 +1 @@
1
- import{randomUUID}from"node:crypto";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL,runDockerBaseSetup,startDockerContainer}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";const DOCKER_BACKEND_NAME=`docker`;function createDockerSandboxBackend(s={}){let c=s.dockerCli??createDockerCli(),l=resolveDockerSandboxOptions(s.createOptions),u=createDockerSandboxOptionsHash(l),d;function ensureDaemon(){return d??=assertDockerDaemonAvailable(c).catch(e=>{throw d=void 0,e}),d}return{name:DOCKER_BACKEND_NAME,async prewarm(r){r.log?.(`checking Docker daemon`),await ensureDaemon();let i={optionsHash:u,templateKey:r.templateKey},a=dockerTemplateImageReference(i),o=resolveDockerTemplateMarkerPath(r.runtimeContext.appRoot,i);if(r.log?.(`checking cached template image "${a}"`),await dockerImageExists(c,a))return r.log?.(`reusing cached template image`),await touchDockerTemplateMarker(o,a),{reused:!0};r.log?.(`checking base image "${l.image}"`),await ensureDockerBaseImage(c,l);let s=`${r.templateKey}-build-${randomUUID().slice(0,8)}`;r.log?.(`starting template build container`),await startDockerContainer({cli:c,containerName:s,image:l.image,initialNetworkPolicy:`allow-all`,options:l,role:`template-build`});try{r.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(c,s),l.networkPolicy!==`allow-all`&&(r.log?.(`applying network policy`),await setDockerNetworkPolicy(c,s,l.networkPolicy));let e=buildSandboxSession(createDockerInternalSession({cli:c,containerName:s,id:r.templateKey}),e=>setDockerNetworkPolicy(c,s,e));r.bootstrap!==void 0&&(r.log?.(`running sandbox bootstrap`),await r.bootstrap({use:async()=>createLoggingSandboxSession({log:r.log,session:e})})),r.seedFiles.length>0&&r.log?.(`writing ${r.seedFiles.length} seed file(s)`),await writeSandboxSeedFiles(e,r.seedFiles),r.log?.(`stopping template build container`),expectDockerSuccess(await c.run([`stop`,`-t`,`0`,s]),`stop template build container "${s}"`),r.log?.(`committing template image "${a}"`),expectDockerSuccess(await c.run([`commit`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}=1`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.role=template`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.template-key=${r.templateKey}`,s,a]),`commit sandbox template image "${a}"`),await touchDockerTemplateMarker(o,a)}finally{await c.run([`rm`,`-f`,s]).catch(()=>{})}return{reused:!1}},async create(e){await ensureDaemon();let n=getDockerContainerName(e.existingMetadata)??e.sessionKey,r=await c.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,n]);if(r.exitCode===0)r.stdout.trim()!==`true`&&expectDockerSuccess(await c.run([`start`,n]),`restart sandbox session container "${n}"`);else{let t;if(e.templateKey===null)await ensureDockerBaseImage(c,l),t=l.image;else{let n={optionsHash:u,templateKey:e.templateKey};if(t=dockerTemplateImageReference(n),!await dockerImageExists(c,t))throw new SandboxTemplateNotProvisionedError({backendName:DOCKER_BACKEND_NAME,templateKey:e.templateKey});await touchDockerTemplateMarker(resolveDockerTemplateMarkerPath(e.runtimeContext.appRoot,n),t)}await startDockerContainer({cli:c,containerName:n,image:t,initialNetworkPolicy:e.templateKey===null?`allow-all`:l.networkPolicy,options:l,role:`session`,tags:e.tags}),e.templateKey===null&&(await runDockerBaseSetup(c,n),l.networkPolicy!==`allow-all`&&await setDockerNetworkPolicy(c,n,l.networkPolicy))}let i=buildSandboxSession(createDockerInternalSession({cli:c,containerName:n,id:e.sessionKey}),e=>setDockerNetworkPolicy(c,n,e));return{session:i,useSessionFn:async()=>i,async captureState(){return{backendName:DOCKER_BACKEND_NAME,metadata:{containerName:n},sessionKey:e.sessionKey}},async dispose(){}}}}}function getDockerContainerName(e){let t=e?.containerName;return typeof t==`string`?t:void 0}export{DOCKER_BACKEND_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxBackend,pruneDockerSandboxTemplates};
1
+ import{randomUUID}from"node:crypto";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";import{markDevelopmentSandboxBackendInitialized}from"#execution/sandbox/development-run.js";import{writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{assertDockerDaemonAvailable,createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL,runDockerBaseSetup,startDockerContainer}from"#execution/sandbox/bindings/docker-container.js";import{setDockerNetworkPolicy}from"#execution/sandbox/bindings/docker-network.js";import{createDockerSandboxOptionsHash,resolveDockerSandboxOptions}from"#execution/sandbox/bindings/docker-options.js";import{createDockerInternalSession}from"#execution/sandbox/bindings/docker-session.js";import{DOCKER_TEMPLATE_IMAGE_REPOSITORY,dockerImageExists,dockerTemplateImageReference,ensureDockerBaseImage,pruneDockerSandboxTemplates,resolveDockerTemplateMarkerPath,touchDockerTemplateMarker}from"#execution/sandbox/bindings/docker-templates.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";const DOCKER_BACKEND_NAME=`docker`;function createDockerSandboxBackend(c={}){let l=c.dockerCli??createDockerCli(),u=resolveDockerSandboxOptions(c.createOptions),d=createDockerSandboxOptionsHash(u),f;function ensureDaemon(){return f??=assertDockerDaemonAvailable(l).catch(e=>{throw f=void 0,e}),f}return{name:DOCKER_BACKEND_NAME,async prewarm(n){n.log?.(`checking Docker daemon`),await ensureDaemon();let i={optionsHash:d,templateKey:n.templateKey},a=dockerTemplateImageReference(i),o=resolveDockerTemplateMarkerPath(n.runtimeContext.appRoot,i);if(n.log?.(`checking cached template image "${a}"`),await dockerImageExists(l,a))return n.log?.(`reusing cached template image`),await touchDockerTemplateMarker(o,a),{reused:!0};n.log?.(`checking base image "${u.image}"`),await ensureDockerBaseImage(l,u);let s=`${n.templateKey}-build-${randomUUID().slice(0,8)}`;n.log?.(`starting template build container`),await startDockerContainer({cli:l,containerName:s,image:u.image,initialNetworkPolicy:`allow-all`,options:u,role:`template-build`});try{n.log?.(`preparing base runtime inside container`),await runDockerBaseSetup(l,s),u.networkPolicy!==`allow-all`&&(n.log?.(`applying network policy`),await setDockerNetworkPolicy(l,s,u.networkPolicy));let e=buildSandboxSession(createDockerInternalSession({cli:l,containerName:s,id:n.templateKey}),e=>setDockerNetworkPolicy(l,s,e));n.bootstrap!==void 0&&(n.log?.(`running sandbox bootstrap`),await n.bootstrap({use:async()=>createLoggingSandboxSession({log:n.log,session:e})})),n.seedFiles.length>0&&n.log?.(`writing ${n.seedFiles.length} seed file(s)`),await writeSandboxSeedFiles(e,n.seedFiles),n.log?.(`stopping template build container`),expectDockerSuccess(await l.run([`stop`,`-t`,`0`,s]),`stop template build container "${s}"`),n.log?.(`committing template image "${a}"`),expectDockerSuccess(await l.run([`commit`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}=1`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.role=template`,`--change`,`LABEL ${DOCKER_SANDBOX_LABEL}.template-key=${n.templateKey}`,s,a]),`commit sandbox template image "${a}"`),await touchDockerTemplateMarker(o,a)}finally{await l.run([`rm`,`-f`,s]).catch(()=>{})}return{reused:!1}},async create(e){await ensureDaemon(),markDevelopmentSandboxBackendInitialized(DOCKER_BACKEND_NAME);let r=getDockerContainerName(e.existingMetadata)??e.sessionKey,i=await l.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,r]);if(i.exitCode===0)i.stdout.trim()!==`true`&&expectDockerSuccess(await l.run([`start`,r]),`restart sandbox session container "${r}"`);else{let t;if(e.templateKey===null)await ensureDockerBaseImage(l,u),t=u.image;else{let n={optionsHash:d,templateKey:e.templateKey};if(t=dockerTemplateImageReference(n),!await dockerImageExists(l,t))throw new SandboxTemplateNotProvisionedError({backendName:DOCKER_BACKEND_NAME,templateKey:e.templateKey});await touchDockerTemplateMarker(resolveDockerTemplateMarkerPath(e.runtimeContext.appRoot,n),t)}await startDockerContainer({cli:l,containerName:r,image:t,initialNetworkPolicy:e.templateKey===null?`allow-all`:u.networkPolicy,options:u,role:`session`,tags:e.tags}),e.templateKey===null&&(await runDockerBaseSetup(l,r),u.networkPolicy!==`allow-all`&&await setDockerNetworkPolicy(l,r,u.networkPolicy))}let a=buildSandboxSession(createDockerInternalSession({cli:l,containerName:r,id:e.sessionKey}),e=>setDockerNetworkPolicy(l,r,e));return{session:a,useSessionFn:async()=>a,async captureState(){return{backendName:DOCKER_BACKEND_NAME,metadata:{containerName:r},sessionKey:e.sessionKey}},async dispose(){}}}}}function getDockerContainerName(e){let t=e?.containerName;return typeof t==`string`?t:void 0}export{DOCKER_BACKEND_NAME,DOCKER_TEMPLATE_IMAGE_REPOSITORY,createDockerSandboxBackend,pruneDockerSandboxTemplates};
@@ -0,0 +1,6 @@
1
+ import type { SandboxCreateOptions, Sandbox as SdkSandbox } from "#compiled/@vercel/sandbox/index.js";
2
+ /**
3
+ * Prepares a fresh Vercel sandbox for use by the framework.
4
+ */
5
+ export declare function ensureVercelSandboxBaseRuntime(sandbox: SdkSandbox): Promise<void>;
6
+ export declare function applyInitialVercelNetworkPolicy(sandbox: SdkSandbox, networkPolicy: SandboxCreateOptions["networkPolicy"]): Promise<void>;
@@ -0,0 +1,3 @@
1
+ import{buildDockerBaseSetupScript}from"#execution/sandbox/bindings/docker-base-setup.js";async function ensureVercelSandboxBaseRuntime(t){await runSandboxBootstrapStep(t,{failureMessage:`Failed to initialize Vercel sandbox base runtime.`,script:buildDockerBaseSetupScript()})}async function applyInitialVercelNetworkPolicy(e,t){t!==void 0&&await e.update({networkPolicy:t})}async function runSandboxBootstrapStep(e,t){let n=await runBootstrapCommand(e,t.script);if(n===null)return;let r=await runBootstrapCommandWithSudo(e,t.script);if(r===null)return;let i=[n,r].filter(Boolean).join(`
2
+ `);throw Error(`${t.failureMessage}${i?`\n${i}`:``}`)}async function runBootstrapCommand(e,t){return await readBootstrapFailure(await e.runCommand({args:[`-lc`,t],cmd:`bash`}))}async function runBootstrapCommandWithSudo(e,t){return await readBootstrapFailure(await e.runCommand({args:[`-n`,`bash`,`-lc`,t],cmd:`sudo`}))}async function readBootstrapFailure(e){if(e.exitCode===0)return null;let t=await e.stdout(),n=await e.stderr();return[t.trim(),n.trim()].filter(Boolean).join(`
3
+ `)}export{applyInitialVercelNetworkPolicy,ensureVercelSandboxBaseRuntime};
@@ -1 +1 @@
1
- import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";async function createVercelEveImageSandbox(e){let t=await createVercelSandboxViaApi(e.createOptions),n=await e.sandboxModule.Sandbox.get({...t,fetch:getVercelSandboxFetch(e.createOptions),name:e.createOptions.name,onResume:e.createOptions.onResume,resume:!1,signal:e.createOptions.signal});if(n===null)throw Error(`Created Vercel sandbox "${e.createOptions.name}" but could not resume it.`);return n}async function createVercelSandboxViaApi(e){let r=await getVercelSandboxCredentials(e),i=new URL(`/v2/sandboxes`,VERCEL_API_BASE_URL);i.searchParams.set(`teamId`,r.teamId);let a=await getVercelSandboxFetch(e)(i,{body:JSON.stringify({projectId:r.projectId,ports:e.ports??[],source:e.source,timeout:e.timeout,resources:e.resources,runtime:e.runtime,name:e.name,persistent:e.persistent,networkPolicy:e.networkPolicy===void 0?void 0:toVercelSandboxApiNetworkPolicy(e.networkPolicy),env:e.env,tags:e.tags,snapshotExpiration:e.snapshotExpiration,keepLastSnapshots:e.keepLastSnapshots,__image:VERCEL_EVE_SANDBOX_IMAGE}),headers:{authorization:`Bearer ${r.token}`,"content-type":`application/json`},method:`POST`,signal:e.signal});if(!a.ok){let e=await a.text().catch(()=>``);throw Error(`Vercel sandbox create API returned ${a.status}${e?`: ${e}`:``}`)}return r}function getVercelSandboxFetch(e){return e.fetch??globalThis.fetch}async function getVercelSandboxCredentials(t){let n=readNonEmptyString(t,`teamId`)??process.env.VERCEL_TEAM_ID?.trim()??process.env.VERCEL_ORG_ID?.trim(),r=readNonEmptyString(t,`projectId`)??process.env.VERCEL_PROJECT_ID?.trim(),i=readNonEmptyString(t,`token`)??process.env.VERCEL_TOKEN?.trim()??process.env.VERCEL_OIDC_TOKEN?.trim();if(i&&n&&r)return{projectId:r,teamId:n,token:i};try{return getVercelSandboxCredentialsFromOidcToken(await getVercelOidcToken({project:r,team:n}))}catch(e){throw Error("Could not resolve Vercel sandbox credentials. Run `vercel login` and `vercel link` so Vercel OIDC can authenticate, set VERCEL_OIDC_TOKEN, or set VERCEL_TOKEN with VERCEL_TEAM_ID and VERCEL_PROJECT_ID.",{cause:e})}}function readNonEmptyString(e,t){let n=e[t];return typeof n==`string`&&n.trim().length>0?n.trim():void 0}function getVercelSandboxCredentialsFromOidcToken(e){let t=e.split(`.`)[1];if(t===void 0)throw Error(`Invalid Vercel OIDC token: missing payload.`);let n=JSON.parse(Buffer.from(base64UrlToBase64(t),`base64`).toString(`utf8`)),r=typeof n.owner_id==`string`?n.owner_id:void 0,i=typeof n.project_id==`string`?n.project_id:void 0;if(r===void 0||i===void 0)throw Error(`Invalid Vercel OIDC token: missing owner_id or project_id.`);return{projectId:i,teamId:r,token:e}}function base64UrlToBase64(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`);return t.padEnd(Math.ceil(t.length/4)*4,`=`)}function toVercelSandboxApiNetworkPolicy(e){return e===`allow-all`||e===`deny-all`?{mode:e}:e}const VERCEL_API_BASE_URL=`https://api.vercel.com`,VERCEL_EVE_SANDBOX_IMAGE=`vercel/eve:latest`;export{createVercelEveImageSandbox};
1
+ import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";async function createVercelEveImageSandbox(e){let t=await createVercelSandboxViaApi(e.createOptions),n=await e.sandboxModule.Sandbox.get({...t,fetch:getVercelSandboxFetch(e.createOptions),name:e.createOptions.name,onResume:e.createOptions.onResume,resume:!1,signal:e.createOptions.signal});if(n===null)throw Error(`Created Vercel sandbox "${e.createOptions.name}" but could not resume it.`);return n}async function createVercelSandboxViaApi(e){let r=await getVercelSandboxCredentials(e),i=new URL(`v2/sandboxes`,VERCEL_API_BASE_URL);i.searchParams.set(`teamId`,r.teamId);let a=await getVercelSandboxFetch(e)(i,{body:JSON.stringify({projectId:r.projectId,ports:e.ports??[],source:e.source,timeout:e.timeout,resources:e.resources,runtime:e.runtime,name:e.name,persistent:e.persistent,networkPolicy:e.networkPolicy===void 0?void 0:toVercelSandboxApiNetworkPolicy(e.networkPolicy),env:e.env,tags:e.tags,snapshotExpiration:e.snapshotExpiration,keepLastSnapshots:e.keepLastSnapshots,__image:VERCEL_EVE_SANDBOX_IMAGE}),headers:{authorization:`Bearer ${r.token}`,"content-type":`application/json`},method:`POST`,signal:e.signal});if(!a.ok){let e=await a.text().catch(()=>``);throw Error(`Vercel sandbox create API returned ${a.status}${e?`: ${e}`:``}`)}return r}function getVercelSandboxFetch(e){return e.fetch??globalThis.fetch}async function getVercelSandboxCredentials(t){let n=readNonEmptyString(t,`teamId`)??readNonEmptyEnvironmentVariable(`VERCEL_TEAM_ID`)??readNonEmptyEnvironmentVariable(`VERCEL_ORG_ID`),r=readNonEmptyString(t,`projectId`)??readNonEmptyEnvironmentVariable(`VERCEL_PROJECT_ID`),i=readNonEmptyString(t,`token`)??readNonEmptyEnvironmentVariable(`VERCEL_OIDC_TOKEN`)??readNonEmptyEnvironmentVariable(`VERCEL_TOKEN`);if(i&&n&&r)return{projectId:r,teamId:n,token:i};try{return getVercelSandboxCredentialsFromOidcToken(await getVercelOidcToken({project:r,team:n}))}catch(e){throw Error("Could not resolve Vercel sandbox credentials. Run `vercel login` and `vercel link` so Vercel OIDC can authenticate, set VERCEL_OIDC_TOKEN, or set VERCEL_TOKEN with VERCEL_TEAM_ID and VERCEL_PROJECT_ID.",{cause:e})}}function readNonEmptyString(e,t){let n=e[t];return typeof n==`string`&&n.trim().length>0?n.trim():void 0}function readNonEmptyEnvironmentVariable(e){let t=process.env[e];return typeof t==`string`&&t.trim().length>0?t.trim():void 0}function getVercelSandboxCredentialsFromOidcToken(e){let t=e.split(`.`)[1];if(t===void 0)throw Error(`Invalid Vercel OIDC token: missing payload.`);let n=JSON.parse(Buffer.from(base64UrlToBase64(t),`base64`).toString(`utf8`)),r=typeof n.owner_id==`string`?n.owner_id:void 0,i=typeof n.project_id==`string`?n.project_id:void 0;if(r===void 0||i===void 0)throw Error(`Invalid Vercel OIDC token: missing owner_id or project_id.`);return{projectId:i,teamId:r,token:e}}function base64UrlToBase64(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`);return t.padEnd(Math.ceil(t.length/4)*4,`=`)}function toVercelSandboxApiNetworkPolicy(e){return e===`allow-all`||e===`deny-all`?{mode:e}:e}const VERCEL_API_BASE_URL=`https://vercel.com/api/`,VERCEL_EVE_SANDBOX_IMAGE=`vercel/eve:latest`;export{createVercelEveImageSandbox};
@@ -1 +1 @@
1
- import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{streamToBuffer}from"#execution/sandbox/stream-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{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-api.js";function createVercelSandboxBackend(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={timeout:DEFAULT_SANDBOX_TIMEOUT_MS,...e.createOptions},r=e.createSandbox??createVercelEveImageSandbox,i=new Map;return{name:`vercel`,async create(e){let a=resolveVercelSandboxTags(n.tags,e.tags),o=e.templateKey===null?null:await readTemplateForCreate({loadSandboxModule:t,prewarmedTemplates:i,templateKey:e.templateKey}),s;try{s=await ensureSession({createOptions:n,createSandbox:r,existingMetadata:e.existingMetadata,sandboxModule:await t(),sessionKey:e.sessionKey,snapshotId:o?.snapshotId,tags:a})}catch(t){throw Error(`Failed to create sandbox session "${e.sessionKey}": ${errorMessage(t)}`,{cause:t})}return o===null&&s.created&&await ensureSandboxWorkingDirectory(s.sandbox),createHandle(s.sandbox,e.sessionKey)},async prewarm(e){let a;try{a=await ensureTemplate({bootstrap:e.bootstrap,createOptions:n,createSandbox:r,loadSandboxModule:t,log:e.log,seedFiles:e.seedFiles,templateKey:e.templateKey})}catch(t){throw Error(`Failed to prewarm Vercel sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}return i.set(e.templateKey,a.template),{reused:a.reused}}}}async function readTemplate(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await getNamedSandbox(await e.loadSandboxModule(),e.templateKey);if(n===null||typeof n.currentSnapshotId!=`string`)throw new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey}}async function readTemplateForCreate(e){try{return await readTemplate(e)}catch(t){throw SandboxTemplateNotProvisionedError.is(t)?t:Error(`Failed to read sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}}async function ensureTemplate(e){let t=await e.loadSandboxModule(),i=await getNamedSandbox(t,e.templateKey),a=resolveVercelSandboxTags(e.createOptions.tags,e.tags),o=extractAuthorSnapshotId(e.createOptions);if(i!==null&&isUnprovisionedTerminalTemplateSandbox(i,o)&&(await i.delete(),i=null),i===null?i=await e.createSandbox({sandboxModule:t,createOptions:{...e.createOptions,name:e.templateKey,persistent:!1,tags:a}}):await ensureVercelSandboxTags(i,a),typeof i.currentSnapshotId==`string`&&i.currentSnapshotId.length>0&&i.currentSnapshotId!==o)return{reused:!0,template:{sandboxName:i.name,snapshotId:i.currentSnapshotId,templateKey:e.templateKey}};await ensureSandboxWorkingDirectory(i);let s=buildSandboxSession(createVercelInternalSandboxSession(i,e.templateKey),createVercelNetworkPolicySetter(i));e.bootstrap!==void 0&&(e.log?.(`running sandbox bootstrap`),await e.bootstrap({use:async t=>(t!==void 0&&await i.update(t),createLoggingSandboxSession({log:e.log,session:s}))}));for(let t of e.seedFiles)typeof t.content==`string`?await s.writeTextFile({content:t.content,path:t.path}):await s.writeBinaryFile({content:t.content,path:t.path});let c=await i.snapshot();return{reused:!1,template:{sandboxName:i.name,snapshotId:c.snapshotId,templateKey:e.templateKey}}}async function ensureSession(e){let t=getVercelSandboxName(e.existingMetadata)??e.sessionKey,n=await getNamedSandbox(e.sandboxModule,t);if(n!==null)return await ensureVercelSandboxTags(n,e.tags),{created:!1,sandbox:n};let r=createSessionCreateParams(e,t);return e.tags!==void 0&&(r.tags=e.tags),{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}function createSessionCreateParams(e,t){if(e.snapshotId===void 0)return{...e.createOptions,name:t,persistent:!0};let{runtime:n,source:r,...i}=e.createOptions;return{...i,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function createHandle(e,t){return{session:buildSandboxSession(createVercelInternalSandboxSession(e,t),createVercelNetworkPolicySetter(e)),useSessionFn:async n=>(n!==void 0&&await e.update(n),buildSandboxSession(createVercelInternalSandboxSession(e,t),createVercelNetworkPolicySetter(e))),async captureState(){return{backendName:`vercel`,metadata:{sandboxName:e.name},sessionKey:t}},async dispose(){}}}function createVercelNetworkPolicySetter(e){return async t=>{await e.update({networkPolicy:t})}}function createVercelInternalSandboxSession(n,r){return{id:r,resolvePath:resolveVercelSandboxPath,async spawn(t){return adaptVercelCommandToSandboxProcess(await n.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory??WORKSPACE_ROOT,detached:!0,env:t.env,signal:t.abortSignal}))},async readFile(e){return await n.readFile({path:e.path})??null},async writeFile(e){let r=await streamToBuffer(e.content);await n.writeFiles([{content:r,path:e.path}])},async removePath(e){await n.fs.rm(e.path,{force:e.force,recursive:e.recursive,signal:e.abortSignal})}}}function adaptVercelCommandToSandboxProcess(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.stream===`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()}}}function resolveVercelSandboxPath(t){return t.startsWith(`/`)?t:`${WORKSPACE_ROOT}/${t}`}async function ensureSandboxWorkingDirectory(t){await runSandboxBootstrapStep(t,{failureMessage:`Failed to initialize Vercel sandbox workspace.`,script:`mkdir -p ${WORKSPACE_ROOT} && test -w ${WORKSPACE_ROOT}`})}async function runSandboxBootstrapStep(e,t){let n=await e.runCommand({args:[`-lc`,t.script],cmd:`bash`});if(n.exitCode!==0){let e=await n.stderr();throw Error(`${t.failureMessage} ${e}`.trim())}}async function getNamedSandbox(e,t){try{return await e.Sandbox.get({name:t,resume:!1})}catch(e){if(isSandboxMissingError(e))return null;throw Error(`Failed to look up Vercel sandbox "${t}": ${errorMessage(e)}`,{cause:e})}}function isSandboxMissingError(e){return e instanceof Error?(e.response?.status??e.cause?.response?.status)===404:!1}function isUnprovisionedTerminalTemplateSandbox(e,t){let n=e.currentSnapshotId;return typeof n==`string`&&n.length>0&&n!==t?!1:e.status===`aborted`||e.status===`failed`||e.status===`stopped`}function extractAuthorSnapshotId(e){let t=e.source;if(t?.type===`snapshot`&&typeof t.snapshotId==`string`)return t.snapshotId}function getVercelSandboxName(e){let t=e?.sandboxName;return typeof t==`string`?t:void 0}function resolveVercelSandboxTags(e,t){let n={};if(e!==void 0)for(let[t,r]of Object.entries(e))n[t]=r;if(t!==void 0)for(let[e,r]of Object.entries(t))n[e]=r;let r=Object.keys(n).length;if(r!==0){if(r>VERCEL_SANDBOX_TAG_LIMIT)throw Error(`Vercel Sandbox supports at most ${VERCEL_SANDBOX_TAG_LIMIT} tags. Eve reserves "agent", "channel", and "sessionId"; remove or consolidate custom tags passed to vercelSandboxBackend().`);return n}}async function ensureVercelSandboxTags(e,t){t===void 0||areVercelSandboxTagsEqual(e.tags,t)||await e.update({tags:t})}function areVercelSandboxTagsEqual(e,t){let n=e??{},r=Object.entries(n),i=Object.entries(t);return r.length===i.length?i.every(([e,t])=>n[e]===t):!1}function errorMessage(e){if(e instanceof Error){let t=e.json,n=e.text,r=typeof n==`string`&&n.length>0?n:t===void 0?void 0:JSON.stringify(t);return r===void 0?e.message:`${e.message}: ${r}`}return String(e)}const DEFAULT_SANDBOX_TIMEOUT_MS=1800*1e3,VERCEL_SANDBOX_TAG_LIMIT=5;export{createVercelSandboxBackend};
1
+ import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{streamToBuffer}from"#execution/sandbox/stream-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{applyInitialVercelNetworkPolicy,ensureVercelSandboxBaseRuntime}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-api.js";function createVercelSandboxBackend(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={timeout:DEFAULT_SANDBOX_TIMEOUT_MS,...e.createOptions},r=e.createSandbox??createVercelEveImageSandbox,i=new Map;return{name:`vercel`,async create(e){let s=resolveVercelSandboxTags(n.tags,e.tags),c=e.templateKey===null?null:await readTemplateForCreate({loadSandboxModule:t,prewarmedTemplates:i,templateKey:e.templateKey}),l;try{l=await ensureSession({createOptions:n,createSandbox:r,existingMetadata:e.existingMetadata,sandboxModule:await t(),sessionKey:e.sessionKey,snapshotId:c?.snapshotId,tags:s})}catch(t){throw Error(`Failed to create sandbox session "${e.sessionKey}": ${errorMessage(t)}`,{cause:t})}return c===null&&l.created&&(await ensureVercelSandboxBaseRuntime(l.sandbox),await applyInitialVercelNetworkPolicy(l.sandbox,n.networkPolicy)),createHandle(l.sandbox,e.sessionKey)},async prewarm(e){let a;try{a=await ensureTemplate({bootstrap:e.bootstrap,createOptions:n,createSandbox:r,loadSandboxModule:t,log:e.log,seedFiles:e.seedFiles,templateKey:e.templateKey})}catch(t){throw Error(`Failed to prewarm Vercel sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}return i.set(e.templateKey,a.template),{reused:a.reused}}}}async function readTemplate(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await getNamedSandbox(await e.loadSandboxModule(),e.templateKey);if(n===null||typeof n.currentSnapshotId!=`string`)throw new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey}}async function readTemplateForCreate(e){try{return await readTemplate(e)}catch(t){throw SandboxTemplateNotProvisionedError.is(t)?t:Error(`Failed to read sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}}async function ensureTemplate(e){let t=await e.loadSandboxModule(),i=await getNamedSandbox(t,e.templateKey),s=resolveVercelSandboxTags(e.createOptions.tags,e.tags),c=extractAuthorSnapshotId(e.createOptions);if(i!==null&&isUnprovisionedTerminalTemplateSandbox(i,c)&&(await i.delete(),i=null),i===null?i=await e.createSandbox({sandboxModule:t,createOptions:withBaseSetupNetworkPolicy({...e.createOptions,name:e.templateKey,persistent:!1,tags:s})}):await ensureVercelSandboxTags(i,s),typeof i.currentSnapshotId==`string`&&i.currentSnapshotId.length>0&&i.currentSnapshotId!==c)return{reused:!0,template:{sandboxName:i.name,snapshotId:i.currentSnapshotId,templateKey:e.templateKey}};e.log?.(`preparing base runtime inside sandbox`),await ensureVercelSandboxBaseRuntime(i),await applyInitialVercelNetworkPolicy(i,e.createOptions.networkPolicy);let l=buildSandboxSession(createVercelInternalSandboxSession(i,e.templateKey),createVercelNetworkPolicySetter(i));e.bootstrap!==void 0&&(e.log?.(`running sandbox bootstrap`),await e.bootstrap({use:async t=>(t!==void 0&&await i.update(t),createLoggingSandboxSession({log:e.log,session:l}))}));for(let t of e.seedFiles)typeof t.content==`string`?await l.writeTextFile({content:t.content,path:t.path}):await l.writeBinaryFile({content:t.content,path:t.path});let u=await i.snapshot();return{reused:!1,template:{sandboxName:i.name,snapshotId:u.snapshotId,templateKey:e.templateKey}}}async function ensureSession(e){let t=getVercelSandboxName(e.existingMetadata)??e.sessionKey,n=await getNamedSandbox(e.sandboxModule,t);if(n!==null)return await ensureVercelSandboxTags(n,e.tags),{created:!1,sandbox:n};let r=createSessionCreateParams(e,t);return e.tags!==void 0&&(r.tags=e.tags),{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}function createSessionCreateParams(e,t){if(e.snapshotId===void 0)return withBaseSetupNetworkPolicy({...e.createOptions,name:t,persistent:!0});let{runtime:n,source:r,...i}=e.createOptions;return{...i,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function withBaseSetupNetworkPolicy(e){return{...e,networkPolicy:`allow-all`}}function createHandle(e,t){return{session:buildSandboxSession(createVercelInternalSandboxSession(e,t),createVercelNetworkPolicySetter(e)),useSessionFn:async n=>(n!==void 0&&await e.update(n),buildSandboxSession(createVercelInternalSandboxSession(e,t),createVercelNetworkPolicySetter(e))),async captureState(){return{backendName:`vercel`,metadata:{sandboxName:e.name},sessionKey:t}},async dispose(){}}}function createVercelNetworkPolicySetter(e){return async t=>{await e.update({networkPolicy:t})}}function createVercelInternalSandboxSession(n,r){return{id:r,resolvePath:resolveVercelSandboxPath,async spawn(t){return adaptVercelCommandToSandboxProcess(await n.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory??WORKSPACE_ROOT,detached:!0,env:t.env,signal:t.abortSignal}))},async readFile(e){return await n.readFile({path:e.path})??null},async writeFile(e){let r=await streamToBuffer(e.content);await n.writeFiles([{content:r,path:e.path}])},async removePath(e){await n.fs.rm(e.path,{force:e.force,recursive:e.recursive,signal:e.abortSignal})}}}function adaptVercelCommandToSandboxProcess(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.stream===`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()}}}function resolveVercelSandboxPath(t){return t.startsWith(`/`)?t:`${WORKSPACE_ROOT}/${t}`}async function getNamedSandbox(e,t){try{return await e.Sandbox.get({name:t,resume:!1})}catch(e){if(isSandboxMissingError(e))return null;throw Error(`Failed to look up Vercel sandbox "${t}": ${errorMessage(e)}`,{cause:e})}}function isSandboxMissingError(e){return e instanceof Error?(e.response?.status??e.cause?.response?.status)===404:!1}function isUnprovisionedTerminalTemplateSandbox(e,t){let n=e.currentSnapshotId;return typeof n==`string`&&n.length>0&&n!==t?!1:e.status===`aborted`||e.status===`failed`||e.status===`stopped`}function extractAuthorSnapshotId(e){let t=e.source;if(t?.type===`snapshot`&&typeof t.snapshotId==`string`)return t.snapshotId}function getVercelSandboxName(e){let t=e?.sandboxName;return typeof t==`string`?t:void 0}function resolveVercelSandboxTags(e,t){let n={};if(e!==void 0)for(let[t,r]of Object.entries(e))n[t]=r;if(t!==void 0)for(let[e,r]of Object.entries(t))n[e]=r;let r=Object.keys(n).length;if(r!==0){if(r>VERCEL_SANDBOX_TAG_LIMIT)throw Error(`Vercel Sandbox supports at most ${VERCEL_SANDBOX_TAG_LIMIT} tags. Eve reserves "agent", "channel", and "sessionId"; remove or consolidate custom tags passed to vercelSandboxBackend().`);return n}}async function ensureVercelSandboxTags(e,t){t===void 0||areVercelSandboxTagsEqual(e.tags,t)||await e.update({tags:t})}function areVercelSandboxTagsEqual(e,t){let n=e??{},r=Object.entries(n),i=Object.entries(t);return r.length===i.length?i.every(([e,t])=>n[e]===t):!1}function errorMessage(e){if(e instanceof Error){let t=e.json,n=e.text,r=typeof n==`string`&&n.length>0?n:t===void 0?void 0:JSON.stringify(t);return r===void 0?e.message:`${e.message}: ${r}`}return String(e)}const DEFAULT_SANDBOX_TIMEOUT_MS=1800*1e3,VERCEL_SANDBOX_TAG_LIMIT=5;export{createVercelSandboxBackend};
@@ -1,4 +1,5 @@
1
1
  export declare function stopDevelopmentSandboxResources(input: {
2
+ readonly backendNames?: readonly string[];
2
3
  readonly devRunId: string;
3
4
  readonly log?: (message: string) => void;
4
5
  }): Promise<void>;
@@ -1 +1 @@
1
- import{toErrorMessage}from"#shared/errors.js";import{randomUUID}from"node:crypto";import{EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG}from"#execution/sandbox/development-run.js";import{createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{MICROSANDBOX_METADATA_VERSION,readSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{createProviderName,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,stopAndSnapshotMicrosandboxSandbox}from"#execution/sandbox/bindings/microsandbox-runtime.js";async function stopDevelopmentSandboxResources(t){let n=await Promise.allSettled([stopDevelopmentDockerResources(t.devRunId),stopDevelopmentMicrosandboxResources(t.devRunId,t.log)]);for(let r of n)r.status===`rejected`&&t.log?.(`failed to stop development sandbox resources: ${toErrorMessage(r.reason)}`)}async function stopDevelopmentDockerResources(e){let t=createDockerCli(),n=[`label=${DOCKER_SANDBOX_LABEL}=1`,`label=${DOCKER_SANDBOX_LABEL}.tag.${EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG}=${e}`],s=await t.run([`ps`,`-q`,...n.flatMap(e=>[`--filter`,e])]);if(s.exitCode!==0)return;let c=s.stdout.trim().split(/\s+/u).filter(Boolean);await Promise.all(c.map(e=>stopDockerContainerIfRunning(t,e)))}async function stopDevelopmentMicrosandboxResources(e,i){let a=await loadMicrosandboxWithoutInstall();if(a===null)return;let o=await a.Sandbox.listWith({labels:{"eve.backend":`microsandbox`,[EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG]:e}});await Promise.all(o.filter(e=>e.status===`running`||e.status===`draining`).map(async e=>{let r=getMicrosandboxLabel(e.configJson,EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG);if(r===void 0){await(await a.Sandbox.get(e.name)).stopWithTimeout(1e4).catch(()=>{});return}let o=await readSessionMetadata(r);if(o===null||o.sandboxName!==e.name){await(await a.Sandbox.get(e.name)).stopWithTimeout(1e4).catch(()=>{});return}i?.(`snapshotting development microsandbox session "${e.name}" before shutdown`);let l=o.stateSnapshotName,u=createProviderName(`eve-sbx-state`,`${o.sandboxName}:${randomUUID()}`);await stopAndSnapshotMicrosandboxSandbox(a,e.name,u),await writeSessionMetadata(r,{networkPolicy:o.networkPolicy,optionsHash:o.optionsHash,sandboxName:o.sandboxName,stateSnapshotName:u,version:MICROSANDBOX_METADATA_VERSION}),l!==void 0&&await removeSnapshotIfExists(a,l)}))}function getMicrosandboxLabel(e,t){let n;try{n=JSON.parse(e)}catch{return}return findLabel(n,t)}function findLabel(e,t){if(!isRecord(e))return;let n=e[t];if(typeof n==`string`)return n;let r=e.labels;if(isRecord(r)&&typeof r[t]==`string`)return r[t];if(typeof e.labelsJson==`string`){let n=parseJsonRecord(e.labelsJson);if(n!==null&&typeof n[t]==`string`)return n[t]}for(let n of Object.values(e)){let e=findLabel(n,t);if(e!==void 0)return e}}function parseJsonRecord(e){try{let t=JSON.parse(e);return isRecord(t)?t:null}catch{return null}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{stopDevelopmentSandboxResources};
1
+ import{toErrorMessage}from"#shared/errors.js";import{randomUUID}from"node:crypto";import{EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG}from"#execution/sandbox/development-run.js";import{createDockerCli}from"#execution/sandbox/bindings/docker-cli.js";import{DOCKER_SANDBOX_LABEL,stopDockerContainerIfRunning}from"#execution/sandbox/bindings/docker-container.js";import{DOCKER_BACKEND_NAME}from"#execution/sandbox/bindings/docker.js";import{MICROSANDBOX_BACKEND_NAME}from"#execution/sandbox/bindings/microsandbox.js";import{MICROSANDBOX_METADATA_VERSION,readSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{createProviderName,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,stopAndSnapshotMicrosandboxSandbox}from"#execution/sandbox/bindings/microsandbox-runtime.js";async function stopDevelopmentSandboxResources(t){let n=t.backendNames===void 0?null:new Set(t.backendNames),r=[];(n===null||n.has(DOCKER_BACKEND_NAME))&&r.push(stopDevelopmentDockerResources(t.devRunId)),(n===null||n.has(MICROSANDBOX_BACKEND_NAME))&&r.push(stopDevelopmentMicrosandboxResources(t.devRunId,t.log));let i=await Promise.allSettled(r);for(let n of i)n.status===`rejected`&&t.log?.(`failed to stop development sandbox resources: ${toErrorMessage(n.reason)}`)}async function stopDevelopmentDockerResources(e){let t=createDockerCli(),n=[`label=${DOCKER_SANDBOX_LABEL}=1`,`label=${DOCKER_SANDBOX_LABEL}.tag.${EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG}=${e}`],s=await t.run([`ps`,`-q`,...n.flatMap(e=>[`--filter`,e])]);if(s.exitCode!==0)return;let c=s.stdout.trim().split(/\s+/u).filter(Boolean);await Promise.all(c.map(e=>stopDockerContainerIfRunning(t,e)))}async function stopDevelopmentMicrosandboxResources(e,i){let a=await loadMicrosandboxWithoutInstall();if(a===null)return;let o=await a.Sandbox.listWith({labels:{"eve.backend":`microsandbox`,[EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG]:e}});await Promise.all(o.filter(e=>e.status===`running`||e.status===`draining`).map(async e=>{let r=getMicrosandboxLabel(e.configJson,EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG);if(r===void 0){await(await a.Sandbox.get(e.name)).stopWithTimeout(1e4).catch(()=>{});return}let o=await readSessionMetadata(r);if(o===null||o.sandboxName!==e.name){await(await a.Sandbox.get(e.name)).stopWithTimeout(1e4).catch(()=>{});return}i?.(`snapshotting development microsandbox session "${e.name}" before shutdown`);let s=o.stateSnapshotName,c=createProviderName(`eve-sbx-state`,`${o.sandboxName}:${randomUUID()}`);await stopAndSnapshotMicrosandboxSandbox(a,e.name,c),await writeSessionMetadata(r,{networkPolicy:o.networkPolicy,optionsHash:o.optionsHash,sandboxName:o.sandboxName,stateSnapshotName:c,version:MICROSANDBOX_METADATA_VERSION}),s!==void 0&&await removeSnapshotIfExists(a,s)}))}function getMicrosandboxLabel(e,t){let n;try{n=JSON.parse(e)}catch{return}return findLabel(n,t)}function findLabel(e,t){if(!isRecord(e))return;let n=e[t];if(typeof n==`string`)return n;let r=e.labels;if(isRecord(r)&&typeof r[t]==`string`)return r[t];if(typeof e.labelsJson==`string`){let n=parseJsonRecord(e.labelsJson);if(n!==null&&typeof n[t]==`string`)return n[t]}for(let n of Object.values(e)){let e=findLabel(n,t);if(e!==void 0)return e}}function parseJsonRecord(e){try{let t=JSON.parse(e);return isRecord(t)?t:null}catch{return null}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{stopDevelopmentSandboxResources};
@@ -6,3 +6,6 @@ export declare function createDevelopmentSandboxRunId(): string;
6
6
  export declare function getDevelopmentSandboxRunId(): string | undefined;
7
7
  export declare function withDevelopmentSandboxTags(tags: SandboxBackendTags | undefined): SandboxBackendTags | undefined;
8
8
  export declare function withDevelopmentSandboxMetadataPathTag(tags: SandboxBackendTags | undefined, metadataPath: string): SandboxBackendTags | undefined;
9
+ export declare function markDevelopmentSandboxBackendInitialized(backendName: string): void;
10
+ export declare function getInitializedDevelopmentSandboxBackendNames(runId: string): readonly string[];
11
+ export declare function clearInitializedDevelopmentSandboxBackendNames(runId: string): void;
@@ -1 +1 @@
1
- import{randomUUID}from"node:crypto";const EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV=`EVE_DEVELOPMENT_SANDBOX_RUN_ID`,EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG=`eve.metadataPath`,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG=`devRunId`;function createDevelopmentSandboxRunId(){return randomUUID()}function getDevelopmentSandboxRunId(){let e=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return e===void 0||e.trim()===``?void 0:e}function withDevelopmentSandboxTags(e){let t=getDevelopmentSandboxRunId();return t===void 0?e:{...e,[EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG]:t}}function withDevelopmentSandboxMetadataPathTag(e,t){return getDevelopmentSandboxRunId()===void 0?e:{...e,[EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG]:t}}export{EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG,EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG,createDevelopmentSandboxRunId,getDevelopmentSandboxRunId,withDevelopmentSandboxMetadataPathTag,withDevelopmentSandboxTags};
1
+ import{randomUUID}from"node:crypto";const EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV=`EVE_DEVELOPMENT_SANDBOX_RUN_ID`,EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG=`eve.metadataPath`,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG=`devRunId`,initializedBackendsByRunId=new Map;function createDevelopmentSandboxRunId(){return randomUUID()}function getDevelopmentSandboxRunId(){let e=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return e===void 0||e.trim()===``?void 0:e}function withDevelopmentSandboxTags(e){let t=getDevelopmentSandboxRunId();return t===void 0?e:{...e,[EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG]:t}}function withDevelopmentSandboxMetadataPathTag(e,t){return getDevelopmentSandboxRunId()===void 0?e:{...e,[EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG]:t}}function markDevelopmentSandboxBackendInitialized(e){let t=getDevelopmentSandboxRunId();if(t===void 0)return;let n=initializedBackendsByRunId.get(t);n===void 0&&(n=new Set,initializedBackendsByRunId.set(t,n)),n.add(e)}function getInitializedDevelopmentSandboxBackendNames(e){return[...initializedBackendsByRunId.get(e)??[]]}function clearInitializedDevelopmentSandboxBackendNames(e){initializedBackendsByRunId.delete(e)}export{EVE_DEVELOPMENT_SANDBOX_METADATA_PATH_TAG,EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,EVE_DEVELOPMENT_SANDBOX_RUN_ID_TAG,clearInitializedDevelopmentSandboxBackendNames,createDevelopmentSandboxRunId,getDevelopmentSandboxRunId,getInitializedDevelopmentSandboxBackendNames,markDevelopmentSandboxBackendInitialized,withDevelopmentSandboxMetadataPathTag,withDevelopmentSandboxTags};
@@ -1 +1 @@
1
- import{waitForDevelopmentSandboxPrewarm}from"#execution/sandbox/development-prewarm.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{createRuntimeSandboxKeys}from"#runtime/sandbox/keys.js";import{createRuntimeSandboxTemplatePlan}from"#runtime/sandbox/template-plan.js";import{prewarmAppSandboxes}from"#execution/sandbox/prewarm.js";import{waitForSandboxTemplatePrewarmLock}from"#execution/sandbox/template-prewarm-lock.js";async function ensureSandboxAccess(n){let r=n.state?.initialized??!1,o=n.state?.session??null,s=getRuntimeCompiledArtifactsSandboxAppRoot(n.compiledArtifactsSource)??process.cwd(),c=n.registry.sandbox,l;function getHandle(){return l===void 0&&(l=createHandle().catch(e=>{throw l=void 0,e})),l}async function createHandle(){if(c===null)return null;let i=c.definition,l=i.backend,u=createRuntimeSandboxTemplatePlan({definition:i,workspaceResourceRoot:c.workspaceResourceRoot}),d=await createRuntimeSandboxKeys({backendName:l.name,compiledArtifactsSource:n.compiledArtifactsSource,nodeId:n.nodeId,sessionId:n.sessionId,sourceId:i.sourceId,templatePlan:u});d.templateKey!==null&&(logDevelopmentSandbox(`Eve: ensuring sandbox template "${formatNodeLabel(n.nodeId)}" before running tool...`),await waitForDevelopmentSandboxPrewarm({appRoot:s,compiledArtifactsSource:n.compiledArtifactsSource,log:e=>logDevelopmentSandbox(`Eve: sandbox template "${formatNodeLabel(n.nodeId)}" (${l.name}): ${e}`)}),await waitForSandboxTemplatePrewarmLock({appRoot:s,backendName:l.name,log:e=>logDevelopmentSandbox(`Eve: sandbox template "${formatNodeLabel(n.nodeId)}" (${l.name}): ${e}`),templateKey:d.templateKey}));let f={existingMetadata:o?.backendName===l.name&&o.sessionKey===d.sessionKey?o.metadata:void 0,runtimeContext:{appRoot:s},sessionKey:d.sessionKey,tags:n.tags,templateKey:d.templateKey},p=await withDevelopmentSandboxProgress(`Eve: opening sandbox session "${formatNodeLabel(n.nodeId)}" on backend "${l.name}"...`,`Eve: opening sandbox session "${formatNodeLabel(n.nodeId)}" on backend "${l.name}"`,async()=>await createBackendHandleWithPrewarmRetry({appRoot:s,backend:l,compiledArtifactsSource:n.compiledArtifactsSource,createInput:f}));return r||=(await runOnSession(async()=>{await i.onSession?.({ctx:buildCallbackContext(),use:p.useSessionFn})}),!0),p}async function runOnSession(e){if(n.runOnSession!==void 0){await n.runOnSession(e);return}await e()}return{async captureState(){if(l!==void 0){let e=await l;e!==null&&(o=await e.captureState())}return{initialized:r,session:o}},async dispose(){l!==void 0&&await(await l)?.dispose()},async get(){return(await getHandle())?.session??null}}}async function createBackendHandleWithPrewarmRetry(e){try{return await e.backend.create(e.createInput)}catch(t){if(e.createInput.templateKey===null||e.compiledArtifactsSource.kind!==`disk`||!SandboxTemplateNotProvisionedError.is(t))throw t;return await prewarmAppSandboxes({appRoot:e.appRoot,compiledArtifactsSource:e.compiledArtifactsSource,log:e=>logDevelopmentSandbox(e)}),await waitForSandboxTemplatePrewarmLock({appRoot:e.appRoot,backendName:e.backend.name,log:e=>logDevelopmentSandbox(`Eve: ${e}`),templateKey:e.createInput.templateKey}),logDevelopmentSandbox(`Eve: sandbox template is ready; retrying sandbox creation...`),await e.backend.create(e.createInput)}}function logDevelopmentSandbox(e){isEveDevEnvironment()&&console.log(e)}async function withDevelopmentSandboxProgress(e,t,r){if(logDevelopmentSandbox(e),!isEveDevEnvironment())return await r();let i=Date.now(),a=setInterval(()=>{logDevelopmentSandbox(`${t} (${Math.round((Date.now()-i)/1e3)}s elapsed)...`)},5e3);a.unref?.();try{return await r()}finally{clearInterval(a)}}function formatNodeLabel(e){return e===`__root__`?`root`:e}export{ensureSandboxAccess};
1
+ import{waitForDevelopmentSandboxPrewarm}from"#execution/sandbox/development-prewarm.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{markDevelopmentSandboxBackendInitialized}from"#execution/sandbox/development-run.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{createRuntimeSandboxKeys}from"#runtime/sandbox/keys.js";import{createRuntimeSandboxTemplatePlan}from"#runtime/sandbox/template-plan.js";import{prewarmAppSandboxes}from"#execution/sandbox/prewarm.js";import{waitForSandboxTemplatePrewarmLock}from"#execution/sandbox/template-prewarm-lock.js";async function ensureSandboxAccess(n){let i=n.state?.initialized??!1,o=n.state?.session??null,s=getRuntimeCompiledArtifactsSandboxAppRoot(n.compiledArtifactsSource)??process.cwd(),c=n.registry.sandbox,l;function getHandle(){return l===void 0&&(l=createHandle().catch(e=>{throw l=void 0,e})),l}async function createHandle(){if(c===null)return null;let a=c.definition,l=a.backend,u=createRuntimeSandboxTemplatePlan({definition:a,workspaceResourceRoot:c.workspaceResourceRoot}),d=await createRuntimeSandboxKeys({backendName:l.name,compiledArtifactsSource:n.compiledArtifactsSource,nodeId:n.nodeId,sessionId:n.sessionId,sourceId:a.sourceId,templatePlan:u});d.templateKey!==null&&(logDevelopmentSandbox(`Eve: ensuring sandbox template "${formatNodeLabel(n.nodeId)}" before running tool...`),await waitForDevelopmentSandboxPrewarm({appRoot:s,compiledArtifactsSource:n.compiledArtifactsSource,log:e=>logDevelopmentSandbox(`Eve: sandbox template "${formatNodeLabel(n.nodeId)}" (${l.name}): ${e}`)}),await waitForSandboxTemplatePrewarmLock({appRoot:s,backendName:l.name,log:e=>logDevelopmentSandbox(`Eve: sandbox template "${formatNodeLabel(n.nodeId)}" (${l.name}): ${e}`),templateKey:d.templateKey}));let f={existingMetadata:o?.backendName===l.name&&o.sessionKey===d.sessionKey?o.metadata:void 0,runtimeContext:{appRoot:s},sessionKey:d.sessionKey,tags:n.tags,templateKey:d.templateKey},p=await withDevelopmentSandboxProgress(`Eve: opening sandbox session "${formatNodeLabel(n.nodeId)}" on backend "${l.name}"...`,`Eve: opening sandbox session "${formatNodeLabel(n.nodeId)}" on backend "${l.name}"`,async()=>await createBackendHandleWithPrewarmRetry({appRoot:s,backend:l,compiledArtifactsSource:n.compiledArtifactsSource,createInput:f}));return markDevelopmentSandboxBackendInitialized(l.name),i||=(await runOnSession(async()=>{await a.onSession?.({ctx:buildCallbackContext(),use:p.useSessionFn})}),!0),p}async function runOnSession(e){if(n.runOnSession!==void 0){await n.runOnSession(e);return}await e()}return{async captureState(){if(l!==void 0){let e=await l;e!==null&&(o=await e.captureState())}return{initialized:i,session:o}},async dispose(){l!==void 0&&await(await l)?.dispose()},async get(){return(await getHandle())?.session??null}}}async function createBackendHandleWithPrewarmRetry(e){try{return await e.backend.create(e.createInput)}catch(t){if(e.createInput.templateKey===null||e.compiledArtifactsSource.kind!==`disk`||!SandboxTemplateNotProvisionedError.is(t))throw t;return await prewarmAppSandboxes({appRoot:e.appRoot,compiledArtifactsSource:e.compiledArtifactsSource,log:e=>logDevelopmentSandbox(e)}),await waitForSandboxTemplatePrewarmLock({appRoot:e.appRoot,backendName:e.backend.name,log:e=>logDevelopmentSandbox(`Eve: ${e}`),templateKey:e.createInput.templateKey}),logDevelopmentSandbox(`Eve: sandbox template is ready; retrying sandbox creation...`),await e.backend.create(e.createInput)}}function logDevelopmentSandbox(e){isEveDevEnvironment()&&console.log(e)}async function withDevelopmentSandboxProgress(e,t,r){if(logDevelopmentSandbox(e),!isEveDevEnvironment())return await r();let i=Date.now(),a=setInterval(()=>{logDevelopmentSandbox(`${t} (${Math.round((Date.now()-i)/1e3)}s elapsed)...`)},5e3);a.unref?.();try{return await r()}finally{clearInterval(a)}}function formatNodeLabel(e){return e===`__root__`?`root`:e}export{ensureSandboxAccess};
@@ -1 +1 @@
1
- import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.8.2`,WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
1
+ import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.8.3`,WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
@@ -1 +1 @@
1
- import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{EVE_DEV_ENV_FLAG}from"#internal/application/optional-package-install.js";import{EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,createDevelopmentSandboxRunId}from"#execution/sandbox/development-run.js";import{pruneDevelopmentRuntimeArtifactsSnapshotsInBackground}from"#internal/nitro/dev-runtime-artifacts.js";import{build,createDevServer,prepare}from"nitro/builder";import{createApplicationNitro}from"#internal/nitro/host/create-application-nitro.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{pruneLocalSandboxTemplatesInBackground,stopDevelopmentSandboxResources}from"#execution/sandbox/bindings/local.js";import{DEFAULT_DEVELOPMENT_SERVER_PORT,MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS}from"#internal/nitro/host/ports.js";const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT=65535,WORKFLOW_LOCAL_BASE_URL_ENV=`WORKFLOW_LOCAL_BASE_URL`,PORT_ENV=`PORT`,WILDCARD_LISTEN_HOSTNAMES=new Set([`[::]`,`::`,`0.0.0.0`]);function normalizeDevelopmentServerClientUrl(e){let t=new URL(e);return WILDCARD_LISTEN_HOSTNAMES.has(t.hostname)?(t.hostname=`127.0.0.1`,t.toString()):e}function isAddressInUseError(e){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`}function resolveDevelopmentServerPort(e){let t=typeof e==`string`?Number(e):e??DEFAULT_DEVELOPMENT_SERVER_PORT;if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid development server port "${String(e)}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function readEnvironmentPort(){let e=process.env[PORT_ENV];if(e===void 0||e.trim()===``)return;let t=Number(e);if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid ${PORT_ENV} environment variable "${e}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function resolveDevelopmentServerPorts(e){let t=resolveDevelopmentServerPort(e.port);if(t===0||!e.retryOnAddressInUse)return[t];let n=[];for(let e=0;e<MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS;e+=1){let r=t+e;if(r>65535)break;n.push(r)}return n}function installWorkflowLocalQueueEnvironment(e){let t=process.env[WORKFLOW_LOCAL_BASE_URL_ENV],n=process.env[PORT_ENV],r=new URL(normalizeDevelopmentServerClientUrl(e));return process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=r.origin,r.port&&(process.env[PORT_ENV]=r.port),()=>{t===void 0?delete process.env[WORKFLOW_LOCAL_BASE_URL_ENV]:process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=t,n===void 0?delete process.env[PORT_ENV]:process.env[PORT_ENV]=n}}function attachTemporarySocketErrorHandler(e){let onSocketError=()=>{};return e.once(`error`,onSocketError),()=>{e.off(`error`,onSocketError)}}function shouldProxyDevelopmentServerWebSocketUpgrades(e){return e.options.features.websocket===!0||e.options.experimental.websocket===!0}function guardDevelopmentServerWebSocketUpgrades(e,t){let n=t.upgrade.bind(t),r=shouldProxyDevelopmentServerWebSocketUpgrades(e);t.upgrade=async(e,t,i)=>{if(!r){t.destroyed||t.destroy();return}let a=attachTemporarySocketErrorHandler(t);try{await n(e,t,i)}catch{t.destroyed||t.destroy()}finally{a()}}}async function listenForDevelopmentServer(e){let t=resolveDevelopmentServerPorts({port:e.port,retryOnAddressInUse:e.retryOnAddressInUse}),n;for(let r of t){let t=e.devServer.listen({hostname:e.host,port:r,silent:!0});try{return await t.ready(),t}catch(r){if(n=r,await t.close().catch(()=>{}),!isAddressInUseError(r)||!e.retryOnAddressInUse)throw r}}throw Error(`Failed to start Nitro dev server after ${t.length} attempts. Tried ports ${t.join(`, `)}.`,{cause:n})}async function startDevelopmentServer(o,s={}){process.env[EVE_DEV_ENV_FLAG]??=`1`,loadDevelopmentEnvironmentFiles(o);let c=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV],l=createDevelopmentSandboxRunId();process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=l;let u,d,f,p;try{let t=await prepareApplicationHost(o,{dev:!0});pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(t.appRoot);let n=resolveNitroCompiledArtifactsSource(createNitroArtifactsConfig({appRoot:t.appRoot,dev:!0}));startDevelopmentSandboxPrewarmInBackground({appRoot:t.appRoot,compiledArtifactsSource:n}),pruneLocalSandboxTemplatesInBackground(t.appRoot),u=await createApplicationNitro(t,!0),d=createDevServer(u),guardDevelopmentServerWebSocketUpgrades(u,d);let r=s.host??u.options.devServer.hostname,i=s.port??readEnvironmentPort(),m=i??u.options.devServer.port,h=await listenForDevelopmentServer({devServer:d,host:r,port:m,retryOnAddressInUse:i===void 0});if(!h.url)throw Error(`Nitro dev server did not expose a URL.`);f=installWorkflowLocalQueueEnvironment(h.url),await prepare(u),await build(u);let{startAuthoredSourceWatcher:g}=await import(`#internal/nitro/host/dev-authored-source-watcher.js`);p=await g({nitro:u,preparedHost:t});let _=f;if(_===void 0)throw Error(`Workflow local queue environment was not initialized.`);let v=p,y=d,b=u;return{async close(){try{await v.close(),await y.close(),await b.close(),await stopDevelopmentSandboxResources({devRunId:l,log:e=>console.warn(`[eve:dev] ${e}`)})}finally{_(),restoreDevelopmentSandboxRunId(c)}},url:normalizeDevelopmentServerClientUrl(h.url)}}catch(e){throw await p?.close().catch(()=>{}),f?.(),await d?.close().catch(()=>{}),await u?.close().catch(()=>{}),await stopDevelopmentSandboxResources({devRunId:l,log:e=>console.warn(`[eve:dev] ${e}`)}).catch(()=>{}),restoreDevelopmentSandboxRunId(c),e}}function restoreDevelopmentSandboxRunId(e){if(e===void 0){delete process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return}process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=e}export{normalizeDevelopmentServerClientUrl,startDevelopmentServer};
1
+ import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{EVE_DEV_ENV_FLAG}from"#internal/application/optional-package-install.js";import{EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,clearInitializedDevelopmentSandboxBackendNames,createDevelopmentSandboxRunId,getInitializedDevelopmentSandboxBackendNames}from"#execution/sandbox/development-run.js";import{pruneDevelopmentRuntimeArtifactsSnapshotsInBackground}from"#internal/nitro/dev-runtime-artifacts.js";import{build,createDevServer,prepare}from"nitro/builder";import{createApplicationNitro}from"#internal/nitro/host/create-application-nitro.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{pruneLocalSandboxTemplatesInBackground,stopDevelopmentSandboxResources}from"#execution/sandbox/bindings/local.js";import{DEFAULT_DEVELOPMENT_SERVER_PORT,MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS}from"#internal/nitro/host/ports.js";const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT=65535,WORKFLOW_LOCAL_BASE_URL_ENV=`WORKFLOW_LOCAL_BASE_URL`,PORT_ENV=`PORT`,WILDCARD_LISTEN_HOSTNAMES=new Set([`[::]`,`::`,`0.0.0.0`]);function normalizeDevelopmentServerClientUrl(e){let t=new URL(e);return WILDCARD_LISTEN_HOSTNAMES.has(t.hostname)?(t.hostname=`127.0.0.1`,t.toString()):e}function isAddressInUseError(e){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`}function resolveDevelopmentServerPort(e){let t=typeof e==`string`?Number(e):e??DEFAULT_DEVELOPMENT_SERVER_PORT;if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid development server port "${String(e)}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function readEnvironmentPort(){let e=process.env[PORT_ENV];if(e===void 0||e.trim()===``)return;let t=Number(e);if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid ${PORT_ENV} environment variable "${e}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function resolveDevelopmentServerPorts(e){let t=resolveDevelopmentServerPort(e.port);if(t===0||!e.retryOnAddressInUse)return[t];let n=[];for(let e=0;e<MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS;e+=1){let r=t+e;if(r>65535)break;n.push(r)}return n}function installWorkflowLocalQueueEnvironment(e){let t=process.env[WORKFLOW_LOCAL_BASE_URL_ENV],n=process.env[PORT_ENV],r=new URL(normalizeDevelopmentServerClientUrl(e));return process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=r.origin,r.port&&(process.env[PORT_ENV]=r.port),()=>{t===void 0?delete process.env[WORKFLOW_LOCAL_BASE_URL_ENV]:process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=t,n===void 0?delete process.env[PORT_ENV]:process.env[PORT_ENV]=n}}function attachTemporarySocketErrorHandler(e){let onSocketError=()=>{};return e.once(`error`,onSocketError),()=>{e.off(`error`,onSocketError)}}function shouldProxyDevelopmentServerWebSocketUpgrades(e){return e.options.features.websocket===!0||e.options.experimental.websocket===!0}function guardDevelopmentServerWebSocketUpgrades(e,t){let n=t.upgrade.bind(t),r=shouldProxyDevelopmentServerWebSocketUpgrades(e);t.upgrade=async(e,t,i)=>{if(!r){t.destroyed||t.destroy();return}let a=attachTemporarySocketErrorHandler(t);try{await n(e,t,i)}catch{t.destroyed||t.destroy()}finally{a()}}}async function listenForDevelopmentServer(e){let t=resolveDevelopmentServerPorts({port:e.port,retryOnAddressInUse:e.retryOnAddressInUse}),n;for(let r of t){let t=e.devServer.listen({hostname:e.host,port:r,silent:!0});try{return await t.ready(),t}catch(r){if(n=r,await t.close().catch(()=>{}),!isAddressInUseError(r)||!e.retryOnAddressInUse)throw r}}throw Error(`Failed to start Nitro dev server after ${t.length} attempts. Tried ports ${t.join(`, `)}.`,{cause:n})}async function startDevelopmentServer(o,s={}){process.env[EVE_DEV_ENV_FLAG]??=`1`,loadDevelopmentEnvironmentFiles(o);let c=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV],l=createDevelopmentSandboxRunId();process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=l;let u,d,f,p;try{let t=await prepareApplicationHost(o,{dev:!0});pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(t.appRoot);let n=resolveNitroCompiledArtifactsSource(createNitroArtifactsConfig({appRoot:t.appRoot,dev:!0}));startDevelopmentSandboxPrewarmInBackground({appRoot:t.appRoot,compiledArtifactsSource:n}),pruneLocalSandboxTemplatesInBackground(t.appRoot),u=await createApplicationNitro(t,!0),d=createDevServer(u),guardDevelopmentServerWebSocketUpgrades(u,d);let r=s.host??u.options.devServer.hostname,a=s.port??readEnvironmentPort(),m=a??u.options.devServer.port,h=await listenForDevelopmentServer({devServer:d,host:r,port:m,retryOnAddressInUse:a===void 0});if(!h.url)throw Error(`Nitro dev server did not expose a URL.`);f=installWorkflowLocalQueueEnvironment(h.url),await prepare(u),await build(u);let{startAuthoredSourceWatcher:g}=await import(`#internal/nitro/host/dev-authored-source-watcher.js`);p=await g({nitro:u,preparedHost:t});let _=f;if(_===void 0)throw Error(`Workflow local queue environment was not initialized.`);let v=p,y=d,b=u;return{async close(){try{await v.close(),await y.close(),await b.close(),await stopDevelopmentSandboxResources({backendNames:getInitializedDevelopmentSandboxBackendNames(l),devRunId:l,log:e=>console.warn(`[eve:dev] ${e}`)})}finally{clearInitializedDevelopmentSandboxBackendNames(l),_(),restoreDevelopmentSandboxRunId(c)}},url:normalizeDevelopmentServerClientUrl(h.url)}}catch(e){throw await p?.close().catch(()=>{}),f?.(),await d?.close().catch(()=>{}),await u?.close().catch(()=>{}),await stopDevelopmentSandboxResources({backendNames:getInitializedDevelopmentSandboxBackendNames(l),devRunId:l,log:e=>console.warn(`[eve:dev] ${e}`)}).catch(()=>{}),clearInitializedDevelopmentSandboxBackendNames(l),restoreDevelopmentSandboxRunId(c),e}}function restoreDevelopmentSandboxRunId(e){if(e===void 0){delete process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return}process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=e}export{normalizeDevelopmentServerClientUrl,startDevelopmentServer};
@@ -6,10 +6,12 @@ import type { VercelSandboxBootstrapUseOptions, VercelSandboxCreateOptions, Verc
6
6
  * including for local development, where it creates real hosted
7
7
  * sandboxes (requires Vercel credentials).
8
8
  *
9
- * The optional `opts` parameter is forwarded to the Vercel SDK's
10
- * `Sandbox.create(...)` for every fresh sandbox the framework creates
11
- * (template at prewarm, session at first-time create). On resume
12
- * (`Sandbox.get`), no create happens, so opts are not re-applied.
9
+ * The optional `opts` parameter is forwarded to Vercel Sandbox creation
10
+ * for every fresh sandbox the framework creates (template at prewarm,
11
+ * session at first-time create). On resume (`Sandbox.get`), no create
12
+ * happens, so opts are not re-applied. `networkPolicy` is applied after
13
+ * framework-owned base setup for fresh templates and template-less
14
+ * sessions, before authored bootstrap code runs.
13
15
  *
14
16
  * `opts.source`, if supplied, is used only on the template create:
15
17
  * the author's snapshot, git revision, or tarball becomes the base
@@ -23,9 +23,9 @@ export interface DockerSandboxCreateOptions {
23
23
  /**
24
24
  * Base container image for templates and sessions. Defaults to
25
25
  * `ubuntu:26.04` — the official Ubuntu 26.04 image. Framework setup
26
- * installs Node 24 and baseline tools. Custom images must provide
27
- * Bash, Node 24, and npm, or a package manager and setup network
28
- * access that can install them.
26
+ * installs Node 24, Python 3, and baseline tools. Custom images must
27
+ * provide Bash, Node 24, npm, and Python 3, or a package manager and
28
+ * setup network access that can install them.
29
29
  */
30
30
  readonly image?: string;
31
31
  /**
@@ -1,10 +1,15 @@
1
1
  import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
2
2
  /**
3
- * Options accepted by `vercelSandboxBackend(opts)`. Forwarded directly to the
4
- * Vercel SDK's `Sandbox.create(...)` for every fresh sandbox the
5
- * framework creates (template at prewarm time, session at first-time
6
- * session-create). Skipped on resume (`Sandbox.get`) since no create
7
- * happens there.
3
+ * Options accepted by `vercelSandboxBackend(opts)`. Forwarded to Vercel
4
+ * Sandbox creation for every fresh sandbox the framework creates
5
+ * (template at prewarm time, session at first-time session-create).
6
+ * Skipped on resume (`Sandbox.get`) since no create happens there.
7
+ *
8
+ * `networkPolicy` is deferred until after framework-owned base setup
9
+ * for fresh templates and template-less sessions, so Eve can install
10
+ * required packages before authored bootstrap code runs. Template-backed
11
+ * session creates receive it at creation time because the template
12
+ * already contains the prepared base runtime.
8
13
  *
9
14
  * Framework-injected fields (`name`, `onResume`, `persistent`, `signal`)
10
15
  * are excluded: the framework owns those and overrides any
@@ -12,8 +17,8 @@ import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@verc
12
17
  *
13
18
  * `source` is honored only on the template create at prewarm time, so
14
19
  * an author-supplied snapshot, git revision, or tarball becomes the
15
- * base layer for the template. Bootstrap, seed files, and framework
16
- * setup (workspace dir, ripgrep) all run on top, and the resulting
20
+ * base layer for the template. Framework setup, bootstrap, and seed
21
+ * files all run on top, and the resulting
17
22
  * framework-owned snapshot is what every later session derives from,
18
23
  * so `source` is stripped from the session-create path. Eve does not
19
24
  * detect external snapshot changes; to pick up a rebuilt external
@@ -1 +1 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"../update/package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{agentTemplateFiles,formatEveDependencySpecifier}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=join(i.projectRoot,`package.json`);if(!await pathExists(a))throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let o=agentTemplateFiles(i.model),s=[];for(let e of Object.keys(o))await pathExists(join(i.projectRoot,e))&&s.push(e);if(s.length===0&&await pathExists(join(i.projectRoot,`agent`))&&s.push(`agent/`),s.length>0)throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it already has: ${s.join(`, `)}. Move them aside first.`);let c=resolveVersionToken(`evePackageVersion`,i.evePackageVersion??`0.8.2`),l=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`7.0.0-canary.171`),u=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.2.2`),d=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),f=[];for(let[e,t]of Object.entries(o)){let r=join(i.projectRoot,e);await writeTextFile(r,t),f.push(r)}let p=JSON.parse(await readFile(a,`utf8`)),m={"@vercel/connect":u,ai:l,eve:formatEveDependencySpecifier(c),zod:d},h={};for(let[e,t]of Object.entries(m))hasDeclaredDependency(p,e)||(h[e]=t);return Object.keys(h).length>0&&await patchPackageJson(a,{dependencies:h}),await getPackageManagerStrategy(i.packageManager??`pnpm`).applyProjectConfiguration(i.projectRoot),{filesWritten:f,dependenciesAdded:Object.keys(h).sort()}}export{addAgentToProject};
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"../update/package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{agentTemplateFiles,formatEveDependencySpecifier}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=join(i.projectRoot,`package.json`);if(!await pathExists(a))throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let o=agentTemplateFiles(i.model),s=[];for(let e of Object.keys(o))await pathExists(join(i.projectRoot,e))&&s.push(e);if(s.length===0&&await pathExists(join(i.projectRoot,`agent`))&&s.push(`agent/`),s.length>0)throw Error(`Cannot add an Eve agent to "${i.projectRoot}" because it already has: ${s.join(`, `)}. Move them aside first.`);let c=resolveVersionToken(`evePackageVersion`,i.evePackageVersion??`0.8.3`),l=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`7.0.0-canary.171`),u=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.2.2`),d=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),f=[];for(let[e,t]of Object.entries(o)){let r=join(i.projectRoot,e);await writeTextFile(r,t),f.push(r)}let p=JSON.parse(await readFile(a,`utf8`)),m={"@vercel/connect":u,ai:l,eve:formatEveDependencySpecifier(c),zod:d},h={};for(let[e,t]of Object.entries(m))hasDeclaredDependency(p,e)||(h[e]=t);return Object.keys(h).length>0&&await patchPackageJson(a,{dependencies:h}),await getPackageManagerStrategy(i.packageManager??`pnpm`).applyProjectConfiguration(i.projectRoot),{filesWritten:f,dependenciesAdded:Object.keys(h).sort()}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_EVE_PACKAGE_VERSION=`0.8.2`,DEFAULT_AI_PACKAGE_VERSION=`7.0.0-canary.171`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`;function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.evePackageVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TSGO_VERSION__`,t.tsgoPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.typesNodePackageVersion)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_EVE_PACKAGE_VERSION=`0.8.3`,DEFAULT_AI_PACKAGE_VERSION=`7.0.0-canary.171`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`;function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.evePackageVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TSGO_VERSION__`,t.tsgoPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.typesNodePackageVersion)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -26,6 +26,12 @@ export default defineAgent({
26
26
  "devDependencies": {
27
27
  ${e?` "@types/node": "__EVE_INIT_TYPES_NODE_VERSION__",
28
28
  "@typescript/native-preview": "__EVE_INIT_TSGO_VERSION__"`:` "@typescript/native-preview": "__EVE_INIT_TSGO_VERSION__"`}
29
+ },
30
+ "overrides": {
31
+ "ai": "__EVE_INIT_AI_SDK_VERSION__"
32
+ },
33
+ "resolutions": {
34
+ "ai": "__EVE_INIT_AI_SDK_VERSION__"
29
35
  }
30
36
  }
31
37
  `}const AGENT_INSTRUCTIONS_TEMPLATE=`# Identity
@@ -80,4 +86,4 @@ export default defineAgent({
80
86
  },
81
87
  },
82
88
  });
83
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(t),...getPackageManagerStrategy(n).scaffoldFiles}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let i=resolve(e.targetDirectory??process.cwd(),e.projectName),a=e.projectName===`.`,s=e.overwriteExisting??!1,u=e.byokProvider??!1,d=e.packageManager??`pnpm`;if(a)await assertCanCreateInPlace(i,s);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let f=e.typesNodePackageVersion??`25.9.1`,p={appName:basename(i),model:e.model,evePackageVersion:resolveVersionToken(`evePackageVersion`,e.evePackageVersion??`0.8.2`),aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`7.0.0-canary.171`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.2.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.4.3`),tsgoPackageVersion:resolveVersionToken(`tsgoPackageVersion`,e.tsgoPackageVersion??`7.0.0-dev.20260523.1`),typesNodePackageVersion:u?resolveVersionToken(`typesNodePackageVersion`,f):f};await mkdir(i,{recursive:!0});for(let[r,o]of Object.entries(templateFiles(u,d))){let c=`${i}/${r}`,l=await pathExists(c);await writeTextFile(c,renderTemplate(o,p),{force:a&&s}),l&&await e.onOverwriteFile?.(c)}return i}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_VERSION,DEFAULT_ZOD_PACKAGE_VERSION,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,scaffoldBaseProject};
89
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(t),...getPackageManagerStrategy(n).scaffoldFiles}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let i=resolve(e.targetDirectory??process.cwd(),e.projectName),a=e.projectName===`.`,s=e.overwriteExisting??!1,u=e.byokProvider??!1,d=e.packageManager??`pnpm`;if(a)await assertCanCreateInPlace(i,s);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let f=e.typesNodePackageVersion??`25.9.1`,p={appName:basename(i),model:e.model,evePackageVersion:resolveVersionToken(`evePackageVersion`,e.evePackageVersion??`0.8.3`),aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`7.0.0-canary.171`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.2.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.4.3`),tsgoPackageVersion:resolveVersionToken(`tsgoPackageVersion`,e.tsgoPackageVersion??`7.0.0-dev.20260523.1`),typesNodePackageVersion:u?resolveVersionToken(`typesNodePackageVersion`,f):f};await mkdir(i,{recursive:!0});for(let[r,o]of Object.entries(templateFiles(u,d))){let c=`${i}/${r}`,l=await pathExists(c);await writeTextFile(c,renderTemplate(o,p),{force:a&&s}),l&&await e.onOverwriteFile?.(c)}return i}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_VERSION,DEFAULT_ZOD_PACKAGE_VERSION,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,scaffoldBaseProject};
@@ -1,4 +1,4 @@
1
- import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH),WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},eve:{buildCommand:`eve build`,entrypoint:`.`,framework:`eve`,routePrefix:`/_eve_internal/eve`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,n){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,n)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),`next`)}async function ensurePackageDependency(e,n,i){return!await pathExists(e)||await readDependencyVersion(e,n)===i?[]:(await patchPackageJson(e,{dependencies:{[n]:i}}),[{path:e,dependencies:[n],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackageVersion:e?.evePackageVersion??`0.8.2`,aiPackageVersion:e?.aiPackageVersion??`7.0.0-canary.171`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,tsgoPackageVersion:e?.tsgoPackageVersion??`7.0.0-dev.20260523.1`,typesNodePackageVersion:e?.typesNodePackageVersion??`25.9.1`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n){if(!await pathExists(e))return[];let a={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,n.aiPackageVersion),eve:formatEveDependencySpecifier(resolveVersionToken(`evePackageVersion`,n.evePackageVersion)),next:resolveVersionToken(`nextPackageVersion`,n.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,n.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,n.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,n.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,n.zodPackageVersion)},o={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":resolveVersionToken(`typesNodePackageVersion`,n.typesNodePackageVersion),"@types/react":resolveVersionToken(`typesReactPackageVersion`,n.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,n.typesReactDomPackageVersion),"@typescript/native-preview":resolveVersionToken(`tsgoPackageVersion`,n.tsgoPackageVersion)},s=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts;return await patchPackageJson(e,{dependencies:a,devDependencies:o,scripts:s}),[{path:e,dependencies:Object.keys(a),devDependencies:Object.keys(o),scripts:Object.keys(s)}]}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
1
+ import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH),WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},eve:{buildCommand:`eve build`,entrypoint:`.`,framework:`eve`,routePrefix:`/_eve_internal/eve`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,n){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,n)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),`next`)}async function ensurePackageDependency(e,n,i){return!await pathExists(e)||await readDependencyVersion(e,n)===i?[]:(await patchPackageJson(e,{dependencies:{[n]:i}}),[{path:e,dependencies:[n],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackageVersion:e?.evePackageVersion??`0.8.3`,aiPackageVersion:e?.aiPackageVersion??`7.0.0-canary.171`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,tsgoPackageVersion:e?.tsgoPackageVersion??`7.0.0-dev.20260523.1`,typesNodePackageVersion:e?.typesNodePackageVersion??`25.9.1`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n){if(!await pathExists(e))return[];let a={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,n.aiPackageVersion),eve:formatEveDependencySpecifier(resolveVersionToken(`evePackageVersion`,n.evePackageVersion)),next:resolveVersionToken(`nextPackageVersion`,n.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,n.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,n.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,n.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,n.zodPackageVersion)},o={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":resolveVersionToken(`typesNodePackageVersion`,n.typesNodePackageVersion),"@types/react":resolveVersionToken(`typesReactPackageVersion`,n.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,n.typesReactDomPackageVersion),"@typescript/native-preview":resolveVersionToken(`tsgoPackageVersion`,n.tsgoPackageVersion)},s=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts;return await patchPackageJson(e,{dependencies:a,devDependencies:o,scripts:s}),[{path:e,dependencies:Object.keys(a),devDependencies:Object.keys(o),scripts:Object.keys(s)}]}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
2
2
  import { slackChannel } from "eve/channels/slack";
3
3
 
4
4
  export default slackChannel({
package/docs/sandbox.mdx CHANGED
@@ -144,7 +144,7 @@ export default defineSandbox({
144
144
 
145
145
  ### Docker
146
146
 
147
- `dockerBackend()` drives the Docker CLI directly. The default base image is `ubuntu:26.04`, the official Ubuntu 26.04 image from Docker Hub; Eve installs Node 24, npm, Bash, and baseline tools during framework setup before authored bootstrap code runs. Configure it through `dockerBackend({ image, env, pullPolicy, networkPolicy })`; custom images must provide Bash, Node 24, and npm, or a package manager and setup network access that can install them. Templates are committed as local Docker images and reused across sessions when the sandbox source, seed files, `revalidationKey`, and Docker backend options still match; sessions run as long-lived containers whose filesystems persist `/workspace` changes across turns for the same durable session. `eve dev` prunes stale template images in the background.
147
+ `dockerBackend()` drives the Docker CLI directly. The default base image is `ubuntu:26.04`, the official Ubuntu 26.04 image from Docker Hub; Eve installs Node 24, npm, Python 3, Bash, and baseline tools during framework setup before authored bootstrap code runs. Configure it through `dockerBackend({ image, env, pullPolicy, networkPolicy })`; custom images must provide Bash, Node 24, npm, and Python 3, or a package manager and setup network access that can install them. Templates are committed as local Docker images and reused across sessions when the sandbox source, seed files, `revalidationKey`, and Docker backend options still match; sessions run as long-lived containers whose filesystems persist `/workspace` changes across turns for the same durable session. `eve dev` prunes stale template images in the background.
148
148
 
149
149
  ### microsandbox
150
150
 
@@ -193,7 +193,7 @@ networkPolicy: {
193
193
  };
194
194
  ```
195
195
 
196
- Set it on the factory (`vercelSandboxBackend({ networkPolicy: "deny-all" })`) and it applies from creation, including during `bootstrap`. Set it in `onSession`'s `use()` to override per-session. The common pattern combines both: leave the factory open so `bootstrap` can `git clone`, then lock down in `onSession`. And to change the policy mid-turn, call `sandbox.setNetworkPolicy(...)` on the live handle.
196
+ Set it on the factory (`vercelSandboxBackend({ networkPolicy: "deny-all" })`) and it applies before authored `bootstrap` code runs; framework-owned base setup may briefly keep egress open to install required packages. Set it in `onSession`'s `use()` to override per-session. The common pattern combines both: leave the factory open so `bootstrap` can `git clone`, then lock down in `onSession`. And to change the policy mid-turn, call `sandbox.setNetworkPolicy(...)` on the live handle.
197
197
 
198
198
  Domain-level allow-lists and credential brokering are supported by `vercelSandboxBackend()` and `microsandboxBackend()`. The Docker backend honors only `"allow-all"` and `"deny-all"` (at creation and via `setNetworkPolicy`); the just-bash backend rejects `setNetworkPolicy` entirely.
199
199
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [