@molecule/api-code-sandbox-e2b 1.2.4 → 1.2.5

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/README.md CHANGED
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-04T08:07:55.241Z
6
+ Generated: 2026-10-04T09:45:27.540Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-code-sandbox-e2b
@@ -603,5 +603,12 @@ default is `onTimeout: 'kill'`, so a sandbox nothing touched for its lifetime
603
603
  would be destroyed with its files. This bond creates every sandbox with
604
604
  `lifecycle: { onTimeout: { action: 'pause', keepMemory: true } }`; the memory
605
605
  snapshot is what lets `resume()` truthfully report `processesPreserved: true`.
606
+ The one exception is the throwaway `verifyEgress()` probe, created with
607
+ `lifecycle: { onTimeout: 'kill' }`: a pause writes a full snapshot to the
608
+ host's disk, and nobody resumes a probe. Every pause and every
609
+ `commitTemplate()` is a new snapshot build on a self-hosted box's disk, so
610
+ a pause-on-timeout sandbox you do not need back is disk you pay for — keep a
611
+ sandbox you intend to keep warm alive with `keepAlive(ms)`, and destroy one
612
+ you are done with rather than letting it time out.
606
613
  Extending the deadline is `keepAlive(ms)` — call it from a real activity
607
614
  signal (an open editor's heartbeat), never as a side effect of polling.
package/dist/index.d.ts CHANGED
@@ -144,6 +144,13 @@
144
144
  * would be destroyed with its files. This bond creates every sandbox with
145
145
  * `lifecycle: { onTimeout: { action: 'pause', keepMemory: true } }`; the memory
146
146
  * snapshot is what lets `resume()` truthfully report `processesPreserved: true`.
147
+ * The one exception is the throwaway `verifyEgress()` probe, created with
148
+ * `lifecycle: { onTimeout: 'kill' }`: a pause writes a full snapshot to the
149
+ * host's disk, and nobody resumes a probe. Every pause and every
150
+ * `commitTemplate()` is a new snapshot build on a self-hosted box's disk, so
151
+ * a pause-on-timeout sandbox you do not need back is disk you pay for — keep a
152
+ * sandbox you intend to keep warm alive with `keepAlive(ms)`, and destroy one
153
+ * you are done with rather than letting it time out.
147
154
  * Extending the deadline is `keepAlive(ms)` — call it from a real activity
148
155
  * signal (an open editor's heartbeat), never as a side effect of polling.
149
156
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsJG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6JG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -144,6 +144,13 @@
144
144
  * would be destroyed with its files. This bond creates every sandbox with
145
145
  * `lifecycle: { onTimeout: { action: 'pause', keepMemory: true } }`; the memory
146
146
  * snapshot is what lets `resume()` truthfully report `processesPreserved: true`.
147
+ * The one exception is the throwaway `verifyEgress()` probe, created with
148
+ * `lifecycle: { onTimeout: 'kill' }`: a pause writes a full snapshot to the
149
+ * host's disk, and nobody resumes a probe. Every pause and every
150
+ * `commitTemplate()` is a new snapshot build on a self-hosted box's disk, so
151
+ * a pause-on-timeout sandbox you do not need back is disk you pay for — keep a
152
+ * sandbox you intend to keep warm alive with `keepAlive(ms)`, and destroy one
153
+ * you are done with rather than letting it time out.
147
154
  * Extending the deadline is `keepAlive(ms)` — call it from a real activity
148
155
  * signal (an open editor's heartbeat), never as a side effect of polling.
149
156
  *
@@ -64,6 +64,22 @@ export declare class E2BSandboxProvider implements SandboxProvider {
64
64
  * @returns A live sandbox handle.
65
65
  */
66
66
  create(config: SandboxConfig): Promise<Sandbox>;
67
+ /**
68
+ * {@link create} with the sandbox's timeout action chosen by the caller.
69
+ *
70
+ * `'pause'` is E2B's `lifecycle: { onTimeout: { action: 'pause', keepMemory:
71
+ * true } }` — the data-safe default for anything that may hold a project
72
+ * (see {@link create}). `'kill'` is `lifecycle: { onTimeout: 'kill' }` — for a
73
+ * THROWAWAY sandbox this bond destroys itself (the egress probe): pausing one
74
+ * at its deadline would write a full memory + filesystem snapshot to the
75
+ * host's disk for a sandbox nobody will ever resume. E2B cannot change a
76
+ * sandbox's `onTimeout` after create, so the choice is made here, once.
77
+ *
78
+ * @param config - As for {@link create}.
79
+ * @param onTimeout - What E2B does at the sandbox's deadline.
80
+ * @returns A live sandbox handle.
81
+ */
82
+ private createSandbox;
67
83
  /**
68
84
  * Resolve an existing sandbox by id.
69
85
  *
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
package/dist/provider.js CHANGED
@@ -551,6 +551,25 @@ class E2BSandbox {
551
551
  async writeFile(path, content) {
552
552
  await this.sbx.files.write(path, content);
553
553
  }
554
+ /**
555
+ * Read a file's exact bytes through envd's file API (never command stdout,
556
+ * which envd truncates for large outputs).
557
+ *
558
+ * @param path - Absolute path inside the sandbox.
559
+ * @returns The file's bytes.
560
+ */
561
+ async readFileBytes(path) {
562
+ return this.sbx.files.read(path, { format: 'bytes' });
563
+ }
564
+ /**
565
+ * Write exact bytes to a file through envd's file API, replacing it.
566
+ *
567
+ * @param path - Absolute path inside the sandbox.
568
+ * @param data - The bytes to write.
569
+ */
570
+ async writeFileBytes(path, data) {
571
+ await this.sbx.files.write(path, data);
572
+ }
554
573
  /**
555
574
  * List a directory. Throws when the path does not exist (an empty array
556
575
  * means "exists and is empty", never "missing").
@@ -777,6 +796,24 @@ export class E2BSandboxProvider {
777
796
  * @returns A live sandbox handle.
778
797
  */
779
798
  async create(config) {
799
+ return this.createSandbox(config, 'pause');
800
+ }
801
+ /**
802
+ * {@link create} with the sandbox's timeout action chosen by the caller.
803
+ *
804
+ * `'pause'` is E2B's `lifecycle: { onTimeout: { action: 'pause', keepMemory:
805
+ * true } }` — the data-safe default for anything that may hold a project
806
+ * (see {@link create}). `'kill'` is `lifecycle: { onTimeout: 'kill' }` — for a
807
+ * THROWAWAY sandbox this bond destroys itself (the egress probe): pausing one
808
+ * at its deadline would write a full memory + filesystem snapshot to the
809
+ * host's disk for a sandbox nobody will ever resume. E2B cannot change a
810
+ * sandbox's `onTimeout` after create, so the choice is made here, once.
811
+ *
812
+ * @param config - As for {@link create}.
813
+ * @param onTimeout - What E2B does at the sandbox's deadline.
814
+ * @returns A live sandbox handle.
815
+ */
816
+ async createSandbox(config, onTimeout) {
780
817
  const client = await this.client();
781
818
  const templateId = config.templateId ?? this.config.templateId;
782
819
  if (config.volumeName && !config.volumeMountPath) {
@@ -789,7 +826,9 @@ export class E2BSandboxProvider {
789
826
  timeoutMs: this.config.defaultTimeoutMs,
790
827
  envs: config.env ?? {},
791
828
  metadata: { projectId: config.projectId, ...(config.labels ?? {}) },
792
- lifecycle: { onTimeout: { action: 'pause', keepMemory: true } },
829
+ lifecycle: onTimeout === 'kill'
830
+ ? { onTimeout: 'kill' }
831
+ : { onTimeout: { action: 'pause', keepMemory: true } },
793
832
  ...(config.volumeName
794
833
  ? { volumeMounts: { [config.volumeMountPath]: config.volumeName } }
795
834
  : {}),
@@ -1193,7 +1232,9 @@ export class E2BSandboxProvider {
1193
1232
  async verifyEgress() {
1194
1233
  let handle;
1195
1234
  try {
1196
- handle = await this.create({ projectId: `egress-probe-${Date.now()}`, env: {} });
1235
+ // Kill, not pause, at its deadline: a leaked probe must not leave a
1236
+ // snapshot on the host's disk (see createSandbox).
1237
+ handle = await this.createSandbox({ projectId: `egress-probe-${Date.now()}`, env: {} }, 'kill');
1197
1238
  }
1198
1239
  catch (error) {
1199
1240
  return {
@@ -1205,8 +1246,7 @@ export class E2BSandboxProvider {
1205
1246
  const verdict = await this.probeEgress(handle);
1206
1247
  // The probe sandbox is destroyed on EVERY path. A failed destroy is retried,
1207
1248
  // and one that still fails is reported in the verdict's detail: the sandbox
1208
- // was created to pause at its timeout, so a silently leaked probe is billed
1209
- // storage forever.
1249
+ // is killed at its own deadline, but until then it runs metered.
1210
1250
  const leaked = await this.destroyProbe(handle.id);
1211
1251
  return leaked ? { ...verdict, detail: `${verdict.detail} ${leaked}` } : verdict;
1212
1252
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-code-sandbox-e2b",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "E2B (e2b.dev) code sandbox provider — Firecracker microVMs with golden templates, fork, and pause/resume",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "license": "Apache-2.0",
31
31
  "devDependencies": {
32
32
  "@molecule/api-bond": "1.0.2",
33
- "@molecule/api-code-sandbox": "1.2.1",
33
+ "@molecule/api-code-sandbox": "1.3.0",
34
34
  "@types/node": "26.1.2",
35
35
  "typescript": "6.0.3",
36
36
  "vitest": "4.1.11"