From d4c6491b93d3c077df1d2476d5a923d50bb42976 Mon Sep 17 00:00:00 2001 From: Hweinstock Date: Wed, 26 Aug 2026 02:45:24 +0000 Subject: [PATCH 1/4] fix(test): await readiness server shutdown --- src/core/dev/supervisor.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/dev/supervisor.test.ts b/src/core/dev/supervisor.test.ts index 4c8bb38e2..a41797f61 100644 --- a/src/core/dev/supervisor.test.ts +++ b/src/core/dev/supervisor.test.ts @@ -292,11 +292,13 @@ describe("DevSupervisor", () => { "produced no output and did not accept connections on port 1 within 0.1s", ); - const server = createServer(); + const server = createServer((socket) => socket.destroy()); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const port = (server.address() as { port: number }).port; await waitForPort(port, signal, undefined, 10, 1000); // resolves against a live listener - server.close(); + await new Promise((resolve, reject) => { + server.close((error) => (error ? reject(error) : resolve())); + }); }); test("recent activity keeps a silent port from timing out", async () => { From 39024a8ec47890560ee7a8d3993f355ebf703dc6 Mon Sep 17 00:00:00 2001 From: Hweinstock Date: Wed, 26 Aug 2026 02:51:34 +0000 Subject: [PATCH 2/4] fix(dev): abort readiness socket attempts --- src/io/port.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/port.ts b/src/io/port.ts index 79c90fe44..372ff3ed1 100644 --- a/src/io/port.ts +++ b/src/io/port.ts @@ -57,7 +57,7 @@ export function waitForPort( ); return; } - const socket = connect({ port, host: "127.0.0.1" }, () => { + const socket = connect({ port, host: "127.0.0.1", signal }, () => { socket.destroy(); resolve(); }); From 06aad5671629c8bfebc674db66c3dfdbef5311a0 Mon Sep 17 00:00:00 2001 From: Hweinstock Date: Wed, 26 Aug 2026 02:57:32 +0000 Subject: [PATCH 3/4] fix(dev): cancel active readiness sockets --- src/io/port.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/io/port.ts b/src/io/port.ts index 372ff3ed1..2ef2cf225 100644 --- a/src/io/port.ts +++ b/src/io/port.ts @@ -57,10 +57,17 @@ export function waitForPort( ); return; } - const socket = connect({ port, host: "127.0.0.1", signal }, () => { + const socket = connect({ port, host: "127.0.0.1" }, () => { socket.destroy(); resolve(); }); + const onAbort = () => { + socket.destroy(); + reject(new Error("Aborted while waiting for the agent to become ready.")); + }; + signal.addEventListener("abort", onAbort, { once: true }); + socket.once("close", () => signal.removeEventListener("abort", onAbort)); + if (signal.aborted) onAbort(); socket.on("error", () => { socket.destroy(); setTimeout(attempt, intervalMs); From 5ae579912c62bb6c184df063507474f08dbf1a84 Mon Sep 17 00:00:00 2001 From: Hweinstock Date: Wed, 26 Aug 2026 03:30:56 +0000 Subject: [PATCH 4/4] fix(dev): cancel readiness retries on abort --- src/io/port.ts | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/io/port.ts b/src/io/port.ts index 2ef2cf225..b2423f5db 100644 --- a/src/io/port.ts +++ b/src/io/port.ts @@ -44,12 +44,25 @@ export function waitForPort( const startedAt = Date.now(); const since = lastActivityAt ?? (() => startedAt); return new Promise((resolve, reject) => { + let socket: ReturnType | undefined; + let retry: ReturnType | undefined; + + const cleanup = () => { + socket?.destroy(); + if (retry) clearTimeout(retry); + signal.removeEventListener("abort", onAbort); + }; + const onAbort = () => { + cleanup(); + reject(new Error("Aborted while waiting for the agent to become ready.")); + }; const attempt = () => { if (signal.aborted) { - reject(new Error("Aborted while waiting for the agent to become ready.")); + onAbort(); return; } if (Date.now() - since() > idleMs) { + cleanup(); reject( new Error( `Agent produced no output and did not accept connections on port ${port} within ${idleMs / 1000}s.`, @@ -57,22 +70,22 @@ export function waitForPort( ); return; } - const socket = connect({ port, host: "127.0.0.1" }, () => { - socket.destroy(); + socket = connect({ port, host: "127.0.0.1" }, () => { + cleanup(); resolve(); }); - const onAbort = () => { - socket.destroy(); - reject(new Error("Aborted while waiting for the agent to become ready.")); - }; - signal.addEventListener("abort", onAbort, { once: true }); - socket.once("close", () => signal.removeEventListener("abort", onAbort)); - if (signal.aborted) onAbort(); socket.on("error", () => { - socket.destroy(); - setTimeout(attempt, intervalMs); + socket?.destroy(); + socket = undefined; + if (signal.aborted) { + onAbort(); + return; + } + retry = setTimeout(attempt, intervalMs); }); }; + + signal.addEventListener("abort", onAbort, { once: true }); attempt(); }); }