@hasna/sandboxes 0.1.7 → 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
@@ -2263,6 +2263,24 @@ ALTER TABLE sandbox_sessions_new RENAME TO sandbox_sessions;
2263
2263
  CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
2264
2264
  CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
2265
2265
  INSERT OR IGNORE INTO _migrations (id) VALUES (3);
2266
+ `,
2267
+ `
2268
+ CREATE TABLE IF NOT EXISTS snapshots (
2269
+ id TEXT PRIMARY KEY,
2270
+ sandbox_id TEXT NOT NULL,
2271
+ provider_sandbox_id TEXT NOT NULL,
2272
+ provider TEXT NOT NULL,
2273
+ name TEXT,
2274
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
2275
+ );
2276
+ CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
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);
2266
2284
  `
2267
2285
  ];
2268
2286
  });
@@ -2314,6 +2332,9 @@ function rowToSandbox(row) {
2314
2332
  project_id: row.project_id,
2315
2333
  on_timeout: row.on_timeout ?? "terminate",
2316
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,
2317
2338
  created_at: row.created_at,
2318
2339
  updated_at: row.updated_at
2319
2340
  };
@@ -2331,8 +2352,10 @@ function createSandbox(input) {
2331
2352
  const project_id = input.project_id ?? null;
2332
2353
  const on_timeout = input.on_timeout ?? "terminate";
2333
2354
  const auto_resume = input.auto_resume ? 1 : 0;
2334
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
2335
- 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);
2336
2359
  return getSandbox(id);
2337
2360
  }
2338
2361
  function getSandbox(id) {
@@ -2404,6 +2427,10 @@ function updateSandbox(id, updates) {
2404
2427
  setClauses.push("keep_alive_until = ?");
2405
2428
  params.push(updates.keep_alive_until);
2406
2429
  }
2430
+ if (updates.started_at !== undefined) {
2431
+ setClauses.push("started_at = ?");
2432
+ params.push(updates.started_at);
2433
+ }
2407
2434
  if (setClauses.length === 0) {
2408
2435
  return getSandbox(resolvedId);
2409
2436
  }
@@ -2682,10 +2709,11 @@ class E2BProvider {
2682
2709
  onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
2683
2710
  envs: opts?.env,
2684
2711
  cwd: opts?.cwd,
2685
- timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
2712
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
2713
+ ...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
2686
2714
  });
2687
2715
  return {
2688
- exit_code: result.exitCode,
2716
+ exit_code: result.exitCode ?? 0,
2689
2717
  stdout: result.stdout,
2690
2718
  stderr: result.stderr
2691
2719
  };
@@ -2693,10 +2721,28 @@ class E2BProvider {
2693
2721
  throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
2694
2722
  }
2695
2723
  }
2696
- async readFile(sandboxId, path) {
2724
+ async readFile(sandboxId, path, opts) {
2697
2725
  const sandbox = await this.getInstance(sandboxId);
2698
2726
  try {
2699
- 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
+ }
2700
2746
  } catch (err) {
2701
2747
  throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
2702
2748
  }
@@ -2709,9 +2755,21 @@ class E2BProvider {
2709
2755
  throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
2710
2756
  }
2711
2757
  }
2712
- async listFiles(sandboxId, path) {
2758
+ async listFiles(sandboxId, path, opts) {
2713
2759
  const sandbox = await this.getInstance(sandboxId);
2714
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
+ }
2715
2773
  const entries = await sandbox.files.list(path);
2716
2774
  return entries.map((e) => ({
2717
2775
  path: e.path,
@@ -2752,6 +2810,15 @@ class E2BProvider {
2752
2810
  throw new ProviderError("e2b", `Failed to resume sandbox: ${err.message}`);
2753
2811
  }
2754
2812
  }
2813
+ async getPublicUrl(sandboxId, port, _protocol) {
2814
+ const sandbox = await this.getInstance(sandboxId);
2815
+ try {
2816
+ const host = sandbox.getHost(port);
2817
+ return `https://${host}`;
2818
+ } catch (err) {
2819
+ throw new ProviderError("e2b", `Failed to get public URL for port ${port}: ${err.message}`);
2820
+ }
2821
+ }
2755
2822
  async keepAlive(sandboxId, durationMs) {
2756
2823
  const sandbox = await this.getInstance(sandboxId);
2757
2824
  try {
@@ -2912,6 +2979,9 @@ class DaytonaProvider {
2912
2979
  throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
2913
2980
  }
2914
2981
  }
2982
+ async getPublicUrl(_sandboxId, _port, _protocol) {
2983
+ throw new ProviderError("daytona", "Port forwarding not supported by Daytona provider");
2984
+ }
2915
2985
  async pause(_sandboxId) {
2916
2986
  throw new ProviderError("daytona", "Pause/resume not supported by Daytona provider");
2917
2987
  }
@@ -3140,6 +3210,9 @@ class ModalProvider {
3140
3210
  async delete(sandboxId) {
3141
3211
  await this.stop(sandboxId);
3142
3212
  }
3213
+ async getPublicUrl(_sandboxId, _port, _protocol) {
3214
+ throw new ProviderError("modal", "Port forwarding not supported by Modal provider");
3215
+ }
3143
3216
  async pause(_sandboxId) {
3144
3217
  throw new ProviderError("modal", "Pause/resume not supported by Modal provider");
3145
3218
  }
@@ -3409,13 +3482,23 @@ __export(exports_agent_runner, {
3409
3482
  stopAgent: () => stopAgent,
3410
3483
  runAgent: () => runAgent
3411
3484
  });
3485
+ async function fireWebhook(url, payload) {
3486
+ try {
3487
+ await fetch(url, {
3488
+ method: "POST",
3489
+ headers: { "Content-Type": "application/json" },
3490
+ body: JSON.stringify(payload)
3491
+ });
3492
+ } catch {}
3493
+ }
3412
3494
  async function runAgent(sandboxId, opts) {
3413
3495
  const sandbox = getSandbox(sandboxId);
3414
3496
  if (!sandbox.provider_sandbox_id) {
3415
3497
  throw new Error("Sandbox has no provider instance");
3416
3498
  }
3417
3499
  const provider = await getProvider(sandbox.provider);
3418
- const env = Object.keys(sandbox.env_vars ?? {}).length > 0 ? sandbox.env_vars : undefined;
3500
+ const mergedEnv = { ...sandbox.env_vars, ...opts.callEnvVars };
3501
+ const env = Object.keys(mergedEnv).length > 0 ? mergedEnv : undefined;
3419
3502
  let cmd;
3420
3503
  const driver = opts.agentType !== "custom" ? getAgentDriver(opts.agentType) : undefined;
3421
3504
  if (opts.command) {
@@ -3434,6 +3517,18 @@ async function runAgent(sandboxId, opts) {
3434
3517
  command: cmd
3435
3518
  });
3436
3519
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} started: ${opts.prompt.slice(0, 100)}`);
3520
+ const startedAt = Date.now();
3521
+ const webhookEvents = opts.webhookEvents ?? ["start", "complete", "error"];
3522
+ if (opts.webhookUrl && webhookEvents.includes("start")) {
3523
+ fireWebhook(opts.webhookUrl, {
3524
+ event: "start",
3525
+ session_id: session.id,
3526
+ sandbox_id: sandbox.id,
3527
+ agent_type: opts.agentType,
3528
+ status: "running",
3529
+ timestamp: new Date().toISOString()
3530
+ });
3531
+ }
3437
3532
  const collector = createStreamCollector(sandbox.id, session.id);
3438
3533
  provider.exec(sandbox.provider_sandbox_id, cmd, {
3439
3534
  onStdout: (data) => {
@@ -3450,9 +3545,32 @@ async function runAgent(sandboxId, opts) {
3450
3545
  const status = exitResult.exit_code === 0 ? "completed" : "failed";
3451
3546
  endSession(session.id, exitResult.exit_code ?? 0, status);
3452
3547
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} finished with exit code ${exitResult.exit_code}`);
3548
+ if (opts.webhookUrl && webhookEvents.includes("complete")) {
3549
+ fireWebhook(opts.webhookUrl, {
3550
+ event: "complete",
3551
+ session_id: session.id,
3552
+ sandbox_id: sandbox.id,
3553
+ agent_type: opts.agentType,
3554
+ status,
3555
+ exit_code: exitResult.exit_code,
3556
+ duration_ms: Date.now() - startedAt,
3557
+ timestamp: new Date().toISOString()
3558
+ });
3559
+ }
3453
3560
  }).catch((err) => {
3454
3561
  endSession(session.id, 1, "failed");
3455
3562
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} failed: ${err.message}`);
3563
+ if (opts.webhookUrl && webhookEvents.includes("error")) {
3564
+ fireWebhook(opts.webhookUrl, {
3565
+ event: "error",
3566
+ session_id: session.id,
3567
+ sandbox_id: sandbox.id,
3568
+ agent_type: opts.agentType,
3569
+ status: "failed",
3570
+ duration_ms: Date.now() - startedAt,
3571
+ timestamp: new Date().toISOString()
3572
+ });
3573
+ }
3456
3574
  });
3457
3575
  return session;
3458
3576
  }
@@ -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;AA6LtC,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"}
@@ -0,0 +1,29 @@
1
+ export interface Snapshot {
2
+ id: string;
3
+ sandbox_id: string;
4
+ provider_sandbox_id: string;
5
+ provider: string;
6
+ name: string | null;
7
+ created_at: string;
8
+ }
9
+ export interface SnapshotRow {
10
+ id: string;
11
+ sandbox_id: string;
12
+ provider_sandbox_id: string;
13
+ provider: string;
14
+ name: string | null;
15
+ created_at: string;
16
+ }
17
+ export declare class SnapshotNotFoundError extends Error {
18
+ constructor(id: string);
19
+ }
20
+ export declare function createSnapshot(input: {
21
+ sandbox_id: string;
22
+ provider_sandbox_id: string;
23
+ provider: string;
24
+ name?: string;
25
+ }): Snapshot;
26
+ export declare function getSnapshot(id: string): Snapshot;
27
+ export declare function listSnapshots(sandboxId?: string): Snapshot[];
28
+ export declare function deleteSnapshot(id: string): void;
29
+ //# sourceMappingURL=snapshots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshots.d.ts","sourceRoot":"","sources":["../../src/db/snapshots.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,QAAQ,CASX;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAOhD;AAED,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAM5D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK/C"}
package/dist/index.d.ts CHANGED
@@ -7,7 +7,11 @@ export { registerAgent, getAgent, getAgentByName, listAgents, deleteAgent } from
7
7
  export { createProject, getProject, getProjectByPath, listProjects, ensureProject, deleteProject } from "./db/projects.js";
8
8
  export { createWebhook, getWebhook, listWebhooks, deleteWebhook } from "./db/webhooks.js";
9
9
  export { createTemplate, getTemplate, getTemplateByName, listTemplates, deleteTemplate } from "./db/templates.js";
10
+ export { createSnapshot, getSnapshot, listSnapshots, deleteSnapshot } from "./db/snapshots.js";
11
+ export type { Snapshot, SnapshotRow } from "./db/snapshots.js";
12
+ export { SnapshotNotFoundError } from "./db/snapshots.js";
10
13
  export { loadConfig, saveConfig, getDefaultProvider, getDefaultTimeout, getDefaultImage, getProviderApiKey, setConfigValue, getConfigValue } from "./lib/config.js";
14
+ export { BUILTIN_IMAGES, resolveImage, getBuiltinImageSetupScript } from "./lib/images.js";
11
15
  export { getProvider } from "./providers/index.js";
12
16
  export type { SandboxProvider, ProviderSandbox, CreateSandboxOpts, ExecOptions } from "./providers/types.js";
13
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;AAGlH,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,
@@ -244,6 +275,15 @@ class E2BProvider {
244
275
  throw new ProviderError("e2b", `Failed to resume sandbox: ${err.message}`);
245
276
  }
246
277
  }
278
+ async getPublicUrl(sandboxId, port, _protocol) {
279
+ const sandbox = await this.getInstance(sandboxId);
280
+ try {
281
+ const host = sandbox.getHost(port);
282
+ return `https://${host}`;
283
+ } catch (err) {
284
+ throw new ProviderError("e2b", `Failed to get public URL for port ${port}: ${err.message}`);
285
+ }
286
+ }
247
287
  async keepAlive(sandboxId, durationMs) {
248
288
  const sandbox = await this.getInstance(sandboxId);
249
289
  try {
@@ -404,6 +444,9 @@ class DaytonaProvider {
404
444
  throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
405
445
  }
406
446
  }
447
+ async getPublicUrl(_sandboxId, _port, _protocol) {
448
+ throw new ProviderError("daytona", "Port forwarding not supported by Daytona provider");
449
+ }
407
450
  async pause(_sandboxId) {
408
451
  throw new ProviderError("daytona", "Pause/resume not supported by Daytona provider");
409
452
  }
@@ -632,6 +675,9 @@ class ModalProvider {
632
675
  async delete(sandboxId) {
633
676
  await this.stop(sandboxId);
634
677
  }
678
+ async getPublicUrl(_sandboxId, _port, _protocol) {
679
+ throw new ProviderError("modal", "Port forwarding not supported by Modal provider");
680
+ }
635
681
  async pause(_sandboxId) {
636
682
  throw new ProviderError("modal", "Pause/resume not supported by Modal provider");
637
683
  }
@@ -848,6 +894,24 @@ ALTER TABLE sandbox_sessions_new RENAME TO sandbox_sessions;
848
894
  CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
849
895
  CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
850
896
  INSERT OR IGNORE INTO _migrations (id) VALUES (3);
897
+ `,
898
+ `
899
+ CREATE TABLE IF NOT EXISTS snapshots (
900
+ id TEXT PRIMARY KEY,
901
+ sandbox_id TEXT NOT NULL,
902
+ provider_sandbox_id TEXT NOT NULL,
903
+ provider TEXT NOT NULL,
904
+ name TEXT,
905
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
906
+ );
907
+ CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
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);
851
915
  `
852
916
  ];
853
917
  var db = null;
@@ -922,6 +986,9 @@ function rowToSandbox(row) {
922
986
  project_id: row.project_id,
923
987
  on_timeout: row.on_timeout ?? "terminate",
924
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,
925
992
  created_at: row.created_at,
926
993
  updated_at: row.updated_at
927
994
  };
@@ -939,8 +1006,10 @@ function createSandbox(input) {
939
1006
  const project_id = input.project_id ?? null;
940
1007
  const on_timeout = input.on_timeout ?? "terminate";
941
1008
  const auto_resume = input.auto_resume ? 1 : 0;
942
- db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, created_at, updated_at)
943
- 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);
944
1013
  return getSandbox(id);
945
1014
  }
946
1015
  function getSandbox(id) {
@@ -1012,6 +1081,10 @@ function updateSandbox(id, updates) {
1012
1081
  setClauses.push("keep_alive_until = ?");
1013
1082
  params.push(updates.keep_alive_until);
1014
1083
  }
1084
+ if (updates.started_at !== undefined) {
1085
+ setClauses.push("started_at = ?");
1086
+ params.push(updates.started_at);
1087
+ }
1015
1088
  if (setClauses.length === 0) {
1016
1089
  return getSandbox(resolvedId);
1017
1090
  }
@@ -1343,6 +1416,45 @@ function deleteTemplate(id) {
1343
1416
  throw new TemplateNotFoundError(id);
1344
1417
  db2.query("DELETE FROM templates WHERE id = ?").run(resolvedId);
1345
1418
  }
1419
+ // src/db/snapshots.ts
1420
+ class SnapshotNotFoundError extends Error {
1421
+ constructor(id) {
1422
+ super(`Snapshot not found: ${id}`);
1423
+ this.name = "SnapshotNotFoundError";
1424
+ }
1425
+ }
1426
+ function createSnapshot(input) {
1427
+ const db2 = getDatabase();
1428
+ const id = uuid();
1429
+ const timestamp = now();
1430
+ db2.query(`INSERT INTO snapshots (id, sandbox_id, provider_sandbox_id, provider, name, created_at)
1431
+ VALUES (?, ?, ?, ?, ?, ?)`).run(id, input.sandbox_id, input.provider_sandbox_id, input.provider, input.name ?? null, timestamp);
1432
+ return getSnapshot(id);
1433
+ }
1434
+ function getSnapshot(id) {
1435
+ const db2 = getDatabase();
1436
+ const resolvedId = resolvePartialId("snapshots", id);
1437
+ if (!resolvedId)
1438
+ throw new SnapshotNotFoundError(id);
1439
+ const row = db2.query("SELECT * FROM snapshots WHERE id = ?").get(resolvedId);
1440
+ if (!row)
1441
+ throw new SnapshotNotFoundError(id);
1442
+ return row;
1443
+ }
1444
+ function listSnapshots(sandboxId) {
1445
+ const db2 = getDatabase();
1446
+ if (sandboxId) {
1447
+ return db2.query("SELECT * FROM snapshots WHERE sandbox_id = ? ORDER BY created_at DESC").all(sandboxId);
1448
+ }
1449
+ return db2.query("SELECT * FROM snapshots ORDER BY created_at DESC").all();
1450
+ }
1451
+ function deleteSnapshot(id) {
1452
+ const db2 = getDatabase();
1453
+ const resolvedId = resolvePartialId("snapshots", id);
1454
+ if (!resolvedId)
1455
+ throw new SnapshotNotFoundError(id);
1456
+ db2.query("DELETE FROM snapshots WHERE id = ?").run(resolvedId);
1457
+ }
1346
1458
  // src/lib/config.ts
1347
1459
  import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
1348
1460
  import { dirname as dirname2, join as join2 } from "path";
@@ -1438,6 +1550,47 @@ function getConfigValue(key) {
1438
1550
  }
1439
1551
  return;
1440
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
+ }
1441
1594
  // src/providers/index.ts
1442
1595
  init_types();
1443
1596
  var providerCache = new Map;
@@ -1656,12 +1809,14 @@ export {
1656
1809
  setConfigValue,
1657
1810
  saveConfig,
1658
1811
  resolvePartialId,
1812
+ resolveImage,
1659
1813
  resetDatabase,
1660
1814
  registerAgent,
1661
1815
  now,
1662
1816
  loadConfig,
1663
1817
  listWebhooks,
1664
1818
  listTemplates,
1819
+ listSnapshots,
1665
1820
  listSessions,
1666
1821
  listSandboxes,
1667
1822
  listProjects,
@@ -1671,6 +1826,7 @@ export {
1671
1826
  getWebhook,
1672
1827
  getTemplateByName,
1673
1828
  getTemplate,
1829
+ getSnapshot,
1674
1830
  getSession,
1675
1831
  getSandbox,
1676
1832
  getProviderApiKey,
@@ -1682,6 +1838,7 @@ export {
1682
1838
  getDefaultImage,
1683
1839
  getDatabase,
1684
1840
  getConfigValue,
1841
+ getBuiltinImageSetupScript,
1685
1842
  getAgentDriver,
1686
1843
  getAgentByName,
1687
1844
  getAgent,
@@ -1690,12 +1847,14 @@ export {
1690
1847
  emitLifecycleEvent,
1691
1848
  deleteWebhook,
1692
1849
  deleteTemplate,
1850
+ deleteSnapshot,
1693
1851
  deleteSandbox,
1694
1852
  deleteProject,
1695
1853
  deleteAgent,
1696
1854
  createWebhook,
1697
1855
  createTemplate,
1698
1856
  createStreamCollector,
1857
+ createSnapshot,
1699
1858
  createSession,
1700
1859
  createSandbox,
1701
1860
  createProject,
@@ -1704,6 +1863,7 @@ export {
1704
1863
  addEvent,
1705
1864
  WebhookNotFoundError,
1706
1865
  TemplateNotFoundError,
1866
+ SnapshotNotFoundError,
1707
1867
  SessionNotFoundError,
1708
1868
  SandboxNotFoundError,
1709
1869
  SESSION_STATUSES,
@@ -1712,6 +1872,7 @@ export {
1712
1872
  ProviderError,
1713
1873
  ProjectNotFoundError,
1714
1874
  EVENT_TYPES,
1875
+ BUILTIN_IMAGES,
1715
1876
  AgentNotFoundError,
1716
1877
  AGENT_TYPES
1717
1878
  };
@@ -6,6 +6,9 @@ export interface RunAgentOpts {
6
6
  command?: string;
7
7
  onStdout?: (data: string) => void;
8
8
  onStderr?: (data: string) => void;
9
+ callEnvVars?: Record<string, string>;
10
+ webhookUrl?: string;
11
+ webhookEvents?: ('start' | 'complete' | 'error')[];
9
12
  }
10
13
  export declare function runAgent(sandboxId: string, opts: RunAgentOpts): Promise<SandboxSession>;
11
14
  export declare function stopAgent(sandboxId: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CA8DzB;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhE"}
1
+ {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAC;CACpD;AAcD,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CAyGzB;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhE"}
@@ -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"}