mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:50:43 +00:00
fix(cli): handle Volta shim respawns
This commit is contained in:
@@ -74,6 +74,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Installer/macOS: rerun Homebrew install steps without the gum spinner when raw-mode ioctl failures occur, and avoid claiming `node@24` was installed when the Homebrew keg binary is missing. Fixes #70411. Thanks @1fanwang and @dad-io.
|
||||
- Installer: load nvm before Node.js detection so `curl | bash` installs respect nvm-managed Node instead of stale system Node. Fixes #49556. Thanks @heavenlxj.
|
||||
- CLI/Volta: respawn raw `openclaw` CLI runs through the named `node` shim when the current Node executable resolves to `volta-shim`, avoiding direct shim execution failures in non-interactive shells. Fixes #68672. Thanks @sanchezm86.
|
||||
- Docker: copy patched dependency files into runtime images so downstream `pnpm install` layers keep working. Fixes #69224. Thanks @gucasbrg.
|
||||
- Agents/runtime: submit heartbeat, cron, and exec wakeups as transient runtime context instead of visible user prompts, keeping synthetic system work out of chat transcripts. Fixes #66496 and #66814. Thanks @jeades and @mandomaker.
|
||||
- Telegram: include native quote excerpts automatically for threaded replies and reply tags when the original Telegram text is available, without adding another config knob. Fixes #6975. Thanks @rex05ai.
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
EXPERIMENTAL_WARNING_FLAG,
|
||||
OPENCLAW_NODE_EXTRA_CA_CERTS_READY,
|
||||
OPENCLAW_NODE_OPTIONS_READY,
|
||||
resolveCliRespawnCommand,
|
||||
} from "./entry.respawn.js";
|
||||
|
||||
const shouldSkipRespawnForArgvMock = vi.hoisted(() => vi.fn(() => false));
|
||||
@@ -42,6 +43,7 @@ describe("buildCliRespawnPlan", () => {
|
||||
});
|
||||
|
||||
expect(plan).not.toBeNull();
|
||||
expect(plan?.command).toBe(process.execPath);
|
||||
expect(plan?.argv[0]).toBe(EXPERIMENTAL_WARNING_FLAG);
|
||||
expect(plan?.env.NODE_EXTRA_CA_CERTS).toBe("/etc/ssl/certs/ca-certificates.crt");
|
||||
expect(plan?.env[OPENCLAW_NODE_EXTRA_CA_CERTS_READY]).toBe("1");
|
||||
@@ -88,4 +90,35 @@ describe("buildCliRespawnPlan", () => {
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("respawns Volta shims through node so the shim is not called directly", () => {
|
||||
const plan = buildCliRespawnPlan({
|
||||
argv: ["/home/alice/.volta/bin/volta-shim", "/usr/local/bin/openclaw", "status"],
|
||||
env: { PATH: "/home/alice/.volta/bin:/usr/bin:/bin" },
|
||||
execArgv: [],
|
||||
execPath: "/home/alice/.volta/bin/volta-shim",
|
||||
autoNodeExtraCaCerts: undefined,
|
||||
platform: "linux",
|
||||
});
|
||||
|
||||
expect(plan?.command).toBe("node");
|
||||
expect(plan?.argv).toEqual([EXPERIMENTAL_WARNING_FLAG, "/usr/local/bin/openclaw", "status"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveCliRespawnCommand", () => {
|
||||
it("keeps normal node paths absolute", () => {
|
||||
expect(resolveCliRespawnCommand({ execPath: "/usr/bin/node", platform: "linux" })).toBe(
|
||||
"/usr/bin/node",
|
||||
);
|
||||
});
|
||||
|
||||
it("maps Volta's Unix shim target back to the named node shim", () => {
|
||||
expect(
|
||||
resolveCliRespawnCommand({
|
||||
execPath: "/home/alice/.volta/bin/volta-shim",
|
||||
platform: "linux",
|
||||
}),
|
||||
).toBe("node");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import path from "node:path";
|
||||
import { resolveNodeStartupTlsEnvironment } from "./bootstrap/node-startup-env.js";
|
||||
import { shouldSkipRespawnForArgv } from "./cli/respawn-policy.js";
|
||||
import { isTruthyEnvValue } from "./infra/env.js";
|
||||
@@ -6,6 +7,28 @@ export const EXPERIMENTAL_WARNING_FLAG = "--disable-warning=ExperimentalWarning"
|
||||
export const OPENCLAW_NODE_OPTIONS_READY = "OPENCLAW_NODE_OPTIONS_READY";
|
||||
export const OPENCLAW_NODE_EXTRA_CA_CERTS_READY = "OPENCLAW_NODE_EXTRA_CA_CERTS_READY";
|
||||
|
||||
export type CliRespawnPlan = {
|
||||
command: string;
|
||||
argv: string[];
|
||||
env: NodeJS.ProcessEnv;
|
||||
};
|
||||
|
||||
function pathModuleForPlatform(platform: NodeJS.Platform): typeof path.posix {
|
||||
return platform === "win32" ? path.win32 : path.posix;
|
||||
}
|
||||
|
||||
export function resolveCliRespawnCommand(params: {
|
||||
execPath: string;
|
||||
platform?: NodeJS.Platform;
|
||||
}): string {
|
||||
const platform = params.platform ?? process.platform;
|
||||
const basename = pathModuleForPlatform(platform).basename(params.execPath).toLowerCase();
|
||||
if (basename === "volta-shim" || basename === "volta-shim.exe") {
|
||||
return "node";
|
||||
}
|
||||
return params.execPath;
|
||||
}
|
||||
|
||||
export function hasExperimentalWarningSuppressed(
|
||||
params: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
@@ -30,7 +53,7 @@ export function buildCliRespawnPlan(
|
||||
autoNodeExtraCaCerts?: string | undefined;
|
||||
platform?: NodeJS.Platform;
|
||||
} = {},
|
||||
): { argv: string[]; env: NodeJS.ProcessEnv } | null {
|
||||
): CliRespawnPlan | null {
|
||||
const argv = params.argv ?? process.argv;
|
||||
const env = params.env ?? process.env;
|
||||
const execArgv = params.execArgv ?? process.execArgv;
|
||||
@@ -80,6 +103,7 @@ export function buildCliRespawnPlan(
|
||||
}
|
||||
|
||||
return {
|
||||
command: resolveCliRespawnCommand({ execPath, platform }),
|
||||
argv: [...childExecArgv, ...argv.slice(1)],
|
||||
env: childEnv,
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ if (
|
||||
return false;
|
||||
}
|
||||
|
||||
const child = spawn(process.execPath, plan.argv, {
|
||||
const child = spawn(plan.command, plan.argv, {
|
||||
stdio: "inherit",
|
||||
env: plan.env,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user