/**
 * ListenerSessionManager — Manages a warm Claude Code session for handling
 * incoming Threadline messages via an authenticated JSONL inbox file.
 *
 * Part of SPEC-threadline-responsive-messaging Phase 2.
 *
 * Architecture:
 * - Server writes HMAC-signed entries to an append-only JSONL inbox file
 * - Listener session polls the inbox file and processes new entries
 * - Ack file tracks processed entries (skip-list pattern for crash recovery)
 * - Rotation creates fresh files when context window fills
 * - Parking releases the session slot when idle
 */
export interface ListenerConfig {
    /** Whether the listener session is enabled */
    enabled: boolean;
    /** Max messages before rotation (default: 20) */
    maxMessages: number;
    /** Max age before rotation (default: '4h') */
    maxAge: string;
    /** Idle time before parking (default: '30m') */
    parkAfterIdle: string;
    /** Queue depth that triggers cold-spawn overflow (default: 10) */
    overflowThreshold: number;
    /** Inbox poll interval in ms (default: 500) */
    pollInterval: number;
    /** Char length threshold for routing to cold-spawn (default: 2000) */
    complexTaskThreshold: number;
    /** Minimum trust level for warm-session injection (default: 'trusted') */
    minTrustForWarmInjection: string;
}
export interface InboxEntry {
    /** Unique entry ID */
    id: string;
    /** ISO 8601 timestamp */
    timestamp: string;
    /** Sender fingerprint */
    from: string;
    /** Sender display name */
    senderName: string;
    /** Trust level of sender */
    trustLevel: string;
    /** Thread ID */
    threadId: string;
    /** Message text content */
    text: string;
    /** HMAC-SHA256 signature */
    hmac: string;
}
export interface ListenerState {
    /** Whether the listener is active */
    active: boolean;
    /** Current state */
    state: 'starting' | 'listening' | 'parked' | 'rotating' | 'dead';
    /** Messages handled in current rotation */
    messagesHandled: number;
    /** Current inbox queue depth (unacked entries) */
    queueDepth: number;
    /** Current rotation ID */
    rotationId: string;
    /** When the current rotation started */
    rotationStartedAt: string;
}
export declare class ListenerSessionManager {
    private readonly stateDir;
    private readonly signingKey;
    private readonly config;
    private rotationId;
    private messagesHandled;
    private rotationStartedAt;
    private state;
    constructor(stateDir: string, authToken: string, config?: Partial<ListenerConfig>);
    get inboxPath(): string;
    get ackPath(): string;
    get wakeSentinelPath(): string;
    get rotationSentinelPath(): string;
    /**
     * Path to the canonical threadline inbox — single source of truth across all
     * routing branches (pipe / warm-listener / cold-spawn). Read by the dashboard
     * observability tab and the threadline → telegram bridge.
     */
    get canonicalInboxPath(): string;
    /**
     * Path to the canonical threadline outbox — every outbound threadline
     * message sent via `/threadline/relay-send` is appended here, regardless
     * of delivery path (local-delivery or relay-delivery). Read by the
     * dashboard observability tab so the conversation view can render BOTH
     * sides of an agent-to-agent thread.
     */
    get canonicalOutboxPath(): string;
    /**
     * Append an HMAC-signed entry to the canonical threadline inbox at
     * `.instar/threadline/inbox.jsonl.active`. Called once at relay-ingest before
     * any pipe/listener/cold-spawn branching, so the canonical inbox is the single
     * source of truth regardless of which routing path handles the message.
     *
     * Distinct from `writeToInbox`, which targets the warm-listener's per-rotation
     * queue file (`state/listener-inbox-{rotation}.jsonl`). Both files coexist:
     * canonical = audit + observability + bridge source; rotated = warm queue.
     */
    appendCanonicalInboxEntry(opts: {
        from: string;
        senderName: string;
        trustLevel: string;
        threadId: string;
        text: string;
        messageId?: string;
    }): InboxEntry;
    /**
     * Append an HMAC-signed entry to the canonical threadline outbox at
     * `.instar/threadline/outbox.jsonl.active`. Mirror of
     * `appendCanonicalInboxEntry` — same shape, same key, written from the
     * `/threadline/relay-send` route on every successful outbound delivery
     * (local or relay) so the dashboard observability tab can render both
     * sides of a conversation.
     */
    appendCanonicalOutboxEntry(opts: {
        /** This agent's identifier (the sender). */
        from: string;
        /** Display name of this agent. */
        senderName: string;
        /** Target agent fingerprint or name. */
        to: string;
        /** Display name of the target. */
        recipientName: string;
        threadId: string;
        text: string;
        messageId?: string;
        /** Delivery outcome from /threadline/relay-send (e.g. "accepted", "queued (no live session)"). */
        outcome?: string;
    }): InboxEntry & {
        to: string;
        recipientName: string;
        outcome?: string;
    };
    /**
     * Look up a previously-sent outbound message's body+target by its messageId,
     * scanning the canonical outbox (most-recent first). Used by the A2A redelivery
     * sentinel (A2A-DURABLE-DELIVERY-SPEC §4) to re-send a message that went
     * unacknowledged — the delivery tracker stores only id/peer/thread, not the
     * body, so the body is recovered here. Returns null if not found (→ the
     * sentinel escalates instead of fabricating a re-send).
     */
    readCanonicalOutboxEntry(messageId: string): {
        id: string;
        to: string;
        recipientName?: string;
        threadId?: string;
        text: string;
    } | null;
    /**
     * Write a message to the inbox file.
     * Called by the server process when a message is routed to the warm listener.
     * Returns the entry ID for tracking.
     */
    writeToInbox(opts: {
        from: string;
        senderName: string;
        trustLevel: string;
        threadId: string;
        text: string;
    }): string;
    /**
     * Verify HMAC of an inbox entry (server-side verification).
     */
    verifyEntry(entry: InboxEntry): boolean;
    /**
     * Get the current inbox queue depth (unacked entries).
     */
    getQueueDepth(): number;
    /**
     * Read all inbox entries from the current rotation.
     */
    readInboxEntries(): InboxEntry[];
    /**
     * Read all acked entry IDs from the current rotation.
     */
    readAckedIds(): Set<string>;
    /**
     * Get unprocessed entries (inbox entries not in ack file).
     */
    getUnprocessedEntries(): InboxEntry[];
    /**
     * Acknowledge an entry (mark as processed).
     */
    acknowledgeEntry(entryId: string): void;
    /**
     * Determine if a message should use the warm listener or cold-spawn.
     * This is the code-level trust gate — NOT an LLM instruction.
     */
    shouldUseListener(trustLevel: string, textLength: number): boolean;
    /**
     * Check if rotation is needed.
     */
    needsRotation(): boolean;
    /**
     * Begin rotation: archive current files and create fresh ones.
     * Returns the new rotation ID.
     */
    rotate(): string;
    /**
     * Compact the inbox file: remove entries that are in the ack file.
     */
    compact(): {
        removed: number;
        remaining: number;
    };
    getState(): ListenerState;
    setState(state: ListenerState['state']): void;
    getConfig(): ListenerConfig;
    /**
     * Build the two-part bootstrap prompt for the listener session.
     * Part 1: Hardcoded security preamble (never stored in editable files)
     * Part 2: Operator-customizable template (from disk if available)
     */
    buildBootstrapPrompt(): string;
    private computeHMAC;
    private generateRotationId;
    private parseAge;
}
//# sourceMappingURL=ListenerSessionManager.d.ts.map