@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
138 lines • 7.07 kB
TypeScript
import type { Context } from '../../commands/config.ts';
import type { ByteSource } from '../../io/types.ts';
import type { PathSpec } from '../../types.ts';
import { Runtime } from '../base.ts';
import type { RuntimeOptions } from '../config.ts';
import { LINE_EXECUTOR, PROCESS_EXECUTOR, type LineExecutorMixin, type ProcessExecutorMixin } from '../mixin.ts';
import type { OutputFn, RunResult } from '../types.ts';
import { type NormalizedSandboxConfig, type SandboxConfig } from './config.ts';
/**
* A runtime that executes programs in a sandbox the user runs.
*
* Captures default to unresolved program names. An explicit WHOLE_LINE
* delegates whole shell lines.
*
* Mirage never creates, provisions, or deletes sandboxes: you bring
* your own (a running container, a live Daytona or E2B sandbox) and
* the provider config says how to reach it. The workspace reaches the
* sandbox at the same prefixes as the host's, so the session cwd and
* every path in a line resolve unchanged: a provider with a `mountType`
* serves them itself (SandboxMounts), otherwise serve them inside it
* yourself (`mirage workspace create` in the image entrypoint or by
* hand). There is no interpreter entry point. Subclasses adapt one
* provider by implementing connect() and execArgv(), and PipeTransport
* for a `mountType`; every run derives from execArgv: a whole line runs
* as `/bin/sh -c`, a program from its argv, and a stream hands its
* output over as it comes. Routing and captures are inherited.
* Constructed like every runtime (captures, config); config is
* how to reach the sandbox, coerced against the provider's own key list.
*/
export declare abstract class RemoteSandbox<C extends SandboxConfig = SandboxConfig> extends Runtime<undefined> implements LineExecutorMixin<undefined>, ProcessExecutorMixin<undefined> {
readonly reach = "remote";
readonly [LINE_EXECUTOR]: true;
readonly [PROCESS_EXECUTOR]: true;
config: NormalizedSandboxConfig<C>;
private connecting;
private mounts;
private readonly faketime;
constructor(options?: RuntimeOptions<C>, configKeys?: readonly string[]);
get fileEffectsDispatched(): boolean;
protected servesSession(restrictedMounts: readonly string[]): boolean;
/**
* Run one raw line in the sandbox, connecting once.
*
* The line, cwd, and paths pass through verbatim: the sandbox is
* expected to serve the workspace at the same prefixes as the host,
* so nothing is rewritten. The session environment merges over the
* config environment.
*
* @param _engine none; a sandbox keeps its own connection.
* @param _paths unused; the line names its paths.
* @param _texts unused.
* @param ctx the line in `flags.c`, the bytes piped into it, the session
* environment and working directory, the signal that stops it.
* @param output receives stdout as it arrives.
* @param errors receives stderr as it arrives.
*/
runLine(_engine: undefined, _paths: PathSpec[], _texts: string[], ctx: Context, output?: OutputFn, errors?: OutputFn): Promise<RunResult>;
runProcess(_engine: undefined, _paths: PathSpec[], texts: string[], ctx: Context, output: OutputFn | undefined, errors?: OutputFn): Promise<RunResult>;
settle(): Promise<void>;
/**
* Connect once, bring the served mounts in step, then run.
*
* @param argv the program and its arguments.
* @param ctx the run's stdin, environment, cwd and signal.
* @param output receives stdout as it arrives.
* @param errors receives stderr as it arrives.
*/
private runArgv;
/**
* Stop a run a lapsed workspace left in the box: every process its
* `EXEC_ID` tag marks gets `signum`, then KILL a second later. Connecting
* is bounded as the stop is (`REAP_WAIT_SECONDS`). Answers true once the
* box held the run's processes and they were stopped, false when it holds
* none of them, as a box other than the run's does; throws when the box
* could not be reached or the stop failed.
*
* @param tag the run's `EXEC_ID`, as its process record has it.
* @param signum the first signal.
*/
reap(tag: string, signum: number): Promise<boolean>;
/**
* Stop what a cancelled run left in the box (`EXEC_ID`), for at most
* `REAP_WAIT_SECONDS`: a box that stopped answering would otherwise hold
* the cancel.
*
* @param execId the run's id.
* @param signum the signal the run is stopped with first.
* @returns the stop line's status (`reapLine`); null when the box did not
* answer.
*/
private reapRun;
/** Let the sandbox see the workspace by `mountType`; null serves nothing. */
private serveMounts;
protected disconnected(): void;
/**
* What a program in this sandbox needs to read the running workspace's
* system time (`faketimeEnv`), through the libfaketime the sandbox holds.
* Empty when the workspace keeps the host's time, and when the sandbox has
* no libfaketime, where the program runs on the sandbox's clock. Mirrors
* Python's `SandboxRuntime._system_time_env`.
*/
private systemTimeEnv;
/**
* Which sandbox a run of the current session goes to, which the libfaketime
* probe is kept for: one per runtime unless a provider picks its sandbox
* per session. Mirrors Python's `SandboxRuntime._sandbox_key`.
*/
protected sandboxKey(): string;
protected ensureConnected(signal?: AbortSignal): Promise<void>;
/** Attach to the user's live sandbox, failing loud if absent. */
abstract connect(): Promise<void>;
/**
* Execute one argv inside the sandbox: the provider's transport.
*
* @param argv the program and its arguments.
* @param stdin the input, read as the program consumes it; null for none.
* @param env the merged environment.
* @param cwd the working directory, passed through verbatim.
* @param output receives stdout as it arrives, which the result then
* leaves out; null, or a transport that cannot stream, returns it whole.
* @param errors the same for stderr.
* @param signal stops the program.
*/
protected abstract execArgv(argv: readonly string[], stdin: ByteSource | null, env: Record<string, string>, cwd: string, output: OutputFn | null, errors: OutputFn | null, signal?: AbortSignal): Promise<RunResult>;
/**
* Execute one shell line inside the sandbox, as `/bin/sh -c`.
*
* @param line the raw shell line.
* @param stdin bytes piped into the line.
* @param env the merged environment.
* @param cwd the working directory, passed through verbatim.
* @param signal stops the line.
*/
execLine(line: string, stdin: ByteSource | null, env: Record<string, string>, cwd: string, signal?: AbortSignal): Promise<RunResult>;
/** Unmount what the sandbox was served; the sandbox itself is the user's. */
close(): Promise<void>;
}
//# sourceMappingURL=base.d.ts.map