Fix: keep the node runtime probe clear of cmd.exe metacharacters - #458
Conversation
Volta's Windows shims exec through `cmd /C`, which re-parses the argument list, so the `>=` inside the probe's `node -e` payload was read as output redirection. The command died with "The filename, directory name, or volume label syntax is incorrect" before node started, the guard read that as a missing runtime, and the hook it exists to protect was disabled on every PostToolUse and Stop. A user on a supported Node 24 got a one-time notice telling them to install Node 22, then silence. Clamping with Math.min is the same floor test in the same ES5-only syntax, with no character cmd.exe can claim. Verified through the Volta shim on Node 24.16.0 and 22.18.0 (exit 0) and against a real Node 20.6.1 binary (exit 1), so the floor is unchanged. Adds a regression test asserting no `<`, `>`, or newline reaches any generated `node -e` payload. Upstream cause: volta-cli/volta#1791. Prepared with AI assistance (Claude Code).
There was a problem hiding this comment.
Pull request overview
This PR fixes a Windows-specific failure mode for the design hook runtime guard when node resolves through Volta shims (which execute via cmd /C). The previous node -e probe used >=, which cmd.exe can misinterpret as redirection, causing the probe to fail before Node runs and silently disabling the hook.
Changes:
- Replace the
>=version-floor check in thenode -eprobe with a clamp-based check (Math.min(... ) === floor) that avoidscmd.exe-claimed characters. - Update hook build tests to expect the new probe and assert the probe payload contains no
<,>, or newline characters. - Regenerate and commit the affected hook manifest artifacts so they reflect the corrected probe.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
scripts/lib/transformers/hooks.js |
Updates the shared NODE_PROBE string used to guard hook execution so it avoids cmd.exe redirection metacharacters. |
tests/hook-build.test.mjs |
Updates the expected probe expression and adds an assertion ensuring the probe payload contains no <, >, or newlines. |
plugin/hooks/hooks.json |
Regenerated plugin hook manifest with the updated probe string. |
.claude/settings.json |
Regenerated Claude settings hooks with the updated probe string. |
.codex/hooks.json |
Regenerated Codex hooks with the updated probe string. |
.cursor/hooks.json |
Regenerated Cursor hooks with the updated probe string. |
.github/hooks/impeccable.json |
Regenerated GitHub hooks with the updated probe string. |
.grok/hooks/impeccable.json |
Regenerated Grok hooks with the updated probe string. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Greptile SummaryThis change makes generated hook commands safe for Volta’s Windows cmd.exe shim by replacing the Node-version comparison with a metacharacter-free equivalent. The emitted probes were checked across all hook builders and committed manifests: Node 20 is rejected, Node 22 and 24 are accepted, and no probe contains angle brackets or line breaks. The focused hook-manifest builder tests passed. No defects were found; this is safe to merge. Confidence Score: 5/5
What T-Rex did
Reviews (1): Last reviewed commit: "Fix: keep the node runtime probe clear o..." | Re-trigger Greptile |
pbakausorabdulwahaboneAdjacent to but distinct from #452 and #453: that pair fixes the POSIX
[ ! -f ... ]guard the installer writes incli/bin/commands/skills.mjs. This fixes the>=in thenode -eprobe emitted byscripts/lib/transformers/hooks.js. No shared code, no overlapping files.Summary
The Node guard from #423 probes with
>=:Volta's Windows shims exec through
cmd /C, which claims the>as redirection. The probe fails withThe filename, directory name, or volume label syntax is incorrectand exits 1 before node runs, so the guard reports no usable Node andhook.mjsnever runs.2>/dev/nullhides the error and thenode-unsupportedmarker shows the notice only once, so the hook is silently dead on every PostToolUse and Stop. Upstream: volta-cli/volta#1791.Fix. Clamp instead of compare. Same floor test, same ES5-only syntax, no character cmd.exe can claim:
Verification. Each version pinned with
volta pin, sonoderesolves through the shim:>=The 20.6.1 row shows the old probe returned the right answer for the wrong reason: it never evaluated the version at all.
tests/hook-build.test.mjsgains one assertion that the probe carries no character cmd.exe re-parses. The suite already asserts every manifest command containsNODE_PROBE, so that covers all seven builders.The six regenerated manifests are included because the generated command string is the artifact being fixed, and
hook-build.test.mjsasserts committed manifests match the builders.Type of change
Checklist
source/(nosource/dir in the repo today; the source change isscripts/lib/transformers/hooks.js)bun run buildran successfullybun testpasses (green in CI on Node 22.12.0 and 24; a local Windows run has pre-existing symlink-EPERM and path-separator failures that reproduce identically on unmodifiedmain)CLAUDE_PROJECT_DIRset; probe passed andhook.mjsexecuted)Note
Low Risk
Localized change to hook shell command strings and build output; same version floor semantics, with lower risk on Windows Volta/cmd paths.
Overview
Fixes silent hook failure on Windows when Node is launched through Volta shims (and similar
cmd /Cpaths): the runtime guard’snode -eprobe used>=, which cmd.exe treats as redirection, so the probe exited before Node ran and manifests behaved as if no supported Node was on PATH.The probe in
scripts/lib/transformers/hooks.jsnow uses a clamp (Math.min(...)===22) with the same Node 22 floor and ES5-only syntax, but without<,>, or newlines in the one-line-epayload. All six regenerated hook manifests (Claude, Codex, Cursor, GitHub, Grok, plugin) pick up the new command string.tests/hook-build.test.mjsupdates the sharedNODE_PROBEexpectation and adds a test that the probe contains no cmd.exe-unsafe characters; existing checks still require every manifest command to include that probe.Reviewed by Cursor Bugbot for commit 9c5e38b. Bugbot is set up for automated code reviews on this repo. Configure here.