fix(ci): resolve current gate regressions

This commit is contained in:
Peter Steinberger
2026-03-08 03:34:36 +00:00
parent ed437434af
commit f2a4bdf069
4 changed files with 63 additions and 3 deletions

View File

@@ -11317,7 +11317,7 @@
"filename": "extensions/voice-call/src/config.test.ts", "filename": "extensions/voice-call/src/config.test.ts",
"hashed_secret": "62207a469ec2fdcfc7d66b04c2980ac1501acbf0", "hashed_secret": "62207a469ec2fdcfc7d66b04c2980ac1501acbf0",
"is_verified": false, "is_verified": false,
"line_number": 39 "line_number": 44
} }
], ],
"extensions/voice-call/src/providers/telnyx.test.ts": [ "extensions/voice-call/src/providers/telnyx.test.ts": [
@@ -13011,5 +13011,5 @@
} }
] ]
}, },
"generated_at": "2026-03-08T02:36:42Z" "generated_at": "2026-03-08T03:31:44Z"
} }

View File

@@ -21,6 +21,7 @@ beforeAll(async () => {
allowPluginLocalInstall: false, allowPluginLocalInstall: false,
installCommand: "n/a", installCommand: "n/a",
cwd: process.cwd(), cwd: process.cwd(),
mcpServers: {},
permissionMode: "approve-reads", permissionMode: "approve-reads",
nonInteractivePermissions: "fail", nonInteractivePermissions: "fail",
strictWindowsCmdWrapper: true, strictWindowsCmdWrapper: true,

View File

@@ -223,8 +223,16 @@ describe("runDaemonRestart health checks", () => {
}); });
it("signals an unmanaged gateway process on stop", async () => { it("signals an unmanaged gateway process on stop", async () => {
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
const killSpy = vi.spyOn(process, "kill").mockImplementation(() => true); const killSpy = vi.spyOn(process, "kill").mockImplementation(() => true);
findGatewayPidsOnPortSync.mockReturnValue([4200, 4200, 4300]); findGatewayPidsOnPortSync.mockReturnValue([4200, 4200, 4300]);
mockSpawnSync.mockReturnValue({
error: null,
status: 0,
stdout:
'CommandLine="C:\\\\Program Files\\\\OpenClaw\\\\openclaw.exe" gateway --port 18789\r\n',
stderr: "",
});
runServiceStop.mockImplementation(async (params: { onNotLoaded?: () => Promise<unknown> }) => { runServiceStop.mockImplementation(async (params: { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.(); await params.onNotLoaded?.();
}); });
@@ -237,8 +245,16 @@ describe("runDaemonRestart health checks", () => {
}); });
it("signals a single unmanaged gateway process on restart", async () => { it("signals a single unmanaged gateway process on restart", async () => {
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
const killSpy = vi.spyOn(process, "kill").mockImplementation(() => true); const killSpy = vi.spyOn(process, "kill").mockImplementation(() => true);
findGatewayPidsOnPortSync.mockReturnValue([4200]); findGatewayPidsOnPortSync.mockReturnValue([4200]);
mockSpawnSync.mockReturnValue({
error: null,
status: 0,
stdout:
'CommandLine="C:\\\\Program Files\\\\OpenClaw\\\\openclaw.exe" gateway --port 18789\r\n',
stderr: "",
});
runServiceRestart.mockImplementation( runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => { async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.(); await params.onNotLoaded?.();
@@ -266,7 +282,15 @@ describe("runDaemonRestart health checks", () => {
}); });
it("fails unmanaged restart when multiple gateway listeners are present", async () => { it("fails unmanaged restart when multiple gateway listeners are present", async () => {
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
findGatewayPidsOnPortSync.mockReturnValue([4200, 4300]); findGatewayPidsOnPortSync.mockReturnValue([4200, 4300]);
mockSpawnSync.mockReturnValue({
error: null,
status: 0,
stdout:
'CommandLine="C:\\\\Program Files\\\\OpenClaw\\\\openclaw.exe" gateway --port 18789\r\n',
stderr: "",
});
runServiceRestart.mockImplementation( runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => { async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.(); await params.onNotLoaded?.();

View File

@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
import fsSync from "node:fs"; import fsSync from "node:fs";
import { isRestartEnabled } from "../../config/commands.js"; import { isRestartEnabled } from "../../config/commands.js";
import { readBestEffortConfig, resolveGatewayPort } from "../../config/config.js"; import { readBestEffortConfig, resolveGatewayPort } from "../../config/config.js";
import { parseCmdScriptCommandLine } from "../../daemon/cmd-argv.js";
import { resolveGatewayService } from "../../daemon/service.js"; import { resolveGatewayService } from "../../daemon/service.js";
import { probeGateway } from "../../gateway/probe.js"; import { probeGateway } from "../../gateway/probe.js";
import { findGatewayPidsOnPortSync } from "../../infra/restart.js"; import { findGatewayPidsOnPortSync } from "../../infra/restart.js";
@@ -52,6 +53,25 @@ function parseProcCmdline(raw: string): string[] {
.filter(Boolean); .filter(Boolean);
} }
function extractWindowsCommandLine(raw: string): string | null {
const lines = raw
.split(/\r?\n/)
.map((line) => line.trim())
.filter(Boolean);
for (const line of lines) {
if (!line.toLowerCase().startsWith("commandline=")) {
continue;
}
const value = line.slice("commandline=".length).trim();
return value || null;
}
return lines.find((line) => line.toLowerCase() !== "commandline") ?? null;
}
function stripExecutableExtension(value: string): string {
return value.replace(/\.(bat|cmd|exe)$/i, "");
}
function isGatewayArgv(args: string[]): boolean { function isGatewayArgv(args: string[]): boolean {
const normalized = args.map(normalizeProcArg); const normalized = args.map(normalizeProcArg);
if (!normalized.includes("gateway")) { if (!normalized.includes("gateway")) {
@@ -69,7 +89,7 @@ function isGatewayArgv(args: string[]): boolean {
return true; return true;
} }
const exe = normalized[0] ?? ""; const exe = stripExecutableExtension(normalized[0] ?? "");
return exe.endsWith("/openclaw") || exe === "openclaw" || exe.endsWith("/openclaw-gateway"); return exe.endsWith("/openclaw") || exe === "openclaw" || exe.endsWith("/openclaw-gateway");
} }
@@ -92,6 +112,21 @@ function readGatewayProcessArgsSync(pid: number): string[] | null {
const command = ps.stdout.trim(); const command = ps.stdout.trim();
return command ? command.split(/\s+/) : null; return command ? command.split(/\s+/) : null;
} }
if (process.platform === "win32") {
const wmic = spawnSync(
"wmic",
["process", "where", `ProcessId=${pid}`, "get", "CommandLine", "/value"],
{
encoding: "utf8",
timeout: 1000,
},
);
if (wmic.error || wmic.status !== 0) {
return null;
}
const command = extractWindowsCommandLine(wmic.stdout);
return command ? parseCmdScriptCommandLine(command) : null;
}
return null; return null;
} }