@tangle-network/sandbox 0.10.2 → 0.10.4

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.
@@ -0,0 +1,1545 @@
1
+ import { $ as EventStreamOptions, A as CommitTaskSessionOptions, Ai as WriteFileOptions, An as Rollout, B as CreateTaskSessionOptions, Br as SearchMatch, Bt as IntelligenceReport, Ci as TurnDriveResult, Cr as SandboxResourceUsage, Ct as GitBranch, D as CodeLanguage, Dr as SandboxRuntimeProfileList, Dt as GitStatus, E as CodeExecutionResult, Et as GitDiff, Gr as SendSessionMessageRequest, Gt as JsonValue, Ht as IntelligenceReportCompareTo, Ir as SandboxTraceOptions, Jr as SessionEventStreamOptions, Kr as SentSessionMessage, Kt as ListMessagesOptions, Mi as WriteManyOptions, Mn as RolloutOptions, Nr as SandboxTraceBundle, Nt as GpuLeaseManager, Oi as WaitForOptions, On as RestoreSnapshotOptions, Or as SandboxStatus, Ot as GpuLease, Pn as RolloutStartResult, Qr as SessionMessage, Rn as SSHCommandDescriptor, Rr as ScopedToken, T as CodeExecutionOptions, Tr as SandboxRuntimeHealth, U as DispatchPromptOptions, Un as SandboxEvent, Vn as SandboxConnection, Vr as SearchOptions, Vt as IntelligenceReportBudget, W as DispatchedSession, Wr as SendSessionMessageOptions, Wt as IntelligenceReportWindow, Xr as SessionInfo, Y as DriverInfo, Yr as SessionForkOptions, Z as EgressManager, Zr as SessionListOptions, Zt as MintScopedTokenOptions, _n as ProvisionResult, _r as SandboxInfo, ai as StartupDiagnostics, an as PreviewLinkManager, bi as TeePublicKeyResponse, br as SandboxPortBinding, cr as SandboxFleetTraceBundle, di as TaskSessionChanges, dt as FileWriteResult, en as NetworkManager, et as ExecOptions, fi as TaskSessionCommitResult, gi as TeeAttestationOptions, gn as ProvisionEvent, hn as PromptResult, j as CompletedTurnResult, ji as WriteManyFile, jr as SandboxTerminalManager, ki as WaitForRolloutOptions, kn as ResumeOptions, l as BackendManager, li as TaskOptions, ln as ProcessManager, mi as TaskSessionInfo, mn as PromptOptions, ni as SnapshotOptions, pn as PromptInputPart, q as DriveTurnOptions, ri as SnapshotResult, rn as PermissionsManager, s as BackendConfig, st as FileSystem, ti as SnapshotInfo, tt as ExecResult, ui as TaskResult, vi as TeeAttestationResponse, w as BranchOptions, wt as GitCommit, z as CreateSessionOptions, zn as SSHCredentials, zt as InstalledTool } from "./types-BvSoEHz8.js";
2
+
3
+ //#region src/mcp.d.ts
4
+ /**
5
+ * MCP (Model Context Protocol) helpers for sandbox capabilities.
6
+ *
7
+ * The sandbox exposes capabilities (currently `computer_use`, more
8
+ * later) as MCP tools over Streamable HTTP. Any MCP-capable client —
9
+ * Claude Desktop, Cursor, claude-code, codex, opencode, raw
10
+ * `@modelcontextprotocol/sdk` apps — can consume this surface by
11
+ * pasting the JSON returned from `Sandbox#getMcpEndpoint()` (or
12
+ * `buildSandboxMcpConfig` if you already have the URL + token) into
13
+ * the client's MCP config.
14
+ *
15
+ * Security model:
16
+ * - Tokens are capability-scoped JWTs (claim `cap: ["computer_use"]`).
17
+ * - Full sandbox runtime tokens are rejected on `/mcp`; only
18
+ * capability-scoped tokens work there.
19
+ * - A scoped token cannot pivot to admin endpoints (`/exec`, `/files`,
20
+ * etc.) — those routes reject scoped tokens.
21
+ * - Tokens are short-lived. Rotate via `Sandbox#getMcpEndpoint()`,
22
+ * which mints a fresh token each call.
23
+ */
24
+ /** Default name of the MCP server entry — surfaces in the host UI. */
25
+ declare const SANDBOX_MCP_SERVER_NAME = "tangle-sandbox";
26
+ /**
27
+ * MCP HTTP server entry — matches the Anthropic MCP HTTP transport
28
+ * schema (`type: "http"`, `url`, optional `headers`). Compatible with
29
+ * every MCP host that implements the spec.
30
+ */
31
+ interface SandboxMcpServerEntry {
32
+ type: "http";
33
+ url: string;
34
+ headers: Record<string, string>;
35
+ }
36
+ /**
37
+ * `.mcp.json`-shaped config any MCP host accepts. Drop the contents of
38
+ * `mcpServers` into your host's `mcpServers` block (Claude Desktop,
39
+ * Cursor, claude-code's `--mcp-config`, etc.) — no host-specific
40
+ * fields, no provider lock-in.
41
+ */
42
+ interface SandboxMcpConfig {
43
+ mcpServers: Record<string, SandboxMcpServerEntry>;
44
+ }
45
+ /**
46
+ * Endpoint payload returned by `GET /v1/sandboxes/:id/mcp`. Includes
47
+ * the canonical config plus token expiry so callers can plan
48
+ * refreshes.
49
+ */
50
+ interface SandboxMcpEndpoint {
51
+ /** MCP host config — paste this into Cursor/Claude Desktop/etc. */
52
+ config: SandboxMcpConfig;
53
+ /** Server entry name used inside `config.mcpServers`. */
54
+ serverName: string;
55
+ /** Reachable URL for the MCP HTTP transport. */
56
+ url: string;
57
+ /** Bearer token sent by the MCP host on every request. */
58
+ authToken: string;
59
+ /** ISO-8601 expiry — the host should refresh before this. */
60
+ expiresAt: string;
61
+ /** Capabilities the token is scoped to. */
62
+ capabilities: ReadonlyArray<"computer_use">;
63
+ }
64
+ interface BuildSandboxMcpConfigOptions {
65
+ /** Public sandbox URL where `/mcp` is reachable. No trailing slash. */
66
+ sandboxUrl: string;
67
+ /** Capability-scoped JWT minted by the Sandbox API. */
68
+ authToken: string;
69
+ /** Override the entry name. Defaults to SANDBOX_MCP_SERVER_NAME. */
70
+ serverName?: string;
71
+ }
72
+ /**
73
+ * Build the canonical `mcpServers` config for a sandbox MCP endpoint.
74
+ * Pure function — no I/O, no crypto. Use this when you already have a
75
+ * `{ url, authToken }` pair from the API and just want the JSON shape
76
+ * to paste into a host. Most callers should use
77
+ * `Sandbox#getMcpEndpoint()` instead, which fetches a freshly-minted
78
+ * token from the API.
79
+ */
80
+ declare function buildSandboxMcpConfig(options: BuildSandboxMcpConfigOptions): {
81
+ serverName: string;
82
+ config: SandboxMcpConfig;
83
+ };
84
+ /**
85
+ * Default name of the control-plane MCP server entry. Distinct from the per-
86
+ * sandbox runtime server (`SANDBOX_MCP_SERVER_NAME`): the sandbox surface
87
+ * operates INSIDE one sandbox (`run_code`/`exec`/`read`/`write`), while this one
88
+ * operates ACROSS the account (sandboxes, workflows, integrations, usage).
89
+ */
90
+ declare const CONTROL_PLANE_MCP_SERVER_NAME = "tangle-control-plane";
91
+ interface BuildControlPlaneMcpConfigOptions {
92
+ /** Public platform URL where `/mcp` is reachable. No trailing slash. */
93
+ platformUrl: string;
94
+ /**
95
+ * A Tangle account API key scoped to the control-plane operations you need
96
+ * (e.g. `read`, `workflows:write`). Sent on every request as a Bearer token.
97
+ */
98
+ apiKey: string;
99
+ /** Override the entry name. Defaults to CONTROL_PLANE_MCP_SERVER_NAME. */
100
+ serverName?: string;
101
+ }
102
+ /**
103
+ * Build the canonical `mcpServers` config for the public control-plane MCP
104
+ * endpoint — the JSON a user pastes into Claude Desktop / Cursor / claude-code
105
+ * to drive their Tangle account from their own agent. Pure function; mirrors
106
+ * `buildSandboxMcpConfig` but carries an account API key instead of a per-
107
+ * sandbox capability token.
108
+ */
109
+ declare function buildControlPlaneMcpConfig(options: BuildControlPlaneMcpConfigOptions): {
110
+ serverName: string;
111
+ config: SandboxMcpConfig;
112
+ };
113
+ //#endregion
114
+ //#region src/interactive.d.ts
115
+ /**
116
+ * Interactive harness sessions on the public SDK.
117
+ *
118
+ * `box.session(id).interactive()` returns a handle that spawns a coding
119
+ * harness's native interactive TUI in the sandbox (start), drives it with
120
+ * prompts (sendPrompt), and tears it down (stop). The live framebuffer is
121
+ * streamed over the WebSocket at the returned `streamUrl` (the secured
122
+ * `/terminals/:id/ws` pixel lane) — open it with your terminal/xterm client.
123
+ *
124
+ * This is the public SDK surface of the Session Protocol Gateway; it rides the
125
+ * same secured runtime routes as the rest of the SDK.
126
+ */
127
+ /** CLI auth file materialized into the harness's auth home before launch. */
128
+ interface InteractiveAuthFile {
129
+ path: string;
130
+ content: string;
131
+ mode?: number;
132
+ }
133
+ interface StartInteractiveOptions {
134
+ /** Harness with a native interactive TUI: "claude-code" | "codex" | "kimi-code". */
135
+ harness: string;
136
+ model?: string;
137
+ apiKey?: string;
138
+ authMode?: string;
139
+ baseUrl?: string;
140
+ /** Working directory; defaults to the sandbox workspace root. */
141
+ cwd?: string;
142
+ cols?: number;
143
+ rows?: number;
144
+ authFiles?: InteractiveAuthFile[];
145
+ }
146
+ interface InteractiveSessionInfo {
147
+ sessionId: string;
148
+ harness: string;
149
+ /** ISO timestamp of when the harness process was spawned. */
150
+ startedAt: string;
151
+ /**
152
+ * Sandbox-relative WebSocket path that streams the live framebuffer and
153
+ * accepts keystrokes (the mTLS- + capability-gated terminal socket).
154
+ */
155
+ streamUrl: string;
156
+ }
157
+ /** Decision passed to `respondToPermission`. */
158
+ interface RespondToPermissionOptions {
159
+ /** The human's decision for the awaiting permission interaction. */
160
+ response: "allow" | "deny";
161
+ }
162
+ /** Result of `interrupt`. */
163
+ interface InterruptResult {
164
+ /**
165
+ * True iff an execution was actively running and the abort signal reached
166
+ * it. `false` means there was nothing in flight to cancel — surfaced
167
+ * explicitly rather than as a silent success so callers can distinguish a
168
+ * real interruption from a no-op.
169
+ */
170
+ cancelled: boolean;
171
+ }
172
+ /**
173
+ * Host hooks the SDK box implements to drive interactive sessions. Kept
174
+ * separate from the prompt/session-event host so the interactive surface is an
175
+ * explicit, independently-mockable contract.
176
+ */
177
+ interface InteractiveSessionHost {
178
+ _startInteractive(id: string, options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
179
+ _sendInteractivePrompt(id: string, prompt: string): Promise<void>;
180
+ _stopInteractive(id: string): Promise<void>;
181
+ }
182
+ /**
183
+ * Handle for one session's interactive harness. Obtained via
184
+ * `box.session(id).interactive()`; does not hit the network until a method is
185
+ * called.
186
+ */
187
+ declare class InteractiveSessionHandle {
188
+ private readonly host;
189
+ private readonly sessionId;
190
+ constructor(host: InteractiveSessionHost, sessionId: string);
191
+ /**
192
+ * Spawn the harness's interactive TUI for this session. Returns the
193
+ * `streamUrl` to attach a terminal client to. Throws if the harness has no
194
+ * interactive entrypoint (e.g. opencode), the binary is not installed, or a
195
+ * session is already running for this id.
196
+ */
197
+ start(options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
198
+ /** Inject a prompt as keystrokes into the live harness (submitted on send). */
199
+ sendPrompt(prompt: string): Promise<void>;
200
+ /** Stop the interactive harness and reap its PTY. */
201
+ stop(): Promise<void>;
202
+ }
203
+ //#endregion
204
+ //#region src/session.d.ts
205
+ /**
206
+ * The subset of `SandboxInstance` a `SandboxSession` drives. Declared here
207
+ * (rather than importing the concrete class) so `session.ts` stays a leaf
208
+ * of `sandbox.ts` — `sandbox.ts` constructs `SandboxSession`, so the reverse
209
+ * import would form a cycle. `SandboxInstance` satisfies this structurally.
210
+ */
211
+ interface SandboxSessionHost extends InteractiveSessionHost {
212
+ prompt(message: string | PromptInputPart[], options?: PromptOptions): Promise<PromptResult>;
213
+ _sessionStatus(id: string): Promise<SessionInfo | null>;
214
+ _sessionEvents(id: string, opts?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
215
+ _sessionResult(id: string): Promise<PromptResult>;
216
+ _sessionCancel(id: string): Promise<void>;
217
+ _sessionDelete(id: string): Promise<void>;
218
+ _sessionSendMessage(id: string, request: SendSessionMessageRequest, options?: SendSessionMessageOptions): Promise<SentSessionMessage>;
219
+ messages(opts: ListMessagesOptions): Promise<SessionMessage[]>;
220
+ _sessionFork(id: string, opts?: SessionForkOptions): Promise<SessionInfo>;
221
+ _respondToPermission(id: string, permissionID: string, options: RespondToPermissionOptions): Promise<void>;
222
+ _interrupt(id: string): Promise<InterruptResult>;
223
+ _answerQuestion(id: string, answers: Record<string, string[]>): Promise<void>;
224
+ }
225
+ /**
226
+ * A single agent session inside a sandbox. Created via
227
+ * `box.session(id)` — does not hit the network until a method is called.
228
+ */
229
+ declare class SandboxSession {
230
+ private readonly box;
231
+ /** Stable session id assigned by the sandbox runtime. */
232
+ readonly id: string;
233
+ /**
234
+ * @internal SDK-internal constructor — apps should call `box.session(id)`.
235
+ */
236
+ constructor(box: SandboxSessionHost, /** Stable session id assigned by the sandbox runtime. */
237
+
238
+ id: string);
239
+ /**
240
+ * Fetch the current session state from the sandbox. Includes status,
241
+ * model, prompt count, token usage if known, and timing metadata.
242
+ *
243
+ * Throws on transport error; returns `null` if the session id is not
244
+ * known to the sandbox (e.g. it ended and was reaped, or the id is
245
+ * invalid).
246
+ */
247
+ status(): Promise<SessionInfo | null>;
248
+ /**
249
+ * Stream events from this session as they arrive. With no `since`,
250
+ * starts at the live tail; with `since`, replays from that event id
251
+ * forward — useful for reconnect-after-disconnect flows.
252
+ *
253
+ * The async iterator terminates when the session reaches a terminal
254
+ * state (`completed`, `failed`, `cancelled`) and the corresponding
255
+ * terminal event has been yielded, OR when the caller's signal aborts.
256
+ */
257
+ events(opts?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
258
+ /**
259
+ * Await the session's terminal result. Polls status + drains events
260
+ * until the session reaches a terminal state, then returns the
261
+ * aggregated `PromptResult`.
262
+ *
263
+ * Use this to wait for a session that was started by another caller
264
+ * (e.g. `dispatchPrompt`).
265
+ */
266
+ result(): Promise<PromptResult>;
267
+ /**
268
+ * List persisted messages for this session, including in-flight assistant
269
+ * content when the runtime has flushed partial output.
270
+ */
271
+ messages(opts?: Omit<ListMessagesOptions, "sessionId">): Promise<SessionMessage[]>;
272
+ /**
273
+ * Continue this session with an additional prompt. Equivalent to
274
+ * `box.prompt(message, { ...opts, sessionId: this.id })` but reads
275
+ * naturally on a Session reference.
276
+ */
277
+ prompt(message: string | PromptInputPart[], opts?: PromptOptions): Promise<PromptResult>;
278
+ /**
279
+ * Send a structured message through the session message endpoint. Model and
280
+ * message identifiers are translated to the runtime's wire names by the SDK.
281
+ */
282
+ sendMessage(request: SendSessionMessageRequest, options?: SendSessionMessageOptions): Promise<SentSessionMessage>;
283
+ /**
284
+ * Abort the session's in-flight execution; the session and its messages
285
+ * are preserved (this does not delete the session). Void-returning alias
286
+ * of `interrupt()` — use `interrupt()` when you need to know whether an
287
+ * execution was actually running. Best-effort: an in-flight LLM call may
288
+ * still complete one more token before the abort takes effect. Idempotent —
289
+ * aborting a session with nothing in flight is a no-op.
290
+ */
291
+ cancel(): Promise<void>;
292
+ /** Delete this session and its persisted runtime state. */
293
+ delete(): Promise<void>;
294
+ /**
295
+ * Fork this session into a new queued session. The fork shares the
296
+ * parent workspace and copies conversation history up to `messageId`
297
+ * when supplied.
298
+ */
299
+ fork(opts?: SessionForkOptions): Promise<{
300
+ session: SandboxSession;
301
+ info: SessionInfo;
302
+ }>;
303
+ /**
304
+ * Drive this session's harness in INTERACTIVE mode: spawn its native TUI,
305
+ * stream the live framebuffer, and inject prompts as keystrokes. Distinct
306
+ * from the headless `prompt()`/`events()` surface above. Lazy — does not hit
307
+ * the network until a handle method is called.
308
+ */
309
+ interactive(): InteractiveSessionHandle;
310
+ /**
311
+ * Resolve a pending permission interaction the agent raised mid-turn,
312
+ * forwarding `allow`/`deny` to the blocked agent through the unified
313
+ * interaction channel. Throws if no matching permission is outstanding.
314
+ */
315
+ respondToPermission(permissionID: string, options: RespondToPermissionOptions): Promise<void>;
316
+ /**
317
+ * Interrupt the session's current execution without deleting it. Returns
318
+ * `{ cancelled: false }` when nothing was running — the no-op is reported
319
+ * explicitly rather than masked as success.
320
+ */
321
+ interrupt(): Promise<InterruptResult>;
322
+ /**
323
+ * Answer a question the agent asked via a question tool invocation. `answers`
324
+ * maps each question id to the selected option(s). Backend-agnostic: works
325
+ * with any backend that raises kind:"question" interactions — OpenCode
326
+ * natively, or CLI backends with `BackendConfig.interactions.question`
327
+ * enabled. Backends with no question support reject loudly.
328
+ */
329
+ answer(answers: Record<string, string[]>): Promise<void>;
330
+ }
331
+ //#endregion
332
+ //#region src/task-session.d.ts
333
+ /** @internal Operations implemented by `SandboxInstance`. */
334
+ interface SandboxTaskSessionHost extends SandboxSessionHost {
335
+ _taskSessionChanges(id: string): Promise<TaskSessionChanges>;
336
+ _taskSessionCommit(id: string, options?: CommitTaskSessionOptions): Promise<TaskSessionCommitResult>;
337
+ }
338
+ /** A background task session with isolated changeset operations. */
339
+ declare class SandboxTaskSession extends SandboxSession {
340
+ private readonly taskBox;
341
+ /** @internal Apps should call `box.taskSession(id)`. */
342
+ constructor(taskBox: SandboxTaskSessionHost, id: string);
343
+ /** Read the task's isolated file changes. */
344
+ changes(): Promise<TaskSessionChanges>;
345
+ /** Apply all or a selected subset of the task's isolated file changes. */
346
+ commit(options?: CommitTaskSessionOptions): Promise<TaskSessionCommitResult>;
347
+ }
348
+ //#endregion
349
+ //#region src/trace-exporter.d.ts
350
+ type JsonObject = {
351
+ [key: string]: JsonValue;
352
+ };
353
+ type TraceExportFormat = "tangle" | "otel-json";
354
+ type TraceExportBundle = SandboxTraceBundle | SandboxFleetTraceBundle;
355
+ interface TraceExportSink {
356
+ url: string;
357
+ headers?: Record<string, string>;
358
+ format?: TraceExportFormat;
359
+ serviceName?: string;
360
+ timeoutMs?: number;
361
+ fetch?: typeof fetch;
362
+ }
363
+ interface TraceExportResult {
364
+ status: number;
365
+ ok: boolean;
366
+ body: string;
367
+ }
368
+ declare function buildTraceExportPayload(bundle: TraceExportBundle, format?: TraceExportFormat, serviceName?: string): TraceExportBundle | JsonObject;
369
+ declare function exportTraceBundle(bundle: TraceExportBundle, sink: TraceExportSink): Promise<TraceExportResult>;
370
+ declare function toOtelJson(bundle: TraceExportBundle, serviceName?: string): JsonObject;
371
+ declare function otelTraceIdForTangleTrace(traceId: string): string;
372
+ //#endregion
373
+ //#region src/sandbox.d.ts
374
+ /**
375
+ * Result of registering a sidecar session mapping. `reprovisionRequired` is
376
+ * true when the server reports the mapped sidecar is stale (HTTP 410) and the
377
+ * caller must reprovision the sandbox before retrying.
378
+ */
379
+ interface SessionMappingResult {
380
+ success: boolean;
381
+ sessionId: string;
382
+ sidecarSessionId?: string;
383
+ reprovisionRequired: boolean;
384
+ code?: string;
385
+ }
386
+ /**
387
+ * HTTP client interface for making requests.
388
+ */
389
+ interface HttpClient {
390
+ fetch(path: string, options?: RequestInit, fetchOptions?: {
391
+ timeoutMs?: number;
392
+ }): Promise<Response>;
393
+ getApiKey?(): string | undefined;
394
+ }
395
+ /**
396
+ * Git capability for repository operations.
397
+ */
398
+ interface GitCapability {
399
+ /** Get repository status */
400
+ status(): Promise<GitStatus>;
401
+ /** Get commit log */
402
+ log(limit?: number): Promise<GitCommit[]>;
403
+ /** Get diff (optionally against a ref) */
404
+ diff(ref?: string): Promise<GitDiff>;
405
+ /** Stage files */
406
+ add(paths: string[]): Promise<void>;
407
+ /** Create a commit */
408
+ commit(message: string, options?: {
409
+ amend?: boolean;
410
+ }): Promise<GitCommit>;
411
+ /** Push to remote */
412
+ push(options?: {
413
+ force?: boolean;
414
+ }): Promise<void>;
415
+ /** Pull from remote */
416
+ pull(options?: {
417
+ rebase?: boolean;
418
+ }): Promise<void>;
419
+ /** List branches */
420
+ branches(): Promise<GitBranch[]>;
421
+ /** Checkout a branch or ref */
422
+ checkout(ref: string, options?: {
423
+ create?: boolean;
424
+ }): Promise<void>;
425
+ }
426
+ /**
427
+ * Tools capability for managing language runtimes via mise.
428
+ */
429
+ interface ToolsCapability {
430
+ /** Install a tool version */
431
+ install(tool: string, version: string): Promise<void>;
432
+ /** Activate a tool version for the session */
433
+ use(tool: string, version: string): Promise<void>;
434
+ /** List installed tools */
435
+ list(): Promise<InstalledTool[]>;
436
+ /** Run a command with a specific tool */
437
+ run(tool: string, args: string[]): Promise<ExecResult>;
438
+ }
439
+ /**
440
+ * A sandbox instance with methods for interaction.
441
+ */
442
+ declare class SandboxInstance {
443
+ private readonly client;
444
+ private info;
445
+ private readonly defaultRuntimeBackend?;
446
+ private readonly runtime;
447
+ constructor(client: HttpClient, info: SandboxInfo, defaultRuntimeBackend?: BackendConfig);
448
+ /** Unique sandbox identifier */
449
+ get id(): string;
450
+ /** Human-readable name */
451
+ get name(): string | undefined;
452
+ /** Current status */
453
+ get status(): SandboxStatus;
454
+ /** Connection information */
455
+ get connection(): SandboxConnection | undefined;
456
+ /** Custom metadata */
457
+ get metadata(): Record<string, unknown> | undefined;
458
+ /** When the sandbox was created */
459
+ get createdAt(): Date;
460
+ /** When the sandbox started running */
461
+ get startedAt(): Date | undefined;
462
+ /** Last activity timestamp */
463
+ get lastActivityAt(): Date | undefined;
464
+ /** When the sandbox will expire */
465
+ get expiresAt(): Date | undefined;
466
+ /** Error message if status is 'failed' */
467
+ get error(): string | undefined;
468
+ /** GPU lease attached during sandbox creation, when requested. */
469
+ get gpuLease(): GpuLease | undefined;
470
+ /** Web terminal URL for browser-based access */
471
+ get url(): string | undefined;
472
+ /**
473
+ * The 12-phase startup breakdown (storage_provision, host_select, edge_bind,
474
+ * edge_ready, egress_proxy, docker_pull/create/start, sidecar_boot,
475
+ * health_check, …) the platform emitted when this sandbox was provisioned.
476
+ *
477
+ * Present only on a freshly-created box; `null` for a box resolved by id or
478
+ * when the runtime did not report diagnostics. Use `.phases` for the
479
+ * operation-name → durationMs map.
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * const d = box.startupDiagnostics();
484
+ * if (d) console.log(`provision phases: ${JSON.stringify(d.phases)}`);
485
+ * ```
486
+ */
487
+ startupDiagnostics(): StartupDiagnostics | null;
488
+ /**
489
+ * Serialize to the public sandbox shape for logs and structured
490
+ * output. Secrets in `connection` (currently `authToken`) are
491
+ * redacted so that `JSON.stringify(box)` is safe to ship to log
492
+ * sinks. Use {@link toDebugJSON} when the bearer is required (e.g.
493
+ * one-off CLI commands that print credentials to the user).
494
+ */
495
+ toJSON(): SandboxInfo;
496
+ /**
497
+ * Serialize the sandbox **including secrets** when `includeSecrets`
498
+ * is true. The default behavior matches {@link toJSON} and redacts
499
+ * `connection.authToken`.
500
+ *
501
+ * Use only when the caller has an explicit need for the bearer
502
+ * (e.g. presenting it once to the human operator). Never wire the
503
+ * result of `toDebugJSON({ includeSecrets: true })` into a structured
504
+ * logger — the bearer will land in any log sink consuming that output.
505
+ */
506
+ toDebugJSON(options?: {
507
+ includeSecrets?: boolean;
508
+ }): SandboxInfo;
509
+ /**
510
+ * Create an advanced direct-runtime view of this sandbox.
511
+ *
512
+ * Runtime methods on the returned instance talk to the sandbox runtime
513
+ * directly using `connection.runtimeUrl` and `connection.authToken`.
514
+ * Lifecycle methods still go through the parent SDK client.
515
+ */
516
+ direct(): SandboxInstance;
517
+ /**
518
+ * Get an MCP endpoint for this sandbox. Returns a paste-able config
519
+ * for any MCP-capable host (Claude Desktop, Cursor, claude-code,
520
+ * codex, opencode, …) plus a freshly-minted, capability-scoped JWT.
521
+ *
522
+ * The token is short-lived and limited to the requested capabilities
523
+ * — it cannot be used against admin endpoints (`/exec`, `/files`,
524
+ * etc.) on the sandbox. Call `getMcpEndpoint()` again to rotate.
525
+ *
526
+ * Requires the sandbox to have been created with `capabilities`
527
+ * including the requested capability (default: `computer_use`).
528
+ *
529
+ * @example
530
+ * ```typescript
531
+ * const ep = await box.getMcpEndpoint();
532
+ * // Save ep.config to your IDE's mcp.json — that's it.
533
+ * fs.writeFileSync("mcp.json", JSON.stringify(ep.config, null, 2));
534
+ * ```
535
+ */
536
+ getMcpEndpoint(options?: {
537
+ capabilities?: ReadonlyArray<"computer_use">; /** Override server entry name (default: "tangle-sandbox"). */
538
+ serverName?: string; /** Token TTL in minutes (server clamps to its policy). */
539
+ ttlMinutes?: number;
540
+ }): Promise<SandboxMcpEndpoint>;
541
+ /**
542
+ * Refresh sandbox information from the server.
543
+ */
544
+ refresh(): Promise<void>;
545
+ /**
546
+ * Fetch fresh TEE attestation evidence for this sandbox.
547
+ *
548
+ * When `attestationNonce` is supplied, the runtime must return evidence bound
549
+ * to that challenge or fail closed if the selected TEE backend cannot support
550
+ * nonce-bound report data.
551
+ */
552
+ getTeeAttestation(options?: TeeAttestationOptions): Promise<TeeAttestationResponse>;
553
+ /**
554
+ * Fetch the TEE-bound public key used for sealed-secret encryption.
555
+ *
556
+ * The returned key includes an attestation report. Verify that report before
557
+ * encrypting secrets to the key.
558
+ */
559
+ getTeePublicKey(): Promise<TeePublicKeyResponse>;
560
+ /**
561
+ * Bootstrap a real-time collaboration session for a file.
562
+ * Returns the WebSocket URL and auth token needed to connect a
563
+ * Hocuspocus/Yjs provider for live multi-user editing.
564
+ *
565
+ * @example
566
+ * ```typescript
567
+ * const collab = await box.collaborate("src/index.ts")
568
+ * // Use collab.transport.websocketUrl + collab.transport.token
569
+ * // with @hocuspocus/provider to connect
570
+ * ```
571
+ */
572
+ collaborate(path: string, options?: {
573
+ access?: "read" | "write";
574
+ }): Promise<{
575
+ documentId: string;
576
+ transport: {
577
+ websocketUrl: string;
578
+ token: string;
579
+ expiresAt: number;
580
+ };
581
+ permissions: {
582
+ access: "read" | "write";
583
+ canSnapshot: boolean;
584
+ };
585
+ }>;
586
+ /**
587
+ * Refresh a collaboration token for an existing document session.
588
+ */
589
+ /**
590
+ * Refresh a collaboration token. Access level is preserved from the original
591
+ * token — cannot be escalated (read stays read, write stays write).
592
+ */
593
+ refreshCollaborationToken(documentId: string, currentToken: string): Promise<{
594
+ token: string;
595
+ expiresAt: number;
596
+ access: "read" | "write";
597
+ }>;
598
+ /**
599
+ * Get SSH credentials for connecting to the sandbox.
600
+ * Throws if SSH is not enabled or sandbox is not running.
601
+ */
602
+ ssh(): Promise<SSHCredentials>;
603
+ sshCommand(): Promise<SSHCommandDescriptor>;
604
+ /**
605
+ * Execute a command in the sandbox.
606
+ */
607
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
608
+ /**
609
+ * Run code in a persistent language kernel.
610
+ *
611
+ * Each `(sessionId, language)` pair gets its own long-lived kernel that
612
+ * keeps variable state across calls — like Jupyter cells. Without a
613
+ * `sessionId`, calls share a process-wide kernel per language.
614
+ *
615
+ * Returns typed results: stdout/stderr text plus a `results` array of
616
+ * structured outputs (matplotlib images as base64 PNG, pandas DataFrames,
617
+ * explicit `display(value)` calls as JSON/HTML, errors with traceback).
618
+ *
619
+ * @example Persistent Python session
620
+ * ```ts
621
+ * await box.runCode("python", "import pandas as pd; df = pd.DataFrame({'x': range(5)})", { sessionId: "s1" });
622
+ * const r = await box.runCode("python", "df.describe()", { sessionId: "s1" });
623
+ * // r.results[0] is a `dataframe` part with columns + rows from the describe()
624
+ * ```
625
+ *
626
+ * @example Matplotlib chart
627
+ * ```ts
628
+ * const r = await box.runCode("python",
629
+ * "import matplotlib.pyplot as plt; plt.plot([1,2,3,4]); plt.show()",
630
+ * { sessionId: "s1" });
631
+ * const png = r.results.find(p => p.type === "image");
632
+ * // png.data is a base64 PNG ready to render or hand back to an LLM
633
+ * ```
634
+ */
635
+ runCode(language: CodeLanguage, source: string, options?: CodeExecutionOptions): Promise<CodeExecutionResult>;
636
+ /**
637
+ * Read a file from the sandbox.
638
+ *
639
+ * @param path - Path to the file. Relative paths resolve from the workspace root.
640
+ * Absolute paths (e.g., `/tmp/output.json`) access the container filesystem directly.
641
+ * @returns File content as string
642
+ *
643
+ * @example
644
+ * ```typescript
645
+ * const content = await box.read("src/index.ts");
646
+ * const report = await box.read("/output/report.json");
647
+ * ```
648
+ */
649
+ read(path: string, options?: {
650
+ sessionId?: string;
651
+ }): Promise<string>;
652
+ /**
653
+ * Write content to a file in the sandbox.
654
+ *
655
+ * @param path - Path to the file. Relative paths resolve from the workspace root.
656
+ * Absolute paths (e.g., `/tmp/cases.json`) write to the container filesystem directly.
657
+ * @param content - Content to write
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * await box.write("src/fix.ts", "export const fix = () => {}");
662
+ * await box.write("/tmp/config.json", JSON.stringify(config));
663
+ * ```
664
+ */
665
+ write(path: string, content: string, options?: WriteFileOptions): Promise<FileWriteResult>;
666
+ /**
667
+ * Write many files in one paced, retry-aware batch — see
668
+ * {@link FileSystem.writeMany}. Each file goes through {@link write}; a small
669
+ * pace between writes keeps a large corpus under the file-write rate limit,
670
+ * and transient failures (quota / server / network / timeout) retry with
671
+ * exponential backoff (honoring a server `retryAfterMs`). Fail-loud on the
672
+ * first file that cannot be written after its retries.
673
+ */
674
+ writeMany(files: WriteManyFile[], options?: WriteManyOptions): Promise<void>;
675
+ /**
676
+ * Send a prompt to the agent running in the sandbox.
677
+ * Returns the complete response after the agent finishes.
678
+ */
679
+ prompt(message: string | PromptInputPart[], options?: PromptOptions): Promise<PromptResult>;
680
+ private logStreamCheckpoint;
681
+ /**
682
+ * Stream events from an agent prompt.
683
+ * Use this for real-time updates during agent execution.
684
+ *
685
+ * Guarantees a terminal event on every non-cancelled path: a clean run
686
+ * ends with the runtime's `result`/`done`; a failure (pre-stream HTTP
687
+ * error, mid-stream network drop, timeout, or reconnect exhaustion) is
688
+ * surfaced as an in-band `error` event followed by a synthetic `done`,
689
+ * never a thrown generator. Caller-initiated cancellation (aborting
690
+ * `options.signal`) ends the stream silently with no synthetic terminal.
691
+ *
692
+ * Automatically reconnects via the runtime event replay endpoint if the
693
+ * SSE stream drops before a terminal event (`result` or `done`) is
694
+ * received. Reconnection is transparent — replayed events that were
695
+ * already yielded (based on event ID tracking) are deduplicated.
696
+ */
697
+ streamPrompt(message: string | PromptInputPart[], options?: PromptOptions): AsyncGenerator<SandboxEvent>;
698
+ /**
699
+ * Inner prompt stream: opens the SSE connection and reconnects on silent
700
+ * drops. May throw (pre-stream HTTP error, timeout, reconnect exhausted);
701
+ * the public `streamPrompt` wrapper converts those throws into a terminal
702
+ * `error` + `done` so callers never see a thrown generator.
703
+ */
704
+ private streamPromptInner;
705
+ /**
706
+ * Stream sandbox lifecycle and activity events.
707
+ */
708
+ events(options?: EventStreamOptions): AsyncGenerator<SandboxEvent>;
709
+ trace(options?: SandboxTraceOptions): Promise<SandboxTraceBundle>;
710
+ intelligence(): Promise<NonNullable<SandboxTraceBundle["intelligence"]>>;
711
+ createIntelligenceReport(options?: {
712
+ mode?: "deterministic" | "agentic";
713
+ acknowledgeCost?: boolean;
714
+ budget?: IntelligenceReportBudget;
715
+ metadata?: Record<string, unknown>; /** Bound the analysis to a time window. */
716
+ window?: IntelligenceReportWindow; /** Compare this sandbox against a same-type baseline sandbox. */
717
+ compareTo?: IntelligenceReportCompareTo;
718
+ }): Promise<IntelligenceReport>;
719
+ createAgenticIntelligenceReport(options: {
720
+ maxUsd: number;
721
+ metadata?: Record<string, unknown>;
722
+ }): Promise<IntelligenceReport>;
723
+ exportTrace(sink: TraceExportSink): Promise<TraceExportResult>;
724
+ /**
725
+ * Stream real-time provisioning progress events.
726
+ *
727
+ * Connects to the SSE events stream and yields typed `ProvisionEvent` objects
728
+ * for each provisioning step. The generator completes when provisioning
729
+ * finishes (success or failure) and returns the terminal result.
730
+ *
731
+ * @returns AsyncGenerator of ProvisionEvent, with a ProvisionResult return value
732
+ *
733
+ * @example
734
+ * ```typescript
735
+ * const box = await client.create({ image: "ethereum" });
736
+ *
737
+ * const stream = box.watchProvisioning();
738
+ * for await (const event of stream) {
739
+ * console.log(`[${event.step}] ${event.status} — ${event.message}`);
740
+ * }
741
+ * // stream.return value contains the terminal result
742
+ * ```
743
+ */
744
+ watchProvisioning(options?: {
745
+ signal?: AbortSignal;
746
+ }): AsyncGenerator<ProvisionEvent, ProvisionResult | undefined>;
747
+ /**
748
+ * Run an agentic task until completion.
749
+ *
750
+ * Unlike prompt(), task() is designed for autonomous agent work:
751
+ * - The agent works until it completes the task or hits an error
752
+ * - Session state is maintained for context continuity
753
+ * - Token usage is aggregated across the execution
754
+ *
755
+ * Note: The agent (OpenCode/Claude) handles multi-turn execution internally.
756
+ * Most tasks complete in a single call. The maxTurns option is for edge cases
757
+ * where the agent explicitly signals it needs additional input.
758
+ *
759
+ * @param prompt - Task description for the agent
760
+ * @param options - Task options
761
+ * @returns Task result with response and execution metadata
762
+ */
763
+ task(prompt: string, options?: TaskOptions): Promise<TaskResult>;
764
+ /**
765
+ * Stream events from a task execution.
766
+ *
767
+ * Use this for real-time updates as the agent works:
768
+ * - Tool calls and results
769
+ * - Thinking/reasoning steps
770
+ * - File operations
771
+ * - Final response
772
+ *
773
+ * @param prompt - Task description for the agent
774
+ * @param options - Task options
775
+ */
776
+ streamTask(prompt: string, options?: TaskOptions): AsyncGenerator<SandboxEvent>;
777
+ /**
778
+ * Search for text patterns in files using ripgrep.
779
+ *
780
+ * This is a first-class code search capability, not a shell wrapper.
781
+ * Ripgrep is pre-installed in all managed sandboxes.
782
+ *
783
+ * @param pattern - Regular expression pattern to search for
784
+ * @param options - Search options
785
+ * @returns Async iterator of search matches
786
+ *
787
+ * @example Search for task-marker comments
788
+ * ```typescript
789
+ * for await (const match of box.search("TASK:", { glob: "**\/*.ts" })) {
790
+ * console.log(`${match.path}:${match.line}: ${match.text}`);
791
+ * }
792
+ * ```
793
+ *
794
+ * @example Collect all matches
795
+ * ```typescript
796
+ * const matches = [];
797
+ * for await (const match of box.search("function.*async")) {
798
+ * matches.push(match);
799
+ * }
800
+ * ```
801
+ */
802
+ search(pattern: string, options?: SearchOptions): AsyncGenerator<SearchMatch>;
803
+ /** Basic health reported by the runtime inside this sandbox. */
804
+ runtimeHealth(): Promise<SandboxRuntimeHealth>;
805
+ /** Return the runtime's current listening-port snapshot. */
806
+ ports(): Promise<SandboxPortBinding[]>;
807
+ /** Interactive terminal operations for this runtime. */
808
+ get terminals(): SandboxTerminalManager;
809
+ /** List profiles installed in this sandbox runtime. */
810
+ listProfiles(): Promise<SandboxRuntimeProfileList>;
811
+ /**
812
+ * Live whole-sandbox resource usage (memory + CPU) from the container cgroup.
813
+ *
814
+ * Returns `null` when cgroup stats are unavailable (non-Linux host). Memory is
815
+ * in MB; `memoryPeakMb` is the high-water mark since the sandbox started. CPU
816
+ * is a cumulative microsecond counter — sample twice and compute
817
+ * `cpu% = ΔcpuUsageUsec / (ΔsampledAtMs * 10)` for utilization.
818
+ *
819
+ * @example
820
+ * ```typescript
821
+ * const r = await box.resourceUsage();
822
+ * if (r) console.log(`peak ${r.memoryPeakMb} MB`);
823
+ * ```
824
+ */
825
+ resourceUsage(): Promise<SandboxResourceUsage | null>;
826
+ /**
827
+ * Git capability object for repository operations.
828
+ *
829
+ * All git operations are executed in the sandbox workspace.
830
+ *
831
+ * @example Check status and commit
832
+ * ```typescript
833
+ * const status = await box.git.status();
834
+ * if (status.isDirty) {
835
+ * await box.git.add(["."]);
836
+ * await box.git.commit("Update files");
837
+ * await box.git.push();
838
+ * }
839
+ * ```
840
+ */
841
+ get git(): GitCapability;
842
+ private gitStatus;
843
+ private gitLog;
844
+ private gitDiff;
845
+ private gitAdd;
846
+ private gitCommit;
847
+ private gitPush;
848
+ private gitPull;
849
+ private gitBranches;
850
+ private gitCheckout;
851
+ /**
852
+ * Tools capability object for managing language runtimes.
853
+ *
854
+ * Uses mise (polyglot version manager) to install and manage tools.
855
+ *
856
+ * @example Install and use Node.js
857
+ * ```typescript
858
+ * await box.tools.install("node", "22");
859
+ * await box.tools.use("node", "22");
860
+ * const list = await box.tools.list();
861
+ * ```
862
+ */
863
+ get tools(): ToolsCapability;
864
+ /**
865
+ * File system operations beyond basic read/write:
866
+ * - Binary upload/download
867
+ * - Directory ops (uploadDir, downloadDir, list, mkdir)
868
+ * - Metadata (stat, exists)
869
+ * - Progress reporting for large files
870
+ *
871
+ * @example Upload and download
872
+ * ```typescript
873
+ * await box.fs.upload("./model.bin", "/workspace/models/model.bin");
874
+ * await box.fs.download("/workspace/results.zip", "./results.zip");
875
+ * ```
876
+ *
877
+ * @example Directory operations
878
+ * ```typescript
879
+ * await box.fs.uploadDir("./project", "/workspace/project");
880
+ * const files = await box.fs.list("/workspace");
881
+ * ```
882
+ *
883
+ * @example File management
884
+ * ```typescript
885
+ * if (await box.fs.exists("/workspace/config.json")) {
886
+ * const info = await box.fs.stat("/workspace/config.json");
887
+ * console.log(`Size: ${info.size}`);
888
+ * }
889
+ * await box.fs.mkdir("/workspace/output", { recursive: true });
890
+ * await box.fs.delete("/workspace/temp", { recursive: true });
891
+ * ```
892
+ */
893
+ get fs(): FileSystem;
894
+ private fsReadBatch;
895
+ private fsTree;
896
+ private fsUpload;
897
+ private fsDownload;
898
+ private fsUploadDir;
899
+ private fsDownloadDir;
900
+ private fsList;
901
+ private fsStat;
902
+ private fsDelete;
903
+ private fsMkdir;
904
+ private fsExists;
905
+ /**
906
+ * Permissions manager for multi-user access control.
907
+ *
908
+ * @example List users
909
+ * ```typescript
910
+ * const users = await box.permissions.list();
911
+ * for (const user of users) {
912
+ * console.log(`${user.username}: ${user.role}`);
913
+ * }
914
+ * ```
915
+ *
916
+ * @example Add a developer
917
+ * ```typescript
918
+ * await box.permissions.add({
919
+ * userId: "user_abc",
920
+ * role: "developer",
921
+ * sshKeys: ["ssh-ed25519 AAAA..."],
922
+ * });
923
+ * ```
924
+ */
925
+ get permissions(): PermissionsManager;
926
+ private permissionsList;
927
+ private permissionsGet;
928
+ private permissionsAdd;
929
+ private permissionsUpdate;
930
+ private permissionsRemove;
931
+ private permissionsSetAccessPolicies;
932
+ private permissionsGetAccessPolicies;
933
+ private permissionsCheckAccess;
934
+ /**
935
+ * Backend manager for runtime agent configuration.
936
+ *
937
+ * @example Check backend status
938
+ * ```typescript
939
+ * const status = await box.backend.status();
940
+ * console.log(`Backend: ${status.type}, Status: ${status.status}`);
941
+ * ```
942
+ *
943
+ * @example Add MCP server at runtime
944
+ * ```typescript
945
+ * await box.backend.addMcp("web-search", {
946
+ * command: "npx",
947
+ * args: ["-y", "@anthropic/web-search"],
948
+ * });
949
+ * ```
950
+ *
951
+ * @example Read provider-native Cursor metadata
952
+ * ```typescript
953
+ * const models = await box.backend.models();
954
+ * const agents = await box.backend.agents({ limit: 20 });
955
+ * const runs = await box.backend.runs(agents.items[0].agentId);
956
+ * ```
957
+ */
958
+ get backend(): BackendManager;
959
+ private backendStatus;
960
+ private backendCapabilities;
961
+ private backendAddMcp;
962
+ private backendGetMcpStatus;
963
+ private backendUpdateConfig;
964
+ private backendControlData;
965
+ private backendControlAction;
966
+ private backendListSearch;
967
+ private backendAccount;
968
+ private backendModels;
969
+ private backendRepositories;
970
+ private backendAgents;
971
+ private backendAgent;
972
+ private backendArchiveAgent;
973
+ private backendUnarchiveAgent;
974
+ private backendDeleteAgent;
975
+ private backendRuns;
976
+ private backendRun;
977
+ private backendAgentMessages;
978
+ private backendArtifacts;
979
+ private backendDownloadArtifact;
980
+ private backendRestart;
981
+ /**
982
+ * Process manager for spawning and controlling processes.
983
+ *
984
+ * Provides non-blocking process execution with real-time log streaming,
985
+ * ideal for long-running tasks like ML training or dev servers.
986
+ *
987
+ * @example Non-blocking process
988
+ * ```typescript
989
+ * const proc = await box.process.spawn("python train.py", {
990
+ * cwd: "/workspace",
991
+ * env: { "CUDA_VISIBLE_DEVICES": "0" }
992
+ * });
993
+ *
994
+ * // Stream logs
995
+ * for await (const entry of proc.logs()) {
996
+ * console.log(`[${entry.type}] ${entry.data}`);
997
+ * }
998
+ *
999
+ * // Check status
1000
+ * const status = await proc.status();
1001
+ * console.log(`Running: ${status.running}`);
1002
+ *
1003
+ * // Kill if needed
1004
+ * await proc.kill();
1005
+ * ```
1006
+ *
1007
+ * @example Run Python code directly
1008
+ * ```typescript
1009
+ * const result = await box.process.runCode(`
1010
+ * import numpy as np
1011
+ * print(np.random.rand(10).mean())
1012
+ * `);
1013
+ * console.log(result.stdout);
1014
+ * ```
1015
+ */
1016
+ get process(): ProcessManager;
1017
+ private processSpawn;
1018
+ private processRunCode;
1019
+ private processList;
1020
+ private processGet;
1021
+ private createProcessHandle;
1022
+ private parseProcessLogStream;
1023
+ /**
1024
+ * Network manager for runtime network configuration.
1025
+ *
1026
+ * @example Update network restrictions
1027
+ * ```typescript
1028
+ * // Block all outbound traffic
1029
+ * await box.network.update({ blockOutbound: true });
1030
+ *
1031
+ * // Or switch to allowlist mode
1032
+ * await box.network.update({
1033
+ * allowList: ["192.168.1.0/24", "8.8.8.8/32"]
1034
+ * });
1035
+ * ```
1036
+ *
1037
+ * @example Expose ports dynamically
1038
+ * ```typescript
1039
+ * const url = await box.network.exposePort(8000);
1040
+ * console.log(`Service available at: ${url}`);
1041
+ * ```
1042
+ */
1043
+ get network(): NetworkManager;
1044
+ /**
1045
+ * Egress policy manager for controlling outbound internet access.
1046
+ *
1047
+ * @example Read current egress policy
1048
+ * ```typescript
1049
+ * const { policy, source } = await box.egress.get();
1050
+ * console.log(policy.mode, source);
1051
+ * ```
1052
+ *
1053
+ * @example Update egress policy at runtime
1054
+ * ```typescript
1055
+ * await box.egress.update({ mode: "strict", allowDomains: ["api.github.com"] });
1056
+ * ```
1057
+ */
1058
+ get egress(): EgressManager;
1059
+ /**
1060
+ * On-demand GPU leases attached to this sandbox.
1061
+ *
1062
+ * The base sandbox stays cheap; `attach` starts a temporary external GPU
1063
+ * worker with an explicit spend cap, and `detach` destroys it.
1064
+ */
1065
+ get gpu(): GpuLeaseManager;
1066
+ private networkUpdate;
1067
+ private networkExposePort;
1068
+ private networkListUrls;
1069
+ private networkGetConfig;
1070
+ private egressGet;
1071
+ private egressUpdate;
1072
+ private gpuAttach;
1073
+ private gpuList;
1074
+ private gpuExec;
1075
+ private gpuDetach;
1076
+ /**
1077
+ * Validate CIDR notation (IPv4 and IPv6)
1078
+ */
1079
+ private isValidCidr;
1080
+ /**
1081
+ * Preview link management.
1082
+ *
1083
+ * Create publicly accessible HTTPS URLs for TCP ports inside the sandbox.
1084
+ *
1085
+ * @example
1086
+ * ```typescript
1087
+ * const link = await box.previewLinks.create(3000);
1088
+ * console.log(link.url);
1089
+ *
1090
+ * const links = await box.previewLinks.list();
1091
+ * await box.previewLinks.remove(link.previewId);
1092
+ * ```
1093
+ */
1094
+ get previewLinks(): PreviewLinkManager;
1095
+ private previewLinkCreate;
1096
+ private previewLinkList;
1097
+ private previewLinkRemove;
1098
+ /**
1099
+ * Get information about the infrastructure driver for this sandbox.
1100
+ *
1101
+ * @example
1102
+ * ```typescript
1103
+ * const info = await box.getDriverInfo();
1104
+ * console.log(`Driver: ${info.type}, CRIU: ${info.capabilities.criu}`);
1105
+ * ```
1106
+ */
1107
+ getDriverInfo(): Promise<DriverInfo>;
1108
+ private toolsInstall;
1109
+ private toolsUse;
1110
+ private toolsList;
1111
+ private toolsRun;
1112
+ /**
1113
+ * Create a snapshot of the sandbox state.
1114
+ * Snapshots can be used to save workspace state for later restoration.
1115
+ *
1116
+ * If `storage` is provided (BYOS3), the snapshot is created directly
1117
+ * directly on the sandbox and uploaded to customer-provided S3 storage.
1118
+ *
1119
+ * @param options - Snapshot options (tags, paths, storage)
1120
+ * @returns Snapshot result with ID and metadata
1121
+ *
1122
+ * @example Standard snapshot (our storage)
1123
+ * ```typescript
1124
+ * const snap = await box.snapshot({
1125
+ * tags: ["v1.0", "stable"],
1126
+ * });
1127
+ * console.log(`Snapshot: ${snap.snapshotId}`);
1128
+ * ```
1129
+ *
1130
+ * @example BYOS3 snapshot (customer storage)
1131
+ * ```typescript
1132
+ * const snap = await box.snapshot({
1133
+ * tags: ["production"],
1134
+ * storage: {
1135
+ * type: "s3",
1136
+ * bucket: "my-snapshots",
1137
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
1138
+ * },
1139
+ * });
1140
+ * ```
1141
+ */
1142
+ snapshot(options?: SnapshotOptions): Promise<SnapshotResult>;
1143
+ /**
1144
+ * List all snapshots for this sandbox.
1145
+ *
1146
+ * If `storage` is provided (BYOS3), lists snapshots from customer-provided
1147
+ * S3 storage.
1148
+ *
1149
+ * @param storage - Optional customer storage config for BYOS3
1150
+ * @returns Array of snapshot metadata
1151
+ *
1152
+ * @example List from our storage
1153
+ * ```typescript
1154
+ * const snapshots = await box.listSnapshots();
1155
+ * for (const snap of snapshots) {
1156
+ * console.log(`${snap.snapshotId}: ${snap.createdAt}`);
1157
+ * }
1158
+ * ```
1159
+ *
1160
+ * @example List from customer S3 (BYOS3)
1161
+ * ```typescript
1162
+ * const snapshots = await box.listSnapshots({
1163
+ * type: "s3",
1164
+ * bucket: "my-snapshots",
1165
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
1166
+ * });
1167
+ * ```
1168
+ */
1169
+ listSnapshots(storage?: SnapshotOptions["storage"]): Promise<SnapshotInfo[]>;
1170
+ revertToSnapshot(snapshotId: string): Promise<SnapshotResult>;
1171
+ private waitForSnapshotRestore;
1172
+ private waitForSnapshotVisible;
1173
+ deleteSnapshot(snapshotId: string): Promise<void>;
1174
+ /**
1175
+ * Restore from the latest snapshot in customer-provided storage.
1176
+ * Only available when using BYOS3 (calls the runtime directly).
1177
+ *
1178
+ * @param storage - Customer storage config (required)
1179
+ * @param destinationPath - Optional path to restore to
1180
+ * @returns Snapshot info if restored, null if no snapshot found
1181
+ *
1182
+ * @example Restore from customer S3
1183
+ * ```typescript
1184
+ * const result = await box.restoreFromStorage({
1185
+ * type: "s3",
1186
+ * bucket: "my-snapshots",
1187
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
1188
+ * });
1189
+ *
1190
+ * if (result) {
1191
+ * console.log(`Restored from ${result.snapshotId}`);
1192
+ * } else {
1193
+ * console.log("No snapshot found");
1194
+ * }
1195
+ * ```
1196
+ */
1197
+ restoreFromStorage(storage: SnapshotOptions["storage"], options?: RestoreSnapshotOptions): Promise<SnapshotResult | null>;
1198
+ /**
1199
+ * @deprecated CRIU checkpoints were removed. To branch live memory into
1200
+ * copy-on-write children of a running sandbox use {@link branch}; for durable
1201
+ * filesystem state use {@link snapshot}. This method now throws.
1202
+ */
1203
+ checkpoint(): never;
1204
+ /**
1205
+ * @deprecated CRIU checkpoints were removed. List durable filesystem state
1206
+ * with {@link listSnapshots}. This method now throws.
1207
+ */
1208
+ listCheckpoints(): never;
1209
+ /**
1210
+ * @deprecated CRIU checkpoints were removed. This method now throws.
1211
+ */
1212
+ deleteCheckpoint(): never;
1213
+ /**
1214
+ * @deprecated Forking from a CRIU checkpoint was removed. Use {@link branch}
1215
+ * to fork a running sandbox's live memory into copy-on-write children, or
1216
+ * `client.create({ fromSnapshot })` to provision from durable disk state.
1217
+ * This method now throws.
1218
+ */
1219
+ fork(): never;
1220
+ /**
1221
+ * Branch this RUNNING sandbox into `count` copy-on-write children
1222
+ * (Morph Infinibranch parity). Unlike {@link fork} — which rehydrates one
1223
+ * sandbox from a CRIU checkpoint — branch forks the live VM's memory into
1224
+ * many children at once via Firecracker UFFD copy-on-write: the children
1225
+ * share the parent's clean pages instead of each copying full guest
1226
+ * memory. The parent stays running.
1227
+ *
1228
+ * @param count - Number of children to create (must be >= 1).
1229
+ * @param options - Per-child overrides.
1230
+ * @returns Exactly `count` new sandbox instances.
1231
+ *
1232
+ * @example
1233
+ * ```typescript
1234
+ * const [a, b, c] = await box.branch(3);
1235
+ * // a, b, c each share box's memory state at branch time
1236
+ * ```
1237
+ */
1238
+ branch(count: number, options?: BranchOptions): Promise<SandboxInstance[]>;
1239
+ /**
1240
+ * Speculative rollouts: branch this RUNNING sandbox into `n` copy-on-write
1241
+ * children, run the SAME agent turn in every child in parallel, and
1242
+ * optionally score each child by running `scorer.command` inside it (exit 0
1243
+ * passes; stdout is parsed as the numeric score — highest wins).
1244
+ *
1245
+ * Async-op shape: resolves as soon as the children exist (their turns are
1246
+ * still running); poll {@link getRollout} or use {@link waitForRollout} for
1247
+ * results. Children are first-class sandboxes the caller may promote or
1248
+ * delete — each occupies a concurrent-session quota slot like a create.
1249
+ *
1250
+ * @example
1251
+ * ```typescript
1252
+ * const started = await box.rollout({
1253
+ * n: 4,
1254
+ * parts: [{ type: "text", text: "make the failing test pass" }],
1255
+ * scorer: { type: "command", command: "npm test --silent && echo 1" },
1256
+ * });
1257
+ * const settled = await box.waitForRollout(started.rolloutId);
1258
+ * console.log(settled.winner, settled.results);
1259
+ * ```
1260
+ */
1261
+ rollout(options: RolloutOptions): Promise<RolloutStartResult>;
1262
+ /**
1263
+ * Poll a rollout's status and per-child results.
1264
+ *
1265
+ * Failed or timed-out children appear as result entries with `error` set —
1266
+ * partial results are never dropped. Rollout poll-state lives in
1267
+ * orchestrator RAM: after an orchestrator restart this returns 404 while
1268
+ * the children themselves survive as first-class sandboxes.
1269
+ */
1270
+ getRollout(rolloutId: string): Promise<Rollout>;
1271
+ /**
1272
+ * Poll {@link getRollout} until the rollout leaves `running`, then return
1273
+ * the terminal record — including `partial`/`failed` outcomes, whose
1274
+ * per-child `error` entries are results the caller inspects, not
1275
+ * exceptions. Throws {@link TimeoutError} on deadline or abort.
1276
+ */
1277
+ waitForRollout(rolloutId: string, options?: WaitForRolloutOptions): Promise<Rollout>;
1278
+ /**
1279
+ * Stop the sandbox (keeps state for resume).
1280
+ *
1281
+ * The stop response carries the orchestrator's per-phase stop breakdown
1282
+ * (`stop_metering` / `container_kill` / `stop_complete` /
1283
+ * `stop_unaccounted`); after this resolves, {@link startupDiagnostics}
1284
+ * returns it (replacing the create breakdown).
1285
+ */
1286
+ stop(): Promise<void>;
1287
+ /**
1288
+ * Resume a stopped sandbox.
1289
+ */
1290
+ resume(options?: ResumeOptions): Promise<void>;
1291
+ /**
1292
+ * Delete the sandbox permanently.
1293
+ *
1294
+ * The delete response carries the orchestrator's per-phase delete breakdown
1295
+ * (`container_remove` / `storage_binding_wait` / `cleanup_parallel` /
1296
+ * `delete_complete` / `delete_unaccounted`); after this resolves,
1297
+ * {@link startupDiagnostics} returns it for post-mortem reads on the
1298
+ * now-gone sandbox.
1299
+ */
1300
+ delete(): Promise<void>;
1301
+ /**
1302
+ * Read the per-phase lifecycle breakdown off a stop/resume/delete response
1303
+ * body. Never throws: diagnostics are measurement data — a body that fails
1304
+ * to parse (older API, empty body) must not fail the lifecycle call.
1305
+ */
1306
+ private readLifecycleDiagnostics;
1307
+ /**
1308
+ * keepAlive is intentionally unavailable until the API exposes timeout updates.
1309
+ * @param seconds - Reserved for future support
1310
+ */
1311
+ keepAlive(_seconds?: number): Promise<void>;
1312
+ /**
1313
+ * Upload a local directory to the sandbox via tar.
1314
+ * @param localPath - Local directory path to upload
1315
+ * @param remotePath - Destination path in the sandbox (default: /home/user)
1316
+ */
1317
+ uploadDirectory(localPath: string, remotePath?: string): Promise<void>;
1318
+ /**
1319
+ * Wait for the sandbox to reach a specific status.
1320
+ *
1321
+ * When `onProgress` is provided and the sandbox is still provisioning,
1322
+ * uses SSE events for real-time progress instead of polling. Falls back
1323
+ * to polling if the SSE connection fails or is unavailable.
1324
+ *
1325
+ * @example Basic wait
1326
+ * ```typescript
1327
+ * await box.waitFor("running");
1328
+ * ```
1329
+ *
1330
+ * @example Wait with progress tracking
1331
+ * ```typescript
1332
+ * await box.waitFor("running", {
1333
+ * onProgress: (event) => {
1334
+ * console.log(`[${event.step}] ${event.status} — ${event.message}`);
1335
+ * if (event.percent !== undefined) {
1336
+ * updateProgressBar(event.percent);
1337
+ * }
1338
+ * },
1339
+ * });
1340
+ * ```
1341
+ */
1342
+ waitFor(status: SandboxStatus | SandboxStatus[], options?: WaitForOptions): Promise<void>;
1343
+ /**
1344
+ * SSE-based wait implementation. Subscribes to provisioning events and
1345
+ * delivers progress callbacks while waiting for a target status.
1346
+ */
1347
+ private waitForWithSSE;
1348
+ private ensureRunning;
1349
+ private runtimeFetch;
1350
+ /**
1351
+ * Delegates to the shared `parseSSEStream` in `lib/sse-parser.ts`
1352
+ * — one canonical SSE implementation for the whole SDK. The
1353
+ * shared parser throws `AbortError` on cancellation (so consumers
1354
+ * can distinguish cancel from clean EOF), but agent/task streaming
1355
+ * callers of this method historically relied on a silent-return
1356
+ * abort: they check `options?.signal?.aborted` AFTER the loop and
1357
+ * decide whether to reconnect. The try/catch below preserves that
1358
+ * legacy contract by swallowing AbortError at the delegate layer.
1359
+ */
1360
+ private parseSSEStream;
1361
+ /**
1362
+ * Associate a session ID with a user ID so the Sandbox API can route
1363
+ * subsequent WebSocket connections to this sandbox.
1364
+ *
1365
+ * @param opts - Session and user identifiers
1366
+ *
1367
+ * @example
1368
+ * ```typescript
1369
+ * await box.registerSessionMapping({
1370
+ * sessionId: "sess_abc",
1371
+ * userId: "user_123",
1372
+ * });
1373
+ * ```
1374
+ */
1375
+ registerSessionMapping(opts: {
1376
+ sessionId: string;
1377
+ userId: string; /** The runtime (sidecar) session id this agent session routes to. */
1378
+ runtimeSessionId: string; /** Optional container id for direct routing. */
1379
+ sidecarId?: string; /** Optional projectRef so the server can detect a stale sidecar. */
1380
+ projectRef?: string;
1381
+ }): Promise<SessionMappingResult>;
1382
+ /**
1383
+ * Remove the sidecar session mapping for an agent session. Sandbox deletion
1384
+ * also cleans mappings, so this is only needed to release a mapping while the
1385
+ * sandbox stays alive.
1386
+ */
1387
+ unregisterSessionMapping(opts: {
1388
+ sessionId: string;
1389
+ userId: string;
1390
+ }): Promise<{
1391
+ success: boolean;
1392
+ sessionId: string;
1393
+ }>;
1394
+ private parseInfo;
1395
+ private sleep;
1396
+ /**
1397
+ * Get a session reference bound to this sandbox. Lazy: does not hit the
1398
+ * network until you call a method on the returned `SandboxSession`.
1399
+ * Use {@link sessions} to discover existing session ids.
1400
+ */
1401
+ session(id: string): SandboxSession;
1402
+ /** Create an agent session and return both its handle and initial metadata. */
1403
+ createSession(options: CreateSessionOptions): Promise<{
1404
+ session: SandboxSession;
1405
+ info: SessionInfo;
1406
+ }>;
1407
+ /** Delete an agent session by id. */
1408
+ deleteSession(id: string): Promise<void>;
1409
+ /** Get a lazy background-task session reference. */
1410
+ taskSession(id: string): SandboxTaskSession;
1411
+ /** Create a background task session. Dispatch work with `session.sendMessage()`. */
1412
+ createTaskSession(options: CreateTaskSessionOptions): Promise<{
1413
+ session: SandboxTaskSession;
1414
+ info: TaskSessionInfo;
1415
+ }>;
1416
+ /**
1417
+ * List sessions on this sandbox, optionally filtering by status. Returns
1418
+ * `SandboxSession` instances paired with their last-known
1419
+ * {@link SessionInfo} so callers can avoid an extra round-trip per
1420
+ * session for status.
1421
+ */
1422
+ sessions(opts?: SessionListOptions): Promise<Array<{
1423
+ session: SandboxSession;
1424
+ info: SessionInfo;
1425
+ }>>;
1426
+ /**
1427
+ * Dispatch a prompt and return immediately with the session id (Issue
1428
+ * #913 Gap 2). The sandbox keeps running the prompt after this call
1429
+ * returns; reconnect via `box.session(id).events()` or wait for
1430
+ * completion with `box.session(id).result()`.
1431
+ *
1432
+ * Idempotent on `opts.sessionId`: re-dispatching with the same id when
1433
+ * the session is already running is a lookup, not a re-create. This
1434
+ * lets queue retries and reconnect-after-Worker-restart be safe by
1435
+ * construction.
1436
+ */
1437
+ dispatchPrompt(message: string | PromptInputPart[], opts?: DispatchPromptOptions): Promise<DispatchedSession>;
1438
+ /**
1439
+ * List messages for a session, including in-flight assistant content
1440
+ * the agent is still streaming. Each entry's `metadata` carries the
1441
+ * durability marker — `status: "streaming" | "completed" | "interrupted"`,
1442
+ * `completed/interrupted` booleans, and the caller-supplied `turnId`
1443
+ * when one was set. See `SessionMessage` for the full contract.
1444
+ *
1445
+ * Polling this is the right way to detect "did the sidecar die mid-
1446
+ * turn?" — a SIGKILL leaves the assistant message with `status:
1447
+ * "streaming"` and no `completed`/`interrupted` marker; a graceful
1448
+ * abort stamps `interrupted: true` explicitly.
1449
+ */
1450
+ messages(opts: ListMessagesOptions): Promise<SessionMessage[]>;
1451
+ /** @internal — invoked by SandboxSession.sendMessage(). */
1452
+ _sessionSendMessage(id: string, request: SendSessionMessageRequest, options?: SendSessionMessageOptions): Promise<SentSessionMessage>;
1453
+ /** @internal — invoked by SandboxSession.delete(). */
1454
+ _sessionDelete(id: string): Promise<void>;
1455
+ /** @internal — invoked by SandboxTaskSession.changes(). */
1456
+ _taskSessionChanges(id: string): Promise<TaskSessionChanges>;
1457
+ /** @internal — invoked by SandboxTaskSession.commit(). */
1458
+ _taskSessionCommit(id: string, options?: CommitTaskSessionOptions): Promise<TaskSessionCommitResult>;
1459
+ _sessionFork(id: string, opts?: SessionForkOptions): Promise<SessionInfo>;
1460
+ /**
1461
+ * Look up a cached turn result by idempotency key. Returns the cached
1462
+ * payload if a turn with this `turnId` previously completed on the
1463
+ * given session; returns `null` if no such turn has finished yet
1464
+ * (either it never started, or it interrupted before completion).
1465
+ *
1466
+ * Call this before re-issuing a `streamPrompt` / `prompt` / `task`
1467
+ * that you might be retrying — a non-null result means the original
1468
+ * attempt finished and you can return that to your caller instead of
1469
+ * running the agent a second time. Only turns that reach the
1470
+ * `completed` terminal state are cached; interrupted turns are not.
1471
+ */
1472
+ findCompletedTurn(turnId: string, opts: {
1473
+ sessionId: string;
1474
+ }): Promise<CompletedTurnResult | null>;
1475
+ /**
1476
+ * Drive a detached turn forward by exactly one settle → poll → dispatch
1477
+ * pass and report where it stands. Built for tick-based callers —
1478
+ * Cloudflare Workflows steps, queue consumers, crons — that re-invoke
1479
+ * on their own schedule instead of holding a stream open. One
1480
+ * invocation never loops, never sleeps, and never keeps a connection
1481
+ * alive past the pass.
1482
+ *
1483
+ * The pass resolves to the first of:
1484
+ * 1. The completed-turn cache has `turnId` → `completed`, or `failed`
1485
+ * when the cached payload carries no text — that result is final,
1486
+ * so a retry cannot improve it.
1487
+ * 2. The session is queued/running → `running`, after enforcing
1488
+ * `wallCapMs`: a session past the cap is cancelled and reported
1489
+ * `failed`.
1490
+ * 3. The session is terminal without a cached turn → settle from the
1491
+ * session result; an unsuccessful result is `failed`.
1492
+ * 4. No session exists → dispatch fire-and-detach (idempotent on
1493
+ * `sessionId`, exactly like `dispatchPrompt`) → `running`.
1494
+ *
1495
+ * `failed` is always deterministic: re-invoking with the same ids
1496
+ * returns the same outcome rather than starting a second agent run, so
1497
+ * callers can treat it as terminal without their own retry bookkeeping.
1498
+ */
1499
+ driveTurn(message: string | PromptInputPart[], opts: DriveTurnOptions): Promise<TurnDriveResult>;
1500
+ /**
1501
+ * Mint a scoped, time-bounded JWT for direct browser access to this
1502
+ * sandbox (Issue #913 Gap 1). Authority is the caller's
1503
+ * `TANGLE_API_KEY` (sk-tan-*) — the Sandbox API mints the token;
1504
+ * signing secrets stay server-side.
1505
+ *
1506
+ * Use this to give a browser direct read access to the sandbox without
1507
+ * leaking the full bearer (`box.connection.authToken`). The returned
1508
+ * token verifies against the same sidecar middleware that already
1509
+ * gates ProductTokenIssuer-issued JWTs — no new sidecar surface.
1510
+ */
1511
+ mintScopedToken(opts: MintScopedTokenOptions): Promise<ScopedToken>;
1512
+ /** @internal — invoked by SandboxSession.status(). */
1513
+ _sessionStatus(id: string): Promise<SessionInfo | null>;
1514
+ /** @internal — invoked by SandboxSession.events(). */
1515
+ _sessionEvents(id: string, opts?: SessionEventStreamOptions): AsyncGenerator<SandboxEvent>;
1516
+ /** @internal — invoked by SandboxSession.result(). */
1517
+ _sessionResult(id: string): Promise<PromptResult>;
1518
+ /**
1519
+ * @internal — invoked by SandboxSession.cancel(). Void-returning alias of
1520
+ * `_interrupt`: both abort the in-flight execution via `POST /{id}/abort`
1521
+ * (the session and its messages are preserved). `cancel()` discards the
1522
+ * `cancelled` flag; callers that need to distinguish a real interruption
1523
+ * from a no-op should use `interrupt()`.
1524
+ */
1525
+ _sessionCancel(id: string): Promise<void>;
1526
+ /** @internal — invoked by InteractiveSessionHandle.start(). */
1527
+ _startInteractive(id: string, options: StartInteractiveOptions): Promise<InteractiveSessionInfo>;
1528
+ /** @internal — invoked by InteractiveSessionHandle.sendPrompt(). */
1529
+ _sendInteractivePrompt(id: string, prompt: string): Promise<void>;
1530
+ /** @internal — invoked by InteractiveSessionHandle.stop(). */
1531
+ _stopInteractive(id: string): Promise<void>;
1532
+ /** @internal — invoked by SandboxSession.respondToPermission(). */
1533
+ _respondToPermission(id: string, permissionID: string, options: RespondToPermissionOptions): Promise<void>;
1534
+ /** @internal — invoked by SandboxSession.interrupt(). */
1535
+ _interrupt(id: string): Promise<InterruptResult>;
1536
+ /**
1537
+ * @internal — invoked by SandboxSession.answer(). Resolves the session's
1538
+ * outstanding question interaction and posts the answer through the
1539
+ * interaction response route. The positional answer arrays map onto the
1540
+ * question's `answerSpec` fields in order.
1541
+ */
1542
+ _answerQuestion(id: string, answers: Record<string, string[]>): Promise<void>;
1543
+ }
1544
+ //#endregion
1545
+ export { SandboxMcpConfig as C, buildSandboxMcpConfig as D, buildControlPlaneMcpConfig as E, SANDBOX_MCP_SERVER_NAME as S, SandboxMcpServerEntry as T, RespondToPermissionOptions as _, TraceExportSink as a, BuildSandboxMcpConfigOptions as b, otelTraceIdForTangleTrace as c, SandboxSession as d, InteractiveAuthFile as f, InterruptResult as g, InteractiveSessionInfo as h, TraceExportResult as i, toOtelJson as l, InteractiveSessionHost as m, SandboxInstance as n, buildTraceExportPayload as o, InteractiveSessionHandle as p, TraceExportFormat as r, exportTraceBundle as s, HttpClient as t, SandboxTaskSession as u, StartInteractiveOptions as v, SandboxMcpEndpoint as w, CONTROL_PLANE_MCP_SERVER_NAME as x, BuildControlPlaneMcpConfigOptions as y };