import { type ChildProcess } from "node:child_process"; import type { FileHandle } from "node:fs/promises"; import { type BrokerDiscovery } from "./discovery"; import { type SdkInternalSpawnCommand } from "./runtime"; export interface EnsureBrokerSettings { agentDir: string; heartbeatTtlMs?: number; /** * Environment for the spawned detached broker. Defaults to `process.env`; tests * that pre-start an isolated broker pass the same sanitized child env so the * broker and the child that attaches to it share one owned root. */ env?: NodeJS.ProcessEnv; } /** * Tail of the detached broker's stderr folded into a discovery failure. * * The broker used to spawn with `stdio: "ignore"`, so a broker that exited * cleanly told the caller nothing beyond `code=0` (#3963). Its stderr goes to a * file instead of a pipe because the child is detached and outlives this * process: a pipe would break under it the moment the parent exits. */ export declare const BROKER_SPAWN_LOG_TAIL_BYTES = 4096; export interface BrokerSpawnLog { path: string; handle: FileHandle; } /** Opens an isolated, bounded-lifetime diagnostic sink for one broker spawn. */ export declare function openBrokerSpawnLog(agentDir: string): Promise; export declare function readBrokerSpawnLogTail(spawnLogPath: string): Promise; export interface FixtureBrokerLease { /** Backward-compatible fixture cleanup alias for exact child termination. */ close(): Promise; } export interface ExactFixtureBrokerLease extends FixtureBrokerLease { /** Observes the retained child only; it never signals a process. */ waitForExit(timeoutMs: number): Promise; /** Signals only the retained ChildProcess, never a discovery-derived PID. */ terminateExactChild(): Promise; } export interface FixtureBrokerCommand { file: string; args: readonly string[]; cwd?: string; env?: NodeJS.ProcessEnv; } export interface StartedFixtureBrokerCommand { lease: ExactFixtureBrokerLease; control: NodeJS.WritableStream; } export interface StartedFixtureBroker { discovery: BrokerDiscovery; lease: ExactFixtureBrokerLease; } interface BrokerOwner { stop(): Promise; canReuse(discovery: BrokerDiscovery | null): boolean; markReady(discovery: BrokerDiscovery): boolean; } interface ReapTiming { gracefulMs: number; killVerifyMs: number; } /** Starts the detached broker entrypoint when discovery has no live owner. */ export declare function ensureBroker(settings: EnsureBrokerSettings): Promise; /** Starts one fresh fixture broker and returns its sole exact-child close lease. */ export declare function startFixtureBrokerWithLeaseForTest(settings: EnsureBrokerSettings): Promise; /** * Test-only launch surface for topology fixtures. It accepts an already-resolved * command and retains the exact spawned child; no production selection path * reaches this function. */ export declare function startFixtureBrokerCommandWithLeaseForTest(command: FixtureBrokerCommand): StartedFixtureBrokerCommand; /** Test hook: returns a stop handle for the detached broker this process spawned. */ export declare function brokerOwnerForTest(agentDir: string): BrokerOwner | undefined; /** Test hook: drives the detached-broker reap on a controllable child surface. */ export declare function reapSpawnedBrokerForTest(child: ChildProcess, timing?: ReapTiming): Promise; /** Test hook: resolves the complete broker environment without spawning. */ export declare function brokerSpawnEnvironmentForTest(command: SdkInternalSpawnCommand, override?: NodeJS.ProcessEnv): NodeJS.ProcessEnv; /** Test hook: installs an exact controllable owner to exercise replacement fencing. */ export declare function registerBrokerOwnerForTest(agentDir: string, child: ChildProcess, timing?: ReapTiming): BrokerOwner; export {};