import { EventEmitter } from "node:events";
import { TelemetryReporter } from "@agentvault/crypto";
import type { SecureChannelConfig, ChannelState, SendOptions, DecisionRequest, DecisionResponse, HeartbeatStatus, StatusAlert, RoomMemberInfo, RoomConversationInfo, RoomInfo, A2AChannel } from "./types.js";
export declare class SecureChannel extends EventEmitter {
    private config;
    private _state;
    private _deviceId;
    private _fingerprint;
    private _primaryConversationId;
    private _deviceJwt;
    private _sessions;
    private _ws;
    private _pollTimer;
    private _reconnectAttempt;
    private _reconnectTimer;
    private _pingTimer;
    private _lastServerMessage;
    private _pendingAcks;
    private _ackTimer;
    private _stopped;
    private _persisted;
    private _httpServer;
    private _pollFallbackTimer;
    private _heartbeatTimer;
    private _heartbeatCallback;
    private _heartbeatIntervalSeconds;
    private _wakeDetectorTimer;
    private _lastWakeTick;
    private _pendingPollTimer;
    private _syncMessageIds;
    /** Queued A2A messages for responder channels not yet activated (no first initiator message received). */
    private _a2aPendingQueue;
    private _scanEngine;
    private _scanRuleSetVersion;
    private _telemetryReporter;
    /** Topic ID from the most recent inbound message — used as fallback for replies. */
    private _lastIncomingTopicId;
    private static readonly PING_INTERVAL_MS;
    private static readonly SILENCE_TIMEOUT_MS;
    private static readonly POLL_FALLBACK_INTERVAL_MS;
    private static readonly POLL_FALLBACK_IDLE_MS;
    constructor(config: SecureChannelConfig);
    get state(): ChannelState;
    get deviceId(): string | null;
    get fingerprint(): string | null;
    /** Returns the primary conversation ID (backward-compatible). */
    get conversationId(): string | null;
    /** Returns all active conversation IDs. */
    get conversationIds(): string[];
    /** Returns the number of active sessions. */
    get sessionCount(): number;
    /** Returns the TelemetryReporter instance (available after WebSocket connect). */
    get telemetry(): TelemetryReporter | null;
    start(): Promise<void>;
    /**
     * Fetch scan rules from the server and load them into the ScanEngine.
     */
    private _fetchScanRules;
    /**
     * Append a message to persistent history for cross-device replay.
     */
    private _appendHistory;
    /**
     * Encrypt and send a message to ALL owner devices (fanout).
     * Each session gets the same plaintext encrypted independently.
     */
    send(plaintext: string, options?: SendOptions): Promise<void>;
    /**
     * Send a typing indicator to all owner devices.
     * Ephemeral (unencrypted metadata), no ratchet advancement.
     */
    sendTyping(): void;
    /**
     * Send a decision request to the owner.
     * Builds a structured envelope with decision metadata and sends it
     * as a high-priority message. Returns the generated decision_id.
     */
    sendDecisionRequest(request: DecisionRequest): Promise<string>;
    /**
     * Wait for a decision response matching the given decisionId.
     * Listens on the "message" event for messages where
     * metadata.messageType === "decision_response" and the parsed plaintext
     * contains a matching decision.decision_id.
     * Optional timeout rejects with an Error.
     */
    waitForDecision(decisionId: string, timeoutMs?: number): Promise<DecisionResponse>;
    /**
     * Join a room by performing X3DH key exchange with each member
     * for the pairwise conversations involving this device.
     */
    joinRoom(roomData: {
        roomId: string;
        name: string;
        members: RoomMemberInfo[];
        conversations: RoomConversationInfo[];
    }): Promise<void>;
    /**
     * Send an encrypted message to all members of a room.
     * Each pairwise conversation gets the plaintext encrypted independently.
     */
    sendToRoom(roomId: string, plaintext: string, opts?: {
        messageType?: string;
    }): Promise<void>;
    /**
     * Leave a room: remove sessions and persisted room state.
     */
    leaveRoom(roomId: string): Promise<void>;
    /**
     * Return info for all joined rooms.
     */
    getRooms(): RoomInfo[];
    startHeartbeat(intervalSeconds: number, statusCallback: () => HeartbeatStatus): void;
    stopHeartbeat(): Promise<void>;
    sendStatusAlert(alert: StatusAlert): Promise<void>;
    sendArtifact(artifact: {
        filePath: string;
        filename: string;
        mimeType: string;
        description?: string;
    }): Promise<void>;
    sendActionConfirmation(confirmation: {
        action: string;
        status: "completed" | "failed" | "partial";
        decisionId?: string;
        detail?: string;
    }): Promise<void>;
    private _sendHeartbeat;
    stop(): Promise<void>;
    startHttpServer(port: number): void;
    private _stopHttpServer;
    /**
     * Create a new topic within the conversation group.
     * Requires the channel to be initialized with a groupId (from activation).
     */
    createTopic(name: string): Promise<{
        id: string;
        name: string;
        isDefault: boolean;
    }>;
    /**
     * List all topics in the conversation group.
     * Requires the channel to be initialized with a groupId (from activation).
     */
    listTopics(): Promise<Array<{
        id: string;
        name: string;
        isDefault: boolean;
    }>>;
    /**
     * Request a new A2A channel with another agent by their hub address.
     * Returns the channel_id from the server response.
     */
    requestA2AChannel(responderHubAddress: string): Promise<string>;
    /**
     * Send a message to another agent via an active A2A channel.
     * Looks up the A2A conversation by hub address and sends via WS.
     *
     * If the channel has an established E2E session, the message is encrypted
     * with the Double Ratchet. If the responder hasn't received the initiator's
     * first message yet (ratchet not activated), the message is queued locally
     * and flushed when the first inbound message arrives.
     *
     * Falls back to plaintext for channels without a session (legacy/pre-encryption).
     */
    sendToAgent(hubAddress: string, text: string, opts?: {
        parentSpanId?: string;
    }): Promise<void>;
    /**
     * List all A2A channels for this agent.
     * Fetches from the server and updates local persisted state.
     */
    listA2AChannels(): Promise<A2AChannel[]>;
    private _enroll;
    private _poll;
    private _activate;
    private _connect;
    /**
     * Handle an incoming encrypted message from a specific conversation.
     * Decrypts using the appropriate session ratchet, emits to the agent,
     * and relays as sync messages to sibling sessions.
     */
    private _handleIncomingMessage;
    /**
     * Download an encrypted attachment blob, decrypt it, verify integrity,
     * and save the plaintext file to disk.
     */
    private _downloadAndDecryptAttachment;
    /**
     * Upload an attachment file: encrypt, upload to server, return metadata
     * for inclusion in the message envelope.
     */
    private _uploadAttachment;
    /**
     * Send a message with an attached file. Encrypts the file, uploads it,
     * then sends the envelope with attachment metadata via Double Ratchet.
     */
    sendWithAttachment(plaintext: string, filePath: string, options?: {
        topicId?: string;
    }): Promise<void>;
    /**
     * Relay an owner's message to all sibling sessions as encrypted sync messages.
     * This allows all owner devices to see messages from any single device.
     */
    private _relaySyncToSiblings;
    /**
     * Send stored message history to a newly-activated session.
     * Batches all history into a single encrypted message.
     */
    private _replayHistoryToSession;
    /**
     * Handle a device_linked event: a new owner device has joined.
     * Fetches the new device's public keys, performs X3DH, and initializes
     * a new ratchet session.
     */
    private _handleDeviceLinked;
    /**
     * Handle an incoming room message. Finds the pairwise conversation
     * for the sender, decrypts, and emits a room_message event.
     */
    private _handleRoomMessage;
    /**
     * Find the pairwise conversation ID for a given sender in a room.
     */
    private _findConversationForSender;
    /**
     * Sync missed messages across ALL sessions.
     * For each conversation, fetches messages since last sync and decrypts.
     */
    /**
     * Paginated sync: fetch missed messages in pages of 200, up to 5 pages (1000 messages).
     * Tracks message IDs in _syncMessageIds to prevent duplicate processing from concurrent WS messages.
     */
    private _syncMissedMessages;
    private _sendAck;
    private _flushAcks;
    private _flushOutboundQueue;
    private _startPing;
    private _stopPing;
    private _startWakeDetector;
    private _stopWakeDetector;
    private _startPendingPoll;
    private _stopPendingPoll;
    private _checkPendingMessages;
    private _scheduleReconnect;
    private _setState;
    private _startPollFallback;
    private _stopPollFallback;
    private _handleError;
    /**
     * Persist all ratchet session states to disk.
     * Syncs live ratchet states back into the persisted sessions map.
     */
    private _persistState;
}
//# sourceMappingURL=channel.d.ts.map