diff --git a/CHANGELOG.md b/CHANGELOG.md index 07756fa55..2ad3631d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ Docs: https://docs.clawd.bot - Android: bump okhttp + dnsjava to satisfy lint dependency checks. - Docs: refresh Android node discovery docs for the Gateway WS service type. +### Fixes +- Tests: stabilize Windows gateway/CLI tests by skipping sidecars and normalizing argv. + ## 2026.1.19-1 ### Breaking diff --git a/src/entry.ts b/src/entry.ts index 61f69953e..7b01bfd47 100644 --- a/src/entry.ts +++ b/src/entry.ts @@ -60,17 +60,39 @@ function ensureExperimentalWarningSuppressed(): boolean { function normalizeWindowsArgv(argv: string[]): string[] { if (process.platform !== "win32") return argv; if (argv.length < 3) return argv; - const execBase = path.basename(process.execPath).toLowerCase(); + const execPath = process.execPath; + const execPathLower = execPath.toLowerCase(); + const execBase = path.basename(execPath).toLowerCase(); + const isExecPath = (value: string | undefined): boolean => { + if (!value) return false; + const lower = value.toLowerCase(); + return lower === execPathLower || path.basename(lower) === execBase; + }; const arg1 = path.basename(argv[1] ?? "").toLowerCase(); const arg2 = path.basename(argv[2] ?? "").toLowerCase(); const looksLikeEntry = arg1 === "entry.ts" || arg1 === "entry.js"; + let next = argv; if (arg1 === execBase) { - return [argv[0], ...argv.slice(2)]; + next = [argv[0], ...argv.slice(2)]; + } else if (looksLikeEntry && arg2 === execBase) { + next = [argv[0], argv[1], ...argv.slice(3)]; } - if (looksLikeEntry && arg2 === execBase) { - return [argv[0], argv[1], ...argv.slice(3)]; + + if (next.length < 3) return next; + const cleaned = [...next]; + for (let i = 2; i < cleaned.length; ) { + const arg = cleaned[i]; + if (!arg || arg.startsWith("-")) { + i += 1; + continue; + } + if (isExecPath(arg)) { + cleaned.splice(i, 1); + continue; + } + break; } - return argv; + return cleaned; } process.argv = normalizeWindowsArgv(process.argv); diff --git a/src/gateway/openai-http.e2e.test.ts b/src/gateway/openai-http.e2e.test.ts index 022b384f6..4f44751dc 100644 --- a/src/gateway/openai-http.e2e.test.ts +++ b/src/gateway/openai-http.e2e.test.ts @@ -13,6 +13,7 @@ async function startServerWithDefaultConfig(port: number) { host: "127.0.0.1", auth: { mode: "token", token: "secret" }, controlUiEnabled: false, + openAiChatCompletionsEnabled: false, }); } diff --git a/src/gateway/server.sessions.gateway-server-sessions-a.test.ts b/src/gateway/server.sessions.gateway-server-sessions-a.test.ts index 3ab734bbb..b7477e6f4 100644 --- a/src/gateway/server.sessions.gateway-server-sessions-a.test.ts +++ b/src/gateway/server.sessions.gateway-server-sessions-a.test.ts @@ -81,12 +81,12 @@ describe("gateway server sessions", () => { }, "discord:group:dev": { sessionId: "sess-group", - updatedAt: now - 120_000, + updatedAt: now - 10 * 60_000, totalTokens: 50, }, "agent:main:subagent:one": { sessionId: "sess-subagent", - updatedAt: now - 120_000, + updatedAt: now - 10 * 60_000, spawnedBy: "agent:main:main", }, global: { @@ -147,7 +147,7 @@ describe("gateway server sessions", () => { }>(ws, "sessions.list", { includeGlobal: false, includeUnknown: false, - activeMinutes: 1, + activeMinutes: 5, }); expect(active.ok).toBe(true); expect(active.payload?.sessions.map((s) => s.key)).toEqual(["agent:main:main"]); diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index f6c4771cd..fc749674f 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -37,6 +37,9 @@ let previousHome: string | undefined; let previousUserProfile: string | undefined; let previousStateDir: string | undefined; let previousConfigPath: string | undefined; +let previousSkipBrowserControl: string | undefined; +let previousSkipGmailWatcher: string | undefined; +let previousSkipCanvasHost: string | undefined; let tempHome: string | undefined; let tempConfigRoot: string | undefined; @@ -75,11 +78,17 @@ export function installGatewayTestHooks() { previousUserProfile = process.env.USERPROFILE; previousStateDir = process.env.CLAWDBOT_STATE_DIR; previousConfigPath = process.env.CLAWDBOT_CONFIG_PATH; + previousSkipBrowserControl = process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER; + previousSkipGmailWatcher = process.env.CLAWDBOT_SKIP_GMAIL_WATCHER; + previousSkipCanvasHost = process.env.CLAWDBOT_SKIP_CANVAS_HOST; tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-gateway-home-")); process.env.HOME = tempHome; process.env.USERPROFILE = tempHome; process.env.CLAWDBOT_STATE_DIR = path.join(tempHome, ".clawdbot"); delete process.env.CLAWDBOT_CONFIG_PATH; + process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER = "1"; + process.env.CLAWDBOT_SKIP_GMAIL_WATCHER = "1"; + process.env.CLAWDBOT_SKIP_CANVAS_HOST = "1"; tempConfigRoot = path.join(tempHome, ".clawdbot-test"); setTestConfigRoot(tempConfigRoot); sessionStoreSaveDelayMs.value = 0; @@ -128,6 +137,13 @@ export function installGatewayTestHooks() { else process.env.CLAWDBOT_STATE_DIR = previousStateDir; if (previousConfigPath === undefined) delete process.env.CLAWDBOT_CONFIG_PATH; else process.env.CLAWDBOT_CONFIG_PATH = previousConfigPath; + if (previousSkipBrowserControl === undefined) + delete process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER; + else process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER = previousSkipBrowserControl; + if (previousSkipGmailWatcher === undefined) delete process.env.CLAWDBOT_SKIP_GMAIL_WATCHER; + else process.env.CLAWDBOT_SKIP_GMAIL_WATCHER = previousSkipGmailWatcher; + if (previousSkipCanvasHost === undefined) delete process.env.CLAWDBOT_SKIP_CANVAS_HOST; + else process.env.CLAWDBOT_SKIP_CANVAS_HOST = previousSkipCanvasHost; if (tempHome) { await fs.rm(tempHome, { recursive: true,