fix(cli): parse where output on Windows to prefer .cmd/.exe wrappers

The locateCommand function returned the bare command name instead of
parsing the where output. On Windows, npm global installs create both
a Unix shell script (no extension) and a .cmd wrapper. where returns
both, and the bare name resolves to the Unix script first, causing
healthcheck failures for OpenClaw and OpenCode.

Fix: parse where output and prefer paths with Windows executable
extensions (.cmd, .exe, .bat, .com).

Related: #935, #863
This commit is contained in:
Ivan
2026-04-03 23:06:55 +03:00
parent 08f1f05d58
commit 921bfbbe3c

View File

@@ -537,7 +537,16 @@ const locateCommand = async (command: string, env: Record<string, string | undef
if (isWindows()) {
const located = await runProcess("where", [command], { env, timeoutMs: 3000 });
if (located.ok && located.stdout) {
return { installed: true, commandPath: command, reason: null };
// `where` may return multiple matches (e.g. `opencode` + `opencode.cmd`).
// npm global installs on Windows create both a Unix shell script (no extension)
// and a .cmd wrapper. We must prefer the Windows executable extension.
const lines = located.stdout
.split(/\r?\n/)
.map((l) => l.trim())
.filter(Boolean);
const winExt = /\.(cmd|exe|bat|com)$/i;
const preferred = lines.find((l) => winExt.test(l)) || lines[0];
return { installed: true, commandPath: preferred, reason: null };
}
return { installed: false, commandPath: null, reason: "not_found" };
}