@hasna/sandboxes 0.1.8 → 0.1.9

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/dist/cli/index.js CHANGED
@@ -2275,6 +2275,12 @@ CREATE TABLE IF NOT EXISTS snapshots (
2275
2275
  );
2276
2276
  CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
2277
2277
  INSERT OR IGNORE INTO _migrations (id) VALUES (4);
2278
+ `,
2279
+ `
2280
+ ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
2281
+ ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
2282
+ ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
2283
+ INSERT OR IGNORE INTO _migrations (id) VALUES (5);
2278
2284
  `
2279
2285
  ];
2280
2286
  });
@@ -2326,6 +2332,9 @@ function rowToSandbox(row) {
2326
2332
  project_id: row.project_id,
2327
2333
  on_timeout: row.on_timeout ?? "terminate",
2328
2334
  auto_resume: row.auto_resume === 1,
2335
+ budget_limit_usd: row.budget_limit_usd ?? null,
2336
+ on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
2337
+ started_at: row.started_at ?? null,
2329
2338
  created_at: row.created_at,
2330
2339
  updated_at: row.updated_at
2331
2340
  };
@@ -2343,8 +2352,10 @@ function createSandbox(input) {
2343
2352
  const project_id = input.project_id ?? null;
2344
2353
  const on_timeout = input.on_timeout ?? "terminate";
2345
2354
  const auto_resume = input.auto_resume ? 1 : 0;
2346
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
2347
- VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, timestamp, timestamp);
2355
+ const budget_limit_usd = input.budget_limit_usd ?? null;
2356
+ const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
2357
+ db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
2358
+ VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
2348
2359
  return getSandbox(id);
2349
2360
  }
2350
2361
  function getSandbox(id) {
@@ -2416,6 +2427,10 @@ function updateSandbox(id, updates) {
2416
2427
  setClauses.push("keep_alive_until = ?");
2417
2428
  params.push(updates.keep_alive_until);
2418
2429
  }
2430
+ if (updates.started_at !== undefined) {
2431
+ setClauses.push("started_at = ?");
2432
+ params.push(updates.started_at);
2433
+ }
2419
2434
  if (setClauses.length === 0) {
2420
2435
  return getSandbox(resolvedId);
2421
2436
  }
@@ -2694,10 +2709,11 @@ class E2BProvider {
2694
2709
  onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
2695
2710
  envs: opts?.env,
2696
2711
  cwd: opts?.cwd,
2697
- timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
2712
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
2713
+ ...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
2698
2714
  });
2699
2715
  return {
2700
- exit_code: result.exitCode,
2716
+ exit_code: result.exitCode ?? 0,
2701
2717
  stdout: result.stdout,
2702
2718
  stderr: result.stderr
2703
2719
  };
@@ -2705,10 +2721,28 @@ class E2BProvider {
2705
2721
  throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
2706
2722
  }
2707
2723
  }
2708
- async readFile(sandboxId, path) {
2724
+ async readFile(sandboxId, path, opts) {
2709
2725
  const sandbox = await this.getInstance(sandboxId);
2710
2726
  try {
2711
- return await sandbox.files.read(path, { format: "text" });
2727
+ if (opts?.encoding === "base64") {
2728
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
2729
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
2730
+ return Buffer.from(sliced).toString("base64");
2731
+ } else if (opts?.encoding === "hex") {
2732
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
2733
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
2734
+ return Buffer.from(sliced).toString("hex");
2735
+ } else {
2736
+ const content = await sandbox.files.read(path, { format: "text" });
2737
+ if (opts?.offset !== undefined || opts?.limit !== undefined) {
2738
+ const lines = content.split(`
2739
+ `);
2740
+ const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
2741
+ return sliced.join(`
2742
+ `);
2743
+ }
2744
+ return content;
2745
+ }
2712
2746
  } catch (err) {
2713
2747
  throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
2714
2748
  }
@@ -2721,9 +2755,21 @@ class E2BProvider {
2721
2755
  throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
2722
2756
  }
2723
2757
  }
2724
- async listFiles(sandboxId, path) {
2758
+ async listFiles(sandboxId, path, opts) {
2725
2759
  const sandbox = await this.getInstance(sandboxId);
2726
2760
  try {
2761
+ if (opts?.recursive || opts?.glob) {
2762
+ const pattern = opts.glob ? opts.glob : "*";
2763
+ const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
2764
+ const result = await sandbox.commands.run(cmd);
2765
+ return result.stdout.trim().split(`
2766
+ `).filter(Boolean).map((p) => ({
2767
+ path: p.trim(),
2768
+ name: p.trim().split("/").pop() || p.trim(),
2769
+ is_dir: false,
2770
+ size: 0
2771
+ }));
2772
+ }
2727
2773
  const entries = await sandbox.files.list(path);
2728
2774
  return entries.map((e) => ({
2729
2775
  path: e.path,
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA2MtC,wBAAgB,WAAW,IAAI,QAAQ,CAYtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmNtC,wBAAgB,WAAW,IAAI,QAAQ,CAYtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf"}
@@ -7,6 +7,6 @@ export declare function listSandboxes(opts?: {
7
7
  provider?: SandboxProviderName;
8
8
  project_id?: string;
9
9
  }): Sandbox[];
10
- export declare function updateSandbox(id: string, updates: Partial<Pick<Sandbox, "status" | "provider_sandbox_id" | "name" | "image" | "timeout" | "config" | "env_vars" | "keep_alive_until">>): Sandbox;
10
+ export declare function updateSandbox(id: string, updates: Partial<Pick<Sandbox, "status" | "provider_sandbox_id" | "name" | "image" | "timeout" | "config" | "env_vars" | "keep_alive_until" | "started_at">>): Sandbox;
11
11
  export declare function deleteSandbox(id: string): void;
12
12
  //# sourceMappingURL=sandboxes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandboxes.d.ts","sourceRoot":"","sources":["../../src/db/sandboxes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAkBrD;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAkChE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,EAAE,CAwBZ;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CACd,IAAI,CACF,OAAO,EACL,QAAQ,GACR,qBAAqB,GACrB,MAAM,GACN,OAAO,GACP,SAAS,GACT,QAAQ,GACR,UAAU,GACV,kBAAkB,CACrB,CACF,GACA,OAAO,CAuDT;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO9C"}
1
+ {"version":3,"file":"sandboxes.d.ts","sourceRoot":"","sources":["../../src/db/sandboxes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAqBrD;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAsChE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,EAAE,CAwBZ;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CACd,IAAI,CACF,OAAO,EACL,QAAQ,GACR,qBAAqB,GACrB,MAAM,GACN,OAAO,GACP,SAAS,GACT,QAAQ,GACR,UAAU,GACV,kBAAkB,GAClB,YAAY,CACf,CACF,GACA,OAAO,CA2DT;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO9C"}
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { createSnapshot, getSnapshot, listSnapshots, deleteSnapshot } from "./db
11
11
  export type { Snapshot, SnapshotRow } from "./db/snapshots.js";
12
12
  export { SnapshotNotFoundError } from "./db/snapshots.js";
13
13
  export { loadConfig, saveConfig, getDefaultProvider, getDefaultTimeout, getDefaultImage, getProviderApiKey, setConfigValue, getConfigValue } from "./lib/config.js";
14
+ export { BUILTIN_IMAGES, resolveImage, getBuiltinImageSetupScript } from "./lib/images.js";
14
15
  export { getProvider } from "./providers/index.js";
15
16
  export type { SandboxProvider, ProviderSandbox, CreateSandboxOpts, ExecOptions } from "./providers/types.js";
16
17
  export { createStreamCollector, addStreamListener, emitLifecycleEvent } from "./lib/stream.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/F,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpK,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG7G,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG/F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/F,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpK,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAG3F,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG7G,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG/F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -174,10 +174,11 @@ class E2BProvider {
174
174
  onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
175
175
  envs: opts?.env,
176
176
  cwd: opts?.cwd,
177
- timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
177
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
178
+ ...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
178
179
  });
179
180
  return {
180
- exit_code: result.exitCode,
181
+ exit_code: result.exitCode ?? 0,
181
182
  stdout: result.stdout,
182
183
  stderr: result.stderr
183
184
  };
@@ -185,10 +186,28 @@ class E2BProvider {
185
186
  throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
186
187
  }
187
188
  }
188
- async readFile(sandboxId, path) {
189
+ async readFile(sandboxId, path, opts) {
189
190
  const sandbox = await this.getInstance(sandboxId);
190
191
  try {
191
- return await sandbox.files.read(path, { format: "text" });
192
+ if (opts?.encoding === "base64") {
193
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
194
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
195
+ return Buffer.from(sliced).toString("base64");
196
+ } else if (opts?.encoding === "hex") {
197
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
198
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
199
+ return Buffer.from(sliced).toString("hex");
200
+ } else {
201
+ const content = await sandbox.files.read(path, { format: "text" });
202
+ if (opts?.offset !== undefined || opts?.limit !== undefined) {
203
+ const lines = content.split(`
204
+ `);
205
+ const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
206
+ return sliced.join(`
207
+ `);
208
+ }
209
+ return content;
210
+ }
192
211
  } catch (err) {
193
212
  throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
194
213
  }
@@ -201,9 +220,21 @@ class E2BProvider {
201
220
  throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
202
221
  }
203
222
  }
204
- async listFiles(sandboxId, path) {
223
+ async listFiles(sandboxId, path, opts) {
205
224
  const sandbox = await this.getInstance(sandboxId);
206
225
  try {
226
+ if (opts?.recursive || opts?.glob) {
227
+ const pattern = opts.glob ? opts.glob : "*";
228
+ const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
229
+ const result = await sandbox.commands.run(cmd);
230
+ return result.stdout.trim().split(`
231
+ `).filter(Boolean).map((p) => ({
232
+ path: p.trim(),
233
+ name: p.trim().split("/").pop() || p.trim(),
234
+ is_dir: false,
235
+ size: 0
236
+ }));
237
+ }
207
238
  const entries = await sandbox.files.list(path);
208
239
  return entries.map((e) => ({
209
240
  path: e.path,
@@ -875,6 +906,12 @@ CREATE TABLE IF NOT EXISTS snapshots (
875
906
  );
876
907
  CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
877
908
  INSERT OR IGNORE INTO _migrations (id) VALUES (4);
909
+ `,
910
+ `
911
+ ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
912
+ ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
913
+ ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
914
+ INSERT OR IGNORE INTO _migrations (id) VALUES (5);
878
915
  `
879
916
  ];
880
917
  var db = null;
@@ -949,6 +986,9 @@ function rowToSandbox(row) {
949
986
  project_id: row.project_id,
950
987
  on_timeout: row.on_timeout ?? "terminate",
951
988
  auto_resume: row.auto_resume === 1,
989
+ budget_limit_usd: row.budget_limit_usd ?? null,
990
+ on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
991
+ started_at: row.started_at ?? null,
952
992
  created_at: row.created_at,
953
993
  updated_at: row.updated_at
954
994
  };
@@ -966,8 +1006,10 @@ function createSandbox(input) {
966
1006
  const project_id = input.project_id ?? null;
967
1007
  const on_timeout = input.on_timeout ?? "terminate";
968
1008
  const auto_resume = input.auto_resume ? 1 : 0;
969
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
970
- VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, timestamp, timestamp);
1009
+ const budget_limit_usd = input.budget_limit_usd ?? null;
1010
+ const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
1011
+ db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
1012
+ VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
971
1013
  return getSandbox(id);
972
1014
  }
973
1015
  function getSandbox(id) {
@@ -1039,6 +1081,10 @@ function updateSandbox(id, updates) {
1039
1081
  setClauses.push("keep_alive_until = ?");
1040
1082
  params.push(updates.keep_alive_until);
1041
1083
  }
1084
+ if (updates.started_at !== undefined) {
1085
+ setClauses.push("started_at = ?");
1086
+ params.push(updates.started_at);
1087
+ }
1042
1088
  if (setClauses.length === 0) {
1043
1089
  return getSandbox(resolvedId);
1044
1090
  }
@@ -1504,6 +1550,47 @@ function getConfigValue(key) {
1504
1550
  }
1505
1551
  return;
1506
1552
  }
1553
+ // src/lib/images.ts
1554
+ var BUILTIN_IMAGES = {
1555
+ node20: {
1556
+ e2b: "e2bdev/base:latest",
1557
+ description: "Node 20 + npm + pnpm + yarn",
1558
+ setup_script: "curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm yarn"
1559
+ },
1560
+ "node20-claude": {
1561
+ e2b: "e2bdev/base:latest",
1562
+ description: "Node 20 + Claude Code CLI pre-installed",
1563
+ setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @anthropic-ai/claude-code && mkdir -p ~/.claude && echo '{"hasCompletedOnboarding":true,"hasTrustDialogAccepted":true,"hasAcknowledgedCostThreshold":true}' > ~/.claude.json`
1564
+ },
1565
+ "node20-codex": {
1566
+ e2b: "e2bdev/base:latest",
1567
+ description: "Node 20 + Codex CLI pre-installed",
1568
+ setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @openai/codex && mkdir -p ~/.codex && echo '[core]
1569
+ approvalMode = "full-auto"
1570
+ ' > ~/.codex/config.toml`
1571
+ },
1572
+ python312: {
1573
+ e2b: "e2bdev/base:latest",
1574
+ description: "Python 3.12 + uv + pip",
1575
+ setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv"
1576
+ },
1577
+ "python312-agents": {
1578
+ e2b: "e2bdev/base:latest",
1579
+ description: "Python 3.12 + uv + common AI libs",
1580
+ setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv anthropic openai langchain"
1581
+ },
1582
+ fullstack: {
1583
+ e2b: "e2bdev/base:latest",
1584
+ description: "Node 20 + Python 3.12 + git + build tools",
1585
+ setup_script: "apt-get update && apt-get install -y git build-essential python3.12 python3-pip && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm"
1586
+ }
1587
+ };
1588
+ function resolveImage(image) {
1589
+ return BUILTIN_IMAGES[image]?.e2b ?? image;
1590
+ }
1591
+ function getBuiltinImageSetupScript(image) {
1592
+ return BUILTIN_IMAGES[image]?.setup_script;
1593
+ }
1507
1594
  // src/providers/index.ts
1508
1595
  init_types();
1509
1596
  var providerCache = new Map;
@@ -1722,6 +1809,7 @@ export {
1722
1809
  setConfigValue,
1723
1810
  saveConfig,
1724
1811
  resolvePartialId,
1812
+ resolveImage,
1725
1813
  resetDatabase,
1726
1814
  registerAgent,
1727
1815
  now,
@@ -1750,6 +1838,7 @@ export {
1750
1838
  getDefaultImage,
1751
1839
  getDatabase,
1752
1840
  getConfigValue,
1841
+ getBuiltinImageSetupScript,
1753
1842
  getAgentDriver,
1754
1843
  getAgentByName,
1755
1844
  getAgent,
@@ -1783,6 +1872,7 @@ export {
1783
1872
  ProviderError,
1784
1873
  ProjectNotFoundError,
1785
1874
  EVENT_TYPES,
1875
+ BUILTIN_IMAGES,
1786
1876
  AgentNotFoundError,
1787
1877
  AGENT_TYPES
1788
1878
  };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Built-in sandbox image aliases.
3
+ * Maps a short name to the provider-specific image identifier.
4
+ * For E2B, these are custom images or base images with setup scripts.
5
+ */
6
+ export declare const BUILTIN_IMAGES: Record<string, {
7
+ e2b: string;
8
+ description: string;
9
+ setup_script?: string;
10
+ }>;
11
+ export declare function resolveImage(image: string): string;
12
+ export declare function getBuiltinImageSetupScript(image: string): string | undefined;
13
+ //# sourceMappingURL=images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/lib/images.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CA+BtG,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E"}
package/dist/mcp/index.js CHANGED
@@ -147,10 +147,11 @@ class E2BProvider {
147
147
  onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
148
148
  envs: opts?.env,
149
149
  cwd: opts?.cwd,
150
- timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
150
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
151
+ ...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
151
152
  });
152
153
  return {
153
- exit_code: result.exitCode,
154
+ exit_code: result.exitCode ?? 0,
154
155
  stdout: result.stdout,
155
156
  stderr: result.stderr
156
157
  };
@@ -158,10 +159,28 @@ class E2BProvider {
158
159
  throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
159
160
  }
160
161
  }
161
- async readFile(sandboxId, path) {
162
+ async readFile(sandboxId, path, opts) {
162
163
  const sandbox = await this.getInstance(sandboxId);
163
164
  try {
164
- return await sandbox.files.read(path, { format: "text" });
165
+ if (opts?.encoding === "base64") {
166
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
167
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
168
+ return Buffer.from(sliced).toString("base64");
169
+ } else if (opts?.encoding === "hex") {
170
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
171
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
172
+ return Buffer.from(sliced).toString("hex");
173
+ } else {
174
+ const content = await sandbox.files.read(path, { format: "text" });
175
+ if (opts?.offset !== undefined || opts?.limit !== undefined) {
176
+ const lines = content.split(`
177
+ `);
178
+ const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
179
+ return sliced.join(`
180
+ `);
181
+ }
182
+ return content;
183
+ }
165
184
  } catch (err) {
166
185
  throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
167
186
  }
@@ -174,9 +193,21 @@ class E2BProvider {
174
193
  throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
175
194
  }
176
195
  }
177
- async listFiles(sandboxId, path) {
196
+ async listFiles(sandboxId, path, opts) {
178
197
  const sandbox = await this.getInstance(sandboxId);
179
198
  try {
199
+ if (opts?.recursive || opts?.glob) {
200
+ const pattern = opts.glob ? opts.glob : "*";
201
+ const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
202
+ const result = await sandbox.commands.run(cmd);
203
+ return result.stdout.trim().split(`
204
+ `).filter(Boolean).map((p) => ({
205
+ path: p.trim(),
206
+ name: p.trim().split("/").pop() || p.trim(),
207
+ is_dir: false,
208
+ size: 0
209
+ }));
210
+ }
180
211
  const entries = await sandbox.files.list(path);
181
212
  return entries.map((e) => ({
182
213
  path: e.path,
@@ -4822,6 +4853,12 @@ CREATE TABLE IF NOT EXISTS snapshots (
4822
4853
  );
4823
4854
  CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
4824
4855
  INSERT OR IGNORE INTO _migrations (id) VALUES (4);
4856
+ `,
4857
+ `
4858
+ ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
4859
+ ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
4860
+ ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
4861
+ INSERT OR IGNORE INTO _migrations (id) VALUES (5);
4825
4862
  `
4826
4863
  ];
4827
4864
  var db = null;
@@ -4882,6 +4919,9 @@ function rowToSandbox(row) {
4882
4919
  project_id: row.project_id,
4883
4920
  on_timeout: row.on_timeout ?? "terminate",
4884
4921
  auto_resume: row.auto_resume === 1,
4922
+ budget_limit_usd: row.budget_limit_usd ?? null,
4923
+ on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
4924
+ started_at: row.started_at ?? null,
4885
4925
  created_at: row.created_at,
4886
4926
  updated_at: row.updated_at
4887
4927
  };
@@ -4899,8 +4939,10 @@ function createSandbox(input) {
4899
4939
  const project_id = input.project_id ?? null;
4900
4940
  const on_timeout = input.on_timeout ?? "terminate";
4901
4941
  const auto_resume = input.auto_resume ? 1 : 0;
4902
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
4903
- VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, timestamp, timestamp);
4942
+ const budget_limit_usd = input.budget_limit_usd ?? null;
4943
+ const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
4944
+ db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
4945
+ VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
4904
4946
  return getSandbox(id);
4905
4947
  }
4906
4948
  function getSandbox(id) {
@@ -4972,6 +5014,10 @@ function updateSandbox(id, updates) {
4972
5014
  setClauses.push("keep_alive_until = ?");
4973
5015
  params.push(updates.keep_alive_until);
4974
5016
  }
5017
+ if (updates.started_at !== undefined) {
5018
+ setClauses.push("started_at = ?");
5019
+ params.push(updates.started_at);
5020
+ }
4975
5021
  if (setClauses.length === 0) {
4976
5022
  return getSandbox(resolvedId);
4977
5023
  }
@@ -5596,7 +5642,61 @@ async function stopAgent(sandboxId) {
5596
5642
  emitLifecycleEvent(sandbox.id, "Agent stopped by user");
5597
5643
  }
5598
5644
 
5645
+ // src/lib/images.ts
5646
+ var BUILTIN_IMAGES = {
5647
+ node20: {
5648
+ e2b: "e2bdev/base:latest",
5649
+ description: "Node 20 + npm + pnpm + yarn",
5650
+ setup_script: "curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm yarn"
5651
+ },
5652
+ "node20-claude": {
5653
+ e2b: "e2bdev/base:latest",
5654
+ description: "Node 20 + Claude Code CLI pre-installed",
5655
+ setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @anthropic-ai/claude-code && mkdir -p ~/.claude && echo '{"hasCompletedOnboarding":true,"hasTrustDialogAccepted":true,"hasAcknowledgedCostThreshold":true}' > ~/.claude.json`
5656
+ },
5657
+ "node20-codex": {
5658
+ e2b: "e2bdev/base:latest",
5659
+ description: "Node 20 + Codex CLI pre-installed",
5660
+ setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @openai/codex && mkdir -p ~/.codex && echo '[core]
5661
+ approvalMode = "full-auto"
5662
+ ' > ~/.codex/config.toml`
5663
+ },
5664
+ python312: {
5665
+ e2b: "e2bdev/base:latest",
5666
+ description: "Python 3.12 + uv + pip",
5667
+ setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv"
5668
+ },
5669
+ "python312-agents": {
5670
+ e2b: "e2bdev/base:latest",
5671
+ description: "Python 3.12 + uv + common AI libs",
5672
+ setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv anthropic openai langchain"
5673
+ },
5674
+ fullstack: {
5675
+ e2b: "e2bdev/base:latest",
5676
+ description: "Node 20 + Python 3.12 + git + build tools",
5677
+ setup_script: "apt-get update && apt-get install -y git build-essential python3.12 python3-pip && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm"
5678
+ }
5679
+ };
5680
+ function resolveImage(image) {
5681
+ return BUILTIN_IMAGES[image]?.e2b ?? image;
5682
+ }
5683
+ function getBuiltinImageSetupScript(image) {
5684
+ return BUILTIN_IMAGES[image]?.setup_script;
5685
+ }
5686
+
5599
5687
  // src/mcp/index.ts
5688
+ var E2B_COST_PER_SECOND = 0.000014;
5689
+ var DAYTONA_COST_PER_SECOND = 0.00001;
5690
+ function estimateCost(providerName, startedAt) {
5691
+ if (!startedAt)
5692
+ return { compute_seconds: 0, cost_usd: 0 };
5693
+ const seconds = (Date.now() - new Date(startedAt).getTime()) / 1000;
5694
+ const rate = providerName === "daytona" ? DAYTONA_COST_PER_SECOND : E2B_COST_PER_SECOND;
5695
+ return {
5696
+ compute_seconds: Math.round(seconds),
5697
+ cost_usd: Math.round(seconds * rate * 1e6) / 1e6
5698
+ };
5699
+ }
5600
5700
  var exposedPorts = new Map;
5601
5701
  function ok(data) {
5602
5702
  return { content: [{ type: "text", text: JSON.stringify(data) }] };
@@ -5638,7 +5738,9 @@ var TOOL_CATALOG = [
5638
5738
  { name: "expose_port", description: "Forward a sandbox port and get a public URL" },
5639
5739
  { name: "list_exposed_ports", description: "List all forwarded ports for a sandbox" },
5640
5740
  { name: "close_port", description: "Stop forwarding a sandbox port" },
5641
- { name: "get_network_log", description: "Get outbound network connections from a sandbox" }
5741
+ { name: "get_network_log", description: "Get outbound network connections from a sandbox" },
5742
+ { name: "watch_file", description: "Get new content from a file since a previous read (tail -f equivalent)" },
5743
+ { name: "list_images", description: "List available pre-warmed sandbox image aliases" }
5642
5744
  ];
5643
5745
  var server = new McpServer({
5644
5746
  name: "sandboxes",
@@ -5654,7 +5756,9 @@ server.tool("create_sandbox", "Create a new sandbox", {
5654
5756
  on_timeout: exports_external.enum(["pause", "terminate"]).optional().describe("What to do on timeout: pause (saves state) or terminate"),
5655
5757
  auto_resume: exports_external.boolean().optional().describe("Auto-resume paused sandbox on next connect"),
5656
5758
  snapshot_id: exports_external.string().optional().describe("Snapshot ID to restore from"),
5657
- network: exports_external.enum(["full", "restricted", "none"]).optional().describe("Network access policy for the sandbox")
5759
+ network: exports_external.enum(["full", "restricted", "none"]).optional().describe("Network access policy for the sandbox"),
5760
+ budget_limit_usd: exports_external.number().optional().describe("Auto-terminate sandbox if compute cost exceeds this USD amount"),
5761
+ on_budget_exceeded: exports_external.enum(["terminate", "pause", "notify"]).optional().describe("Action when budget limit is reached (default: terminate)")
5658
5762
  }, async (params) => {
5659
5763
  try {
5660
5764
  const providerName = params.provider ?? getDefaultProvider();
@@ -5664,20 +5768,24 @@ server.tool("create_sandbox", "Create a new sandbox", {
5664
5768
  const tmpl = getTemplate(params.template_id);
5665
5769
  templateData = { image: tmpl.image ?? undefined, env_vars: tmpl.env_vars, setup_script: tmpl.setup_script };
5666
5770
  }
5667
- const image = params.image ?? templateData.image;
5771
+ const rawImage = params.image ?? templateData.image;
5772
+ const resolvedImage = rawImage ? resolveImage(rawImage) : rawImage;
5773
+ const builtinSetupScript = rawImage ? getBuiltinImageSetupScript(rawImage) : undefined;
5668
5774
  const envVars = { ...templateData.env_vars, ...params.env_vars };
5669
5775
  const onTimeout = params.on_timeout ?? "terminate";
5670
5776
  const autoResume = params.auto_resume ?? false;
5671
5777
  const sandbox = createSandbox({
5672
5778
  provider: providerName,
5673
- image,
5779
+ image: resolvedImage,
5674
5780
  timeout,
5675
5781
  name: params.name,
5676
5782
  env_vars: envVars,
5677
5783
  on_timeout: onTimeout,
5678
5784
  auto_resume: autoResume,
5679
5785
  template_id: params.template_id,
5680
- config: { network: params.network ?? "full" }
5786
+ config: { network: params.network ?? "full" },
5787
+ budget_limit_usd: params.budget_limit_usd,
5788
+ on_budget_exceeded: params.on_budget_exceeded
5681
5789
  });
5682
5790
  const provider = await getProvider(providerName);
5683
5791
  if (params.snapshot_id) {
@@ -5691,7 +5799,7 @@ server.tool("create_sandbox", "Create a new sandbox", {
5691
5799
  return ok(updated2);
5692
5800
  }
5693
5801
  const result = await provider.create({
5694
- image,
5802
+ image: resolvedImage,
5695
5803
  timeout,
5696
5804
  envVars,
5697
5805
  onTimeout,
@@ -5699,7 +5807,8 @@ server.tool("create_sandbox", "Create a new sandbox", {
5699
5807
  });
5700
5808
  const updated = updateSandbox(sandbox.id, {
5701
5809
  provider_sandbox_id: result.id,
5702
- status: "running"
5810
+ status: "running",
5811
+ started_at: new Date().toISOString()
5703
5812
  });
5704
5813
  emitLifecycleEvent(sandbox.id, "sandbox created");
5705
5814
  if (templateData.setup_script && result.id) {
@@ -5707,6 +5816,11 @@ server.tool("create_sandbox", "Create a new sandbox", {
5707
5816
  await provider.exec(result.id, templateData.setup_script);
5708
5817
  } catch {}
5709
5818
  }
5819
+ if (builtinSetupScript && result.id) {
5820
+ try {
5821
+ await provider.exec(result.id, builtinSetupScript);
5822
+ } catch {}
5823
+ }
5710
5824
  return ok(updated);
5711
5825
  } catch (e) {
5712
5826
  return err(e);
@@ -5716,7 +5830,9 @@ server.tool("get_sandbox", "Get sandbox details by ID", {
5716
5830
  id: exports_external.string().describe("Sandbox ID or partial ID")
5717
5831
  }, async (params) => {
5718
5832
  try {
5719
- return ok(getSandbox(params.id));
5833
+ const sandbox = getSandbox(params.id);
5834
+ const cost = estimateCost(sandbox.provider, sandbox.started_at);
5835
+ return ok({ ...sandbox, ...cost });
5720
5836
  } catch (e) {
5721
5837
  return err(e);
5722
5838
  }
@@ -5726,10 +5842,11 @@ server.tool("list_sandboxes", "List sandboxes with filters", {
5726
5842
  provider: exports_external.string().optional().describe("Filter by provider")
5727
5843
  }, async (params) => {
5728
5844
  try {
5729
- return ok(listSandboxes({
5845
+ const sandboxes = listSandboxes({
5730
5846
  status: params.status,
5731
5847
  provider: params.provider
5732
- }));
5848
+ });
5849
+ return ok(sandboxes.map((s) => ({ ...s, ...estimateCost(s.provider, s.started_at) })));
5733
5850
  } catch (e) {
5734
5851
  return err(e);
5735
5852
  }
@@ -5786,7 +5903,9 @@ server.tool("exec_command", "Execute a command in a sandbox", {
5786
5903
  sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
5787
5904
  command: exports_external.string().describe("Command to execute"),
5788
5905
  background: exports_external.boolean().optional().describe("Run in background"),
5789
- env_vars: exports_external.record(exports_external.string()).optional().describe("Per-call environment variables (merged with sandbox env_vars, not persisted)")
5906
+ env_vars: exports_external.record(exports_external.string()).optional().describe("Per-call environment variables (merged with sandbox env_vars, not persisted)"),
5907
+ stdin: exports_external.string().optional().describe("String to pipe as stdin to the command"),
5908
+ tty: exports_external.boolean().optional().describe("Allocate a TTY for the session (best-effort)")
5790
5909
  }, async (params) => {
5791
5910
  try {
5792
5911
  const sandbox = getSandbox(params.sandbox_id);
@@ -5804,7 +5923,9 @@ server.tool("exec_command", "Execute a command in a sandbox", {
5804
5923
  provider.exec(sandbox.provider_sandbox_id, params.command, {
5805
5924
  onStdout: collector.onStdout,
5806
5925
  onStderr: collector.onStderr,
5807
- env
5926
+ env,
5927
+ stdin: params.stdin,
5928
+ tty: params.tty
5808
5929
  }).then((res) => {
5809
5930
  const r = res;
5810
5931
  endSession(session.id, r.exit_code ?? 0);
@@ -5816,7 +5937,9 @@ server.tool("exec_command", "Execute a command in a sandbox", {
5816
5937
  const result = await provider.exec(sandbox.provider_sandbox_id, params.command, {
5817
5938
  onStdout: collector.onStdout,
5818
5939
  onStderr: collector.onStderr,
5819
- env
5940
+ env,
5941
+ stdin: params.stdin,
5942
+ tty: params.tty
5820
5943
  });
5821
5944
  const execResult = result;
5822
5945
  endSession(session.id, execResult.exit_code);
@@ -5832,15 +5955,22 @@ server.tool("exec_command", "Execute a command in a sandbox", {
5832
5955
  });
5833
5956
  server.tool("read_file", "Read a file from a sandbox", {
5834
5957
  sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
5835
- path: exports_external.string().describe("File path")
5958
+ path: exports_external.string().describe("File path"),
5959
+ offset: exports_external.number().optional().describe("Line or byte offset to start reading from"),
5960
+ limit: exports_external.number().optional().describe("Max lines or bytes to return"),
5961
+ encoding: exports_external.enum(["utf8", "base64", "hex"]).optional().describe("Output encoding (default: utf8)")
5836
5962
  }, async (params) => {
5837
5963
  try {
5838
5964
  const sandbox = getSandbox(params.sandbox_id);
5839
5965
  if (!sandbox.provider_sandbox_id)
5840
5966
  throw new Error("Sandbox has no provider ID");
5841
5967
  const provider = await getProvider(sandbox.provider);
5842
- const content = await provider.readFile(sandbox.provider_sandbox_id, params.path);
5843
- return ok({ path: params.path, content });
5968
+ const content = await provider.readFile(sandbox.provider_sandbox_id, params.path, {
5969
+ encoding: params.encoding,
5970
+ offset: params.offset,
5971
+ limit: params.limit
5972
+ });
5973
+ return ok({ path: params.path, content, encoding: params.encoding ?? "utf8" });
5844
5974
  } catch (e) {
5845
5975
  return err(e);
5846
5976
  }
@@ -5863,14 +5993,19 @@ server.tool("write_file", "Write a file to a sandbox", {
5863
5993
  });
5864
5994
  server.tool("list_files", "List files in a sandbox directory", {
5865
5995
  sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
5866
- path: exports_external.string().describe("Directory path")
5996
+ path: exports_external.string().describe("Directory path"),
5997
+ recursive: exports_external.boolean().optional().describe("List files recursively"),
5998
+ glob: exports_external.string().optional().describe("Glob pattern to filter files")
5867
5999
  }, async (params) => {
5868
6000
  try {
5869
6001
  const sandbox = getSandbox(params.sandbox_id);
5870
6002
  if (!sandbox.provider_sandbox_id)
5871
6003
  throw new Error("Sandbox has no provider ID");
5872
6004
  const provider = await getProvider(sandbox.provider);
5873
- const files = await provider.listFiles(sandbox.provider_sandbox_id, params.path);
6005
+ const files = await provider.listFiles(sandbox.provider_sandbox_id, params.path, {
6006
+ recursive: params.recursive,
6007
+ glob: params.glob
6008
+ });
5874
6009
  return ok(files);
5875
6010
  } catch (e) {
5876
6011
  return err(e);
@@ -6205,5 +6340,43 @@ server.tool("get_network_log", "Get outbound network connections from a sandbox"
6205
6340
  return err(e);
6206
6341
  }
6207
6342
  });
6343
+ server.tool("watch_file", "Get new content from a file since a previous read (tail -f equivalent)", {
6344
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
6345
+ path: exports_external.string().describe("File path to watch"),
6346
+ offset: exports_external.number().optional().describe("Line offset to read from (use next_offset from previous call)"),
6347
+ limit: exports_external.number().optional().describe("Max lines to return (default: 100)")
6348
+ }, async (params) => {
6349
+ try {
6350
+ const sandbox = getSandbox(params.sandbox_id);
6351
+ if (!sandbox.provider_sandbox_id)
6352
+ throw new Error("Sandbox has no provider ID");
6353
+ const provider = await getProvider(sandbox.provider);
6354
+ const content = await provider.readFile(sandbox.provider_sandbox_id, params.path, {
6355
+ offset: params.offset,
6356
+ limit: params.limit ?? 100
6357
+ });
6358
+ const lines = content.split(`
6359
+ `);
6360
+ return ok({
6361
+ path: params.path,
6362
+ content,
6363
+ lines_read: lines.length,
6364
+ next_offset: (params.offset ?? 0) + lines.length
6365
+ });
6366
+ } catch (e) {
6367
+ return err(e);
6368
+ }
6369
+ });
6370
+ server.tool("list_images", "List available pre-warmed sandbox image aliases", {}, async () => {
6371
+ try {
6372
+ return ok(Object.entries(BUILTIN_IMAGES).map(([name, info]) => ({
6373
+ name,
6374
+ description: info.description,
6375
+ has_setup_script: !!info.setup_script
6376
+ })));
6377
+ } catch (e) {
6378
+ return err(e);
6379
+ }
6380
+ });
6208
6381
  var transport = new StdioServerTransport;
6209
6382
  await server.connect(transport);
@@ -7,9 +7,16 @@ export declare class E2BProvider implements SandboxProvider {
7
7
  create(opts?: CreateSandboxOpts): Promise<ProviderSandbox>;
8
8
  private getInstance;
9
9
  exec(sandboxId: string, command: string, opts?: ExecOptions): Promise<ExecResult | ExecHandle>;
10
- readFile(sandboxId: string, path: string): Promise<string>;
10
+ readFile(sandboxId: string, path: string, opts?: {
11
+ encoding?: 'utf8' | 'base64' | 'hex';
12
+ offset?: number;
13
+ limit?: number;
14
+ }): Promise<string>;
11
15
  writeFile(sandboxId: string, path: string, content: string): Promise<void>;
12
- listFiles(sandboxId: string, path: string): Promise<FileInfo[]>;
16
+ listFiles(sandboxId: string, path: string, opts?: {
17
+ recursive?: boolean;
18
+ glob?: string;
19
+ }): Promise<FileInfo[]>;
13
20
  stop(sandboxId: string): Promise<void>;
14
21
  delete(sandboxId: string): Promise<void>;
15
22
  pause(sandboxId: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"e2b.d.ts","sourceRoot":"","sources":["../../src/providers/e2b.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,CAAC,IAAI,SAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;YAwBlD,WAAW;IAkBnB,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IA0D7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAY1D,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAYV,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAkB/D,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUlF,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWvE"}
1
+ {"version":3,"file":"e2b.d.ts","sourceRoot":"","sources":["../../src/providers/e2b.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,CAAC,IAAI,SAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;YAwBlD,WAAW;IAkBnB,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IA2D7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgC5I,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAYV,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA+B9G,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUlF,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWvE"}
@@ -13,6 +13,8 @@ export interface ExecOptions {
13
13
  timeout?: number;
14
14
  env?: Record<string, string>;
15
15
  cwd?: string;
16
+ stdin?: string;
17
+ tty?: boolean;
16
18
  }
17
19
  export interface ProviderSandbox {
18
20
  id: string;
@@ -22,9 +24,16 @@ export interface SandboxProvider {
22
24
  readonly name: string;
23
25
  create(opts?: CreateSandboxOpts): Promise<ProviderSandbox>;
24
26
  exec(sandboxId: string, command: string, opts?: ExecOptions): Promise<ExecResult | ExecHandle>;
25
- readFile(sandboxId: string, path: string): Promise<string>;
27
+ readFile(sandboxId: string, path: string, opts?: {
28
+ encoding?: 'utf8' | 'base64' | 'hex';
29
+ offset?: number;
30
+ limit?: number;
31
+ }): Promise<string>;
26
32
  writeFile(sandboxId: string, path: string, content: string): Promise<void>;
27
- listFiles(sandboxId: string, path: string): Promise<FileInfo[]>;
33
+ listFiles(sandboxId: string, path: string, opts?: {
34
+ recursive?: boolean;
35
+ glob?: string;
36
+ }): Promise<FileInfo[]>;
28
37
  stop(sandboxId: string): Promise<void>;
29
38
  delete(sandboxId: string): Promise<void>;
30
39
  keepAlive(sandboxId: string, durationMs?: number): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAE3D,IAAI,CACF,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC;IAEpC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEhE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnF"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAE3D,IAAI,CACF,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC;IAEpC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7I,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE/G,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnF"}
@@ -147,10 +147,11 @@ class E2BProvider {
147
147
  onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
148
148
  envs: opts?.env,
149
149
  cwd: opts?.cwd,
150
- timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
150
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
151
+ ...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
151
152
  });
152
153
  return {
153
- exit_code: result.exitCode,
154
+ exit_code: result.exitCode ?? 0,
154
155
  stdout: result.stdout,
155
156
  stderr: result.stderr
156
157
  };
@@ -158,10 +159,28 @@ class E2BProvider {
158
159
  throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
159
160
  }
160
161
  }
161
- async readFile(sandboxId, path) {
162
+ async readFile(sandboxId, path, opts) {
162
163
  const sandbox = await this.getInstance(sandboxId);
163
164
  try {
164
- return await sandbox.files.read(path, { format: "text" });
165
+ if (opts?.encoding === "base64") {
166
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
167
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
168
+ return Buffer.from(sliced).toString("base64");
169
+ } else if (opts?.encoding === "hex") {
170
+ const bytes = await sandbox.files.read(path, { format: "bytes" });
171
+ const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
172
+ return Buffer.from(sliced).toString("hex");
173
+ } else {
174
+ const content = await sandbox.files.read(path, { format: "text" });
175
+ if (opts?.offset !== undefined || opts?.limit !== undefined) {
176
+ const lines = content.split(`
177
+ `);
178
+ const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
179
+ return sliced.join(`
180
+ `);
181
+ }
182
+ return content;
183
+ }
165
184
  } catch (err) {
166
185
  throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
167
186
  }
@@ -174,9 +193,21 @@ class E2BProvider {
174
193
  throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
175
194
  }
176
195
  }
177
- async listFiles(sandboxId, path) {
196
+ async listFiles(sandboxId, path, opts) {
178
197
  const sandbox = await this.getInstance(sandboxId);
179
198
  try {
199
+ if (opts?.recursive || opts?.glob) {
200
+ const pattern = opts.glob ? opts.glob : "*";
201
+ const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
202
+ const result = await sandbox.commands.run(cmd);
203
+ return result.stdout.trim().split(`
204
+ `).filter(Boolean).map((p) => ({
205
+ path: p.trim(),
206
+ name: p.trim().split("/").pop() || p.trim(),
207
+ is_dir: false,
208
+ size: 0
209
+ }));
210
+ }
180
211
  const entries = await sandbox.files.list(path);
181
212
  return entries.map((e) => ({
182
213
  path: e.path,
@@ -848,6 +879,12 @@ CREATE TABLE IF NOT EXISTS snapshots (
848
879
  );
849
880
  CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
850
881
  INSERT OR IGNORE INTO _migrations (id) VALUES (4);
882
+ `,
883
+ `
884
+ ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
885
+ ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
886
+ ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
887
+ INSERT OR IGNORE INTO _migrations (id) VALUES (5);
851
888
  `
852
889
  ];
853
890
  var db = null;
@@ -908,6 +945,9 @@ function rowToSandbox(row) {
908
945
  project_id: row.project_id,
909
946
  on_timeout: row.on_timeout ?? "terminate",
910
947
  auto_resume: row.auto_resume === 1,
948
+ budget_limit_usd: row.budget_limit_usd ?? null,
949
+ on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
950
+ started_at: row.started_at ?? null,
911
951
  created_at: row.created_at,
912
952
  updated_at: row.updated_at
913
953
  };
@@ -925,8 +965,10 @@ function createSandbox(input) {
925
965
  const project_id = input.project_id ?? null;
926
966
  const on_timeout = input.on_timeout ?? "terminate";
927
967
  const auto_resume = input.auto_resume ? 1 : 0;
928
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
929
- VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, timestamp, timestamp);
968
+ const budget_limit_usd = input.budget_limit_usd ?? null;
969
+ const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
970
+ db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
971
+ VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
930
972
  return getSandbox(id);
931
973
  }
932
974
  function getSandbox(id) {
@@ -998,6 +1040,10 @@ function updateSandbox(id, updates) {
998
1040
  setClauses.push("keep_alive_until = ?");
999
1041
  params.push(updates.keep_alive_until);
1000
1042
  }
1043
+ if (updates.started_at !== undefined) {
1044
+ setClauses.push("started_at = ?");
1045
+ params.push(updates.started_at);
1046
+ }
1001
1047
  if (setClauses.length === 0) {
1002
1048
  return getSandbox(resolvedId);
1003
1049
  }
@@ -22,6 +22,9 @@ export interface Sandbox {
22
22
  project_id: string | null;
23
23
  on_timeout: 'pause' | 'terminate';
24
24
  auto_resume: boolean;
25
+ budget_limit_usd: number | null;
26
+ on_budget_exceeded: 'terminate' | 'pause' | 'notify';
27
+ started_at: string | null;
25
28
  created_at: string;
26
29
  updated_at: string;
27
30
  }
@@ -39,6 +42,9 @@ export interface SandboxRow {
39
42
  project_id: string | null;
40
43
  on_timeout: string;
41
44
  auto_resume: number;
45
+ budget_limit_usd: number | null;
46
+ on_budget_exceeded: string;
47
+ started_at: string | null;
42
48
  created_at: string;
43
49
  updated_at: string;
44
50
  }
@@ -54,6 +60,8 @@ export interface CreateSandboxInput {
54
60
  auto_resume?: boolean;
55
61
  template_id?: string;
56
62
  network?: 'full' | 'restricted' | 'none';
63
+ budget_limit_usd?: number;
64
+ on_budget_exceeded?: 'terminate' | 'pause' | 'notify';
57
65
  }
58
66
  export interface SandboxSession {
59
67
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/sandboxes",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "author": "Andrei Hasna <andrei@hasna.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,7 +10,7 @@
10
10
  "dependencies": {
11
11
  "@daytonaio/sdk": "^0.18.0",
12
12
  "@e2b/code-interpreter": "^1.5.0",
13
- "@hasna/sandboxes": "^0.1.7",
13
+ "@hasna/sandboxes": "^0.1.8",
14
14
  "@modelcontextprotocol/sdk": "^1.12.1",
15
15
  "chalk": "^5.4.1",
16
16
  "commander": "^13.1.0",