From 50e5553533dd36a1e84d46d5f2fcb1fed610fcaf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 18 Feb 2026 04:32:49 +0100 Subject: [PATCH] fix: align retry backoff semantics and test mock signatures --- src/agents/subagent-registry.ts | 7 ++--- src/cli/acp-cli.option-collisions.test.ts | 4 +-- ...rowser-cli-state.option-collisions.test.ts | 30 ++++--------------- .../register-service-commands.test.ts | 12 ++++---- src/cli/update-cli.option-collisions.test.ts | 6 ++-- 5 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/agents/subagent-registry.ts b/src/agents/subagent-registry.ts index 142581d10..0e14a2aaa 100644 --- a/src/agents/subagent-registry.ts +++ b/src/agents/subagent-registry.ts @@ -60,10 +60,9 @@ const ANNOUNCE_EXPIRY_MS = 5 * 60_000; // 5 minutes function resolveAnnounceRetryDelayMs(retryCount: number) { const boundedRetryCount = Math.max(0, Math.min(retryCount, 10)); - // retryCount tracks completed failed attempts. The next retry delay should - // start at 1s for retry #1, then 2s, 4s, ... - const exponent = Math.max(0, boundedRetryCount - 1); - const baseDelay = MIN_ANNOUNCE_RETRY_DELAY_MS * 2 ** exponent; + // retryCount is "attempts already made", so retry #1 waits 1s, then 2s, 4s... + const backoffExponent = Math.max(0, boundedRetryCount - 1); + const baseDelay = MIN_ANNOUNCE_RETRY_DELAY_MS * 2 ** backoffExponent; return Math.min(baseDelay, MAX_ANNOUNCE_RETRY_DELAY_MS); } diff --git a/src/cli/acp-cli.option-collisions.test.ts b/src/cli/acp-cli.option-collisions.test.ts index 44596d8cf..2f7df9d49 100644 --- a/src/cli/acp-cli.option-collisions.test.ts +++ b/src/cli/acp-cli.option-collisions.test.ts @@ -1,8 +1,8 @@ import { Command } from "commander"; import { beforeEach, describe, expect, it, vi } from "vitest"; -const runAcpClientInteractive = vi.fn(async (_opts?: unknown) => {}); -const serveAcpGateway = vi.fn(async (_opts?: unknown) => {}); +const runAcpClientInteractive = vi.fn(async (_opts: unknown) => {}); +const serveAcpGateway = vi.fn(async (_opts: unknown) => {}); const defaultRuntime = { error: vi.fn(), diff --git a/src/cli/browser-cli-state.option-collisions.test.ts b/src/cli/browser-cli-state.option-collisions.test.ts index 2bddcce01..700079ca2 100644 --- a/src/cli/browser-cli-state.option-collisions.test.ts +++ b/src/cli/browser-cli-state.option-collisions.test.ts @@ -4,18 +4,7 @@ import type { BrowserParentOpts } from "./browser-cli-shared.js"; import { registerBrowserStateCommands } from "./browser-cli-state.js"; const mocks = vi.hoisted(() => ({ - callBrowserRequest: vi.fn( - async ( - _opts: BrowserParentOpts, - _params: { - method: "GET" | "POST" | "DELETE"; - path: string; - query?: Record; - body?: unknown; - }, - _extra?: { timeoutMs?: number; progress?: boolean }, - ) => ({ ok: true }), - ), + callBrowserRequest: vi.fn(async (..._args: unknown[]) => ({ ok: true })), runBrowserResizeWithOutput: vi.fn(async (_params: unknown) => {}), runtime: { log: vi.fn(), @@ -25,20 +14,11 @@ const mocks = vi.hoisted(() => ({ })); vi.mock("./browser-cli-shared.js", () => ({ - callBrowserRequest: ( - opts: BrowserParentOpts, - params: { - method: "GET" | "POST" | "DELETE"; - path: string; - query?: Record; - body?: unknown; - }, - extra?: { timeoutMs?: number; progress?: boolean }, - ) => mocks.callBrowserRequest(opts, params, extra), + callBrowserRequest: mocks.callBrowserRequest, })); vi.mock("./browser-cli-resize.js", () => ({ - runBrowserResizeWithOutput: (params: unknown) => mocks.runBrowserResizeWithOutput(params), + runBrowserResizeWithOutput: mocks.runBrowserResizeWithOutput, })); vi.mock("../runtime.js", () => ({ @@ -82,7 +62,7 @@ describe("browser state option collisions", () => { const call = mocks.callBrowserRequest.mock.calls.at(-1); expect(call).toBeDefined(); if (!call) { - throw new Error("Expected callBrowserRequest to be called"); + throw new Error("expected browser request call"); } const request = call[1] as { body?: { targetId?: string } }; expect(request.body?.targetId).toBe("tab-1"); @@ -105,7 +85,7 @@ describe("browser state option collisions", () => { const call = mocks.callBrowserRequest.mock.calls.at(-1); expect(call).toBeDefined(); if (!call) { - throw new Error("Expected callBrowserRequest to be called"); + throw new Error("expected browser request call"); } const request = call[1] as { body?: { headers?: Record } }; expect(request.body?.headers).toEqual({ "x-auth": "ok" }); diff --git a/src/cli/daemon-cli/register-service-commands.test.ts b/src/cli/daemon-cli/register-service-commands.test.ts index 1b90e1fed..00e8d9fec 100644 --- a/src/cli/daemon-cli/register-service-commands.test.ts +++ b/src/cli/daemon-cli/register-service-commands.test.ts @@ -2,12 +2,12 @@ import { Command } from "commander"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { addGatewayServiceCommands } from "./register-service-commands.js"; -const runDaemonInstall = vi.fn(async (_opts?: unknown) => {}); -const runDaemonRestart = vi.fn(async (_opts?: unknown) => {}); -const runDaemonStart = vi.fn(async (_opts?: unknown) => {}); -const runDaemonStatus = vi.fn(async (_opts?: unknown) => {}); -const runDaemonStop = vi.fn(async (_opts?: unknown) => {}); -const runDaemonUninstall = vi.fn(async (_opts?: unknown) => {}); +const runDaemonInstall = vi.fn(async (_opts: unknown) => {}); +const runDaemonRestart = vi.fn(async (_opts: unknown) => {}); +const runDaemonStart = vi.fn(async (_opts: unknown) => {}); +const runDaemonStatus = vi.fn(async (_opts: unknown) => {}); +const runDaemonStop = vi.fn(async (_opts: unknown) => {}); +const runDaemonUninstall = vi.fn(async (_opts: unknown) => {}); vi.mock("./runners.js", () => ({ runDaemonInstall: (opts: unknown) => runDaemonInstall(opts), diff --git a/src/cli/update-cli.option-collisions.test.ts b/src/cli/update-cli.option-collisions.test.ts index 6503daf4f..7ea0c672b 100644 --- a/src/cli/update-cli.option-collisions.test.ts +++ b/src/cli/update-cli.option-collisions.test.ts @@ -1,9 +1,9 @@ import { Command } from "commander"; import { beforeEach, describe, expect, it, vi } from "vitest"; -const updateCommand = vi.fn(async (_opts?: unknown) => {}); -const updateStatusCommand = vi.fn(async (_opts?: unknown) => {}); -const updateWizardCommand = vi.fn(async (_opts?: unknown) => {}); +const updateCommand = vi.fn(async (_opts: unknown) => {}); +const updateStatusCommand = vi.fn(async (_opts: unknown) => {}); +const updateWizardCommand = vi.fn(async (_opts: unknown) => {}); const defaultRuntime = { log: vi.fn(),