BlaiseBlaise
Documentation
Runner and PlugsReference

Host API

The building blocks in @blaiseagent/runner/host for plugs that provide a host.

@blaiseagent/runner/host exports what a plug needs to provide a host. The Host type itself, which plugs receive as ctx.host, is described in the Plug API.

createHost(options)

Builds a lazy Host.

OptionTypeDescription
infoHostInfoKind, OS, home, temporary directory, workspace and persistent.
connect() => Promise<HostConnection>Creates or wakes the machine and connects. Runs once, on first use.

Concurrent first uses share one connect call. exec and spawn run over the connection's transport, and fs is the node:vfs API over its provider. When info.persistent is true, spawn starts the process under the watchdog unless its transport already owns supervision. SSH transports manage their own process groups and wait for remote termination before reporting exit. After the runner closes the host, any further use rejects.

HostConnection

What connect returns.

FieldRequiredDescription
transportyesspawn(argv, { cwd, env }) returns a HostProcess: stdin, stdout, stderr, exited, kill.
fsnoAn async VirtualProvider. The default is ExecProvider over transport.
forwardnoPort forwarding for ForwardSpec values. Without it, host.forward rejects.
syncnoA WorkerConnectSpec that enables the synchronous fs methods.
closeyesCalled by the runner when the host is no longer needed.

The synchronous file system

Remote providers are async. When a connection has sync, a worker thread opens its own connection and the calling thread waits for it, so readFileSync and the rest work.

WorkerConnectSpec fieldDescription
moduleA file: URL the worker imports.
exportNameAn exported function that takes args and resolves with a SyncConnection.
argsPlain data that can be copied to the worker. It is not shared with the main thread.

A SyncConnection has an fs provider and an optional close(). Without sync, the synchronous methods throw ENOTSUP. File descriptors (openSync) are never available on remote hosts.

The first synchronous call starts the worker, which connects before it answers. Later calls cost one round trip. The bridge works on Bun. A call that gets no answer within 30 seconds fails with ETIMEDOUT.

wrapHost(base, wrap)

A host that runs every process of base through wrap, for example under an OS sandbox. wrap receives the argv with the working directory and environment and returns the new argv and environment. fs, info and forward are the base host's, and closing is still the base host's plug's job.

ExecProvider

A file system provider for any host that can run POSIX tools. Every operation is a small command over transport.spawn. It supports the async API only, and needs uname, stat, ls, mkdir, rmdir, rm, mv, cp, cat, test, ln, readlink and realpath on the machine.

SSH

ExportDescription
sshConnect(stream, auth)SSH over any byte stream, with keepalives. auth has username, privateKey and an optional hostKey fingerprint.
SshConnectiontransport, sftp(), forward(spec), and Symbol.asyncDispose to disconnect.
SftpProviderThe provider behind sftp().
generateSessionKey()A new ed25519 key pair in OpenSSH format, for access that lasts one session.

hostKey is the fingerprint in the format ssh-keygen -lf prints (SHA256:…). It is checked before anything else is sent. Omit it only when the stream is already authenticated end to end.

Commands run as one remote shell command line: cd to the working directory, export each environment variable (names must be valid shell names), then exec the command with every word quoted.

Byte streams

ExportDescription
tcpStream(host, port)A TCP connection as a ByteStream. Rejects if it cannot connect.
webSocketStream(url, options)A WebSocket as a ByteStream; binary messages are the bytes. options.headers sets request headers.

A ByteStream is a readable and a writable of Uint8Array chunks.

Testing

@blaiseagent/runner/testing exports startSshServer(), an SSH server on a loopback port for tests. It accepts one generated key, runs exec requests with /bin/sh -c on the local machine, serves SFTP over the local file system, and supports both directions of port forwarding. The result has host, port, hostKey (the fingerprint to pin), clientKey and close().

Tests of the synchronous bridge must run the server in another process, because the calling thread is blocked while it waits.

On this page