/** * Fastify lifecycle for the cadre-host local UI. * * Bound to `127.0.0.1:` only — never `0.0.0.0`. On `EADDRINUSE` * tries the configured port and then nine consecutive ports. On total * failure the start() promise rejects with a clear message naming every * port that was attempted. * * Shutdown drains with a 5 s timeout, mirroring cadre-provider's pattern. */ import { type FastifyInstance } from 'fastify'; export interface StartServerOptions { /** Preferred port. The server tries this then the next 9 on EADDRINUSE. */ preferredPort: number; /** * Test override: when 0, lets the OS pick any free port (skips the * fallback loop). The returned `port` reflects the actual bound port. */ forcePort?: 0; } export interface StartedServer { port: number; url: string; } export interface ShutdownOptions { /** Override the 5 s drain timeout (tests). */ drainTimeoutMs?: number; } /** * Bind `app` to the loopback interface with port-fallback. Returns the * actually-bound port — the configured port may be in use. */ export declare function startListening(app: FastifyInstance, opts: StartServerOptions): Promise; /** * Close the server with a hard 5 s drain timeout. Idempotent — safe to call * from a SIGINT/SIGTERM handler that may fire twice. */ export declare function stopListening(app: FastifyInstance, opts?: ShutdownOptions): Promise; /** * Create a Fastify instance with the project's logging convention and the * empty-body-tolerant JSON parser (see {@link acceptEmptyJsonBodies}). */ export declare function buildFastify(): FastifyInstance;