@hasna/sandboxes 0.1.8 → 0.1.10

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,
@@ -3318,6 +3364,25 @@ var init_stream = __esm(() => {
3318
3364
  listeners = new Map;
3319
3365
  });
3320
3366
 
3367
+ // src/lib/runtime-state.ts
3368
+ function getErrorMessage(error) {
3369
+ return error instanceof Error ? error.message : String(error);
3370
+ }
3371
+ function finalizeSessionExit(sessionId, exitCode) {
3372
+ endSession(sessionId, exitCode, exitCode === 0 ? "completed" : "failed");
3373
+ }
3374
+ function finalizeSessionFailure(sessionId, _error, exitCode = 1) {
3375
+ endSession(sessionId, exitCode, "failed");
3376
+ }
3377
+ function finalizeSandboxProvisionFailure(sandboxId, error) {
3378
+ updateSandbox(sandboxId, { status: "error" });
3379
+ return getErrorMessage(error);
3380
+ }
3381
+ var init_runtime_state = __esm(() => {
3382
+ init_sessions();
3383
+ init_sandboxes();
3384
+ });
3385
+
3321
3386
  // src/lib/agents/claude.ts
3322
3387
  class ClaudeDriver {
3323
3388
  name = "claude";
@@ -3497,7 +3562,7 @@ async function runAgent(sandboxId, opts) {
3497
3562
  }).then((result) => {
3498
3563
  const exitResult = result;
3499
3564
  const status = exitResult.exit_code === 0 ? "completed" : "failed";
3500
- endSession(session.id, exitResult.exit_code ?? 0, status);
3565
+ finalizeSessionExit(session.id, exitResult.exit_code ?? 0);
3501
3566
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} finished with exit code ${exitResult.exit_code}`);
3502
3567
  if (opts.webhookUrl && webhookEvents.includes("complete")) {
3503
3568
  fireWebhook(opts.webhookUrl, {
@@ -3512,7 +3577,7 @@ async function runAgent(sandboxId, opts) {
3512
3577
  });
3513
3578
  }
3514
3579
  }).catch((err) => {
3515
- endSession(session.id, 1, "failed");
3580
+ finalizeSessionFailure(session.id, err);
3516
3581
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} failed: ${err.message}`);
3517
3582
  if (opts.webhookUrl && webhookEvents.includes("error")) {
3518
3583
  fireWebhook(opts.webhookUrl, {
@@ -3544,6 +3609,7 @@ var init_agent_runner = __esm(() => {
3544
3609
  init_providers();
3545
3610
  init_stream();
3546
3611
  init_agents();
3612
+ init_runtime_state();
3547
3613
  });
3548
3614
 
3549
3615
  // node_modules/commander/esm.mjs
@@ -3623,6 +3689,20 @@ function listAgents() {
3623
3689
  init_providers();
3624
3690
  init_config();
3625
3691
  init_stream();
3692
+ init_runtime_state();
3693
+
3694
+ // src/lib/version.ts
3695
+ import { readFileSync as readFileSync2 } from "fs";
3696
+ var cachedVersion;
3697
+ function getPackageVersion() {
3698
+ if (cachedVersion)
3699
+ return cachedVersion;
3700
+ const packageJson = JSON.parse(readFileSync2(new URL("../../package.json", import.meta.url), "utf8"));
3701
+ cachedVersion = packageJson.version ?? "0.0.0";
3702
+ return cachedVersion;
3703
+ }
3704
+
3705
+ // src/cli/index.tsx
3626
3706
  function printTable(headers, rows) {
3627
3707
  const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] || "").length)));
3628
3708
  const headerLine = headers.map((h, i) => chalk.bold(h.padEnd(widths[i]))).join(" ");
@@ -3674,11 +3754,12 @@ function parseEnvVars(envArgs) {
3674
3754
  }
3675
3755
  return vars;
3676
3756
  }
3677
- var program2 = new Command().name("sandboxes").description("Universal cloud sandbox manager for AI coding agents").version("0.1.0");
3757
+ var program2 = new Command().name("sandboxes").description("Universal cloud sandbox manager for AI coding agents").version(getPackageVersion());
3678
3758
  program2.command("create").description("Create a new sandbox").option("-p, --provider <provider>", "Provider (e2b, daytona, modal)").option("-i, --image <image>", "Container image").option("-t, --timeout <seconds>", "Timeout in seconds").option("-n, --name <name>", "Sandbox name").option("-e, --env <KEY=VAL...>", "Environment variables", (val, acc) => {
3679
3759
  acc.push(val);
3680
3760
  return acc;
3681
3761
  }, []).action(async (opts) => {
3762
+ let sandboxId;
3682
3763
  try {
3683
3764
  const provider = opts.provider || getDefaultProvider();
3684
3765
  const timeout = opts.timeout ? parseInt(opts.timeout, 10) : getDefaultTimeout();
@@ -3691,6 +3772,7 @@ program2.command("create").description("Create a new sandbox").option("-p, --pro
3691
3772
  timeout,
3692
3773
  env_vars: envVars
3693
3774
  });
3775
+ sandboxId = sandbox.id;
3694
3776
  console.log(chalk.dim("Creating sandbox..."));
3695
3777
  const p = await getProvider(provider);
3696
3778
  const result = await p.create({
@@ -3710,6 +3792,9 @@ program2.command("create").description("Create a new sandbox").option("-p, --pro
3710
3792
  console.log(` ${chalk.bold("Name:")} ${updated.name}`);
3711
3793
  }
3712
3794
  } catch (err) {
3795
+ if (sandboxId) {
3796
+ finalizeSandboxProvisionFailure(sandboxId, err);
3797
+ }
3713
3798
  handleError(err);
3714
3799
  }
3715
3800
  });
@@ -3766,6 +3851,7 @@ program2.command("show <id>").description("Show sandbox details").action((id) =>
3766
3851
  }
3767
3852
  });
3768
3853
  program2.command("exec <id> <command...>").description("Execute a command in a sandbox").action(async (id, commandParts) => {
3854
+ let sessionId;
3769
3855
  try {
3770
3856
  const sandbox = getSandbox(id);
3771
3857
  if (!sandbox.provider_sandbox_id) {
@@ -3777,6 +3863,7 @@ program2.command("exec <id> <command...>").description("Execute a command in a s
3777
3863
  sandbox_id: sandbox.id,
3778
3864
  command: cmd
3779
3865
  });
3866
+ sessionId = session.id;
3780
3867
  const collector = createStreamCollector(sandbox.id, session.id);
3781
3868
  const p = await getProvider(sandbox.provider);
3782
3869
  const result = await p.exec(sandbox.provider_sandbox_id, cmd, {
@@ -3790,9 +3877,12 @@ program2.command("exec <id> <command...>").description("Execute a command in a s
3790
3877
  }
3791
3878
  });
3792
3879
  const execResult = "exit_code" in result ? result : await result.wait();
3793
- endSession(session.id, execResult.exit_code, execResult.exit_code === 0 ? "completed" : "failed");
3880
+ finalizeSessionExit(session.id, execResult.exit_code);
3794
3881
  process.exit(execResult.exit_code);
3795
3882
  } catch (err) {
3883
+ if (sessionId) {
3884
+ finalizeSessionFailure(sessionId, err);
3885
+ }
3796
3886
  handleError(err);
3797
3887
  }
3798
3888
  });
@@ -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"}
@@ -4,6 +4,6 @@ export declare function createProject(input: CreateProjectInput): Project;
4
4
  export declare function getProject(id: string): Project;
5
5
  export declare function getProjectByPath(path: string): Project | null;
6
6
  export declare function listProjects(): Project[];
7
- export declare function ensureProject(name: string, path: string): Project;
7
+ export declare function ensureProject(name: string, path: string, description?: string): Project;
8
8
  export declare function deleteProject(id: string): void;
9
9
  //# sourceMappingURL=projects.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKlE,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CASlD;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAYhE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAS7D;AAED,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAQxC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKjE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO9C"}
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKlE,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CASlD;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAYhE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAS7D;AAED,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAQxC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAKvF;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO9C"}
@@ -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
  }
@@ -1262,11 +1308,11 @@ function listProjects() {
1262
1308
  const rows = db2.query("SELECT * FROM projects ORDER BY created_at DESC").all();
1263
1309
  return rows.map(rowToProject);
1264
1310
  }
1265
- function ensureProject(name, path) {
1311
+ function ensureProject(name, path, description) {
1266
1312
  const existing = getProjectByPath(path);
1267
1313
  if (existing)
1268
1314
  return existing;
1269
- return createProject({ name, path });
1315
+ return createProject({ name, path, description });
1270
1316
  }
1271
1317
  function deleteProject(id) {
1272
1318
  const db2 = getDatabase();
@@ -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
  };
@@ -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;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"}
1
+ {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAMA,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"}
@@ -0,0 +1,5 @@
1
+ export declare function getErrorMessage(error: unknown): string;
2
+ export declare function finalizeSessionExit(sessionId: string, exitCode: number): void;
3
+ export declare function finalizeSessionFailure(sessionId: string, _error?: unknown, exitCode?: number): void;
4
+ export declare function finalizeSandboxProvisionFailure(sandboxId: string, error?: unknown): string;
5
+ //# sourceMappingURL=runtime-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-state.d.ts","sourceRoot":"","sources":["../../src/lib/runtime-state.ts"],"names":[],"mappings":"AAGA,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,SAAI,GAAG,IAAI,CAG9F;AAED,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAI1F"}
@@ -0,0 +1,2 @@
1
+ export declare function getPackageVersion(): string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/lib/version.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C"}