UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

161 lines • 7.59 kB
import { SessionOwner } from '../../context/session_context.ts'; import { SessionState } from './session.ts'; import type { CompiledProfile } from '../../policy/profile.ts'; import type { NamespaceStore } from '../mount/namespace/store.ts'; import type { AdmissionRules, Decision, ProfileScripts } from '../../policy/types.ts'; import type { EnvEntries } from '../../secrets/config.ts'; import type { ShellVar } from '../../shell/variable.ts'; import type { MountMode } from '../../types.ts'; import { type Clock } from '../../utils/clock.ts'; import { type IdSource } from '../../utils/ids.ts'; /** * Owns the live session table over a storage-agnostic NamespaceStore. * * The same store type the Namespace keeps its nodes in, one table each per * workspace: sessions are worked on in memory (creation stays synchronous), * the store hydrates once at the first async entry point, and durable fields * flush back at async boundaries (end of execute, snapshot, explicit * persist). `close` * deletes from the store — closing a session revokes it everywhere — * while process shutdown leaves stored sessions in place. */ export declare class SessionManager extends SessionOwner { private readonly sessions; private readonly persistLock; private readonly sessionStore; private defaultIdInternal; private loaded; private loadPromise; private readonly persisted; private defaultProfileInternal; private seedVarsInternal; private hasManaged; private readonly clock; private readonly ids; /** * @param clock the workspace clock a session's `createdAt` is read on; * omitted means the system clock. * @param ids the workspace's id source, which each session's `$RANDOM` * first draws from; omitted means the system source. */ constructor(defaultSessionId: string, store?: NamespaceStore, seedVars?: Record<string, ShellVar>, clock?: Clock, ids?: IdSource); /** * True once any session may hold a managed variable. * * The fill step is skipped entirely while this is false, so it is * sticky-true: set by the workspace's env block, a created session's * own entries, a hydrated record, or a snapshot, and never cleared (a * detached name costs nothing extra -- the fill pass finds nothing to * fetch and returns). */ get hasManagedEnv(): boolean; /** The env template a created session starts from, copied. */ get seedVars(): Record<string, ShellVar>; /** * Install the env template a snapshot or copy carried over. * * The template is constructor state, so `fromState` rebuilds a * workspace without it; existing sessions recover their own vars, * but a session created afterward would start bare while its older * siblings still carry every workspace env entry. Sticky on * `hasManagedEnv`, like every other writer of it. */ restoreSeed(seedVars: Record<string, ShellVar>): void; /** The document's default profile, as compiled for this workspace. */ get defaultProfile(): CompiledProfile | null; /** * Shape the default session by the document's default profile. The * workspace's own session is a session created without a name, so * `profiles.default` reaches it the way it reaches `createSession(id)`: * applied in full now (modes, hides, exported env, cwd), and its * narrowing stamped again after hydration, where a record from before * the profile existed would otherwise wake the primary agent * unrestricted. null (no default profile) leaves the session, and * hydration, as they were. */ set defaultProfile(compiled: CompiledProfile | null); /** Replace an existing, hydrated session's restrictions, preserving its scratch state. */ setProfile(sessionId: string, compiled: CompiledProfile): Promise<SessionState>; /** * The admission rules one session runs under (SessionCommandsQuery). * The default profile's rules for an id this manager does not know, the * empty id of an unbound entry point included, so an entry point that names no * session still fails toward refusal. */ commandsOf(sessionId: string): AdmissionRules | null; /** * The policy programs of the profile one session runs under, by * method (SessionScriptsQuery). * The default profile's for an id this manager does not know, the * same fallback `commandsOf` makes and for the same reason: an entry point * that names no session is judged like a session that named no * profile. */ scriptsOf(sessionId: string): ProfileScripts; /** * The ledger records one session holds (SessionDecisionsQuery). Read off the * registered session, never a fork, so a line running in a background * copy sees the same answers. */ decisionsOf(sessionId: string): readonly Decision[]; /** Every session id holding ledger records (SessionDecisionsQuery). */ decisionSessions(): readonly string[]; /** Replace one session's ledger records (SessionDecisionsQuery); durable at the next flush. */ setDecisions(sessionId: string, records: readonly Decision[]): void; get store(): NamespaceStore; get defaultId(): string; /** * Re-key the default session to an externally decided id. * * Two callers: attach (the discovery record already names a default * session, so the freshly minted placeholder re-keys before hydration * lands the stored durable fields on it) and snapshot restore (the * snapshot's default identity wins). The store itself is untouched; * the next flush or snapshot replace writes the new key. */ adoptDefault(sessionId: string): void; get cwd(): string; set cwd(value: string); get env(): Record<string, string>; set env(value: Record<string, string>); /** * Hydrate sessions from the store once. * * Stored sessions fill in ids this process has not created; locally * created sessions win a conflict (they overwrite the store on the * next flush). The default session adopts the stored durable fields * so a restarted daemon keeps its cwd/env. */ ensureLoaded(): Promise<void>; private hydrate; /** Persist one session, or all sessions at a workspace boundary. */ flush(sessionId?: string): Promise<void>; /** Wait for admitted session writes before their store closes. */ settle(): Promise<void>; /** Persist one session, retrying when another writer races us. */ private flushOne; /** * Adopt a snapshot's session table and replace the store. The * snapshot wins over prior store contents, mirroring * `Namespace.replaceNodes`. */ replaceFromSnapshot(sessions: readonly SessionState[]): Promise<void>; /** * Create a session, seeded with the workspace's env template. * `options.env` is this session's own env entries, literal or * managed, merged over the template (session entries win), and * `options.profile` the profile it is created under, applied here so * a pointer its env names counts toward `hasManagedEnv`. */ create(sessionId: string, options?: { mountModes?: ReadonlyMap<string, MountMode> | null; env?: EnvEntries; profile?: CompiledProfile; }): SessionState; get(sessionId: string): SessionState; has(sessionId: string): boolean; list(): SessionState[]; close(sessionId: string): Promise<void>; private defaultSession; } //# sourceMappingURL=manager.d.ts.map