mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
fix: quote Windows UI runner paths
This commit is contained in:
@@ -80,6 +80,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
- UI/Windows: quote resolved pnpm `.cmd` launcher paths before spawning UI install/build/test commands so Node installs under `C:\Program Files` no longer fail as `C:\Program`. Fixes #45275. Thanks @Kobevictor, @stoppieboy, and @iubns.
|
||||||
- Plugins/uninstall: remove tracked plugin files from their recorded managed extensions root even when the current state directory points somewhere else, so `openclaw plugins uninstall --force` does not leave the plugin discoverable. Thanks @shakkernerd.
|
- Plugins/uninstall: remove tracked plugin files from their recorded managed extensions root even when the current state directory points somewhere else, so `openclaw plugins uninstall --force` does not leave the plugin discoverable. Thanks @shakkernerd.
|
||||||
- Agents/runtime: add `agentRuntime.id` as the canonical config key, migrate
|
- Agents/runtime: add `agentRuntime.id` as the canonical config key, migrate
|
||||||
legacy runtime-policy configs with `openclaw doctor --fix`, and route
|
legacy runtime-policy configs with `openclaw doctor --fix`, and route
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ export function assertSafeWindowsShellArgs(args, platform = process.platform) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function prepareSpawnCommand(cmd, platform = process.platform) {
|
||||||
|
return shouldUseShellForCommand(cmd, platform) ? `"${cmd}"` : cmd;
|
||||||
|
}
|
||||||
|
|
||||||
function createSpawnOptions(cmd, args, envOverride) {
|
function createSpawnOptions(cmd, args, envOverride) {
|
||||||
const useShell = shouldUseShellForCommand(cmd);
|
const useShell = shouldUseShellForCommand(cmd);
|
||||||
if (useShell) {
|
if (useShell) {
|
||||||
@@ -92,7 +96,7 @@ function createSpawnOptions(cmd, args, envOverride) {
|
|||||||
function run(cmd, args) {
|
function run(cmd, args) {
|
||||||
let child;
|
let child;
|
||||||
try {
|
try {
|
||||||
child = spawn(cmd, args, createSpawnOptions(cmd, args));
|
child = spawn(prepareSpawnCommand(cmd), args, createSpawnOptions(cmd, args));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Failed to launch ${cmd}:`, err);
|
console.error(`Failed to launch ${cmd}:`, err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@@ -113,7 +117,7 @@ function run(cmd, args) {
|
|||||||
function runSync(cmd, args, envOverride) {
|
function runSync(cmd, args, envOverride) {
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
result = spawnSync(cmd, args, createSpawnOptions(cmd, args, envOverride));
|
result = spawnSync(prepareSpawnCommand(cmd), args, createSpawnOptions(cmd, args, envOverride));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Failed to launch ${cmd}:`, err);
|
console.error(`Failed to launch ${cmd}:`, err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { assertSafeWindowsShellArgs, shouldUseShellForCommand } from "../../scripts/ui.js";
|
import {
|
||||||
|
assertSafeWindowsShellArgs,
|
||||||
|
prepareSpawnCommand,
|
||||||
|
shouldUseShellForCommand,
|
||||||
|
} from "../../scripts/ui.js";
|
||||||
|
|
||||||
describe("scripts/ui windows spawn behavior", () => {
|
describe("scripts/ui windows spawn behavior", () => {
|
||||||
it("enables shell for Windows command launchers that require cmd.exe", () => {
|
it("enables shell for Windows command launchers that require cmd.exe", () => {
|
||||||
@@ -14,6 +18,16 @@ describe("scripts/ui windows spawn behavior", () => {
|
|||||||
expect(shouldUseShellForCommand("/usr/local/bin/pnpm", "linux")).toBe(false);
|
expect(shouldUseShellForCommand("/usr/local/bin/pnpm", "linux")).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("quotes Windows shell launcher paths before passing them to spawn", () => {
|
||||||
|
expect(prepareSpawnCommand("C:\\Program Files\\nodejs\\pnpm.cmd", "win32")).toBe(
|
||||||
|
'"C:\\Program Files\\nodejs\\pnpm.cmd"',
|
||||||
|
);
|
||||||
|
expect(prepareSpawnCommand("C:\\Program Files\\nodejs\\pnpm.exe", "win32")).toBe(
|
||||||
|
"C:\\Program Files\\nodejs\\pnpm.exe",
|
||||||
|
);
|
||||||
|
expect(prepareSpawnCommand("/usr/local/bin/pnpm", "linux")).toBe("/usr/local/bin/pnpm");
|
||||||
|
});
|
||||||
|
|
||||||
it("allows safe forwarded args when shell mode is required on Windows", () => {
|
it("allows safe forwarded args when shell mode is required on Windows", () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
assertSafeWindowsShellArgs(["run", "build", "--filter", "@openclaw/ui"], "win32"),
|
assertSafeWindowsShellArgs(["run", "build", "--filter", "@openclaw/ui"], "win32"),
|
||||||
|
|||||||
Reference in New Issue
Block a user