/**
 * ThreadResumeMap — persistent mapping from thread IDs to Claude/Codex session
 * UUIDs, for `--resume`.
 *
 * Phase 2a (THREADLINE-SINGLE-STORE-SPEC.md / CMT-497): this is now a **view over
 * `ConversationStore`** — the single source of truth. Every method maps the legacy
 * `ThreadResumeEntry` shape onto a `Conversation` record via the field bridge
 * below. `save` MERGES (it never clobbers the loop gate's `turnCount`/
 * `lastInboundHash`/`lastOutboundHash`). The on-disk `thread-resume-map.json` is no
 * longer written; a one-release dual-read window falls back to it on a miss and
 * writes through, so threads written by a pre-2a version are not lost.
 *
 * Field bridge (ThreadResumeEntry ↔ Conversation):
 *   uuid↔sessionUuid · sessionName↔boundSessionName · lastAccessedAt↔lastActivityAt
 *   originTopicId↔boundTopicId · originSessionName↔originSessionName · the rest 1:1.
 */
import { ConversationStore, type ConversationState } from './ConversationStore.js';
/** Thread lifecycle state (legacy subset of ConversationState). */
export type ThreadState = 'active' | 'idle' | 'resolved' | 'failed' | 'archived';
/** A single thread resume mapping entry. */
export interface ThreadResumeEntry {
    uuid: string;
    sessionName: string;
    createdAt: string;
    savedAt: string;
    lastAccessedAt: string;
    remoteAgent: string;
    subject: string;
    state: ThreadState;
    resolvedAt?: string;
    pinned: boolean;
    messageCount: number;
    machineOrigin?: string;
    migratedTo?: string;
    spawnMode?: 'interactive' | 'pipe';
    originTopicId?: number;
    originSessionName?: string;
}
export interface ThreadResumeSessionMatch {
    threadId: string;
    entry: ThreadResumeEntry;
    conversationState: ConversationState;
}
export declare class ThreadResumeMap {
    private store;
    private legacyPath;
    private projectDir;
    private tmuxPath;
    constructor(stateDir: string, projectDir: string, tmuxPath?: string, store?: ConversationStore);
    /**
     * Look up a thread resume entry. Returns null if not found, expired, or the
     * session JSONL no longer exists. Dual-read: on a ConversationStore miss, fall
     * back to the legacy file and write through (one-release transition window).
     */
    get(threadId: string): ThreadResumeEntry | null;
    /** Save or update a thread resume mapping (MERGES — preserves gate turn state). */
    save(threadId: string, entry: ThreadResumeEntry): void;
    /** Remove a thread entry (cross-process safe via ConversationStore). */
    remove(threadId: string): void;
    /** Mark a thread resolved (grace period before removal). */
    resolve(threadId: string): void;
    /** Pin — never evicted. */
    pin(threadId: string): void;
    /** Unpin — allow normal TTL/LRU eviction. */
    unpin(threadId: string): void;
    /** Find all (non-expired) threads with a specific remote agent. */
    getByRemoteAgent(agentName: string): Array<{
        threadId: string;
        entry: ThreadResumeEntry;
    }>;
    /** List all active or idle threads. */
    listActive(): Array<{
        threadId: string;
        entry: ThreadResumeEntry;
    }>;
    /** Reverse lookup live conversation entries by their bound tmux session name. */
    getBySessionName(sessionName: string): ThreadResumeSessionMatch[];
    /** Reverse lookup live conversation entries by their bound SessionManager UUID. */
    getBySessionUuid(uuid: string): ThreadResumeSessionMatch[];
    /** Archive stale non-pinned active/idle/open conversations. */
    retireInactive(maxInactiveMs?: number, now?: Date): number;
    /** Cross-machine failover: demote a source machine's active threads to idle. */
    migrateFrom(sourceMachine: string, targetMachine: string): {
        migrated: number;
        skipped: number;
    };
    /** Get entries migrated to this machine (for resume capability). */
    getMigratedEntries(targetMachine: string): Array<{
        threadId: string;
        entry: ThreadResumeEntry;
    }>;
    /** Total stored entries (for monitoring). */
    size(): number;
    /** Prune expired / resolved-past-grace / LRU overflow. */
    prune(): void;
    /**
     * Proactive resume heartbeat: scan active thread-linked tmux sessions and
     * update the thread→UUID mapping so a crash leaves the UUID on file.
     */
    refreshResumeMappings(threadSessions: Map<string, string>): void;
    /** Dual-read: read a single entry from the frozen legacy file, if present + fresh. */
    private readLegacyEntry;
    private isExpired;
    /**
     * True if a tmux session by this EXACT name currently exists. Used by get() to
     * keep a resume entry alive for the live-inject path even when its transcript
     * JSONL doesn't exist yet (placeholder uuid). `=name` forces an exact tmux match
     * (no prefix/fnmatch) — the same idiom as the resume heartbeat and cli.ts.
     * Protected so unit tests can stub liveness deterministically via a subclass.
     */
    protected sessionAlive(sessionName: string): boolean;
    /** Check if a JSONL file exists for the given session UUID. (protected so
     *  tests can bypass the filesystem check via a subclass.) */
    protected jsonlExists(uuid: string): boolean;
}
//# sourceMappingURL=ThreadResumeMap.d.ts.map