export interface ServerInfo {
    /**
     * Pidfile schema version (L3). Absent on pidfiles written before this
     * field existed — detectServer treats a missing `schema` as legacy and
     * still accepts the pidfile.
     */
    schema?: number;
    pid: number;
    port: number;
    url: string;
    started_at: string;
}
/**
 * Read .hippo/server.pid and return the embedded ServerInfo if a live hippo
 * server is genuinely answering on the recorded url. Returns null on missing,
 * malformed, or stale pidfiles, and best-effort unlinks the file in the
 * stale/malformed cases.
 *
 * Liveness is proven in two steps. `process.kill(pid, 0)` rules out dead
 * pids. But a pid can be reused by an unrelated process, so a GET /health
 * then confirms the process that answers is *this* hippo server: its
 * `started_at` must equal the pidfile's. A mismatch, non-200, malformed
 * body, or timeout all mean the pidfile is stale.
 *
 * The /health probe runs only when a pidfile exists and the pid is live, so
 * the common no-server path stays a single fast file existence check.
 */
export declare function detectServer(hippoRoot: string): Promise<ServerInfo | null>;
/**
 * Atomically write the pidfile. Writes to a process-scoped temp file then
 * renames into place, which is atomic on POSIX and on NTFS via MoveFileEx.
 *
 * `startedAt` is supplied by the caller (`serve()`) rather than generated
 * here, so the pidfile and the server's GET /health response carry the same
 * timestamp — detectServer's liveness probe compares the two for equality.
 */
export declare function writePidfile(hippoRoot: string, opts: {
    port: number;
    url: string;
    startedAt: string;
}): void;
/**
 * Best-effort pidfile removal. Silent on ENOENT or any other error so the
 * caller can use this in shutdown paths without fear of throwing.
 *
 * Identity-blind: deletes whatever pidfile is on disk. A shutdown path that
 * must not clobber a newer server's pidfile should use removePidfileIfOwned.
 */
export declare function removePidfile(hippoRoot: string): void;
/**
 * Remove the pidfile only if it still describes the caller's own server.
 * Reads and parses the pidfile and unlinks it ONLY when both `pid` and
 * `started_at` match `owner`. A pidfile rewritten by a newer server is left
 * intact, so a shutting-down older server cannot orphan the newer one by
 * deleting its pidfile out from under it.
 *
 * Best-effort and never throws: a missing, unreadable, malformed, or
 * non-object pidfile (including a literal JSON `null`) is "not provably mine"
 * and left alone — detectServer unlinks a malformed pidfile on its next
 * probe, so it does not leak. Returns true iff a matching pidfile was removed.
 *
 * Residual TOCTOU: the pidfile could be rewritten between the read and the
 * unlink. The window is microseconds and the shape is the same read-check-
 * unlink detectServer already uses; this narrows the clobber from an
 * unbounded window (any time between writePidfile and stop) to a negligible
 * one.
 */
export declare function removePidfileIfOwned(hippoRoot: string, owner: {
    pid: number;
    startedAt: string;
}): boolean;
//# sourceMappingURL=server-detect.d.ts.map