---
title: Sandbox
description: TypeScript SDK - Sandbox API reference
---

Create and control a microVM sandbox: boot it from an image, run commands, stream logs and metrics, then shut it down. See [Overview](/sandboxes/overview) for configuration examples and [Lifecycle](/sandboxes/lifecycle) for state management.

## Functions

#### <span className="msb-hn">allSandboxMetrics()</span>

```typescript
allSandboxMetrics(): Promise<Record<string, SandboxMetrics>>
```

Return one [`SandboxMetrics`](#sandboxmetrics) snapshot for every running sandbox, keyed by sandbox name. See [Metrics](/sandboxes/metrics) for a complete example.

## Sandbox

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">builder()</span>

```typescript
static builder(name: string): SandboxBuilder
```

<Accordion title="Example">

```typescript
await using sandbox = await Sandbox.builder("api")
  .image("python")
  .create();
```

</Accordion>

Begin building a new sandbox. Configure it with chainable setters, then call `.create()` to boot it. Sandbox names must be non-empty and no longer than 128 UTF-8 bytes. See [`SandboxBuilder`](#sandboxbuilder) for all available options.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxbuilder">SandboxBuilder</a></div>
    <div className="msb-param-desc">Fluent builder for configuring the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">get()</span>

```typescript
static get(name: string): Promise<SandboxHandle>
```

<Accordion title="Example">

```typescript
const handle = await Sandbox.get("api");
console.log(handle.status);
```

</Accordion>

Get a live handle to an existing sandbox (running or stopped). The handle provides status, configuration, and lifecycle control without requiring a full connection to the guest agent.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxhandle">Promise&lt;SandboxHandle&gt;</a></div>
    <div className="msb-param-desc">Live handle with status and lifecycle control.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">list()</span>

```typescript
static list(): Promise<SandboxPage>
```

<Accordion title="Example">

```typescript
const page = await Sandbox.list();
for (const h of page.sandboxes) {
  console.log(`${h.name} - ${h.status}`);
}
```

</Accordion>

Return the first page of sandboxes (running, stopped, and crashed), ordered newest first. The default page size is 20. Handles are read-only - call [`Sandbox.get(name)`](#sandbox-get) to get a live handle for lifecycle calls.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise&lt;SandboxPage&gt;</span></div>
    <div className="msb-param-desc">Read-only handles in this page and an optional cursor for the next page.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">listWith()</span>

```typescript
static listWith(configure: (list: SandboxListBuilder) => SandboxListBuilder): Promise<SandboxPage>
```

<Accordion title="Example">

```typescript
const page = await Sandbox.listWith((list) =>
  list.limit(50).label("role", "worker"),
);

if (page.nextCursor) {
  const nextPage = await Sandbox.listWith((list) =>
    list.limit(50).cursor(page.nextCursor!).label("role", "worker"),
  );
}
```

</Accordion>

Return a configured page of sandboxes. Label filters are applied before pagination and are AND-matched. Like [`list()`](#sandbox-list), returned handles are read-only.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><span className="msb-type">(list: SandboxListBuilder) =&gt; SandboxListBuilder</span></div>
    <div className="msb-param-desc">Configure a limit (1-100), next-page cursor, and/or AND-matched labels.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise&lt;SandboxPage&gt;</span></div>
    <div className="msb-param-desc">Matching read-only handles and an optional cursor for the next page.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">remove()</span>

```typescript
static remove(name: string): Promise<void>
```

<Accordion title="Example">

```typescript
await Sandbox.remove("api");
```

</Accordion>

Delete a stopped sandbox by name. See [Remove](/sandboxes/lifecycle#remove) for the exact local deletion scope and the external resources that are preserved. Fails if the sandbox is still running—stop it first.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">start()</span>

```typescript
static start(name: string): Promise<Sandbox>
```

<Accordion title="Example">

```typescript
await using sandbox = await Sandbox.start("api");
```

</Accordion>

Restart a previously stopped sandbox. The VM reboots using the persisted configuration. The sandbox enters attached mode - it stops when the binding goes out of scope (via `await using`) or when [`stop()`](#sandbox-stop) is called.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Name of a stopped sandbox, up to 128 UTF-8 bytes.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Promise&lt;Sandbox&gt;</a></div>
    <div className="msb-param-desc">Running sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">Sandbox.</span><span className="msb-hn">startDetached()</span>

```typescript
static startDetached(name: string): Promise<Sandbox>
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.startDetached("worker");
```

</Accordion>

Restart a stopped sandbox in detached mode. The sandbox survives after your process exits.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Name of a stopped sandbox, up to 128 UTF-8 bytes.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Promise&lt;Sandbox&gt;</a></div>
    <div className="msb-param-desc">Running sandbox.</div>
  </div>
</div>

<p className="msb-member-group">Instance methods</p>

A running `Sandbox` also exposes two read-only properties: `name` (`string`, the sandbox name) and `ownsLifecycle` (`boolean`, `true` in attached mode where the auto-disposer stops the sandbox, `false` in detached mode).

Command execution (`exec`, `execWith`, `execStream`, `execStreamWith`, `shell`, `shellStream`) and foreground attachment (`attach`, `attachWith`, `attachShell`) live on the [Execution](/sdk/typescript/execution) page.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">config()</span>

```typescript
config(): Promise<SandboxConfig>
```

<Accordion title="Example">

```typescript
const config = await sandbox.config();
console.log(`${config.memoryMib} MiB`);
```

</Accordion>

Get the full configuration the sandbox was created with - image, cpus, memory, env, mounts, and the rest. The shape mirrors [`SandboxBuilder.build()`](#build).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxconfig">Promise&lt;SandboxConfig&gt;</a></div>
    <div className="msb-param-desc">Sandbox configuration.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">detach()</span>

```typescript
detach(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.detach(); // keeps running in the background
```

</Accordion>

Release the handle without stopping the sandbox. The sandbox continues running as a background process. Reconnect later with [`Sandbox.get()`](#sandbox-get).

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">fs()</span>

```typescript
fs(): SandboxFsOps
```

<Accordion title="Example">

```typescript
await sandbox.fs().writeFile("/tmp/hello.txt", "hi");
```

</Accordion>

Get a filesystem handle for reading and writing files inside the running sandbox. See [Filesystem](/sdk/typescript/filesystem) for API details.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="/sdk/typescript/filesystem">SandboxFsOps</a></div>
    <div className="msb-param-desc">Filesystem handle.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">kill()</span>

<Tooltip tip="Not available on microsandbox cloud; use a graceful stop."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
kill(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.kill(); // no graceful shutdown
```

</Accordion>

Force-terminate the sandbox and wait until stopped state is observed. No graceful shutdown - use when the sandbox is unresponsive. Pending writes that the workload hasn't `fsync`'d may be lost, same durability semantics as a sudden power loss on a physical machine. Prefer [`stop()`](#sandbox-stop) for graceful shutdown that gives the workload a chance to flush.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">killWithTimeout()</span>

<Tooltip tip="Not available on microsandbox cloud; use a graceful stop."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
killWithTimeout(timeoutMs: number): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.killWithTimeout(2000);
```

</Accordion>

Force-terminate the sandbox and wait up to `timeoutMs` for stopped-state observation.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>timeoutMs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Milliseconds to wait for the stopped state to be observed.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">logs()</span>

<Tooltip tip="Bounded log reads are not available on microsandbox cloud; follow live with log streaming and persist output externally."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
logs(opts?: LogReadOptions): Promise<LogEntry[]>
```

<Accordion title="Example">

```typescript
import { Sandbox } from "microsandbox";

const handle = await Sandbox.get("web");

// Default: all user-program output, regardless of pipe/pty mode
const entries = await handle.logs();

for (const e of entries) {
  const source =
    e.source === "stdout" ? "OUT" :
    e.source === "stderr" ? "ERR" :
    e.source === "output" ? "PTY" :
    "SYS";

  console.log(
    `[${e.timestamp.toISOString()}] ${source} ${e.sessionId}: ${e.text().trimEnd()}`
  );
}

// Filtered: last 50 entries from the past hour, including system lines
const recent = await handle.logs({
  tail: 50,
  since: new Date(Date.now() - 60 * 60 * 1000),
  sources: ["stdout", "stderr", "output", "system"],
});
```

</Accordion>

Read captured output from the sandbox's `exec.log`. Backed by an on-disk JSON Lines file the runtime writes via the relay tap. Works on running and stopped sandboxes alike - there is no protocol traffic. The same method is available on [`SandboxHandle`](#sandboxhandle) for callers that don't want to start the sandbox first.

The default sources are `"stdout"`, `"stderr"`, and `"output"` (PTY-merged). Pass `"system"` to also include synthetic lifecycle markers and runtime/kernel diagnostic lines, or `"all"` for every source.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#logreadoptions">LogReadOptions?</a></div>
    <div className="msb-param-desc">Filters: <code>tail</code>, <code>since</code>, <code>until</code>, <code>sources</code>. Omit for the default user-program sources.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#logentry">Promise&lt;LogEntry[]&gt;</a></div>
    <div className="msb-param-desc">Matching entries in chronological order.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">logStream()</span>

<Tooltip tip="On microsandbox cloud, log streaming is follow-only; set follow. Bounded, non-follow reads are not available."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
logStream(opts?: LogStreamOptions): Promise<LogStream>
```

<Accordion title="Example">

```typescript
await using stream = await sandbox.logStream({ follow: true });
for await (const e of stream) {
  console.log(e.text().trimEnd());
}
```

</Accordion>

Stream captured output as it appears, with optional follow. Backed by the same on-disk `exec.log` as [`logs()`](#sandbox-logs), but yields entries lazily. Pass `{ follow: true }` to keep the stream open past current EOF and pick up new entries as they are written; otherwise the stream drains the current contents and ends. Each yielded [`LogEntry`](#logentry) carries an opaque `cursor` that can be passed back via [`LogStreamOptions.fromCursor`](#logstreamoptions) to resume.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#logstreamoptions">LogStreamOptions?</a></div>
    <div className="msb-param-desc">Filters plus <code>follow</code> and resume controls (<code>since</code>, <code>fromCursor</code>).</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#logstream">Promise&lt;LogStream&gt;</a></div>
    <div className="msb-param-desc">Async iterable of log entries.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">ping()</span>

<Tooltip tip="Not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
ping(): Promise<SandboxPingResult>
```

<Accordion title="Example">

```typescript
const health = await sandbox.ping();
console.log(`${health.name}: ${health.latencyMs.toFixed(1)} ms`);
```

</Accordion>

Check that the running sandbox's guest agent is reachable without refreshing idle activity. This sends `core.ping` and waits for `core.pong`; it does not start stopped sandboxes and returns an error if the sandbox is not running or `agentd` cannot respond. After upgrading from a runtime that predates protocol generation 6, restart already-running sandboxes so the guest agent understands the message.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxpingresult">Promise&lt;SandboxPingResult&gt;</a></div>
    <div className="msb-param-desc">Sandbox name and agent round-trip latency.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">touch()</span>

<Tooltip tip="Not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
touch(): Promise<SandboxTouchResult>
```

<Accordion title="Example">

```typescript
const keepalive = await sandbox.touch();
console.log(`${keepalive.name}: ${keepalive.activitySeq}`);
```

</Accordion>

Explicitly refresh the running sandbox's idle activity. This sends `core.touch`, receives `core.touched`, and advances the guest activity sequence used by the runtime idle-timeout monitor. It does not start stopped sandboxes and it does not bypass `maxDuration`.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxtouchresult">Promise&lt;SandboxTouchResult&gt;</a></div>
    <div className="msb-param-desc">Sandbox name and updated activity sequence.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">modify()</span>

<Tooltip tip="modify is not available on microsandbox cloud; recreate the sandbox with the new configuration."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
modify(opts?: ModifyOptions): Promise<SandboxModificationPlan>
```

<Accordion title="Example">

```typescript
// Live resize: applies to the running VM when within the booted capacity
const plan = await sandbox.modify({ cpus: 4, memory: 4096 });
for (const r of plan.resizeStatus) {
  console.log(`${r.resource}: ${r.requested} -> ${r.actual} (${r.state})`);
}

// Preview a change without applying it
const preview = await sandbox.modify({ maxMemory: 16384, dryRun: true });
for (const c of preview.changes) {
  console.log(`${c.field}: ${c.disposition}`);
}

// Make an env change active now by restarting
await sandbox.modify({ env: { MODE: "prod" }, policy: "restart" });
// Grow the managed OCI root disk offline and restart
await sandbox.modify({ rootDiskSize: 8192, policy: "restart" });

// Add or rotate a host-environment secret; restart if it is newly added
await sandbox.modify({
  secrets: {
    API_KEY: { env: "API_KEY", allowedHosts: ["api.example.com"] },
  },
  policy: "restart",
});

// Remove an existing secret
await sandbox.modify({ secretsRemove: ["OLD_API_KEY"] });
```

</Accordion>

Plan or apply a configuration change. The returned plan labels each change `"live"`, `"next start"`, `"requires restart"`, or `"unsupported"`, and apply is all-or-nothing.

`cpus` and `memory` resize live within the [`maxCpus`](#maxcpus) / [`maxMemory`](#maxmemory) ceilings; raising a ceiling requires a restart. `rootDiskSize` changes are offline: managed and flat OCI root disks grow only, tmpfs root disks can change in either direction on the next boot, and user-supplied disk images are rejected. Env and workdir changes affect future execs only. On a stopped sandbox, changes are saved for the next boot.

Secret specs are keyed by stable secret name. Each `SecretModifySpec` selects at most one source—`env`, `value`, or `store`—and may also set `placeholder` and `allowedHosts`; omitting a source updates only the other supplied fields. Plans expose only safe references and metadata; raw secret values never appear in a plan. Removal is explicit through `secretsRemove`.

A live CPU or memory resize can take a moment to settle. The new limits are enforced immediately, and the returned plan's `resizeStatus` reports when the sandbox has finished adjusting. See [`SandboxModificationPlan`](#sandboxmodificationplan).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#modifyoptions">ModifyOptions</a></div>
    <div className="msb-param-desc">Requested changes plus <code>policy</code> and <code>dryRun</code>. Omitted fields are left unchanged.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxmodificationplan">Promise&lt;SandboxModificationPlan&gt;</a></div>
    <div className="msb-param-desc">The modification plan, applied unless <code>dryRun: true</code>.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">metrics()</span>

<Tooltip tip="Resource metrics are not available on microsandbox cloud; use an external monitoring system."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
metrics(): Promise<SandboxMetrics>
```

<Accordion title="Example">

```typescript
const m = await sandbox.metrics();
console.log(`cpu ${m.cpuPercent.toFixed(1)}% · mem ${Math.round(m.memoryBytes / 1048576)} MiB`);
```

</Accordion>

Get a point-in-time snapshot of the sandbox's resource usage: CPU, memory, disk I/O, network I/O, optional upper disk usage, and uptime.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxmetrics">Promise&lt;SandboxMetrics&gt;</a></div>
    <div className="msb-param-desc">Resource metrics.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">metricsStream()</span>

<Tooltip tip="Resource metrics are not available on microsandbox cloud; use an external monitoring system."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
metricsStream(intervalMs: number): Promise<MetricsStream>
```

<Accordion title="Example">

```typescript
await using stream = await sandbox.metricsStream(1000);
for await (const snapshot of stream) {
  console.log(`${snapshot.cpuPercent.toFixed(1)}%`);
}
```

</Accordion>

Stream resource metrics at a regular interval. The returned [`MetricsStream`](#metricsstream) supports both `recv()` and `for await...of`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>intervalMs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Milliseconds between metric snapshots.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#metricsstream">Promise&lt;MetricsStream&gt;</a></div>
    <div className="msb-param-desc">Async stream yielding a snapshot each interval.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">requestDrain()</span>

<Tooltip tip="Not available on microsandbox cloud; use a graceful stop."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
requestDrain(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.requestDrain();
await sandbox.waitUntilStopped();
```

</Accordion>

Request a graceful drain and return once the request is sent. Existing commands run to completion, but new `exec` calls are rejected. The sandbox transitions to `stopped` when all in-flight commands finish. Use [`waitUntilStopped()`](#sandbox-waituntilstopped) when the caller needs stopped-state observation. Useful for zero-downtime rotation of worker sandboxes.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">requestKill()</span>

<Tooltip tip="Not available on microsandbox cloud; use a graceful stop."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
requestKill(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.requestKill();
```

</Accordion>

Request force termination and return once the signal is sent, without waiting for the stopped state to be observed.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">requestStop()</span>

```typescript
requestStop(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.requestStop();
```

</Accordion>

Request graceful shutdown and return once the request is sent, without waiting for the stopped state to be observed.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">ssh()</span>

```typescript
ssh(): SandboxSshOps
```

Get an SSH handle for opening interactive sessions and port forwards into the running guest. See [SSH](/sdk/typescript/ssh) for API details.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="/sdk/typescript/ssh">SandboxSshOps</a></div>
    <div className="msb-param-desc">SSH handle.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">stop()</span>

```typescript
stop(): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.stop();
```

</Accordion>

Gracefully shut down the sandbox and wait until stopped state is observed. Lets the sandbox finish writing any pending data to disk before it exits, so files written inside the sandbox aren't lost across a later restart. Waits up to 10_000 ms for a clean exit; if the sandbox is still running after that, it is force-killed.

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">stopWithTimeout()</span>

```typescript
stopWithTimeout(timeoutMs: number): Promise<void>
```

<Accordion title="Example">

```typescript
await sandbox.stopWithTimeout(5000);
```

</Accordion>

Gracefully shut down the sandbox with an explicit observation timeout before force-kill escalation. `0` force-kills immediately. Resolves successfully either way - it does not throw on timeout expiry.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>timeoutMs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Milliseconds to wait for a clean exit before force-killing. <code>0</code> skips the grace period.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">waitUntilStopped()</span>

```typescript
waitUntilStopped(): Promise<SandboxStopResult>
```

<Accordion title="Example">

```typescript
const result = await sandbox.waitUntilStopped();
console.log(result.status, result.exitCode);
```

</Accordion>

Block until the sandbox is observed in a terminal non-running state, without triggering a stop or kill request.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxstopresult">Promise&lt;SandboxStopResult&gt;</a></div>
    <div className="msb-param-desc">Terminal status, exit code, and signal that were observed.</div>
  </div>
</div>

#### <span className="msb-recv">sandbox.</span><span className="msb-hn">[Symbol.asyncDispose]()</span>

<Tooltip tip="On microsandbox cloud this does not stop the sandbox; the cloud handle does not own the host process, so call stop() or remove() explicitly."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
[Symbol.asyncDispose](): Promise<void>
```

<Accordion title="Example">

```typescript
{
  await using sandbox = await Sandbox.builder("api").image("python").create();
  await sandbox.exec("python", ["-V"]);
} // sandbox.stop() runs here, automatically
```

</Accordion>

Implements `AsyncDisposable` so the sandbox can be used with `await using`. When the binding goes out of scope, the sandbox is stopped (best-effort) - but only if `ownsLifecycle` is `true`.

## SandboxBuilder

Fluent builder for configuring a sandbox before creation. Obtained via [`Sandbox.builder(name)`](#sandbox-builder). Every setter returns the same builder so calls chain. Examples are shown on the methods where usage is non-obvious.

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">build()</span>

```typescript
build(): Promise<SandboxConfig>
```

Materialize the [`SandboxConfig`](#sandboxconfig) without booting the sandbox. Validates the configuration and consumes the builder. For booting, use [`create`](#create) instead - it builds internally.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxconfig">Promise&lt;SandboxConfig&gt;</a></div>
    <div className="msb-param-desc">Validated, ready-to-boot configuration.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">cpus()</span>

```typescript
cpus(n: number): this
```

Set the number of virtual CPUs. This is a limit, not a reservation.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>n</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Number of vCPUs.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">maxCpus()</span>

<Tooltip tip="On microsandbox cloud these ceilings are not carried; the maximum is pinned to the initial value. Recreate the sandbox to resize."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
maxCpus(n: number): this
```

Set the boot-time maximum possible virtual CPU capacity. This reserves the envelope a sandbox can use after restart-backed changes and future live CPU activation; it does not increase the effective vCPU count by itself.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>n</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Maximum possible vCPUs.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">create()</span>

```typescript
create(): Promise<Sandbox>
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("python")
  .detached(true)
  .create();
await sandbox.detach();
```

</Accordion>

Build and boot the sandbox. By default the sandbox is attached - it stops when the `await using` binding goes out of scope. Call [`detached(true)`](#detached) first for background mode.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Promise&lt;Sandbox&gt;</a></div>
    <div className="msb-param-desc">Running sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">createWithPullProgress()</span>

<Tooltip tip="On microsandbox cloud, per-layer pull progress is not reported; creation still completes."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
createWithPullProgress(): Promise<PullProgressCreate>
```

<Accordion title="Example">

```typescript
const creation = await Sandbox.builder("demo")
  .image("alpine")
  .createWithPullProgress();

for await (const ev of creation) {
  if (ev.kind === "layerDownloadProgress") {
    console.log(`${ev.layerIndex}: ${ev.downloadedBytes}/${ev.totalBytes}`);
  }
}

const sandbox = await creation.awaitSandbox();
```

</Accordion>

Build and boot while streaming image pull progress. Returns a [`PullProgressCreate`](#pullprogresscreate) that yields [`PullProgress`](#pullprogress) events as the image is resolved, downloaded, and materialized; call `awaitSandbox()` after iteration to obtain the live sandbox.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#pullprogresscreate">Promise&lt;PullProgressCreate&gt;</a></div>
    <div className="msb-param-desc">Async iterable creation handle.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">detached()</span>

```typescript
detached(enabled: boolean): this
```

Create in detached/background mode when `true`. A detached sandbox survives after your process exits and does not auto-stop on `await using` scope exit.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Whether to boot in detached mode.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">disableMetricsSample()</span>

<Tooltip tip="Metrics sampling does not apply on microsandbox cloud, where resource metrics are unavailable."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
disableMetricsSample(): this
```

Disable periodic background metrics sampling for this sandbox.

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">disableNetwork()</span>

```typescript
disableNetwork(): this
```

Fully disable networking. No network interface is created.

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">entrypoint()</span>

```typescript
entrypoint(cmd: string[]): this
```

Override the image ENTRYPOINT used by default-workload execution. [`sandbox.execDefault`](/sdk/typescript/execution) combines it with the effective CMD. Literal [`sandbox.exec`](/sdk/typescript/execution), [`sandbox.attach`](/sdk/typescript/execution), and [`sandbox.shell`](/sdk/typescript/execution) calls ignore it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>cmd</code><span className="msb-type">string[]</span></div>
    <div className="msb-param-desc">Entrypoint command and arguments.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">env()</span>

```typescript
env(key: string, value: string): this
```

Set an environment variable visible to all commands. Can be called multiple times. Per-command env vars (via `execWith`) are merged on top.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>key</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Variable name.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Variable value.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">envs()</span>

```typescript
envs(vars: Record<string, string>): this
```

Add many environment variables at once.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>vars</code><span className="msb-type">Record&lt;string, string&gt;</span></div>
    <div className="msb-param-desc">Map of variable names to values.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">ephemeral()</span>

```typescript
ephemeral(enabled: boolean): this
```

When `true`, the sandbox and all its persisted state are removed automatically once it stops, rather than left on disk for restart.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Whether the sandbox is ephemeral.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">fromSnapshot()</span>

```typescript
fromSnapshot(pathOrName: string): this
```

Boot from a previously captured snapshot instead of a fresh image. The image reference and upper-layer source are pinned from the snapshot manifest. See [Snapshots](/sdk/typescript/snapshots).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>pathOrName</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Snapshot name or filesystem path.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">hostname()</span>

<Tooltip tip="On microsandbox cloud, the hostname is assigned by the platform; a value set here is ignored."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
hostname(name: string): this
```

Set the guest hostname.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Hostname.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">libkrunfwPath()</span>

```typescript
libkrunfwPath(path: string): this
```

Deprecated compatibility alias for older builder chains. This sets the same process-level override as `setRuntimeLibkrunfwPath(path)` and returns the builder; it is not a per-sandbox setting.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Path to the libkrunfw shared library.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">idleTimeout()</span>

```typescript
idleTimeout(secs: number): this
```

Auto-drain the sandbox after this many seconds of inactivity (no active exec sessions). Enforced on the host side.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>secs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Idle timeout in seconds.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">image()</span>

<Tooltip tip="On microsandbox cloud, only OCI image references are accepted; host-directory and disk-image root filesystems are local-only."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
image(src: string): this
```

Set the root filesystem source. Accepts OCI image names (`"alpine"`), local directory paths, or disk image paths. The format is auto-detected. **Required** unless [`fromSnapshot`](#fromsnapshot) is used.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">OCI image name, local directory path, or disk image path.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">imageWith()</span>

<Tooltip tip="On microsandbox cloud, only OCI image references are accepted; host-directory and disk-image root filesystems are local-only."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
imageWith(configure: (b: ImageBuilder) => ImageBuilder): this
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .imageWith((i) => i.oci("python:3.12").upperSize(8192))
  .create();
```

</Accordion>

Configure an explicit rootfs source. Use this for OCI-only settings such as the writable overlay upper size, or for disk images when the filesystem type can't be auto-detected.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><span className="msb-type">(b: ImageBuilder) =&gt; ImageBuilder</span></div>
    <div className="msb-param-desc">Configure the rootfs source.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">cmd()</span>

```typescript
cmd(cmd: string[]): this
```

Override the image CMD used by default-workload execution. An empty array explicitly clears the image CMD. This describes durable configuration and does not execute anything during `create()`.

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("example/worker:latest")
  .cmd(["worker.py", "--once"])
  .create();
```

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">init()</span>

```typescript
init(cmd: string, args?: string[]): this
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("jrei/systemd-debian:12")
  .init("auto")
  .create();
```

</Accordion>

Hand off PID 1 inside the guest to `cmd` after agentd finishes its boot-time setup. `cmd` is either an absolute path inside the guest rootfs or the literal `"auto"`, which honors a known image ENTRYPOINT init then falls back to probing common init paths. See [Custom init system](/sandboxes/bootstrap#custom-init-system). For init binaries that need extra env, use [`initWith`](#initwith).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>cmd</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest, or <code>"auto"</code>.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>args</code><span className="msb-type">string[]?</span></div>
    <div className="msb-param-desc">Optional argv for the init binary.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">initWith()</span>

```typescript
initWith(cmd: string, configure: (b: InitOptionsBuilder) => InitOptionsBuilder): this
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("jrei/systemd-debian:12")
  .initWith("/lib/systemd/systemd", (i) =>
    i.args(["--unit=multi-user.target"]).env("container", "microsandbox"))
  .create();
```

</Accordion>

Like [`init`](#init), but with a closure-builder for argv and env vars. The builder exposes `.arg`, `.args`, `.env`, and `.envs`. Calling `init` or `initWith` more than once overwrites.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>cmd</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path to the init binary inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><span className="msb-type">(b: InitOptionsBuilder) =&gt; InitOptionsBuilder</span></div>
    <div className="msb-param-desc">Closure populating argv and env.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">label()</span>

```typescript
label(key: string, value: string): this
```

Attach a single label to the sandbox. Labels can be matched later with [`Sandbox.listWith()`](#sandbox-listwith).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>key</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Label key.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Label value.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">labels()</span>

```typescript
labels(labels: Record<string, string>): this
```

Attach many labels at once.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>labels</code><span className="msb-type">Record&lt;string, string&gt;</span></div>
    <div className="msb-param-desc">Map of label keys to values.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">logLevel()</span>

```typescript
logLevel(level: LogLevel): this
```

Override the sandbox process's log verbosity.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>level</code><a className="msb-type" href="#loglevel">LogLevel</a></div>
    <div className="msb-param-desc">Log level.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">maxDuration()</span>

```typescript
maxDuration(secs: number): this
```

Set the maximum sandbox lifetime in seconds. When exceeded, the sandbox is drained and stopped. Enforced on the host side - the guest cannot override it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>secs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Maximum lifetime in seconds.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">memory()</span>

```typescript
memory(mib: number): this
```

Set the guest memory size in MiB. Physical pages are only allocated as the guest touches them, so this is a limit, not an upfront reservation.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>mib</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Memory in MiB.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">maxMemory()</span>

<Tooltip tip="On microsandbox cloud these ceilings are not carried; the maximum is pinned to the initial value. Recreate the sandbox to resize."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
maxMemory(mib: number): this
```

Set the boot-time maximum hotpluggable guest memory in MiB. This reserves the envelope a sandbox can use after restart-backed changes and future live memory activation; it does not increase the effective memory by itself.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>mib</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Maximum memory in MiB.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">thp()</span>

```typescript
thp(policy: "always" | "madvise" | "never"): this
```

Select the guest transparent huge-page policy applied through the kernel command line at boot. Default: `"madvise"`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>policy</code><span className="msb-type">"always" | "madvise" | "never"</span></div>
    <div className="msb-param-desc">The THP policy persisted for the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">metricsSampleIntervalMs()</span>

<Tooltip tip="Metrics sampling does not apply on microsandbox cloud, where resource metrics are unavailable."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
metricsSampleIntervalMs(ms: number): this
```

Set the interval, in milliseconds, at which the host samples background metrics for this sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ms</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Sampling interval in milliseconds.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">network()</span>

```typescript
network(configure: (b: NetworkBuilder) => NetworkBuilder): this
```

Configure DNS, TLS, policy, and secrets. See [Networking](/sdk/typescript/networking) for the full builder API.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="/sdk/typescript/networking">(b: NetworkBuilder) =&gt; NetworkBuilder</a></div>
    <div className="msb-param-desc">Configure the network.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">patch()</span>

```typescript
patch(configure: (b: PatchBuilder) => PatchBuilder): this
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("python")
  .patch((p) => p.text("/etc/app.conf", "mode=prod\n", { mode: 0o644 }))
  .create();
```

</Accordion>

Modify the rootfs before the VM boots. Patches go into the writable layer - the base image is untouched. See [`PatchBuilder`](#patchbuilder) for the operations.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#patchbuilder">(b: PatchBuilder) =&gt; PatchBuilder</a></div>
    <div className="msb-param-desc">Configure rootfs patches.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">port()</span>

<Tooltip tip="Publishing host ports is not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
port(host: number, guest: number): this
```

Publish a TCP port from the sandbox to the host. The default host bind address is `127.0.0.1`. For an explicit bind address, use [`portBind`](#portbind).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port on the host.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port inside the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">portBind()</span>

<Tooltip tip="Publishing host ports is not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
portBind(bind: string, host: number, guest: number): this
```

Publish a TCP port on a specific host bind address, such as `"0.0.0.0"`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>bind</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Host bind address.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port on the host.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port inside the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">portUdp()</span>

<Tooltip tip="Publishing host ports is not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
portUdp(host: number, guest: number): this
```

Publish a UDP port. The default host bind address is `127.0.0.1`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port on the host.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port inside the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">portUdpBind()</span>

<Tooltip tip="Publishing host ports is not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
portUdpBind(bind: string, host: number, guest: number): this
```

Publish a UDP port on a specific host bind address.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>bind</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Host bind address.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port on the host.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Port inside the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">pullPolicy()</span>

```typescript
pullPolicy(policy: PullPolicy): this
```

Control when the OCI image is pulled from the registry.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>policy</code><a className="msb-type" href="#pullpolicy">PullPolicy</a></div>
    <div className="msb-param-desc">Pull behavior.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">quietLogs()</span>

```typescript
quietLogs(): this
```

Suppress sandbox process log output.

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">registry()</span>

<Tooltip tip="On microsandbox cloud, plain-HTTP and custom-CA registry options are not available; credential auth still works."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
registry(configure: (b: RegistryConfigBuilder) => RegistryConfigBuilder): this
```

<Accordion title="Example">

```typescript
const sandbox = await Sandbox.builder("worker")
  .image("registry.internal/app:latest")
  .registry((r) =>
    r.auth({ kind: "basic", username: "user", password: "token" }),
  )
  .create();
```

</Accordion>

Configure the OCI registry connection: authentication, insecure transport, and CA certificates.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#registryconfigbuilder">(b: RegistryConfigBuilder) =&gt; RegistryConfigBuilder</a></div>
    <div className="msb-param-desc">Configure registry authentication, transport, and CA certificates.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">replace()</span>

<Tooltip tip="Replace-on-create is not available on microsandbox cloud; remove the existing sandbox first."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
replace(): this
```

If a sandbox with the same name already exists, stop it (10s SIGTERM grace, then SIGKILL), remove it, and create a fresh one. Without this, creation fails on name conflict.

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">replaceWithTimeout()</span>

<Tooltip tip="Replace-on-create is not available on microsandbox cloud; remove the existing sandbox first."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
replaceWithTimeout(timeoutMs: number): this
```

Same as [`replace()`](#replace) with a custom SIGTERM timeout in milliseconds. `0` skips SIGTERM and force-kills immediately. Implies `replace()`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>timeoutMs</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Milliseconds to wait after SIGTERM before escalating to SIGKILL.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">rlimit()</span>

```typescript
rlimit(resource: string, limit: number): this
```

Set a guest resource limit (a soft and hard limit at the same value). For separate soft/hard values, use [`rlimitRange`](#rlimitrange).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>resource</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Resource name, e.g. <code>"nofile"</code>.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>limit</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Limit value applied to both soft and hard.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">rlimitRange()</span>

```typescript
rlimitRange(resource: string, soft: number, hard: number): this
```

Set a guest resource limit with explicit soft and hard values.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>resource</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Resource name, e.g. <code>"nofile"</code>.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>soft</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Soft limit.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>hard</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Hard limit.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">script()</span>

```typescript
script(name: string, content: string): this
```

Add a named script at `/.msb/scripts/` inside the guest. Scripts are added to `PATH` and can be called by name via `exec()` or `shell()`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Script name (becomes the filename).</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>content</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Script content.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">scripts()</span>

```typescript
scripts(scripts: Record<string, string>): this
```

Add many named scripts at once.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>scripts</code><span className="msb-type">Record&lt;string, string&gt;</span></div>
    <div className="msb-param-desc">Map of script names to contents.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">security()</span>

```typescript
security(profile: "default" | "restricted"): this
```

Set the in-guest security profile.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>profile</code><span className="msb-type">"default" | "restricted"</span></div>
    <div className="msb-param-desc">Security profile.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">secret()</span>

```typescript
secret(configure: (b: SecretBuilder) => SecretBuilder): this
```

Add a secret with full configuration. See [Secrets](/sdk/typescript/secrets) for the builder API. Automatically enables TLS interception.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="/sdk/typescript/secrets#secretbuilder">(b: SecretBuilder) =&gt; SecretBuilder</a></div>
    <div className="msb-param-desc">Configure the secret.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">secretEnv()</span>

```typescript
secretEnv(envVar: string, value: string, allowedHost: string): this
```

Auto-placeholder shorthand for adding a header-injected secret. Generates a `$MSB_<env_var>` placeholder usable in headers.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>envVar</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Environment variable name (non-empty, no <code>=</code> or NUL).</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Secret value.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>allowedHost</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Allowed destination host.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">shell()</span>

```typescript
shell(shell: string): this
```

Set the shell binary used by [`sandbox.shell()`](/sdk/typescript/execution).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>shell</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Shell path (e.g. <code>"/bin/bash"</code>).</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">user()</span>

```typescript
user(user: string): this
```

Set the default guest user for all commands.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>user</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">User name or UID.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">volume()</span>

```typescript
volume(guest: string, configure: (b: MountBuilder) => MountBuilder): this
```

Add a volume mount. See [Volumes](/sdk/typescript/volumes) for mount types.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>guest</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Mount point inside the sandbox.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="/sdk/typescript/volumes">(b: MountBuilder) =&gt; MountBuilder</a></div>
    <div className="msb-param-desc">Configure the mount.</div>
  </div>
</div>

#### <span className="msb-recv">sandboxBuilder.</span><span className="msb-hn">workdir()</span>

```typescript
workdir(path: string): this
```

Set the default working directory for all commands.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

## PatchBuilder

Builder for pre-boot root filesystem patches.

#### <span className="msb-recv">patch.</span><span className="msb-hn">append()</span>

```typescript
append(path: string, content: string): this
```

Append `content` to an existing file at `path`. If the file lives in a lower image layer, it's copied up first.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>content</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Text to append.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">copyDir()</span>

<Tooltip tip="On microsandbox cloud, host sources resolve against your organization's host volume, not the computer running the SDK or CLI."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
copyDir(src: string, dst: string, opts?: { replace?: boolean }): this
```

Recursively copy a host directory at `src` into the guest rootfs at `dst`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Host source directory.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute destination path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.replace</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">When <code>true</code>, overwrite an existing path at <code>dst</code>.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">copyFile()</span>

<Tooltip tip="On microsandbox cloud, host sources resolve against your organization's host volume, not the computer running the SDK or CLI."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
copyFile(src: string, dst: string, opts?: { mode?: number; replace?: boolean }): this
```

Copy a single host file at `src` into the guest rootfs at `dst`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Host source file.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute destination path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.mode</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">File mode, e.g. <code>0o644</code>. Omit to keep the source mode.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.replace</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">When <code>true</code>, overwrite an existing path at <code>dst</code>.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">file()</span>

```typescript
file(path: string, content: Buffer, opts?: { mode?: number; replace?: boolean }): this
```

Write raw bytes at `path`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>content</code><span className="msb-type">Buffer</span></div>
    <div className="msb-param-desc">Raw byte content.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.mode</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">File mode, e.g. <code>0o644</code>.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.replace</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">When <code>true</code>, overwrite an existing path.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">mkdir()</span>

<Tooltip tip="On microsandbox cloud, host sources resolve against your organization's host volume, not the computer running the SDK or CLI."><span className="msb-badge-note">On cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```typescript
mkdir(path: string, opts?: { mode?: number }): this
```

Create a directory at `path`. Idempotent: a no-op if the directory already exists.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.mode</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">Directory mode, e.g. <code>0o755</code>.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">remove()</span>

```typescript
remove(path: string): this
```

Delete a file or directory at `path`. Idempotent: a no-op if the path doesn't exist.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">symlink()</span>

```typescript
symlink(target: string, link: string, opts?: { replace?: boolean }): this
```

Create a symlink at `link` pointing to `target`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>target</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">What the symlink points to (literal symlink target text).</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>link</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path of the symlink itself.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.replace</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">When <code>true</code>, overwrite an existing path at <code>link</code>.</div>
  </div>
</div>

#### <span className="msb-recv">patch.</span><span className="msb-hn">text()</span>

```typescript
text(path: string, content: string, opts?: { mode?: number; replace?: boolean }): this
```

Write UTF-8 text content at `path`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>content</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Text content.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.mode</code><span className="msb-type">number</span></div>
    <div className="msb-param-desc">File mode, e.g. <code>0o644</code>.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>opts.replace</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">When <code>true</code>, overwrite an existing path.</div>
  </div>
</div>

## LogEntry


<p className="msb-backref">Returned by <a href="#sandbox-logs">logs()</a> · <a href="#sandbox-logstream">logStream()</a></p>

A class wrapping one captured log entry from `exec.log`. Bytes are exposed via `data`; use `text()` for a UTF-8-lossy decode.

#### <span className="msb-recv">entry.</span><span className="msb-hn">timestamp</span>

`Date`

Wall-clock capture time on the host

#### <span className="msb-recv">entry.</span><span className="msb-hn">source</span>

[`LogSource`](#logsource)

Where the chunk came from

#### <span className="msb-recv">entry.</span><span className="msb-hn">sessionId</span>

`number \| null`

Relay-monotonic session id; `null` for `"system"` entries

#### <span className="msb-recv">entry.</span><span className="msb-hn">data</span>

`Uint8Array`

The captured chunk's bytes (UTF-8 lossy decoded by default)

#### <span className="msb-recv">entry.</span><span className="msb-hn">cursor</span>

`string`

Opaque resume token; pass to [`LogStreamOptions.fromCursor`](#logstreamoptions) to resume

#### <span className="msb-recv">entry.</span><span className="msb-hn">text()</span>

```typescript
text()
```

Convenience: UTF-8 decode of `data` (lossy - invalid bytes are replaced)

<p className="msb-label">Returns</p>

`string`

## LogStream


<p className="msb-backref">Returned by <a href="#sandbox-logstream">logStream()</a></p>

An async iterable of [`LogEntry`](#logentry) values. Drain it with `for await...of` or call `recv()` directly. Implements `AsyncDisposable`, so it works with `await using`.

#### <span className="msb-recv">logStream.</span><span className="msb-hn">recv()</span>

```typescript
recv()
```

Receive the next entry. Returns `null` when the stream ends.

<p className="msb-label">Returns</p>

`Promise<`[`LogEntry`](#logentry)` \| null>`

#### <span className="msb-recv">stream.</span><span className="msb-hn">[Symbol.asyncIterator]()</span>

```typescript
[Symbol.asyncIterator]()
```

Use with `for await...of`

<p className="msb-label">Returns</p>

`AsyncIterator<`[`LogEntry`](#logentry)`>`

#### <span className="msb-recv">stream.</span><span className="msb-hn">[Symbol.asyncDispose]()</span>

```typescript
[Symbol.asyncDispose]()
```

Stop iterating; safe to use with `await using`

<p className="msb-label">Returns</p>

`Promise<void>`

## MetricsStream


<p className="msb-backref">Returned by <a href="#sandbox-metricsstream">metricsStream()</a></p>

Async stream for receiving periodic metrics snapshots. Implements `AsyncDisposable`, so it works with `await using`.

#### <span className="msb-recv">metricsStream.</span><span className="msb-hn">recv()</span>

```typescript
recv()
```

Receive the next snapshot. Returns `null` when the stream ends.

<p className="msb-label">Returns</p>

`Promise<`[`SandboxMetrics`](#sandboxmetrics)` \| null>`

#### <span className="msb-recv">stream.</span><span className="msb-hn">[Symbol.asyncIterator]()</span>

```typescript
[Symbol.asyncIterator]()
```

Use with `for await...of`

<p className="msb-label">Returns</p>

`AsyncIterator<`[`SandboxMetrics`](#sandboxmetrics)`>`

#### <span className="msb-recv">stream.</span><span className="msb-hn">[Symbol.asyncDispose]()</span>

```typescript
[Symbol.asyncDispose]()
```

Stop iterating; safe to use with `await using`

<p className="msb-label">Returns</p>

`Promise<void>`

## PullProgressCreate


<p className="msb-backref">Returned by <a href="#createwithpullprogress">createWithPullProgress()</a></p>

Async iterable creation handle returned by [`createWithPullProgress()`](#createwithpullprogress). Yields [`PullProgress`](#pullprogress) events as the image is resolved, downloaded, and materialized. Call `awaitSandbox()` after iteration to obtain the live sandbox.

#### <span className="msb-recv">pull.</span><span className="msb-hn">progress</span>

`NapiPullProgressStream`

The underlying progress event stream

#### <span className="msb-recv">pull.</span><span className="msb-hn">awaitSandbox()</span>

```typescript
awaitSandbox()
```

Resolve the underlying creation task and return the running sandbox

<p className="msb-label">Returns</p>

`Promise<`[`Sandbox`](#instance-methods)`>`

#### <span className="msb-recv">pull.</span><span className="msb-hn">[Symbol.asyncIterator]()</span>

```typescript
[Symbol.asyncIterator]()
```

Use with `for await...of`

<p className="msb-label">Returns</p>

`AsyncIterator<`[`PullProgress`](#pullprogress)`>`

## SandboxListBuilder


Fluent configuration passed to [`Sandbox.listWith()`](#sandbox-listwith). Keep the labels and limit unchanged when continuing with a cursor.


#### <span className="msb-recv">list.</span><span className="msb-hn">limit()</span>

```typescript
limit(n)
```

Set a page size from 1 through 100

#### <span className="msb-recv">list.</span><span className="msb-hn">cursor()</span>

```typescript
cursor(cursor)
```

Continue after a previous page's `nextCursor`

#### <span className="msb-recv">list.</span><span className="msb-hn">label()</span>

```typescript
label(key, value)
```

Require one label; repeated calls are AND-matched

#### <span className="msb-recv">list.</span><span className="msb-hn">labels()</span>

```typescript
labels(record)
```

Add several AND-matched labels

## SandboxHandle


<p className="msb-backref">Returned by <a href="#sandbox-get">Sandbox.get()</a> · <a href="#sandbox-list">Sandbox.list()</a> · <a href="#sandbox-listwith">Sandbox.listWith()</a></p>

A metadata and lifecycle handle for an existing sandbox.

#### <span className="msb-recv">handle.</span><span className="msb-hn">name</span>

`string`

Sandbox name, up to 128 UTF-8 bytes

#### <span className="msb-recv">handle.</span><span className="msb-hn">status</span>

[`SandboxStatus`](#sandboxstatus)

Current status

#### <span className="msb-recv">handle.</span><span className="msb-hn">configJson</span>

`string`

Raw JSON configuration

#### <span className="msb-recv">handle.</span><span className="msb-hn">createdAt</span>

`Date \| null`

Creation timestamp

#### <span className="msb-recv">handle.</span><span className="msb-hn">updatedAt</span>

`Date \| null`

Last update timestamp

#### <span className="msb-recv">handle.</span><span className="msb-hn">config()</span>

```typescript
config()
```

Parsed configuration

<p className="msb-label">Returns</p>

[`SandboxConfig`](#sandboxconfig)

#### <span className="msb-recv">handle.</span><span className="msb-hn">refresh()</span>

```typescript
refresh()
```

Re-read the handle's state from the database

<p className="msb-label">Returns</p>

`Promise<`[`SandboxHandle`](#sandboxhandle)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">ping()</span>

```typescript
ping()
```

Check agent reachability without refreshing idle activity; does not start stopped sandboxes

<p className="msb-label">Returns</p>

`Promise<`[`SandboxPingResult`](#sandboxpingresult)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">touch()</span>

```typescript
touch()
```

Explicitly refresh idle activity; does not start stopped sandboxes

<p className="msb-label">Returns</p>

`Promise<`[`SandboxTouchResult`](#sandboxtouchresult)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">modify()</span>

```typescript
modify(opts?)
```

Plan or apply a configuration change; same options as [`modify()`](#sandbox-modify). Does not start stopped sandboxes; changes persist for the next boot

<p className="msb-label">Returns</p>

`Promise<`[`SandboxModificationPlan`](#sandboxmodificationplan)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">metrics()</span>

```typescript
metrics()
```

Point-in-time resource metrics

<p className="msb-label">Returns</p>

`Promise<`[`SandboxMetrics`](#sandboxmetrics)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">logs()</span>

```typescript
logs()
```

Read captured `exec.log` (works without starting)

<p className="msb-label">Returns</p>

`Promise<`[`LogEntry`](#logentry)`[]>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">logStream()</span>

```typescript
logStream()
```

Stream captured `exec.log`, with optional follow

<p className="msb-label">Returns</p>

`Promise<`[`LogStream`](#logstream)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">start()</span>

```typescript
start()
```

Start in attached mode

<p className="msb-label">Returns</p>

`Promise<`[`Sandbox`](#instance-methods)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">startDetached()</span>

```typescript
startDetached()
```

Start in detached mode

<p className="msb-label">Returns</p>

`Promise<`[`Sandbox`](#instance-methods)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">connect()</span>

```typescript
connect()
```

Connect to a running sandbox without taking ownership. Returns an error if it doesn't respond within 10_000 ms

<p className="msb-label">Returns</p>

`Promise<`[`Sandbox`](#instance-methods)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">connectWithTimeout()</span>

```typescript
connectWithTimeout(timeoutMs)
```

Same as `connect()` with an explicit timeout in milliseconds

<p className="msb-label">Returns</p>

`Promise<`[`Sandbox`](#instance-methods)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">stop()</span>

```typescript
stop()
```

Gracefully shut down. Waits up to 10_000 ms for pending writes to flush, then force-kills

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">stopWithTimeout()</span>

```typescript
stopWithTimeout(timeoutMs)
```

Same as `stop()` with an explicit timeout in milliseconds; `0` force-kills immediately

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">requestStop()</span>

```typescript
requestStop()
```

Request graceful shutdown without waiting

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">kill()</span>

```typescript
kill()
```

Force terminate and wait until stopped state is observed

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">killWithTimeout()</span>

```typescript
killWithTimeout(timeoutMs)
```

Same as `kill()` with an explicit observation timeout

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">requestKill()</span>

```typescript
requestKill()
```

Request force termination without waiting

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">requestDrain()</span>

```typescript
requestDrain()
```

Request graceful drain without waiting

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">waitUntilStopped()</span>

```typescript
waitUntilStopped()
```

Block until the sandbox reaches terminal state

<p className="msb-label">Returns</p>

`Promise<`[`SandboxStopResult`](#sandboxstopresult)`>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">remove()</span>

```typescript
remove()
```

Delete sandbox and state

<p className="msb-label">Returns</p>

`Promise<void>`

#### <span className="msb-recv">handle.</span><span className="msb-hn">snapshot()</span>

```typescript
snapshot(name)
```

Snapshot this stopped sandbox under a bare name. See [Snapshots](/sdk/typescript/snapshots)

<p className="msb-label">Returns</p>

`Promise<Snapshot>`

## RegistryConfigBuilder

Fluent builder for OCI registry connection settings. Obtain it through [`SandboxBuilder.registry()`](#registry); the callback's returned builder is stored in the sandbox configuration.

```typescript
.registry((r) =>
  r.auth({ kind: "basic", username: "user", password: "token" })
    .caCertsPath("/etc/company-registry-ca.pem"),
)
```


#### <span className="msb-recv">registry.</span><span className="msb-hn">auth()</span>

```typescript
auth(auth: RegistryAuth): this
```

Set registry authentication credentials.

<p className="msb-label">Returns</p>

`this`

#### <span className="msb-recv">registry.</span><span className="msb-hn">insecure()</span>

```typescript
insecure(): this
```

Use plain HTTP instead of TLS.

<p className="msb-label">Returns</p>

`this`

#### <span className="msb-recv">registry.</span><span className="msb-hn">caCerts()</span>

```typescript
caCerts(pemData: Buffer): this
```

Add a PEM-encoded CA certificate. May be called repeatedly.

<p className="msb-label">Returns</p>

`this`

#### <span className="msb-recv">registry.</span><span className="msb-hn">caCertsPath()</span>

```typescript
caCertsPath(path: string): this
```

Read and add a PEM-encoded CA certificate from a filesystem path.

<p className="msb-label">Returns</p>

`this`

#### <span className="msb-recv">registry.</span><span className="msb-hn">build()</span>

```typescript
build(): RegistryConfig
```

Snapshot the accumulated registry configuration.

<p className="msb-label">Returns</p>

[`RegistryConfig`](#registryconfig)

## Types

### LogLevel

<p className="msb-backref">Used by <a href="#loglevel">logLevel()</a></p>

Sandbox process log verbosity. String literal type.

| Value | Description |
|-------|-------------|
| `"error"` | Errors only |
| `"warn"` | Warnings and errors only |
| `"info"` | Info and higher |
| `"debug"` | Debug and higher |
| `"trace"` | Most verbose - all diagnostic output |

### LogReadOptions

<p className="msb-backref">Used by <a href="#sandbox-logs">logs()</a></p>

Filters passed to [`logs()`](#sandbox-logs). All fields optional. Omit the argument entirely for the default sources (`stdout` + `stderr` + `output`).

| Field | Type | Description |
|-------|------|-------------|
| tail | `number?` | Show only the last N entries after other filters apply |
| since | `Date?` | Inclusive lower bound on entry timestamp |
| until | `Date?` | Exclusive upper bound on entry timestamp |
| sources | `ReadonlyArray<`[`LogSource`](#logsource)` \| "all">?` | Sources to include. Omit = `["stdout", "stderr", "output"]`. Add `"system"` or pass `"all"` to merge runtime/kernel diagnostics. |

### LogStreamOptions

<p className="msb-backref">Used by <a href="#sandbox-logstream">logStream()</a></p>

Options passed to [`logStream()`](#sandbox-logstream). All fields optional. `since` and `fromCursor` are mutually exclusive - passing both rejects at the boundary.

| Field | Type | Description |
|-------|------|-------------|
| sources | `ReadonlyArray<`[`LogSource`](#logsource)` \| "all">?` | Same shape as [`LogReadOptions.sources`](#logreadoptions) |
| since | `Date?` | Start at the first entry whose timestamp is `>= since`. Mutually exclusive with `fromCursor`. |
| fromCursor | `string?` | Resume strictly after the entry whose [`LogEntry.cursor`](#logentry) matches. Mutually exclusive with `since`. |
| until | `Date?` | Stop emitting at the first entry whose timestamp is `>= until` |
| follow | `boolean?` | When `true`, keep the stream open past current EOF and yield new entries as they are written. Defaults to `false`. |

### LogSource

<p className="msb-backref">Used by <a href="#logentry">LogEntry.source</a> · <a href="#logreadoptions">LogReadOptions.sources</a></p>

Tag indicating where a captured log entry came from. String literal type:

```typescript
type LogSource = "stdout" | "stderr" | "output" | "system";
```

| Value | Description |
|-------|-------------|
| `"stdout"` | Captured from a session's stdout (pipe mode - streams stayed separated) |
| `"stderr"` | Captured from a session's stderr (pipe mode) |
| `"output"` | Captured from a session running in PTY mode. PTY allocation merges stdout and stderr at the kernel level inside the guest, so they arrive as a single stream - tagged `"output"` rather than mislabelled as `"stdout"`. |
| `"system"` | Synthetic entry: lifecycle markers in `exec.log` plus runtime/kernel diagnostic lines merged in at read time when `"system"` is requested. |

### ModifyOptions

<p className="msb-backref">Used by <a href="#sandbox-modify">modify()</a></p>

A requested sandbox modification. Omitted fields are left unchanged.

| Field | Type | Description |
|-------|------|-------------|
| cpus | `number` | Desired effective vCPU count. Live when within the booted `maxCpus` |
| maxCpus | `number` | Boot-time maximum possible vCPUs (restart-backed) |
| memory | `number` | Desired effective guest memory in MiB. Live when within the booted `maxMemory` |
| maxMemory | `number` | Boot-time maximum hotpluggable memory in MiB (restart-backed) |
| rootDiskSize | `number` | Desired root disk size in MiB. Managed and flat OCI disks are grow-only; applies on restart or next start |
| env | `Record<string, string>` | Environment variables to set for future execs |
| envRemove | `string[]` | Environment variable keys to remove |
| labels | `Record<string, string>` | Labels to set |
| labelsRemove | `string[]` | Label keys to remove |
| workdir | `string` | Working directory for future execs |
| secrets | `Record<string, SecretModifySpec>` | Desired secret specs keyed by stable secret name |
| secretsRemove | `string[]` | Secret names to remove explicitly |
| policy | `"no_restart" \| "next_start" \| "restart"` | `"no_restart"` (default) applies only changes that can complete without restarting; `"next_start"` persists changes for the next start without mutating a running VM; `"restart"` restarts if needed so restart-required changes become active now |
| dryRun | `boolean` | Compute the plan without applying anything. Defaults to `false` |

### SecretModifySpec

<p className="msb-backref">Used by <a href="#sandbox-modify">modify()</a></p>

Desired state for one secret. `env`, `value`, and `store` are mutually exclusive sources. Omit all three to update only the placeholder or allowed hosts.

| Field | Type | Description |
|-------|------|-------------|
| env | `string` | Host environment variable to resolve when applying the modification |
| value | `string` | Raw secret value. Stored in the durable sandbox config until replaced by a source reference |
| store | `string` | Reserved for a host-side secret store reference; currently unsupported |
| placeholder | `string` | Explicit guest-visible placeholder. New secrets default to `$MSB_<NAME>` |
| allowedHosts | `string[]` | Desired allowed host patterns. A new secret requires at least one; an empty list leaves existing hosts unchanged |

### PullPolicy

<p className="msb-backref">Used by <a href="#pullpolicy">pullPolicy()</a></p>

Controls when the SDK fetches an OCI image from the registry. String literal type.

| Value | Description |
|-------|-------------|
| `"always"` | Pull the image every time, even if cached locally |
| `"if-missing"` | Pull only if the image is not already cached. This is the default. |
| `"never"` | Never pull; fail if the image is not cached locally |

### PullProgress

<p className="msb-backref">Yielded by <a href="#pullprogresscreate">PullProgressCreate</a></p>

Image pull and materialize progress event emitted by [`PullProgressCreate`](#pullprogresscreate). A discriminated union. Narrow on `kind` to access variant-specific fields.

| `kind` value | Additional fields |
|--------------|-------------------|
| `"resolving"` | `reference: string` |
| `"resolved"` | `reference: string`, `manifestDigest: string`, `layerCount: number`, `totalDownloadBytes?: number` |
| `"layerDownloadProgress"` | `layerIndex: number`, `digest: string`, `downloadedBytes: number`, `totalBytes?: number` |
| `"layerDownloadComplete"` | `layerIndex: number`, `digest: string`, `downloadedBytes: number` |
| `"layerDownloadVerifying"` | `layerIndex: number`, `digest: string` |
| `"layerMaterializeStarted"` | `layerIndex: number`, `diffId: string` |
| `"layerMaterializeProgress"` | `layerIndex: number`, `bytesRead: number`, `totalBytes: number` |
| `"layerMaterializeWriting"` | `layerIndex: number` |
| `"layerMaterializeComplete"` | `layerIndex: number`, `diffId: string` |
| `"stitchMergingTrees"` | `layerCount: number` |
| `"stitchWritingFsmeta"` | (none) |
| `"stitchWritingVmdk"` | (none) |
| `"stitchComplete"` | (none) |
| `"complete"` | `reference: string`, `layerCount: number` |

`totalDownloadBytes` and `totalBytes` on the `"resolved"` / `"layerDownloadProgress"` variants may be absent if the manifest omits sizes.

### RegistryAuth

Authentication used when pulling images from an OCI registry.

```typescript
type RegistryAuth =
  | { kind: "anonymous" }
  | { kind: "basic"; username: string; password: string };
```

### RegistryConfig

<p className="msb-backref">Built by <a href="#registryconfigbuilder">RegistryConfigBuilder</a> · stored in <a href="#sandboxconfig">SandboxConfig.registry</a></p>

OCI registry connection settings produced by [`RegistryConfigBuilder.build()`](#registryconfigbuilder).

| Field | Type | Description |
|-------|------|-------------|
| auth | [`RegistryAuth`](#registryauth)` \| undefined` | Registry authentication, if configured. |
| insecure | `boolean` | Whether to use plain HTTP instead of TLS. |
| caCertsCount | `number` | Number of CA certificates added through `caCerts()` or `caCertsPath()`. |
| caCertsPath | `string \| undefined` | Last CA certificate path passed to `caCertsPath()`, if any. |

### SandboxConfig

<p className="msb-backref">Returned by <a href="#sandbox-config">config()</a> · <a href="#build">build()</a></p>

Configuration object produced by [`build()`](#build) and returned by [`config()`](#sandbox-config). You generally should not construct this by hand; use the builder.

| Field | Type | Description |
|-------|------|-------------|
| name | `string` | Sandbox name, up to 128 UTF-8 bytes |
| image | `RootfsSource` | OCI / bind / disk discriminated union |
| cpus | `number \| null` | Virtual CPUs |
| maxCpus | `number \| null` | Boot-time maximum possible virtual CPUs |
| memoryMib | `number \| null` | Guest memory in MiB |
| maxMemoryMib | `number \| null` | Boot-time maximum hotpluggable memory in MiB |
| logLevel | [`LogLevel`](#loglevel)` \| null` | Log verbosity |
| quietLogs | `boolean` | Suppress log output |
| workdir | `string \| null` | Default working directory |
| shell | `string \| null` | Shell binary |
| securityProfile | `"default" \| "restricted"` | In-guest security profile |
| entrypoint | `string[] \| null` | Override the image ENTRYPOINT used by default-workload execution |
| cmd | `string[] \| null` | Override the image CMD used by default-workload execution; an empty array clears CMD |
| hostname | `string \| null` | Guest hostname |
| user | `string \| null` | Default guest user |
| env | `Array<readonly [string, string]>` | Environment variables |
| scripts | `Array<readonly [string, string]>` | Named scripts |
| mounts | `VolumeMount[]` | Volume mounts |
| patches | `Patch[]` | Rootfs modifications applied before boot |
| pullPolicy | [`PullPolicy`](#pullpolicy)` \| null` | Image pull behavior |
| replace | `boolean` | Replace existing sandbox with same name |
| replaceWithTimeoutMs | `number` | Milliseconds to wait after `SIGTERM` before escalating to `SIGKILL` (default `10000`; `0` skips `SIGTERM`) |
| maxDurationSecs | `number \| null` | Maximum sandbox lifetime |
| idleTimeoutSecs | `number \| null` | Stop after idle time |
| portsTcp | `Array<readonly [number, number]>` | TCP host→guest mappings |
| portsUdp | `Array<readonly [number, number]>` | UDP host→guest mappings |
| registry | [`RegistryConfig`](#registryconfig)` \| null` | Registry connection settings |
| network | `NetworkConfig \| null` | Network configuration |
| disableNetwork | `boolean` | Disable networking entirely |
| secrets | `SecretEntry[]` | Secret entries (top-level) |

### SandboxPage

One stable, newest-first page returned by [`Sandbox.list()`](#sandbox-list) or [`Sandbox.listWith()`](#sandbox-listwith).

| Property | Type | Description |
|----------|------|-------------|
| `sandboxes` | `SandboxHandle[]` | Handles in this page |
| `nextCursor` | `string \| undefined` | Opaque continuation cursor, absent on the final page |

### SandboxModificationPlan

<p className="msb-backref">Returned by <a href="#sandbox-modify">modify()</a></p>

Dry-run or apply plan for a sandbox modification. Values never appear in a plan: secret entries carry only guest-visible references.

| Field | Type | Description |
|-------|------|-------------|
| sandbox | `string` | Sandbox being modified |
| status | `string` | Status used for classification (`"running"`, `"stopped"`, ...) |
| applied | `boolean` | Whether the changes were applied; `false` for dry runs |
| policy | `"no_restart" \| "next_start" \| "restart"` | Policy used to produce the plan |
| changes | [`PlannedChange`](#plannedchange)`[]` | Planned changes, one entry per field or secret |
| conflicts | `{ field, message }[]` | Conflicts that must be resolved before the patch can apply |
| warnings | `{ field, message }[]` | Non-fatal warnings, e.g. the future-execs-only env caveat |
| resizeStatus | `ResourceResizeStatus[]` | Live resource resize outcomes, populated by apply when a live change ran (see below) |

### PlannedChange

<p className="msb-backref">Used by <a href="#sandboxmodificationplan">SandboxModificationPlan.changes</a></p>

Discriminated union on `kind`. Both variants carry `field`, `change`, `disposition`, and `reason`.

| Variant | Type | Description |
|---------|------|-------------|
| `kind: "config"` | [`ConfigPlannedChange`](#configplannedchange) | Ordinary config change |
| `kind: "secret"` | [`SecretPlannedChange`](#secretplannedchange) | Secret change. Values are omitted by construction; references are guest-visible only |

### ConfigPlannedChange

<p className="msb-backref">Variant of <a href="#plannedchange">PlannedChange</a></p>

Ordinary configuration change in a modification plan.

| Field | Type | Description |
|-------|------|-------------|
| field | `string` | Config field being changed |
| change | `"added" \| "updated" \| "removed"` | Natural change type for table rendering |
| before | `string \| null` | Previous safe visible state |
| after | `string \| null` | New safe visible state |
| disposition | `"live" \| "next start" \| "requires restart" \| "unsupported"` | When or whether the change can take effect |
| reason | `string \| null` | Human-readable reason for the classification, when useful |

### SecretPlannedChange

<p className="msb-backref">Variant of <a href="#plannedchange">PlannedChange</a></p>

Secret change in a modification plan. Values are omitted by construction; `beforeRef` and `afterRef` are guest-visible references.

| Field | Type | Description |
|-------|------|-------------|
| field | `string` | Always `"secret"` |
| name | `string` | Stable secret identity, usually the environment variable name |
| change | `"added" \| "rotated" \| "removed" \| "renamed" \| "hosts updated" \| "placeholder updated"` | Natural change type for table rendering |
| beforeRef | `string \| null` | Previous guest-visible reference or placeholder |
| afterRef | `string \| null` | New guest-visible reference or placeholder |
| disposition | `"live" \| "next start" \| "requires restart" \| "unsupported"` | When or whether the change can take effect |
| allowHosts | `string[]` | Allowed hosts after the requested change |
| reason | `string \| null` | Human-readable reason for the classification, when useful |

`ResourceResizeStatus` reports runtime convergence for a live resize; enforcement applies immediately, the guest converges asynchronously:

| Field | Type | Description |
|-------|------|-------------|
| resource | `"cpus" \| "memory"` | Resource being resized |
| requested | `string` | Requested value |
| actual | `string` | Actual value observed in the guest/runtime |
| enforced | `string` | Host/VMM-enforced value |
| state | `"accepted" \| "converging" \| "applied" \| "guest-refused" \| "failed"` | `"applied"` when requested, actual, and enforced match; `"converging"` while the guest is still onlining CPUs or plugging memory; `"guest-refused"` when the guest would not cooperate (the host enforces the new limit anyway) |

### SandboxPingResult

<p className="msb-backref">Returned by <a href="#sandbox-ping">ping()</a></p>

Agent reachability result.

| Field | Type | Description |
|-------|------|-------------|
| name | `string` | Sandbox name |
| latencyMs | `number` | Round-trip latency in milliseconds |

### SandboxTouchResult

<p className="msb-backref">Returned by <a href="#sandbox-touch">touch()</a></p>

Explicit idle-refresh result.

| Field | Type | Description |
|-------|------|-------------|
| name | `string` | Sandbox name |
| activitySeq | `number` | Monotonic activity sequence after the touch |

### SandboxMetrics

<p className="msb-backref">Returned by <a href="#sandbox-metrics">metrics()</a> · yielded by <a href="#metricsstream">MetricsStream</a></p>

Point-in-time resource usage snapshot.

| Field | Type | Description |
|-------|------|-------------|
| cpuPercent | `number` | CPU usage as a percentage |
| vcpuTimeNs | `number` | Cumulative vCPU time in nanoseconds |
| memoryBytes | `number` | Current memory usage in bytes |
| memoryAvailableBytes | `number \| null` | Guest-visible available memory in bytes when reported |
| memoryHostResidentBytes | `number \| null` | Host-resident memory backing the guest in bytes when reported |
| memoryLimitBytes | `number` | Memory limit in bytes |
| diskReadBytes | `number` | Total bytes read from disk since boot |
| diskWriteBytes | `number` | Total bytes written to disk since boot |
| netRxBytes | `number` | Total bytes received over the network since boot |
| netTxBytes | `number` | Total bytes sent over the network since boot |
| upperUsedBytes | `number \| null` | Guest-visible OCI upper filesystem used bytes when the protected reporter is available and fresh |
| upperFreeBytes | `number \| null` | Guest-visible OCI upper filesystem free bytes when the protected reporter is available and fresh |
| upperHostAllocatedBytes | `number \| null` | Host-allocated bytes for the writable OCI upper image when available |
| uptimeMs | `number` | Time since the sandbox was created (ms) |
| timestamp | `Date` | When this measurement was taken |

### SandboxStopResult

<p className="msb-backref">Returned by <a href="#sandbox-waituntilstopped">waitUntilStopped()</a></p>

Observed terminal sandbox state returned by [`waitUntilStopped()`](#sandbox-waituntilstopped).

| Field | Type | Description |
|-------|------|-------------|
| name | `string` | Sandbox name |
| status | [`SandboxStatus`](#sandboxstatus) | Terminal status that was observed |
| exitCode | `number \| null` | Process exit code when it is available |
| signal | `number \| null` | Terminating signal when the process was killed |
| observedAt | `Date` | When the terminal state was observed |
| source | `string \| null` | Origin of the observation when reported |

### SandboxStatus

<p className="msb-backref">Used by <a href="#sandboxhandle">SandboxHandle.status</a> · <a href="#sandboxstopresult">SandboxStopResult.status</a></p>

Current lifecycle state of a sandbox. String literal type.

| Value | Description |
|-------|-------------|
| `"running"` | Guest agent is ready; `exec`, `shell`, `fs` work |
| `"stopped"` | VM shut down; configuration persisted; can be restarted |
| `"crashed"` | VM exited unexpectedly (kernel panic, OOM, etc.) |
| `"draining"` | Graceful shutdown in progress; existing commands finish, new ones rejected |
