From 2f0da018db86baed5494537556e57cdf6206c896 Mon Sep 17 00:00:00 2001 From: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com> Date: Mon, 19 Oct 2026 11:52:53 +0800 Subject: [PATCH 1/2] fix(dsh): align Node admission with the LoopX runtime minimum Signed-off-by: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com> --- packages/dsh-loopx-plugin/install.sh | 7 +++-- packages/dsh-loopx-plugin/package.json | 2 +- .../smoke/dsh-peer-range-smoke.mjs | 29 ++++++++++++++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/dsh-loopx-plugin/install.sh b/packages/dsh-loopx-plugin/install.sh index 4439cbe14d..25a0af6751 100755 --- a/packages/dsh-loopx-plugin/install.sh +++ b/packages/dsh-loopx-plugin/install.sh @@ -48,10 +48,11 @@ need node need pnpm node -e ' - const [major, minor] = process.versions.node.split(".").map(Number) - if (!((major === 22 && minor >= 19) || major >= 24)) process.exit(1) + if (!/^\d+\.\d+\.\d+$/.test(process.versions.node)) process.exit(1) + const [major, minor, patch] = process.versions.node.split(".").map(Number) + if (!((major === 22 && (minor > 22 || (minor === 22 && patch >= 3))) || major >= 24)) process.exit(1) ' || { - echo "install: Node.js 22.19+ (excluding Node.js 23) is required" >&2 + echo "install: Node.js 22.22.3+ (excluding Node.js 23 and prereleases) is required" >&2 exit 2 } pnpm_version="$(pnpm --version)" diff --git a/packages/dsh-loopx-plugin/package.json b/packages/dsh-loopx-plugin/package.json index 2ed079a3ca..ed1acc8f17 100644 --- a/packages/dsh-loopx-plugin/package.json +++ b/packages/dsh-loopx-plugin/package.json @@ -46,7 +46,7 @@ "NOTICE" ], "engines": { - "node": "^22.19.0 || >=24.0.0" + "node": "^22.22.3 || >=24.0.0" }, "scripts": { "build": "node scripts/build.mjs", diff --git a/packages/dsh-loopx-plugin/smoke/dsh-peer-range-smoke.mjs b/packages/dsh-loopx-plugin/smoke/dsh-peer-range-smoke.mjs index 561f81b446..0a933453fa 100644 --- a/packages/dsh-loopx-plugin/smoke/dsh-peer-range-smoke.mjs +++ b/packages/dsh-loopx-plugin/smoke/dsh-peer-range-smoke.mjs @@ -4,10 +4,37 @@ import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -import { satisfies, validRange } from 'semver' +import { runInNewContext } from 'node:vm' +import { minVersion, satisfies, validRange } from 'semver' const packageRoot = dirname(dirname(fileURLToPath(import.meta.url))) const manifest = JSON.parse(await readFile(join(packageRoot, 'package.json'), 'utf8')) +const runtimeManifest = JSON.parse(await readFile(join(packageRoot, '../../package.json'), 'utf8')) +assert.equal(minVersion(manifest.engines.node).version, minVersion(runtimeManifest.engines.node).version, + 'the plugin must not advertise a Node version below the LoopX runtime minimum') + +const installer = await readFile(join(packageRoot, 'install.sh'), 'utf8') +const guard = installer.match(/node -e '([\s\S]*?)'\s*\|\|/) +assert(guard, 'the source installer must check Node before installing dependencies') +for (const [version, expected] of [ + ['22.19.0', false], ['22.22.2', false], ['22.22.3-rc.1', false], + ['22.22.3', true], ['22.23.0', true], ['22.23.0-rc.1', false], + ['23.0.0', false], ['24.0.0-rc.1', false], ['24.0.0', true], ['24.20.0', true], +]) { + assert.equal(satisfies(version, manifest.engines.node), expected, `package Node range: ${version}`) + const rejected = Symbol('unsupported Node') + let admitted = true + try { + runInNewContext(guard[1], { process: { + versions: { node: version }, + exit(code) { assert.equal(code, 1); throw rejected }, + } }) + } catch (error) { + if (error !== rejected) throw error + admitted = false + } + assert.equal(admitted, expected, `source installer Node guard: ${version}`) +} for (const [name, range] of Object.entries(manifest.peerDependencies ?? {})) { if (!name.startsWith('@deepseek-ai/')) continue From d0d43cedf75fe2ac134add70399a723f8af85fb1 Mon Sep 17 00:00:00 2001 From: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com> Date: Mon, 19 Oct 2026 11:52:53 +0800 Subject: [PATCH 2/2] docs(dsh): state the supported stable Node prerequisite Signed-off-by: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com> --- packages/dsh-loopx-plugin/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/dsh-loopx-plugin/README.md b/packages/dsh-loopx-plugin/README.md index 085b96c499..0c4619a46c 100644 --- a/packages/dsh-loopx-plugin/README.md +++ b/packages/dsh-loopx-plugin/README.md @@ -36,9 +36,10 @@ deferred atomicity limit are specified in the versioned ## Install -Requirements are Node.js 22.19+, `pnpm`, Python 3.11+ with `pip`, and network -access for the first DSH start when no compatible LoopX CLI is already -installed. LoopX itself is deliberately not a prerequisite. The initializer +Requirements are stable Node.js 22.22.3+ (excluding Node.js 23), `pnpm`, +Python 3.11+ with `pip`, and network access for the first DSH start when no +compatible LoopX CLI is already installed. LoopX itself is deliberately not a +prerequisite. The initializer honors an explicit `PYTHON_BIN`; otherwise it tries `python3`, then discovers `python3.` executables on the supplied `PATH` in descending numeric order, then tries the bare name `python`. The last name is what a python.org