import { Session } from './session.ts'; import type { CompiledProfile } from '../../policy/profile.ts'; import { type SessionStore } from './store.ts'; import type { AdmissionRules, Decision, HideReason, ProfileScript } from '../../policy/types.ts'; import type { EnvEntries } from '../../secrets/config.ts'; import type { ShellVar } from '../../shell/variable.ts'; import type { MountMode } from '../../types.ts'; /** * Owns the live session table over a storage-agnostic SessionStore. * * Mirrors the Namespace/NamespaceStore split: 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 { private readonly sessions; private readonly sessionStore; private defaultIdInternal; private loaded; private loadPromise; private readonly persisted; private defaultProfileInternal; private seedVarsInternal; private hasManaged; constructor(defaultSessionId: string, store?: SessionStore, seedVars?: Record); /** * 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; /** * 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): 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); /** * 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 door included, so a door that names no * session still fails toward refusal. */ commandsOf(sessionId: string): AdmissionRules | null; /** * The profile script one session runs under (SessionScriptsQuery). * The default profile's for an id this manager does not know, the * same fallback `commandsOf` makes and for the same reason: a door * that names no session is judged like a session that named no * profile. */ scriptOf(sessionId: string): ProfileScript | null; /** * The operator's hide reasons for one session's profile. The default * profile's for an id this manager does not know, the same fallback * `commandsOf` makes and for the same reason. Host-side only: * nothing on the command surface renders these, because a reason on * a nonexistent path would confirm the path exists. */ hideReasonsOf(sessionId: string): readonly HideReason[]; /** * 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(): SessionStore; 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; set env(value: Record); /** * 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; private hydrate; /** Write dirty sessions through the store's generation gate. */ flush(): Promise; /** 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 Session[]): Promise; /** * 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). */ create(sessionId: string, options?: { mountModes?: ReadonlyMap | null; env?: EnvEntries; }): Session; get(sessionId: string): Session; list(): Session[]; close(sessionId: string): Promise; closeAll(): Promise; closeStore(): Promise; private defaultSession; } //# sourceMappingURL=manager.d.ts.map