Connectors
Connectors abstract how commands reach a target system. Every connector implements connect(), isReady(), spawn(), and [Symbol.asyncDispose]().
Connector Interface
Section titled “Connector Interface”interface Connector extends AsyncDisposable { readonly host: string; readonly name: string; readonly vars: Record<string | symbol, any> | undefined; readonly rsh: string[]; // command prefix for remote execution connect(signal?: AbortSignal): Promise<void>; isReady(signal?: AbortSignal): Promise<boolean>; // side-effect-free probe for waitForReady() spawn(cmd: string[], signal?: AbortSignal): Promise<Process>; [Symbol.asyncDispose](): Promise<void>;}The Process object returned by spawn() provides Web Streams for its input and output:
interface Process { stdin: WritableStream; stdout: ReadableStream; stderr: ReadableStream; exited: Promise<number>; kill(code?: number): void;}LocalConnector
Section titled “LocalConnector”Runs commands directly on the local host.
import { start, apply } from 'sysopkit';import { LocalConnector } from 'sysopkit/connector/local';
await start(async () => { await using c = new LocalConnector();
await apply('example', c, async () => { await sh('echo hello'); });});SSHConnector
Section titled “SSHConnector”Connects to remote hosts via native OpenSSH with ControlMaster multiplexing for connection reuse. Supports password and key authentication.
import { SSHConnector } from 'sysopkit/connector/ssh';
await using c = new SSHConnector({ host: '192.168.1.1', user: 'sysop', key: '/path/to/id_rsa', strictHostKeyChecking: false,});The SSH connector builds a ControlMaster socket for multiplexing, validates the connection on connect(), and cleans up the control socket on dispose.
Rotating host keys (reinstall flows)
Section titled “Rotating host keys (reinstall flows)”disableStrictHostKeyChecking() permanently stops verifying host keys on subsequently established connections — same flag set as constructing with strictHostKeyChecking: false (StrictHostKeyChecking=no + UserKnownHostsFile=/dev/null). One-way: no re-enable on the same instance; re-pinning is a new connector’s job. A live multiplex master is untouched until it dies. Log the downgrade via the current context (ctx.warn(...)) so op logs show exactly when verification stopped.
import { SSHConnector } from 'sysopkit/connector/ssh';
await using c = new SSHConnector({ host: '192.168.1.1', user: 'sysop' });// strict phase...c.disableStrictHostKeyChecking();// lax phase: survives key rotation across rebootsUpdating current connector options
Section titled “Updating current connector options”updateConnectorOptions(fn) unwraps any middleware chain and invokes fn with the base connector, so callers narrow with instanceof. Only operates on the ambient context’s connector; for single-connector flows (not parallel apply() batches).
import { updateConnectorOptions } from 'sysopkit';import { SSHConnector } from 'sysopkit/connector/ssh';
updateConnectorOptions((conn) => { if (conn instanceof SSHConnector) { conn.disableStrictHostKeyChecking(); } else { throw new Error(`refusing: unsupported connector '${conn.name}'`); }});Waiting for readiness
Section titled “Waiting for readiness”waitForReady(conn) polls the side-effect-free isReady() probe until the target accepts connections — useful for boot/wait flows. It takes a live connector instance:
import { waitForReady } from 'sysopkit';import { SSHConnector } from 'sysopkit/connector/ssh';
await waitForReady(new SSHConnector({ host: '192.168.1.1' }));// opts: { timeoutMs = 5*60_000, intervalMs = 5_000, signal }PodmanConnector
Section titled “PodmanConnector”Executes commands inside running Podman containers via podman exec.
import { PodmanConnector } from 'sysopkit/connector/podman';
await using c = new PodmanConnector({ host: 'my-app' });await c.connect(); // validates container is runningHost Prefixes in Inventory
Section titled “Host Prefixes in Inventory”When using resolveInventory(), host strings with prefixes automatically select the right connector:
ssh:hostname— SSH connector (default)pod:container— Podman connector
Factories for other transports can be registered under custom prefixes.