gitnexus 1.6.10-rc.93 → 1.6.10-rc.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,10 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { createRequire } from 'node:module';
4
+ import { spawnSync } from 'node:child_process';
5
+ /** Cap the out-of-process native load probe so a hung filesystem cannot wedge a
6
+ * CLI startup gate (same bounding rationale as the extension probe below). */
7
+ const NATIVE_LOAD_PROBE_TIMEOUT_MS = 15_000;
4
8
  export function checkLbugNative(overridePkgDir) {
5
9
  let pkgDir;
6
10
  if (overridePkgDir) {
@@ -51,35 +55,68 @@ export function checkLbugNative(overridePkgDir) {
51
55
  ].join('\n'),
52
56
  };
53
57
  }
54
- try {
55
- const _require = createRequire(import.meta.url);
56
- _require(binaryPath);
58
+ // Validate loadability in a THROWAWAY CHILD PROCESS, not in-process. A merely
59
+ // truncated or corrupted .node (valid header, missing pages) does not throw a
60
+ // catchable error — it SIGBUSes the dynamic loader mid-dlopen, which would take
61
+ // the whole CLI down with a raw exit 135 and no guidance (#2441). Loading it in
62
+ // a child lets us observe that crash (a non-zero exit or a kill signal) and turn
63
+ // it into the same actionable failure as a clean load error. The child requires
64
+ // the binary by absolute path, exactly as the former in-process load did.
65
+ const probe = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', binaryPath], {
66
+ encoding: 'utf8',
67
+ timeout: NATIVE_LOAD_PROBE_TIMEOUT_MS,
68
+ stdio: ['ignore', 'ignore', 'pipe'],
69
+ // Run as Node even if process.execPath is an Electron/embedder binary.
70
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
71
+ });
72
+ // Only a child that actually RAN and failed proves the binary is bad. If the
73
+ // probe could not run at all — a spawn error or a timeout, e.g. a sandbox that
74
+ // forbids subprocesses or a non-Node execPath — we could not test the binary,
75
+ // so we stay out of the way and let the command's own load be the authority
76
+ // rather than condemn a healthy binary. (#2441 still holds: a genuinely broken
77
+ // binary loaded in-process later still exits non-zero.)
78
+ if (probe.error || probe.status === 0) {
79
+ return { ok: true, binaryPath };
57
80
  }
58
- catch (err) {
59
- const nativeError = err instanceof Error ? err.message : String(err);
60
- return {
61
- ok: false,
62
- binaryPath,
63
- message: [
64
- 'LadybugDB native binary (lbugjs.node) exists but failed to load:',
65
- ` ${nativeError}`,
66
- '',
67
- 'This can happen with a truncated file, ABI mismatch, or wrong-platform binary.',
68
- '',
69
- 'To repair:',
70
- ` node ${path.join(pkgDir, 'install.js')}`,
71
- '',
72
- 'If install scripts were skipped (pnpm dlx / pnpx / ignore-scripts):',
73
- ' pnpm --allow-build=@ladybugdb/core --allow-build=gitnexus --allow-build=tree-sitter \\',
74
- ' dlx gitnexus@latest serve',
75
- ' pnpm add -g --allow-build=@ladybugdb/core --allow-build=gitnexus --allow-build=tree-sitter gitnexus',
76
- '',
77
- 'If using bun, add to package.json and reinstall:',
78
- ' "trustedDependencies": ["@ladybugdb/core"]',
79
- ].join('\n'),
80
- };
81
+ return {
82
+ ok: false,
83
+ binaryPath,
84
+ message: [
85
+ 'LadybugDB native binary (lbugjs.node) exists but failed to load:',
86
+ ` ${describeNativeLoadFailure(probe)}`,
87
+ '',
88
+ 'This can happen with a truncated file, ABI mismatch, or wrong-platform binary.',
89
+ '',
90
+ 'To repair:',
91
+ ` node ${path.join(pkgDir, 'install.js')}`,
92
+ '',
93
+ 'If install scripts were skipped (pnpm dlx / pnpx / ignore-scripts):',
94
+ ' pnpm --allow-build=@ladybugdb/core --allow-build=gitnexus --allow-build=tree-sitter \\',
95
+ ' dlx gitnexus@latest serve',
96
+ ' pnpm add -g --allow-build=@ladybugdb/core --allow-build=gitnexus --allow-build=tree-sitter gitnexus',
97
+ '',
98
+ 'If using bun, add to package.json and reinstall:',
99
+ ' "trustedDependencies": ["@ladybugdb/core"]',
100
+ ].join('\n'),
101
+ };
102
+ }
103
+ /**
104
+ * Describe a child-observed native load failure. Reached only after a probe that
105
+ * actually ran and failed: a fatal signal (SIGBUS/SIGSEGV ⇒ truncated/corrupt
106
+ * binary), otherwise the child's own load error lifted from its stderr.
107
+ */
108
+ function describeNativeLoadFailure(probe) {
109
+ if (probe.signal) {
110
+ return `crashed while loading (signal ${probe.signal}) — the binary is likely truncated or corrupted`;
81
111
  }
82
- return { ok: true, binaryPath };
112
+ const lines = (probe.stderr ?? '')
113
+ .split('\n')
114
+ .map((line) => line.trim())
115
+ .filter(Boolean);
116
+ const errorLine = lines.find((line) => /^\w*Error: /.test(line));
117
+ return (errorLine?.replace(/^\w*Error:\s*/, '') ??
118
+ lines.at(-1) ??
119
+ `exited with code ${probe.status ?? 'unknown'}`);
83
120
  }
84
121
  const DEFAULT_FTS_PROBE_TIMEOUT_MS = 10_000;
85
122
  /** Close each result, swallowing close-time errors so a successful LOAD is not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.10-rc.93",
3
+ "version": "1.6.10-rc.95",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",