build: raise Node 22 compatibility floor to 22.16

This commit is contained in:
Altay
2026-03-12 15:24:54 +03:00
committed by Ayaan Zaidi
parent deada7edd3
commit 0a8d2b6200
17 changed files with 35 additions and 35 deletions

View File

@@ -56,7 +56,7 @@ describe("resolvePreferredNodePath", () => {
const execFile = vi
.fn()
.mockResolvedValueOnce({ stdout: "18.0.0\n", stderr: "" }) // execPath too old
.mockResolvedValueOnce({ stdout: "22.12.0\n", stderr: "" }); // system node ok
.mockResolvedValueOnce({ stdout: "22.16.0\n", stderr: "" }); // system node ok
const result = await resolvePreferredNodePath({
env: {},
@@ -73,7 +73,7 @@ describe("resolvePreferredNodePath", () => {
it("ignores execPath when it is not node", async () => {
mockNodePathPresent(darwinNode);
const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" });
const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" });
const result = await resolvePreferredNodePath({
env: {},
@@ -93,8 +93,8 @@ describe("resolvePreferredNodePath", () => {
it("uses system node when it meets the minimum version", async () => {
mockNodePathPresent(darwinNode);
// Node 22.12.0+ is the minimum required version
const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" });
// Node 22.16.0+ is the minimum required version
const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" });
const result = await resolvePreferredNodePath({
env: {},
@@ -111,8 +111,8 @@ describe("resolvePreferredNodePath", () => {
it("skips system node when it is too old", async () => {
mockNodePathPresent(darwinNode);
// Node 22.11.x is below minimum 22.12.0
const execFile = vi.fn().mockResolvedValue({ stdout: "22.11.0\n", stderr: "" });
// Node 22.15.x is below minimum 22.16.0
const execFile = vi.fn().mockResolvedValue({ stdout: "22.15.0\n", stderr: "" });
const result = await resolvePreferredNodePath({
env: {},
@@ -168,7 +168,7 @@ describe("resolveStableNodePath", () => {
it("resolves versioned node@22 formula to opt symlink", async () => {
mockNodePathPresent("/opt/homebrew/opt/node@22/bin/node");
const result = await resolveStableNodePath("/opt/homebrew/Cellar/node@22/22.12.0/bin/node");
const result = await resolveStableNodePath("/opt/homebrew/Cellar/node@22/22.16.0/bin/node");
expect(result).toBe("/opt/homebrew/opt/node@22/bin/node");
});
@@ -218,8 +218,8 @@ describe("resolveSystemNodeInfo", () => {
it("returns supported info when version is new enough", async () => {
mockNodePathPresent(darwinNode);
// Node 22.12.0+ is the minimum required version
const execFile = vi.fn().mockResolvedValue({ stdout: "22.12.0\n", stderr: "" });
// Node 22.16.0+ is the minimum required version
const execFile = vi.fn().mockResolvedValue({ stdout: "22.16.0\n", stderr: "" });
const result = await resolveSystemNodeInfo({
env: {},
@@ -229,7 +229,7 @@ describe("resolveSystemNodeInfo", () => {
expect(result).toEqual({
path: darwinNode,
version: "22.12.0",
version: "22.16.0",
supported: true,
});
});

View File

@@ -16,16 +16,16 @@ describe("runtime-guard", () => {
});
it("compares versions correctly", () => {
expect(isAtLeast({ major: 22, minor: 12, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe(
expect(isAtLeast({ major: 22, minor: 16, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe(
true,
);
expect(isAtLeast({ major: 22, minor: 13, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe(
expect(isAtLeast({ major: 22, minor: 17, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe(
true,
);
expect(isAtLeast({ major: 22, minor: 11, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe(
expect(isAtLeast({ major: 22, minor: 15, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe(
false,
);
expect(isAtLeast({ major: 21, minor: 9, patch: 0 }, { major: 22, minor: 12, patch: 0 })).toBe(
expect(isAtLeast({ major: 21, minor: 9, patch: 0 }, { major: 22, minor: 16, patch: 0 })).toBe(
false,
);
});
@@ -33,11 +33,11 @@ describe("runtime-guard", () => {
it("validates runtime thresholds", () => {
const nodeOk: RuntimeDetails = {
kind: "node",
version: "22.12.0",
version: "22.16.0",
execPath: "/usr/bin/node",
pathEnv: "/usr/bin",
};
const nodeOld: RuntimeDetails = { ...nodeOk, version: "22.11.0" };
const nodeOld: RuntimeDetails = { ...nodeOk, version: "22.15.0" };
const nodeTooOld: RuntimeDetails = { ...nodeOk, version: "21.9.0" };
const unknown: RuntimeDetails = {
kind: "unknown",
@@ -78,7 +78,7 @@ describe("runtime-guard", () => {
const details: RuntimeDetails = {
...detectRuntime(),
kind: "node",
version: "22.12.0",
version: "22.16.0",
execPath: "/usr/bin/node",
};
expect(() => assertSupportedRuntime(runtime, details)).not.toThrow();

View File

@@ -9,7 +9,7 @@ type Semver = {
patch: number;
};
const MIN_NODE: Semver = { major: 22, minor: 12, patch: 0 };
const MIN_NODE: Semver = { major: 22, minor: 16, patch: 0 };
export type RuntimeDetails = {
kind: RuntimeKind;
@@ -88,7 +88,7 @@ export function assertSupportedRuntime(
runtime.error(
[
"openclaw requires Node >=22.12.0.",
"openclaw requires Node >=22.16.0.",
`Detected: ${runtimeLabel} (exec: ${execLabel}).`,
`PATH searched: ${details.pathEnv}`,
"Install Node: https://nodejs.org/en/download",

View File

@@ -310,7 +310,7 @@ function formatLocalSetupError(err: unknown): string {
: undefined,
missing && detail ? `Detail: ${detail}` : null,
"To enable local embeddings:",
"1) Use Node 24 (recommended for installs/updates; Node 22.12+ remains supported)",
"1) Use Node 24 (recommended for installs/updates; Node 22 LTS, currently 22.16+, remains supported)",
missing
? "2) Reinstall OpenClaw (this should install node-llama-cpp): npm i -g openclaw@latest"
: null,