Skip to content

Commit c41559a

Browse files
colbymchenryclaude
andauthored
fix(installer): Windows npm launcher EINVAL on modern Node (#289) (#292)
The npm thin-installer shim spawned the per-platform bundle's `.cmd` launcher directly. Modern Node on Windows refuses to spawn `.cmd`/`.bat` without `shell: true` (the CVE-2024-27980 hardening), so every `codegraph` command failed with `spawnSync …\codegraph.cmd EINVAL` (seen on Node 24). On Windows the shim now invokes the bundled `node.exe` against the app entry point directly, bypassing the `.cmd` (and avoiding the arg-quoting pitfalls of `shell: true`). Unix is unchanged. Validated end-to-end against a real win32-x64 bundle: `npm install` of the packed tarballs + `codegraph init -i`/`status` run on the bundled Node 24. Also cuts release 0.9.2, rolling up the pending Drupal, zero-config, config-removal, Hermes-installer, and symlink-security changes. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f6772da commit c41559a

5 files changed

Lines changed: 46 additions & 9 deletions

File tree

BUNDLING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ linux/amd64`).
5050
bundles ship as per-platform `optionalDependencies`
5151
(`@colbymchenry/codegraph-<target>` with `os`/`cpu`), so npm installs only the
5252
matching one. The shim — run by the user's Node — execs the bundle, so the
53-
real work runs on the bundled Node 24. Works even on old Node.
53+
real work runs on the bundled Node 24. Works even on old Node. On Windows it
54+
invokes the bundled `node.exe` against the app entry directly (not the `.cmd`
55+
launcher) — modern Node throws `EINVAL` when asked to spawn a `.cmd`/`.bat`.
5456
3. **Windows** ([`install.ps1`](install.ps1)) — `irm … | iex`; same flow as
5557
install.sh (detect arch, pull the `.zip` from Releases, add to PATH).
5658
4. **Homebrew / Scoop** — TODO (tap + cask pointing at the Release archives).

CHANGELOG.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ a [GitHub Release](https://github.com/colbymchenry/codegraph/releases) tagged
77
This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
88
and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10-
## [Unreleased]
10+
## [0.9.2] - 2026-05-21
1111

1212
### Added
13+
- **Installer target: Hermes Agent (Nous Research).** `codegraph install` now
14+
supports Hermes Agent — it writes the `mcp_servers.codegraph` entry and ensures
15+
`platform_toolsets.cli` includes `mcp-codegraph` in `$HERMES_HOME/config.yaml`,
16+
so Hermes can drive the CodeGraph knowledge graph like the other agents.
1317
- **Framework support: Drupal 8/9/10/11** — CodeGraph now detects Drupal
1418
projects (via a `drupal/*` dependency in `composer.json`) and adds three
1519
levels of intelligence:
@@ -42,6 +46,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4246
those names; now `.gitignore` is the single source of truth. Resolves
4347
[#283](https://github.com/colbymchenry/codegraph/issues/283).
4448

49+
### Fixed
50+
- **Windows: `npm i -g @colbymchenry/codegraph` then any `codegraph` command
51+
failed with `spawnSync …\codegraph.cmd EINVAL`.** The npm launcher spawned the
52+
bundle's `.cmd` file directly, which modern Node refuses to do on Windows
53+
(the CVE-2024-27980 hardening — seen on Node 24). The launcher now invokes the
54+
bundled `node.exe` against the app directly, so `codegraph` works on Windows
55+
regardless of your Node version. Resolves
56+
[#289](https://github.com/colbymchenry/codegraph/issues/289).
57+
4558
### Removed
4659
- **`.codegraph/config.json` and the entire config surface.** Every field was
4760
either inert or now redundant with `.gitignore`:
@@ -60,6 +73,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6073
exports are gone. Existing `.codegraph/config.json` files are simply ignored.
6174
The `.codegraphignore` marker is no longer supported — use `.gitignore`.
6275

76+
### Security
77+
- **MCP session marker no longer follows symlinks** (CWE-59). Every
78+
`codegraph_context` call writes a `codegraph-consulted-*` marker into the
79+
system temp dir; the previous write followed symlinks, so on a multi-user
80+
system another local user could pre-plant that path as a symlink and redirect
81+
the write onto a victim-writable file. The marker is now opened with
82+
`O_NOFOLLOW` and mode `0600`, and a planted symlink is refused rather than
83+
followed. Resolves [#280](https://github.com/colbymchenry/codegraph/issues/280).
84+
6385
## [0.9.1] - 2026-05-21
6486

6587
### Fixed
@@ -71,6 +93,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7193
find its bundle. The release pipeline now verifies every package reached the
7294
registry (and is idempotent), so a release can't pass green-but-broken again.
7395

96+
[0.9.2]: https://github.com/colbymchenry/codegraph/releases/tag/v0.9.2
7497
[0.9.1]: https://github.com/colbymchenry/codegraph/releases/tag/v0.9.1
7598

7699
## [0.9.0] - 2026-05-21

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@colbymchenry/codegraph",
3-
"version": "0.9.1",
3+
"version": "0.9.2",
44
"description": "Supercharge Claude Code with semantic code intelligence. 94% fewer tool calls • 77% faster exploration • 100% local.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

scripts/npm-shim.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,23 @@ var childProcess = require('child_process');
1919

2020
var target = process.platform + '-' + process.arch; // e.g. darwin-arm64, linux-x64
2121
var pkg = '@colbymchenry/codegraph-' + target;
22-
var launcher = process.platform === 'win32' ? 'bin/codegraph.cmd' : 'bin/codegraph';
22+
var isWindows = process.platform === 'win32';
2323

24-
var binPath;
24+
// On Windows the bundle's launcher is a .cmd batch file. Modern Node refuses to
25+
// spawn .cmd/.bat directly — spawnSync throws EINVAL (the CVE-2024-27980
26+
// hardening, observed on Node 24). So on Windows we skip the .cmd and invoke the
27+
// bundled node.exe against the app entry point directly. On unix the bin launcher
28+
// is a shell script that spawns cleanly.
29+
var command, args;
2530
try {
26-
binPath = require.resolve(pkg + '/' + launcher);
31+
if (isWindows) {
32+
command = require.resolve(pkg + '/node.exe');
33+
var entry = require.resolve(pkg + '/lib/dist/bin/codegraph.js');
34+
args = [entry].concat(process.argv.slice(2));
35+
} else {
36+
command = require.resolve(pkg + '/bin/codegraph');
37+
args = process.argv.slice(2);
38+
}
2739
} catch (e) {
2840
process.stderr.write(
2941
'codegraph: no prebuilt bundle for ' + target + '.\n' +
@@ -35,7 +47,7 @@ try {
3547
process.exit(1);
3648
}
3749

38-
var res = childProcess.spawnSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
50+
var res = childProcess.spawnSync(command, args, { stdio: 'inherit' });
3951
if (res.error) {
4052
process.stderr.write('codegraph: ' + res.error.message + '\n');
4153
process.exit(1);

0 commit comments

Comments
 (0)