/** * SQLite-backed session store operations. * * CRUD operations for sessions and task work tracking backed by tasks.db. * * @epic T4454 * @task W1-T4 * @task T1609 insertHandoffEntry — write-once INSERT path for handoff data */ import type { Session } from '@cleocode/contracts'; /** Create a new session. */ export declare function createSession(session: Session, cwd?: string): Promise; /** Get a session by ID. */ export declare function getSession(sessionId: string, cwd?: string): Promise; /** Update a session. */ export declare function updateSession(sessionId: string, updates: Partial, cwd?: string): Promise; /** * Insert a handoff entry for a session (write-once, append-only). * * The underlying `session_handoff_entries` table enforces: * - UNIQUE on `session_id` — only one handoff per session. * - BEFORE UPDATE trigger — rows are immutable after insertion. * - AFTER INSERT trigger — mirrors value to `sessions.handoff_json` * so existing read paths continue to work without change. * * Throws a SQLite `SQLITE_CONSTRAINT_UNIQUE` error (message contains * "UNIQUE constraint failed") if a handoff already exists for this session. * Callers should catch and surface as `E_HANDOFF_ALREADY_PERSISTED`. * * @param sessionId - The session that is being handed off. * @param handoffJson - Serialised HandoffData or DebriefData JSON string. * @param cwd - Optional working directory (resolves tasks.db location). * @task T1609 */ export declare function insertHandoffEntry(sessionId: string, handoffJson: string, cwd?: string): Promise; /** List sessions with optional filters. */ export declare function listSessions(filters?: { active?: boolean; limit?: number; }, cwd?: string): Promise; /** End a session. */ export declare function endSession(sessionId: string, note?: string, cwd?: string): Promise; /** Start working on a task within a session. */ export declare function startTask(sessionId: string, taskId: string, cwd?: string): Promise; /** Get current task for a session. */ export declare function getCurrentTask(sessionId: string, cwd?: string): Promise<{ taskId: string | null; since: string | null; }>; /** Stop working on the current task for a session. */ export declare function stopTask(sessionId: string, cwd?: string): Promise; /** Get work history for a session. */ export declare function workHistory(sessionId: string, limit?: number, cwd?: string): Promise>; /** Garbage collect old sessions (mark ended sessions as orphaned after threshold). */ export declare function gcSessions(maxAgeDays?: number, cwd?: string): Promise; /** * Get the currently active session — the most-recent `status='active'` row. * * @internal LEGACY single-process TTY fallback ONLY (T11640 · Epic T11638). * * This resolves "whoever wrote an active session to the DB most recently", * which is the WRONG identity in any multi-tenant context: under the warm * daemon (many concurrent connections) and under multi-agent spawn isolation * (many worktrees writing the same DB) it collapses every caller's identity * onto the last writer, causing session-bleed and memory scope-leakage. * * Identity-meaning callers — anything that means "the session of whoever is * calling THIS request" — MUST use {@link resolveCurrentSession} / * {@link resolveCurrentSessionId}, which resolve, in order: * 1. the daemon connection handle ({@link getCurrentConnectionSessionId}), * 2. the env-named session (`CLEO_SESSION_ID`, via * {@link resolveSessionIdFromEnv}), * 3. and only THEN fall back to this most-recent-active row. * * `getActiveSession` survives as that final tier-3 fallback and for genuine * SCAN-meaning callers (e.g. "is there any active session at all?", * `gcSessions`, the data-accessor pass-throughs). The * `lint-no-bare-get-active-session.mjs` gate bans NEW bare callsites so the * identity-vs-scan split cannot silently regress — annotate a justified scan * callsite with a trailing `// get-active-session-allowed: `. * * @param cwd - Working directory for DB resolution. * @returns The most-recent active session, or `null`. */ export declare function getActiveSession(cwd?: string): Promise; /** * Resolve the CALLER's current session (T11344/T11640 · Epics T11284, T11638). * * THE canonical identity-resolution helper. Replaces bare {@link getActiveSession} * for any consumer that means "the session of whoever is calling THIS request". * Resolution precedence (first hit wins): * * 1. **Daemon connection handle** ({@link getCurrentConnectionSessionId}) — when * dispatching a request frame on a warm-daemon connection, the connection's * accept-time-bound session is authoritative. A row with that id is honoured * when present; when the bound id has no row yet, resolution proceeds (the * connection asserted an identity that the env/active tiers may still * satisfy). This is the seam that gives the multi-connection daemon a stable * per-connection identity (T11640). * 2. **Env-named session** — `resolveSessionIdFromEnv()` (`CLEO_SESSION_ID` * injected by spawn isolation, T11343); the spawned agent's OWN session. * 3. **Most-recent active row** — {@link getActiveSession}, the legacy * single-process fallback. * * Making most-recent-active the FALLBACK rather than the default identity is * what dissolves multi-agent session-bleed AND memory scope-leakage: a * short-lived `cleo` call in agent A's worktree no longer resolves agent B's * session just because B wrote to the DB more recently. * * The connection-handle and env-named sessions are honoured even when their * status is not `active` (the caller explicitly asserted that id), so callers * that need an active-only guarantee should check `.status` on the result. * * @param cwd - Working directory for DB resolution. * @returns The resolved session, or `null` when none can be resolved. * @task T11344 * @task T11640 */ export declare function resolveCurrentSession(cwd?: string): Promise; /** * Resolve the CALLER's current session id (T11344/T11640). * * Thin id-only convenience over {@link resolveCurrentSession} sharing its * connection-handle → env → most-recent-active precedence. Prefer this over * `(await getActiveSession())?.id` in identity-resolution hot paths. * * @param cwd - Working directory for DB resolution. * @returns The resolved session id, or `null`. * @task T11344 * @task T11640 */ export declare function resolveCurrentSessionId(cwd?: string): Promise; //# sourceMappingURL=session-store.d.ts.map