Skip to main content
AgentClient is the low-level raw transport for talking to agentd through a running sandbox’s relay socket. For most applications, use Sandbox, exec, and fs instead. Reach for this API when you are building protocol-level tools or higher-level SDK helpers. All request and response bodies are raw CBOR bytes. The SDK handles framing and correlation ids, but it does not encode or decode the CBOR message body for you: decode it with a library such as cbor-x. The raw body is the full CBOR-encoded protocol Message body (v, t, p), not just the inner payload.

Typical flow

import { encode, decode } from "cbor-x";
import { AgentClient, FLAG_SESSION_START } from "microsandbox";

const client = await AgentClient.connectSandbox("dev");        // 1. connect

const body = encode({                                          // 2. build a CBOR Message
  v: 1,
  t: "core.fs.request",
  p: encode({ op: { Stat: { path: "/etc" } } }),
});

const frame = await client.request(FLAG_SESSION_START, body);  // 3. request / response
console.log(decode(frame.body));

await client.close();                                          // 4. close

Constants

FLAG_TERMINAL

const FLAG_TERMINAL = 0b0000_0001
Frame flag: this is the last message for the given correlation id. When a frame on an open stream carries this bit, no further frames will arrive for that id.

FLAG_SESSION_START

const FLAG_SESSION_START = 0b0000_0010
Frame flag: this is the first message of a new session. Set it on the opening frame of a request/response RPC or a streaming session.

FLAG_SHUTDOWN

const FLAG_SHUTDOWN = 0b0000_0100
Frame flag: this message requests sandbox shutdown.

Static methods

AgentClient.connectSandbox()

static connectSandbox(name: string, opts?: AgentConnectOptions): Promise<AgentClient>
const client = await AgentClient.connectSandbox("dev", { timeoutMs: 5000 });
Connect to a running sandbox by name. Resolves the sandbox’s relay socket path and performs the core.ready handshake. Sandbox names are limited to 128 UTF-8 bytes.

Parameters

namestring
Sandbox name, up to 128 UTF-8 bytes.
Optional connect settings, e.g. handshake timeout.

Returns

Connected client.

AgentClient.connect()

static connect(path: string, opts?: AgentConnectOptions): Promise<AgentClient>
const path = AgentClient.socketPath("dev");
const client = await AgentClient.connect(path);
Connect to an agentd relay socket by path. Use this when you already have the socket path, for example one returned by socketPath().

Parameters

pathstring
Filesystem path of the relay socket.
Optional connect settings, e.g. handshake timeout.

Returns

Connected client.

AgentClient.socketPath()

static socketPath(name: string): string
const path = AgentClient.socketPath("dev");
Resolve a sandbox’s agentd relay socket path without connecting. Returns the same path connectSandbox() would dial, so you can talk to agentd over a raw byte transport (for example a transparent relay that splices bytes to and from the socket) instead of this frame client. The sandbox need not be running. Sandbox names are limited to 128 UTF-8 bytes.

Parameters

namestring
Sandbox name, up to 128 UTF-8 bytes.

Returns

string
Relay socket path.

Instance methods

client.request()

request(flags: number, body: Buffer): Promise<RawFrame>
import { encode, decode } from "cbor-x";
import { FLAG_SESSION_START } from "microsandbox";

const body = encode({ v: 1, t: "core.fs.request", p: encode({ op: { Stat: { path: "/etc" } } }) });
const frame = await client.request(FLAG_SESSION_START, body);
console.log(decode(frame.body));
Send one frame and await a single response frame. Use for request/response RPCs that produce exactly one terminal response (for example FsRequest to FsResponse).

Parameters

flagsnumber
Frame flag byte, e.g. FLAG_SESSION_START.
bodyBuffer
CBOR-encoded protocol message body.

Returns

The single response frame.

client.stream()

stream(flags: number, body: Buffer): Promise<AgentStream>
import { FLAG_SESSION_START, FLAG_TERMINAL } from "microsandbox";

const stream = await client.stream(FLAG_SESSION_START, body);
for await (const frame of stream) {
  if ((frame.flags & FLAG_TERMINAL) !== 0) break;
}
Open a streaming session. The returned AgentStream carries the protocol correlation id (pass it to send() for follow-up frames) and is also an async iterator of raw frames.

Parameters

flagsnumber
Frame flag byte for the opening frame, e.g. FLAG_SESSION_START.
bodyBuffer
CBOR-encoded protocol message body.

Returns

Open stream of raw frames.

client.send()

send(id: number, flags: number, body: Buffer): Promise<void>
await client.send(stream.id, 0, encode({ v: 1, t: "core.pty.stdin", p: encode({ data: "ls\n" }) }));
Send a follow-up frame on an existing correlation id (for example stdin, a signal, a resize, or data chunks on an open session). Use the id of the AgentStream returned by stream().

Parameters

idnumber
Correlation id of an open session.
flagsnumber
Frame flag byte.
bodyBuffer
CBOR-encoded protocol message body.

client.readyBytes()

readyBytes(): Buffer
import { decode } from "cbor-x";

const ready = decode(client.readyBytes());
Return the cached handshake core.ready frame body as CBOR bytes. Captured during connect, so this is a synchronous accessor with no protocol traffic.

Returns

Buffer
CBOR-encoded core.ready frame body.

client.close()

close(): Promise<void>
await client.close();
Close the connection. Idempotent: calling it more than once is safe.

Types

AgentClient

Low-level client for talking to agentd through the sandbox relay socket. All bodies are raw CBOR bytes: encode and decode them in your code with a library like cbor-x, and build typed convenience methods on top of this class. Construct it with one of the static connect methods.
Property / MethodTypeDescription
AgentClient.connectSandbox(name, opts?)Promise<AgentClient>Connect by sandbox name
AgentClient.connect(path, opts?)Promise<AgentClient>Connect by relay socket path
AgentClient.socketPath(name)stringResolve the relay socket path without connecting
request(flags, body)Promise<RawFrame>Send one frame, await one response
stream(flags, body)Promise<AgentStream>Open a streaming session
send(id, flags, body)Promise<void>Send a follow-up frame on a correlation id
readyBytes()BufferCached core.ready handshake frame body
close()Promise<void>Close the connection (idempotent)

AgentStream

Returned by stream()

An open raw agent stream. Implements AsyncIterableIterator<RawFrame>, so it can be driven with for await. The iterator ends after a frame carrying FLAG_TERMINAL or when the underlying stream is exhausted.
Property / MethodTypeDescription
idnumberProtocol correlation id; pass to send() for follow-up frames
next()Promise<IteratorResult<RawFrame>>Pull the next frame; done once terminal or exhausted
close()Promise<void>Release the stream handle early (idempotent)
return()Promise<IteratorResult<RawFrame>>Async-iterator early-exit hook; closes the stream
Symbol.asyncIteratorAgentStreamReturns itself so the stream is iterable

RawFrame

Returned by request() · iterated from AgentStream

A raw protocol frame. The body is the CBOR-encoded Message body (v, t, p) as it appeared on the wire; decode it with a CBOR library such as cbor-x.
FieldTypeDescription
idnumberCorrelation id from the frame header
flagsnumberFrame flags (FLAG_TERMINAL, FLAG_SESSION_START, …)
bodyBufferRaw CBOR-encoded body bytes

AgentConnectOptions

Used by connectSandbox() · connect()

Options for connecting to an agent relay.
FieldTypeDescription
timeoutMsnumberHandshake timeout in milliseconds. Defaults to 10_000.