@tangle-network/sandbox 0.0.3

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,3332 @@
1
+ //#region src/agent-profile.d.ts
2
+ /**
3
+ * Provider-neutral agent profile types for public SDK consumers.
4
+ *
5
+ * These model portable agent intent at the application boundary.
6
+ * Individual backends can translate this shape into their own native
7
+ * profile/configuration formats internally.
8
+ */
9
+ /**
10
+ * Permission policy value for a capability.
11
+ */
12
+ type AgentProfilePermissionValue = "allow" | "ask" | "deny";
13
+ /**
14
+ * Generic resource reference that can be resolved into a file or instruction.
15
+ */
16
+ type AgentProfileResourceRef = {
17
+ kind: "inline";
18
+ name: string;
19
+ content: string;
20
+ } | {
21
+ kind: "github";
22
+ path: string;
23
+ ref?: string;
24
+ name?: string;
25
+ };
26
+ /**
27
+ * Helper for creating typed inline resource refs.
28
+ */
29
+ declare function defineInlineResource(name: string, content: string): AgentProfileResourceRef;
30
+ /**
31
+ * Helper for creating typed GitHub-backed resource refs.
32
+ */
33
+ declare function defineGitHubResource(path: string, options?: {
34
+ ref?: string;
35
+ name?: string;
36
+ }): AgentProfileResourceRef;
37
+ /**
38
+ * Resource mounted into a backend workspace.
39
+ */
40
+ interface AgentProfileFileMount {
41
+ path: string;
42
+ resource: AgentProfileResourceRef;
43
+ executable?: boolean;
44
+ }
45
+ /**
46
+ * Provider-neutral resource bundle.
47
+ *
48
+ * Provider-specific concepts such as "skills" or "commands" should be modeled
49
+ * under `extensions` unless they become portable across multiple backends.
50
+ */
51
+ interface AgentProfileResources {
52
+ /**
53
+ * Generic files to materialize into the agent workspace before execution.
54
+ */
55
+ files?: AgentProfileFileMount[];
56
+ /**
57
+ * Additional instructions injected into the agent context.
58
+ */
59
+ instructions?: string | AgentProfileResourceRef;
60
+ }
61
+ /**
62
+ * Model selection hints for backends.
63
+ */
64
+ interface AgentProfileModelHints {
65
+ /**
66
+ * Preferred default model (format depends on backend, commonly "provider/model").
67
+ */
68
+ default?: string;
69
+ /**
70
+ * Preferred small/cheap model for lightweight work.
71
+ */
72
+ small?: string;
73
+ /**
74
+ * Optional provider preference hint.
75
+ */
76
+ provider?: string;
77
+ /**
78
+ * Backend-agnostic model metadata/hints.
79
+ */
80
+ metadata?: Record<string, unknown>;
81
+ }
82
+ /**
83
+ * Prompt shaping for an agent.
84
+ */
85
+ interface AgentProfilePrompt {
86
+ /**
87
+ * Full system prompt replacement, when supported.
88
+ */
89
+ systemPrompt?: string;
90
+ /**
91
+ * Additional instruction lines appended to the active prompt.
92
+ */
93
+ instructions?: string[];
94
+ }
95
+ /**
96
+ * Generic subagent definition.
97
+ */
98
+ interface AgentSubagentProfile {
99
+ description?: string;
100
+ prompt?: string;
101
+ model?: string;
102
+ tools?: Record<string, boolean>;
103
+ permissions?: Record<string, AgentProfilePermissionValue>;
104
+ maxSteps?: number;
105
+ metadata?: Record<string, unknown>;
106
+ }
107
+ /**
108
+ * Generic MCP server configuration.
109
+ */
110
+ interface AgentProfileMcpServer {
111
+ transport?: "stdio" | "sse" | "http";
112
+ command?: string;
113
+ args?: string[];
114
+ env?: Record<string, string>;
115
+ cwd?: string;
116
+ url?: string;
117
+ headers?: Record<string, string>;
118
+ enabled?: boolean;
119
+ metadata?: Record<string, unknown>;
120
+ }
121
+ /**
122
+ * Public provider-neutral agent profile contract.
123
+ */
124
+ interface AgentProfile {
125
+ name?: string;
126
+ description?: string;
127
+ version?: string;
128
+ tags?: string[];
129
+ prompt?: AgentProfilePrompt;
130
+ model?: AgentProfileModelHints;
131
+ permissions?: Record<string, AgentProfilePermissionValue>;
132
+ tools?: Record<string, boolean>;
133
+ mcp?: Record<string, AgentProfileMcpServer>;
134
+ subagents?: Record<string, AgentSubagentProfile>;
135
+ resources?: AgentProfileResources;
136
+ metadata?: Record<string, unknown>;
137
+ /**
138
+ * Non-portable backend-specific extensions.
139
+ *
140
+ * Use this only for features that cannot be expressed generically.
141
+ * SDK consumers should treat extension keys as backend namespaces.
142
+ */
143
+ extensions?: Record<string, Record<string, unknown> | undefined>;
144
+ }
145
+ /**
146
+ * Helper for declaring typed profiles in application code.
147
+ */
148
+ declare function defineAgentProfile<T extends AgentProfile>(profile: T): T;
149
+ /**
150
+ * Capabilities describing how a backend interprets AgentProfile.
151
+ */
152
+ interface AgentProfileCapabilities {
153
+ namedProfiles: boolean;
154
+ systemPrompt: boolean;
155
+ instructions: boolean;
156
+ tools: boolean;
157
+ permissions: boolean;
158
+ mcp: boolean;
159
+ subagents: boolean;
160
+ resources: {
161
+ files: boolean;
162
+ instructions: boolean;
163
+ };
164
+ runtimeUpdate: boolean;
165
+ validation: boolean;
166
+ /**
167
+ * Backend extension namespaces understood by this backend.
168
+ */
169
+ extensions?: string[];
170
+ }
171
+ /**
172
+ * Validation issue for a profile/backend pairing.
173
+ */
174
+ interface AgentProfileValidationIssue {
175
+ level: "error" | "warning" | "info";
176
+ code: string;
177
+ message: string;
178
+ path?: string;
179
+ }
180
+ /**
181
+ * Validation output for a provider adapter.
182
+ */
183
+ interface AgentProfileValidationResult {
184
+ ok: boolean;
185
+ issues: AgentProfileValidationIssue[];
186
+ normalizedProfile?: AgentProfile;
187
+ }
188
+ /**
189
+ * Merge two public AgentProfile values.
190
+ *
191
+ * Overlay fields win on conflicts. Array-like instruction sets are appended.
192
+ */
193
+ declare function mergeAgentProfiles(base: AgentProfile | undefined, overlay: AgentProfile | undefined): AgentProfile | undefined;
194
+ //#endregion
195
+ //#region src/types.d.ts
196
+ /**
197
+ * A development environment.
198
+ *
199
+ * Environments provide toolchains provisioned via Nix profiles mounted into
200
+ * a shared base container. The default "universal" environment includes all
201
+ * common toolchains (Node.js, Python, Rust, Go, etc.).
202
+ */
203
+ interface SandboxEnvironment {
204
+ /** Environment identifier (e.g., "universal") */
205
+ id: string;
206
+ /** Human-readable description */
207
+ description?: string;
208
+ /** Base template this environment extends */
209
+ base?: string;
210
+ /** Environment version tag */
211
+ version: string;
212
+ }
213
+ /**
214
+ * Git authentication configuration.
215
+ *
216
+ * @example HTTPS token
217
+ * ```typescript
218
+ * const auth: GitAuth = {
219
+ * token: process.env.GITHUB_TOKEN,
220
+ * };
221
+ * ```
222
+ */
223
+ interface GitAuth {
224
+ /** HTTPS auth token (e.g., GitHub PAT) */
225
+ token?: string;
226
+ }
227
+ /**
228
+ * Git repository configuration for cloning at sandbox creation.
229
+ *
230
+ * When provided, the repository is cloned during sandbox provisioning,
231
+ * before the sandbox becomes ready. This is more efficient than cloning
232
+ * after the sandbox starts.
233
+ *
234
+ * @example Basic clone
235
+ * ```typescript
236
+ * const git: GitConfig = {
237
+ * url: "https://github.com/user/repo.git",
238
+ * };
239
+ * ```
240
+ *
241
+ * @example Clone specific branch with auth
242
+ * ```typescript
243
+ * const git: GitConfig = {
244
+ * url: "https://github.com/user/private-repo.git",
245
+ * ref: "develop",
246
+ * auth: { token: process.env.GITHUB_TOKEN },
247
+ * };
248
+ * ```
249
+ *
250
+ * @example Sparse checkout for monorepo
251
+ * ```typescript
252
+ * const git: GitConfig = {
253
+ * url: "https://github.com/org/monorepo.git",
254
+ * sparse: ["packages/my-package", "shared"],
255
+ * depth: 1,
256
+ * };
257
+ * ```
258
+ */
259
+ interface GitConfig {
260
+ /** Repository URL (HTTPS or SSH) */
261
+ url: string;
262
+ /** Branch, tag, or commit SHA to checkout (default: default branch) */
263
+ ref?: string;
264
+ /** Shallow clone depth (default: 1 for faster clones) */
265
+ depth?: number;
266
+ /** Sparse checkout paths - only clone these directories */
267
+ sparse?: string[];
268
+ /** Authentication for private repositories */
269
+ auth?: GitAuth;
270
+ }
271
+ /**
272
+ * Tool version specifications for mise (polyglot version manager).
273
+ *
274
+ * Mise is pre-installed in all managed sandboxes and can install any
275
+ * language runtime or tool on demand. Specify versions here to have
276
+ * them pre-installed when the sandbox starts.
277
+ *
278
+ * @see https://mise.jdx.dev for supported tools
279
+ *
280
+ * @example Common tools
281
+ * ```typescript
282
+ * const tools: ToolsConfig = {
283
+ * node: "22", // Node.js 22.x (latest minor/patch)
284
+ * python: "3.12", // Python 3.12.x
285
+ * rust: "1.75", // Rust 1.75.x
286
+ * go: "1.22", // Go 1.22.x
287
+ * };
288
+ * ```
289
+ *
290
+ * @example Exact versions
291
+ * ```typescript
292
+ * const tools: ToolsConfig = {
293
+ * node: "20.11.0", // Exact version
294
+ * pnpm: "8.15.1",
295
+ * deno: "1.40",
296
+ * };
297
+ * ```
298
+ */
299
+ interface ToolsConfig {
300
+ /** Node.js version (e.g., "22", "20.11.0", "lts") */
301
+ node?: string;
302
+ /** Python version (e.g., "3.12", "3.11.7") */
303
+ python?: string;
304
+ /** Rust version (e.g., "1.75", "stable", "nightly") */
305
+ rust?: string;
306
+ /** Go version (e.g., "1.22", "1.21.6") */
307
+ go?: string;
308
+ /** Java version (e.g., "21", "17") */
309
+ java?: string;
310
+ /** Ruby version (e.g., "3.3", "3.2.2") */
311
+ ruby?: string;
312
+ /** Any other mise-supported tool and version */
313
+ [tool: string]: string | undefined;
314
+ }
315
+ /**
316
+ * Configuration for initializing the Sandbox client.
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * const client = new Sandbox({
321
+ * apiKey: "sk_sandbox_abc123",
322
+ * baseUrl: "https://your-sandbox-api.example.com",
323
+ * timeoutMs: 60000,
324
+ * });
325
+ * ```
326
+ */
327
+ interface SandboxClientConfig {
328
+ /** API key for authentication. Must start with `sk_sandbox_` */
329
+ apiKey: string;
330
+ /** Base URL for the Sandbox API */
331
+ baseUrl: string;
332
+ /** Request timeout in milliseconds. Defaults to 30000 (30 seconds) */
333
+ timeoutMs?: number;
334
+ }
335
+ /**
336
+ * Status of a sandbox instance.
337
+ *
338
+ * Lifecycle: `pending` -> `provisioning` -> `running` -> `stopped` -> (deleted)
339
+ *
340
+ * - `pending` - Sandbox created but not yet provisioning
341
+ * - `provisioning` - Container and resources being allocated
342
+ * - `running` - Sandbox is active and accepting commands
343
+ * - `stopped` - Sandbox is paused (can be resumed)
344
+ * - `failed` - Sandbox encountered an error
345
+ * - `expired` - Sandbox exceeded its lifetime limit
346
+ */
347
+ type SandboxStatus = "pending" | "provisioning" | "running" | "stopped" | "failed" | "expired";
348
+ /**
349
+ * Resource limits for a sandbox.
350
+ */
351
+ interface SandboxResources {
352
+ /** Number of CPU cores */
353
+ cpuCores?: number;
354
+ /** Memory in megabytes */
355
+ memoryMB?: number;
356
+ /** Disk space in gigabytes */
357
+ diskGB?: number;
358
+ }
359
+ /**
360
+ * Configuration for creating a new sandbox.
361
+ *
362
+ * Sandboxes can run in two modes:
363
+ * - **Managed** (default): Full-featured with agent, files, terminal, git, tools
364
+ * - **Bare**: Minimal container with only exec() and lifecycle methods
365
+ *
366
+ * @example Minimal sandbox (managed mode with defaults)
367
+ * ```typescript
368
+ * const box = await client.create();
369
+ * // Uses 'universal' image, managed mode, sane defaults
370
+ * ```
371
+ *
372
+ * @example Sandbox with pre-built image and git
373
+ * ```typescript
374
+ * const box = await client.create({
375
+ * image: "ethereum", // Stack name — tools provisioned via Nix profile
376
+ * git: {
377
+ * url: "https://github.com/user/dapp.git",
378
+ * ref: "main",
379
+ * },
380
+ * tools: { node: "22", python: "3.12" },
381
+ * });
382
+ * ```
383
+ *
384
+ * @example Sandbox with custom Docker image
385
+ * ```typescript
386
+ * const box = await client.create({
387
+ * image: "python:3.12-slim",
388
+ * git: { url: "https://github.com/user/ml-project.git" },
389
+ * tools: { python: "3.12" },
390
+ * });
391
+ * ```
392
+ *
393
+ * @example Bare sandbox (no managed runtime, just exec)
394
+ * ```typescript
395
+ * const box = await client.create({
396
+ * image: "ubuntu:24.04",
397
+ * bare: true,
398
+ * });
399
+ * // Only box.exec(), box.stop(), box.resume(), box.delete() available
400
+ * ```
401
+ *
402
+ * @example With BYOS3 storage for snapshots
403
+ * ```typescript
404
+ * const box = await client.create({
405
+ * image: "universal",
406
+ * storage: {
407
+ * type: "s3",
408
+ * bucket: "my-snapshots",
409
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
410
+ * },
411
+ * fromSnapshot: "snap_abc123",
412
+ * });
413
+ * ```
414
+ */
415
+ interface CreateSandboxOptions {
416
+ /**
417
+ * Development environment name.
418
+ *
419
+ * Environments provision toolchains via Nix profiles mounted into a
420
+ * shared base container. Use `client.environments.list()` to discover
421
+ * available environments.
422
+ *
423
+ * Takes precedence over `image` if both are specified.
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * environment: "universal" // Multi-language (default)
428
+ * ```
429
+ */
430
+ environment?: string;
431
+ /**
432
+ * Container image to use for the sandbox.
433
+ *
434
+ * For most use cases the default "universal" environment is sufficient.
435
+ * Use this field for custom images; the SDK runtime integration is applied
436
+ * automatically.
437
+ *
438
+ * **Resolution rules:**
439
+ * - Full image paths → Used as-is
440
+ * - Simple names without `/` or `:` → Treated as environment name
441
+ * (equivalent to setting `environment`)
442
+ *
443
+ * When neither `environment` nor `image` is set the SDK omits the
444
+ * field entirely and the server applies its own default.
445
+ */
446
+ image?: string;
447
+ /**
448
+ * Create a bare sandbox without the managed runtime.
449
+ *
450
+ * Bare sandboxes only have:
451
+ * - `exec()` - Execute commands
452
+ * - `stop()` / `resume()` - Lifecycle control
453
+ * - `delete()` - Cleanup
454
+ *
455
+ * Use bare mode when you need a clean container without the managed
456
+ * runtime integration.
457
+ *
458
+ * @default false
459
+ */
460
+ bare?: boolean;
461
+ /**
462
+ * Infrastructure driver selection.
463
+ * Controls how the sandbox is provisioned and isolated.
464
+ *
465
+ * @example Firecracker with CRIU
466
+ * ```typescript
467
+ * driver: { type: "firecracker", enableCriu: true }
468
+ * ```
469
+ */
470
+ driver?: DriverConfig;
471
+ /**
472
+ * AI coding agent backend configuration.
473
+ * Determines which agent runs inside the sandbox.
474
+ *
475
+ * @example OpenCode with profile
476
+ * ```typescript
477
+ * backend: { type: "opencode", profile: "with-web-search" }
478
+ * ```
479
+ */
480
+ backend?: BackendConfig;
481
+ /**
482
+ * Initial permissions and access control settings.
483
+ *
484
+ * @example Multi-user sandbox
485
+ * ```typescript
486
+ * permissions: {
487
+ * defaultRole: "developer",
488
+ * initialUsers: [{ userId: "user_xyz", role: "developer" }],
489
+ * }
490
+ * ```
491
+ */
492
+ permissions?: SandboxPermissionsConfig;
493
+ /**
494
+ * Network security configuration.
495
+ * Controls outbound network access from the sandbox.
496
+ *
497
+ * @example Block all outbound traffic
498
+ * ```typescript
499
+ * network: { blockOutbound: true }
500
+ * ```
501
+ *
502
+ * @example Allow only specific destinations
503
+ * ```typescript
504
+ * network: {
505
+ * allowList: ["8.8.8.8/32", "10.0.0.0/8"],
506
+ * ports: [8000, 8080], // Pre-expose ports
507
+ * }
508
+ * ```
509
+ */
510
+ network?: NetworkConfig;
511
+ /**
512
+ * Git repository to clone at sandbox creation.
513
+ *
514
+ * The repository is cloned during provisioning, before the sandbox
515
+ * becomes ready. This is more efficient than cloning after start.
516
+ *
517
+ * @example { url: "https://github.com/user/repo.git", ref: "main" }
518
+ */
519
+ git?: GitConfig;
520
+ /**
521
+ * Tool versions to pre-install via mise.
522
+ *
523
+ * Mise (polyglot version manager) is pre-installed in managed sandboxes.
524
+ * Specify versions here to have them ready when the sandbox starts.
525
+ *
526
+ * @example { node: "22", python: "3.12", rust: "1.75" }
527
+ */
528
+ tools?: ToolsConfig;
529
+ /** Human-readable name for the sandbox */
530
+ name?: string;
531
+ /** Resource limits (CPU cores, memory, disk) */
532
+ resources?: SandboxResources;
533
+ /** Environment variables injected into the sandbox */
534
+ env?: Record<string, string>;
535
+ /**
536
+ * Maximum lifetime in seconds.
537
+ * Sandbox is automatically deleted after this time.
538
+ * @default 3600 (1 hour)
539
+ */
540
+ maxLifetimeSeconds?: number;
541
+ /**
542
+ * Idle timeout in seconds.
543
+ * Sandbox is suspended after this period of inactivity.
544
+ * @default 900 (15 minutes)
545
+ */
546
+ idleTimeoutSeconds?: number;
547
+ /**
548
+ * Enable SSH access to the sandbox.
549
+ * Use `sandbox.ssh()` to get connection credentials.
550
+ * @default false
551
+ */
552
+ sshEnabled?: boolean;
553
+ /** Custom SSH public key for access (optional) */
554
+ sshPublicKey?: string;
555
+ /**
556
+ * Enable web terminal access.
557
+ * Provides a browser-based terminal via websocket.
558
+ * @default false
559
+ */
560
+ webTerminalEnabled?: boolean;
561
+ /**
562
+ * Customer-provided S3-compatible storage for snapshots (BYOS3).
563
+ *
564
+ * When configured, snapshots are stored in your own bucket
565
+ * instead of Tangle's managed storage.
566
+ */
567
+ storage?: StorageConfig;
568
+ /** Snapshot ID to restore from when creating the sandbox */
569
+ fromSnapshot?: string;
570
+ /** Source sandbox ID that owns the snapshot (required when fromSnapshot is set) */
571
+ fromSandboxId?: string;
572
+ /**
573
+ * Names of secrets to inject as environment variables.
574
+ *
575
+ * Secrets must be created via `client.secrets.create()` before use.
576
+ * They are injected as environment variables with the same name.
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * // First, create the secrets
581
+ * await client.secrets.create("HF_TOKEN", "hf_xxx");
582
+ * await client.secrets.create("AWS_ACCESS_KEY", "AKIA...");
583
+ *
584
+ * // Then use them in a sandbox
585
+ * const box = await client.create({
586
+ * secrets: ["HF_TOKEN", "AWS_ACCESS_KEY"],
587
+ * });
588
+ *
589
+ * // Secrets are available as env vars
590
+ * const result = await box.exec("echo $HF_TOKEN");
591
+ * ```
592
+ */
593
+ secrets?: string[];
594
+ /** Custom metadata to store with the sandbox */
595
+ metadata?: Record<string, unknown>;
596
+ /**
597
+ * Share this sandbox with a team. The caller must be an active
598
+ * member of the team — the API rejects requests from non-members
599
+ * before provisioning. When omitted the sandbox is personal
600
+ * (accessible only to the creator).
601
+ */
602
+ teamId?: string;
603
+ }
604
+ /**
605
+ * SSH connection credentials.
606
+ */
607
+ interface SSHCredentials {
608
+ /** SSH server hostname */
609
+ host: string;
610
+ /** SSH server port */
611
+ port: number;
612
+ /** Username for SSH authentication */
613
+ username: string;
614
+ }
615
+ /**
616
+ * Connection information for a sandbox.
617
+ *
618
+ * Most code should use `SandboxInstance` methods (`exec`, `prompt`, etc.).
619
+ * The raw `runtimeUrl` and `authToken` are surfaced only for advanced
620
+ * lower-level use cases such as custom protocol clients.
621
+ */
622
+ interface SandboxConnection {
623
+ /** Sandbox runtime API URL for programmatic access */
624
+ runtimeUrl?: string;
625
+ /** Access token for authenticating directly with the runtime (Bearer token) */
626
+ authToken?: string;
627
+ /** Token expiration timestamp (ISO 8601). Refresh before this time. */
628
+ authTokenExpiresAt?: string;
629
+ /** SSH connection info if `sshEnabled` was true during creation */
630
+ ssh?: SSHCredentials;
631
+ /** Web terminal URL if `webTerminalEnabled` was true during creation */
632
+ webTerminalUrl?: string;
633
+ }
634
+ /**
635
+ * Full sandbox information returned from the API.
636
+ */
637
+ interface SandboxInfo {
638
+ /** Unique sandbox identifier */
639
+ id: string;
640
+ /** Human-readable name */
641
+ name?: string;
642
+ /** Current status */
643
+ status: SandboxStatus;
644
+ /** Connection information */
645
+ connection?: SandboxConnection;
646
+ /** Custom metadata */
647
+ metadata?: Record<string, unknown>;
648
+ /** When the sandbox was created */
649
+ createdAt: Date;
650
+ /** When the sandbox started running */
651
+ startedAt?: Date;
652
+ /** Last activity timestamp */
653
+ lastActivityAt?: Date;
654
+ /** When the sandbox will expire */
655
+ expiresAt?: Date;
656
+ /** Error message if status is 'failed' */
657
+ error?: string;
658
+ }
659
+ /**
660
+ * Options for listing sandboxes.
661
+ */
662
+ interface ListSandboxOptions {
663
+ /** Filter by status */
664
+ status?: SandboxStatus | SandboxStatus[];
665
+ /** Maximum number of results */
666
+ limit?: number;
667
+ /** Offset for pagination */
668
+ offset?: number;
669
+ }
670
+ /**
671
+ * Result of executing a command.
672
+ */
673
+ interface ExecResult {
674
+ /** Exit code (0 = success) */
675
+ exitCode: number;
676
+ /** Standard output */
677
+ stdout: string;
678
+ /** Standard error */
679
+ stderr: string;
680
+ }
681
+ /**
682
+ * Options for executing a command.
683
+ */
684
+ interface ExecOptions {
685
+ /** Working directory for the command */
686
+ cwd?: string;
687
+ /** Environment variables */
688
+ env?: Record<string, string>;
689
+ /** Timeout in milliseconds */
690
+ timeoutMs?: number;
691
+ }
692
+ /**
693
+ * Options for code search.
694
+ *
695
+ * @example Search TypeScript files
696
+ * ```typescript
697
+ * const matches = await box.search("TODO", {
698
+ * glob: "**\/*.ts",
699
+ * maxResults: 100,
700
+ * });
701
+ * ```
702
+ */
703
+ interface SearchOptions {
704
+ /** Glob pattern to filter files (e.g., "**\/*.ts") */
705
+ glob?: string;
706
+ /** Directory to search in (default: workspace root) */
707
+ cwd?: string;
708
+ /** Maximum number of results */
709
+ maxResults?: number;
710
+ /** Case-insensitive search */
711
+ ignoreCase?: boolean;
712
+ /** Include line context (lines before/after match) */
713
+ context?: number;
714
+ }
715
+ /**
716
+ * A single search match from ripgrep.
717
+ */
718
+ interface SearchMatch {
719
+ /** File path relative to search root */
720
+ path: string;
721
+ /** Line number (1-indexed) */
722
+ line: number;
723
+ /** Column number (1-indexed) */
724
+ column: number;
725
+ /** The matching line text */
726
+ text: string;
727
+ /** Context lines before the match */
728
+ before?: string[];
729
+ /** Context lines after the match */
730
+ after?: string[];
731
+ }
732
+ /**
733
+ * Git repository status.
734
+ */
735
+ interface GitStatus {
736
+ /** Current branch name */
737
+ branch: string;
738
+ /** Commit SHA of HEAD */
739
+ head: string;
740
+ /** Whether there are uncommitted changes */
741
+ isDirty: boolean;
742
+ /** Number of commits ahead of upstream */
743
+ ahead: number;
744
+ /** Number of commits behind upstream */
745
+ behind: number;
746
+ /** Staged files */
747
+ staged: string[];
748
+ /** Modified but unstaged files */
749
+ modified: string[];
750
+ /** Untracked files */
751
+ untracked: string[];
752
+ }
753
+ /**
754
+ * Git commit information.
755
+ */
756
+ interface GitCommit {
757
+ /** Commit SHA */
758
+ sha: string;
759
+ /** Short SHA (7 chars) */
760
+ shortSha: string;
761
+ /** Commit message */
762
+ message: string;
763
+ /** Author name */
764
+ author: string;
765
+ /** Author email */
766
+ email: string;
767
+ /** Commit date */
768
+ date: Date;
769
+ }
770
+ /**
771
+ * Git branch information.
772
+ */
773
+ interface GitBranch {
774
+ /** Branch name */
775
+ name: string;
776
+ /** Whether this is the current branch */
777
+ current: boolean;
778
+ /** Upstream branch (if tracking) */
779
+ upstream?: string;
780
+ /** Latest commit SHA */
781
+ commit: string;
782
+ }
783
+ /**
784
+ * Git diff information.
785
+ */
786
+ interface GitDiff {
787
+ /** Files changed */
788
+ files: Array<{
789
+ path: string;
790
+ status: "added" | "modified" | "deleted" | "renamed";
791
+ additions: number;
792
+ deletions: number;
793
+ }>;
794
+ /** Total additions */
795
+ additions: number;
796
+ /** Total deletions */
797
+ deletions: number;
798
+ /** Raw diff output */
799
+ raw: string;
800
+ }
801
+ /**
802
+ * Information about an installed tool.
803
+ */
804
+ interface InstalledTool {
805
+ /** Tool name (e.g., "node", "python") */
806
+ name: string;
807
+ /** Installed version */
808
+ version: string;
809
+ /** Path to the tool binary */
810
+ path: string;
811
+ /** Whether this is the active/default version */
812
+ active: boolean;
813
+ }
814
+ /**
815
+ * Result of an agent prompt.
816
+ */
817
+ interface PromptResult {
818
+ /** Whether the prompt completed successfully */
819
+ success: boolean;
820
+ /** Agent's response text */
821
+ response?: string;
822
+ /** Error message if failed */
823
+ error?: string;
824
+ /** Trace ID for debugging */
825
+ traceId?: string;
826
+ /** Duration in milliseconds */
827
+ durationMs: number;
828
+ /** Token usage */
829
+ usage?: {
830
+ inputTokens: number;
831
+ outputTokens: number;
832
+ };
833
+ }
834
+ type PromptInputPart = {
835
+ type: "text";
836
+ text: string;
837
+ } | {
838
+ type: "image";
839
+ filename?: string;
840
+ mediaType?: string;
841
+ url?: string;
842
+ path?: string;
843
+ } | {
844
+ type: "file";
845
+ filename?: string;
846
+ mediaType?: string;
847
+ url?: string;
848
+ path?: string;
849
+ content?: string;
850
+ };
851
+ /**
852
+ * Options for sending a prompt.
853
+ */
854
+ interface PromptOptions {
855
+ /** Session ID for conversation continuity */
856
+ sessionId?: string;
857
+ /** Model to use (format: provider/model, e.g., anthropic/claude-sonnet-4-20250514) */
858
+ model?: string;
859
+ /**
860
+ * Per-run backend override.
861
+ *
862
+ * Use `backend.profile` with a string for a named profile or a provider-neutral
863
+ * `AgentProfile` object for inline profile configuration.
864
+ */
865
+ backend?: Partial<BackendConfig>;
866
+ /** Timeout in milliseconds */
867
+ timeoutMs?: number;
868
+ /** Additional context */
869
+ context?: Record<string, unknown>;
870
+ /** AbortSignal for cancellation */
871
+ signal?: AbortSignal;
872
+ }
873
+ /**
874
+ * SSE event from sandbox streaming.
875
+ */
876
+ interface SandboxEvent {
877
+ /** Event type */
878
+ type: string;
879
+ /** Event data */
880
+ data: Record<string, unknown>;
881
+ /** Event ID */
882
+ id?: string;
883
+ }
884
+ /**
885
+ * Options for event streaming.
886
+ */
887
+ interface EventStreamOptions {
888
+ /** AbortSignal for cancellation */
889
+ signal?: AbortSignal;
890
+ /** Filter to specific event types */
891
+ eventTypes?: string[];
892
+ }
893
+ /**
894
+ * Provisioning step identifier for progress reporting.
895
+ */
896
+ type ProvisionStep = "match" | "networking" | "git" | "host-select" | "storage" | "image-check" | "image-pull" | "image-build" | "container-create" | "container-start" | "health-check" | "runtime-ready" | "workspace";
897
+ /**
898
+ * Status of a provisioning step.
899
+ */
900
+ type ProvisionStatus = "started" | "progress" | "completed" | "skipped" | "error";
901
+ /**
902
+ * Provisioning progress event emitted during sandbox creation.
903
+ *
904
+ * Subscribe via `box.watchProvisioning()` or pass `onProgress` to `box.waitFor()`.
905
+ *
906
+ * @example
907
+ * ```typescript
908
+ * for await (const event of box.watchProvisioning()) {
909
+ * console.log(`[${event.step}] ${event.status} — ${event.message}`);
910
+ * if (event.percent !== undefined) {
911
+ * updateProgressBar(event.percent);
912
+ * }
913
+ * }
914
+ * ```
915
+ */
916
+ interface ProvisionEvent {
917
+ /** The provisioning step (e.g., "image-pull", "container-start") */
918
+ step: ProvisionStep;
919
+ /** Status of this step */
920
+ status: ProvisionStatus;
921
+ /** Human-readable progress message */
922
+ message?: string;
923
+ /** Overall progress percentage (0-100) */
924
+ percent?: number;
925
+ /** Additional detail for the step */
926
+ detail?: Record<string, unknown>;
927
+ /** ISO timestamp */
928
+ timestamp: string;
929
+ }
930
+ /**
931
+ * Terminal provisioning event indicating success or failure.
932
+ */
933
+ type ProvisionResult = {
934
+ type: "complete";
935
+ containerId: string;
936
+ timestamp: string;
937
+ } | {
938
+ type: "failed";
939
+ error: string;
940
+ timestamp: string;
941
+ };
942
+ /**
943
+ * Options for `waitFor()`.
944
+ */
945
+ interface WaitForOptions {
946
+ /** Timeout in milliseconds (default: 120000) */
947
+ timeoutMs?: number;
948
+ /** Poll interval in milliseconds when SSE is unavailable (default: 2000) */
949
+ pollIntervalMs?: number;
950
+ /** AbortSignal for cancellation */
951
+ signal?: AbortSignal;
952
+ /**
953
+ * Callback invoked with real-time provisioning progress events.
954
+ * When provided and the sandbox is provisioning, `waitFor()` uses SSE
955
+ * instead of polling for faster, more granular updates.
956
+ */
957
+ onProgress?: (event: ProvisionEvent) => void;
958
+ }
959
+ /**
960
+ * Usage information for the account.
961
+ */
962
+ interface UsageInfo {
963
+ /** Total compute minutes used today */
964
+ computeMinutes: number;
965
+ /** Number of currently active sandboxes */
966
+ activeSandboxes: number;
967
+ /** Total sandboxes created (lifetime) */
968
+ totalSandboxes: number;
969
+ /** Period start date (current day UTC) */
970
+ periodStart: Date;
971
+ /** Period end date (next day UTC) */
972
+ periodEnd: Date;
973
+ }
974
+ /**
975
+ * Subscription and billing information for the account.
976
+ */
977
+ interface SubscriptionInfo {
978
+ /** Current plan tier */
979
+ plan: "free" | "pro" | "enterprise";
980
+ /** Subscription status */
981
+ status: "active" | "canceled" | "past_due";
982
+ /**
983
+ * Available credit balance in USD.
984
+ *
985
+ * **May be negative** for overage-enabled plans (pro/enterprise):
986
+ * overage charges can push the stored balance below zero. Free-tier
987
+ * plans cap at 0 at the charge path (`capAtZero: true`).
988
+ *
989
+ * Freshness semantics differ by deployment backend: the
990
+ * Cloudflare/D1 backend includes real-time projected cost of
991
+ * currently-running sandboxes; the Node/Redis backend returns the
992
+ * last-deducted stored balance and reflects running sandboxes only
993
+ * once their usage is recorded. Consumers should not assume this
994
+ * value is non-negative — use `>= 0` checks rather than truthiness.
995
+ */
996
+ creditsAvailableUsd: number;
997
+ /** Credits used in USD */
998
+ creditsUsedUsd: number;
999
+ /** Monthly included balance in USD */
1000
+ monthlyBalanceUsd: number;
1001
+ /** Max concurrent sandboxes (0 = unlimited) */
1002
+ maxConcurrentSandboxes: number;
1003
+ /** Whether overage billing is allowed */
1004
+ overageAllowed: boolean;
1005
+ /** Resource limits */
1006
+ limits: {
1007
+ maxCpuCores: number;
1008
+ maxRamGB: number;
1009
+ maxStorageGB: number;
1010
+ };
1011
+ /** Current billing period end (epoch ms) */
1012
+ currentPeriodEnd: number;
1013
+ }
1014
+ /**
1015
+ * S3-compatible storage provider configuration (BYOS3 - Bring Your Own S3).
1016
+ *
1017
+ * Allows customers to store snapshots in their own S3-compatible storage.
1018
+ * Supports AWS S3, Google Cloud Storage (GCS), and Cloudflare R2.
1019
+ *
1020
+ * @example AWS S3
1021
+ * ```typescript
1022
+ * const storage: StorageConfig = {
1023
+ * type: "s3",
1024
+ * bucket: "my-snapshots",
1025
+ * region: "us-east-1",
1026
+ * credentials: {
1027
+ * accessKeyId: "AKIA...",
1028
+ * secretAccessKey: "...",
1029
+ * },
1030
+ * };
1031
+ * ```
1032
+ *
1033
+ * @example Cloudflare R2
1034
+ * ```typescript
1035
+ * const storage: StorageConfig = {
1036
+ * type: "r2",
1037
+ * bucket: "my-snapshots",
1038
+ * endpoint: "https://<account>.r2.cloudflarestorage.com",
1039
+ * credentials: {
1040
+ * accessKeyId: "...",
1041
+ * secretAccessKey: "...",
1042
+ * },
1043
+ * };
1044
+ * ```
1045
+ *
1046
+ * @example Google Cloud Storage
1047
+ * ```typescript
1048
+ * const storage: StorageConfig = {
1049
+ * type: "gcs",
1050
+ * bucket: "my-snapshots",
1051
+ * credentials: {
1052
+ * accessKeyId: "...", // HMAC key
1053
+ * secretAccessKey: "...",
1054
+ * },
1055
+ * };
1056
+ * ```
1057
+ */
1058
+ interface StorageConfig {
1059
+ /** Storage provider type */
1060
+ type: "s3" | "gcs" | "r2";
1061
+ /** Bucket name */
1062
+ bucket: string;
1063
+ /** Custom endpoint URL (required for R2, optional for S3/GCS) */
1064
+ endpoint?: string;
1065
+ /** Region (e.g., us-east-1) */
1066
+ region?: string;
1067
+ /** Access credentials */
1068
+ credentials: {
1069
+ accessKeyId: string;
1070
+ secretAccessKey: string;
1071
+ };
1072
+ /** Path prefix within bucket (default: sandbox-snapshots/) */
1073
+ prefix?: string;
1074
+ }
1075
+ /**
1076
+ * Options for running a multi-turn task.
1077
+ */
1078
+ interface TaskOptions extends PromptOptions {
1079
+ /** Maximum number of agent turns (default: 10, 0 = unlimited) */
1080
+ maxTurns?: number;
1081
+ }
1082
+ /**
1083
+ * Result of a multi-turn task execution.
1084
+ */
1085
+ interface TaskResult extends PromptResult {
1086
+ /** Number of agent turns used */
1087
+ turnsUsed: number;
1088
+ /** Session ID for the task (can be used to continue) */
1089
+ sessionId: string;
1090
+ }
1091
+ /**
1092
+ * Options for creating a snapshot.
1093
+ */
1094
+ interface SnapshotOptions {
1095
+ /** Tags to apply to the snapshot */
1096
+ tags?: string[];
1097
+ /** Specific paths to include (default: entire workspace) */
1098
+ paths?: string[];
1099
+ /** Customer-provided storage for BYOS3 (calls the runtime directly) */
1100
+ storage?: StorageConfig;
1101
+ }
1102
+ /**
1103
+ * Result of a snapshot operation.
1104
+ */
1105
+ interface SnapshotResult {
1106
+ /** Unique snapshot identifier */
1107
+ snapshotId: string;
1108
+ /** When the snapshot was created */
1109
+ createdAt: Date;
1110
+ /** Size in bytes */
1111
+ sizeBytes?: number;
1112
+ /** Tags applied to the snapshot */
1113
+ tags: string[];
1114
+ }
1115
+ interface RestoreSnapshotOptions {
1116
+ destinationPath?: string;
1117
+ snapshotId?: string;
1118
+ }
1119
+ /**
1120
+ * Metadata about an existing snapshot.
1121
+ */
1122
+ interface SnapshotInfo {
1123
+ /** Unique snapshot identifier */
1124
+ snapshotId: string;
1125
+ /** Sandbox this snapshot belongs to */
1126
+ sandboxId: string;
1127
+ /** When the snapshot was created */
1128
+ createdAt: Date;
1129
+ /** Tags applied to the snapshot */
1130
+ tags: string[];
1131
+ /** Paths included in the snapshot */
1132
+ paths: string[];
1133
+ /** Size in bytes */
1134
+ sizeBytes?: number;
1135
+ }
1136
+ /**
1137
+ * A single task in a batch execution.
1138
+ */
1139
+ interface BatchTask {
1140
+ /** Unique task identifier */
1141
+ id: string;
1142
+ /** Task prompt/message */
1143
+ message: string;
1144
+ /** Additional context for this task */
1145
+ context?: Record<string, unknown>;
1146
+ /** Per-task timeout in milliseconds */
1147
+ timeoutMs?: number;
1148
+ }
1149
+ /**
1150
+ * Options for batch execution.
1151
+ */
1152
+ interface BatchOptions {
1153
+ /** Timeout for entire batch in milliseconds (default: 300000 = 5 min) */
1154
+ timeoutMs?: number;
1155
+ /** Scaling mode: fastest, balanced, or cheapest (default: balanced) */
1156
+ scalingMode?: "fastest" | "balanced" | "cheapest";
1157
+ /**
1158
+ * Shared backend override for the batch.
1159
+ *
1160
+ * Use `backend.profile` with a string for a named profile or a provider-neutral
1161
+ * `AgentProfile` object for inline profile configuration.
1162
+ */
1163
+ backend?: Partial<BackendConfig>;
1164
+ /** Keep sandboxes alive after completion (default: false) */
1165
+ persistent?: boolean;
1166
+ /**
1167
+ * AbortSignal to cancel the batch mid-stream. When aborted, the HTTP
1168
+ * request to `/batch/run` is torn down; the SSE generator stops
1169
+ * yielding and `runBatch`/`streamBatch` reject with an `AbortError`.
1170
+ *
1171
+ * Note: the server-side batch may continue running to completion —
1172
+ * the signal is strictly for disconnecting the client from the
1173
+ * stream, not for halting server work.
1174
+ */
1175
+ signal?: AbortSignal;
1176
+ }
1177
+ /**
1178
+ * Result of a single task in a batch.
1179
+ */
1180
+ interface BatchTaskResult {
1181
+ /** Task identifier */
1182
+ taskId: string;
1183
+ /** Whether the task succeeded */
1184
+ success: boolean;
1185
+ /** Task response if successful */
1186
+ response?: string;
1187
+ /** Error message if failed */
1188
+ error?: string;
1189
+ /** Duration in milliseconds */
1190
+ durationMs: number;
1191
+ /** Number of retries */
1192
+ retries: number;
1193
+ /** Token usage if available */
1194
+ tokensUsed?: number;
1195
+ }
1196
+ /**
1197
+ * Summary of batch execution.
1198
+ */
1199
+ interface BatchResult {
1200
+ /** Total tasks executed */
1201
+ totalTasks: number;
1202
+ /** Number of successful tasks */
1203
+ succeeded: number;
1204
+ /** Number of failed tasks */
1205
+ failed: number;
1206
+ /** Total retries across all tasks */
1207
+ totalRetries: number;
1208
+ /** Success rate (0-100) */
1209
+ successRate: number;
1210
+ /** Individual task results */
1211
+ results: BatchTaskResult[];
1212
+ }
1213
+ /**
1214
+ * SSE event from batch streaming.
1215
+ */
1216
+ interface BatchEvent {
1217
+ /** Event type (batch.started, task.completed, etc.) */
1218
+ type: string;
1219
+ /** Event data */
1220
+ data: Record<string, unknown>;
1221
+ /**
1222
+ * Optional `id:` from the SSE frame. Present at runtime whenever
1223
+ * the server emits an `id:` line (used by EventSource-style
1224
+ * reconnection). Declared optional because the batch protocol
1225
+ * doesn't currently emit it — downstream consumers that want to
1226
+ * implement resume should feature-detect.
1227
+ */
1228
+ id?: string;
1229
+ }
1230
+ /**
1231
+ * Options for creating a checkpoint.
1232
+ */
1233
+ interface CheckpointOptions {
1234
+ /** Tags to apply to the checkpoint */
1235
+ tags?: string[];
1236
+ /** Keep sandbox running after checkpoint (default: false - sandbox stops) */
1237
+ leaveRunning?: boolean;
1238
+ /** Also create a filesystem snapshot for data consistency */
1239
+ includeSnapshot?: boolean;
1240
+ }
1241
+ /**
1242
+ * Result of a checkpoint operation.
1243
+ */
1244
+ interface CheckpointResult {
1245
+ /** Unique checkpoint identifier */
1246
+ checkpointId: string;
1247
+ /** When the checkpoint was created */
1248
+ createdAt: Date;
1249
+ /** Size of checkpoint in bytes (memory state) */
1250
+ sizeBytes?: number;
1251
+ /** Tags applied to the checkpoint */
1252
+ tags: string[];
1253
+ }
1254
+ /**
1255
+ * Information about an existing checkpoint.
1256
+ */
1257
+ interface CheckpointInfo {
1258
+ /** Unique checkpoint identifier */
1259
+ checkpointId: string;
1260
+ /** Sandbox this checkpoint belongs to */
1261
+ sandboxId: string;
1262
+ /** When the checkpoint was created */
1263
+ createdAt: Date;
1264
+ /** Tags applied to the checkpoint */
1265
+ tags: string[];
1266
+ /** Size of checkpoint in bytes */
1267
+ sizeBytes?: number;
1268
+ /** Whether checkpoint includes memory state */
1269
+ hasMemoryState: boolean;
1270
+ /** Whether checkpoint includes filesystem snapshot */
1271
+ hasFilesystemSnapshot: boolean;
1272
+ }
1273
+ /**
1274
+ * Options for forking a sandbox from a checkpoint.
1275
+ */
1276
+ interface ForkOptions {
1277
+ /** Name for the forked sandbox */
1278
+ name?: string;
1279
+ /** Override environment variables in the fork */
1280
+ env?: Record<string, string>;
1281
+ /** Override resource limits in the fork */
1282
+ resources?: SandboxResources;
1283
+ /** Custom metadata for the fork */
1284
+ metadata?: Record<string, unknown>;
1285
+ }
1286
+ /**
1287
+ * Result of a fork operation.
1288
+ */
1289
+ interface ForkResult {
1290
+ /** The newly created sandbox instance */
1291
+ sandbox: SandboxInfo;
1292
+ /** The checkpoint that was forked from */
1293
+ sourceCheckpoint: CheckpointInfo;
1294
+ /** ID of the source sandbox */
1295
+ sourceId: string;
1296
+ /** Time taken to fork in milliseconds */
1297
+ forkTimeMs: number;
1298
+ }
1299
+ /**
1300
+ * Infrastructure driver identifier.
1301
+ *
1302
+ * Most callers should omit `driver` and let the platform select automatically.
1303
+ */
1304
+ type DriverType = "docker" | "firecracker" | "host-agent" | "tangle";
1305
+ /**
1306
+ * Accelerator class for GPU-enabled sandboxes.
1307
+ */
1308
+ type GpuType = "nvidia-a100" | "nvidia-h100" | "nvidia-l4" | "amd-mi250";
1309
+ /**
1310
+ * Infrastructure driver configuration.
1311
+ *
1312
+ * @example Default
1313
+ * ```typescript
1314
+ * driver: { type: "docker" }
1315
+ * ```
1316
+ *
1317
+ * @example With pause/resume support
1318
+ * ```typescript
1319
+ * driver: { type: "firecracker", enableCriu: true }
1320
+ * ```
1321
+ *
1322
+ * @example GPU-enabled sandbox
1323
+ * ```typescript
1324
+ * driver: {
1325
+ * type: "host-agent",
1326
+ * gpuRequired: true,
1327
+ * gpuType: "nvidia-a100",
1328
+ * }
1329
+ * ```
1330
+ */
1331
+ interface DriverConfig {
1332
+ /**
1333
+ * Driver type identifier.
1334
+ * @default "docker"
1335
+ */
1336
+ type: DriverType;
1337
+ /**
1338
+ * Enable checkpointing for pause/resume and fork operations.
1339
+ * Support depends on the selected driver.
1340
+ */
1341
+ enableCriu?: boolean;
1342
+ /** Require a GPU for this sandbox. */
1343
+ gpuRequired?: boolean;
1344
+ /** Accelerator class preference. */
1345
+ gpuType?: GpuType;
1346
+ /**
1347
+ * Number of GPUs required.
1348
+ * @default 1 (when gpuRequired is true)
1349
+ */
1350
+ gpuCount?: number;
1351
+ /**
1352
+ * Preferred placement region.
1353
+ * e.g., "us-east-1", "eu-west-1".
1354
+ */
1355
+ preferredRegion?: string;
1356
+ }
1357
+ /**
1358
+ * Driver capabilities and status.
1359
+ */
1360
+ interface DriverInfo {
1361
+ /** Driver type */
1362
+ type: DriverType;
1363
+ /** Whether driver is available */
1364
+ available: boolean;
1365
+ /** Driver version string */
1366
+ version: string;
1367
+ /** Driver capabilities */
1368
+ capabilities: {
1369
+ /** Checkpoint/restore support */criu: boolean; /** GPU support */
1370
+ gpu: boolean; /** Filesystem snapshots */
1371
+ snapshots: boolean; /** Multi-user management */
1372
+ userManagement: boolean; /** Network isolation */
1373
+ networkIsolation: boolean;
1374
+ };
1375
+ /** Current capacity */
1376
+ capacity?: {
1377
+ available: number;
1378
+ total: number;
1379
+ };
1380
+ }
1381
+ /**
1382
+ * Backend type identifier. Controls which AI agent runtime runs inside the sandbox.
1383
+ *
1384
+ * The public-SDK source of truth. Kept in lock-step with the private
1385
+ * `@tangle-network/cli-agent-registry` spec list via the parity check in
1386
+ * `packages/cli-agent-registry/tests/specs.test.ts` (adding a new CLI spec
1387
+ * without updating this union surfaces as a test failure at PR review
1388
+ * time). Inlined here so the published SDK doesn't carry an unpublished
1389
+ * internal package as a runtime dep.
1390
+ *
1391
+ * - `"opencode"` — Default. Multi-provider, profile system, MCP support.
1392
+ * - `"claude-code"` — Anthropic Claude Code CLI. Requires an Anthropic API key.
1393
+ * - `"codex"` — OpenAI Codex CLI. Requires an OpenAI API key.
1394
+ * - `"amp"` — Sourcegraph AMP agent.
1395
+ * - `"factory-droids"` — Factory Droid agent.
1396
+ * - `"pi"` — Pi coding-agent CLI.
1397
+ * - `"hermes"` — Hermes inference-router agent.
1398
+ * - `"forge"` — Forge (forgecode.dev, tailcallhq) multi-provider coding agent.
1399
+ * - `"openclaw"` — OpenClaw dispatcher that routes to claude-cli/codex-cli/gemini-cli.
1400
+ * - `"acp"` — Agent Client Protocol bridge — fronts any ACP-compliant
1401
+ * agent binary (claude-agent-acp, codex-acp, gemini, openclaw acp).
1402
+ * Pick the backing agent via config.subAgent.
1403
+ * - `"cli-base"` — Minimal CLI-only (no AI agent).
1404
+ */
1405
+ type BackendType = "opencode" | "claude-code" | "codex" | "amp" | "factory-droids" | "pi" | "hermes" | "forge" | "openclaw" | "acp" | "cli-base";
1406
+ /**
1407
+ * MCP (Model Context Protocol) server configuration.
1408
+ */
1409
+ interface McpServerConfig {
1410
+ /** Command to run (e.g., "npx", "node") */
1411
+ command: string;
1412
+ /** Command arguments */
1413
+ args?: string[];
1414
+ /** Environment variables */
1415
+ env?: Record<string, string>;
1416
+ /** Working directory */
1417
+ cwd?: string;
1418
+ /** Remote URL (for remote MCP servers via SSE) */
1419
+ url?: string;
1420
+ /** Headers for remote connections */
1421
+ headers?: Record<string, string>;
1422
+ }
1423
+ /**
1424
+ * AI coding agent backend configuration.
1425
+ *
1426
+ * @example OpenCode with default settings
1427
+ * ```typescript
1428
+ * backend: { type: "opencode" }
1429
+ * ```
1430
+ *
1431
+ * @example OpenCode with named profile
1432
+ * ```typescript
1433
+ * backend: {
1434
+ * type: "opencode",
1435
+ * profile: "with-web-search",
1436
+ * }
1437
+ * ```
1438
+ *
1439
+ * @example Claude Code with BYOK
1440
+ * ```typescript
1441
+ * backend: {
1442
+ * type: "claude-code",
1443
+ * model: {
1444
+ * provider: "anthropic",
1445
+ * model: "claude-sonnet-4-20250514",
1446
+ * apiKey: process.env.ANTHROPIC_API_KEY,
1447
+ * }
1448
+ * }
1449
+ * ```
1450
+ */
1451
+ interface BackendConfig {
1452
+ /**
1453
+ * Backend type identifier.
1454
+ * @default "opencode"
1455
+ */
1456
+ type: BackendType;
1457
+ /**
1458
+ * Backend profile selection.
1459
+ *
1460
+ * Use a string for a named provider/backend profile, or an `AgentProfile`
1461
+ * object for an inline provider-neutral profile definition.
1462
+ */
1463
+ profile?: string | AgentProfile;
1464
+ /**
1465
+ * Model configuration override.
1466
+ */
1467
+ model?: {
1468
+ /** Provider name (e.g., "anthropic", "openai", "google") */provider?: string; /** Model identifier (e.g., "claude-sonnet-4-20250514") */
1469
+ model?: string; /** BYOK (Bring Your Own Key) API key */
1470
+ apiKey?: string; /** Custom API base URL (for proxies or on-prem) */
1471
+ baseUrl?: string; /** Maximum thinking tokens for extended reasoning */
1472
+ maxThinkingTokens?: number; /** API mode: "api" for direct calls, "cli" for CLI wrapper */
1473
+ mode?: "api" | "cli"; /** Authentication mode for CLI-native backends */
1474
+ authMode?: "api-key" | "oauth"; /** Auth files to write into the sandbox home directory before CLI startup */
1475
+ authFiles?: Array<{
1476
+ path: string;
1477
+ content: string;
1478
+ mode?: number;
1479
+ }>;
1480
+ };
1481
+ /**
1482
+ * Backend server configuration.
1483
+ */
1484
+ server?: {
1485
+ /** Server port (auto-assigned if not specified) */port?: number; /** Server hostname */
1486
+ hostname?: string;
1487
+ };
1488
+ }
1489
+ /**
1490
+ * Backend capabilities.
1491
+ */
1492
+ interface BackendCapabilities {
1493
+ /** Supports streaming responses */
1494
+ streaming: boolean;
1495
+ /** Supports tool/function use */
1496
+ toolUse: boolean;
1497
+ /** Supports extended thinking/reasoning */
1498
+ reasoning: boolean;
1499
+ /** Supports multimodal (images, etc) */
1500
+ multimodal: boolean;
1501
+ /** Context window size in tokens */
1502
+ contextWindow: number;
1503
+ /** Support details for provider-neutral `AgentProfile` values */
1504
+ profile?: AgentProfileCapabilities;
1505
+ }
1506
+ /**
1507
+ * Backend status information.
1508
+ */
1509
+ interface BackendStatus {
1510
+ /** Backend type */
1511
+ type: BackendType;
1512
+ /** Current status */
1513
+ status: "running" | "stopped" | "starting" | "stopping" | "unknown";
1514
+ /** Backend version */
1515
+ version?: string;
1516
+ /** Error message if failed */
1517
+ error?: string;
1518
+ /** Additional metadata */
1519
+ metadata?: Record<string, unknown>;
1520
+ }
1521
+ /**
1522
+ * Backend information.
1523
+ */
1524
+ interface BackendInfo {
1525
+ /** Backend type */
1526
+ type: BackendType;
1527
+ /** Whether backend is available */
1528
+ available: boolean;
1529
+ /** Backend capabilities */
1530
+ capabilities: BackendCapabilities;
1531
+ /** Available profiles (for opencode) */
1532
+ profiles?: Array<{
1533
+ name: string;
1534
+ description?: string;
1535
+ tags?: string[];
1536
+ }>;
1537
+ }
1538
+ /**
1539
+ * Network configuration for sandbox network isolation.
1540
+ *
1541
+ * Supports two modes:
1542
+ * - `blockOutbound: true` - Block all egress traffic (ports still work for inbound)
1543
+ * - `allowList: ["cidr", ...]` - Allow only specific destinations
1544
+ *
1545
+ * These modes are mutually exclusive.
1546
+ *
1547
+ * @example Block all outbound traffic
1548
+ * ```typescript
1549
+ * const box = await client.create({
1550
+ * network: { blockOutbound: true }
1551
+ * });
1552
+ * ```
1553
+ *
1554
+ * @example Allow only specific destinations
1555
+ * ```typescript
1556
+ * const box = await client.create({
1557
+ * network: {
1558
+ * allowList: [
1559
+ * "8.8.8.8/32", // Google DNS
1560
+ * "10.0.0.0/8", // Private network
1561
+ * ]
1562
+ * }
1563
+ * });
1564
+ * ```
1565
+ *
1566
+ * @example Pre-expose ports at creation
1567
+ * ```typescript
1568
+ * const box = await client.create({
1569
+ * network: {
1570
+ * blockOutbound: true,
1571
+ * ports: [8000, 8080], // Pre-expose these ports
1572
+ * }
1573
+ * });
1574
+ * ```
1575
+ */
1576
+ interface NetworkConfig {
1577
+ /**
1578
+ * Block all outbound network traffic.
1579
+ * Exposed ports still work for inbound connections.
1580
+ * Mutually exclusive with `allowList`.
1581
+ */
1582
+ blockOutbound?: boolean;
1583
+ /**
1584
+ * CIDR allowlist for outbound traffic.
1585
+ * Only traffic to these destinations is allowed.
1586
+ * Maximum 10 entries. Mutually exclusive with `blockOutbound`.
1587
+ *
1588
+ * Supports both IPv4 and IPv6 CIDR notation:
1589
+ * - "8.8.8.8/32" - Single IPv4 address
1590
+ * - "10.0.0.0/8" - IPv4 subnet
1591
+ * - "2001:db8::/32" - IPv6 subnet
1592
+ */
1593
+ allowList?: string[];
1594
+ /**
1595
+ * Ports to expose at creation time.
1596
+ * These ports will be accessible regardless of network restrictions.
1597
+ */
1598
+ ports?: number[];
1599
+ }
1600
+ /**
1601
+ * Network manager for runtime network configuration.
1602
+ * Access via `sandbox.network`.
1603
+ *
1604
+ * @example Update network restrictions
1605
+ * ```typescript
1606
+ * // Block all outbound traffic
1607
+ * await box.network.update({ blockOutbound: true });
1608
+ *
1609
+ * // Or switch to allowlist mode
1610
+ * await box.network.update({
1611
+ * allowList: ["192.168.1.0/24", "8.8.8.8/32"]
1612
+ * });
1613
+ *
1614
+ * // Remove restrictions
1615
+ * await box.network.update({ blockOutbound: false });
1616
+ * ```
1617
+ *
1618
+ * @example Expose ports dynamically
1619
+ * ```typescript
1620
+ * const url = await box.network.exposePort(8000);
1621
+ * console.log(`Service available at: ${url}`);
1622
+ *
1623
+ * const allUrls = await box.network.listUrls();
1624
+ * ```
1625
+ */
1626
+ interface NetworkManager {
1627
+ /**
1628
+ * Update network permissions at runtime.
1629
+ * Changes apply immediately without container restart.
1630
+ *
1631
+ * @param config - Partial network configuration to apply
1632
+ * @throws Error if blockOutbound and allowList are both specified
1633
+ * @throws Error if allowList exceeds 10 entries
1634
+ * @throws Error if CIDR format is invalid
1635
+ */
1636
+ update(config: Partial<NetworkConfig>): Promise<void>;
1637
+ /**
1638
+ * Expose a port dynamically.
1639
+ * Returns a publicly accessible URL for the port.
1640
+ * Works regardless of network restrictions.
1641
+ *
1642
+ * @param port - Port number to expose (1-65535)
1643
+ * @returns Public URL for accessing the exposed port
1644
+ */
1645
+ exposePort(port: number): Promise<string>;
1646
+ /**
1647
+ * List all exposed port URLs.
1648
+ *
1649
+ * @returns Map of port numbers to their public URLs
1650
+ */
1651
+ listUrls(): Promise<Record<number, string>>;
1652
+ /**
1653
+ * Get current network configuration.
1654
+ *
1655
+ * @returns Current network config including any runtime changes
1656
+ */
1657
+ getConfig(): Promise<NetworkConfig>;
1658
+ }
1659
+ interface PreviewLinkInfo {
1660
+ previewId: string;
1661
+ sandboxId: string;
1662
+ port: number;
1663
+ protocol: "tcp" | "udp";
1664
+ hostname: string;
1665
+ url: string;
1666
+ status: "provisioning" | "ready" | "error" | "disabled";
1667
+ lastSyncAt: string;
1668
+ createdAt: string;
1669
+ updatedAt: string;
1670
+ metadata?: Record<string, unknown>;
1671
+ }
1672
+ /**
1673
+ * Preview link management.
1674
+ *
1675
+ * Create publicly accessible HTTPS URLs for TCP ports inside the sandbox.
1676
+ *
1677
+ * @example
1678
+ * ```typescript
1679
+ * // Expose a dev server
1680
+ * const link = await box.previewLinks.create(3000);
1681
+ * console.log(link.url);
1682
+ *
1683
+ * // List all preview links
1684
+ * const links = await box.previewLinks.list();
1685
+ *
1686
+ * // Remove a preview link
1687
+ * await box.previewLinks.remove(link.previewId);
1688
+ * ```
1689
+ */
1690
+ interface PreviewLinkManager {
1691
+ /**
1692
+ * Create a preview link for a port.
1693
+ * Returns the preview link with its public URL.
1694
+ * If a link already exists for this port, returns the existing one.
1695
+ *
1696
+ * @param port - Port number to expose (1-65535)
1697
+ * @param options - Optional protocol and metadata
1698
+ */
1699
+ create(port: number, options?: {
1700
+ protocol?: "tcp" | "udp";
1701
+ metadata?: Record<string, unknown>;
1702
+ }): Promise<PreviewLinkInfo>;
1703
+ /**
1704
+ * List all preview links for this sandbox.
1705
+ */
1706
+ list(): Promise<PreviewLinkInfo[]>;
1707
+ /**
1708
+ * Remove a preview link by ID.
1709
+ *
1710
+ * @param previewId - The preview link ID to remove
1711
+ */
1712
+ remove(previewId: string): Promise<void>;
1713
+ }
1714
+ /**
1715
+ * Permission level for sandbox users.
1716
+ *
1717
+ * - `owner` — Full access, can manage users.
1718
+ * - `admin` — Read/write workspace, can manage users.
1719
+ * - `developer` — Read/write workspace.
1720
+ * - `viewer` — Read-only workspace.
1721
+ */
1722
+ type PermissionLevel = "owner" | "admin" | "developer" | "viewer";
1723
+ /**
1724
+ * Directory-level permission override.
1725
+ */
1726
+ interface DirectoryPermission {
1727
+ /** Directory path (absolute, e.g. "/workspace/shared") */
1728
+ path: string;
1729
+ /** Read access */
1730
+ read: boolean;
1731
+ /** Write access */
1732
+ write: boolean;
1733
+ /** Execute/traverse access */
1734
+ execute: boolean;
1735
+ }
1736
+ /**
1737
+ * Glob-based access policy rule.
1738
+ *
1739
+ * @example Block all .env files
1740
+ * ```typescript
1741
+ * { pattern: "*.env", permission: "none" }
1742
+ * ```
1743
+ *
1744
+ * @example Read-only secrets directory
1745
+ * ```typescript
1746
+ * { pattern: "/secrets/**", permission: "read" }
1747
+ * ```
1748
+ */
1749
+ interface AccessPolicyRule {
1750
+ /** Glob pattern for matching (e.g., "*.env", "/secrets/**") */
1751
+ pattern: string;
1752
+ /** Access level for matching paths */
1753
+ permission: "read" | "write" | "none";
1754
+ /** Priority when patterns overlap (higher wins) */
1755
+ priority?: number;
1756
+ }
1757
+ /**
1758
+ * User in a sandbox.
1759
+ */
1760
+ interface SandboxUser {
1761
+ /** Unique user ID (from auth system) */
1762
+ userId: string;
1763
+ /** Username inside sandbox (Unix username) */
1764
+ username: string;
1765
+ /** Home directory path */
1766
+ homeDir: string;
1767
+ /** Permission level */
1768
+ role: PermissionLevel;
1769
+ /** SSH public keys */
1770
+ sshKeys: string[];
1771
+ /** Directory permission overrides */
1772
+ directoryPermissions?: DirectoryPermission[];
1773
+ /** Access policy rules */
1774
+ accessPolicies?: AccessPolicyRule[];
1775
+ /** When user was added */
1776
+ createdAt: Date;
1777
+ }
1778
+ /**
1779
+ * Options for adding a user to a sandbox.
1780
+ */
1781
+ interface AddUserOptions {
1782
+ /** Unique user ID (from your auth system) */
1783
+ userId: string;
1784
+ /** Preferred username (will be sanitized for Unix) */
1785
+ username?: string;
1786
+ /** Permission level (default: developer) */
1787
+ role?: PermissionLevel;
1788
+ /** SSH public keys for remote access */
1789
+ sshKeys?: string[];
1790
+ /** Custom directory permissions */
1791
+ directoryPermissions?: DirectoryPermission[];
1792
+ }
1793
+ /**
1794
+ * Options for updating a user.
1795
+ */
1796
+ interface UpdateUserOptions {
1797
+ /** New permission level */
1798
+ role?: PermissionLevel;
1799
+ /** SSH keys to add */
1800
+ addSshKeys?: string[];
1801
+ /** SSH keys to remove */
1802
+ removeSshKeys?: string[];
1803
+ /** Directory permissions to add/update */
1804
+ directoryPermissions?: DirectoryPermission[];
1805
+ }
1806
+ /**
1807
+ * Initial permissions configuration for sandbox creation.
1808
+ */
1809
+ interface SandboxPermissionsConfig {
1810
+ /**
1811
+ * Default role for invited users.
1812
+ * @default "developer"
1813
+ */
1814
+ defaultRole?: PermissionLevel;
1815
+ /**
1816
+ * Users to invite at creation time.
1817
+ * Owner is automatically added from the API key.
1818
+ */
1819
+ initialUsers?: Array<{
1820
+ userId: string;
1821
+ role?: PermissionLevel;
1822
+ sshKeys?: string[];
1823
+ }>;
1824
+ /**
1825
+ * Default access policies for all users.
1826
+ */
1827
+ defaultPolicies?: AccessPolicyRule[];
1828
+ /**
1829
+ * Enable multi-user mode.
1830
+ * @default true when initialUsers is provided
1831
+ */
1832
+ multiUser?: boolean;
1833
+ }
1834
+ /**
1835
+ * Permissions manager interface.
1836
+ * Access via `sandbox.permissions`.
1837
+ */
1838
+ interface PermissionsManager {
1839
+ /** List all users in the sandbox */
1840
+ list(): Promise<SandboxUser[]>;
1841
+ /** Get a specific user */
1842
+ get(userId: string): Promise<SandboxUser | null>;
1843
+ /** Add a user to the sandbox */
1844
+ add(options: AddUserOptions): Promise<SandboxUser>;
1845
+ /** Update a user's permissions */
1846
+ update(userId: string, options: UpdateUserOptions): Promise<SandboxUser>;
1847
+ /** Remove a user from the sandbox */
1848
+ remove(userId: string, options?: {
1849
+ preserveHomeDir?: boolean;
1850
+ }): Promise<void>;
1851
+ /** Set access policies for a user */
1852
+ setAccessPolicies(userId: string, rules: AccessPolicyRule[]): Promise<void>;
1853
+ /** Get access policies for a user */
1854
+ getAccessPolicies(userId: string): Promise<AccessPolicyRule[]>;
1855
+ /** Check if a user can perform an action on a path */
1856
+ checkAccess(userId: string, path: string, action: "read" | "write" | "execute"): Promise<boolean>;
1857
+ }
1858
+ /**
1859
+ * Backend manager for runtime agent configuration.
1860
+ * Access via `sandbox.backend`.
1861
+ */
1862
+ interface BackendManager {
1863
+ /** Get current backend status */
1864
+ status(): Promise<BackendStatus>;
1865
+ /** Get backend capabilities */
1866
+ capabilities(): Promise<BackendCapabilities>;
1867
+ /** Add MCP server at runtime (opencode only) */
1868
+ addMcp(name: string, config: McpServerConfig): Promise<void>;
1869
+ /** Get MCP server status */
1870
+ getMcpStatus(): Promise<Record<string, {
1871
+ status: "running" | "stopped" | "error";
1872
+ error?: string;
1873
+ }>>;
1874
+ /** Update backend configuration */
1875
+ updateConfig(config: Partial<BackendConfig>): Promise<void>;
1876
+ /**
1877
+ * Validate a provider-neutral profile against the active backend.
1878
+ *
1879
+ * Optional while backends adopt the public `AgentProfile` contract.
1880
+ */
1881
+ validateProfile?(profile: AgentProfile): Promise<AgentProfileValidationResult>;
1882
+ /** Restart the backend agent */
1883
+ restart(): Promise<void>;
1884
+ }
1885
+ /**
1886
+ * Options for spawning a process.
1887
+ *
1888
+ * @example Basic spawn
1889
+ * ```typescript
1890
+ * const proc = await box.process.spawn("python train.py");
1891
+ * ```
1892
+ *
1893
+ * @example With options
1894
+ * ```typescript
1895
+ * const proc = await box.process.spawn("python train.py", {
1896
+ * cwd: "/workspace/ml",
1897
+ * env: { "CUDA_VISIBLE_DEVICES": "0" },
1898
+ * timeoutMs: 3600000, // 1 hour
1899
+ * });
1900
+ * ```
1901
+ */
1902
+ interface ProcessSpawnOptions {
1903
+ /** Working directory for the process */
1904
+ cwd?: string;
1905
+ /** Environment variables to set */
1906
+ env?: Record<string, string>;
1907
+ /** Timeout in milliseconds (0 = no timeout) */
1908
+ timeoutMs?: number;
1909
+ }
1910
+ /**
1911
+ * Options for running Python code.
1912
+ *
1913
+ * @example Simple code execution
1914
+ * ```typescript
1915
+ * const result = await box.process.runCode(`
1916
+ * import numpy as np
1917
+ * print(np.random.rand(10))
1918
+ * `);
1919
+ * ```
1920
+ */
1921
+ interface RunCodeOptions {
1922
+ /** Working directory */
1923
+ cwd?: string;
1924
+ /** Environment variables */
1925
+ env?: Record<string, string>;
1926
+ /** Timeout in milliseconds */
1927
+ timeoutMs?: number;
1928
+ }
1929
+ /**
1930
+ * Status of a spawned process.
1931
+ */
1932
+ interface ProcessStatus {
1933
+ /** Process ID */
1934
+ pid: number;
1935
+ /** Command that was executed */
1936
+ command: string;
1937
+ /** Working directory */
1938
+ cwd?: string;
1939
+ /** Whether the process is still running */
1940
+ running: boolean;
1941
+ /** Exit code (-1 if still running) */
1942
+ exitCode: number;
1943
+ /** Signal that killed the process (if any) */
1944
+ exitSignal?: string;
1945
+ /** When the process started */
1946
+ startedAt: Date;
1947
+ /** When the process exited (if exited) */
1948
+ exitedAt?: Date;
1949
+ }
1950
+ /**
1951
+ * Full process information including environment.
1952
+ */
1953
+ interface ProcessInfo extends ProcessStatus {
1954
+ /** Environment variables used */
1955
+ env?: Record<string, string>;
1956
+ }
1957
+ /**
1958
+ * A log entry from process stdout/stderr.
1959
+ */
1960
+ interface ProcessLogEntry {
1961
+ /** Log source: stdout or stderr */
1962
+ type: "stdout" | "stderr";
1963
+ /** Log content */
1964
+ data: string;
1965
+ /** Timestamp in milliseconds */
1966
+ timestamp: number;
1967
+ }
1968
+ /**
1969
+ * Result of running code or a blocking process.
1970
+ */
1971
+ interface CodeResult {
1972
+ /** Process ID */
1973
+ pid: number;
1974
+ /** Exit code */
1975
+ exitCode: number;
1976
+ /** Standard output */
1977
+ stdout: string;
1978
+ /** Standard error */
1979
+ stderr: string;
1980
+ /** Execution duration in milliseconds */
1981
+ durationMs: number;
1982
+ }
1983
+ /**
1984
+ * Signal types for killing processes.
1985
+ */
1986
+ type ProcessSignal = "SIGTERM" | "SIGKILL" | "SIGINT" | "SIGHUP" | "SIGQUIT" | "SIGUSR1" | "SIGUSR2";
1987
+ /**
1988
+ * A handle to a spawned process with control methods.
1989
+ *
1990
+ * @example Non-blocking process with log streaming
1991
+ * ```typescript
1992
+ * const proc = await box.process.spawn("python train.py", {
1993
+ * cwd: "/workspace",
1994
+ * env: { "CUDA_VISIBLE_DEVICES": "0" }
1995
+ * });
1996
+ *
1997
+ * console.log(`Started PID: ${proc.pid}`);
1998
+ *
1999
+ * // Stream logs in real-time
2000
+ * for await (const line of proc.logs()) {
2001
+ * console.log(line);
2002
+ * }
2003
+ *
2004
+ * // Or wait for completion
2005
+ * const exitCode = await proc.wait();
2006
+ * ```
2007
+ *
2008
+ * @example Check status and kill
2009
+ * ```typescript
2010
+ * const status = await proc.status();
2011
+ * if (status.running) {
2012
+ * await proc.kill("SIGKILL");
2013
+ * }
2014
+ * ```
2015
+ */
2016
+ interface Process {
2017
+ /** Process ID */
2018
+ readonly pid: number;
2019
+ /** Command that was executed */
2020
+ readonly command: string;
2021
+ /**
2022
+ * Get current process status.
2023
+ */
2024
+ status(): Promise<ProcessStatus>;
2025
+ /**
2026
+ * Wait for the process to exit.
2027
+ * @returns Exit code
2028
+ */
2029
+ wait(): Promise<number>;
2030
+ /**
2031
+ * Kill the process.
2032
+ * @param signal - Signal to send (default: SIGTERM)
2033
+ */
2034
+ kill(signal?: ProcessSignal): Promise<void>;
2035
+ /**
2036
+ * Stream stdout/stderr logs in real-time.
2037
+ * Includes buffered logs from process start.
2038
+ */
2039
+ logs(): AsyncIterable<ProcessLogEntry>;
2040
+ /**
2041
+ * Stream only stdout.
2042
+ */
2043
+ stdout(): AsyncIterable<string>;
2044
+ /**
2045
+ * Stream only stderr.
2046
+ */
2047
+ stderr(): AsyncIterable<string>;
2048
+ }
2049
+ /**
2050
+ * Process manager for spawning and controlling processes.
2051
+ * Access via `sandbox.process`.
2052
+ *
2053
+ * Provides non-blocking process execution with real-time log streaming,
2054
+ * ideal for long-running tasks like ML training or dev servers.
2055
+ *
2056
+ * @example Non-blocking process
2057
+ * ```typescript
2058
+ * const proc = await box.process.spawn("python train.py", {
2059
+ * cwd: "/workspace",
2060
+ * env: { "CUDA_VISIBLE_DEVICES": "0" }
2061
+ * });
2062
+ *
2063
+ * // Stream logs
2064
+ * for await (const entry of proc.logs()) {
2065
+ * console.log(`[${entry.type}] ${entry.data}`);
2066
+ * }
2067
+ *
2068
+ * // Check status
2069
+ * const status = await proc.status();
2070
+ * console.log(`Running: ${status.running}`);
2071
+ *
2072
+ * // Kill if needed
2073
+ * await proc.kill();
2074
+ * ```
2075
+ *
2076
+ * @example Run Python code directly
2077
+ * ```typescript
2078
+ * const result = await box.process.runCode(`
2079
+ * import numpy as np
2080
+ * print(np.random.rand(10).mean())
2081
+ * `);
2082
+ * console.log(result.stdout); // Prints the mean
2083
+ * ```
2084
+ *
2085
+ * @example List and manage processes
2086
+ * ```typescript
2087
+ * const procs = await box.process.list();
2088
+ * for (const p of procs) {
2089
+ * console.log(`PID ${p.pid}: ${p.command} (${p.running ? 'running' : 'exited'})`);
2090
+ * }
2091
+ *
2092
+ * // Get specific process
2093
+ * const proc = await box.process.get(1234);
2094
+ * if (proc) {
2095
+ * await proc.kill();
2096
+ * }
2097
+ * ```
2098
+ */
2099
+ interface ProcessManager {
2100
+ /**
2101
+ * Spawn a process without blocking.
2102
+ * Returns immediately with a Process handle.
2103
+ *
2104
+ * @param command - Shell command to execute
2105
+ * @param options - Spawn options (cwd, env, timeout)
2106
+ * @returns Process handle for control and monitoring
2107
+ */
2108
+ spawn(command: string, options?: ProcessSpawnOptions): Promise<Process>;
2109
+ /**
2110
+ * Run Python code directly.
2111
+ * Blocks until completion and returns result.
2112
+ *
2113
+ * @param code - Python code to execute
2114
+ * @param options - Execution options
2115
+ * @returns Execution result with stdout/stderr
2116
+ */
2117
+ runCode(code: string, options?: RunCodeOptions): Promise<CodeResult>;
2118
+ /**
2119
+ * List all tracked processes.
2120
+ *
2121
+ * @returns Array of process status objects
2122
+ */
2123
+ list(): Promise<ProcessStatus[]>;
2124
+ /**
2125
+ * Get a process by PID.
2126
+ *
2127
+ * @param pid - Process ID
2128
+ * @returns Process handle or null if not found
2129
+ */
2130
+ get(pid: number): Promise<Process | null>;
2131
+ }
2132
+ /**
2133
+ * Information about a stored secret (without the value).
2134
+ */
2135
+ interface SecretInfo {
2136
+ /** Secret name (e.g., HF_TOKEN, AWS_ACCESS_KEY) */
2137
+ name: string;
2138
+ /** When the secret was created */
2139
+ createdAt: Date;
2140
+ /** When the secret was last updated */
2141
+ updatedAt: Date;
2142
+ }
2143
+ /**
2144
+ * Secrets manager for storing and retrieving encrypted secrets.
2145
+ * Access via `client.secrets`.
2146
+ *
2147
+ * Secrets are encrypted at rest and can be injected into sandboxes
2148
+ * as environment variables.
2149
+ *
2150
+ * @example Create and manage secrets
2151
+ * ```typescript
2152
+ * // Create a secret
2153
+ * await client.secrets.create("HF_TOKEN", "hf_xxx");
2154
+ *
2155
+ * // List all secrets (names only, not values)
2156
+ * const secrets = await client.secrets.list();
2157
+ * console.log(secrets.map(s => s.name)); // ["HF_TOKEN"]
2158
+ *
2159
+ * // Get a secret value (audited operation)
2160
+ * const value = await client.secrets.get("HF_TOKEN");
2161
+ *
2162
+ * // Update a secret
2163
+ * await client.secrets.update("HF_TOKEN", "hf_new_value");
2164
+ *
2165
+ * // Delete a secret
2166
+ * await client.secrets.delete("HF_TOKEN");
2167
+ * ```
2168
+ *
2169
+ * @example Use secrets in a sandbox
2170
+ * ```typescript
2171
+ * // Create sandbox with secrets injected as env vars
2172
+ * const box = await client.create({
2173
+ * secrets: ["HF_TOKEN", "AWS_ACCESS_KEY"],
2174
+ * });
2175
+ *
2176
+ * // Secrets are available as environment variables
2177
+ * const result = await box.exec("echo $HF_TOKEN");
2178
+ * ```
2179
+ */
2180
+ interface SecretsManager {
2181
+ /**
2182
+ * Create a new secret.
2183
+ *
2184
+ * @param name - Secret name (uppercase, alphanumeric + underscore, max 63 chars)
2185
+ * @param value - Secret value (max 64KB)
2186
+ * @returns Created secret info
2187
+ * @throws If secret already exists or name is invalid
2188
+ *
2189
+ * @example
2190
+ * ```typescript
2191
+ * await client.secrets.create("HF_TOKEN", "hf_xxx");
2192
+ * await client.secrets.create("AWS_ACCESS_KEY", "AKIA...");
2193
+ * ```
2194
+ */
2195
+ create(name: string, value: string): Promise<SecretInfo>;
2196
+ /**
2197
+ * List all secrets (names and metadata only, not values).
2198
+ *
2199
+ * @returns Array of secret info objects
2200
+ *
2201
+ * @example
2202
+ * ```typescript
2203
+ * const secrets = await client.secrets.list();
2204
+ * for (const s of secrets) {
2205
+ * console.log(`${s.name} - created ${s.createdAt}`);
2206
+ * }
2207
+ * ```
2208
+ */
2209
+ list(): Promise<SecretInfo[]>;
2210
+ /**
2211
+ * Get a secret's decrypted value.
2212
+ *
2213
+ * This is an audited operation - access is logged.
2214
+ *
2215
+ * @param name - Secret name
2216
+ * @returns Secret value
2217
+ * @throws If secret not found
2218
+ *
2219
+ * @example
2220
+ * ```typescript
2221
+ * const token = await client.secrets.get("HF_TOKEN");
2222
+ * ```
2223
+ */
2224
+ get(name: string): Promise<string>;
2225
+ /**
2226
+ * Update an existing secret's value.
2227
+ *
2228
+ * @param name - Secret name
2229
+ * @param value - New secret value
2230
+ * @returns Updated secret info
2231
+ * @throws If secret not found
2232
+ *
2233
+ * @example
2234
+ * ```typescript
2235
+ * await client.secrets.update("HF_TOKEN", "hf_new_value");
2236
+ * ```
2237
+ */
2238
+ update(name: string, value: string): Promise<SecretInfo>;
2239
+ /**
2240
+ * Delete a secret.
2241
+ *
2242
+ * @param name - Secret name
2243
+ * @throws If secret not found
2244
+ *
2245
+ * @example
2246
+ * ```typescript
2247
+ * await client.secrets.delete("HF_TOKEN");
2248
+ * ```
2249
+ */
2250
+ delete(name: string): Promise<void>;
2251
+ }
2252
+ /**
2253
+ * Detailed file/directory information.
2254
+ */
2255
+ interface FileInfo {
2256
+ /** File/directory name */
2257
+ name: string;
2258
+ /** Full path relative to workspace */
2259
+ path: string;
2260
+ /** Size in bytes */
2261
+ size: number;
2262
+ /** Whether this is a directory */
2263
+ isDir: boolean;
2264
+ /** Whether this is a regular file */
2265
+ isFile: boolean;
2266
+ /** Whether this is a symbolic link */
2267
+ isSymlink: boolean;
2268
+ /** Unix permissions (e.g., 0o755) */
2269
+ permissions: number;
2270
+ /** Owner user ID/name */
2271
+ owner: string;
2272
+ /** Group ID/name */
2273
+ group: string;
2274
+ /** Last modification time */
2275
+ modTime: Date;
2276
+ /** Last access time */
2277
+ accessTime: Date;
2278
+ }
2279
+ /**
2280
+ * Options for uploading files.
2281
+ */
2282
+ interface UploadOptions {
2283
+ /** Overwrite if file exists (default: true) */
2284
+ overwrite?: boolean;
2285
+ /** Set file permissions (Unix mode, e.g., 0o644) */
2286
+ permissions?: number;
2287
+ /** Progress callback for large files */
2288
+ onProgress?: (progress: UploadProgress) => void;
2289
+ }
2290
+ /**
2291
+ * Upload progress information.
2292
+ */
2293
+ interface UploadProgress {
2294
+ /** Bytes uploaded so far */
2295
+ bytesUploaded: number;
2296
+ /** Total bytes to upload */
2297
+ totalBytes: number;
2298
+ /** Percentage complete (0-100) */
2299
+ percentage: number;
2300
+ }
2301
+ /**
2302
+ * Options for downloading files.
2303
+ */
2304
+ interface DownloadOptions {
2305
+ /** Overwrite local file if exists (default: true) */
2306
+ overwrite?: boolean;
2307
+ /** Progress callback for large files */
2308
+ onProgress?: (progress: DownloadProgress) => void;
2309
+ }
2310
+ /**
2311
+ * Download progress information.
2312
+ */
2313
+ interface DownloadProgress {
2314
+ /** Bytes downloaded so far */
2315
+ bytesDownloaded: number;
2316
+ /** Total bytes to download */
2317
+ totalBytes: number;
2318
+ /** Percentage complete (0-100) */
2319
+ percentage: number;
2320
+ }
2321
+ /**
2322
+ * Options for listing directories.
2323
+ */
2324
+ interface ListOptions {
2325
+ /** Include hidden files (starting with .) */
2326
+ all?: boolean;
2327
+ /** Include full metadata (like ls -l) */
2328
+ long?: boolean;
2329
+ }
2330
+ /**
2331
+ * Options for creating directories.
2332
+ */
2333
+ interface MkdirOptions {
2334
+ /** Create parent directories as needed (like mkdir -p) */
2335
+ recursive?: boolean;
2336
+ /** Set directory permissions (Unix mode, e.g., 0o755) */
2337
+ mode?: number;
2338
+ }
2339
+ /**
2340
+ * Options for deleting files/directories.
2341
+ */
2342
+ interface DeleteOptions {
2343
+ /** Recursively delete directories (like rm -rf) */
2344
+ recursive?: boolean;
2345
+ }
2346
+ /**
2347
+ * Enhanced file system operations for sandboxes.
2348
+ * Access via `sandbox.fs`.
2349
+ *
2350
+ * Provides comprehensive file operations beyond basic read/write,
2351
+ * including binary file upload/download, directory operations,
2352
+ * and progress reporting for large files.
2353
+ *
2354
+ * @example Upload and download files
2355
+ * ```typescript
2356
+ * // Upload a local file
2357
+ * await box.fs.upload("./model.bin", "/workspace/models/model.bin");
2358
+ *
2359
+ * // Download a file
2360
+ * await box.fs.download("/workspace/results.zip", "./local/results.zip");
2361
+ *
2362
+ * // With progress reporting
2363
+ * await box.fs.upload("./large-file.bin", "/workspace/data.bin", {
2364
+ * onProgress: (p) => console.log(`${p.percentage}%`),
2365
+ * });
2366
+ * ```
2367
+ *
2368
+ * @example Directory operations
2369
+ * ```typescript
2370
+ * // Upload entire directory
2371
+ * await box.fs.uploadDir("./local/project", "/workspace/project");
2372
+ *
2373
+ * // Download entire directory
2374
+ * await box.fs.downloadDir("/workspace/output", "./local/output");
2375
+ *
2376
+ * // List directory contents
2377
+ * const files = await box.fs.list("/workspace");
2378
+ * for (const f of files) {
2379
+ * console.log(`${f.name} - ${f.size} bytes`);
2380
+ * }
2381
+ * ```
2382
+ *
2383
+ * @example File management
2384
+ * ```typescript
2385
+ * // Check if file exists
2386
+ * if (await box.fs.exists("/workspace/config.json")) {
2387
+ * const info = await box.fs.stat("/workspace/config.json");
2388
+ * console.log(`Size: ${info.size}, Modified: ${info.modTime}`);
2389
+ * }
2390
+ *
2391
+ * // Create directory
2392
+ * await box.fs.mkdir("/workspace/output/images", { recursive: true });
2393
+ *
2394
+ * // Delete file or directory
2395
+ * await box.fs.delete("/workspace/temp", { recursive: true });
2396
+ * ```
2397
+ */
2398
+ interface FileSystem {
2399
+ /**
2400
+ * Read a file's contents as a string.
2401
+ * For binary files, use download() instead.
2402
+ *
2403
+ * @param path - Path to file (relative to workspace)
2404
+ * @returns File contents as UTF-8 string
2405
+ * @throws NotFoundError if file doesn't exist
2406
+ */
2407
+ read(path: string): Promise<string>;
2408
+ /**
2409
+ * Write string content to a file.
2410
+ * For binary files, use upload() instead.
2411
+ * Creates parent directories as needed.
2412
+ *
2413
+ * @param path - Path to file (relative to workspace)
2414
+ * @param content - Content to write
2415
+ */
2416
+ write(path: string, content: string): Promise<void>;
2417
+ /**
2418
+ * Search for text patterns in files using ripgrep.
2419
+ * @see SearchOptions for available options
2420
+ */
2421
+ search(query: string, options?: SearchOptions): AsyncIterable<SearchMatch>;
2422
+ /**
2423
+ * Upload a local file to the sandbox.
2424
+ * Handles binary files correctly using multipart upload.
2425
+ * Creates parent directories as needed.
2426
+ *
2427
+ * @param localPath - Path to local file
2428
+ * @param remotePath - Destination path in sandbox
2429
+ * @param options - Upload options (overwrite, permissions, progress)
2430
+ * @throws Error if local file doesn't exist
2431
+ *
2432
+ * @example
2433
+ * ```typescript
2434
+ * await box.fs.upload("./model.bin", "/workspace/models/model.bin");
2435
+ *
2436
+ * // With progress
2437
+ * await box.fs.upload("./large-file.bin", "/data/file.bin", {
2438
+ * onProgress: (p) => console.log(`${p.percentage.toFixed(1)}%`),
2439
+ * });
2440
+ * ```
2441
+ */
2442
+ upload(localPath: string, remotePath: string, options?: UploadOptions): Promise<void>;
2443
+ /**
2444
+ * Download a file from the sandbox.
2445
+ * Handles binary files correctly.
2446
+ * Creates local parent directories as needed.
2447
+ *
2448
+ * @param remotePath - Path to file in sandbox
2449
+ * @param localPath - Local destination path
2450
+ * @param options - Download options (overwrite, progress)
2451
+ * @throws NotFoundError if remote file doesn't exist
2452
+ *
2453
+ * @example
2454
+ * ```typescript
2455
+ * await box.fs.download("/workspace/output.zip", "./results.zip");
2456
+ * ```
2457
+ */
2458
+ download(remotePath: string, localPath: string, options?: DownloadOptions): Promise<void>;
2459
+ /**
2460
+ * Upload a local directory to the sandbox.
2461
+ * Uses tar for efficient transfer.
2462
+ * Preserves directory structure and file permissions.
2463
+ *
2464
+ * @param localDir - Path to local directory
2465
+ * @param remoteDir - Destination directory in sandbox
2466
+ * @throws Error if local directory doesn't exist
2467
+ *
2468
+ * @example
2469
+ * ```typescript
2470
+ * await box.fs.uploadDir("./project", "/workspace/project");
2471
+ * ```
2472
+ */
2473
+ uploadDir(localDir: string, remoteDir: string): Promise<void>;
2474
+ /**
2475
+ * Download a directory from the sandbox.
2476
+ * Uses tar for efficient transfer.
2477
+ * Preserves directory structure and file permissions.
2478
+ *
2479
+ * @param remoteDir - Directory path in sandbox
2480
+ * @param localDir - Local destination directory
2481
+ * @throws NotFoundError if remote directory doesn't exist
2482
+ *
2483
+ * @example
2484
+ * ```typescript
2485
+ * await box.fs.downloadDir("/workspace/output", "./local-output");
2486
+ * ```
2487
+ */
2488
+ downloadDir(remoteDir: string, localDir: string): Promise<void>;
2489
+ /**
2490
+ * List directory contents with metadata.
2491
+ *
2492
+ * @param path - Directory path (relative to workspace)
2493
+ * @param options - List options (all, long)
2494
+ * @returns Array of file/directory info
2495
+ * @throws NotFoundError if directory doesn't exist
2496
+ *
2497
+ * @example
2498
+ * ```typescript
2499
+ * const entries = await box.fs.list("/workspace", { all: true });
2500
+ * for (const e of entries) {
2501
+ * const type = e.isDir ? "DIR" : "FILE";
2502
+ * console.log(`[${type}] ${e.name} (${e.size} bytes)`);
2503
+ * }
2504
+ * ```
2505
+ */
2506
+ list(path: string, options?: ListOptions): Promise<FileInfo[]>;
2507
+ /**
2508
+ * Get detailed information about a file or directory.
2509
+ *
2510
+ * @param path - Path to file/directory
2511
+ * @returns File/directory metadata
2512
+ * @throws NotFoundError if path doesn't exist
2513
+ *
2514
+ * @example
2515
+ * ```typescript
2516
+ * const info = await box.fs.stat("/workspace/model.bin");
2517
+ * console.log(`Size: ${info.size}, Modified: ${info.modTime}`);
2518
+ * ```
2519
+ */
2520
+ stat(path: string): Promise<FileInfo>;
2521
+ /**
2522
+ * Delete a file or directory.
2523
+ *
2524
+ * @param path - Path to delete
2525
+ * @param options - Delete options (recursive for directories)
2526
+ * @throws NotFoundError if path doesn't exist
2527
+ * @throws Error if deleting non-empty directory without recursive
2528
+ *
2529
+ * @example
2530
+ * ```typescript
2531
+ * // Delete file
2532
+ * await box.fs.delete("/workspace/temp.txt");
2533
+ *
2534
+ * // Delete directory recursively
2535
+ * await box.fs.delete("/workspace/cache", { recursive: true });
2536
+ * ```
2537
+ */
2538
+ delete(path: string, options?: DeleteOptions): Promise<void>;
2539
+ /**
2540
+ * Create a directory.
2541
+ *
2542
+ * @param path - Directory path to create
2543
+ * @param options - Options (recursive to create parents)
2544
+ *
2545
+ * @example
2546
+ * ```typescript
2547
+ * // Create with parents
2548
+ * await box.fs.mkdir("/workspace/output/images", { recursive: true });
2549
+ * ```
2550
+ */
2551
+ mkdir(path: string, options?: MkdirOptions): Promise<void>;
2552
+ /**
2553
+ * Check if a path exists.
2554
+ *
2555
+ * @param path - Path to check
2556
+ * @returns true if path exists, false otherwise
2557
+ *
2558
+ * @example
2559
+ * ```typescript
2560
+ * if (await box.fs.exists("/workspace/config.json")) {
2561
+ * // File exists
2562
+ * }
2563
+ * ```
2564
+ */
2565
+ exists(path: string): Promise<boolean>;
2566
+ }
2567
+ //#endregion
2568
+ //#region src/sandbox.d.ts
2569
+ /**
2570
+ * HTTP client interface for making requests.
2571
+ */
2572
+ interface HttpClient {
2573
+ fetch(path: string, options?: RequestInit): Promise<Response>;
2574
+ }
2575
+ /**
2576
+ * Git capability for repository operations.
2577
+ */
2578
+ interface GitCapability {
2579
+ /** Get repository status */
2580
+ status(): Promise<GitStatus>;
2581
+ /** Get commit log */
2582
+ log(limit?: number): Promise<GitCommit[]>;
2583
+ /** Get diff (optionally against a ref) */
2584
+ diff(ref?: string): Promise<GitDiff>;
2585
+ /** Stage files */
2586
+ add(paths: string[]): Promise<void>;
2587
+ /** Create a commit */
2588
+ commit(message: string, options?: {
2589
+ amend?: boolean;
2590
+ }): Promise<GitCommit>;
2591
+ /** Push to remote */
2592
+ push(options?: {
2593
+ force?: boolean;
2594
+ }): Promise<void>;
2595
+ /** Pull from remote */
2596
+ pull(options?: {
2597
+ rebase?: boolean;
2598
+ }): Promise<void>;
2599
+ /** List branches */
2600
+ branches(): Promise<GitBranch[]>;
2601
+ /** Checkout a branch or ref */
2602
+ checkout(ref: string, options?: {
2603
+ create?: boolean;
2604
+ }): Promise<void>;
2605
+ }
2606
+ /**
2607
+ * Tools capability for managing language runtimes via mise.
2608
+ */
2609
+ interface ToolsCapability {
2610
+ /** Install a tool version */
2611
+ install(tool: string, version: string): Promise<void>;
2612
+ /** Activate a tool version for the session */
2613
+ use(tool: string, version: string): Promise<void>;
2614
+ /** List installed tools */
2615
+ list(): Promise<InstalledTool[]>;
2616
+ /** Run a command with a specific tool */
2617
+ run(tool: string, args: string[]): Promise<ExecResult>;
2618
+ }
2619
+ /**
2620
+ * A sandbox instance with methods for interaction.
2621
+ */
2622
+ declare class SandboxInstance {
2623
+ private readonly client;
2624
+ private info;
2625
+ constructor(client: HttpClient, info: SandboxInfo);
2626
+ /** Unique sandbox identifier */
2627
+ get id(): string;
2628
+ /** Human-readable name */
2629
+ get name(): string | undefined;
2630
+ /** Current status */
2631
+ get status(): SandboxStatus;
2632
+ /** Connection information */
2633
+ get connection(): SandboxConnection | undefined;
2634
+ /** Custom metadata */
2635
+ get metadata(): Record<string, unknown> | undefined;
2636
+ /** When the sandbox was created */
2637
+ get createdAt(): Date;
2638
+ /** When the sandbox started running */
2639
+ get startedAt(): Date | undefined;
2640
+ /** Last activity timestamp */
2641
+ get lastActivityAt(): Date | undefined;
2642
+ /** When the sandbox will expire */
2643
+ get expiresAt(): Date | undefined;
2644
+ /** Error message if status is 'failed' */
2645
+ get error(): string | undefined;
2646
+ /** Web terminal URL for browser-based access */
2647
+ get url(): string | undefined;
2648
+ /**
2649
+ * Serialize to the public sandbox shape for CLI JSON output.
2650
+ */
2651
+ toJSON(): SandboxInfo;
2652
+ /**
2653
+ * Create an advanced direct-runtime view of this sandbox.
2654
+ *
2655
+ * Runtime methods on the returned instance talk to the sandbox runtime
2656
+ * directly using `connection.runtimeUrl` and `connection.authToken`.
2657
+ * Lifecycle methods still go through the parent SDK client.
2658
+ */
2659
+ direct(): SandboxInstance;
2660
+ /**
2661
+ * Refresh sandbox information from the server.
2662
+ */
2663
+ refresh(): Promise<void>;
2664
+ /**
2665
+ * Bootstrap a real-time collaboration session for a file.
2666
+ * Returns the WebSocket URL and auth token needed to connect a
2667
+ * Hocuspocus/Yjs provider for live multi-user editing.
2668
+ *
2669
+ * @example
2670
+ * ```typescript
2671
+ * const collab = await box.collaborate("src/index.ts")
2672
+ * // Use collab.transport.websocketUrl + collab.transport.token
2673
+ * // with @hocuspocus/provider to connect
2674
+ * ```
2675
+ */
2676
+ collaborate(path: string, options?: {
2677
+ access?: "read" | "write";
2678
+ }): Promise<{
2679
+ documentId: string;
2680
+ transport: {
2681
+ websocketUrl: string;
2682
+ token: string;
2683
+ expiresAt: number;
2684
+ };
2685
+ permissions: {
2686
+ access: "read" | "write";
2687
+ canSnapshot: boolean;
2688
+ };
2689
+ }>;
2690
+ /**
2691
+ * Refresh a collaboration token for an existing document session.
2692
+ */
2693
+ /**
2694
+ * Refresh a collaboration token. Access level is preserved from the original
2695
+ * token — cannot be escalated (read stays read, write stays write).
2696
+ */
2697
+ refreshCollaborationToken(documentId: string, currentToken: string): Promise<{
2698
+ token: string;
2699
+ expiresAt: number;
2700
+ access: "read" | "write";
2701
+ }>;
2702
+ /**
2703
+ * Get SSH credentials for connecting to the sandbox.
2704
+ * Throws if SSH is not enabled or sandbox is not running.
2705
+ */
2706
+ ssh(): Promise<SSHCredentials>;
2707
+ /**
2708
+ * Execute a command in the sandbox.
2709
+ */
2710
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
2711
+ /**
2712
+ * Read a file from the sandbox.
2713
+ *
2714
+ * @param path - Path to the file. Relative paths resolve from the workspace root.
2715
+ * Absolute paths (e.g., `/tmp/output.json`) access the container filesystem directly.
2716
+ * @returns File content as string
2717
+ *
2718
+ * @example
2719
+ * ```typescript
2720
+ * const content = await box.read("src/index.ts");
2721
+ * const report = await box.read("/output/report.json");
2722
+ * ```
2723
+ */
2724
+ read(path: string): Promise<string>;
2725
+ /**
2726
+ * Write content to a file in the sandbox.
2727
+ *
2728
+ * @param path - Path to the file. Relative paths resolve from the workspace root.
2729
+ * Absolute paths (e.g., `/tmp/cases.json`) write to the container filesystem directly.
2730
+ * @param content - Content to write
2731
+ *
2732
+ * @example
2733
+ * ```typescript
2734
+ * await box.write("src/fix.ts", "export const fix = () => {}");
2735
+ * await box.write("/tmp/config.json", JSON.stringify(config));
2736
+ * ```
2737
+ */
2738
+ write(path: string, content: string): Promise<void>;
2739
+ /**
2740
+ * Send a prompt to the agent running in the sandbox.
2741
+ * Returns the complete response after the agent finishes.
2742
+ */
2743
+ prompt(message: string | PromptInputPart[], options?: PromptOptions): Promise<PromptResult>;
2744
+ /**
2745
+ * Stream events from an agent prompt.
2746
+ * Use this for real-time updates during agent execution.
2747
+ *
2748
+ * Automatically reconnects via the runtime event replay endpoint if the
2749
+ * SSE stream drops before a terminal event (`result` or `done`) is received.
2750
+ * Reconnection is transparent — replayed events that were already yielded
2751
+ * (based on event ID tracking) are deduplicated.
2752
+ */
2753
+ streamPrompt(message: string | PromptInputPart[], options?: PromptOptions): AsyncGenerator<SandboxEvent>;
2754
+ /**
2755
+ * Stream sandbox lifecycle and activity events.
2756
+ */
2757
+ events(options?: EventStreamOptions): AsyncGenerator<SandboxEvent>;
2758
+ /**
2759
+ * Stream real-time provisioning progress events.
2760
+ *
2761
+ * Connects to the SSE events stream and yields typed `ProvisionEvent` objects
2762
+ * for each provisioning step. The generator completes when provisioning
2763
+ * finishes (success or failure) and returns the terminal result.
2764
+ *
2765
+ * @returns AsyncGenerator of ProvisionEvent, with a ProvisionResult return value
2766
+ *
2767
+ * @example
2768
+ * ```typescript
2769
+ * const box = await client.create({ image: "ethereum" });
2770
+ *
2771
+ * const stream = box.watchProvisioning();
2772
+ * for await (const event of stream) {
2773
+ * console.log(`[${event.step}] ${event.status} — ${event.message}`);
2774
+ * }
2775
+ * // stream.return value contains the terminal result
2776
+ * ```
2777
+ */
2778
+ watchProvisioning(options?: {
2779
+ signal?: AbortSignal;
2780
+ }): AsyncGenerator<ProvisionEvent, ProvisionResult | undefined>;
2781
+ /**
2782
+ * Run an agentic task until completion.
2783
+ *
2784
+ * Unlike prompt(), task() is designed for autonomous agent work:
2785
+ * - The agent works until it completes the task or hits an error
2786
+ * - Session state is maintained for context continuity
2787
+ * - Token usage is aggregated across the execution
2788
+ *
2789
+ * Note: The agent (OpenCode/Claude) handles multi-turn execution internally.
2790
+ * Most tasks complete in a single call. The maxTurns option is for edge cases
2791
+ * where the agent explicitly signals it needs additional input.
2792
+ *
2793
+ * @param prompt - Task description for the agent
2794
+ * @param options - Task options
2795
+ * @returns Task result with response and execution metadata
2796
+ */
2797
+ task(prompt: string, options?: TaskOptions): Promise<TaskResult>;
2798
+ /**
2799
+ * Stream events from a task execution.
2800
+ *
2801
+ * Use this for real-time updates as the agent works:
2802
+ * - Tool calls and results
2803
+ * - Thinking/reasoning steps
2804
+ * - File operations
2805
+ * - Final response
2806
+ *
2807
+ * @param prompt - Task description for the agent
2808
+ * @param options - Task options
2809
+ */
2810
+ streamTask(prompt: string, options?: TaskOptions): AsyncGenerator<SandboxEvent>;
2811
+ /**
2812
+ * Search for text patterns in files using ripgrep.
2813
+ *
2814
+ * This is a first-class code search capability, not a shell wrapper.
2815
+ * Ripgrep is pre-installed in all managed sandboxes.
2816
+ *
2817
+ * @param pattern - Regular expression pattern to search for
2818
+ * @param options - Search options
2819
+ * @returns Async iterator of search matches
2820
+ *
2821
+ * @example Search for task-marker comments
2822
+ * ```typescript
2823
+ * for await (const match of box.search("TASK:", { glob: "**\/*.ts" })) {
2824
+ * console.log(`${match.path}:${match.line}: ${match.text}`);
2825
+ * }
2826
+ * ```
2827
+ *
2828
+ * @example Collect all matches
2829
+ * ```typescript
2830
+ * const matches = [];
2831
+ * for await (const match of box.search("function.*async")) {
2832
+ * matches.push(match);
2833
+ * }
2834
+ * ```
2835
+ */
2836
+ search(pattern: string, options?: SearchOptions): AsyncGenerator<SearchMatch>;
2837
+ /**
2838
+ * Git capability object for repository operations.
2839
+ *
2840
+ * All git operations are executed in the sandbox workspace.
2841
+ *
2842
+ * @example Check status and commit
2843
+ * ```typescript
2844
+ * const status = await box.git.status();
2845
+ * if (status.isDirty) {
2846
+ * await box.git.add(["."]);
2847
+ * await box.git.commit("Update files");
2848
+ * await box.git.push();
2849
+ * }
2850
+ * ```
2851
+ */
2852
+ get git(): GitCapability;
2853
+ private gitStatus;
2854
+ private gitLog;
2855
+ private gitDiff;
2856
+ private gitAdd;
2857
+ private gitCommit;
2858
+ private gitPush;
2859
+ private gitPull;
2860
+ private gitBranches;
2861
+ private gitCheckout;
2862
+ /**
2863
+ * Tools capability object for managing language runtimes.
2864
+ *
2865
+ * Uses mise (polyglot version manager) to install and manage tools.
2866
+ *
2867
+ * @example Install and use Node.js
2868
+ * ```typescript
2869
+ * await box.tools.install("node", "22");
2870
+ * await box.tools.use("node", "22");
2871
+ * const list = await box.tools.list();
2872
+ * ```
2873
+ */
2874
+ get tools(): ToolsCapability;
2875
+ /**
2876
+ * Enhanced file system operations.
2877
+ *
2878
+ * Provides comprehensive file operations beyond basic read/write:
2879
+ * - Binary file upload/download
2880
+ * - Directory operations (uploadDir, downloadDir, list, mkdir)
2881
+ * - File metadata (stat, exists)
2882
+ * - Progress reporting for large files
2883
+ *
2884
+ * @example Upload and download
2885
+ * ```typescript
2886
+ * await box.fs.upload("./model.bin", "/workspace/models/model.bin");
2887
+ * await box.fs.download("/workspace/results.zip", "./results.zip");
2888
+ * ```
2889
+ *
2890
+ * @example Directory operations
2891
+ * ```typescript
2892
+ * await box.fs.uploadDir("./project", "/workspace/project");
2893
+ * const files = await box.fs.list("/workspace");
2894
+ * ```
2895
+ *
2896
+ * @example File management
2897
+ * ```typescript
2898
+ * if (await box.fs.exists("/workspace/config.json")) {
2899
+ * const info = await box.fs.stat("/workspace/config.json");
2900
+ * console.log(`Size: ${info.size}`);
2901
+ * }
2902
+ * await box.fs.mkdir("/workspace/output", { recursive: true });
2903
+ * await box.fs.delete("/workspace/temp", { recursive: true });
2904
+ * ```
2905
+ */
2906
+ get fs(): FileSystem;
2907
+ private fsUpload;
2908
+ private fsDownload;
2909
+ private fsUploadDir;
2910
+ private fsDownloadDir;
2911
+ private fsList;
2912
+ private fsStat;
2913
+ private fsDelete;
2914
+ private fsMkdir;
2915
+ private fsExists;
2916
+ /**
2917
+ * Permissions manager for multi-user access control.
2918
+ *
2919
+ * @example List users
2920
+ * ```typescript
2921
+ * const users = await box.permissions.list();
2922
+ * for (const user of users) {
2923
+ * console.log(`${user.username}: ${user.role}`);
2924
+ * }
2925
+ * ```
2926
+ *
2927
+ * @example Add a developer
2928
+ * ```typescript
2929
+ * await box.permissions.add({
2930
+ * userId: "user_abc",
2931
+ * role: "developer",
2932
+ * sshKeys: ["ssh-ed25519 AAAA..."],
2933
+ * });
2934
+ * ```
2935
+ */
2936
+ get permissions(): PermissionsManager;
2937
+ private permissionsList;
2938
+ private permissionsGet;
2939
+ private permissionsAdd;
2940
+ private permissionsUpdate;
2941
+ private permissionsRemove;
2942
+ private permissionsSetAccessPolicies;
2943
+ private permissionsGetAccessPolicies;
2944
+ private permissionsCheckAccess;
2945
+ /**
2946
+ * Backend manager for runtime agent configuration.
2947
+ *
2948
+ * @example Check backend status
2949
+ * ```typescript
2950
+ * const status = await box.backend.status();
2951
+ * console.log(`Backend: ${status.type}, Status: ${status.status}`);
2952
+ * ```
2953
+ *
2954
+ * @example Add MCP server at runtime
2955
+ * ```typescript
2956
+ * await box.backend.addMcp("web-search", {
2957
+ * command: "npx",
2958
+ * args: ["-y", "@anthropic/web-search"],
2959
+ * });
2960
+ * ```
2961
+ */
2962
+ get backend(): BackendManager;
2963
+ private backendStatus;
2964
+ private backendCapabilities;
2965
+ private backendAddMcp;
2966
+ private backendGetMcpStatus;
2967
+ private backendUpdateConfig;
2968
+ private backendRestart;
2969
+ /**
2970
+ * Process manager for spawning and controlling processes.
2971
+ *
2972
+ * Provides non-blocking process execution with real-time log streaming,
2973
+ * ideal for long-running tasks like ML training or dev servers.
2974
+ *
2975
+ * @example Non-blocking process
2976
+ * ```typescript
2977
+ * const proc = await box.process.spawn("python train.py", {
2978
+ * cwd: "/workspace",
2979
+ * env: { "CUDA_VISIBLE_DEVICES": "0" }
2980
+ * });
2981
+ *
2982
+ * // Stream logs
2983
+ * for await (const entry of proc.logs()) {
2984
+ * console.log(`[${entry.type}] ${entry.data}`);
2985
+ * }
2986
+ *
2987
+ * // Check status
2988
+ * const status = await proc.status();
2989
+ * console.log(`Running: ${status.running}`);
2990
+ *
2991
+ * // Kill if needed
2992
+ * await proc.kill();
2993
+ * ```
2994
+ *
2995
+ * @example Run Python code directly
2996
+ * ```typescript
2997
+ * const result = await box.process.runCode(`
2998
+ * import numpy as np
2999
+ * print(np.random.rand(10).mean())
3000
+ * `);
3001
+ * console.log(result.stdout);
3002
+ * ```
3003
+ */
3004
+ get process(): ProcessManager;
3005
+ private processSpawn;
3006
+ private processRunCode;
3007
+ private processList;
3008
+ private processGet;
3009
+ private createProcessHandle;
3010
+ private parseProcessLogStream;
3011
+ /**
3012
+ * Network manager for runtime network configuration.
3013
+ *
3014
+ * @example Update network restrictions
3015
+ * ```typescript
3016
+ * // Block all outbound traffic
3017
+ * await box.network.update({ blockOutbound: true });
3018
+ *
3019
+ * // Or switch to allowlist mode
3020
+ * await box.network.update({
3021
+ * allowList: ["192.168.1.0/24", "8.8.8.8/32"]
3022
+ * });
3023
+ * ```
3024
+ *
3025
+ * @example Expose ports dynamically
3026
+ * ```typescript
3027
+ * const url = await box.network.exposePort(8000);
3028
+ * console.log(`Service available at: ${url}`);
3029
+ * ```
3030
+ */
3031
+ get network(): NetworkManager;
3032
+ private networkUpdate;
3033
+ private networkExposePort;
3034
+ private networkListUrls;
3035
+ private networkGetConfig;
3036
+ /**
3037
+ * Validate CIDR notation (IPv4 and IPv6)
3038
+ */
3039
+ private isValidCidr;
3040
+ /**
3041
+ * Preview link management.
3042
+ *
3043
+ * Create publicly accessible HTTPS URLs for TCP ports inside the sandbox.
3044
+ *
3045
+ * @example
3046
+ * ```typescript
3047
+ * const link = await box.previewLinks.create(3000);
3048
+ * console.log(link.url);
3049
+ *
3050
+ * const links = await box.previewLinks.list();
3051
+ * await box.previewLinks.remove(link.previewId);
3052
+ * ```
3053
+ */
3054
+ get previewLinks(): PreviewLinkManager;
3055
+ private previewLinkCreate;
3056
+ private previewLinkList;
3057
+ private previewLinkRemove;
3058
+ /**
3059
+ * Get information about the infrastructure driver for this sandbox.
3060
+ *
3061
+ * @example
3062
+ * ```typescript
3063
+ * const info = await box.getDriverInfo();
3064
+ * console.log(`Driver: ${info.type}, CRIU: ${info.capabilities.criu}`);
3065
+ * ```
3066
+ */
3067
+ getDriverInfo(): Promise<DriverInfo>;
3068
+ private toolsInstall;
3069
+ private toolsUse;
3070
+ private toolsList;
3071
+ private toolsRun;
3072
+ /**
3073
+ * Create a snapshot of the sandbox state.
3074
+ * Snapshots can be used to save workspace state for later restoration.
3075
+ *
3076
+ * If `storage` is provided (BYOS3), the snapshot is created directly
3077
+ * directly on the sandbox and uploaded to customer-provided S3 storage.
3078
+ *
3079
+ * @param options - Snapshot options (tags, paths, storage)
3080
+ * @returns Snapshot result with ID and metadata
3081
+ *
3082
+ * @example Standard snapshot (our storage)
3083
+ * ```typescript
3084
+ * const snap = await box.snapshot({
3085
+ * tags: ["v1.0", "stable"],
3086
+ * });
3087
+ * console.log(`Snapshot: ${snap.snapshotId}`);
3088
+ * ```
3089
+ *
3090
+ * @example BYOS3 snapshot (customer storage)
3091
+ * ```typescript
3092
+ * const snap = await box.snapshot({
3093
+ * tags: ["production"],
3094
+ * storage: {
3095
+ * type: "s3",
3096
+ * bucket: "my-snapshots",
3097
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
3098
+ * },
3099
+ * });
3100
+ * ```
3101
+ */
3102
+ snapshot(options?: SnapshotOptions): Promise<SnapshotResult>;
3103
+ /**
3104
+ * List all snapshots for this sandbox.
3105
+ *
3106
+ * If `storage` is provided (BYOS3), lists snapshots from customer-provided
3107
+ * S3 storage.
3108
+ *
3109
+ * @param storage - Optional customer storage config for BYOS3
3110
+ * @returns Array of snapshot metadata
3111
+ *
3112
+ * @example List from our storage
3113
+ * ```typescript
3114
+ * const snapshots = await box.listSnapshots();
3115
+ * for (const snap of snapshots) {
3116
+ * console.log(`${snap.snapshotId}: ${snap.createdAt}`);
3117
+ * }
3118
+ * ```
3119
+ *
3120
+ * @example List from customer S3 (BYOS3)
3121
+ * ```typescript
3122
+ * const snapshots = await box.listSnapshots({
3123
+ * type: "s3",
3124
+ * bucket: "my-snapshots",
3125
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
3126
+ * });
3127
+ * ```
3128
+ */
3129
+ listSnapshots(storage?: SnapshotOptions["storage"]): Promise<SnapshotInfo[]>;
3130
+ revertToSnapshot(snapshotId: string): Promise<SnapshotResult>;
3131
+ private waitForSnapshotRestore;
3132
+ deleteSnapshot(snapshotId: string): Promise<void>;
3133
+ /**
3134
+ * Restore from the latest snapshot in customer-provided storage.
3135
+ * Only available when using BYOS3 (calls the runtime directly).
3136
+ *
3137
+ * @param storage - Customer storage config (required)
3138
+ * @param destinationPath - Optional path to restore to
3139
+ * @returns Snapshot info if restored, null if no snapshot found
3140
+ *
3141
+ * @example Restore from customer S3
3142
+ * ```typescript
3143
+ * const result = await box.restoreFromStorage({
3144
+ * type: "s3",
3145
+ * bucket: "my-snapshots",
3146
+ * credentials: { accessKeyId: "...", secretAccessKey: "..." },
3147
+ * });
3148
+ *
3149
+ * if (result) {
3150
+ * console.log(`Restored from ${result.snapshotId}`);
3151
+ * } else {
3152
+ * console.log("No snapshot found");
3153
+ * }
3154
+ * ```
3155
+ */
3156
+ restoreFromStorage(storage: SnapshotOptions["storage"], options?: RestoreSnapshotOptions): Promise<SnapshotResult | null>;
3157
+ /**
3158
+ * Create a CRIU checkpoint of the sandbox's memory state.
3159
+ *
3160
+ * Checkpoints capture the complete memory state of the running sandbox,
3161
+ * enabling true pause/resume and fork operations. Unlike snapshots which
3162
+ * only preserve filesystem state, checkpoints preserve process memory,
3163
+ * open file descriptors, and execution state.
3164
+ *
3165
+ * **Requirements:** CRIU must be available on the host. Check availability
3166
+ * with `client.criuStatus()` before calling.
3167
+ *
3168
+ * **Note:** By default, checkpoint stops the sandbox. Use `leaveRunning: true`
3169
+ * to keep it running (creates a copy-on-write checkpoint).
3170
+ *
3171
+ * @param options - Checkpoint options
3172
+ * @returns Checkpoint result with ID and metadata
3173
+ *
3174
+ * @example Basic checkpoint (stops sandbox)
3175
+ * ```typescript
3176
+ * const checkpoint = await box.checkpoint();
3177
+ * console.log(`Checkpoint: ${checkpoint.checkpointId}`);
3178
+ * // Sandbox is now stopped, resume with box.resume()
3179
+ * ```
3180
+ *
3181
+ * @example Checkpoint without stopping
3182
+ * ```typescript
3183
+ * const checkpoint = await box.checkpoint({
3184
+ * tags: ["before-deploy"],
3185
+ * leaveRunning: true,
3186
+ * });
3187
+ * // Sandbox continues running
3188
+ * ```
3189
+ */
3190
+ checkpoint(options?: CheckpointOptions): Promise<CheckpointResult>;
3191
+ /**
3192
+ * List all checkpoints for this sandbox.
3193
+ *
3194
+ * @returns Array of checkpoint metadata
3195
+ *
3196
+ * @example
3197
+ * ```typescript
3198
+ * const checkpoints = await box.listCheckpoints();
3199
+ * for (const cp of checkpoints) {
3200
+ * console.log(`${cp.checkpointId}: ${cp.createdAt}`);
3201
+ * }
3202
+ * ```
3203
+ */
3204
+ listCheckpoints(): Promise<CheckpointInfo[]>;
3205
+ /**
3206
+ * Delete a checkpoint.
3207
+ *
3208
+ * @param checkpointId - ID of the checkpoint to delete
3209
+ */
3210
+ deleteCheckpoint(checkpointId: string): Promise<void>;
3211
+ /**
3212
+ * Fork a new sandbox from a checkpoint.
3213
+ *
3214
+ * Creates a new sandbox with the same memory state as this sandbox
3215
+ * at the time of the checkpoint. The fork has a new identity but
3216
+ * preserves the execution state.
3217
+ *
3218
+ * **Use cases:**
3219
+ * - Branch workflows: Create parallel execution paths
3220
+ * - A/B testing: Run same state with different configurations
3221
+ * - Debugging: Fork at a specific point to investigate
3222
+ *
3223
+ * @param checkpointId - ID of the checkpoint to fork from
3224
+ * @param options - Fork configuration
3225
+ * @returns The new sandbox instance
3226
+ *
3227
+ * @example Basic fork
3228
+ * ```typescript
3229
+ * const checkpoint = await box.checkpoint({ leaveRunning: true });
3230
+ * const forked = await box.fork(checkpoint.checkpointId);
3231
+ * // forked has same memory state as box at checkpoint time
3232
+ * ```
3233
+ *
3234
+ * @example Fork with custom config
3235
+ * ```typescript
3236
+ * const forked = await box.fork(checkpointId, {
3237
+ * name: "experiment-branch",
3238
+ * env: { EXPERIMENT: "true" },
3239
+ * });
3240
+ * ```
3241
+ */
3242
+ fork(checkpointId: string, options?: ForkOptions): Promise<SandboxInstance>;
3243
+ /**
3244
+ * Stop the sandbox (keeps state for resume).
3245
+ */
3246
+ stop(): Promise<void>;
3247
+ /**
3248
+ * Resume a stopped sandbox.
3249
+ */
3250
+ resume(): Promise<void>;
3251
+ /**
3252
+ * Delete the sandbox permanently.
3253
+ */
3254
+ delete(): Promise<void>;
3255
+ /**
3256
+ * keepAlive is intentionally unavailable until the API exposes timeout updates.
3257
+ * @param seconds - Reserved for future support
3258
+ */
3259
+ keepAlive(_seconds?: number): Promise<void>;
3260
+ /**
3261
+ * Upload a local directory to the sandbox via tar.
3262
+ * @param localPath - Local directory path to upload
3263
+ * @param remotePath - Destination path in the sandbox (default: /home/user)
3264
+ */
3265
+ uploadDirectory(localPath: string, remotePath?: string): Promise<void>;
3266
+ /**
3267
+ * Wait for the sandbox to reach a specific status.
3268
+ *
3269
+ * When `onProgress` is provided and the sandbox is still provisioning,
3270
+ * uses SSE events for real-time progress instead of polling. Falls back
3271
+ * to polling if the SSE connection fails or is unavailable.
3272
+ *
3273
+ * @example Basic wait
3274
+ * ```typescript
3275
+ * await box.waitFor("running");
3276
+ * ```
3277
+ *
3278
+ * @example Wait with progress tracking
3279
+ * ```typescript
3280
+ * await box.waitFor("running", {
3281
+ * onProgress: (event) => {
3282
+ * console.log(`[${event.step}] ${event.status} — ${event.message}`);
3283
+ * if (event.percent !== undefined) {
3284
+ * updateProgressBar(event.percent);
3285
+ * }
3286
+ * },
3287
+ * });
3288
+ * ```
3289
+ */
3290
+ waitFor(status: SandboxStatus | SandboxStatus[], options?: WaitForOptions): Promise<void>;
3291
+ /**
3292
+ * SSE-based wait implementation. Subscribes to provisioning events and
3293
+ * delivers progress callbacks while waiting for a target status.
3294
+ */
3295
+ private waitForWithSSE;
3296
+ private parseCheckpointInfo;
3297
+ private ensureRunning;
3298
+ private runtimeFetch;
3299
+ /**
3300
+ * Delegates to the shared `parseSSEStream` in `lib/sse-parser.ts`
3301
+ * — one canonical SSE implementation for the whole SDK. The
3302
+ * shared parser throws `AbortError` on cancellation (so consumers
3303
+ * can distinguish cancel from clean EOF), but agent/task streaming
3304
+ * callers of this method historically relied on a silent-return
3305
+ * abort: they check `options?.signal?.aborted` AFTER the loop and
3306
+ * decide whether to reconnect. The try/catch below preserves that
3307
+ * legacy contract by swallowing AbortError at the delegate layer.
3308
+ */
3309
+ private parseSSEStream;
3310
+ /**
3311
+ * Associate a session ID with a user ID so the Sandbox API can route
3312
+ * subsequent WebSocket connections to this sandbox.
3313
+ *
3314
+ * @param opts - Session and user identifiers
3315
+ *
3316
+ * @example
3317
+ * ```typescript
3318
+ * await box.registerSessionMapping({
3319
+ * sessionId: "sess_abc",
3320
+ * userId: "user_123",
3321
+ * });
3322
+ * ```
3323
+ */
3324
+ registerSessionMapping(opts: {
3325
+ sessionId: string;
3326
+ userId: string;
3327
+ }): Promise<void>;
3328
+ private parseInfo;
3329
+ private sleep;
3330
+ }
3331
+ //#endregion
3332
+ export { Process as $, defineGitHubResource as $t, ExecResult as A, StorageConfig as At, GitStatus as B, AgentProfile as Bt, DownloadOptions as C, SearchMatch as Ct, DriverType as D, SnapshotInfo as Dt, DriverInfo as E, SecretsManager as Et, GitAuth as F, UpdateUserOptions as Ft, McpServerConfig as G, AgentProfilePermissionValue as Gt, InstalledTool as H, AgentProfileFileMount as Ht, GitBranch as I, UploadOptions as It, NetworkManager as J, AgentProfileResources as Jt, MkdirOptions as K, AgentProfilePrompt as Kt, GitCommit as L, UploadProgress as Lt, FileSystem as M, TaskOptions as Mt, ForkOptions as N, TaskResult as Nt, EventStreamOptions as O, SnapshotOptions as Ot, ForkResult as P, ToolsConfig as Pt, PreviewLinkManager as Q, defineAgentProfile as Qt, GitConfig as R, UsageInfo as Rt, DirectoryPermission as S, SandboxUser as St, DriverConfig as T, SecretInfo as Tt, ListOptions as U, AgentProfileMcpServer as Ut, GpuType as V, AgentProfileCapabilities as Vt, ListSandboxOptions as W, AgentProfileModelHints as Wt, PermissionsManager as X, AgentProfileValidationResult as Xt, PermissionLevel as Y, AgentProfileValidationIssue as Yt, PreviewLinkInfo as Z, AgentSubagentProfile as Zt, CheckpointOptions as _, SandboxEvent as _t, BackendCapabilities as a, ProcessStatus as at, CreateSandboxOptions as b, SandboxResources as bt, BackendManager as c, ProvisionEvent as ct, BatchEvent as d, ProvisionStep as dt, defineInlineResource as en, ProcessInfo as et, BatchOptions as f, RunCodeOptions as ft, CheckpointInfo as g, SandboxEnvironment as gt, BatchTaskResult as h, SandboxConnection as ht, AddUserOptions as i, ProcessSpawnOptions as it, FileInfo as j, SubscriptionInfo as jt, ExecOptions as k, SnapshotResult as kt, BackendStatus as l, ProvisionResult as lt, BatchTask as m, SandboxClientConfig as mt, SandboxInstance as n, ProcessManager as nt, BackendConfig as o, PromptOptions as ot, BatchResult as p, SSHCredentials as pt, NetworkConfig as q, AgentProfileResourceRef as qt, AccessPolicyRule as r, ProcessSignal as rt, BackendInfo as s, PromptResult as st, HttpClient as t, mergeAgentProfiles as tn, ProcessLogEntry as tt, BackendType as u, ProvisionStatus as ut, CheckpointResult as v, SandboxInfo as vt, DownloadProgress as w, SearchOptions as wt, DeleteOptions as x, SandboxStatus as xt, CodeResult as y, SandboxPermissionsConfig as yt, GitDiff as z, WaitForOptions as zt };