microsandbox 0.1.1 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.cts ADDED
@@ -0,0 +1,751 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ /**
4
+ * Handle for a streaming command execution.
5
+ *
6
+ * Use `recv()` to get events one at a time, or iterate with a loop:
7
+ * ```js
8
+ * const handle = await sandbox.execStream("tail", ["-f", "/var/log/app.log"]);
9
+ * let event;
10
+ * while ((event = await handle.recv()) !== null) {
11
+ * if (event.eventType === "stdout") process.stdout.write(event.data);
12
+ * }
13
+ * ```
14
+ */
15
+ export declare class ExecHandle {
16
+ /** Get the correlation ID for this execution. */
17
+ get id(): Promise<string>
18
+ /** Receive the next event. Returns `null` when the stream ends. */
19
+ recv(): Promise<ExecEvent | null>
20
+ /** Take the stdin writer. Can only be called once; returns `null` on subsequent calls. */
21
+ takeStdin(): Promise<ExecSink | null>
22
+ /** Wait for the process to exit and return the exit status. */
23
+ wait(): Promise<ExitStatus>
24
+ /** Wait for completion and collect all output. */
25
+ collect(): Promise<ExecOutput>
26
+ /** Send a signal to the running process. */
27
+ signal(signal: number): Promise<void>
28
+ /** Kill the running process (SIGKILL). */
29
+ kill(): Promise<void>
30
+ }
31
+ export type JsExecHandle = ExecHandle
32
+
33
+ /**
34
+ * Output of a completed command execution.
35
+ *
36
+ * Provides both string and raw byte access to stdout/stderr:
37
+ * ```js
38
+ * const output = await sandbox.shell("echo hello");
39
+ * console.log(output.stdout()); // "hello
40
+ "
41
+ * console.log(output.stdoutBytes()); // <Buffer 68 65 6c 6c 6f 0a>
42
+ * console.log(output.code); // 0
43
+ * console.log(output.success); // true
44
+ * ```
45
+ */
46
+ export declare class ExecOutput {
47
+ /** Exit code of the process. */
48
+ get code(): number
49
+ /** Whether the process exited successfully (code == 0). */
50
+ get success(): boolean
51
+ /** Get stdout as a UTF-8 string. */
52
+ stdout(): string
53
+ /** Get stderr as a UTF-8 string. */
54
+ stderr(): string
55
+ /** Get stdout as raw bytes. */
56
+ stdoutBytes(): Buffer
57
+ /** Get stderr as raw bytes. */
58
+ stderrBytes(): Buffer
59
+ /** Get the exit status. */
60
+ status(): ExitStatus
61
+ }
62
+
63
+ /** Stdin writer for a running process. */
64
+ export declare class ExecSink {
65
+ /** Write data to the process stdin. */
66
+ write(data: Buffer): Promise<void>
67
+ /** Close stdin (sends EOF to the process). */
68
+ close(): Promise<void>
69
+ }
70
+ export type JsExecSink = ExecSink
71
+
72
+ /**
73
+ * Factory for creating volume mount configurations.
74
+ *
75
+ * ```js
76
+ * import { Mount, Sandbox } from 'microsandbox'
77
+ *
78
+ * const sb = await Sandbox.create({
79
+ * name: "worker",
80
+ * image: "python:3.12",
81
+ * volumes: {
82
+ * "/app/src": Mount.bind("./src", { readonly: true }),
83
+ * "/data": Mount.named("my-data"),
84
+ * "/tmp": Mount.tmpfs({ sizeMib: 100 }),
85
+ * },
86
+ * })
87
+ * ```
88
+ */
89
+ export declare class Mount {
90
+ /** Create a bind mount (host directory → guest path). */
91
+ static bind(path: string, opts?: MountOptions | undefined | null): MountConfig
92
+ /** Create a named volume mount. */
93
+ static named(name: string, opts?: MountOptions | undefined | null): MountConfig
94
+ /** Create a tmpfs (in-memory) mount. */
95
+ static tmpfs(opts?: TmpfsOptions | undefined | null): MountConfig
96
+ }
97
+
98
+ /**
99
+ * Factory for creating network policy configurations.
100
+ *
101
+ * ```js
102
+ * import { NetworkPolicy, Sandbox } from 'microsandbox'
103
+ *
104
+ * const sb = await Sandbox.create({
105
+ * name: "worker",
106
+ * image: "python:3.12",
107
+ * network: NetworkPolicy.publicOnly(),
108
+ * })
109
+ * ```
110
+ */
111
+ export declare class NetworkPolicy {
112
+ /** No network access at all. */
113
+ static none(): NetworkConfig
114
+ /** Public internet only — blocks private ranges (default). */
115
+ static publicOnly(): NetworkConfig
116
+ /** Unrestricted network access. */
117
+ static allowAll(): NetworkConfig
118
+ }
119
+ export type JsNetworkPolicy = NetworkPolicy
120
+
121
+ /**
122
+ * Factory for creating rootfs patch configurations.
123
+ *
124
+ * ```js
125
+ * import { Patch, Sandbox } from 'microsandbox'
126
+ *
127
+ * const sb = await Sandbox.create({
128
+ * name: "worker",
129
+ * image: "alpine",
130
+ * patches: [
131
+ * Patch.text("/etc/greeting.txt", "Hello!
132
+ "),
133
+ * Patch.mkdir("/app", { mode: 0o755 }),
134
+ * Patch.append("/etc/hosts", "127.0.0.1 myapp.local
135
+ "),
136
+ * Patch.copyFile("./config.json", "/app/config.json"),
137
+ * Patch.copyDir("./scripts", "/app/scripts"),
138
+ * Patch.symlink("/usr/bin/python3", "/usr/bin/python"),
139
+ * Patch.remove("/etc/motd"),
140
+ * ],
141
+ * })
142
+ * ```
143
+ */
144
+ export declare class Patch {
145
+ /** Write text content to a file in the guest filesystem. */
146
+ static text(path: string, content: string, opts?: PatchOptions | undefined | null): PatchConfig
147
+ /** Create a directory in the guest filesystem (idempotent). */
148
+ static mkdir(path: string, opts?: PatchOptions | undefined | null): PatchConfig
149
+ /** Append content to an existing file in the guest filesystem. */
150
+ static append(path: string, content: string): PatchConfig
151
+ /** Copy a file from the host into the guest filesystem. */
152
+ static copyFile(src: string, dst: string, opts?: PatchOptions | undefined | null): PatchConfig
153
+ /** Copy a directory from the host into the guest filesystem. */
154
+ static copyDir(src: string, dst: string, opts?: PatchReplaceOptions | undefined | null): PatchConfig
155
+ /** Create a symlink in the guest filesystem. */
156
+ static symlink(target: string, link: string, opts?: PatchReplaceOptions | undefined | null): PatchConfig
157
+ /** Remove a file or directory from the guest filesystem (idempotent). */
158
+ static remove(path: string): PatchConfig
159
+ }
160
+
161
+ /**
162
+ * A running sandbox instance.
163
+ *
164
+ * Created via `Sandbox.create()` or `Sandbox.start()`. Holds a live connection
165
+ * to the guest VM and can execute commands, access the filesystem, and query metrics.
166
+ */
167
+ export declare class Sandbox {
168
+ /** Create a sandbox from configuration (attached mode — stops on GC/process exit). */
169
+ static create(config: SandboxConfig): Promise<Sandbox>
170
+ /** Create a sandbox that survives the parent process (detached mode). */
171
+ static createDetached(config: SandboxConfig): Promise<Sandbox>
172
+ /** Start an existing stopped sandbox (attached mode). */
173
+ static start(name: string): Promise<Sandbox>
174
+ /** Start an existing stopped sandbox (detached mode). */
175
+ static startDetached(name: string): Promise<Sandbox>
176
+ /** Get a lightweight handle to an existing sandbox. */
177
+ static get(name: string): Promise<JsSandboxHandle>
178
+ /** List all sandboxes. */
179
+ static list(): Promise<Array<SandboxInfo>>
180
+ /** Remove a stopped sandbox from the database. */
181
+ static remove(name: string): Promise<void>
182
+ /** Sandbox name. */
183
+ get name(): Promise<string>
184
+ /** Whether this handle owns the sandbox lifecycle (attached mode). */
185
+ get ownsLifecycle(): Promise<boolean>
186
+ /** Execute a command and wait for completion. */
187
+ exec(cmd: string, args?: Array<string> | undefined | null): Promise<ExecOutput>
188
+ /** Execute a command with full configuration and wait for completion. */
189
+ execWithConfig(config: ExecConfig): Promise<ExecOutput>
190
+ /** Execute a command with streaming I/O. */
191
+ execStream(cmd: string, args?: Array<string> | undefined | null): Promise<ExecHandle>
192
+ /** Execute a shell command using the sandbox's configured shell. */
193
+ shell(script: string): Promise<ExecOutput>
194
+ /** Execute a shell command with streaming I/O. */
195
+ shellStream(script: string): Promise<ExecHandle>
196
+ /** Get a filesystem handle for operations on the running sandbox. */
197
+ fs(): SandboxFs
198
+ /** Get point-in-time resource metrics. */
199
+ metrics(): Promise<SandboxMetrics>
200
+ /** Stop the sandbox gracefully (SIGTERM). */
201
+ stop(): Promise<void>
202
+ /** Stop and wait for exit, returning the exit status. */
203
+ stopAndWait(): Promise<ExitStatus>
204
+ /** Kill the sandbox immediately (SIGKILL). */
205
+ kill(): Promise<void>
206
+ /** Graceful drain (SIGUSR1 — for load balancing). */
207
+ drain(): Promise<void>
208
+ /** Wait for the sandbox process to exit. */
209
+ wait(): Promise<ExitStatus>
210
+ /** Detach from the sandbox — it will continue running after this handle is dropped. */
211
+ detach(): Promise<void>
212
+ /** Remove the persisted database record after stopping. */
213
+ removePersisted(): Promise<void>
214
+ }
215
+
216
+ /** Filesystem operations on a running sandbox (via agent protocol). */
217
+ export declare class SandboxFs {
218
+ /** Read a file as a Buffer. */
219
+ read(path: string): Promise<Buffer>
220
+ /** Read a file as a UTF-8 string. */
221
+ readString(path: string): Promise<string>
222
+ /** Write data to a file (accepts Buffer or string). */
223
+ write(path: string, data: Buffer): Promise<void>
224
+ /** List directory contents. */
225
+ list(path: string): Promise<Array<FsEntry>>
226
+ /** Create a directory. */
227
+ mkdir(path: string): Promise<void>
228
+ /** Remove a directory. */
229
+ removeDir(path: string): Promise<void>
230
+ /** Remove a file. */
231
+ remove(path: string): Promise<void>
232
+ /** Copy a file within the sandbox. */
233
+ copy(from: string, to: string): Promise<void>
234
+ /** Rename a file within the sandbox. */
235
+ rename(from: string, to: string): Promise<void>
236
+ /** Get file or directory metadata. */
237
+ stat(path: string): Promise<FsMetadata>
238
+ /** Check if a path exists. */
239
+ exists(path: string): Promise<boolean>
240
+ /** Copy a file from the host into the sandbox. */
241
+ copyFromHost(hostPath: string, guestPath: string): Promise<void>
242
+ /** Copy a file from the sandbox to the host. */
243
+ copyToHost(guestPath: string, hostPath: string): Promise<void>
244
+ }
245
+ export type JsSandboxFs = SandboxFs
246
+
247
+ /**
248
+ * A lightweight handle to a sandbox from the database.
249
+ *
250
+ * Does NOT hold a live connection — use `connect()` or `start()` to get a live `Sandbox`.
251
+ */
252
+ export declare class SandboxHandle {
253
+ /** Sandbox name. */
254
+ get name(): string
255
+ /** Status at time of query: "running", "stopped", "crashed", or "draining". */
256
+ get status(): string
257
+ /** Raw config JSON string from the database. */
258
+ get configJson(): string
259
+ /** Creation timestamp as ms since Unix epoch. */
260
+ get createdAt(): number | null
261
+ /** Last update timestamp as ms since Unix epoch. */
262
+ get updatedAt(): number | null
263
+ /** Get point-in-time metrics from the database. */
264
+ metrics(): Promise<SandboxMetrics>
265
+ /** Start the sandbox (attached mode) — returns a live Sandbox handle. */
266
+ start(): Promise<Sandbox>
267
+ /** Start the sandbox (detached mode). */
268
+ startDetached(): Promise<Sandbox>
269
+ /** Connect to an already-running sandbox (no lifecycle ownership). */
270
+ connect(): Promise<Sandbox>
271
+ /** Stop the sandbox (SIGTERM). */
272
+ stop(): Promise<void>
273
+ /** Kill the sandbox (SIGKILL). */
274
+ kill(): Promise<void>
275
+ /** Remove the sandbox from the database. */
276
+ remove(): Promise<void>
277
+ }
278
+ export type JsSandboxHandle = SandboxHandle
279
+
280
+ /**
281
+ * Factory for creating secret entries.
282
+ *
283
+ * ```js
284
+ * import { Secret, Sandbox } from 'microsandbox'
285
+ *
286
+ * const sb = await Sandbox.create({
287
+ * name: "agent",
288
+ * image: "python:3.12",
289
+ * secrets: [
290
+ * Secret.env("OPENAI_API_KEY", {
291
+ * value: process.env.OPENAI_API_KEY,
292
+ * allowHosts: ["api.openai.com"],
293
+ * }),
294
+ * ],
295
+ * })
296
+ * ```
297
+ */
298
+ export declare class Secret {
299
+ /** Create a secret bound to an environment variable. */
300
+ static env(envVar: string, opts: SecretEnvOptions): SecretEntry
301
+ }
302
+
303
+ /** A named persistent volume. */
304
+ export declare class Volume {
305
+ /** Create a new named volume. */
306
+ static create(config: VolumeConfig): Promise<Volume>
307
+ /** Get a lightweight handle to an existing volume. */
308
+ static get(name: string): Promise<VolumeHandle>
309
+ /** List all volumes. */
310
+ static list(): Promise<Array<VolumeInfo>>
311
+ /** Remove a volume. */
312
+ static remove(name: string): Promise<void>
313
+ /** Volume name. */
314
+ get name(): string
315
+ /** Host path of the volume. */
316
+ get path(): string
317
+ }
318
+ export type JsVolume = Volume
319
+
320
+ /** A lightweight handle to a volume from the database. */
321
+ export declare class VolumeHandle {
322
+ /** Volume name. */
323
+ get name(): string
324
+ /** Size quota in MiB, if set. */
325
+ get quotaMib(): number | null
326
+ /** Used bytes on disk. */
327
+ get usedBytes(): number
328
+ /** Key-value labels. */
329
+ get labels(): Record<string, string>
330
+ /** Creation timestamp as ms since epoch. */
331
+ get createdAt(): number | null
332
+ /** Remove this volume. */
333
+ remove(): Promise<void>
334
+ }
335
+ export type JsVolumeHandle = VolumeHandle
336
+
337
+ /** Get metrics for all running sandboxes. */
338
+ export declare function allSandboxMetrics(): Promise<Record<string, SandboxMetrics>>
339
+
340
+ /** Configuration for command execution. */
341
+ export interface ExecConfig {
342
+ /** Command to execute. */
343
+ cmd: string
344
+ /** Command arguments. */
345
+ args?: Array<string>
346
+ /** Working directory inside the sandbox. */
347
+ cwd?: string
348
+ /** User to run as. */
349
+ user?: string
350
+ /** Environment variables. */
351
+ env?: Record<string, string>
352
+ /** Timeout in milliseconds. */
353
+ timeoutMs?: number
354
+ /** Stdin mode: "null" (default), "pipe", or a string to send as stdin bytes. */
355
+ stdin?: string
356
+ /** Enable pseudo-TTY. */
357
+ tty?: boolean
358
+ }
359
+
360
+ /** Execution event emitted by `ExecHandle.recv()`. */
361
+ export interface ExecEvent {
362
+ /** "started", "stdout", "stderr", or "exited". */
363
+ eventType: string
364
+ /** Process ID (only for "started" events). */
365
+ pid?: number
366
+ /** Output data (only for "stdout" and "stderr" events). */
367
+ data?: Buffer
368
+ /** Exit code (only for "exited" events). */
369
+ code?: number
370
+ }
371
+
372
+ /** Execution event type. */
373
+ export declare const enum ExecEventType {
374
+ Started = 'started',
375
+ Stdout = 'stdout',
376
+ Stderr = 'stderr',
377
+ Exited = 'exited'
378
+ }
379
+
380
+ /** Process exit status. */
381
+ export interface ExitStatus {
382
+ code: number
383
+ success: boolean
384
+ }
385
+
386
+ /** Filesystem entry metadata returned by `fs.list()`. */
387
+ export interface FsEntry {
388
+ path: string
389
+ /** "file", "directory", "symlink", or "other". */
390
+ kind: string
391
+ size: number
392
+ mode: number
393
+ modified?: number
394
+ }
395
+
396
+ /** Filesystem entry kind. */
397
+ export declare const enum FsEntryKind {
398
+ File = 'file',
399
+ Directory = 'directory',
400
+ Symlink = 'symlink',
401
+ Other = 'other'
402
+ }
403
+
404
+ /** Filesystem metadata returned by `fs.stat()`. */
405
+ export interface FsMetadata {
406
+ /** "file", "directory", "symlink", or "other". */
407
+ kind: string
408
+ size: number
409
+ mode: number
410
+ readonly: boolean
411
+ modified?: number
412
+ created?: number
413
+ }
414
+
415
+ /** Download and install msb + libkrunfw to ~/.microsandbox/. */
416
+ export declare function install(): Promise<void>
417
+
418
+ /** Check if msb and libkrunfw are installed and available. */
419
+ export declare function isInstalled(): boolean
420
+
421
+ /** Log level for sandbox process output. */
422
+ export declare const enum LogLevel {
423
+ Trace = 'trace',
424
+ Debug = 'debug',
425
+ Info = 'info',
426
+ Warn = 'warn',
427
+ Error = 'error'
428
+ }
429
+
430
+ /** Volume mount configuration. */
431
+ export interface MountConfig {
432
+ /** Mount a host directory. Mutually exclusive with `named` and `tmpfs`. */
433
+ bind?: string
434
+ /** Mount a named volume. Mutually exclusive with `bind` and `tmpfs`. */
435
+ named?: string
436
+ /** Use tmpfs (memory-backed). Mutually exclusive with `bind` and `named`. */
437
+ tmpfs?: boolean
438
+ /** Read-only mount. */
439
+ readonly?: boolean
440
+ /** Size limit in MiB (for tmpfs). */
441
+ sizeMib?: number
442
+ }
443
+
444
+ /** Options for bind and named volume mounts. */
445
+ export interface MountOptions {
446
+ /** Read-only mount. */
447
+ readonly?: boolean
448
+ }
449
+
450
+ /** Network configuration. */
451
+ export interface NetworkConfig {
452
+ /**
453
+ * Preset policy: "public-only" (default), "allow-all", or "none".
454
+ * Ignored if `rules` is provided.
455
+ */
456
+ policy?: string
457
+ /** Custom policy rules (first match wins). Overrides `policy` preset. */
458
+ rules?: Array<PolicyRule>
459
+ /** Default action when no rule matches: "allow" or "deny". */
460
+ defaultAction?: string
461
+ /** Block specific domains via DNS interception. */
462
+ blockDomains?: Array<string>
463
+ /** Block domain suffixes via DNS interception. */
464
+ blockDomainSuffixes?: Array<string>
465
+ /** Enable DNS rebinding protection (default: true). */
466
+ dnsRebindProtection?: boolean
467
+ /** TLS interception configuration. */
468
+ tls?: TlsConfig
469
+ /** Max concurrent connections (default: 256). */
470
+ maxConnections?: number
471
+ }
472
+
473
+ /** Rootfs patch applied before VM startup. */
474
+ export interface PatchConfig {
475
+ /** Patch kind: "text", "file", "copyFile", "copyDir", "symlink", "mkdir", "remove", "append". */
476
+ kind: string
477
+ /** Guest path (all kinds except symlink where it's `link`). */
478
+ path?: string
479
+ /** Text content (for "text" and "append" kinds). */
480
+ content?: string
481
+ /** Source host path (for "copyFile" and "copyDir" kinds). */
482
+ src?: string
483
+ /** Destination guest path (for "copyFile" and "copyDir" kinds). */
484
+ dst?: string
485
+ /** Symlink target path (for "symlink" kind). */
486
+ target?: string
487
+ /** Symlink link path (for "symlink" kind). */
488
+ link?: string
489
+ /** File permissions (e.g. 0o644). */
490
+ mode?: number
491
+ /** Allow replacing existing files. */
492
+ replace?: boolean
493
+ }
494
+
495
+ /** Options for `Patch.text()` and `Patch.copyFile()`. */
496
+ export interface PatchOptions {
497
+ /** File permissions (e.g. 0o644). */
498
+ mode?: number
499
+ /** Allow replacing existing files. */
500
+ replace?: boolean
501
+ }
502
+
503
+ /** Options for `Patch.copyDir()` and `Patch.symlink()`. */
504
+ export interface PatchReplaceOptions {
505
+ /** Allow replacing existing files/directories. */
506
+ replace?: boolean
507
+ }
508
+
509
+ /** Network policy rule action. */
510
+ export declare const enum PolicyAction {
511
+ Allow = 'allow',
512
+ Deny = 'deny'
513
+ }
514
+
515
+ /** Network policy rule direction. */
516
+ export declare const enum PolicyDirection {
517
+ Outbound = 'outbound',
518
+ Inbound = 'inbound'
519
+ }
520
+
521
+ /** Network policy rule protocol. */
522
+ export declare const enum PolicyProtocol {
523
+ Tcp = 'tcp',
524
+ Udp = 'udp',
525
+ Icmpv4 = 'icmpv4',
526
+ Icmpv6 = 'icmpv6'
527
+ }
528
+
529
+ /** A network policy rule. */
530
+ export interface PolicyRule {
531
+ /** "allow" or "deny". */
532
+ action: string
533
+ /** "outbound" or "inbound". */
534
+ direction?: string
535
+ /**
536
+ * Destination filter. One of:
537
+ * - "*" — any destination
538
+ * - "1.2.3.4/24" — CIDR notation
539
+ * - "example.com" — exact domain
540
+ * - ".example.com" — domain suffix
541
+ * - "loopback", "private", "link-local", "metadata", "multicast" — destination group
542
+ */
543
+ destination?: string
544
+ /** Protocol filter: "tcp", "udp", "icmpv4", "icmpv6". */
545
+ protocol?: string
546
+ /** Port or port range (e.g. 443 or "8000-9000"). */
547
+ port?: string
548
+ }
549
+
550
+ /** Image pull policy. */
551
+ export declare const enum PullPolicy {
552
+ Always = 'always',
553
+ IfMissing = 'if-missing',
554
+ Never = 'never'
555
+ }
556
+
557
+ /** Registry credentials for pulling private images. */
558
+ export interface RegistryCredentials {
559
+ username: string
560
+ password: string
561
+ }
562
+
563
+ /** Configuration for creating a sandbox. */
564
+ export interface SandboxConfig {
565
+ /** Unique sandbox name. */
566
+ name: string
567
+ /** OCI image ref (e.g. "python:3.12"), host path, or disk image path. */
568
+ image: string
569
+ /** Guest memory in MiB (default: 512). */
570
+ memoryMib?: number
571
+ /** Virtual CPU count (default: 1). */
572
+ cpus?: number
573
+ /** Working directory inside the guest. */
574
+ workdir?: string
575
+ /** Default shell binary path. */
576
+ shell?: string
577
+ /** Override image entrypoint. */
578
+ entrypoint?: Array<string>
579
+ /** Override image cmd. */
580
+ cmd?: Array<string>
581
+ /** Guest hostname. */
582
+ hostname?: string
583
+ /** User to run as (UID or name). */
584
+ user?: string
585
+ /** Environment variables. */
586
+ env?: Record<string, string>
587
+ /** Named scripts that can be run via `sandbox.run(name)`. */
588
+ scripts?: Record<string, string>
589
+ /** Volume mounts keyed by guest path. */
590
+ volumes?: Record<string, MountConfig>
591
+ /** Rootfs patches applied before boot. */
592
+ patches?: Array<PatchConfig>
593
+ /** Image pull policy: "always", "if-missing", or "never". */
594
+ pullPolicy?: string
595
+ /** Log level: "trace", "debug", "info", "warn", "error". */
596
+ logLevel?: string
597
+ /** Kill any existing sandbox with the same name before creating. */
598
+ replace?: boolean
599
+ /** Suppress log output. */
600
+ quietLogs?: boolean
601
+ /** Arbitrary key-value labels. */
602
+ labels?: Record<string, string>
603
+ /** Signal to send on stop (default: SIGTERM). */
604
+ stopSignal?: string
605
+ /** Maximum run duration in seconds. */
606
+ maxDurationSecs?: number
607
+ /** Registry credentials for pulling private images. */
608
+ registryAuth?: RegistryCredentials
609
+ /** Port mappings: host_port → guest_port (TCP). */
610
+ ports?: Record<string, number>
611
+ /** Network configuration. */
612
+ network?: NetworkConfig
613
+ /**
614
+ * Secret entries. Created with `Secret.env()`.
615
+ *
616
+ * ```js
617
+ * import { Secret } from 'microsandbox'
618
+ * secrets: [
619
+ * Secret.env("OPENAI_API_KEY", { value: "sk-...", allowHosts: ["api.openai.com"] }),
620
+ * ]
621
+ * ```
622
+ */
623
+ secrets?: Array<SecretEntry>
624
+ }
625
+
626
+ /** Lightweight handle info for a sandbox from the database. */
627
+ export interface SandboxInfo {
628
+ name: string
629
+ /** "running", "stopped", "crashed", or "draining". */
630
+ status: string
631
+ configJson: string
632
+ createdAt?: number
633
+ updatedAt?: number
634
+ }
635
+
636
+ /** Point-in-time resource metrics for a sandbox. */
637
+ export interface SandboxMetrics {
638
+ cpuPercent: number
639
+ memoryBytes: number
640
+ memoryLimitBytes: number
641
+ diskReadBytes: number
642
+ diskWriteBytes: number
643
+ netRxBytes: number
644
+ netTxBytes: number
645
+ /** Uptime in milliseconds. */
646
+ uptimeMs: number
647
+ /** Timestamp as milliseconds since Unix epoch. */
648
+ timestampMs: number
649
+ }
650
+
651
+ /** Sandbox status. */
652
+ export declare const enum SandboxStatus {
653
+ Running = 'running',
654
+ Stopped = 'stopped',
655
+ Crashed = 'crashed',
656
+ Draining = 'draining'
657
+ }
658
+
659
+ /**
660
+ * A secret entry for the `secrets` array on `SandboxConfig`.
661
+ *
662
+ * Created via `Secret.env()`:
663
+ * ```js
664
+ * import { Secret } from 'microsandbox'
665
+ * Secret.env("OPENAI_API_KEY", { value: "sk-...", allowHosts: ["api.openai.com"] })
666
+ * ```
667
+ */
668
+ export interface SecretEntry {
669
+ /** Environment variable name. */
670
+ envVar: string
671
+ /** The secret value (never enters the sandbox). */
672
+ value: string
673
+ /** Allowed hosts (exact match, e.g. `["api.openai.com"]`). */
674
+ allowHosts?: Array<string>
675
+ /** Allowed host patterns (wildcard, e.g. `["*.openai.com"]`). */
676
+ allowHostPatterns?: Array<string>
677
+ /** Custom placeholder (auto-generated as `$MSB_<ENV_VAR>` if omitted). */
678
+ placeholder?: string
679
+ /** Require verified TLS identity before substitution (default: true). */
680
+ requireTls?: boolean
681
+ /** Violation action: "block", "block-and-log" (default), "block-and-terminate". */
682
+ onViolation?: string
683
+ }
684
+
685
+ /** Options for `Secret.env()`. */
686
+ export interface SecretEnvOptions {
687
+ /** The secret value (never enters the sandbox). */
688
+ value: string
689
+ /** Allowed hosts (exact match, e.g. `["api.openai.com"]`). */
690
+ allowHosts?: Array<string>
691
+ /** Allowed host patterns (wildcard, e.g. `["*.openai.com"]`). */
692
+ allowHostPatterns?: Array<string>
693
+ /** Custom placeholder (auto-generated as `$MSB_<ENV_VAR>` if omitted). */
694
+ placeholder?: string
695
+ /** Require verified TLS identity before substitution (default: true). */
696
+ requireTls?: boolean
697
+ /** Violation action: "block", "block-and-log" (default), "block-and-terminate". */
698
+ onViolation?: string
699
+ }
700
+
701
+ /** TLS interception configuration. */
702
+ export interface TlsConfig {
703
+ /** Domains to bypass (no interception). Supports "*.suffix" wildcards. */
704
+ bypass?: Array<string>
705
+ /** Verify upstream server certificates (default: true). */
706
+ verifyUpstream?: boolean
707
+ /** Ports to intercept (default: [443]). */
708
+ interceptedPorts?: Array<number>
709
+ /** Block QUIC on intercepted ports (default: false). */
710
+ blockQuic?: boolean
711
+ /** Path to custom CA certificate PEM file. */
712
+ caCert?: string
713
+ /** Path to custom CA private key PEM file. */
714
+ caKey?: string
715
+ }
716
+
717
+ /** Options for tmpfs mounts. */
718
+ export interface TmpfsOptions {
719
+ /** Size limit in MiB. */
720
+ sizeMib?: number
721
+ /** Read-only mount. */
722
+ readonly?: boolean
723
+ }
724
+
725
+ /** Action to take when a secret is sent to a disallowed host. */
726
+ export declare const enum ViolationAction {
727
+ /** Silently block the request. */
728
+ Block = 'block',
729
+ /** Block the request and log the violation. */
730
+ BlockAndLog = 'block-and-log',
731
+ /** Block the request and terminate the sandbox. */
732
+ BlockAndTerminate = 'block-and-terminate'
733
+ }
734
+
735
+ /** Volume configuration for creation. */
736
+ export interface VolumeConfig {
737
+ name: string
738
+ /** Size quota in MiB. */
739
+ quotaMib?: number
740
+ /** Arbitrary key-value labels. */
741
+ labels?: Record<string, string>
742
+ }
743
+
744
+ /** Volume handle info from the database. */
745
+ export interface VolumeInfo {
746
+ name: string
747
+ quotaMib?: number
748
+ usedBytes: number
749
+ labels: Record<string, string>
750
+ createdAt?: number
751
+ }