CLI: expand versioned node argv handling

This commit is contained in:
Gustavo Madeira Santana
2026-01-26 20:29:15 -05:00
committed by Gustavo Madeira Santana
parent c95072fc26
commit 566c9982b3
2 changed files with 59 additions and 6 deletions

View File

@@ -78,6 +78,48 @@ describe("argv helpers", () => {
}); });
expect(nodeArgv).toEqual(["node", "clawdbot", "status"]); expect(nodeArgv).toEqual(["node", "clawdbot", "status"]);
const versionedNodeArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["node-22", "clawdbot", "status"],
});
expect(versionedNodeArgv).toEqual(["node-22", "clawdbot", "status"]);
const versionedNodeWindowsArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["node-22.2.0.exe", "clawdbot", "status"],
});
expect(versionedNodeWindowsArgv).toEqual(["node-22.2.0.exe", "clawdbot", "status"]);
const versionedNodePatchlessArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["node-22.2", "clawdbot", "status"],
});
expect(versionedNodePatchlessArgv).toEqual(["node-22.2", "clawdbot", "status"]);
const versionedNodeWindowsPatchlessArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["node-22.2.exe", "clawdbot", "status"],
});
expect(versionedNodeWindowsPatchlessArgv).toEqual(["node-22.2.exe", "clawdbot", "status"]);
const versionedNodeWithPathArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["/usr/bin/node-22.2.0", "clawdbot", "status"],
});
expect(versionedNodeWithPathArgv).toEqual(["/usr/bin/node-22.2.0", "clawdbot", "status"]);
const nodejsArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["nodejs", "clawdbot", "status"],
});
expect(nodejsArgv).toEqual(["nodejs", "clawdbot", "status"]);
const nonVersionedNodeArgv = buildParseArgv({
programName: "clawdbot",
rawArgs: ["node-dev", "clawdbot", "status"],
});
expect(nonVersionedNodeArgv).toEqual(["node", "clawdbot", "node-dev", "clawdbot", "status"]);
const directArgv = buildParseArgv({ const directArgv = buildParseArgv({
programName: "clawdbot", programName: "clawdbot",
rawArgs: ["clawdbot", "status"], rawArgs: ["clawdbot", "status"],

View File

@@ -96,16 +96,27 @@ export function buildParseArgv(params: {
: baseArgv; : baseArgv;
const executable = (normalizedArgv[0]?.split(/[/\\]/).pop() ?? "").toLowerCase(); const executable = (normalizedArgv[0]?.split(/[/\\]/).pop() ?? "").toLowerCase();
const looksLikeNode = const looksLikeNode =
normalizedArgv.length >= 2 && normalizedArgv.length >= 2 && (isNodeExecutable(executable) || isBunExecutable(executable));
(executable === "node" ||
executable === "node.exe" ||
executable.startsWith("node-") ||
executable === "bun" ||
executable === "bun.exe");
if (looksLikeNode) return normalizedArgv; if (looksLikeNode) return normalizedArgv;
return ["node", programName || "clawdbot", ...normalizedArgv]; return ["node", programName || "clawdbot", ...normalizedArgv];
} }
const nodeExecutablePattern = /^node-\d+(?:\.\d+)*(?:\.exe)?$/;
function isNodeExecutable(executable: string): boolean {
return (
executable === "node" ||
executable === "node.exe" ||
executable === "nodejs" ||
executable === "nodejs.exe" ||
nodeExecutablePattern.test(executable)
);
}
function isBunExecutable(executable: string): boolean {
return executable === "bun" || executable === "bun.exe";
}
export function shouldMigrateStateFromPath(path: string[]): boolean { export function shouldMigrateStateFromPath(path: string[]): boolean {
if (path.length === 0) return true; if (path.length === 0) return true;
const [primary, secondary] = path; const [primary, secondary] = path;