@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
101 lines • 4.96 kB
TypeScript
import type { IOResult } from '../io/types.ts';
import type { JsonObject } from '../types.ts';
import { type Clock } from '../utils/clock.ts';
import type { OpRecord } from './record.ts';
import { type ObserverStore } from './store.ts';
/**
* Opt in by assigning a debug sink, as Python's module logger is off until
* configured: history is read after every command, and a torn line stays in
* the file, so a sink that always wrote would repeat it on every read.
*/
export declare const logger: {
debug?: (message: string) => void;
};
/**
* Persists LogEntry records to an ObserverStore as JSONL files.
*
* The hidden recorder: it owns no mount and its store is reachable only
* through this class, so the log is invisible to agents. Views
* (/.bash_history, the history builtin) render from the query methods
* below; swapping infra (RAM, disk, opfs) means passing a different
* store, nothing above this seam changes.
*
* Every entry is stamped, and filed under its day, on `clock`: the
* workspace's, which also stamps the op records the entries carry, so a
* workspace on a manual clock keeps one time domain in its history. No
* entry is stamped before the newest one its session holds: a clock that
* restarts behind stored history (a fresh `ManualClock` over a restored or
* persisted log) would otherwise file a clear or delete ahead of the
* commands it acts on. A session with no history sets no floor.
*
* Each line that ends also goes to OpenTelemetry as a span, its vfs calls
* as spans under it; nothing leaves the process until an SDK is set up.
*/
export declare class Observer {
private readonly workspaceId?;
private readonly _store;
private readonly clock;
private readonly newest;
private readonly started;
constructor(store?: ObserverStore, clock?: Clock, workspaceId?: string | undefined);
/** The clock's wall time in epoch milliseconds, an entry's stamp. */
private nowMs;
get store(): ObserverStore;
/**
* The newest stamp `session` holds, null when it holds none. Read once per
* session, from that session's files only (the files its history view
* reads); an entry stamped while they are read is newer still and is kept.
*/
private floor;
private log;
logOp(rec: OpRecord, session: string, cwd?: string, parent?: string): Promise<void>;
/**
* Record a typed line as it starts, under its id `line`, which its vfs
* calls and its result name as their parent.
*/
logCommand(command: string, session: string, cwd?: string, line?: string): Promise<void>;
/**
* Record how a typed line ended: its vfs calls, then its result, each
* naming the line as its parent. A line ends once: a second call for a
* line already ended records nothing.
*/
logResult(io: IOResult, opRecords: OpRecord[], session: string, cwd?: string, line?: string): Promise<void>;
/** Append a command entry without an execution (history -s). */
logCommandText(command: string, session: string, cwd?: string): Promise<void>;
/** Append a clear tombstone for a session (history -c). */
logClear(session: string): Promise<void>;
/** Append a delete event for one listing entry (history -d). */
logDelete(session: string, offset: number): Promise<void>;
/**
* All recorded events, in timestamp order: every session's, or only
* `session`'s, read from its own log alone. Stable over the per-file
* line order, so events that share a millisecond (one line's ops plus
* its command entry) keep append order.
*/
events(session?: string): Promise<JsonObject[]>;
/**
* The command events of every session's ended lines, in the order they
* ended: a line enters its history once its result is in, and an entry
* added without running (`history -s`) at once, so the listing only ever
* grows at its end.
*/
commandEvents(): Promise<JsonObject[]>;
/**
* One session's visible history listing, append order. Projects the
* session's events: a line joins the listing when its result is in (an
* entry added without running, `history -s`, at once), a clear
* tombstone empties it, and delete events apply at the position they
* were issued (history -d renumbers subsequent entries, GNU behavior).
*/
sessionCommandEvents(session: string): Promise<JsonObject[]>;
/**
* Rewind the recorder to a snapshot's events. Clears the store first,
* mirroring `ws.cache.clear()` on the checkout path: restoring means
* becoming the snapshot, so events from the pre-restore timeline do
* not survive. Foreign-format entries (e.g. the Python snapshot's
* different history shape) without a recognized `type` are skipped:
* the views filter by `type` so they are unusable here anyway.
*/
loadEvents(events: JsonObject[]): Promise<void>;
}
//# sourceMappingURL=observer.d.ts.map