eve 0.11.0 → 0.11.1
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 +6 -0
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +2 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-errors.d.ts +1 -0
- package/dist/src/execution/sandbox/bindings/vercel-errors.js +1 -2
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +0 -5
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/docs/getting-started.mdx +3 -1
- package/docs/{introduction.md → introduction.mdx} +3 -1
- package/docs/meta.json +0 -1
- package/docs/reference/cli.md +0 -2
- package/docs/{legal.md → responsible-use.md} +2 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.11.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e7cdefd: Handle missing sandbox template and session state more gracefully across Vercel, Microsandbox, and Docker backends. Eve now treats stale Vercel template references, missing Microsandbox session/template snapshots, and Docker template image races as recoverable provisioning misses so the runtime can rebuild or create a fresh sandbox automatically.
|
|
8
|
+
|
|
3
9
|
## 0.11.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
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};
|
|
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)}try{await startDockerContainer({cli:l,containerName:r,image:t,initialNetworkPolicy:e.templateKey===null?`allow-all`:u.networkPolicy,options:u,role:`session`,tags:e.tags})}catch(t){throw e.templateKey===null?t:new SandboxTemplateNotProvisionedError({backendName:DOCKER_BACKEND_NAME,templateKey:e.templateKey})}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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname}from"node:path";import{mkdir,rename,rm}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{withDevelopmentSandboxMetadataPathTag}from"#execution/sandbox/development-run.js";import{createFileBackedInternalSandboxSession,touchDirectory,writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{MICROSANDBOX_METADATA_VERSION,readSessionMetadata,readSessionMetadataRecord,readTemplateMetadata,resolveMicrosandboxMetadataPath,writeTemplateMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{connectMicrosandbox,createPreparedMicrosandbox,createProviderName,doesPathExist,loadMicrosandboxModule,removeSnapshotIfExists,sandboxExists,snapshotExists}from"#execution/sandbox/bindings/microsandbox-runtime.js";import{resolveMicrosandboxSessionRootPath,resolveMicrosandboxTemplateRootPath}from"#execution/sandbox/bindings/microsandbox-templates.js";const activeMicrosandboxSessionHandles=new Map;async function prewarmMicrosandboxTemplate(i){i.prewarmInput.log?.(`loading microsandbox runtime`);let a=await loadMicrosandboxModule({appRoot:i.prewarmInput.runtimeContext.appRoot,log:i.prewarmInput.log,options:i.options}),u=resolveMicrosandboxTemplateRootPath(resolveSandboxCacheDirectory(i.prewarmInput.runtimeContext.appRoot),i.prewarmInput.templateKey),f=resolveMicrosandboxMetadataPath(u);i.prewarmInput.log?.(`checking cached snapshot`);let p=await readTemplateMetadata(f);if(p?.optionsHash===i.optionsHash&&await snapshotExists(a,p.snapshotName))return i.prewarmInput.log?.(`reusing cached snapshot`),await touchDirectory(u),{reused:!0};let h=createProviderName(`eve-sbx-tpl`,i.prewarmInput.templateKey,i.optionsHash),_=`${u}.${randomUUID()}.tmp`,v=createProviderName(`eve-sbx-tpl-tmp`,`${i.prewarmInput.templateKey}:${randomUUID()}`);await removeSnapshotIfExists(a,h),await rm(_,{force:!0,recursive:!0}),await mkdir(_,{recursive:!0}),i.prewarmInput.log?.(`creating template VM from image "${i.options.image}"`);let y=await createPreparedMicrosandbox({log:i.prewarmInput.log,module:a,name:v,networkPolicy:i.options.networkPolicy,options:i.options,sessionKey:i.prewarmInput.templateKey,setupBaseRuntime:!0,tags:void 0}),b=buildSandboxSession(createMicrosandboxInternalSession(y),async e=>{await y.setNetworkPolicy(e)});try{i.prewarmInput.bootstrap!==void 0&&(i.prewarmInput.log?.(`running sandbox bootstrap`),await i.prewarmInput.bootstrap({use:async e=>(e?.networkPolicy!==void 0&&await y.setNetworkPolicy(e.networkPolicy),createLoggingSandboxSession({log:i.prewarmInput.log,session:b}))})),i.prewarmInput.seedFiles.length>0&&i.prewarmInput.log?.(`writing ${i.prewarmInput.seedFiles.length} seed file(s)`),await writeSandboxSeedFiles(b,i.prewarmInput.seedFiles),i.prewarmInput.log?.(`snapshotting template VM`),await y.stopAndSnapshot(h),await writeTemplateMetadata(resolveMicrosandboxMetadataPath(_),{optionsHash:i.optionsHash,snapshotName:h,version:MICROSANDBOX_METADATA_VERSION}),await mkdir(dirname(u),{recursive:!0}),await rm(u,{force:!0,recursive:!0});try{await rename(_,u)}catch(e){if(await doesPathExist(u))return{reused:!0};throw e}}finally{await y.removePersisted(),await rm(_,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}}async function createMicrosandboxHandle(e){let t=await loadMicrosandboxModule({appRoot:e.createInput.runtimeContext.appRoot,options:e.options}),n=resolveSandboxCacheDirectory(e.createInput.runtimeContext.appRoot),r=resolveMicrosandboxSessionRootPath(n,e.createInput.sessionKey),a=createActiveMicrosandboxSessionKey(r,e.optionsHash),o=activeMicrosandboxSessionHandles.get(a);if(o!==void 0)return o;let s=resolveMicrosandboxMetadataPath(r),c=readSessionMetadataRecord(e.createInput.existingMetadata)??await readSessionMetadata(s),l=withDevelopmentSandboxMetadataPathTag(e.createInput.tags,s);if(c?.optionsHash===e.optionsHash&&(await sandboxExists(t,c.sandboxName)||c.stateSnapshotName!==void 0&&await snapshotExists(t,c.stateSnapshotName)))
|
|
1
|
+
import{dirname}from"node:path";import{mkdir,rename,rm}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{withDevelopmentSandboxMetadataPathTag}from"#execution/sandbox/development-run.js";import{createFileBackedInternalSandboxSession,touchDirectory,writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{MICROSANDBOX_METADATA_VERSION,readSessionMetadata,readSessionMetadataRecord,readTemplateMetadata,resolveMicrosandboxMetadataPath,writeTemplateMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{connectMicrosandbox,createPreparedMicrosandbox,createProviderName,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,removeSnapshotIfExists,sandboxExists,snapshotExists}from"#execution/sandbox/bindings/microsandbox-runtime.js";import{resolveMicrosandboxSessionRootPath,resolveMicrosandboxTemplateRootPath}from"#execution/sandbox/bindings/microsandbox-templates.js";const activeMicrosandboxSessionHandles=new Map;async function prewarmMicrosandboxTemplate(i){i.prewarmInput.log?.(`loading microsandbox runtime`);let a=await loadMicrosandboxModule({appRoot:i.prewarmInput.runtimeContext.appRoot,log:i.prewarmInput.log,options:i.options}),u=resolveMicrosandboxTemplateRootPath(resolveSandboxCacheDirectory(i.prewarmInput.runtimeContext.appRoot),i.prewarmInput.templateKey),f=resolveMicrosandboxMetadataPath(u);i.prewarmInput.log?.(`checking cached snapshot`);let p=await readTemplateMetadata(f);if(p?.optionsHash===i.optionsHash&&await snapshotExists(a,p.snapshotName))return i.prewarmInput.log?.(`reusing cached snapshot`),await touchDirectory(u),{reused:!0};let h=createProviderName(`eve-sbx-tpl`,i.prewarmInput.templateKey,i.optionsHash),_=`${u}.${randomUUID()}.tmp`,v=createProviderName(`eve-sbx-tpl-tmp`,`${i.prewarmInput.templateKey}:${randomUUID()}`);await removeSnapshotIfExists(a,h),await rm(_,{force:!0,recursive:!0}),await mkdir(_,{recursive:!0}),i.prewarmInput.log?.(`creating template VM from image "${i.options.image}"`);let y=await createPreparedMicrosandbox({log:i.prewarmInput.log,module:a,name:v,networkPolicy:i.options.networkPolicy,options:i.options,sessionKey:i.prewarmInput.templateKey,setupBaseRuntime:!0,tags:void 0}),b=buildSandboxSession(createMicrosandboxInternalSession(y),async e=>{await y.setNetworkPolicy(e)});try{i.prewarmInput.bootstrap!==void 0&&(i.prewarmInput.log?.(`running sandbox bootstrap`),await i.prewarmInput.bootstrap({use:async e=>(e?.networkPolicy!==void 0&&await y.setNetworkPolicy(e.networkPolicy),createLoggingSandboxSession({log:i.prewarmInput.log,session:b}))})),i.prewarmInput.seedFiles.length>0&&i.prewarmInput.log?.(`writing ${i.prewarmInput.seedFiles.length} seed file(s)`),await writeSandboxSeedFiles(b,i.prewarmInput.seedFiles),i.prewarmInput.log?.(`snapshotting template VM`),await y.stopAndSnapshot(h),await writeTemplateMetadata(resolveMicrosandboxMetadataPath(_),{optionsHash:i.optionsHash,snapshotName:h,version:MICROSANDBOX_METADATA_VERSION}),await mkdir(dirname(u),{recursive:!0}),await rm(u,{force:!0,recursive:!0});try{await rename(_,u)}catch(e){if(await doesPathExist(u))return{reused:!0};throw e}}finally{await y.removePersisted(),await rm(_,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}}async function createMicrosandboxHandle(e){let t=await loadMicrosandboxModule({appRoot:e.createInput.runtimeContext.appRoot,options:e.options}),n=resolveSandboxCacheDirectory(e.createInput.runtimeContext.appRoot),r=resolveMicrosandboxSessionRootPath(n,e.createInput.sessionKey),a=createActiveMicrosandboxSessionKey(r,e.optionsHash),o=activeMicrosandboxSessionHandles.get(a);if(o!==void 0)return o;let s=resolveMicrosandboxMetadataPath(r),c=readSessionMetadataRecord(e.createInput.existingMetadata)??await readSessionMetadata(s),l=withDevelopmentSandboxMetadataPathTag(e.createInput.tags,s);if(c?.optionsHash===e.optionsHash&&(await sandboxExists(t,c.sandboxName)||c.stateSnapshotName!==void 0&&await snapshotExists(t,c.stateSnapshotName))){let n=await connectMicrosandbox({metadata:c,metadataPath:s,module:t,options:e.options,sessionKey:e.createInput.sessionKey,tags:l});if(n!==null)return cacheHandle(a,createHandle(n,e.backendName,e.optionsHash,()=>{activeMicrosandboxSessionHandles.delete(a)}))}let d=null;if(e.createInput.templateKey!==null){let r=await readTemplateMetadata(resolveMicrosandboxMetadataPath(resolveMicrosandboxTemplateRootPath(n,e.createInput.templateKey)));if(r===null||r.optionsHash!==e.optionsHash||!await snapshotExists(t,r.snapshotName))throw new SandboxTemplateNotProvisionedError({backendName:e.backendName,templateKey:e.createInput.templateKey});d=r.snapshotName}let m=createProviderName(`eve-sbx-ses`,`${e.createInput.sessionKey}:${randomUUID()}`),g;try{g=await createPreparedMicrosandbox({fromSnapshot:d??void 0,module:t,name:m,networkPolicy:e.options.networkPolicy,options:e.options,sessionKey:e.createInput.sessionKey,setupBaseRuntime:d===null,tags:l})}catch(t){throw d!==null&&e.createInput.templateKey!==null&&isMicrosandboxNotFoundError(t)?new SandboxTemplateNotProvisionedError({backendName:e.backendName,templateKey:e.createInput.templateKey}):t}return await g.writeMetadata(s,e.optionsHash),cacheHandle(a,createHandle(g,e.backendName,e.optionsHash,()=>{activeMicrosandboxSessionHandles.delete(a)}))}function createHandle(e,t,n,r){return{session:buildSandboxSession(createMicrosandboxInternalSession(e),async t=>{await e.setNetworkPolicy(t)}),useSessionFn:async t=>(t?.networkPolicy!==void 0&&await e.setNetworkPolicy(t.networkPolicy),buildSandboxSession(createMicrosandboxInternalSession(e),async t=>{await e.setNetworkPolicy(t)})),async captureState(){return{backendName:t,metadata:{...await e.captureState(n)},sessionKey:e.id}},async dispose(){r?.(),await e.detach()}}}function createMicrosandboxInternalSession(e){return createFileBackedInternalSandboxSession({id:e.id,sandbox:e})}function createActiveMicrosandboxSessionKey(e,t){return`${e}\0${t}`}function cacheHandle(e,t){return activeMicrosandboxSessionHandles.set(e,t),t}function clearActiveMicrosandboxSessionHandlesForTest(){activeMicrosandboxSessionHandles.clear()}export{clearActiveMicrosandboxSessionHandlesForTest,createMicrosandboxHandle,prewarmMicrosandboxTemplate};
|
|
@@ -47,7 +47,7 @@ export declare function connectMicrosandbox(input: {
|
|
|
47
47
|
readonly options: ResolvedMicrosandboxOptions;
|
|
48
48
|
readonly sessionKey: string;
|
|
49
49
|
readonly tags?: SandboxBackendTags;
|
|
50
|
-
}): Promise<MicrosandboxVm>;
|
|
50
|
+
}): Promise<MicrosandboxVm | null>;
|
|
51
51
|
/**
|
|
52
52
|
* Loads the microsandbox npm package and ensures its VM runtime is
|
|
53
53
|
* installed. During `eve dev`, both are installed automatically when
|
|
@@ -73,3 +73,4 @@ export declare function removeSnapshotIfExists(module: MicrosandboxModule, snaps
|
|
|
73
73
|
export declare function createProviderName(prefix: string, key: string, extra?: string): string;
|
|
74
74
|
export declare function createStableHash(value: string): string;
|
|
75
75
|
export declare function doesPathExist(path: string): Promise<boolean>;
|
|
76
|
+
export declare function isMicrosandboxNotFoundError(error: unknown): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{posix}from"node:path";import{access}from"node:fs/promises";import{createHash,randomUUID}from"node:crypto";import{isEveDevEnvironment,loadOptionalEnginePackage}from"#internal/application/optional-package-install.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";const MICROSANDBOX_STOP_TIMEOUT_MS=1e4;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION};let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n,version:MICROSANDBOX_METADATA_VERSION}}async detach(){await this.#i.detach().catch(()=>{})}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a),this.#o!==void 0&&await removeSnapshotIfExists(this.#e.module,this.#o)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),i=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,i);let a=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:a,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=a,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...this.#e.options.env,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(t){let n=this.#i.fs();for(let r of t){let t=posix.dirname(r.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(t)}`,user:MICROSANDBOX_USER}),await n.write(r.path,r.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(r.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,module:e.module,name:e.name,networkPolicy:t,options:e.options,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError(t)||e.metadata.stateSnapshotName===void 0)throw t;return await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists(e.module,e.metadata.stateSnapshotName))throw Error(`Microsandbox session snapshot is missing for sandbox "${e.metadata.sandboxName}".`);let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let i=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await i.writeMetadata(e.metadataPath,e.metadata.optionsHash),i}async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>loadOptionalEnginePackage({appRoot:e.appRoot,autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),missingMessage:"The microsandbox sandbox backend requires the `microsandbox` package, which is not bundled with Eve. Install it in your application (for example `pnpm add -D microsandbox`), or use docker() / vercel() instead.",packageName:`microsandbox`}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(){try{let e=await import(`microsandbox`);return e.isInstalled()?e:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}async function snapshotExists(e,t){try{return await e.Snapshot.get(t),!0}catch(e){if(isMicrosandboxNotFoundError(e))return!1;throw e}}async function sandboxExists(e,t){try{return await e.Sandbox.get(t),!0}catch(e){if(isMicrosandboxNotFoundError(e))return!1;throw e}}async function removeSnapshotIfExists(e,t){try{await e.Snapshot.remove(t,{force:!0})}catch(e){if(!isMicrosandboxNotFoundError(e))throw e}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs(e.options.env).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);return t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.user!==void 0&&(t=t.user(e.user)),await applyMicrosandboxNetwork(t,e.networkPolicy).create()}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function isMicrosandboxNotFoundError(e){return e instanceof Error?/not found|not exist|no such/i.test(e.message):!1}function isMicrosandboxStillRunningError(e){return e instanceof Error?/still running/i.test(e.message):!1}function isMicrosandboxSnapshotSourceRunningError(e){return e instanceof Error?/snapshot source sandbox .*not stopped|SnapshotSandboxRunning/i.test(e.message):!1}function resolveMicrosandboxLabels(e){return{"eve.backend":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
1
|
+
import{posix}from"node:path";import{access}from"node:fs/promises";import{createHash,randomUUID}from"node:crypto";import{isEveDevEnvironment,loadOptionalEnginePackage}from"#internal/application/optional-package-install.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";const MICROSANDBOX_STOP_TIMEOUT_MS=1e4;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION};let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t),{networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n,version:MICROSANDBOX_METADATA_VERSION}}async detach(){await this.#i.detach().catch(()=>{})}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a),this.#o!==void 0&&await removeSnapshotIfExists(this.#e.module,this.#o)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),i=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,i);let a=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:a,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=a,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...this.#e.options.env,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(t){let n=this.#i.fs();for(let r of t){let t=posix.dirname(r.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(t)}`,user:MICROSANDBOX_USER}),await n.write(r.path,r.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(r.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,module:e.module,name:e.name,networkPolicy:t,options:e.options,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError(t))throw t;return e.metadata.stateSnapshotName===void 0?null:await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists(e.module,e.metadata.stateSnapshotName))return null;let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let i=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await i.writeMetadata(e.metadataPath,e.metadata.optionsHash),i}async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>loadOptionalEnginePackage({appRoot:e.appRoot,autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),missingMessage:"The microsandbox sandbox backend requires the `microsandbox` package, which is not bundled with Eve. Install it in your application (for example `pnpm add -D microsandbox`), or use docker() / vercel() instead.",packageName:`microsandbox`}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(){try{let e=await import(`microsandbox`);return e.isInstalled()?e:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}async function snapshotExists(e,t){try{return await e.Snapshot.get(t),!0}catch{return!1}}async function sandboxExists(e,t){try{return await e.Sandbox.get(t),!0}catch(e){if(isMicrosandboxNotFoundError(e))return!1;throw e}}async function removeSnapshotIfExists(e,t){try{await e.Snapshot.remove(t,{force:!0})}catch(e){if(!isMicrosandboxNotFoundError(e))throw e}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs(e.options.env).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);return t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.user!==void 0&&(t=t.user(e.user)),await applyMicrosandboxNetwork(t,e.networkPolicy).create()}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function isMicrosandboxNotFoundError(e){return e instanceof Error?/not found|not exist|no such/i.test(e.message):!1}function isMicrosandboxStillRunningError(e){return e instanceof Error?/still running/i.test(e.message):!1}function isMicrosandboxSnapshotSourceRunningError(e){return e instanceof Error?/snapshot source sandbox .*not stopped|SnapshotSandboxRunning/i.test(e.message):!1}function resolveMicrosandboxLabels(e){return{"eve.backend":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
function isVercelSnapshotUnavailableError(e){for(let t of walkErrorChain(e))
|
|
2
|
-
`);if(/snapshot .*expired|expired .*snapshot|snapshot .*deleted|deleted .*snapshot/i.test(e))return!0}return!1}function*walkErrorChain(e){let t=e,n=new Set;for(;t!=null&&!n.has(t);)n.add(t),yield t,t=t.cause}export{isVercelSnapshotUnavailableError};
|
|
1
|
+
function isVercelSnapshotUnavailableError(e){for(let t of walkErrorChain(e))if((t.response?.status??t.status??t.statusCode)===410)return!0;return!1}function isVercelSandboxMissingError(e){for(let t of walkErrorChain(e))if((t.response?.status??t.status??t.statusCode)===404)return!0;return!1}function*walkErrorChain(e){let t=e,n=new Set;for(;t!=null&&!n.has(t);)n.add(t),yield t,t=t.cause}export{isVercelSandboxMissingError,isVercelSnapshotUnavailableError};
|
|
@@ -2,11 +2,6 @@ import type { SandboxCreateOptions } from "#compiled/@vercel/sandbox/index.js";
|
|
|
2
2
|
import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
3
3
|
import type { VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
4
4
|
import { type CreateVercelSandbox, type VercelSandboxModule } from "#execution/sandbox/bindings/vercel-create-sdk.js";
|
|
5
|
-
/**
|
|
6
|
-
* Construction input for {@link createVercelSandbox}. Internal —
|
|
7
|
-
* the public surface is the `vercel()` factory under
|
|
8
|
-
* `eve/sandbox`.
|
|
9
|
-
*/
|
|
10
5
|
export interface CreateVercelSandboxInput {
|
|
11
6
|
readonly createSandbox?: CreateVercelSandbox;
|
|
12
7
|
readonly createOptions?: SandboxCreateOptions;
|
|
@@ -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{applyInitialVercelNetworkPolicy,ensureVercelSandboxBaseRuntime}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-sdk.js";import{isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{getNamedVercelSandbox}from"#execution/sandbox/bindings/vercel-lookup.js";function createVercelSandbox(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,
|
|
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-sdk.js";import{isVercelSandboxMissingError,isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{getNamedVercelSandbox}from"#execution/sandbox/bindings/vercel-lookup.js";function createVercelSandbox(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,d=new Map;return{name:`vercel`,async create(e){let s=resolveVercelSandboxTags(n.tags,e.tags),u=e.templateKey===null?null:await readTemplateForCreate({createOptions:n,loadSandboxModule:t,prewarmedTemplates:d,templateKey:e.templateKey}),f=await t(),p;try{p=await ensureSession({createOptions:n,createSandbox:r,existingMetadata:e.existingMetadata,sandboxModule:f,sessionKey:e.sessionKey,snapshotId:u?.snapshotId,tags:s})}catch(t){throw u!==null&&(isVercelSnapshotUnavailableError(t)||isVercelSandboxMissingError(t))?(d.delete(u.templateKey),await(await getNamedVercelSandbox({createOptions:n,sandboxModule:f,sandboxName:u.sandboxName}))?.delete(),new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:u.templateKey})):Error(`Failed to create sandbox session "${e.sessionKey}": ${errorMessage(t)}`,{cause:t})}return u===null&&p.created&&(await ensureVercelSandboxBaseRuntime(p.sandbox),await applyInitialVercelNetworkPolicy(p.sandbox,n.networkPolicy)),createHandle(p.sandbox,e.sessionKey)},async prewarm(e){let i;try{i=await ensureTemplateWithUnavailableRetry({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 d.set(e.templateKey,i.template),{reused:i.reused}}}}async function ensureTemplateWithUnavailableRetry(e){try{return await ensureTemplate(e)}catch(t){if(!isVercelSnapshotUnavailableError(t)&&!isVercelSandboxMissingError(t))throw t;return e.log?.(`cached template disappeared; rebuilding sandbox template`),await ensureTemplate(e)}}async function readTemplate(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await e.loadSandboxModule(),r=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:n,sandboxName:e.templateKey});if(r===null||typeof r.currentSnapshotId!=`string`)throw new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:r.name,snapshotId:r.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 getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:t,sandboxName: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 getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:e.sandboxModule,sandboxName: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}`}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 vercel().`);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{createVercelSandbox};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.11.
|
|
1
|
+
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.11.1`,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 n=e;for(;;){if(existsSync(join(n,`package.json`))&&!isBuildOutputPackageRoot(n))return n;let r=dirname(n);if(r===n)throw Error(`Failed to resolve package root from "${e}".`);n=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 r=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(r?.name===t)return r}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,4 +1,4 @@
|
|
|
1
|
-
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.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_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.11.
|
|
1
|
+
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.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_AI_PACKAGE_VERSION=`7.0.0-beta.178`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.11.1`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}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.eveVersion)).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.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}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__",
|
package/docs/getting-started.mdx
CHANGED
|
@@ -5,7 +5,9 @@ description: "Install Eve, scaffold your first agent, give it a tool, and run it
|
|
|
5
5
|
|
|
6
6
|
Eve is a filesystem-first framework for durable agents. You write capabilities under `agent/`, and Eve runs the model loop, persists every session, and serves the agent over HTTP and platform channels. You'll scaffold an app, add a tool, run it locally, then create, stream, and continue a session over HTTP.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
<Callout>
|
|
9
|
+
Eve is currently in beta and subject to the [Vercel beta terms](https://vercel.com/docs/release-phases/public-beta-agreement); the framework, APIs, documentation, and behavior may change before general availability.
|
|
10
|
+
</Callout>
|
|
9
11
|
|
|
10
12
|
## Prerequisites
|
|
11
13
|
|
|
@@ -7,7 +7,9 @@ Eve is a framework for building durable agents as ordinary files in a TypeScript
|
|
|
7
7
|
|
|
8
8
|
Instead of one large configuration object, each part of your agent gets a clear home. Instructions go in one file, tools in one folder, channels in another. Eve discovers that structure and turns it into an agent that runs locally, serves HTTP, connects to other platforms, and keeps working across many turns.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
<Callout>
|
|
11
|
+
Eve is currently in beta and subject to the [Vercel beta terms](https://vercel.com/docs/release-phases/public-beta-agreement); the framework, APIs, documentation, and behavior may change before general availability.
|
|
12
|
+
</Callout>
|
|
11
13
|
|
|
12
14
|
## An Eve project at a glance
|
|
13
15
|
|
package/docs/meta.json
CHANGED
package/docs/reference/cli.md
CHANGED
|
@@ -5,8 +5,6 @@ description: "Reference for every eve CLI command: init, info, build, start, dev
|
|
|
5
5
|
|
|
6
6
|
The `eve` binary (`bin: eve`) runs from your app root, and every command first loads `.env`/`.env.local` from that root. Running `eve` with no command runs `eve dev`.
|
|
7
7
|
|
|
8
|
-
Eve is currently a preview and subject to the Vercel beta terms; the framework, APIs, documentation, and behavior may change before general availability.
|
|
9
|
-
|
|
10
8
|
## Commands
|
|
11
9
|
|
|
12
10
|
| Command | Description |
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
description: "
|
|
2
|
+
title: "Responsible Use"
|
|
3
|
+
description: "Deployer responsibility and safeguards to review before using Eve with sensitive, regulated, or production data."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Eve is currently a preview and subject to the Vercel beta terms; the framework, APIs, documentation, and behavior may change before general availability.
|
|
7
|
-
|
|
8
6
|
As the deployer, it is your responsibility to ensure your agent complies with applicable laws.
|
|
9
7
|
|
|
10
8
|
You are responsible for configuring approval policies, tool restrictions, connection scopes, route/session authorization, sandbox controls, telemetry exports, and other safeguards appropriate for your use case.
|