From 6c9836fb2d0170d11f35905db289efc0c77c2542 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Sun, 5 Jul 2026 19:42:34 -0700 Subject: [PATCH] fix(cli): configurable dev readiness timeout; de-flake child-disposal test Under CI load the dev child's tsx boot could exceed the parent's hard-coded 5s /healthz readiness window, so the parent killed a child that had not yet written its PID file and the disposal test timed out on waitForPath. Add DAWN_DEV_READY_TIMEOUT_MS (mirroring DAWN_DEV_SHUTDOWN_TIMEOUT_MS), widen the window in the test, and raise the waitForPath default. Co-Authored-By: Claude Opus 4.8 --- .changeset/dev-ready-timeout.md | 5 +++++ packages/cli/src/lib/dev/dev-session.ts | 13 ++++++++++++- packages/cli/test/dev-command.test.ts | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 .changeset/dev-ready-timeout.md diff --git a/.changeset/dev-ready-timeout.md b/.changeset/dev-ready-timeout.md new file mode 100644 index 00000000..f02e99de --- /dev/null +++ b/.changeset/dev-ready-timeout.md @@ -0,0 +1,5 @@ +--- +"@dawn-ai/cli": patch +--- + +`dawn dev` startup readiness timeout is now configurable via `DAWN_DEV_READY_TIMEOUT_MS` (default unchanged at 5s). Also de-flakes the dev-command disposal test that raced child startup against the readiness window in CI. diff --git a/packages/cli/src/lib/dev/dev-session.ts b/packages/cli/src/lib/dev/dev-session.ts index 24e490d3..7ecb4a88 100644 --- a/packages/cli/src/lib/dev/dev-session.ts +++ b/packages/cli/src/lib/dev/dev-session.ts @@ -263,7 +263,7 @@ class InternalDevSession { try { await child.waitForReady() - await waitForDevServerReady(this.url) + await waitForDevServerReady(this.url, { timeoutMs: readReadyTimeoutMs() }) } catch (error) { await child.stop(readShutdownTimeoutMs()) @@ -399,3 +399,14 @@ function readShutdownTimeoutMs(): number { const parsedValue = Number(rawValue) return Number.isFinite(parsedValue) ? parsedValue : 1_000 } + +function readReadyTimeoutMs(): number { + const rawValue = process.env.DAWN_DEV_READY_TIMEOUT_MS + + if (!rawValue) { + return 5_000 + } + + const parsedValue = Number(rawValue) + return Number.isFinite(parsedValue) ? parsedValue : 5_000 +} diff --git a/packages/cli/test/dev-command.test.ts b/packages/cli/test/dev-command.test.ts index 4141fc61..15909d47 100644 --- a/packages/cli/test/dev-command.test.ts +++ b/packages/cli/test/dev-command.test.ts @@ -220,6 +220,7 @@ describe("dawn dev lifecycle", () => { env: { DAWN_DEV_CHILD_PID_PATH: pidPath, DAWN_DEV_CHILD_TEST_MODE: "report-ready-without-server", + DAWN_DEV_READY_TIMEOUT_MS: "15000", }, }) devProcesses.push(dev) @@ -739,7 +740,7 @@ async function delay(ms: number): Promise { await new Promise((resolve) => setTimeout(resolve, ms)) } -async function waitForPath(path: string, timeoutMs = 2_000): Promise { +async function waitForPath(path: string, timeoutMs = 10_000): Promise { const startedAt = Date.now() while (Date.now() - startedAt < timeoutMs) {