mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-24 11:24:49 +08:00
fix(bundle): bundle Node 24.21.0 so Windows commands no longer abort as they exit (#2806)
Root cause: every release bundles the Node that scripts/build-bundle.sh defaults to, since the release workflow passes only the target, and that default was v24.16.0. On Windows that Node can abort just as the process exits, after the command's work is done: a V8 worker posts a delayed task after the platform's delayed-task scheduler has started closing its uv_async handle, and libuv fails "Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94" with status 0xC0000409 (nodejs/node issue 56645). Node fixed it in 24.20.0 (nodejs/node PR 61999). Fix: the default moves to v24.21.0, the newest 24.x LTS release that is at least two weeks old (2026-09-07). It also carries the Windows 8.3 short-path file-watcher fix (nodejs/node PR 65118). V8 13.6.233.17, libuv 1.52.1 and the module ABI (137, N-API 10) are unchanged; SQLite goes from 3.53.0 to 3.53.4. A comment at the default says why it must stay on 24.x at 24.20.0 or later, and a test pins that, along with the workflow passing only the target. Validation, on Windows 11 x64: - Node's own regression test for the crash (test-process-exit-after-fetch-throw.js, from the v24.21.0 tag), 300 runs per arm, against the official win-x64 node.exe of each version (zips checked against nodejs.org's SHASUMS256.txt): v24.16.0 aborted 300/300 with 0xC0000409 and that async.c line 94 assertion, and the test as written failed 300/300; v24.21.0 passed 300/300. With the launchers' --liftoff-only both passed 300/300, since that flag only removes this test's trigger. - build-bundle.sh win32-x64 builds the bundle on this machine. Its node.exe is byte-identical to the official v24.21.0 one. --version through the Git Bash launcher, cmd and PowerShell, then init, status, query, callers and sync on a small TypeScript and Python project all exit 0, on the wasm path and with the native kernel bundled. - The real CLI (index, status -j, sync) run 300 times per runtime on the bundled app: 0 nonzero exits on either. - The runtime-facing test files (WASM flags, node:sqlite backend and open errors, launchers, worker teardown, version check) pass under Node 24.21.0: 9 files, 65 passed, 3 skipped (POSIX-only). - The new test fails on main's script (expected 16 to be greater than or equal to 20) and passes with the fix. Fixes #2617 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
89cd08fab8
commit
c4dbc126b0
@@ -47,6 +47,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
- The shared background server is no longer killed with "Main thread unresponsive" while it brings another project's index up to date, such as one a session names with `projectPath`: only its own project's index counted as progress, so a long update of any other looked like a hang, and the server was stopped and restarted again and again. Every index the server keeps up to date now counts, and so does the one a session updates on its own when the background server is unavailable. Thanks @mradwankhalil for the report and the first fix. (#2404)
|
||||
- An index left incomplete by an indexing run that was stopped partway, by a crash, an out-of-memory kill or the server's own hang check, no longer gets the background server killed with "Main thread unresponsive" every time it starts: on a large project, restoring the database indexes the run had set aside took longer than the hang check allows, so each restart died at the same point and the index was never repaired. They are now restored in the background, and the project is served once they are back. Thanks @cbeaulieu-gt for the report and the first fix. (#1887)
|
||||
- A new agent session no longer waits up to about 12 minutes for its first answer when the background server is stuck: a server whose process still holds its connection open but never responds made the session wait out a long series of retries. The session now gives up within seconds and answers on its own, and switches back to the background server once that has been restarted.
|
||||
- On Windows, a command like `codegraph sync` no longer sometimes crashes as it exits, after its work is done, printing `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)`, which made a script or CI run that had succeeded fail. The bundled Node runtime moves to 24.21.0, which fixes that crash in Node itself. Thanks @Ancienttwo for the report and the first fix. (#2617)
|
||||
- When CodeGraph can't open a project's database, it now says what went wrong: SQLite's error, the file's path, and what to check, such as another program holding the file open, a folder you can't write to, or a network share. Before, every such failure read "CodeGraph requires node:sqlite (Node.js 22.5+)", and an agent was told no project was loaded. That hint now appears only when Node really can't load its built-in SQLite, a case that used to end in an unhandled error instead.
|
||||
- `codegraph upgrade` no longer wipes your agent instructions file, such as a global `AGENTS.md`, `CLAUDE.md` or `GEMINI.md`, when it refreshes CodeGraph's section in it: a stray `<!-- CODEGRAPH_START -->` line above that section, like one left behind when part of an older section was deleted by hand, made the refresh replace everything in between, often the whole file. CodeGraph now rewrites only its own section, in `codegraph install` and `codegraph uninstall` too, and keeps everything around it exactly as it was, Windows line endings included. Thanks @pzaj2 for the report. (#2506)
|
||||
- `codegraph install`, `upgrade` and `uninstall` now write through an instructions or config file that is a symbolic link, such as a `~/.codex/AGENTS.md` or `~/.claude.json` linked from your dotfiles, instead of replacing the link with a copy: the shared file gets CodeGraph's settings, uninstall takes them out again, and the link stays in place. A link CodeGraph can't write through, like one to a read-only file or into a folder that doesn't exist, is now reported by name and left alone, and an upgrade still refreshes your other agents. Thanks @jguerra6 for the report and @danusha2345 for the first fix. (#2721)
|
||||
|
||||
@@ -122,3 +122,23 @@ describe('bundled launchers (#1278)', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('bundled Node runtime (#2617)', () => {
|
||||
it('ships a Node 24 release with the fix for the Windows abort at exit', () => {
|
||||
// The release workflow passes only the target, so the recipe's default
|
||||
// version is the Node every release bundles.
|
||||
const workflow = fs.readFileSync(path.resolve('.github/workflows/release.yml'), 'utf8');
|
||||
const calls = workflow.match(/build-bundle\.sh[^\r\n]*/g) ?? [];
|
||||
expect(calls.length).toBeGreaterThan(0);
|
||||
for (const call of calls) expect(call.trim()).toBe('build-bundle.sh "$t"');
|
||||
|
||||
const pin = /^NODE_VERSION="\$\{2:-v(\d+)\.(\d+)\.(\d+)\}"\r?$/m.exec(recipe);
|
||||
expect(pin, 'default NODE_VERSION in scripts/build-bundle.sh').not.toBeNull();
|
||||
const [major, minor] = pin!.slice(1, 3).map(Number);
|
||||
// The CLI refuses to run on Node 25 and later.
|
||||
expect(major).toBe(24);
|
||||
// Node 24 before 24.20.0 can abort on Windows as the process exits, after
|
||||
// the command's work is done (0xC0000409, nodejs/node#56645).
|
||||
expect(minor).toBeGreaterThanOrEqual(20);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# scripts/build-bundle.sh <target> [node-version]
|
||||
# target: darwin-arm64 | darwin-x64 | linux-x64 | linux-arm64
|
||||
# | win32-x64 | win32-arm64
|
||||
# node-version: e.g. v24.16.0 (default below; pin for reproducible builds)
|
||||
# node-version: e.g. v24.21.0 (default below; pin for reproducible builds)
|
||||
#
|
||||
# Output:
|
||||
# unix: release/codegraph-<target>.tar.gz (launcher: bin/codegraph)
|
||||
@@ -21,7 +21,13 @@
|
||||
set -euo pipefail
|
||||
|
||||
TARGET="${1:?usage: build-bundle.sh <target> [node-version]}"
|
||||
NODE_VERSION="${2:-v24.16.0}"
|
||||
# The release workflow passes no version, so this default is the Node every
|
||||
# release bundles. Keep it on 24.x (the CLI refuses Node 25+) and at 24.20.0 or
|
||||
# later: older 24.x releases can abort on Windows just as the process exits,
|
||||
# after its work is done, with 0xC0000409 and "Assertion failed:
|
||||
# !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c" (nodejs/node#56645,
|
||||
# fixed by nodejs/node#61999 in 24.20.0; issue #2617).
|
||||
NODE_VERSION="${2:-v24.21.0}"
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
OUT="$ROOT/release"
|
||||
|
||||
Reference in New Issue
Block a user