gitnexus 1.6.6-rc.2 → 1.6.6-rc.3

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.
@@ -12,6 +12,7 @@ import { execFileSync } from 'child_process';
12
12
  import v8 from 'v8';
13
13
  import cliProgress from 'cli-progress';
14
14
  import { closeLbug } from '../core/lbug/lbug-adapter.js';
15
+ import { isWalCorruptionError, WAL_RECOVERY_SUGGESTION } from '../core/lbug/lbug-config.js';
15
16
  import { getStoragePaths, getGlobalRegistryPath, RegistryNameCollisionError, AnalysisNotFinalizedError, assertAnalysisFinalized, } from '../storage/repo-manager.js';
16
17
  import { getGitRoot, hasGitDir } from '../storage/git.js';
17
18
  import { runFullAnalysis } from '../core/run-analyze.js';
@@ -468,6 +469,16 @@ export const analyzeCommand = async (inputPath, options) => {
468
469
  process.exitCode = 1;
469
470
  return;
470
471
  }
472
+ // WAL corruption — the index file is unreadable. Give a clear recovery
473
+ // path without a confusing stack trace (the native error message alone
474
+ // is enough signal).
475
+ if (isWalCorruptionError(err) || msg.includes('LadybugDB WAL corruption')) {
476
+ cliError(` The GitNexus index has a corrupted WAL file.\n` +
477
+ ` This usually happens when a previous analysis was interrupted mid-write.\n` +
478
+ ` ${WAL_RECOVERY_SUGGESTION}\n`, { recoveryHint: 'wal-corruption' });
479
+ process.exitCode = 1;
480
+ return;
481
+ }
471
482
  // HF download failure — show clean guidance without the raw stack trace.
472
483
  // Checked before writeFatalToStderr so the user sees one focused message
473
484
  // rather than a stack-trace dump followed by a second remediation block.
package/dist/cli/serve.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createServer } from '../server/api.js';
2
2
  import { logger, flushLoggerSync } from '../core/logger.js';
3
3
  import { cliError } from './cli-message.js';
4
+ import { isWalCorruptionError, WAL_RECOVERY_SUGGESTION } from '../core/lbug/lbug-config.js';
4
5
  // Catch anything that would cause a silent exit. Pino v10's default
5
6
  // destination is `sync: false` (SonicBoom buffered) — call
6
7
  // `flushLoggerSync()` between the log and `process.exit(1)` so the crash
@@ -32,7 +33,11 @@ export const serveCommand = async (options) => {
32
33
  await createServer(port, host);
33
34
  }
34
35
  catch (err) {
35
- if (err.code === 'EADDRINUSE') {
36
+ if (isWalCorruptionError(err)) {
37
+ cliError(`\nGitNexus server could not start: the index has a corrupted WAL file.\n` +
38
+ ` ${WAL_RECOVERY_SUGGESTION}\n`, { recoveryHint: 'wal-corruption' });
39
+ }
40
+ else if (err.code === 'EADDRINUSE') {
36
41
  cliError(`\nFailed to start GitNexus server:\n` +
37
42
  ` ${err.message || err}\n\n` +
38
43
  ` Port ${port} is already in use. Either:\n` +
@@ -8,7 +8,7 @@ import lbug from '@ladybugdb/core';
8
8
  import { NODE_TABLES, REL_TABLE_NAME, SCHEMA_QUERIES, EMBEDDING_TABLE_NAME, STALE_HASH_SENTINEL, } from './schema.js';
9
9
  import { streamAllCSVsToDisk } from './csv-generator.js';
10
10
  import { extensionManager } from './extension-loader.js';
11
- import { closeLbugConnection, isDbBusyError, isOpenRetryExhausted, openLbugConnection, waitForWindowsHandleRelease, } from './lbug-config.js';
11
+ import { closeLbugConnection, isDbBusyError, isOpenRetryExhausted, isWalCorruptionError, openLbugConnection, WAL_RECOVERY_SUGGESTION, waitForWindowsHandleRelease, } from './lbug-config.js';
12
12
  import { isVectorExtensionSupportedByPlatform } from '../platform/capabilities.js';
13
13
  import { logger } from '../logger.js';
14
14
  /**
@@ -508,6 +508,22 @@ const doInitLbug = async (dbPath) => {
508
508
  // anyway and any genuine cross-process lock contention surfaces
509
509
  // on the next operation via withLbugDb's retry. Logging it here
510
510
  // would just be noise in CI.
511
+ //
512
+ // WAL corruption: the first DDL write after DB open triggers WAL
513
+ // replay — if the WAL file was left in a corrupt state by an
514
+ // interrupted previous run, the native engine throws here. Rather
515
+ // than logging a WARN and continuing in a broken state, close the
516
+ // DB cleanly and surface an actionable error so the caller (serve,
517
+ // MCP, analyze) can exit with a clear recovery message.
518
+ if (isWalCorruptionError(err)) {
519
+ await safeClose();
520
+ currentDbPath = null;
521
+ ftsLoaded = false;
522
+ vectorExtensionLoaded = false;
523
+ ensuredFTSIndexes.clear();
524
+ throw new Error(`LadybugDB WAL corruption detected at ${dbPath}. ${WAL_RECOVERY_SUGGESTION}\n` +
525
+ ` Original error: ${msg.slice(0, 200)}`);
526
+ }
511
527
  if (!msg.includes('already exists') && !isDbBusyError(err)) {
512
528
  logger.warn(`⚠️ Schema creation warning: ${msg.slice(0, 120)}`);
513
529
  }
@@ -32,7 +32,7 @@ import type lbug from '@ladybugdb/core';
32
32
  * integer; anything invalid falls back to the default.
33
33
  */
34
34
  export declare const LBUG_MAX_DB_SIZE: number;
35
- export declare const WAL_RECOVERY_SUGGESTION = "WAL corruption detected. Run `gitnexus analyze` to rebuild the index.";
35
+ export declare const WAL_RECOVERY_SUGGESTION = "WAL corruption detected. Run `gitnexus analyze --force` to rebuild the index.";
36
36
  export declare function isWalCorruptionError(err: unknown): boolean;
37
37
  type LbugModule = typeof lbug;
38
38
  export interface LbugDatabaseOptions {
@@ -44,7 +44,7 @@ export const LBUG_MAX_DB_SIZE = (() => {
44
44
  })();
45
45
  /** Matches WAL corruption errors from the LadybugDB engine. */
46
46
  const WAL_CORRUPTION_RE = /corrupt(ed)?\s+wal|invalid\s+wal\s+record|wal.*corrupt|checksum.*wal/i;
47
- export const WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `gitnexus analyze` to rebuild the index.';
47
+ export const WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `gitnexus analyze --force` to rebuild the index.';
48
48
  export function isWalCorruptionError(err) {
49
49
  if (!err)
50
50
  return false;
@@ -17,7 +17,7 @@
17
17
  import fs from 'fs/promises';
18
18
  import lbug from '@ladybugdb/core';
19
19
  import { loadFTSExtension } from './lbug-adapter.js';
20
- import { createLbugDatabase, isWalCorruptionError } from './lbug-config.js';
20
+ import { createLbugDatabase, isWalCorruptionError, WAL_RECOVERY_SUGGESTION, } from './lbug-config.js';
21
21
  const pool = new Map();
22
22
  const poolCloseListeners = new Set();
23
23
  /**
@@ -310,8 +310,7 @@ async function doInitLbug(repoId, dbPath) {
310
310
  break;
311
311
  }
312
312
  catch (retryErr) {
313
- throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ` +
314
- `Run \`gitnexus analyze\` to rebuild the index. ` +
313
+ throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ${WAL_RECOVERY_SUGGESTION} ` +
315
314
  `(${retryErr instanceof Error ? retryErr.message : String(retryErr)})`);
316
315
  }
317
316
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.6-rc.2",
3
+ "version": "1.6.6-rc.3",
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",