mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-11-06 12:50:54 -04:00
chore: require Node 24.22.1+ and default to Node 26 (#2365)
Co-authored-by: jatmn <12479882+jatmn@users.noreply.github.com>
This commit is contained in:
@@ -28,7 +28,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
node-version: [22, 24]
|
||||
node-version: ["24.22.1", "26"]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "22"
|
||||
node-version-file: .node-version
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "22"
|
||||
node-version-file: .node-version
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "22"
|
||||
node-version-file: .node-version
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "22"
|
||||
node-version-file: .node-version
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -191,7 +191,7 @@ jobs:
|
||||
timeout-minutes: 5
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ["22", "24.11.x"]
|
||||
node-version: ["24.22.1", "26"]
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
@@ -243,7 +243,7 @@ jobs:
|
||||
- name: Set up minimum supported Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "22.0.0"
|
||||
node-version: "24.22.1"
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
@@ -314,7 +314,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
node-version-file: .node-version
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
|
||||
@@ -30,8 +30,8 @@ jobs:
|
||||
release-type: node
|
||||
|
||||
# Zero-warning install gate: pack the release tag and install it globally in
|
||||
# a sandbox (cold + upgrade scenarios) on the supported Node floor (22 →
|
||||
# npm 10) and current (24 → npm 11), whose warning output differs. Publish
|
||||
# a sandbox (cold + upgrade scenarios) on the supported Node floor (24.22.1)
|
||||
# and current (26), both shipping npm 11. Publish
|
||||
# is blocked unless the real `npm install -g` experience is clean.
|
||||
install-verify:
|
||||
name: Verify clean npm install (Node ${{ matrix.node-version }})
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [22, 24]
|
||||
node-version: ["24.22.1", "26"]
|
||||
steps:
|
||||
- name: Checkout release tag
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: 24
|
||||
node-version-file: .node-version
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
- name: Set up Bun
|
||||
@@ -110,7 +110,7 @@ jobs:
|
||||
run: bun run smoke
|
||||
|
||||
# Final install-hygiene gate on the publishing machine itself (the
|
||||
# install-verify job covered Node 22/24 already); packs with
|
||||
# install-verify job covered Node 24.22.1/26 already); packs with
|
||||
# --ignore-scripts to reuse the dist/ built above. Supersedes the old
|
||||
# `npm pack --dry-run` (contents are asserted inside the verify).
|
||||
- name: Verify zero-warning global install
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
22
|
||||
26
|
||||
|
||||
@@ -6,7 +6,7 @@ This guide is for AI coding agents working in the OpenClaude repository. Read it
|
||||
|
||||
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
|
||||
|
||||
The installed CLI runs on Node.js `>=22.0.0`. Bun is used for source builds, scripts, dependency management, and tests.
|
||||
The installed CLI runs on Node.js `>=24.22.1` (Node 26 recommended/default). Bun is used for source builds, scripts, dependency management, and tests.
|
||||
|
||||
## Work Style
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ pkg install nodejs-lts git proot-distro
|
||||
|
||||
Verify Node.js:
|
||||
```bash
|
||||
node --version # should be v20+
|
||||
node --version # requires v24.22.1 or newer; Node 26 recommended/default
|
||||
```
|
||||
|
||||
### Step 3 — Clone OpenClaude
|
||||
|
||||
+2
-2
@@ -211,7 +211,7 @@ When submitting provider changes:
|
||||
|
||||
## Local Setup
|
||||
|
||||
Use Node.js `>=22.0.0` and Bun `1.4.4` (tracked in `.bun-version`).
|
||||
Use Node.js `>=24.22.1` (Node 26 recommended/default) and Bun `1.4.4` (tracked in `.bun-version`).
|
||||
|
||||
Install dependencies:
|
||||
|
||||
@@ -320,7 +320,7 @@ Notes on the local preflight:
|
||||
- `bun run test` runs test files in a shared process and requires Bun's completed JUnit report as well as a successful exit. `test:full` runs all eight native Bun shards serially to release memory between groups. Use `bun run scripts/run-tests.ts --shards=N --shard-index=K` with the same test flags to run only shard K of N. `test:full` then applies the same completion check to the conversation-arc pass and the context-efficiency pass with `HISTORY_SNIP` enabled. Every shard must produce a complete report; a failed shard does not prevent the remaining shards from running. A test that terminates the runner early fails the command, even if it exits with code zero. Each shard has a ten-minute deadline (override with `--shard-timeout-ms=<milliseconds>`), reports its start/end and elapsed time, and kills its process group on timeout or cancellation. A timeout stops the remaining shards and exits nonzero. On Linux, shard output is relayed from temporary regular files; diagnostics remain visible during execution. Temporary reports and logs are removed after the check. CI runs `check:static` in `smoke-and-tests`, runs the eight unit shards as parallel `unit-tests` jobs, and runs each dedicated feature pass once in `dedicated-tests`. Each unit shard builds the CLI before testing. CI caps these jobs at 15 minutes each and the other jobs at five minutes.
|
||||
- Fetching upstream `main` by URL avoids assuming that a fork checkout's `origin` points at Twigpine/openclaude. `FETCH_HEAD` is the fetched upstream tip. The scan deliberately uses local `HEAD` so it includes commits that have not been pushed yet; CI uses the pushed PR head SHA after the push.
|
||||
- The web CI job runs on PRs that change `web/**`, root `package.json` or `bun.lock`, `.bun-version`, or `.github/workflows/pr-checks.yml`, and on every push to `main`. Contributors do not need to run the web suite locally for changes that cannot affect the site.
|
||||
- This preflight covers the same command families as CI, but it does not reproduce CI exactly in one shell. When selected, CI runs static checks with Node 22 available for smoke checks, runs the unit shards and dedicated feature passes under Node 22, separately builds and checks launcher compatibility under Node 22 and 24.11.x, separately builds and launches under exact Node 22.0.0, and executes every job on a clean runner.
|
||||
- This preflight covers the same command families as CI, but it does not reproduce CI exactly in one shell. When selected, CI runs static checks with Node 26 available for smoke checks, runs the unit shards and dedicated feature passes under Node 26, separately builds and checks launcher compatibility under Node 24.22.1 and 26, separately builds and launches under exact Node 24.22.1, and executes every job on a clean runner.
|
||||
|
||||
If a local or GitHub CI check fails, first determine whether the PR owns the failure. Treat a failure as pre-existing only when you can reproduce it on the PR's current base (or link to the same failure on a current `main` CI run) and the PR neither changes the causal surface nor claims to fix that problem.
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# ---- build stage ----
|
||||
FROM node:22-slim AS build
|
||||
FROM node:26-slim AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -28,7 +28,7 @@ RUN bun run build
|
||||
RUN rm -rf node_modules && bun install --frozen-lockfile --production
|
||||
|
||||
# ---- runtime stage ----
|
||||
FROM node:22-slim
|
||||
FROM node:26-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ OpenClaude is also mirrored to Twigpine:
|
||||
|
||||
### Install
|
||||
|
||||
OpenClaude requires Node.js `>=22.0.0` for npm installs and runtime. Bun is
|
||||
OpenClaude requires Node.js `>=24.22.1` for npm installs and runtime (Node 26 recommended/default). Bun is
|
||||
only needed for source builds and local development.
|
||||
|
||||
```bash
|
||||
@@ -489,7 +489,7 @@ and client generation from `src/proto/openclaude.proto`.
|
||||
|
||||
## Development
|
||||
|
||||
Use Node.js `>=22.0.0` and Bun `1.4.4` for source builds.
|
||||
Use Node.js `>=24.22.1` (Node 26 recommended/default) and Bun `1.4.4` for source builds.
|
||||
|
||||
```bash
|
||||
bun install
|
||||
@@ -515,9 +515,8 @@ bun run build
|
||||
bun run benchmark:startup
|
||||
```
|
||||
|
||||
The benchmark requires Node `>=22.8.0`, where the compile-cache API was added;
|
||||
the built OpenClaude launcher continues to support the declared Node `>=22.0.0`
|
||||
runtime range.
|
||||
The benchmark and built OpenClaude launcher require Node `>=24.22.1`;
|
||||
Node 26 is recommended/default.
|
||||
|
||||
The benchmark defaults to 30 separate-process warm runs and 10 isolated
|
||||
empty-cache runs. It reports the median, IQR, MAD, first cache-populating run,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"@smithy/core": "3.24.3",
|
||||
"@smithy/node-http-handler": "4.7.3",
|
||||
"@types/bun": "1.4.4",
|
||||
"@types/node": "25.5.0",
|
||||
"@types/node": "^24.19.2",
|
||||
"@types/react": "19.2.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8.69.0",
|
||||
"@typescript-eslint/parser": "^8.69.0",
|
||||
@@ -539,7 +539,7 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
||||
"@types/node": ["@types/node@24.19.2", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
@@ -1219,7 +1219,7 @@
|
||||
|
||||
"undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="],
|
||||
|
||||
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||
"undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
|
||||
|
||||
"unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
|
||||
|
||||
@@ -1415,6 +1415,8 @@
|
||||
|
||||
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
|
||||
|
||||
"bun-types/undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||
|
||||
"cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"cli-highlight/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="],
|
||||
|
||||
@@ -4,7 +4,7 @@ This guide is for users who want source builds, Bun workflows, provider profiles
|
||||
|
||||
## Install Options
|
||||
|
||||
OpenClaude requires Node.js `>=22.0.0` for npm installs and runtime. Bun is
|
||||
OpenClaude requires Node.js `>=24.22.1` for npm installs and runtime (Node 26 recommended/default). Bun is
|
||||
only required when building or running from source.
|
||||
|
||||
### Option A: npm
|
||||
@@ -424,7 +424,7 @@ the percentage through the OpenClaude launcher. OpenClaude converts
|
||||
`--max-old-space-size-percentage` and
|
||||
`OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_PERCENTAGE` to an explicit
|
||||
`--max-old-space-size` in megabytes so the same command works on every supported
|
||||
Node version, including `22.0.0`:
|
||||
Node version, including `24.22.1`:
|
||||
|
||||
```bash
|
||||
openclaude --max-old-space-size-percentage=50
|
||||
@@ -441,7 +441,7 @@ Heap size precedence, earlier wins:
|
||||
|
||||
Putting the native flag in `NODE_OPTIONS` or
|
||||
`node --max-old-space-size-percentage=…` only works on Node versions that accept
|
||||
that option; Node 22.0.0 rejects it before OpenClaude starts. When a supporting
|
||||
that option. When a supporting
|
||||
Node already applied that native flag, OpenClaude leaves it in place and does
|
||||
not append `8192`. Launcher-only flags (`--max-old-space-size-percentage`,
|
||||
`--max-memory=`) are still stripped so Commander can start. That native-flag
|
||||
@@ -507,7 +507,7 @@ host. Without this variable the behavior is unchanged.
|
||||
| `OLLAMA_BASE_URL` | Ollama only | Optional Ollama server base URL used for model discovery and the signed-in local Web Search proxy. The Ollama provider profile normally supplies the equivalent `OPENAI_BASE_URL`. |
|
||||
| `OLLAMA_API_KEY` | Ollama Web Search only | Enables hosted Ollama search at `https://ollama.com/api/web_search` and acts as a fallback when the configured local Ollama search endpoint is unavailable. |
|
||||
| `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_MB` | No | Explicit V8 old-space heap cap in megabytes for the Node launcher. Used only when `--max-memory`, `--max-old-space-size-percentage`, and `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_PERCENTAGE` are all unset. Default `8192`. |
|
||||
| `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_PERCENTAGE` | No | Size the V8 old-space heap as a percentage (greater than 0, up to 100) of constrained/container memory when Node reports it, otherwise total system RAM. Converted to `--max-old-space-size` so Node 22.0.0 can start. Precedence, earlier wins: `--max-memory` → `--max-old-space-size-percentage` → this variable → `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_MB` → default `8192`. |
|
||||
| `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_PERCENTAGE` | No | Size the V8 old-space heap as a percentage (greater than 0, up to 100) of constrained/container memory when Node reports it, otherwise total system RAM. Converted to `--max-old-space-size` for compatibility across supported Node versions. Precedence, earlier wins: `--max-memory` → `--max-old-space-size-percentage` → this variable → `OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_MB` → default `8192`. |
|
||||
| `CLAUDE_CODE_OPENAI_CONTEXT_WINDOWS` | No | JSON map of OpenAI-compatible model names to context windows, such as `{"custom-model":1000000}`. Use this when a custom provider does not expose context metadata from `/v1/models`. |
|
||||
| `CLAUDE_CODE_OPENAI_MAX_OUTPUT_TOKENS` | No | JSON map of OpenAI-compatible model names to max output tokens, such as `{"custom-model":32768}`. Use this when a custom provider does not expose output-limit metadata from `/v1/models`. |
|
||||
| `OPENCODE_API_KEY` | OpenCode Zen / Go | Shared API key for OpenCode Zen (pay-as-you-go) and OpenCode Go (subscription); get yours from https://opencode.ai |
|
||||
|
||||
@@ -22,7 +22,7 @@ For most first-time users, OpenAI is the easiest option.
|
||||
|
||||
You need:
|
||||
|
||||
1. Node.js 22 LTS or newer installed
|
||||
1. Node.js 24.22.1 or newer (Node 26 recommended/default) installed
|
||||
2. A terminal window
|
||||
3. An API key from your provider, unless you are using a local model like Ollama
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ This guide uses a standard shell such as Terminal, iTerm, bash, or zsh.
|
||||
|
||||
## 1. Install Node.js
|
||||
|
||||
Install Node.js 22 LTS or newer from:
|
||||
Install Node.js 24.22.1 or newer (Node 26 recommended/default) from:
|
||||
|
||||
- `https://nodejs.org/`
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ This guide uses Windows PowerShell.
|
||||
|
||||
## 1. Install Node.js
|
||||
|
||||
Install Node.js 22 LTS or newer from:
|
||||
Install Node.js 24.22.1 or newer (Node 26 recommended/default) from:
|
||||
|
||||
- `https://nodejs.org/`
|
||||
|
||||
|
||||
+2
-2
@@ -107,7 +107,7 @@
|
||||
"@smithy/core": "3.24.3",
|
||||
"@smithy/node-http-handler": "4.7.3",
|
||||
"@types/bun": "1.4.4",
|
||||
"@types/node": "25.5.0",
|
||||
"@types/node": "^24.19.2",
|
||||
"@types/react": "19.2.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8.69.0",
|
||||
"@typescript-eslint/parser": "^8.69.0",
|
||||
@@ -191,7 +191,7 @@
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
"node": ">=24.22.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -34,7 +34,7 @@ if (warmRuns < MIN_WARM_RUNS) {
|
||||
throw new Error(`--warm-runs must be at least ${MIN_WARM_RUNS}`)
|
||||
}
|
||||
if (typeof nodeModule.enableCompileCache !== 'function') {
|
||||
throw new Error(`Node ${process.version} does not expose module.enableCompileCache; the benchmark requires Node >=22.8.0`)
|
||||
throw new Error(`Node ${process.version} does not expose module.enableCompileCache; the benchmark requires Node >=24.22.1`)
|
||||
}
|
||||
if (!existsSync(BUNDLE_PATH) || !statSync(BUNDLE_PATH).isFile()) {
|
||||
throw new Error('dist/cli.mjs is missing; run `bun run build` first')
|
||||
|
||||
@@ -304,7 +304,7 @@ describe('validateRuntimeDependencyContract', () => {
|
||||
})
|
||||
|
||||
describe('validateInstallHygieneFields', () => {
|
||||
const CLEAN = { engines: { node: '>=22.0.0' } }
|
||||
const CLEAN = { engines: { node: '>=24.22.1' } }
|
||||
|
||||
test('passes for a clean manifest', () => {
|
||||
expect(validateInstallHygieneFields(CLEAN).ok).toBe(true)
|
||||
|
||||
@@ -40,7 +40,7 @@ export const RUNTIME_DEPENDENCY_CONTRACT: Readonly<Record<string, string>> = {
|
||||
}
|
||||
|
||||
/** Node range advertised to installers; changing it changes who gets EBADENGINE. */
|
||||
export const ENGINES_NODE_CONTRACT = '>=22.0.0'
|
||||
export const ENGINES_NODE_CONTRACT = '>=24.22.1'
|
||||
|
||||
const EXACT_VERSION_RE = /^\d+\.\d+\.\d+(?:-[\w.]+)?$/
|
||||
|
||||
|
||||
@@ -1048,14 +1048,14 @@ describe('checkNodeVersion', () => {
|
||||
test('reads the Node.js version from the node executable output', () => {
|
||||
const probe = readNodeExecutableVersion(() => ({
|
||||
status: 0,
|
||||
stdout: 'v22.0.0\n',
|
||||
stdout: 'v24.22.1\n',
|
||||
stderr: '',
|
||||
error: undefined,
|
||||
}))
|
||||
|
||||
expect(probe).toEqual({
|
||||
ok: true,
|
||||
version: 'v22.0.0',
|
||||
version: 'v24.22.1',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1064,7 +1064,7 @@ describe('checkNodeVersion', () => {
|
||||
ok: false,
|
||||
label: 'Node.js version',
|
||||
detail:
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=22.0.0. Install Node 22 LTS or newer, then reinstall/re-run OpenClaude.',
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=24.22.1. Install Node 24.22.1 or newer, then reinstall/re-run OpenClaude.',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1080,7 +1080,7 @@ describe('checkNodeVersion', () => {
|
||||
ok: false,
|
||||
label: 'Node.js version',
|
||||
detail:
|
||||
'Unable to run `node --version`: spawn node ENOENT. OpenClaude requires Node.js >=22.0.0 on PATH.',
|
||||
'Unable to run `node --version`: spawn node ENOENT. OpenClaude requires Node.js >=24.22.1 on PATH.',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1089,17 +1089,36 @@ describe('checkNodeVersion', () => {
|
||||
ok: false,
|
||||
label: 'Node.js version',
|
||||
detail:
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=22.0.0. Install Node 22 LTS or newer, then reinstall/re-run OpenClaude.',
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=24.22.1. Install Node 24.22.1 or newer, then reinstall/re-run OpenClaude.',
|
||||
})
|
||||
})
|
||||
|
||||
test('passes supported Node.js versions', () => {
|
||||
expect(checkNodeVersion('22.0.0')).toEqual({
|
||||
expect(checkNodeVersion('24.22.1')).toEqual({
|
||||
ok: true,
|
||||
label: 'Node.js version',
|
||||
detail: '22.0.0',
|
||||
detail: '24.22.1',
|
||||
})
|
||||
})
|
||||
|
||||
test('rejects the patch immediately below the Node.js minimum', () => {
|
||||
expect(checkNodeVersion({ ok: true, version: 'v24.22.0' })).toEqual({
|
||||
ok: false,
|
||||
label: 'Node.js version',
|
||||
detail:
|
||||
'Detected 24.22.0. OpenClaude requires Node.js >=24.22.1. Install Node 24.22.1 or newer, then reinstall/re-run OpenClaude.',
|
||||
})
|
||||
})
|
||||
|
||||
test.each(['v24.22.1', 'v26.12.1'])(
|
||||
'passes the supported probed version %s', version => {
|
||||
expect(checkNodeVersion({ ok: true, version })).toEqual({
|
||||
ok: true,
|
||||
label: 'Node.js version',
|
||||
detail: version.slice(1),
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
describe('sandbox runtime diagnostics', () => {
|
||||
|
||||
@@ -407,7 +407,7 @@ const STATE: State = getInitialState()
|
||||
*
|
||||
* **Runtime Requirement:** Uses Node.js `async_hooks.AsyncLocalStorage`.
|
||||
* Not available in browsers or non-Node JavaScript environments.
|
||||
* SDK consumers must run in OpenClaude's supported Node.js runtime (>=22.0.0).
|
||||
* SDK consumers must run in OpenClaude's supported Node.js runtime (>=24.22.1).
|
||||
*/
|
||||
type SdkContext = {
|
||||
sessionId: SessionId
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '../utils/printFlag.js'
|
||||
|
||||
// Defensive compatibility guard for environments where globalThis.File is
|
||||
// unexpectedly absent. OpenClaude's supported runtime is Node >=22; this is
|
||||
// unexpectedly absent. OpenClaude's supported runtime is Node >=24.22.1; this is
|
||||
// not a Node 18 support guarantee. The guard is harmless on supported Node
|
||||
// versions and prevents undici's module evaluation from throwing in unusual
|
||||
// embedded/runtime setups.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { createHash, randomUUID } from 'node:crypto'
|
||||
import { isAbsolute, posix, win32 } from 'node:path'
|
||||
import {
|
||||
monitorEventLoopDelay,
|
||||
type IntervalHistogram,
|
||||
} from 'node:perf_hooks'
|
||||
import { monitorEventLoopDelay } from 'node:perf_hooks'
|
||||
import { normalizeAbortReason } from './abortReasons.js'
|
||||
import { appendDiagnosticsNoPII } from './diagLogs.js'
|
||||
import { redactHomePath, redactLikelySecrets } from './redaction.js'
|
||||
@@ -117,7 +114,7 @@ let signalAbortEventIds = new WeakMap<AbortSignal, string>()
|
||||
let signalAbortSources = new WeakMap<AbortSignal, string>()
|
||||
let signalStates = new WeakMap<AbortSignal, SignalTraceState>()
|
||||
let errorCausalEventIds = new WeakMap<object, string>()
|
||||
let eventLoopDelay: IntervalHistogram | undefined
|
||||
let eventLoopDelay: ReturnType<typeof monitorEventLoopDelay> | undefined
|
||||
let flushQueue: Promise<void> = Promise.resolve()
|
||||
let retryBatch:
|
||||
| {
|
||||
|
||||
@@ -13,27 +13,27 @@ describe('node runtime contract', () => {
|
||||
new URL('../../package.json', import.meta.url),
|
||||
).json()
|
||||
|
||||
expect(MIN_NODE_MAJOR).toBe(22)
|
||||
expect(MIN_NODE_VERSION).toBe('22.0.0')
|
||||
expect(MIN_NODE_ENGINE_RANGE).toBe('>=22.0.0')
|
||||
expect(MIN_NODE_MAJOR).toBe(24)
|
||||
expect(MIN_NODE_VERSION).toBe('24.22.1')
|
||||
expect(MIN_NODE_ENGINE_RANGE).toBe('>=24.22.1')
|
||||
expect(packageJson.engines.node).toBe(MIN_NODE_ENGINE_RANGE)
|
||||
})
|
||||
|
||||
test('accepts supported Node versions', () => {
|
||||
expect(checkSupportedNodeVersion('v22.0.0')).toEqual({
|
||||
expect(checkSupportedNodeVersion('v24.22.1')).toEqual({
|
||||
ok: true,
|
||||
version: '22.0.0',
|
||||
major: 22,
|
||||
version: '24.22.1',
|
||||
major: 24,
|
||||
})
|
||||
expect(checkSupportedNodeVersion('22.0.0')).toEqual({
|
||||
expect(checkSupportedNodeVersion('24.22.1')).toEqual({
|
||||
ok: true,
|
||||
version: '22.0.0',
|
||||
major: 22,
|
||||
version: '24.22.1',
|
||||
major: 24,
|
||||
})
|
||||
expect(checkSupportedNodeVersion('25.5.0')).toEqual({
|
||||
expect(checkSupportedNodeVersion('26.12.1')).toEqual({
|
||||
ok: true,
|
||||
version: '25.5.0',
|
||||
major: 25,
|
||||
version: '26.12.1',
|
||||
major: 26,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -43,17 +43,38 @@ describe('node runtime contract', () => {
|
||||
version: '20.11.1',
|
||||
major: 20,
|
||||
message:
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=22.0.0. Install Node 22 LTS or newer, then reinstall/re-run OpenClaude.',
|
||||
'Detected 20.11.1. OpenClaude requires Node.js >=24.22.1. Install Node 24.22.1 or newer, then reinstall/re-run OpenClaude.',
|
||||
})
|
||||
})
|
||||
|
||||
test.each(['23.12.0', '24.21.9', '24.22.0', '24.22.1-rc.1'])(
|
||||
'rejects %s below the exact minimum', version => {
|
||||
expect(checkSupportedNodeVersion(version)).toEqual({
|
||||
ok: false,
|
||||
version,
|
||||
major: Number(version.split('.')[0]),
|
||||
message: `Detected ${version}. OpenClaude requires Node.js >=24.22.1. Install Node 24.22.1 or newer, then reinstall/re-run OpenClaude.`,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
test.each(['24.22.1', '24.22.2', '24.23.0', '26.0.0', '26.12.1'])(
|
||||
'accepts %s at or above the exact minimum', version => {
|
||||
expect(checkSupportedNodeVersion(version)).toEqual({
|
||||
ok: true,
|
||||
version,
|
||||
major: Number(version.split('.')[0]),
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
test('rejects malformed Node versions with the same required minimum', () => {
|
||||
expect(checkSupportedNodeVersion('nightly')).toEqual({
|
||||
ok: false,
|
||||
version: 'nightly',
|
||||
major: null,
|
||||
message:
|
||||
'Could not parse Node.js version: nightly. OpenClaude requires Node.js >=22.0.0.',
|
||||
'Could not parse Node.js version: nightly. OpenClaude requires Node.js >=24.22.1.',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const MIN_NODE_MAJOR = 22
|
||||
export const MIN_NODE_VERSION = '22.0.0'
|
||||
import { satisfies } from './semver.js'
|
||||
|
||||
export const MIN_NODE_MAJOR = 24
|
||||
export const MIN_NODE_VERSION = '24.22.1'
|
||||
export const MIN_NODE_ENGINE_RANGE = `>=${MIN_NODE_VERSION}`
|
||||
|
||||
export type NodeVersionCheckResult =
|
||||
@@ -39,12 +41,12 @@ export function checkSupportedNodeVersion(
|
||||
}
|
||||
}
|
||||
|
||||
if (major < MIN_NODE_MAJOR) {
|
||||
if (!satisfies(version, MIN_NODE_ENGINE_RANGE)) {
|
||||
return {
|
||||
ok: false,
|
||||
version,
|
||||
major,
|
||||
message: `Detected ${version}. OpenClaude requires Node.js ${MIN_NODE_ENGINE_RANGE}. Install Node ${MIN_NODE_MAJOR} LTS or newer, then reinstall/re-run OpenClaude.`,
|
||||
message: `Detected ${version}. OpenClaude requires Node.js ${MIN_NODE_ENGINE_RANGE}. Install Node ${MIN_NODE_VERSION} or newer, then reinstall/re-run OpenClaude.`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +237,8 @@ function streamOnOpen(this: StreamState, fd: number): void {
|
||||
})
|
||||
}
|
||||
|
||||
function streamOnData(this: StreamState, chunk: string): void {
|
||||
function streamOnData(this: StreamState, chunk: string | Buffer): void {
|
||||
chunk = typeof chunk === 'string' ? chunk : chunk.toString('utf8')
|
||||
if (this.isFirstChunk) {
|
||||
this.isFirstChunk = false
|
||||
if (chunk.charCodeAt(0) === 0xfeff) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Polyfill for Promise.withResolvers() (ES2024, Node 22+).
|
||||
* Native on every supported runtime now that engines.node is >=22.0.0; kept as a
|
||||
* Native on every supported runtime (engines.node >=24.22.1); kept as a
|
||||
* thin wrapper so call sites stay stable and downstream embeds running older Node
|
||||
* (despite the warning) don't crash.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ OpenClaude originated from the Claude Code codebase and has since been substanti
|
||||
- [Quick start (Windows)](https://github.com/Twigpine/openclaude/blob/main/docs/quick-start-windows.md)
|
||||
- [Non-technical setup](https://github.com/Twigpine/openclaude/blob/main/docs/non-technical-setup.md)
|
||||
- [Android install](https://github.com/Twigpine/openclaude/blob/main/ANDROID_INSTALL.md)
|
||||
- [npm install](https://www.npmjs.com/package/@twigpine/openclaude): `npm install -g @twigpine/openclaude@latest` (requires Node >= 22)
|
||||
- [npm install](https://www.npmjs.com/package/@twigpine/openclaude): `npm install -g @twigpine/openclaude@latest` (requires Node >= 24.22.1; Node 26 recommended/default)
|
||||
- [AUR package: openclaude](https://aur.archlinux.org/packages/openclaude)
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -22,7 +22,7 @@ const toc = [
|
||||
>
|
||||
<h2 id="requirements">requirements</h2>
|
||||
<ul>
|
||||
<li><strong>Node.js 22 or newer</strong> — grab it from <a href="https://nodejs.org/" rel="noopener">nodejs.org</a> and confirm with <code>node --version</code>.</li>
|
||||
<li><strong>Node.js 24.22.1 or newer (Node 26 recommended/default)</strong> — grab it from <a href="https://nodejs.org/" rel="noopener">nodejs.org</a> and confirm with <code>node --version</code>.</li>
|
||||
<li>A terminal: Terminal/iTerm on macOS, any shell on Linux, PowerShell or Windows Terminal on Windows.</li>
|
||||
<li><code>ripgrep</code> is bundled; if startup reports <code>ripgrep not found</code>, install it system-wide and confirm <code>rg --version</code> works.</li>
|
||||
</ul>
|
||||
|
||||
@@ -216,7 +216,7 @@ const jsonLd = [
|
||||
<span class="step-num">01</span>
|
||||
<div>
|
||||
<strong>install</strong>
|
||||
<p>requires node ≥ 22. <a href="/docs/installation/">platform guides →</a></p>
|
||||
<p>requires node ≥ 24.22.1; node 26 recommended/default. <a href="/docs/installation/">platform guides →</a></p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
Reference in New Issue
Block a user