Skip to content

Commit 31b43a5

Browse files
authored
Windows: load native addon from immutable per-user cache (#156)
* fix(native): cache Windows addon outside npm installs * fix: synchronize native dependency lockfile * fix(native): close cache publication race
1 parent 1495cd5 commit 31b43a5

36 files changed

Lines changed: 2421 additions & 56 deletions

PUBLISHING.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,22 @@ npm publish
121121

122122
The root package should be published last so its optional native dependency points at the final native meta version.
123123

124+
## Windows Native Cache Validation
125+
126+
Before publishing a cache-enabled release:
127+
128+
- package both `win32-x64-msvc` and `win32-arm64-msvc` target artifacts;
129+
- run `npm run test:native` on Windows, including the live-process source-rename integration test;
130+
- install the packed root package into a synthetic or disposable prefix and confirm `codegraph doctor` reports `native.origin.mode` as `cache`;
131+
- verify a cache-loaded process remains healthy while its synthetic package source is renamed;
132+
- verify a global update succeeds while a cache-enabled MCP process remains alive;
133+
- verify the old process reports restart required and a new process reports the new version and cache key;
134+
- state the one-time stop-update-restart requirement in the first cache-enabled release notes.
135+
136+
Do not claim updates are universally lock-free. The supported claim is that Codegraph no longer maps the npm-owned native addon; antivirus, backup tools, and stale npm retirement paths can still cause `EBUSY`.
137+
124138
## Release Notes
125139

126140
- `@lzehrung/codegraph` and `@lzehrung/codegraph-native` version independently.
127-
- `src/native/treeSitterNative.ts` prefers the installed `@lzehrung/codegraph-native` package and falls back to the local workspace package for development.
128-
- If a native binary or query is unavailable at runtime, Codegraph degrades to reduced graph-only and regex recovery mode.
141+
- `src/native/bindingLoader.ts` loads a local workspace binary directly, caches installed Windows binaries, and uses the installed native package directly on other platforms or as a safe fallback.
142+
- If the cache is unavailable, Codegraph records the cache error and preserves the existing native package fallback; if native loading or a query remains unavailable, it degrades to reduced graph-only and regex recovery mode.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ codegraph doctor
7777

7878
Published installs resolve the optional native runtime automatically when a compatible artifact exists. See [Installation](./docs/installation.md) for registry setup, release tarballs, local global installs, and native runtime modes.
7979

80+
On Windows, installed releases load the native addon from a verified per-user cache so long-running MCP servers do not keep npm's package copy mapped. The first upgrade from an older direct-loading release still requires one stop-update-restart cycle; see [Updating on Windows](./docs/installation.md#updating-on-windows).
81+
8082
## A useful first five minutes
8183

8284
Do not begin by generating every possible report. Start with the question you actually have.

codegraph-skill/codegraph/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,7 @@ codegraph doctor
190190
```
191191

192192
Do not suggest the unscoped `codegraph` package. Published installs resolve the optional native runtime when a compatible artifact exists; otherwise Codegraph reports reduced graph-only and regex recovery behavior rather than semantic parity.
193+
194+
On Windows, installed releases load native code from `%LOCALAPPDATA%\codegraph\native-cache\v1`. The first upgrade from an older direct-loading release requires closing Codegraph MCP clients once, running `npm install -g @lzehrung/codegraph@latest`, and restarting the clients.
195+
196+
Use `codegraph doctor` to inspect `native.origin`, cache fallback errors, stale `.codegraph-*` npm retirement siblings, and installed-versus-running version drift. Do not delete reported paths or kill Node/IDE processes automatically; restart the owning client explicitly, and only clean obsolete cache entries after every process using them has stopped.

docs/cli.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ codegraph skill doctor
579579
580580
`codegraph skill install --agent <name>` supports `agents`, `codex`, `claude`, `cursor`, `gemini`, and `opencode`. Skill install targets must end with `skills/codegraph`; when that safe target shape is satisfied, the installer creates the directory as needed. Cursor CLI now supports native skills directories too, so `.cursor/skills/codegraph` works alongside the universal `~/.agents/skills/codegraph` location. `codegraph -v`, `codegraph version --json`, and `codegraph doctor` include or identify the installed package version so local tarball or source-checkout installs can confirm which build the `codegraph` command is actually running. `doctor` also reports backend/runtime state and optional artifact details, including `artifactBundle` details for directories with a Codegraph `manifest.json`.
581581
582+
`doctor.native.origin` reports `workspace`, `package`, or `cache`, plus normalized source and loaded paths when known. Cache origins include the target, package version, cache key, SHA-256, and `updateSafeForCurrentProcess`; a package fallback retains `cacheError` instead of treating cache preparation failure as native unavailability.
583+
584+
`doctor.native.update` reports bounded, normalized `staleRetirementPaths`, `runningVersion`, `installedVersion`, `restartRequired`, and an optional reason. Doctor never deletes retirement paths, cache entries, or running processes.
585+
582586
## Incremental git-scoped runs
583587
584588
Use `--changed-since <ref>` or `--git-base <ref> [--git-head <ref>]` with `graph` and `index` to limit processing to the files reported by `git diff`.

docs/how-it-works.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ For supported source languages, language definitions provide a Tree-sitter gramm
2828

2929
In the normal `auto` runtime mode, the native addon performs this Tree-sitter parse and query work when available. TypeScript code owns discovery, normalization, resolution, graph assembly, semantic operations, and output formatting, so native acceleration does not change the public result contract.
3030

31+
### Windows installed-runtime cache
32+
33+
On Windows, an installed Codegraph package resolves the platform `.node` file without loading it, hashes it with a bounded streaming buffer, and publishes the verified bytes to `%LOCALAPPDATA%\codegraph\native-cache\v1`. Each cache entry is keyed by platform target, package version, and SHA-256; concurrent processes converge on one immutable final file without overwriting mapped binaries.
34+
35+
The loader requires the cached path and records both the package-owned source and loaded origin. Local workspace builds bypass this cache so rebuilding `packages/codegraph-native` still takes effect immediately, while non-Windows installed packages keep their existing package loader.
36+
3137
### Opt-in: `--fast-graph`
3238

3339
`--fast-graph` bypasses native import queries only for plain `.js` and `.ts` files and extracts their module specifiers with a lightweight text matcher instead. TSX and other parser-backed languages keep their normal extraction path, and other analysis work can still require parsed syntax.

docs/installation.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ Important: the tarball alone does not bundle the native addon. To analyze source
6767

6868
Without the native runtime package, the CLI and library still install, but supported source languages run in reduced graph-only and regex recovery mode.
6969

70+
## Updating on Windows
71+
72+
Installed Windows releases copy the resolved native addon to `%LOCALAPPDATA%\codegraph\native-cache\v1` and load the verified cached copy. Cache entries are content-addressed and immutable, so an existing MCP process can keep using its old entry while npm replaces package-owned files.
73+
74+
The first upgrade from a release that loaded the addon directly requires one transition:
75+
76+
1. Close or disconnect Codegraph MCP clients.
77+
2. Run `npm install -g @lzehrung/codegraph@latest`.
78+
3. Restart the clients and run `codegraph doctor`.
79+
80+
Later upgrades should not be blocked solely because Codegraph mapped npm's native addon. Antivirus, backup software, or stale npm retirement directories can still cause `EBUSY`; `codegraph doctor` reports matching `.codegraph-*` siblings without deleting them.
81+
82+
An MCP server that survives an update continues running its captured version and warns when the installed version differs. Restart that client or shared server to use the new JavaScript runtime and native cache identity.
83+
84+
Old cache entries are inert after every process using them has stopped. Cleanup must be explicit: close Codegraph clients first, then remove only obsolete version/hash directories under the fixed `v1` cache root; never overwrite or delete a mapped entry in place.
85+
7086
## Native runtime modes
7187

7288
The runtime defaults to `native: "auto"`.

docs/mcp.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ The shared HTTP endpoint is `http://127.0.0.1:7331/mcp`. HTTP binds to `127.0.0.
3131

3232
Use stdio for a client-owned subprocess. Use HTTP for one long-running Codegraph process per repository, then point every MCP-capable IDE, terminal, or agent client at the same local URL. Exact config keys vary by client, but the MCP settings should use HTTP/Streamable HTTP transport plus the `/mcp` URL instead of a `command`/`args` stdio launch.
3333

34+
## Runtime identity and updates
35+
36+
The MCP initialize response advertises the Codegraph package version captured when the server starts. The server checks its captured package metadata path at most once every 30 seconds during tool calls; a changed or temporarily unavailable installation produces a deduplicated stderr warning but does not fail the request or terminate the server.
37+
38+
On Windows, installed-package servers map the verified native addon from `%LOCALAPPDATA%\codegraph\native-cache\v1`, not from npm's package directory. An old server may therefore remain healthy after npm installs a new release, but it must be restarted to use the new JavaScript runtime and cache identity.
39+
40+
Run `codegraph doctor` in the installed release to inspect `native.origin`, `native.update`, and any stale npm retirement siblings. `updateSafeForCurrentProcess` describes only the process running doctor; it does not prove that no other process or filesystem service holds a package file.
41+
3442
## Tools
3543

3644
The server exposes the same bounded primitives as the CLI and library session layer:

docs/plans/2026-07-03-03-shared-server-lifecycle.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ codegraph server stop --root .
1818

1919
Keep `codegraph mcp serve` as the low-level primitive. `server start` is a convenience wrapper around it.
2020

21+
Shared servers use the immutable Windows native cache described in [`2026-07-12-windows-native-runtime-cache-updates.md`](./2026-07-12-windows-native-runtime-cache-updates.md). Their registry and health output must preserve the version captured at server start, surface installed-version drift, and require an explicit restart rather than replacing mapped runtime files or terminating clients automatically.
22+
2123
## Server registry
2224

2325
Store only process metadata:

docs/plans/2026-07-03-13-upgrade-command.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ codegraph upgrade 1.9.0
1616

1717
Start with a conservative implementation that detects install channel and prints exact commands. Do not self-modify global installs in the first PR unless the channel is a self-contained bundle installed by our own installer.
1818

19+
This command depends on the immutable Windows native runtime cache and runtime-version diagnostics in [`2026-07-12-windows-native-runtime-cache-updates.md`](./2026-07-12-windows-native-runtime-cache-updates.md). For npm installs it may report readiness and invoke npm only with explicit consent; it must not kill MCP hosts or replace npm as install authority.
20+
1921
Install channels:
2022

2123
- source checkout

0 commit comments

Comments
 (0)