/**
 * Leader election for the unified web console.
 *
 * When multiple MCP server instances run concurrently, only one should host
 * the web console (the "leader"). Others become "followers" that forward
 * events to the leader. This module handles:
 *
 * 1. Reading/writing a leader lock file at ~/.dollhouse/run/console-leader.lock
 * 2. Atomic claim via temp+rename to prevent TOCTOU races
 * 3. PID-based stale detection (signal-0 liveness check)
 * 4. Heartbeat updates (10s interval) so followers can detect hung leaders
 * 5. Cleanup on process exit
 *
 * The configured port binding is the ultimate tiebreaker: even if two
 * processes both write the lock file, only one can bind the port (see
 * `DOLLHOUSE_WEB_CONSOLE_PORT` in `src/config/env.ts`).
 *
 * @since v2.1.0 — Issue #1700
 */
/** Current lock file schema version */
export declare const LOCK_VERSION = 1;
/**
 * Version of the leader-election/session metadata contract used by the
 * authenticated web console. Older leaders will not have this field.
 */
export declare const CONSOLE_PROTOCOL_VERSION = 1;
/** Missing protocol metadata means the leader predates version-aware election. */
export declare const LEGACY_CONSOLE_PROTOCOL_VERSION = 0;
/** Old lock files do not carry package version metadata. Treat them as oldest. */
export declare const LEGACY_SERVER_VERSION = "0.0.0";
/**
 * Information stored in the leader lock file.
 */
export interface ConsoleLeaderInfo {
    version: number;
    pid: number;
    port: number;
    sessionId: string;
    startedAt: string;
    heartbeat: string;
    serverVersion?: string;
    consoleProtocolVersion?: number;
}
/**
 * Result of a leader election attempt.
 */
export interface ElectionResult {
    role: 'leader' | 'follower';
    /** Leader info — for followers, this is the existing leader's info */
    leaderInfo: ConsoleLeaderInfo;
}
export interface LeaderPreferenceDecision {
    shouldReplace: boolean;
    reason: 'newer-compatible-version' | 'same-version' | 'older-version' | 'incompatible-protocol';
    candidateVersion: string;
    existingVersion: string;
    candidateProtocolVersion: number;
    existingProtocolVersion: number;
}
/**
 * Check whether a process with the given PID is alive.
 * Uses signal 0 which checks existence without sending a signal.
 */
export declare function isProcessAlive(pid: number): boolean;
/**
 * Normalize the server version present in the leader lock.
 * Missing metadata means "legacy leader" for election purposes.
 */
export declare function getLeaderServerVersion(info: ConsoleLeaderInfo): string;
/**
 * Normalize the console protocol version present in the leader lock.
 * Missing metadata means a leader from before version-aware election.
 */
export declare function getLeaderConsoleProtocolVersion(info: ConsoleLeaderInfo): number;
/**
 * Create this process's leader metadata in one place so all leadership paths
 * publish the same version and protocol information.
 */
export declare function createLeaderInfo(sessionId: string, port: number): ConsoleLeaderInfo;
/**
 * Decide whether this process should replace the current live leader based on
 * compatibility first, then package version.
 */
export declare function evaluateLeaderPreference(candidate: ConsoleLeaderInfo, existing: ConsoleLeaderInfo): LeaderPreferenceDecision;
/**
 * Result of a legacy-leader detection scan.
 * `legacyRunning === true` means a pre-authentication DollhouseMCP console
 * is currently running on this machine (its lock file exists and its pid
 * is alive). Callers can surface this to the user as a warning.
 */
export interface LegacyLeaderInfo {
    legacyRunning: boolean;
    pid?: number;
    port?: number;
    lockPath: string;
}
/**
 * Detect whether a legacy (pre-authentication) DollhouseMCP console is
 * currently running on this machine (#1794).
 *
 * The pre-authentication console writes its lock to
 * `~/.dollhouse/run/console-leader.lock` (no `.auth` suffix). An
 * authenticated console on a different port will not interfere with
 * it — they have fully independent ports, lock files, and token files —
 * but the user probably wants to know the two exist simultaneously
 * because the security posture of each console is different.
 *
 * Returns info about the legacy leader if one is detected, or
 * `{ legacyRunning: false }` otherwise.
 *
 * @param lockPath - Optional override for the legacy lock file path.
 *                   Defaults to the built-in legacy location. Primarily
 *                   used by tests to point at a temp directory.
 */
export declare function detectLegacyLeader(lockPath?: string): Promise<LegacyLeaderInfo>;
/**
 * Read and parse the leader lock file.
 * Returns null if the file doesn't exist, is unreadable, or has invalid content.
 */
export declare function readLeaderLock(): Promise<ConsoleLeaderInfo | null>;
/**
 * Check if a leader lock is stale (dead process or expired heartbeat).
 */
export declare function isLockStale(info: ConsoleLeaderInfo): boolean;
/**
 * Attempt to atomically claim leadership.
 *
 * Writes to a temp file then renames to the lock path. On POSIX systems
 * rename is atomic, so only one writer wins. After renaming, re-reads the
 * lock to verify our PID won.
 *
 * @returns true if this process successfully claimed leadership
 */
export declare function claimLeadership(info: ConsoleLeaderInfo): Promise<boolean>;
/**
 * Delete the leader lock file (for cleanup or takeover).
 */
export declare function deleteLeaderLock(): Promise<void>;
/**
 * Run the leader election protocol.
 *
 * 1. If no lock exists or lock is stale → claim leadership
 * 2. If lock exists with a live, responsive leader → become follower
 *
 * @param sessionId - This process's unique session identifier
 * @param port - The port this process would use as leader (see `DOLLHOUSE_WEB_CONSOLE_PORT`)
 * @returns Election result with role and leader info
 */
export declare function electLeader(sessionId: string, port: number): Promise<ElectionResult>;
/**
 * Probe whether the leader's web console is reachable.
 * Returns true if the leader's ingest endpoint responds, false otherwise.
 */
export declare function isLeaderWebConsoleReachable(leaderInfo: ConsoleLeaderInfo): Promise<boolean>;
/**
 * Force claim leadership by deleting the existing lock and claiming.
 * Used when the existing leader is alive but not running a web console.
 */
export declare function forceClaimLeadership(sessionId: string, port: number): Promise<ElectionResult>;
/**
 * Start the leader heartbeat loop.
 * Updates the lock file every HEARTBEAT_INTERVAL_MS so followers know the leader is alive.
 *
 * @returns A stop function to clear the interval
 */
export declare function startHeartbeat(info: ConsoleLeaderInfo): () => void;
/**
 * Register cleanup handlers to remove the leader lock on process exit.
 * Should only be called by the leader.
 */
export declare function registerLeaderCleanup(): void;
//# sourceMappingURL=LeaderElection.d.ts.map