/**
 * Agent Heartbeat Monitor Service
 *
 * Monitors all non-orchestrator agents for responsiveness using a
 * non-intrusive, server-side approach:
 *
 * 1. Dual idle detection: Checks BOTH PTY activity (via PtyActivityTrackerService)
 *    AND API activity (via AgentHeartbeatService lastActiveTime). An agent is only
 *    considered truly idle when both signals are stale.
 *
 * 2. Process liveness check: Instead of injecting heartbeat requests into the
 *    agent's PTY input (which corrupts the input buffer and conflicts with
 *    orchestrator task delivery), this service checks isChildProcessAlive()
 *    on the session backend to determine if the agent process is still running.
 *
 * 3. Progressive restart: After MAX_DEAD_CHECKS_BEFORE_RESTART consecutive
 *    checks finding the process dead, triggers agent restart with session ID
 *    preservation and task re-delivery.
 *
 * Interaction with other services:
 * - IdleDetectionService (configurable timeout): Suspends idle but responsive agents
 * - AgentHeartbeatMonitorService: Restarts crashed/unresponsive agents
 * - RuntimeExitMonitorService: Detects exit patterns in PTY output (complementary)
 *
 * Key design principle: NEVER write to an agent's PTY input. All checks are
 * performed server-side via process inspection and API activity timestamps.
 *
 * @module agent-heartbeat-monitor.service
 */
import { StorageService } from '../core/storage.service.js';
import type { AgentRegistrationService } from './agent-registration.service.js';
import type { ISessionBackend } from '../session/session-backend.interface.js';
/**
 * Per-agent monitoring state tracked by the heartbeat monitor.
 */
export interface AgentMonitorState {
    /** PTY session name */
    sessionName: string;
    /** Team member ID */
    memberId: string;
    /** Team ID */
    teamId: string;
    /** Agent role */
    role: string;
    /** Number of consecutive checks where the child process was found dead */
    consecutiveDeadChecks: number;
    /** Timestamps of recent restarts for cooldown tracking */
    restartTimestamps: number[];
    /** Total restart count */
    restartCount: number;
    /** Cached timestamp of last API activity (ms since epoch) for on-demand skip (#191) */
    lastApiCallTime: number;
    /** Number of consecutive checks where agent was idle but alive (#191) */
    consecutiveIdleChecks: number;
    /** Whether heartbeat monitoring is suspended for this idle agent (#191) */
    heartbeatSuspended: boolean;
}
/**
 * Monitors all non-orchestrator agents for responsiveness.
 *
 * Uses dual-signal idle detection (PTY activity + API heartbeat) and
 * server-side process liveness checks to detect crashed agents without
 * injecting into the agent's PTY input buffer.
 *
 * @example
 * ```typescript
 * const monitor = AgentHeartbeatMonitorService.getInstance();
 * monitor.setDependencies(sessionBackend, agentRegistrationService, storageService);
 * monitor.start();
 * ```
 */
export declare class AgentHeartbeatMonitorService {
    private static instance;
    private logger;
    /** Interval timer handle */
    private checkTimer;
    /** When monitoring started */
    private startedAt;
    /** Per-agent monitoring state */
    private agentStates;
    /** Dependencies (injected via setDependencies) */
    private sessionBackend;
    private agentRegistrationService;
    private storageService;
    private constructor();
    /**
     * Get the singleton instance.
     *
     * @returns The AgentHeartbeatMonitorService singleton
     */
    static getInstance(): AgentHeartbeatMonitorService;
    /**
     * Reset the singleton (for testing).
     */
    static resetInstance(): void;
    /**
     * Inject required dependencies.
     *
     * @param sessionBackend - Session backend for accessing agent PTY sessions
     * @param agentRegistrationService - For recreating agent sessions on restart
     * @param storageService - For querying teams and agent statuses
     */
    setDependencies(sessionBackend: ISessionBackend, agentRegistrationService: AgentRegistrationService, storageService: StorageService): void;
    /**
     * Start the heartbeat monitoring loop.
     * Applies a startup grace period before the first check.
     */
    start(): void;
    /**
     * Stop the heartbeat monitoring loop.
     */
    stop(): void;
    /**
     * Check if the monitor is currently running.
     *
     * @returns True if the check loop is active
     */
    isRunning(): boolean;
    /**
     * Get monitoring state for all tracked agents.
     *
     * @returns Map of session name to agent monitor state
     */
    getAgentStates(): Map<string, AgentMonitorState>;
    /**
     * Resume heartbeat monitoring for a suspended agent.
     * Called when an agent transitions from idle back to active work. (#191)
     *
     * @param sessionName - Session name of the agent to resume
     */
    resumeHeartbeat(sessionName: string): void;
    /**
     * Perform a single heartbeat check cycle across all active agents.
     *
     * For each active non-orchestrator agent:
     * 1. Skip if within startup grace period
     * 2. Skip if session doesn't exist, or agent is suspended/rehydrating
     * 3. Check dual idle signals (PTY + API). If either is recent → agent is alive → reset dead checks
     * 4. If truly idle (both PTY and API stale for threshold), check process liveness
     * 5. If process is alive → agent is idle but responsive → reset dead checks (let IdleDetectionService handle)
     * 6. If process is dead → increment consecutiveDeadChecks
     * 7. After MAX_DEAD_CHECKS_BEFORE_RESTART consecutive dead checks → restart agent
     */
    performCheck(): Promise<void>;
    /**
     * Get the API idle time in milliseconds for a team member.
     *
     * Reads the agent's lastActiveTime from AgentHeartbeatService and
     * calculates how long ago it was. Returns 0 if no heartbeat data
     * exists (treat as "just started").
     *
     * @param memberId - Team member ID to check
     * @returns Milliseconds since last API activity, or 0 if unknown
     */
    private getApiIdleTimeMs;
    /**
     * Check if the child process (e.g. Claude Code) inside an agent's
     * PTY shell is still alive.
     *
     * Uses the session backend's isChildProcessAlive() method which
     * inspects the process tree via pgrep. This is a non-intrusive
     * server-side check that does not write to the agent's PTY.
     *
     * @param sessionName - Session to check
     * @returns true if child process is alive, false if dead or check unavailable
     */
    private isChildProcessAlive;
    /**
     * Restart a crashed/unresponsive agent.
     *
     * Follows the AgentSuspendService.rehydrateAgent() pattern:
     * 1. Check cooldown (max restarts per window)
     * 2. Save Claude session ID for resume
     * 3. Stop exit monitoring
     * 4. Kill old PTY session
     * 5. Pre-set session ID for resume
     * 6. Recreate agent session via AgentRegistrationService
     * 7. Re-deliver in-progress tasks from TaskPool
     * 8. Broadcast WebSocket event
     *
     * @param state - Agent monitor state
     */
    private triggerAgentRestart;
    /**
     * Re-deliver in-progress tasks to a restarted agent.
     *
     * Waits for the agent to initialize, queries TaskPoolService for
     * running/queued WorkItems targeting this agent's session, and writes
     * task descriptions into the agent's PTY session.
     *
     * @param state - Agent monitor state
     */
    private redeliverTasks;
}
//# sourceMappingURL=agent-heartbeat-monitor.service.d.ts.map