import type { FeatureIdentity, PostboxOwnerListScope, PostboxOwnerSummary, PresenceState, SemanticState, SessionRegisterPayload, SessionUpdatePayload, StateSnapshot } from "../protocol.js"; import type { SqliteDatabase } from "../db/database.js"; export interface PresenceOptions { staleAfterMs: number; offlineAfterMs: number; } export interface PostboxOwnerListOptions { scope?: PostboxOwnerListScope; includeInactive?: boolean; cursor?: string; pageSize?: number; } export interface PostboxOwnerListPage { owners: PostboxOwnerSummary[]; nextCursor?: string; } export interface SessionStoreOptions extends PresenceOptions { /** Offline sessions older than this are omitted from state snapshots. */ hideOfflineAfterMs?: number; /** Offline sessions older than this are deleted, unless ask requests still reference them. */ retentionMs?: number; } export interface PostboxOwnerStatus { owner: { harness: string; ownerId: string; }; presence: PresenceState; semanticState: SemanticState; lastHeartbeatAt: string | undefined; activeQuestionCount: number; unreadAnswerCount: number; } export declare class SessionStore { private readonly db; private readonly now; private readonly presenceOptions; private readonly activeConnections; private readonly hideOfflineAfterMs; private readonly retentionMs; private closed; constructor(db: SqliteDatabase, now: () => number, presenceOptions: SessionStoreOptions); close(): void; ownerForSession(sessionId: string): { harness: string; ownerId: string; } | undefined; semanticStateForSession(sessionId: string): SemanticState | undefined; presenceForOwner(owner: { harness: string; ownerId: string; }): "live" | "stale" | "offline"; hasOfflineLease(owner: { harness: string; ownerId: string; }): boolean; listPostboxOwners(sessionId: string, scope?: PostboxOwnerListScope): PostboxOwnerSummary[]; listPostboxOwnersPage(sessionId: string, options?: PostboxOwnerListOptions): PostboxOwnerListPage; getPostboxOwnerStatus(owners: ReadonlyArray<{ harness: string; ownerId: string; }>): PostboxOwnerStatus[]; isConnectedNonWaitingOwner(sessionId: string, owner: { harness: string; ownerId: string; }): boolean; isCurrentConnection(sessionId: string, connectionId: string): boolean; groupingForSession(sessionId: string): { repositoryId: string; worktreeId: string; featureId: string; } | undefined; selectFeature(sessionId: string, action: { action: "start"; name: string; } | { action: "select" | "inherit"; featureId: string; }): FeatureIdentity; register(connectionId: string, payload: SessionRegisterPayload): FeatureIdentity | undefined; heartbeat(connectionId: string, sessionId: string, semanticState?: SemanticState): void; updateSession(payload: SessionUpdatePayload): void; disconnectConnection(connectionId: string): void; renameMachine(machineId: string, displayName: string): void; renameProject(projectId: string, displayName: string): void; shutdown(sessionId: string): void; questionChatCwd(sessionId: string): string | undefined; snapshot(): StateSnapshot; /** Deletes only offline sessions which have never sourced a durable Question. */ pruneOfflineSessions(): number; private toSnapshot; private offlineSinceMs; private derivePresence; private presenceRank; } export declare class SessionStoreError extends Error { readonly code: string; constructor(code: string, message: string); } //# sourceMappingURL=sessionStore.d.ts.map