/** * Activation Store * * Persists per-session element activation state to disk. * Each MCP session (identified by DOLLHOUSE_SESSION_ID) gets its own * activation file so concurrent sessions maintain independent profiles. * * Follows the DangerZoneEnforcer pattern: * - DI-managed singleton with FileOperationsService * - initialize() loads from disk (tolerates missing/corrupt files) * - In-memory state is the hot path; disk writes are fire-and-forget * - atomicWriteFile (write-to-temp + rename) prevents partial reads * * Forward compatibility: The versioned file format (v1) can evolve to * include userId, orgId, and audit fields for multi-user HTTPS mode * without breaking existing installations. * * @since v2.0.0 - Issue #598 */ import type { FileOperationsService } from './FileOperationsService.js'; /** * A persisted activation record for a single element. */ export interface PersistedActivation { /** Element name (human-readable, used for all types) */ name: string; /** For personas only: the filename key used by PersonaManager */ filename?: string; /** ISO-8601 timestamp of when activation was persisted */ activatedAt: string; } export interface PersistedActivationStateSnapshot { sessionId: string; lastUpdated: string; activations: Record; } /** * Per-session activation state persistence. * * Persists element activation state to `~/.dollhouse/state/activations-{sessionId}.json`. * Each MCP session is identified by the `DOLLHOUSE_SESSION_ID` environment variable. * * Thread-safety note: Node.js is single-threaded, so Map operations are safe. * For multi-process deployments (future HTTPS), consider Redis or DB backing. * * @example * ```ts * // Session ID set via environment: * // DOLLHOUSE_SESSION_ID=claude-code * * const store = new ActivationStore(fileOps); * await store.initialize(); // loads ~/.dollhouse/state/activations-claude-code.json * * store.recordActivation('skill', 'code-reviewer'); * store.recordActivation('persona', 'Creative Dev', 'creative-dev.md'); * * // On next server start, initialize() restores these activations * ``` */ export declare class ActivationStore { private readonly fileOps; private readonly stateDir; private readonly sessionId; private readonly runtimeSessionId; private readonly persistPath; private readonly enabled; private state; constructor(fileOps: FileOperationsService, stateDir?: string); /** * Load persisted activations from disk. * Call once after construction to restore state from a previous session. * If the file is missing or corrupt, starts with empty activations. */ initialize(): Promise; /** * Record an element activation. Fire-and-forget persist. */ recordActivation(elementType: string, name: string, filename?: string): void; /** * Record an element deactivation. Fire-and-forget persist. */ recordDeactivation(elementType: string, name: string): void; /** * Remove a specific activation by name (used during restore to prune stale entries). */ removeStaleActivation(elementType: string, name: string): void; /** * Get all persisted activations for a given element type. */ getActivations(elementType: string): PersistedActivation[]; /** * Read persisted activation snapshots from disk for reporting/diagnostics. * * This intentionally does not mutate the store's in-memory state, and it is * safe to call from the web console to inspect other sessions' persisted * activations without changing live policy enforcement for the current * process. */ listPersistedActivationStates(sessionId?: string): Promise; private getPersistedActivationFilenames; private readPersistedActivationState; private isPersistedActivationState; private normalizePersistedActivations; private normalizePersistedActivation; private logSnapshotReadError; /** * Get the session ID this store is scoped to. */ getSessionId(): string; /** * Runtime-unique session identifier used for live console/session registry * surfaces when the stable persistence identity is shared across unnamed * sessions. */ getRuntimeSessionId(): string; /** * Check if persistence is enabled. */ isEnabled(): boolean; /** * Clear all persisted activations. Used for testing or admin reset. */ clearAll(): void; /** * Fire-and-forget persistence with retry for transient disk failures. * Retries up to PERSIST_MAX_RETRIES times with a short delay. * Disk failure does not block activation operations. */ private persistAsync; /** * Attempt to persist with retries for transient failures (e.g., EBUSY, EAGAIN). */ private persistWithRetry; /** * Write current activation state to disk. */ private persist; private createEmptyState; private getTotalActivationCount; private getActivationCounts; private logResolvedSessionIdentity; } //# sourceMappingURL=ActivationStore.d.ts.map