@hasna/sandboxes 0.1.6 → 0.1.8

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/mcp/index.js CHANGED
@@ -217,6 +217,15 @@ class E2BProvider {
217
217
  throw new ProviderError("e2b", `Failed to resume sandbox: ${err.message}`);
218
218
  }
219
219
  }
220
+ async getPublicUrl(sandboxId, port, _protocol) {
221
+ const sandbox = await this.getInstance(sandboxId);
222
+ try {
223
+ const host = sandbox.getHost(port);
224
+ return `https://${host}`;
225
+ } catch (err) {
226
+ throw new ProviderError("e2b", `Failed to get public URL for port ${port}: ${err.message}`);
227
+ }
228
+ }
220
229
  async keepAlive(sandboxId, durationMs) {
221
230
  const sandbox = await this.getInstance(sandboxId);
222
231
  try {
@@ -377,6 +386,9 @@ class DaytonaProvider {
377
386
  throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
378
387
  }
379
388
  }
389
+ async getPublicUrl(_sandboxId, _port, _protocol) {
390
+ throw new ProviderError("daytona", "Port forwarding not supported by Daytona provider");
391
+ }
380
392
  async pause(_sandboxId) {
381
393
  throw new ProviderError("daytona", "Pause/resume not supported by Daytona provider");
382
394
  }
@@ -605,6 +617,9 @@ class ModalProvider {
605
617
  async delete(sandboxId) {
606
618
  await this.stop(sandboxId);
607
619
  }
620
+ async getPublicUrl(_sandboxId, _port, _protocol) {
621
+ throw new ProviderError("modal", "Port forwarding not supported by Modal provider");
622
+ }
608
623
  async pause(_sandboxId) {
609
624
  throw new ProviderError("modal", "Pause/resume not supported by Modal provider");
610
625
  }
@@ -4776,6 +4791,37 @@ CREATE TABLE IF NOT EXISTS templates (
4776
4791
  CREATE INDEX IF NOT EXISTS idx_templates_name ON templates(name);
4777
4792
 
4778
4793
  INSERT OR IGNORE INTO _migrations (id) VALUES (2);
4794
+ `,
4795
+ `
4796
+ CREATE TABLE IF NOT EXISTS sandbox_sessions_new (
4797
+ id TEXT PRIMARY KEY,
4798
+ sandbox_id TEXT NOT NULL REFERENCES sandboxes(id) ON DELETE CASCADE,
4799
+ agent_name TEXT,
4800
+ agent_type TEXT,
4801
+ command TEXT,
4802
+ status TEXT NOT NULL DEFAULT 'running' CHECK(status IN ('running', 'completed', 'failed', 'killed')),
4803
+ exit_code INTEGER,
4804
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
4805
+ ended_at TEXT
4806
+ );
4807
+ INSERT INTO sandbox_sessions_new SELECT * FROM sandbox_sessions;
4808
+ DROP TABLE sandbox_sessions;
4809
+ ALTER TABLE sandbox_sessions_new RENAME TO sandbox_sessions;
4810
+ CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
4811
+ CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
4812
+ INSERT OR IGNORE INTO _migrations (id) VALUES (3);
4813
+ `,
4814
+ `
4815
+ CREATE TABLE IF NOT EXISTS snapshots (
4816
+ id TEXT PRIMARY KEY,
4817
+ sandbox_id TEXT NOT NULL,
4818
+ provider_sandbox_id TEXT NOT NULL,
4819
+ provider TEXT NOT NULL,
4820
+ name TEXT,
4821
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
4822
+ );
4823
+ CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
4824
+ INSERT OR IGNORE INTO _migrations (id) VALUES (4);
4779
4825
  `
4780
4826
  ];
4781
4827
  var db = null;
@@ -5164,6 +5210,46 @@ function deleteTemplate(id) {
5164
5210
  db2.query("DELETE FROM templates WHERE id = ?").run(resolvedId);
5165
5211
  }
5166
5212
 
5213
+ // src/db/snapshots.ts
5214
+ class SnapshotNotFoundError extends Error {
5215
+ constructor(id) {
5216
+ super(`Snapshot not found: ${id}`);
5217
+ this.name = "SnapshotNotFoundError";
5218
+ }
5219
+ }
5220
+ function createSnapshot(input) {
5221
+ const db2 = getDatabase();
5222
+ const id = uuid();
5223
+ const timestamp = now();
5224
+ db2.query(`INSERT INTO snapshots (id, sandbox_id, provider_sandbox_id, provider, name, created_at)
5225
+ VALUES (?, ?, ?, ?, ?, ?)`).run(id, input.sandbox_id, input.provider_sandbox_id, input.provider, input.name ?? null, timestamp);
5226
+ return getSnapshot(id);
5227
+ }
5228
+ function getSnapshot(id) {
5229
+ const db2 = getDatabase();
5230
+ const resolvedId = resolvePartialId("snapshots", id);
5231
+ if (!resolvedId)
5232
+ throw new SnapshotNotFoundError(id);
5233
+ const row = db2.query("SELECT * FROM snapshots WHERE id = ?").get(resolvedId);
5234
+ if (!row)
5235
+ throw new SnapshotNotFoundError(id);
5236
+ return row;
5237
+ }
5238
+ function listSnapshots(sandboxId) {
5239
+ const db2 = getDatabase();
5240
+ if (sandboxId) {
5241
+ return db2.query("SELECT * FROM snapshots WHERE sandbox_id = ? ORDER BY created_at DESC").all(sandboxId);
5242
+ }
5243
+ return db2.query("SELECT * FROM snapshots ORDER BY created_at DESC").all();
5244
+ }
5245
+ function deleteSnapshot(id) {
5246
+ const db2 = getDatabase();
5247
+ const resolvedId = resolvePartialId("snapshots", id);
5248
+ if (!resolvedId)
5249
+ throw new SnapshotNotFoundError(id);
5250
+ db2.query("DELETE FROM snapshots WHERE id = ?").run(resolvedId);
5251
+ }
5252
+
5167
5253
  // src/providers/index.ts
5168
5254
  init_types();
5169
5255
 
@@ -5297,19 +5383,144 @@ function emitLifecycleEvent(sandboxId, message) {
5297
5383
  notifyListeners(sandboxId, "lifecycle", message);
5298
5384
  }
5299
5385
 
5386
+ // src/lib/agents/claude.ts
5387
+ class ClaudeDriver {
5388
+ name = "claude";
5389
+ requiredEnvVars = ["ANTHROPIC_API_KEY"];
5390
+ async install(provider, providerSandboxId) {
5391
+ const check = await provider.exec(providerSandboxId, "which claude 2>/dev/null || echo MISSING");
5392
+ if (check.stdout.trim() !== "MISSING")
5393
+ return;
5394
+ await provider.exec(providerSandboxId, "npm install -g @anthropic-ai/claude-code 2>&1 || sudo npm install -g @anthropic-ai/claude-code 2>&1");
5395
+ }
5396
+ async configure(provider, providerSandboxId, _envVars) {
5397
+ const config = JSON.stringify({
5398
+ hasCompletedOnboarding: true,
5399
+ hasTrustDialogAccepted: true,
5400
+ hasAcknowledgedCostThreshold: true
5401
+ });
5402
+ await provider.exec(providerSandboxId, `mkdir -p ~/.claude && echo '${config}' > ~/.claude.json`);
5403
+ }
5404
+ buildCommand(prompt) {
5405
+ return `claude --dangerously-skip-permissions -p ${JSON.stringify(prompt)}`;
5406
+ }
5407
+ }
5408
+
5409
+ // src/lib/agents/codex.ts
5410
+ class CodexDriver {
5411
+ name = "codex";
5412
+ requiredEnvVars = ["OPENAI_API_KEY"];
5413
+ async install(provider, providerSandboxId) {
5414
+ const check = await provider.exec(providerSandboxId, "which codex 2>/dev/null || echo MISSING");
5415
+ if (check.stdout.trim() !== "MISSING")
5416
+ return;
5417
+ await provider.exec(providerSandboxId, "npm install -g @openai/codex 2>&1 || sudo npm install -g @openai/codex 2>&1");
5418
+ }
5419
+ async configure(provider, providerSandboxId, _envVars) {
5420
+ const config = `[core]
5421
+ approvalMode = "full-auto"
5422
+ quiet = true
5423
+ `;
5424
+ await provider.exec(providerSandboxId, `mkdir -p ~/.codex && printf '${config.replace(/'/g, "'\\''")}' > ~/.codex/config.toml`);
5425
+ }
5426
+ buildCommand(prompt) {
5427
+ return `codex --approval-mode full-auto -q ${JSON.stringify(prompt)}`;
5428
+ }
5429
+ }
5430
+
5431
+ // src/lib/agents/gemini.ts
5432
+ class GeminiDriver {
5433
+ name = "gemini";
5434
+ requiredEnvVars = ["GEMINI_API_KEY"];
5435
+ async install(provider, providerSandboxId) {
5436
+ const check = await provider.exec(providerSandboxId, "which gemini 2>/dev/null || echo MISSING");
5437
+ if (check.stdout.trim() !== "MISSING")
5438
+ return;
5439
+ await provider.exec(providerSandboxId, "npm install -g @google/gemini-cli 2>&1 || sudo npm install -g @google/gemini-cli 2>&1");
5440
+ }
5441
+ async configure(provider, providerSandboxId, _envVars) {
5442
+ const settings = JSON.stringify({ theme: "Default", selectedAuthType: "gemini-api-key" });
5443
+ await provider.exec(providerSandboxId, `mkdir -p ~/.gemini && echo '${settings}' > ~/.gemini/settings.json`);
5444
+ }
5445
+ buildCommand(prompt) {
5446
+ return `gemini -p ${JSON.stringify(prompt)}`;
5447
+ }
5448
+ }
5449
+
5450
+ // src/lib/agents/opencode.ts
5451
+ class OpenCodeDriver {
5452
+ name = "opencode";
5453
+ requiredEnvVars = [];
5454
+ async install(provider, providerSandboxId) {
5455
+ const check = await provider.exec(providerSandboxId, "which opencode 2>/dev/null || echo MISSING");
5456
+ if (check.stdout.trim() !== "MISSING")
5457
+ return;
5458
+ await provider.exec(providerSandboxId, "npm install -g opencode-ai 2>&1 || sudo npm install -g opencode-ai 2>&1");
5459
+ }
5460
+ async configure(_provider, _providerSandboxId, _envVars) {}
5461
+ buildCommand(prompt) {
5462
+ return `opencode run ${JSON.stringify(prompt)}`;
5463
+ }
5464
+ }
5465
+
5466
+ // src/lib/agents/pi.ts
5467
+ class PiDriver {
5468
+ name = "pi";
5469
+ requiredEnvVars = ["PI_API_KEY"];
5470
+ async install(provider, providerSandboxId) {
5471
+ const check = await provider.exec(providerSandboxId, "which pi 2>/dev/null || echo MISSING");
5472
+ if (check.stdout.trim() !== "MISSING")
5473
+ return;
5474
+ await provider.exec(providerSandboxId, "npm install -g @pi-ai/cli 2>&1 || sudo npm install -g @pi-ai/cli 2>&1");
5475
+ }
5476
+ async configure(_provider, _providerSandboxId, _envVars) {}
5477
+ buildCommand(prompt) {
5478
+ return `pi ask ${JSON.stringify(prompt)}`;
5479
+ }
5480
+ }
5481
+
5482
+ // src/lib/agents/index.ts
5483
+ var DRIVERS = [
5484
+ new ClaudeDriver,
5485
+ new CodexDriver,
5486
+ new GeminiDriver,
5487
+ new OpenCodeDriver,
5488
+ new PiDriver
5489
+ ];
5490
+ var DRIVER_MAP = new Map(DRIVERS.map((d) => [d.name, d]));
5491
+ function getAgentDriver(name) {
5492
+ return DRIVER_MAP.get(name);
5493
+ }
5494
+
5300
5495
  // src/lib/agent-runner.ts
5301
- var CLAUDE_ONBOARDING_SETUP = `mkdir -p ~/.claude && ` + `echo '{"hasCompletedOnboarding":true,"hasTrustDialogAccepted":true,"hasAcknowledgedCostThreshold":true}' > ~/.claude.json`;
5302
- var AGENT_COMMANDS = {
5303
- claude: (prompt) => `${CLAUDE_ONBOARDING_SETUP} && claude --dangerously-skip-permissions -p ${JSON.stringify(prompt)}`,
5304
- codex: (prompt) => `codex -q ${JSON.stringify(prompt)}`,
5305
- gemini: (prompt) => `gemini -p ${JSON.stringify(prompt)}`
5306
- };
5496
+ async function fireWebhook(url, payload) {
5497
+ try {
5498
+ await fetch(url, {
5499
+ method: "POST",
5500
+ headers: { "Content-Type": "application/json" },
5501
+ body: JSON.stringify(payload)
5502
+ });
5503
+ } catch {}
5504
+ }
5307
5505
  async function runAgent(sandboxId, opts) {
5308
5506
  const sandbox = getSandbox(sandboxId);
5309
5507
  if (!sandbox.provider_sandbox_id) {
5310
5508
  throw new Error("Sandbox has no provider instance");
5311
5509
  }
5312
- const cmd = opts.command || AGENT_COMMANDS[opts.agentType]?.(opts.prompt) || opts.prompt;
5510
+ const provider = await getProvider(sandbox.provider);
5511
+ const mergedEnv = { ...sandbox.env_vars, ...opts.callEnvVars };
5512
+ const env = Object.keys(mergedEnv).length > 0 ? mergedEnv : undefined;
5513
+ let cmd;
5514
+ const driver = opts.agentType !== "custom" ? getAgentDriver(opts.agentType) : undefined;
5515
+ if (opts.command) {
5516
+ cmd = opts.command;
5517
+ } else if (driver) {
5518
+ await driver.install(provider, sandbox.provider_sandbox_id);
5519
+ await driver.configure(provider, sandbox.provider_sandbox_id, sandbox.env_vars ?? {});
5520
+ cmd = driver.buildCommand(opts.prompt);
5521
+ } else {
5522
+ cmd = opts.prompt;
5523
+ }
5313
5524
  const session = createSession({
5314
5525
  sandbox_id: sandbox.id,
5315
5526
  agent_name: opts.agentName,
@@ -5317,9 +5528,19 @@ async function runAgent(sandboxId, opts) {
5317
5528
  command: cmd
5318
5529
  });
5319
5530
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} started: ${opts.prompt.slice(0, 100)}`);
5531
+ const startedAt = Date.now();
5532
+ const webhookEvents = opts.webhookEvents ?? ["start", "complete", "error"];
5533
+ if (opts.webhookUrl && webhookEvents.includes("start")) {
5534
+ fireWebhook(opts.webhookUrl, {
5535
+ event: "start",
5536
+ session_id: session.id,
5537
+ sandbox_id: sandbox.id,
5538
+ agent_type: opts.agentType,
5539
+ status: "running",
5540
+ timestamp: new Date().toISOString()
5541
+ });
5542
+ }
5320
5543
  const collector = createStreamCollector(sandbox.id, session.id);
5321
- const provider = await getProvider(sandbox.provider);
5322
- const env = Object.keys(sandbox.env_vars ?? {}).length > 0 ? sandbox.env_vars : undefined;
5323
5544
  provider.exec(sandbox.provider_sandbox_id, cmd, {
5324
5545
  onStdout: (data) => {
5325
5546
  collector.onStdout(data);
@@ -5335,9 +5556,32 @@ async function runAgent(sandboxId, opts) {
5335
5556
  const status = exitResult.exit_code === 0 ? "completed" : "failed";
5336
5557
  endSession(session.id, exitResult.exit_code ?? 0, status);
5337
5558
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} finished with exit code ${exitResult.exit_code}`);
5559
+ if (opts.webhookUrl && webhookEvents.includes("complete")) {
5560
+ fireWebhook(opts.webhookUrl, {
5561
+ event: "complete",
5562
+ session_id: session.id,
5563
+ sandbox_id: sandbox.id,
5564
+ agent_type: opts.agentType,
5565
+ status,
5566
+ exit_code: exitResult.exit_code,
5567
+ duration_ms: Date.now() - startedAt,
5568
+ timestamp: new Date().toISOString()
5569
+ });
5570
+ }
5338
5571
  }).catch((err) => {
5339
5572
  endSession(session.id, 1, "failed");
5340
5573
  emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} failed: ${err.message}`);
5574
+ if (opts.webhookUrl && webhookEvents.includes("error")) {
5575
+ fireWebhook(opts.webhookUrl, {
5576
+ event: "error",
5577
+ session_id: session.id,
5578
+ sandbox_id: sandbox.id,
5579
+ agent_type: opts.agentType,
5580
+ status: "failed",
5581
+ duration_ms: Date.now() - startedAt,
5582
+ timestamp: new Date().toISOString()
5583
+ });
5584
+ }
5341
5585
  });
5342
5586
  return session;
5343
5587
  }
@@ -5347,12 +5591,13 @@ async function stopAgent(sandboxId) {
5347
5591
  return;
5348
5592
  const provider = await getProvider(sandbox.provider);
5349
5593
  try {
5350
- await provider.exec(sandbox.provider_sandbox_id, "pkill -f 'claude\\|codex\\|gemini' || true");
5594
+ await provider.exec(sandbox.provider_sandbox_id, "pkill -f 'claude\\|codex\\|gemini\\|opencode\\|pi' || true");
5351
5595
  } catch {}
5352
5596
  emitLifecycleEvent(sandbox.id, "Agent stopped by user");
5353
5597
  }
5354
5598
 
5355
5599
  // src/mcp/index.ts
5600
+ var exposedPorts = new Map;
5356
5601
  function ok(data) {
5357
5602
  return { content: [{ type: "text", text: JSON.stringify(data) }] };
5358
5603
  }
@@ -5385,7 +5630,15 @@ var TOOL_CATALOG = [
5385
5630
  { name: "create_template", description: "Create a reusable sandbox template" },
5386
5631
  { name: "list_templates", description: "List all sandbox templates" },
5387
5632
  { name: "get_template", description: "Get a sandbox template by ID" },
5388
- { name: "delete_template", description: "Delete a sandbox template" }
5633
+ { name: "delete_template", description: "Delete a sandbox template" },
5634
+ { name: "get_sandbox_status", description: "Get running processes, disk usage and uptime in a sandbox" },
5635
+ { name: "snapshot_sandbox", description: "Capture sandbox filesystem state as a snapshot" },
5636
+ { name: "list_snapshots", description: "List filesystem snapshots" },
5637
+ { name: "delete_snapshot", description: "Delete a snapshot" },
5638
+ { name: "expose_port", description: "Forward a sandbox port and get a public URL" },
5639
+ { name: "list_exposed_ports", description: "List all forwarded ports for a sandbox" },
5640
+ { name: "close_port", description: "Stop forwarding a sandbox port" },
5641
+ { name: "get_network_log", description: "Get outbound network connections from a sandbox" }
5389
5642
  ];
5390
5643
  var server = new McpServer({
5391
5644
  name: "sandboxes",
@@ -5399,7 +5652,9 @@ server.tool("create_sandbox", "Create a new sandbox", {
5399
5652
  env_vars: exports_external.record(exports_external.string()).optional().describe("Environment variables"),
5400
5653
  template_id: exports_external.string().optional().describe("Template ID to base this sandbox on"),
5401
5654
  on_timeout: exports_external.enum(["pause", "terminate"]).optional().describe("What to do on timeout: pause (saves state) or terminate"),
5402
- auto_resume: exports_external.boolean().optional().describe("Auto-resume paused sandbox on next connect")
5655
+ auto_resume: exports_external.boolean().optional().describe("Auto-resume paused sandbox on next connect"),
5656
+ 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")
5403
5658
  }, async (params) => {
5404
5659
  try {
5405
5660
  const providerName = params.provider ?? getDefaultProvider();
@@ -5421,9 +5676,20 @@ server.tool("create_sandbox", "Create a new sandbox", {
5421
5676
  env_vars: envVars,
5422
5677
  on_timeout: onTimeout,
5423
5678
  auto_resume: autoResume,
5424
- template_id: params.template_id
5679
+ template_id: params.template_id,
5680
+ config: { network: params.network ?? "full" }
5425
5681
  });
5426
5682
  const provider = await getProvider(providerName);
5683
+ if (params.snapshot_id) {
5684
+ const snapshot = getSnapshot(params.snapshot_id);
5685
+ await provider.resume(snapshot.provider_sandbox_id);
5686
+ const updated2 = updateSandbox(sandbox.id, {
5687
+ provider_sandbox_id: snapshot.provider_sandbox_id,
5688
+ status: "running"
5689
+ });
5690
+ emitLifecycleEvent(sandbox.id, `Sandbox restored from snapshot ${snapshot.id}`);
5691
+ return ok(updated2);
5692
+ }
5427
5693
  const result = await provider.create({
5428
5694
  image,
5429
5695
  timeout,
@@ -5519,7 +5785,8 @@ server.tool("keep_alive", "Extend sandbox lifetime", {
5519
5785
  server.tool("exec_command", "Execute a command in a sandbox", {
5520
5786
  sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
5521
5787
  command: exports_external.string().describe("Command to execute"),
5522
- background: exports_external.boolean().optional().describe("Run in background")
5788
+ 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)")
5523
5790
  }, async (params) => {
5524
5791
  try {
5525
5792
  const sandbox = getSandbox(params.sandbox_id);
@@ -5531,7 +5798,8 @@ server.tool("exec_command", "Execute a command in a sandbox", {
5531
5798
  });
5532
5799
  const collector = createStreamCollector(sandbox.id, session.id);
5533
5800
  const provider = await getProvider(sandbox.provider);
5534
- const env = Object.keys(sandbox.env_vars ?? {}).length > 0 ? sandbox.env_vars : undefined;
5801
+ const callEnv = { ...sandbox.env_vars, ...params.env_vars };
5802
+ const env = Object.keys(callEnv).length > 0 ? callEnv : undefined;
5535
5803
  if (params.background) {
5536
5804
  provider.exec(sandbox.provider_sandbox_id, params.command, {
5537
5805
  onStdout: collector.onStdout,
@@ -5679,17 +5947,23 @@ server.tool("search_tools", "Search tools by keyword", {
5679
5947
  });
5680
5948
  server.tool("run_agent", "Run an AI agent inside a sandbox", {
5681
5949
  sandbox_id: exports_external.string().describe("Sandbox ID"),
5682
- agent_type: exports_external.enum(["claude", "codex", "gemini", "custom"]).describe("Agent type"),
5950
+ agent_type: exports_external.enum(["claude", "codex", "gemini", "opencode", "pi", "custom"]).describe("Agent type"),
5683
5951
  prompt: exports_external.string().describe("Prompt for the agent"),
5684
5952
  agent_name: exports_external.string().optional().describe("Agent name"),
5685
- command: exports_external.string().optional().describe("Custom command (for 'custom' type)")
5953
+ command: exports_external.string().optional().describe("Custom command (for 'custom' type)"),
5954
+ env_vars: exports_external.record(exports_external.string()).optional().describe("Per-call environment variables (merged with sandbox env_vars, not persisted)"),
5955
+ webhook_url: exports_external.string().optional().describe("URL to POST result to when agent finishes"),
5956
+ webhook_events: exports_external.array(exports_external.enum(["start", "complete", "error"])).optional().describe("Which events to notify on (default: all)")
5686
5957
  }, async (params) => {
5687
5958
  try {
5688
5959
  const session = await runAgent(params.sandbox_id, {
5689
5960
  agentType: params.agent_type,
5690
5961
  prompt: params.prompt,
5691
5962
  agentName: params.agent_name,
5692
- command: params.command
5963
+ command: params.command,
5964
+ callEnvVars: params.env_vars,
5965
+ webhookUrl: params.webhook_url,
5966
+ webhookEvents: params.webhook_events
5693
5967
  });
5694
5968
  return ok({ session_id: session.id, status: session.status });
5695
5969
  } catch (e) {
@@ -5709,17 +5983,19 @@ server.tool("stop_agent", "Stop a running agent in a sandbox", {
5709
5983
  server.tool("get_agent_output", "Get output from an agent session", {
5710
5984
  sandbox_id: exports_external.string().describe("Sandbox ID"),
5711
5985
  session_id: exports_external.string().optional().describe("Session ID"),
5712
- limit: exports_external.number().optional().describe("Max events")
5986
+ limit: exports_external.number().optional().describe("Max events"),
5987
+ offset: exports_external.number().optional().describe("Skip first N events (for incremental polling)")
5713
5988
  }, async (params) => {
5714
5989
  try {
5715
5990
  const events = listEvents({
5716
5991
  sandbox_id: params.sandbox_id,
5717
5992
  session_id: params.session_id,
5718
- limit: params.limit || 100
5993
+ limit: params.limit || 100,
5994
+ offset: params.offset
5719
5995
  });
5720
5996
  const stdout = events.filter((e) => e.type === "stdout").map((e) => e.data).join("");
5721
5997
  const stderr = events.filter((e) => e.type === "stderr").map((e) => e.data).join("");
5722
- return ok({ stdout, stderr, event_count: events.length });
5998
+ return ok({ stdout, stderr, event_count: events.length, next_offset: (params.offset ?? 0) + events.length });
5723
5999
  } catch (e) {
5724
6000
  return err(e);
5725
6001
  }
@@ -5796,5 +6072,138 @@ server.tool("delete_template", "Delete a sandbox template", {
5796
6072
  return err(e);
5797
6073
  }
5798
6074
  });
6075
+ server.tool("get_sandbox_status", "Get running processes, disk usage and uptime in a sandbox", {
6076
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID")
6077
+ }, async (params) => {
6078
+ try {
6079
+ const sandbox = getSandbox(params.sandbox_id);
6080
+ if (!sandbox.provider_sandbox_id)
6081
+ throw new Error("Sandbox has no provider ID");
6082
+ const provider = await getProvider(sandbox.provider);
6083
+ const [psResult, dfResult, uptimeResult] = await Promise.all([
6084
+ provider.exec(sandbox.provider_sandbox_id, "ps aux --no-headers 2>/dev/null | head -30 || ps aux 2>/dev/null | tail -n +2 | head -30"),
6085
+ provider.exec(sandbox.provider_sandbox_id, "df -h / 2>/dev/null || df -h 2>/dev/null | head -5"),
6086
+ provider.exec(sandbox.provider_sandbox_id, "uptime 2>/dev/null || echo unknown")
6087
+ ]);
6088
+ const processes = (psResult.stdout || "").trim().split(`
6089
+ `).filter(Boolean).map((line) => {
6090
+ const parts = line.trim().split(/\s+/);
6091
+ return {
6092
+ pid: parts[1] || "",
6093
+ cpu: parts[2] || "0",
6094
+ mem: parts[3] || "0",
6095
+ command: parts.slice(10).join(" ") || parts.slice(4).join(" ")
6096
+ };
6097
+ });
6098
+ return ok({
6099
+ sandbox_id: sandbox.id,
6100
+ status: sandbox.status,
6101
+ processes,
6102
+ disk: (dfResult.stdout || "").trim(),
6103
+ uptime: (uptimeResult.stdout || "").trim()
6104
+ });
6105
+ } catch (e) {
6106
+ return err(e);
6107
+ }
6108
+ });
6109
+ server.tool("snapshot_sandbox", "Capture sandbox filesystem state as a snapshot", {
6110
+ id: exports_external.string().describe("Sandbox ID or partial ID"),
6111
+ name: exports_external.string().optional().describe("Snapshot name")
6112
+ }, async (params) => {
6113
+ try {
6114
+ const sandbox = getSandbox(params.id);
6115
+ if (!sandbox.provider_sandbox_id)
6116
+ throw new Error("Sandbox has no provider ID");
6117
+ const provider = await getProvider(sandbox.provider);
6118
+ await provider.pause(sandbox.provider_sandbox_id);
6119
+ updateSandbox(sandbox.id, { status: "paused" });
6120
+ const snapshot = createSnapshot({
6121
+ sandbox_id: sandbox.id,
6122
+ provider_sandbox_id: sandbox.provider_sandbox_id,
6123
+ provider: sandbox.provider,
6124
+ name: params.name
6125
+ });
6126
+ emitLifecycleEvent(sandbox.id, `Snapshot created: ${snapshot.id}`);
6127
+ return ok(snapshot);
6128
+ } catch (e) {
6129
+ return err(e);
6130
+ }
6131
+ });
6132
+ server.tool("list_snapshots", "List filesystem snapshots", {
6133
+ sandbox_id: exports_external.string().optional().describe("Filter by sandbox ID")
6134
+ }, async (params) => {
6135
+ try {
6136
+ return ok(listSnapshots(params.sandbox_id));
6137
+ } catch (e) {
6138
+ return err(e);
6139
+ }
6140
+ });
6141
+ server.tool("delete_snapshot", "Delete a snapshot", {
6142
+ id: exports_external.string().describe("Snapshot ID or partial ID")
6143
+ }, async (params) => {
6144
+ try {
6145
+ deleteSnapshot(params.id);
6146
+ return ok({ deleted: params.id });
6147
+ } catch (e) {
6148
+ return err(e);
6149
+ }
6150
+ });
6151
+ server.tool("expose_port", "Forward a sandbox port and get a public URL", {
6152
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
6153
+ port: exports_external.number().describe("Port number to expose"),
6154
+ protocol: exports_external.string().optional().describe("Protocol: http or ws (default: http)")
6155
+ }, async (params) => {
6156
+ try {
6157
+ const sandbox = getSandbox(params.sandbox_id);
6158
+ if (!sandbox.provider_sandbox_id)
6159
+ throw new Error("Sandbox has no provider ID");
6160
+ const provider = await getProvider(sandbox.provider);
6161
+ const url = await provider.getPublicUrl(sandbox.provider_sandbox_id, params.port, params.protocol);
6162
+ if (!exposedPorts.has(sandbox.id))
6163
+ exposedPorts.set(sandbox.id, new Map);
6164
+ exposedPorts.get(sandbox.id).set(params.port, url);
6165
+ return ok({ sandbox_id: sandbox.id, port: params.port, url });
6166
+ } catch (e) {
6167
+ return err(e);
6168
+ }
6169
+ });
6170
+ server.tool("list_exposed_ports", "List all forwarded ports for a sandbox", {
6171
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID")
6172
+ }, async (params) => {
6173
+ try {
6174
+ const sandbox = getSandbox(params.sandbox_id);
6175
+ const ports = exposedPorts.get(sandbox.id) ?? new Map;
6176
+ const result = Array.from(ports.entries()).map(([port, url]) => ({ port, url }));
6177
+ return ok(result);
6178
+ } catch (e) {
6179
+ return err(e);
6180
+ }
6181
+ });
6182
+ server.tool("close_port", "Stop forwarding a sandbox port", {
6183
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID"),
6184
+ port: exports_external.number().describe("Port number to close")
6185
+ }, async (params) => {
6186
+ try {
6187
+ const sandbox = getSandbox(params.sandbox_id);
6188
+ exposedPorts.get(sandbox.id)?.delete(params.port);
6189
+ return ok({ sandbox_id: sandbox.id, port: params.port, closed: true });
6190
+ } catch (e) {
6191
+ return err(e);
6192
+ }
6193
+ });
6194
+ server.tool("get_network_log", "Get outbound network connections from a sandbox", {
6195
+ sandbox_id: exports_external.string().describe("Sandbox ID or partial ID")
6196
+ }, async (params) => {
6197
+ try {
6198
+ const sandbox = getSandbox(params.sandbox_id);
6199
+ if (!sandbox.provider_sandbox_id)
6200
+ throw new Error("Sandbox has no provider ID");
6201
+ const provider = await getProvider(sandbox.provider);
6202
+ const result = await provider.exec(sandbox.provider_sandbox_id, "ss -tnp 2>/dev/null || netstat -tnp 2>/dev/null || echo 'Network log not available'");
6203
+ return ok({ sandbox_id: sandbox.id, connections: (result.stdout || "").trim() });
6204
+ } catch (e) {
6205
+ return err(e);
6206
+ }
6207
+ });
5799
6208
  var transport = new StdioServerTransport;
5800
6209
  await server.connect(transport);
@@ -12,6 +12,7 @@ export declare class DaytonaProvider implements SandboxProvider {
12
12
  listFiles(sandboxId: string, path: string): Promise<FileInfo[]>;
13
13
  stop(sandboxId: string): Promise<void>;
14
14
  delete(sandboxId: string): Promise<void>;
15
+ getPublicUrl(_sandboxId: string, _port: number, _protocol?: string): Promise<string>;
15
16
  pause(_sandboxId: string): Promise<void>;
16
17
  resume(_sandboxId: string): Promise<void>;
17
18
  keepAlive(sandboxId: string, durationMs?: number): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"daytona.d.ts","sourceRoot":"","sources":["../../src/providers/daytona.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,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,aAAa;IAC1B,OAAO,CAAC,MAAM,CAAU;gBAEZ,MAAM,EAAE,MAAM;IAMpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;YA0BlD,WAAW;IAgBnB,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAgG7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1D,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;IAaxC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAcvE"}
1
+ {"version":3,"file":"daytona.d.ts","sourceRoot":"","sources":["../../src/providers/daytona.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,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,aAAa;IAC1B,OAAO,CAAC,MAAM,CAAU;gBAEZ,MAAM,EAAE,MAAM;IAMpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;YA0BlD,WAAW;IAgBnB,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAgG7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1D,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;IAaxC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpF,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAcvE"}
@@ -14,6 +14,7 @@ export declare class E2BProvider implements SandboxProvider {
14
14
  delete(sandboxId: string): Promise<void>;
15
15
  pause(sandboxId: string): Promise<void>;
16
16
  resume(sandboxId: string): Promise<void>;
17
+ getPublicUrl(sandboxId: string, port: number, _protocol?: string): Promise<string>;
17
18
  keepAlive(sandboxId: string, durationMs?: number): Promise<void>;
18
19
  }
19
20
  //# sourceMappingURL=e2b.d.ts.map
@@ -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,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;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"}
@@ -15,6 +15,7 @@ export declare class ModalProvider implements SandboxProvider {
15
15
  listFiles(sandboxId: string, path: string): Promise<FileInfo[]>;
16
16
  stop(sandboxId: string): Promise<void>;
17
17
  delete(sandboxId: string): Promise<void>;
18
+ getPublicUrl(_sandboxId: string, _port: number, _protocol?: string): Promise<string>;
18
19
  pause(_sandboxId: string): Promise<void>;
19
20
  resume(_sandboxId: string): Promise<void>;
20
21
  keepAlive(_sandboxId: string, _durationMs?: number): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/providers/modal.ts"],"names":[],"mappings":"AACA,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;AAKpB,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAS;gBAEb,MAAM,CAAC,EAAE,MAAM;YAIb,YAAY;IAiBpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsChE,OAAO,CAAC,UAAU;IAWZ,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAmF7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB1D,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAoBV,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmD/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,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,OAAO,CAAC,YAAY;IAuCpB;;OAEG;IACH,OAAO,CAAC,WAAW;CAGpB"}
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/providers/modal.ts"],"names":[],"mappings":"AACA,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;AAKpB,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAS;gBAEb,MAAM,CAAC,EAAE,MAAM;YAIb,YAAY;IAiBpB,MAAM,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsChE,OAAO,CAAC,UAAU;IAWZ,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAmF7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB1D,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAoBV,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmD/D,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpF,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE;;OAEG;IACH,OAAO,CAAC,YAAY;IAuCpB;;OAEG;IACH,OAAO,CAAC,WAAW;CAGpB"}
@@ -30,5 +30,6 @@ export interface SandboxProvider {
30
30
  keepAlive(sandboxId: string, durationMs?: number): Promise<void>;
31
31
  pause(sandboxId: string): Promise<void>;
32
32
  resume(sandboxId: string): Promise<void>;
33
+ getPublicUrl(sandboxId: string, port: number, protocol?: string): Promise<string>;
33
34
  }
34
35
  //# sourceMappingURL=types.d.ts.map
@@ -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;CAC1C"}
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"}