feat(cli)!: drop Node 20, require Node >= 22.12 - #538
Conversation
Node 20 is EOL (2026-04-30). The new floor matches commander 15's engine requirement, so the later commander major needs no second engines change. The runtime guard reads engines from the manifest, so the refusal message updates itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Point the Node-too-old refusal at the remote no-Node setup too
Pre-existing: the Node-floor refusal labels deploy/local/README.md as 'the' no-Node manual setup, but the bound failure also hits users running the CLI in remote/VPS mode, who need the deploy/remote manual instead. A misdirected user follows a local bind-mount walkthrough and discovers the remote deployment path only later. Failure scenario: A user on Node 18.19.0 runs Suggested fixEmit both no-Node paths (or point at the project README that routes to both):
```ts
const requiredNodeVersion = minimumNodeVersion(engines.node)
if (!satisfiesMinimum(process.versions.node, requiredNodeVersion)) {
console.error(
`vault-cortex requires Node.js >= ${requiredNodeVersion} (you have ${process.versions.node}).\n` +
`Upgrade at https://nodejs.org — or use a no-Node manual setup:\n` +
` local: https://github.com/aliasunder/vault-cortex/blob/main/deploy/local/README.md\n` +
` remote: https://github.com/aliasunder/vault-cortex/blob/main/deploy/remote/README.md`,
)
process.exit(1)
}
```umm-actually · deepseek/deepseek-v4-flash-0731 |
|
umm-actually re-reviewed at No new findings (3 tracked finding(s) across all runs). Context notes
umm-actually · deepseek/deepseek-v4-flash-0731 |
The message named only the local guide; a remote-mode user was misdirected to a bind-mount walkthrough. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Valid — fixed in 3eca710: the refusal now lists both no-Node setups, labeled Posted by Claude Code |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (11)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe CLI minimum Node.js version changes from 20.12 to 22.12. CI removes Node 20 smoke tests. CLI error guidance and setup documentation are updated to match. ChangesCLI Node.js version update
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The CLI now requires Node.js 22.12 or newer, clearly directs unsupported users to local and remote no-Node setup options, and documents and tests the supported Node 22 and 24 runtimes. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The toThrow assertion used a substring ('Cannot parse engines range')
instead of the full deterministic message including the input value.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extract the message into node-version.ts — the zero-import module the entry guard already loads before any dependency-laden import — so the version string and both no-Node setup links cannot silently drift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The matrix's 22 row resolved to the newest 22.x, so the engines floor's API surface never ran in CI. The label keeps the required-check contexts at the major, so the ruleset survives future floor bumps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The refusal branch never executes on supported majors, so no CI job ran it; the floor row now re-runs the built CLI on Node 20 and asserts nonzero exit, the floor in the message, and both setup pointers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Drops Node 20 (EOL 2026-04-30) from the CLI's supported runtimes. The engines floor moves to
>=22.12.0— commander 15's engine requirement — so the eventual commander major bump needs no second engines change. No current dependency requires more.cli/package.jsonengines>=20.12.0→>=22.12.0. The runtime guard inbin.tsreads the manifest, so the refusal message updates itself.local:/remote:) and lives asnodeVersionRefusalMessage()innode-version.ts— the zero-import module the guard loads before any dependency-laden import — pinned by an exact-match unit test.ci.ymlcli-smoke: the floor row pins Node22.12(the engines floor line) via a matrixincludewith a separatelabel, keeping the required-check contexts stable atcli-smoke (22)/cli-smoke (24); the floor row also re-runs the built CLI on Node 20 and asserts the refusal shape (nonzero exit, floor in the message, both setup pointers).CONTRIBUTING.mdrequired-checks list updated:cli-smoke (20)removed, count is now seven; cli-smoke bullet describes the floor row and refusal smoke. Themainruleset's required status checks were updated to match, so open PRs are not blocked on a check that no longer reports.dependabot.ymlcommander-ignore comment trimmed: the engine-incompatibility rationale no longer applies after this bump; the version-sync and deliberate-major rationale stays (the ignore itself is unchanged).>= 20.12→>= 22.12inREADME.md,deploy/local/README.md,deploy/remote/README.md, andcli/README.md.DOCKERHUB.mdregenerated as a verified no-op (it carries no Node version).Tests
npm test— thenode-version.test.tsdrift pin proves the22.12.0floor against the real manifest (fails if either side drifts), andnodeVersionRefusalMessageis exact-match tested (mutation-checked: dropping the remote pointer fails the named test). One pre-existing failure unrelated to this change: the OAuth sliding-expiry test, which fails locally on a DST-crossing wall clock and passes in CI (UTC).cli-smoke (22)floor row runs the built CLI on Node 20 and asserts nonzero exit plus the full refusal shape; the snippet was verified underbash -ein both directions (passes on refusal, fails if the CLI runs).prettier:check,lint,markdownlint,knip, andnpm run build(server + cli + sst) all green.test:cli-pty(runs on Node 24 incli_release.ymlbefore any publish; it exercises prompt flows under the repo toolchain, not the runtime floor).Live beta validation
Published
0.13.2-beta.66from this branch and validated against the real registry artifact:npx vault-cortex@beta --helpwith Node 20.20.2 first onPATH→ exit 1, refusal names the22.12.0floor and both setup guides. Same result running the extracted tarball'sdist/bin.jsdirectly under Node 20.npx vault-cortex@beta --versionunder Node 24.18.0 →0.13.2-beta.66.npx vault-cortex@beta init --yesunder Node 22.20.0 → scaffolds.envand prints the connect block normally.engines: { node: ">=22.12.0" }(verified vianpm view).BREAKING CHANGE: the CLI now requires Node.js >= 22.12. On Node 20 it exits with an upgrade message instead of running. The server image is unaffected.
🤖 Generated with Claude Code