1
0
Эх сурвалжийг харах

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>
Colby Mchenry 1 сар өмнө
parent
commit
c41559a9d0

+ 3 - 1
BUNDLING.md

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

+ 24 - 1
CHANGELOG.md

@@ -7,9 +7,13 @@ a [GitHub Release](https://github.com/colbymchenry/codegraph/releases) tagged
 This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
 This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
 and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 
-## [Unreleased]
+## [0.9.2] - 2026-05-21
 
 
 ### Added
 ### Added
+- **Installer target: Hermes Agent (Nous Research).** `codegraph install` now
+  supports Hermes Agent — it writes the `mcp_servers.codegraph` entry and ensures
+  `platform_toolsets.cli` includes `mcp-codegraph` in `$HERMES_HOME/config.yaml`,
+  so Hermes can drive the CodeGraph knowledge graph like the other agents.
 - **Framework support: Drupal 8/9/10/11** — CodeGraph now detects Drupal
 - **Framework support: Drupal 8/9/10/11** — CodeGraph now detects Drupal
   projects (via a `drupal/*` dependency in `composer.json`) and adds three
   projects (via a `drupal/*` dependency in `composer.json`) and adds three
   levels of intelligence:
   levels of intelligence:
@@ -42,6 +46,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
   those names; now `.gitignore` is the single source of truth. Resolves
   those names; now `.gitignore` is the single source of truth. Resolves
   [#283](https://github.com/colbymchenry/codegraph/issues/283).
   [#283](https://github.com/colbymchenry/codegraph/issues/283).
 
 
+### Fixed
+- **Windows: `npm i -g @colbymchenry/codegraph` then any `codegraph` command
+  failed with `spawnSync …\codegraph.cmd EINVAL`.** The npm launcher spawned the
+  bundle's `.cmd` file directly, which modern Node refuses to do on Windows
+  (the CVE-2024-27980 hardening — seen on Node 24). The launcher now invokes the
+  bundled `node.exe` against the app directly, so `codegraph` works on Windows
+  regardless of your Node version. Resolves
+  [#289](https://github.com/colbymchenry/codegraph/issues/289).
+
 ### Removed
 ### Removed
 - **`.codegraph/config.json` and the entire config surface.** Every field was
 - **`.codegraph/config.json` and the entire config surface.** Every field was
   either inert or now redundant with `.gitignore`:
   either inert or now redundant with `.gitignore`:
@@ -60,6 +73,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
   exports are gone. Existing `.codegraph/config.json` files are simply ignored.
   exports are gone. Existing `.codegraph/config.json` files are simply ignored.
   The `.codegraphignore` marker is no longer supported — use `.gitignore`.
   The `.codegraphignore` marker is no longer supported — use `.gitignore`.
 
 
+### Security
+- **MCP session marker no longer follows symlinks** (CWE-59). Every
+  `codegraph_context` call writes a `codegraph-consulted-*` marker into the
+  system temp dir; the previous write followed symlinks, so on a multi-user
+  system another local user could pre-plant that path as a symlink and redirect
+  the write onto a victim-writable file. The marker is now opened with
+  `O_NOFOLLOW` and mode `0600`, and a planted symlink is refused rather than
+  followed. Resolves [#280](https://github.com/colbymchenry/codegraph/issues/280).
+
 ## [0.9.1] - 2026-05-21
 ## [0.9.1] - 2026-05-21
 
 
 ### Fixed
 ### Fixed
@@ -71,6 +93,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
   find its bundle. The release pipeline now verifies every package reached the
   find its bundle. The release pipeline now verifies every package reached the
   registry (and is idempotent), so a release can't pass green-but-broken again.
   registry (and is idempotent), so a release can't pass green-but-broken again.
 
 
+[0.9.2]: https://github.com/colbymchenry/codegraph/releases/tag/v0.9.2
 [0.9.1]: https://github.com/colbymchenry/codegraph/releases/tag/v0.9.1
 [0.9.1]: https://github.com/colbymchenry/codegraph/releases/tag/v0.9.1
 
 
 ## [0.9.0] - 2026-05-21
 ## [0.9.0] - 2026-05-21

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
 {
   "name": "@colbymchenry/codegraph",
   "name": "@colbymchenry/codegraph",
-  "version": "0.9.1",
+  "version": "0.9.2",
   "lockfileVersion": 3,
   "lockfileVersion": 3,
   "requires": true,
   "requires": true,
   "packages": {
   "packages": {
     "": {
     "": {
       "name": "@colbymchenry/codegraph",
       "name": "@colbymchenry/codegraph",
-      "version": "0.9.1",
+      "version": "0.9.2",
       "license": "MIT",
       "license": "MIT",
       "dependencies": {
       "dependencies": {
         "@clack/prompts": "^1.3.0",
         "@clack/prompts": "^1.3.0",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@colbymchenry/codegraph",
   "name": "@colbymchenry/codegraph",
-  "version": "0.9.1",
+  "version": "0.9.2",
   "description": "Supercharge Claude Code with semantic code intelligence. 94% fewer tool calls • 77% faster exploration • 100% local.",
   "description": "Supercharge Claude Code with semantic code intelligence. 94% fewer tool calls • 77% faster exploration • 100% local.",
   "main": "dist/index.js",
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
   "types": "dist/index.d.ts",

+ 16 - 4
scripts/npm-shim.js

@@ -19,11 +19,23 @@ var childProcess = require('child_process');
 
 
 var target = process.platform + '-' + process.arch; // e.g. darwin-arm64, linux-x64
 var target = process.platform + '-' + process.arch; // e.g. darwin-arm64, linux-x64
 var pkg = '@colbymchenry/codegraph-' + target;
 var pkg = '@colbymchenry/codegraph-' + target;
-var launcher = process.platform === 'win32' ? 'bin/codegraph.cmd' : 'bin/codegraph';
+var isWindows = process.platform === 'win32';
 
 
-var binPath;
+// On Windows the bundle's launcher is a .cmd batch file. Modern Node refuses to
+// spawn .cmd/.bat directly — spawnSync throws EINVAL (the CVE-2024-27980
+// hardening, observed on Node 24). So on Windows we skip the .cmd and invoke the
+// bundled node.exe against the app entry point directly. On unix the bin launcher
+// is a shell script that spawns cleanly.
+var command, args;
 try {
 try {
-  binPath = require.resolve(pkg + '/' + launcher);
+  if (isWindows) {
+    command = require.resolve(pkg + '/node.exe');
+    var entry = require.resolve(pkg + '/lib/dist/bin/codegraph.js');
+    args = [entry].concat(process.argv.slice(2));
+  } else {
+    command = require.resolve(pkg + '/bin/codegraph');
+    args = process.argv.slice(2);
+  }
 } catch (e) {
 } catch (e) {
   process.stderr.write(
   process.stderr.write(
     'codegraph: no prebuilt bundle for ' + target + '.\n' +
     'codegraph: no prebuilt bundle for ' + target + '.\n' +
@@ -35,7 +47,7 @@ try {
   process.exit(1);
   process.exit(1);
 }
 }
 
 
-var res = childProcess.spawnSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
+var res = childProcess.spawnSync(command, args, { stdio: 'inherit' });
 if (res.error) {
 if (res.error) {
   process.stderr.write('codegraph: ' + res.error.message + '\n');
   process.stderr.write('codegraph: ' + res.error.message + '\n');
   process.exit(1);
   process.exit(1);