diff --git a/BUNDLING.md b/BUNDLING.md index 8cba33099..dc21ab531 100644 --- a/BUNDLING.md +++ b/BUNDLING.md @@ -50,7 +50,9 @@ linux/amd64`). bundles ship as per-platform `optionalDependencies` (`@colbymchenry/codegraph-` with `os`/`cpu`), so npm installs only 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 install.sh (detect arch, pull the `.zip` from Releases, add to PATH). 4. **Homebrew / Scoop** — TODO (tap + cask pointing at the Release archives). diff --git a/CHANGELOG.md b/CHANGELOG.md index 20a2b9bc8..b544414b3 100644 --- a/CHANGELOG.md +++ b/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/) and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.9.2] - 2026-05-21 ### 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 projects (via a `drupal/*` dependency in `composer.json`) and adds three 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 [#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 - **`.codegraph/config.json` and the entire config surface.** Every field was 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. 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 ### 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 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.0] - 2026-05-21 diff --git a/package-lock.json b/package-lock.json index d96712a0d..493424966 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@colbymchenry/codegraph", - "version": "0.9.1", + "version": "0.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@colbymchenry/codegraph", - "version": "0.9.1", + "version": "0.9.2", "license": "MIT", "dependencies": { "@clack/prompts": "^1.3.0", diff --git a/package.json b/package.json index fdd591851..4ea932150 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "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.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/scripts/npm-shim.js b/scripts/npm-shim.js index e12f6fb7a..bea905f38 100755 --- a/scripts/npm-shim.js +++ b/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 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 { - 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) { process.stderr.write( 'codegraph: no prebuilt bundle for ' + target + '.\n' + @@ -35,7 +47,7 @@ try { 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) { process.stderr.write('codegraph: ' + res.error.message + '\n'); process.exit(1);