diff --git a/src/acp/server.startup.test.ts b/src/acp/server.startup.test.ts index 628935e1f0c..5d80ff4cd0a 100644 --- a/src/acp/server.startup.test.ts +++ b/src/acp/server.startup.test.ts @@ -21,6 +21,7 @@ const mockState = vi.hoisted(() => ({ gatewayAuth: [] as GatewayClientAuth[], agentSideConnectionCtor: vi.fn(), agentStart: vi.fn(), + routeLogsToStderr: vi.fn(), resolveGatewayClientBootstrap: vi.fn(async (_params) => ({ url: "ws://127.0.0.1:18789", urlSource: "local loopback", @@ -104,6 +105,10 @@ vi.mock("../infra/is-main.js", () => ({ isMainModule: () => false, })); +vi.mock("../logging/console.js", () => ({ + routeLogsToStderr: () => mockState.routeLogsToStderr(), +})); + vi.mock("./translator.js", () => ({ AcpGatewayAgent: class { start(): void { @@ -166,6 +171,7 @@ describe("serveAcpGateway startup", () => { mockState.gatewayAuth.length = 0; mockState.agentSideConnectionCtor.mockReset(); mockState.agentStart.mockReset(); + mockState.routeLogsToStderr.mockReset(); mockState.resolveGatewayClientBootstrap.mockReset(); mockState.resolveGatewayClientBootstrap.mockResolvedValue({ url: "ws://127.0.0.1:18789", @@ -192,6 +198,26 @@ describe("serveAcpGateway startup", () => { } }); + it("routes logs to stderr before loading gateway config", async () => { + const { signalHandlers, onceSpy } = captureProcessSignalHandlers(); + + try { + const servePromise = serveAcpGateway({}); + await Promise.resolve(); + + expect(mockState.routeLogsToStderr).toHaveBeenCalledTimes(1); + expect(mockState.routeLogsToStderr.mock.invocationCallOrder[0]).toBeLessThan( + mockState.resolveGatewayClientBootstrap.mock.invocationCallOrder[0] ?? + Number.MAX_SAFE_INTEGER, + ); + + await emitHelloAndWaitForAgentSideConnection(); + await stopServeWithSigint(signalHandlers, servePromise); + } finally { + onceSpy.mockRestore(); + } + }); + it("rejects startup when gateway connect fails before hello", async () => { const onceSpy = vi .spyOn(process, "once") diff --git a/src/acp/server.ts b/src/acp/server.ts index afdbec82e85..f922d1ed129 100644 --- a/src/acp/server.ts +++ b/src/acp/server.ts @@ -7,12 +7,14 @@ import { resolveGatewayClientBootstrap } from "../gateway/client-bootstrap.js"; import { GatewayClient } from "../gateway/client.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js"; import { isMainModule } from "../infra/is-main.js"; +import { routeLogsToStderr } from "../logging/console.js"; import { normalizeOptionalString } from "../shared/string-coerce.js"; import { readSecretFromFile } from "./secret-file.js"; import { AcpGatewayAgent } from "./translator.js"; import { normalizeAcpProvenanceMode, type AcpServerOptions } from "./types.js"; export async function serveAcpGateway(opts: AcpServerOptions = {}): Promise { + routeLogsToStderr(); const cfg = loadConfig(); const bootstrap = await resolveGatewayClientBootstrap({ config: cfg,