@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
99 lines • 5.17 kB
TypeScript
import type { Context } from '../commands/config.ts';
import { type Caller } from '../context/session_context.ts';
import type { OpKwargs } from '../view/types.ts';
import type { MountResolver } from './resolver.ts';
import type { BridgeDispatchFn, DispatchFn, RunResult } from './types.ts';
import { Files } from '../workspace/files.ts';
import type { SessionState } from '../workspace/session/session.ts';
/** Local workspace entry points captured for one execution, never guest
* globals. They run as `caller`, the caller the execution was captured
* under (its session, policies, recording and execution), even when a
* guest calls them later from a callback of its own. `ctx` is the same
* `Context` a command or CLI gets: its `vfs` is the session's files over
* the binding's dispatch, so a guest's calls are the program's own. */
export interface RuntimeContext {
readonly caller: Caller;
readonly ctx: Context;
readonly restrictedMounts?: readonly string[];
}
/** Live workspace connection; capture creates views scoped to one execution. */
export declare class WorkspaceBinding {
readonly dispatch: DispatchFn | null;
readonly resolver: MountResolver;
private readonly context?;
readonly files: Files | null;
readonly getSession: ((sessionId: string) => SessionState) | null;
readonly mountPrefixes: (() => string[]) | null;
readonly bridge: BridgeDispatchFn | null;
/**
* @param dispatch a program's own file call, its gate included; null
* over a guest bridge alone (`overBridge`).
* @param resolver the routing table.
* @param context the capture for one execution; `captureBinding` when
* absent.
* @param files the workspace's `ws.vfs`, for an adapter that serves the
* mounts as files (a sandbox's SFTP); null outside a workspace.
* @param getSession its live session by id; null outside a workspace.
* @param mountPrefixes every prefix a sandbox may be told of, whatever
* the session hides; null outside a workspace.
* @param bridge the guest bridge a run with no files rides.
*/
constructor(dispatch: DispatchFn | null, resolver: MountResolver, context?: ((binding: WorkspaceBinding) => RuntimeContext) | undefined, files?: Files | null, getSession?: ((sessionId: string) => SessionState) | null, mountPrefixes?: (() => string[]) | null, bridge?: BridgeDispatchFn | null);
/**
* A binding whose file calls ride a guest bridge (the Pyodide worker's,
* across `postMessage`) rather than a dispatcher.
*
* @param bridge the guest bridge.
* @param resolver the routing table.
* @param context the capture for one execution; `captureBinding` when
* absent.
*/
static overBridge(bridge: BridgeDispatchFn, resolver: MountResolver, context?: (binding: WorkspaceBinding) => RuntimeContext): WorkspaceBinding;
capture(): RuntimeContext;
}
/**
* A run the session's restrictions refuse before it starts, as admission
* refuses a command: bash's `<name>: Permission denied` at 126, the reason
* on the line's refusal record and never on stderr. `name` is the runtime,
* which names the refusal. Mirrors Python's `refused_run`.
*/
export declare function refusedRun(name: string, reason: string): RunResult;
/** Map restrictions to owning mounts, not ancestors whose trees contain another mount. */
export declare function restrictedMountsFor(session: SessionState, prefixes: readonly string[]): string[];
/**
* Pin callback attribution without copying authoritative workspace state.
*
* @param binding the workspace connection.
* @param views the session's context, its restricted mounts, and the
* dispatch bound to that session (the binding's own when absent).
* @param caller who the entry points run as.
*/
export declare function captureBinding(binding: WorkspaceBinding, views?: {
ctx?: Partial<Context>;
restrictedMounts?: readonly string[];
dispatch?: DispatchFn;
}, caller?: Caller): RuntimeContext;
/** Ask every routing question as the captured caller, whose session
* decides which mounts it is told of. */
export declare class CallerResolver implements MountResolver {
private readonly resolver;
private readonly caller;
/**
* @param resolver the routing table asked.
* @param caller who each question is asked as.
*/
constructor(resolver: MountResolver, caller: Caller);
prefixes(): string[];
ownerOf(path: string): string | null;
linkChildren(directory: string): Set<string>;
}
/**
* The bridge a runtime's file I/O rides, over a dispatch shaped like
* `Workspace.dispatch` (name, string path, positional args, kwargs): the
* run's files for a guest (`RuntimeFiles.of`), `ws.vfs.dispatch` for
* node's patched `fs`. A read is the rendered one unless its `raw` attr asks for the
* stored bytes, and its `offset`/`size` attrs ask for a byte range,
* matching Python's `RuntimeFiles.read`.
*/
export declare function workspaceBridge(dispatch: (name: string, path: string, args?: readonly unknown[], kwargs?: OpKwargs) => Promise<unknown>): BridgeDispatchFn;
//# sourceMappingURL=binding.d.ts.map