/**
 * Process Manager for Dev Mode
 *
 * Tracks all spawned processes and ensures they're cleaned up on:
 * - Startup failure (any server fails to start)
 * - Runtime crash (uncaught exception)
 * - Graceful shutdown (SIGINT/SIGTERM)
 *
 * This prevents orphan processes and port conflicts between dev sessions.
 *
 * Key design decisions:
 * - Process tree killing: Uses process.kill(-pid) to kill entire process groups,
 *   preventing orphaned child processes (e.g., Bun backend spawning workers).
 * - Per-process SIGTERM→SIGKILL escalation: Each process gets its own grace
 *   period instead of waiting for all processes to exit before force-killing.
 * - Last-resort synchronous cleanup: forceKillAllSync() can be called from
 *   process.on('exit') handlers where async operations are not possible.
 */
import type { Logger } from '../../types';
export interface ManagedProcess {
    /** Process identifier for logging */
    id: string;
    /** The process handle */
    process: {
        kill: (signal?: number | NodeJS.Signals) => void;
        exitCode: number | null;
        pid?: number;
    };
    /** Human-readable description */
    description: string;
    /** The port this process uses (if any) */
    port?: number;
    /** Whether this process is critical (startup fails if it dies) */
    critical?: boolean;
}
export interface ManagedServer {
    /** Server identifier */
    id: string;
    /** The server handle */
    server: {
        close: () => void | Promise<void>;
    };
    /** Human-readable description */
    description: string;
    /** The port this server uses */
    port?: number;
    /**
     * Maximum time (ms) to wait for this server's close() to resolve before
     * moving on. Defaults to 1000ms. Servers like Vite that own filesystem
     * watchers and HMR sockets may need more time.
     */
    closeTimeoutMs?: number;
}
/**
 * Process Manager
 *
 * Tracks all processes and servers started during dev mode and provides
 * centralized cleanup on failure or shutdown.
 */
export declare class ProcessManager {
    private processes;
    private servers;
    private logger;
    private cleaningUp;
    constructor(logger: Logger);
    /**
     * Register a spawned process for tracking.
     */
    registerProcess(proc: ManagedProcess): void;
    /**
     * Register a server for tracking.
     */
    registerServer(server: ManagedServer): void;
    /**
     * Unregister a process (e.g., after it exits normally).
     */
    unregisterProcess(id: string): void;
    /**
     * Unregister a server.
     */
    unregisterServer(id: string): void;
    /**
     * Get all registered ports (for cleanup verification).
     */
    getPorts(): number[];
    /**
     * Whether cleanup has already completed.
     * Used by forceKillAllSync() to avoid redundant work.
     */
    get isCleanedUp(): boolean;
    /**
     * Kill a process and its entire process tree.
     *
     * Uses process.kill(-pid) to send the signal to the entire process group.
     * This ensures child processes (e.g., workers spawned by Bun) are also killed.
     * Falls back to direct PID kill if process group kill fails (e.g., EPERM or
     * the process is not a group leader).
     */
    private killProcessTree;
    /**
     * Clean up all tracked processes and servers.
     *
     * Uses per-process SIGTERM→SIGKILL escalation: each process gets up to
     * `timeout` ms to exit gracefully after SIGTERM. Processes that exit early
     * don't delay cleanup of other processes.
     *
     * @param reason - Why cleanup is happening (for logging)
     * @param timeout - Max time to wait for graceful shutdown per process (ms)
     */
    cleanup(reason: string, timeout?: number): Promise<void>;
    /**
     * Synchronous last-resort cleanup for use in process.on('exit') handlers.
     *
     * Sends SIGKILL to all tracked process trees. This is intentionally
     * aggressive because it's the final opportunity to prevent orphans.
     * Only runs if async cleanup() hasn't already completed.
     */
    forceKillAllSync(): void;
    /**
     * Verify that all ports used by tracked processes are released.
     * Used after cleanup to ensure no orphan processes remain.
     */
    verifyPortsReleased(): Promise<{
        port: number;
        released: boolean;
    }[]>;
    /**
     * Check if a port is available.
     */
    private isPortAvailable;
}
/**
 * Get the global process manager (throws if not initialized).
 */
export declare function getProcessManager(): ProcessManager;
/**
 * Initialize the global process manager.
 */
export declare function initProcessManager(logger: Logger): ProcessManager;
/**
 * Cleanup helper that can be called from signal handlers or error handlers.
 */
export declare function cleanupAll(reason: string): Promise<void>;
//# sourceMappingURL=process-manager.d.ts.map