@lzehrung/codegraph 2.3.13 → 2.3.15

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.
Files changed (41) hide show
  1. package/codegraph-skill/codegraph/SKILL.md +1 -1
  2. package/dist/agent/query-index/workerPool.d.ts.map +1 -1
  3. package/dist/agent/query-index/workerPool.js +2 -0
  4. package/dist/agent/query-index/workerPool.js.map +1 -1
  5. package/dist/bin/cli.js +201 -54
  6. package/dist/bin/queryIndexWorker.js +30 -0
  7. package/dist/bin/rawQueryWorker.js +34 -0
  8. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  9. package/dist/indexer/build-cache/project-snapshot.js +39 -22
  10. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  11. package/dist/indexer/build-index.d.ts.map +1 -1
  12. package/dist/indexer/build-index.js +29 -2
  13. package/dist/indexer/build-index.js.map +1 -1
  14. package/dist/indexer/types.d.ts +2 -0
  15. package/dist/indexer/types.d.ts.map +1 -1
  16. package/dist/native/runtime.d.ts.map +1 -1
  17. package/dist/native/runtime.js +2 -0
  18. package/dist/native/runtime.js.map +1 -1
  19. package/dist/sqlite/rawQueryWorkerPool.d.ts.map +1 -1
  20. package/dist/sqlite/rawQueryWorkerPool.js +10 -6
  21. package/dist/sqlite/rawQueryWorkerPool.js.map +1 -1
  22. package/dist/sqlite-driver.d.ts +1 -0
  23. package/dist/sqlite-driver.d.ts.map +1 -1
  24. package/dist/sqlite-driver.js +6 -0
  25. package/dist/sqlite-driver.js.map +1 -1
  26. package/dist/util/git.d.ts +4 -0
  27. package/dist/util/git.d.ts.map +1 -1
  28. package/dist/util/git.js +4 -0
  29. package/dist/util/git.js.map +1 -1
  30. package/dist/util/projectFiles.d.ts +0 -9
  31. package/dist/util/projectFiles.d.ts.map +1 -1
  32. package/dist/util/projectFiles.js +95 -26
  33. package/dist/util/projectFiles.js.map +1 -1
  34. package/dist/util/windowsProcessDrain.d.ts +23 -0
  35. package/dist/util/windowsProcessDrain.d.ts.map +1 -0
  36. package/dist/util/windowsProcessDrain.js +51 -0
  37. package/dist/util/windowsProcessDrain.js.map +1 -0
  38. package/dist/worker/nativeWorkerPool.d.ts.map +1 -1
  39. package/dist/worker/nativeWorkerPool.js +2 -0
  40. package/dist/worker/nativeWorkerPool.js.map +1 -1
  41. package/package.json +3 -3
@@ -134,7 +134,7 @@ Current-state commands validate the on-disk index automatically and default to t
134
134
  - Repeated agent queries over one repo snapshot: prefer MCP so the index stays warm. MCP inputs are flat JSON objects and the server root is fixed at startup; send only fields in the mounted tool schema, never CLI flags such as `--root` or `--json`. Unknown tool fields are rejected as invalid parameters. If the first MCP call fails at startup or loses its transport, do not retry the same server; run `codegraph doctor`, use the equivalent CLI command for this session, and restart the agent client after package upgrades.
135
135
  - Durable graph handoff: use `codegraph graph --root . ./src --json --output codegraph.json` rather than parsing display text. `graph --json` and `index --json` payloads include an `analysis` object (`mode`, `backend`, `label`, fallback counts); when `mode` is `mixed` or `reduced` the run used regex/graph-only extraction for some or all files, so treat symbol accuracy accordingly. Degraded runs also print a `Backend:` warning on stderr even without `--progress`.
136
136
  - Search and inspect performance diagnosis: add `--report` for JSON on stderr or `--report-file <path>` for a file while keeping normal command output unchanged.
137
- - Index discovery diagnosis: `--report` timing JSON can include `sourceDiscoveryMs` and `metadataDiscoveryMs` when those discovery steps run.
137
+ - Index discovery diagnosis: `--report` timing JSON can include `sourceDiscoveryMs`, `metadataDiscoveryMs`, `gitListMs`, `filesystemScanMs`, and `cacheProbeMs` when those steps run.
138
138
 
139
139
  ### Human Graph Viewer
140
140
 
@@ -1 +1 @@
1
- {"version":3,"file":"workerPool.d.ts","sourceRoot":"","sources":["../../../src/agent/query-index/workerPool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyB,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAGlF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAIlE;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAyB,GAAG,OAAO,CAErH;AAMD,wBAAgB,2BAA2B,IAAI,MAAM,CAUpD;AACD,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CAc1C;AAED,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CA0C1C;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CAM1C"}
1
+ {"version":3,"file":"workerPool.d.ts","sourceRoot":"","sources":["../../../src/agent/query-index/workerPool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyB,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAIlF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAIlE;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAyB,GAAG,OAAO,CAErH;AAMD,wBAAgB,2BAA2B,IAAI,MAAM,CAUpD;AACD,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CAc1C;AAED,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CA2C1C;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,GAC9E,OAAO,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,CAM1C"}
@@ -6,6 +6,7 @@ import { findPackageRoot } from "../../util/packageInfo.js";
6
6
  import { prepareQueryIndexFile } from "./content.js";
7
7
  import { resolveQueryIndexSourcePath } from "./paths.js";
8
8
  import { resolveWorkerThreadCount } from "../../util/workerThreads.js";
9
+ import { markWindowsProcessDrainRequired } from "../../util/windowsProcessDrain.js";
9
10
  const QUERY_INDEX_MAX_THREADS = 4;
10
11
  /**
11
12
  * Every worker thread imports the language registry before it can prepare its first file, so a
@@ -66,6 +67,7 @@ export async function prepareQueryIndexFilesInWorker(projectRoot, files) {
66
67
  catch {
67
68
  return await prepareQueryIndexFilesInProcess(projectRoot, files);
68
69
  }
70
+ markWindowsProcessDrainRequired();
69
71
  const pool = new Piscina({
70
72
  filename: workerPath,
71
73
  minThreads: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"workerPool.js","sourceRoot":"","sources":["../../../src/agent/query-index/workerPool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workerPool.js","sourceRoot":"","sources":["../../../src/agent/query-index/workerPool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAA+B,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AAGpF,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAElC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,oCAAoC,CAAC,SAAiB,EAAE,WAAW,GAAG,oBAAoB,EAAE;IAC1G,OAAO,WAAW,GAAG,CAAC,IAAI,SAAS,IAAI,4BAA4B,CAAC;AACtE,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,wBAAwB,CAAC,EAAE,GAAG,EAAE,uBAAuB,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;IAC7D,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;IAC/F,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC7E,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;AACnE,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,WAAmB,EACnB,KAA+E;IAE/E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,YAAY,GAAG,2BAA2B,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACjF,OAAO,MAAM,qBAAqB,CAAC;YACjC,YAAY;YACZ,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;IACF,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,WAAmB,EACnB,KAA+E;IAE/E,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/D,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,2BAA2B,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,+BAA+B,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,+BAA+B,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC;QACvB,QAAQ,EAAE,UAAU;QACpB,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;QAC7C,WAAW,EAAE,MAAM;KACpB,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,KAAK,CAAC,GAAG,CACP,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,GAAG,CAAC;YACP,WAAW;YACX,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;SACL,CAA2C,CAC9E,CACF,CAAC;QACF,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,sFAAsF;QACtF,uFAAuF;QACvF,+EAA+E;QAC/E,qFAAqF;QACrF,qFAAqF;QACrF,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,+BAA+B,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,KAA+E;IAE/E,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC7B,IAAI,CAAC,oCAAoC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,OAAO,MAAM,+BAA+B,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,8BAA8B,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAClE,CAAC"}
package/dist/bin/cli.js CHANGED
@@ -1181,7 +1181,7 @@ function createInteractiveProgressDisplay(write, delayMs = 0) {
1181
1181
  let mode = "build";
1182
1182
  let activity = progressAction(mode);
1183
1183
  let interval;
1184
- let delay;
1184
+ let delay2;
1185
1185
  const clear = () => {
1186
1186
  if (!rendered)
1187
1187
  return;
@@ -1202,9 +1202,9 @@ function createInteractiveProgressDisplay(write, delayMs = 0) {
1202
1202
  clearInterval(interval);
1203
1203
  interval = void 0;
1204
1204
  }
1205
- if (delay !== void 0) {
1206
- clearTimeout(delay);
1207
- delay = void 0;
1205
+ if (delay2 !== void 0) {
1206
+ clearTimeout(delay2);
1207
+ delay2 = void 0;
1208
1208
  }
1209
1209
  };
1210
1210
  const start = (update) => {
@@ -1225,8 +1225,8 @@ function createInteractiveProgressDisplay(write, delayMs = 0) {
1225
1225
  interval.unref();
1226
1226
  };
1227
1227
  if (delayMs) {
1228
- delay = setTimeout(beginRendering, delayMs);
1229
- delay.unref();
1228
+ delay2 = setTimeout(beginRendering, delayMs);
1229
+ delay2.unref();
1230
1230
  } else {
1231
1231
  beginRendering();
1232
1232
  }
@@ -1294,12 +1294,12 @@ function createLogProgressDisplay(write, delayMs = 0) {
1294
1294
  let total = 0;
1295
1295
  let mode = "build";
1296
1296
  let activity = progressAction(mode);
1297
- let delay;
1297
+ let delay2;
1298
1298
  let heartbeat;
1299
1299
  const stopTimers = () => {
1300
- if (delay !== void 0) {
1301
- clearTimeout(delay);
1302
- delay = void 0;
1300
+ if (delay2 !== void 0) {
1301
+ clearTimeout(delay2);
1302
+ delay2 = void 0;
1303
1303
  }
1304
1304
  if (heartbeat !== void 0) {
1305
1305
  clearInterval(heartbeat);
@@ -1330,8 +1330,8 @@ function createLogProgressDisplay(write, delayMs = 0) {
1330
1330
  mode = update.mode ?? "build";
1331
1331
  activity = update.activity ?? `${progressAction(mode)} project index`;
1332
1332
  if (delayMs) {
1333
- delay = setTimeout(renderStart, delayMs);
1334
- delay.unref();
1333
+ delay2 = setTimeout(renderStart, delayMs);
1334
+ delay2.unref();
1335
1335
  } else {
1336
1336
  renderStart();
1337
1337
  }
@@ -14243,10 +14243,6 @@ function isPresent(value) {
14243
14243
  function normalizeGlobPattern(globPattern) {
14244
14244
  return globPattern.trim().replace(/\\/g, "/");
14245
14245
  }
14246
- function defaultIgnoreGitExcludePathspecs(includeGlobs = []) {
14247
- const activeIgnores = includeGlobs.length ? DEFAULT_PROJECT_FILE_IGNORES.filter((ignoreGlob) => !isIgnoreGlobReopenedByIncludes(ignoreGlob, includeGlobs)) : DEFAULT_PROJECT_FILE_IGNORES;
14248
- return activeIgnores.map((globPattern) => `:(exclude,glob)${normalizeGlobPattern(globPattern)}`);
14249
- }
14250
14246
  function couldBeDirectorySymlink(filePath) {
14251
14247
  const basename2 = path9.posix.basename(normalizePath(filePath));
14252
14248
  if (DIRECTORY_METADATA_BASENAMES.has(basename2.toLowerCase()))
@@ -14256,6 +14252,13 @@ function couldBeDirectorySymlink(filePath) {
14256
14252
  return true;
14257
14253
  return DIRECTORY_METADATA_EXTENSIONS.has(extension.toLowerCase());
14258
14254
  }
14255
+ function isProjectMetadataDirectoryName(dirPath) {
14256
+ const basename2 = path9.posix.basename(normalizePath(dirPath));
14257
+ if (DIRECTORY_METADATA_BASENAMES.has(basename2.toLowerCase()))
14258
+ return true;
14259
+ const extension = path9.posix.extname(basename2);
14260
+ return Boolean(extension) && DIRECTORY_METADATA_EXTENSIONS.has(extension.toLowerCase());
14261
+ }
14259
14262
  function globLiteralPrefix(globPattern) {
14260
14263
  const prefix = [];
14261
14264
  let seenLiteral = false;
@@ -14498,29 +14501,81 @@ function collectCandidateAncestorDirectories(root, files) {
14498
14501
  }
14499
14502
  return directories;
14500
14503
  }
14501
- async function findGitIgnoreSources(sourceRoots, excludePathspecs = defaultIgnoreGitExcludePathspecs()) {
14504
+ function owningGitIgnoreSourceRoot(file2, roots) {
14505
+ const normalized = normalizePath(file2);
14506
+ let owning;
14507
+ for (const root of roots) {
14508
+ if (!isFilePathWithinRoot(root.path, normalized) && !isFilePathWithinRoot(root.repositoryRoot, normalized)) {
14509
+ continue;
14510
+ }
14511
+ if (!owning || root.repositoryRoot.length > owning.repositoryRoot.length) {
14512
+ owning = root;
14513
+ }
14514
+ }
14515
+ return owning;
14516
+ }
14517
+ async function gitignoreFileIfPresent(directory) {
14518
+ const file2 = normalizePath(path9.join(directory, ".gitignore"));
14519
+ try {
14520
+ const stat = await fsp5.stat(file2);
14521
+ return stat.isFile() ? file2 : void 0;
14522
+ } catch {
14523
+ return void 0;
14524
+ }
14525
+ }
14526
+ async function findGitIgnoreSources(sourceRoots, candidateFiles) {
14502
14527
  const roots = Array.from(new Map(sourceRoots.map(({ path: sourceRoot, repositoryRoot }) => [
14503
14528
  fileIdentityKey(sourceRoot),
14504
14529
  { path: normalizePath(sourceRoot), repositoryRoot: normalizePath(repositoryRoot) }
14505
14530
  ])).values());
14506
- const sources = [];
14531
+ const directories = /* @__PURE__ */ new Map();
14532
+ const walkedDirectoryKeys = /* @__PURE__ */ new Set();
14533
+ const addDirectory = (directory, repositoryRoot) => {
14534
+ const dir = normalizePath(directory);
14535
+ const key = fileIdentityKey(dir);
14536
+ if (!directories.has(key))
14537
+ directories.set(key, { dir, repositoryRoot: normalizePath(repositoryRoot) });
14538
+ };
14507
14539
  for (const { path: sourceRoot, repositoryRoot } of roots) {
14508
- const [gitignoreFiles, excludeFiles] = await Promise.all([
14509
- listGitIgnoreFiles(sourceRoot, { excludePathspecs }),
14510
- listGitExcludeFiles(sourceRoot)
14511
- ]);
14512
- sources.push(...gitignoreFiles.map((file2) => ({
14513
- file: file2,
14514
- baseDir: path9.dirname(file2),
14515
- repositoryRoot,
14516
- priority: 2
14517
- })));
14518
- sources.push(...excludeFiles.map((source) => ({
14540
+ addDirectory(sourceRoot, repositoryRoot);
14541
+ }
14542
+ for (const file2 of candidateFiles) {
14543
+ const owning = owningGitIgnoreSourceRoot(file2, roots);
14544
+ if (!owning)
14545
+ continue;
14546
+ let dir = normalizePath(path9.dirname(file2));
14547
+ const stopKey = fileIdentityKey(owning.repositoryRoot);
14548
+ for (; ; ) {
14549
+ const dirKey = fileIdentityKey(dir);
14550
+ const walkKey = `${dirKey}\0${stopKey}`;
14551
+ if (walkedDirectoryKeys.has(walkKey))
14552
+ break;
14553
+ addDirectory(dir, owning.repositoryRoot);
14554
+ walkedDirectoryKeys.add(walkKey);
14555
+ if (dirKey === stopKey)
14556
+ break;
14557
+ const parent = normalizePath(path9.dirname(dir));
14558
+ if (parent === dir || !isFilePathWithinRoot(owning.path, parent) && !isFilePathWithinRoot(owning.repositoryRoot, parent)) {
14559
+ break;
14560
+ }
14561
+ dir = parent;
14562
+ }
14563
+ }
14564
+ const uniqueRepositoryRoots = Array.from(new Set(roots.map((root) => root.repositoryRoot)));
14565
+ const [gitignoreHits, excludeLists] = await Promise.all([
14566
+ mapLimitSemaphore(Array.from(directories.values()), REALPATH_FILTER_CONCURRENCY, async ({ dir, repositoryRoot }) => {
14567
+ const file2 = await gitignoreFileIfPresent(dir);
14568
+ return file2 ? [{ file: file2, baseDir: dir, repositoryRoot, priority: 2 }] : [];
14569
+ }),
14570
+ Promise.all(uniqueRepositoryRoots.map((repositoryRoot) => listGitExcludeFiles(repositoryRoot)))
14571
+ ]);
14572
+ return [
14573
+ ...gitignoreHits.flat(),
14574
+ ...excludeLists.flat().map((source) => ({
14519
14575
  ...source,
14520
14576
  repositoryRoot: source.baseDir
14521
- })));
14522
- }
14523
- return sources;
14577
+ }))
14578
+ ];
14524
14579
  }
14525
14580
  async function listGitCandidateFiles(root, logLevel, opts) {
14526
14581
  let gitListStart;
@@ -14570,7 +14625,7 @@ async function listGitCandidateFiles(root, logLevel, opts) {
14570
14625
  emitDiscoveryActivity(opts?.onDiscoveryProgress, "Listing Git ignore files");
14571
14626
  const ignoreStartedAt = performance2.now();
14572
14627
  gitIgnoreStart = ignoreStartedAt;
14573
- const gitignoreFiles = await findGitIgnoreSources(sourceRoots, defaultIgnoreGitExcludePathspecs(opts?.includeGlobs ?? []));
14628
+ const gitignoreFiles = await findGitIgnoreSources(sourceRoots, files);
14574
14629
  emitDiscoveryTiming(opts?.onDiscoveryTiming, "git-ignore", ignoreStartedAt);
14575
14630
  gitIgnoreStart = void 0;
14576
14631
  emitDiscoveryActivity(opts?.onDiscoveryProgress, "Listing Git ignore files", gitignoreFiles.length, gitignoreFiles.length);
@@ -14625,7 +14680,7 @@ async function listProjectFilesInternal(projectRoot, patterns = DEFAULT_PROJECT_
14625
14680
  ...options?.onDiscoveryProgress ? { onDiscoveryProgress: options.onDiscoveryProgress } : {},
14626
14681
  ...options?.onDiscoveryTiming ? { onDiscoveryTiming: options.onDiscoveryTiming } : {}
14627
14682
  };
14628
- const gitCandidates = attemptedGitCandidates ? await listGitCandidateFiles(root, options?.logLevel, { includeGlobs, ...gitDiscoveryCallbacks }) : null;
14683
+ const gitCandidates = attemptedGitCandidates ? await listGitCandidateFiles(root, options?.logLevel, gitDiscoveryCallbacks) : null;
14629
14684
  if (attemptedGitCandidates) {
14630
14685
  options?.onGitCandidatesDiscovered?.(gitCandidates);
14631
14686
  }
@@ -14935,7 +14990,7 @@ async function discoverProjectFilesInternal(projectRoot, options) {
14935
14990
  const candidateFiles = Array.from(new Set(gitCandidates.files.map(normalizePath)));
14936
14991
  const metadataCandidates = candidateFiles.filter((file2) => PROJECT_FILE_DEFINITIONS.some((definition, definitionIndex) => definition.kind === "file" && matchesDefinition(path9.basename(file2), definitionIndex)));
14937
14992
  const fileMatches = filterGitIgnoredEntries(await filterRealPathsWithinRootEntries(metadataCandidates, realRoot, reportMetadataFileChecks));
14938
- const rawCandidateDirectories = collectCandidateAncestorDirectories(root, candidateFiles);
14993
+ const rawCandidateDirectories = collectCandidateAncestorDirectories(root, candidateFiles).filter(isProjectMetadataDirectoryName);
14939
14994
  const candidateDirectoryKeys = new Set(rawCandidateDirectories.map(fileIdentityKey));
14940
14995
  const safeSymlinkDirectoryKeys = new Set(safeSymlinkDirectories.map(fileIdentityKey));
14941
14996
  const directoryMatches = [
@@ -20532,6 +20587,40 @@ var init_bindingLoader = __esm({
20532
20587
  }
20533
20588
  });
20534
20589
 
20590
+ // dist/util/windowsProcessDrain.js
20591
+ function markWindowsProcessDrainRequired() {
20592
+ drainRequired = true;
20593
+ ensureWindowsProcessDrainHook();
20594
+ }
20595
+ function delay(ms) {
20596
+ return new Promise((resolve) => {
20597
+ setTimeout(resolve, ms);
20598
+ });
20599
+ }
20600
+ function ensureWindowsProcessDrainHook() {
20601
+ if (process.platform !== "win32" || beforeExitListener)
20602
+ return;
20603
+ beforeExitListener = () => {
20604
+ void drainWindowsProcessHandles();
20605
+ };
20606
+ process.once("beforeExit", beforeExitListener);
20607
+ }
20608
+ async function drainWindowsProcessHandles(options) {
20609
+ const platform = options?.platform ?? process.platform;
20610
+ const required2 = options?.required ?? drainRequired;
20611
+ if (platform !== "win32" || !required2)
20612
+ return;
20613
+ await (options?.wait ?? delay)(WINDOWS_LIBUV_EXIT_DRAIN_MS);
20614
+ }
20615
+ var WINDOWS_LIBUV_EXIT_DRAIN_MS, drainRequired, beforeExitListener;
20616
+ var init_windowsProcessDrain = __esm({
20617
+ "dist/util/windowsProcessDrain.js"() {
20618
+ "use strict";
20619
+ WINDOWS_LIBUV_EXIT_DRAIN_MS = 100;
20620
+ drainRequired = false;
20621
+ }
20622
+ });
20623
+
20535
20624
  // dist/native/runtime.js
20536
20625
  import fs14 from "node:fs";
20537
20626
  import path25 from "node:path";
@@ -20560,6 +20649,7 @@ function loadBinding() {
20560
20649
  });
20561
20650
  if (loaded.binding) {
20562
20651
  const supportedLanguageIds = new Set(loaded.binding.supportedLanguageIds());
20652
+ markWindowsProcessDrainRequired();
20563
20653
  bindingState = {
20564
20654
  loaded: true,
20565
20655
  binding: loaded.binding,
@@ -20784,6 +20874,7 @@ var init_runtime = __esm({
20784
20874
  init_ast();
20785
20875
  init_bindingLoader();
20786
20876
  init_runtimeCache();
20877
+ init_windowsProcessDrain();
20787
20878
  require2 = createRequire2(import.meta.url);
20788
20879
  localNativePackageRoot = path25.resolve(path25.dirname(fileURLToPath2(import.meta.url)), "../../packages/codegraph-native");
20789
20880
  NATIVE_REQUIRED_ERROR_PREFIX = "native tree-sitter required by explicit option but unavailable";
@@ -32017,6 +32108,7 @@ var init_sqlite_driver = __esm({
32017
32108
  "dist/sqlite-driver.js"() {
32018
32109
  "use strict";
32019
32110
  init_errors();
32111
+ init_windowsProcessDrain();
32020
32112
  requireNodeModule = createRequire4(import.meta.url);
32021
32113
  reportedReadonlyAuthorizerDegradation = false;
32022
32114
  READONLY_AUTHORIZER_CONSTANTS = [
@@ -32075,6 +32167,7 @@ var init_sqlite_driver = __esm({
32075
32167
  SqliteDatabase = class {
32076
32168
  db;
32077
32169
  statements = /* @__PURE__ */ new Map();
32170
+ closed = false;
32078
32171
  constructor(filePath, options) {
32079
32172
  if (!isNodeSqliteUsable()) {
32080
32173
  throw nodeSqliteUnavailableError() ?? new Error("node:sqlite is unavailable");
@@ -32084,6 +32177,7 @@ var init_sqlite_driver = __esm({
32084
32177
  readOnly: options?.readonly,
32085
32178
  timeout: options?.timeout ?? 5e3
32086
32179
  });
32180
+ markWindowsProcessDrainRequired();
32087
32181
  if (options?.readonly) {
32088
32182
  const { constants: constants2 } = sqlite;
32089
32183
  if (this.db.setAuthorizer && canInstallReadonlyAuthorizer(constants2)) {
@@ -32128,8 +32222,11 @@ var init_sqlite_driver = __esm({
32128
32222
  };
32129
32223
  }
32130
32224
  close() {
32225
+ if (this.closed)
32226
+ return;
32131
32227
  this.statements.clear();
32132
32228
  this.db.close();
32229
+ this.closed = true;
32133
32230
  }
32134
32231
  };
32135
32232
  }
@@ -53066,6 +53163,23 @@ function isSymbolEdge(value) {
53066
53163
  const edge = value;
53067
53164
  return typeof edge.from === "string" && typeof edge.to === "string" && (edge.label === void 0 || typeof edge.label === "string") && (edge.site === void 0 || !!edge.site && typeof edge.site === "object" && typeof edge.site.file === "string" && !!edge.site.file && isDetailedRange(edge.site.range));
53068
53165
  }
53166
+ function sameSymbolNodeSemantics(actual, expected) {
53167
+ return actual.file === expected.file && actual.name === expected.name && actual.kind === expected.kind && actual.docstring === expected.docstring && actual.lineSpan === expected.lineSpan && actual.complexity === expected.complexity;
53168
+ }
53169
+ function indexDefinesSymbolNode(index, node) {
53170
+ const moduleEntry = index.byFile.get(fileIdentityKey(node.file));
53171
+ if (!moduleEntry)
53172
+ return false;
53173
+ if (moduleEntry.locals.some((local) => defNodeId(local) === node.id))
53174
+ return true;
53175
+ const filePrefix = `${normalizePath(moduleEntry.file)}::`;
53176
+ return moduleEntry.imports.some((imp) => {
53177
+ if (imp.kind === "star")
53178
+ return false;
53179
+ const local = imp.kind === "namespace" ? imp.localNS : imp.local;
53180
+ return node.id === `${filePrefix}${local}::import`;
53181
+ });
53182
+ }
53069
53183
  async function isDetailedSymbolGraphCompatibleWithProject(projectRoot, index, graph) {
53070
53184
  const normalizedRoot = path43.resolve(projectRoot);
53071
53185
  const indexedFiles = /* @__PURE__ */ new Set([...index.byFile.keys()]);
@@ -53086,25 +53200,26 @@ async function isDetailedSymbolGraphCompatibleWithProject(projectRoot, index, gr
53086
53200
  }
53087
53201
  }
53088
53202
  const base = await buildSymbolGraph(index);
53089
- if (graph.nodes.size !== base.nodes.size)
53090
- return false;
53091
53203
  for (const [id, expected] of base.nodes) {
53092
53204
  const actual = graph.nodes.get(id);
53093
- if (!actual || actual.file !== expected.file || actual.name !== expected.name || actual.kind !== expected.kind || actual.docstring !== expected.docstring || actual.lineSpan !== expected.lineSpan || actual.complexity !== expected.complexity) {
53205
+ if (!actual || !sameSymbolNodeSemantics(actual, expected))
53094
53206
  return false;
53095
- }
53096
53207
  }
53097
- return sameSymbolEdgeMultiset(base.edges, graph.edges);
53208
+ for (const node of graph.nodes.values()) {
53209
+ if (base.nodes.has(node.id))
53210
+ continue;
53211
+ if (!indexDefinesSymbolNode(index, node))
53212
+ return false;
53213
+ }
53214
+ return symbolEdgeMultisetContains(graph.edges, base.edges);
53098
53215
  }
53099
- function sameSymbolEdgeMultiset(expected, actual) {
53100
- if (expected.length !== actual.length)
53101
- return false;
53216
+ function symbolEdgeMultisetContains(haystack, needles) {
53102
53217
  const counts = /* @__PURE__ */ new Map();
53103
- for (const edge of expected) {
53218
+ for (const edge of haystack) {
53104
53219
  const key = symbolEdgeKey(edge);
53105
53220
  counts.set(key, (counts.get(key) ?? 0) + 1);
53106
53221
  }
53107
- for (const edge of actual) {
53222
+ for (const edge of needles) {
53108
53223
  const key = symbolEdgeKey(edge);
53109
53224
  const remaining = counts.get(key);
53110
53225
  if (remaining === void 0)
@@ -53114,7 +53229,7 @@ function sameSymbolEdgeMultiset(expected, actual) {
53114
53229
  else
53115
53230
  counts.set(key, remaining - 1);
53116
53231
  }
53117
- return !counts.size;
53232
+ return true;
53118
53233
  }
53119
53234
  function symbolEdgeKey(edge) {
53120
53235
  const from = lengthPrefixedSymbolEdgeField(edge.from);
@@ -55142,6 +55257,7 @@ function createNativeWorkerPool(opts) {
55142
55257
  const bounded = typeof requestedMax === "number" && Number.isFinite(requestedMax) && requestedMax > 0 ? Math.max(1, Math.floor(requestedMax)) : HARD_MAX_THREADS;
55143
55258
  const threads = Math.min(resolveThreadCount(opts?.threads), bounded);
55144
55259
  const workerPath = resolveNativeWorkerPath();
55260
+ markWindowsProcessDrainRequired();
55145
55261
  return new Piscina({
55146
55262
  filename: workerPath,
55147
55263
  minThreads: 1,
@@ -55157,6 +55273,7 @@ var init_nativeWorkerPool = __esm({
55157
55273
  "use strict";
55158
55274
  init_esm_wrapper();
55159
55275
  init_workerThreads();
55276
+ init_windowsProcessDrain();
55160
55277
  HARD_MAX_THREADS = 64;
55161
55278
  DEFAULT_NATIVE_THREAD_CAP = 8;
55162
55279
  }
@@ -55876,6 +55993,16 @@ function emitIndexCheckActivity(opts, activity, current = 0, total = 0) {
55876
55993
  total
55877
55994
  });
55878
55995
  }
55996
+ function createCountedCheckProgress(opts, activity, total) {
55997
+ emitIndexCheckActivity(opts, activity, 0, total);
55998
+ let completed = 0;
55999
+ return () => {
56000
+ completed += 1;
56001
+ if (completed === total || completed % 100 === 0) {
56002
+ emitIndexCheckActivity(opts, activity, completed, total);
56003
+ }
56004
+ };
56005
+ }
55879
56006
  function resetDiscoveryTimingSteps(timings) {
55880
56007
  if (!timings)
55881
56008
  return;
@@ -55883,6 +56010,7 @@ function resetDiscoveryTimingSteps(timings) {
55883
56010
  delete timings.filesystemScanMs;
55884
56011
  delete timings.sourceDiscoveryMs;
55885
56012
  delete timings.metadataDiscoveryMs;
56013
+ delete timings.cacheProbeMs;
55886
56014
  const remaining = (timings.steps ?? []).filter((step) => !DISCOVERY_TIMING_STEP_NAMES.has(step.name));
55887
56015
  if (remaining.length) {
55888
56016
  timings.steps = remaining;
@@ -55983,6 +56111,10 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
55983
56111
  }
55984
56112
  const manifestEntriesForIndex = useManifest ? projectIndexManifestEntries2(cachedGraphEntries ?? []) : /* @__PURE__ */ new Map();
55985
56113
  const modules = /* @__PURE__ */ new Map();
56114
+ const moduleCacheAvailable = opts?.cache !== "disk" || diskModuleCacheExists(projectRoot, opts);
56115
+ const shouldReportFileCacheCheck = Boolean(helperOpts?.reportDiscoveryProgress);
56116
+ const reportFileCacheCheck = shouldReportFileCacheCheck ? createCountedCheckProgress(opts, "Checking file cache", normalizedFiles.length) : () => void 0;
56117
+ const cacheProbeStart = performance6.now();
55986
56118
  const gitAvailable = await isGitRepo(projectRoot);
55987
56119
  const needsPersistentSignatures = cacheEnabled || useManifest;
55988
56120
  const useGitSignatures = gitAvailable && needsPersistentSignatures;
@@ -56022,7 +56154,6 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
56022
56154
  return !(matchesGitSig || cachedEdgesEntry.sig === sigInfo.sig);
56023
56155
  };
56024
56156
  const jsonDependencies = /* @__PURE__ */ new Map();
56025
- const moduleCacheAvailable = opts?.cache !== "disk" || diskModuleCacheExists(projectRoot, opts);
56026
56157
  const cacheProbes = new Map(await mapLimit(normalizedFiles, conc, async (file2) => {
56027
56158
  try {
56028
56159
  let sigInfo = fileSignatures.get(file2);
@@ -56051,8 +56182,15 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
56051
56182
  return [file2, { sigInfo, mod: mod2 }];
56052
56183
  } catch (error51) {
56053
56184
  return [file2, { error: error51 }];
56185
+ } finally {
56186
+ reportFileCacheCheck();
56054
56187
  }
56055
56188
  }));
56189
+ if (timings) {
56190
+ const cacheProbeMs = Math.round(performance6.now() - cacheProbeStart);
56191
+ timings.cacheProbeMs = cacheProbeMs;
56192
+ recordBuildTimingStep(timings, { name: "cache-probe", ms: cacheProbeMs });
56193
+ }
56056
56194
  const cacheMisses = Array.from(cacheProbes, ([file2, probe]) => !("error" in probe) && !probe.mod ? file2 : null).filter((file2) => file2 !== null);
56057
56195
  const workerSetup = await setupWorkerPool(opts, countNativeWorkerEligibleFiles(cacheMisses, opts?.languageExtensions));
56058
56196
  try {
@@ -56088,6 +56226,8 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
56088
56226
  buildStartedAt = performance6.now();
56089
56227
  emitIndexLifecycleProgress(opts, "start", "build", totalFiles);
56090
56228
  };
56229
+ if (cacheMisses.length)
56230
+ ensureBuildProgressStarted();
56091
56231
  const fileResults = await mapLimit(normalizedFiles, conc, async (file2) => {
56092
56232
  try {
56093
56233
  const cacheProbe = cacheProbes.get(file2);
@@ -56365,6 +56505,7 @@ async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpt
56365
56505
  manifestMode: useDiskCache ? "read-write" : "off",
56366
56506
  warnNoFilesMessage: `Warning: No files found in project root: ${projectRoot}. Check codegraph.config.json globs and CLI --include-glob/--ignore-glob filters. Diagnostic: codegraph doctor`,
56367
56507
  ...helperOpts?.ignoreExistingManifest ? { ignoreExistingManifest: true } : {},
56508
+ ...helperOpts?.reportDiscoveryProgress ? { reportDiscoveryProgress: true } : {},
56368
56509
  projectFiles,
56369
56510
  transientFiles,
56370
56511
  ...discoveredSymlinkDirectories !== void 0 ? { symlinkDirectories: discoveredSymlinkDirectories } : {}
@@ -57255,7 +57396,7 @@ var init_build_index = __esm({
57255
57396
  init_build_workers();
57256
57397
  init_incremental_plan();
57257
57398
  init_parsed_cache();
57258
- DISCOVERY_TIMING_STEP_NAMES = /* @__PURE__ */ new Set(["git-list", "git-ignore", "filesystem-scan"]);
57399
+ DISCOVERY_TIMING_STEP_NAMES = /* @__PURE__ */ new Set(["git-list", "git-ignore", "filesystem-scan", "cache-probe"]);
57259
57400
  }
57260
57401
  });
57261
57402
 
@@ -63218,12 +63359,15 @@ function resolveRawSqlQueryWorkerPath() {
63218
63359
  }
63219
63360
  async function runRawSqlQueryInWorker(task, deadlineMs, signal) {
63220
63361
  const workerPath = resolveRawSqlQueryWorkerPath();
63221
- return await rawSqlQueryWorkerLifecycle.run(task, deadlineMs, signal, () => new Piscina({
63222
- filename: workerPath,
63223
- minThreads: 1,
63224
- maxThreads: 1,
63225
- idleTimeout: 5e3
63226
- }));
63362
+ return await rawSqlQueryWorkerLifecycle.run(task, deadlineMs, signal, () => {
63363
+ markWindowsProcessDrainRequired();
63364
+ return new Piscina({
63365
+ filename: workerPath,
63366
+ minThreads: 1,
63367
+ maxThreads: 1,
63368
+ idleTimeout: 5e3
63369
+ });
63370
+ });
63227
63371
  }
63228
63372
  var MAX_RAW_SQL_QUERY_WORKERS, SqliteQueryDeadlineExceededError, SqliteQueryCancelledError, SqliteQueryWorkerCleanupCapacityExceededError, RawSqlQueryWorkerLifecycle, rawSqlQueryWorkerLifecycle;
63229
63373
  var init_rawQueryWorkerPool = __esm({
@@ -63231,6 +63375,7 @@ var init_rawQueryWorkerPool = __esm({
63231
63375
  "use strict";
63232
63376
  init_esm_wrapper();
63233
63377
  init_packageInfo();
63378
+ init_windowsProcessDrain();
63234
63379
  MAX_RAW_SQL_QUERY_WORKERS = 2;
63235
63380
  SqliteQueryDeadlineExceededError = class extends Error {
63236
63381
  constructor(deadlineMs) {
@@ -75641,6 +75786,7 @@ async function prepareQueryIndexFilesInWorker(projectRoot, files) {
75641
75786
  } catch {
75642
75787
  return await prepareQueryIndexFilesInProcess(projectRoot, files);
75643
75788
  }
75789
+ markWindowsProcessDrainRequired();
75644
75790
  const pool = new Piscina({
75645
75791
  filename: workerPath,
75646
75792
  minThreads: 1,
@@ -75681,6 +75827,7 @@ var init_workerPool = __esm({
75681
75827
  init_content();
75682
75828
  init_paths2();
75683
75829
  init_workerThreads();
75830
+ init_windowsProcessDrain();
75684
75831
  QUERY_INDEX_MAX_THREADS = 4;
75685
75832
  QUERY_INDEX_WORKER_MIN_FILES = 512;
75686
75833
  }
@@ -3552,6 +3552,35 @@ function loadNativeBinding(options) {
3552
3552
  }
3553
3553
  }
3554
3554
 
3555
+ // dist/util/windowsProcessDrain.js
3556
+ var WINDOWS_LIBUV_EXIT_DRAIN_MS = 100;
3557
+ var drainRequired = false;
3558
+ var beforeExitListener;
3559
+ function markWindowsProcessDrainRequired() {
3560
+ drainRequired = true;
3561
+ ensureWindowsProcessDrainHook();
3562
+ }
3563
+ function delay(ms) {
3564
+ return new Promise((resolve) => {
3565
+ setTimeout(resolve, ms);
3566
+ });
3567
+ }
3568
+ function ensureWindowsProcessDrainHook() {
3569
+ if (process.platform !== "win32" || beforeExitListener)
3570
+ return;
3571
+ beforeExitListener = () => {
3572
+ void drainWindowsProcessHandles();
3573
+ };
3574
+ process.once("beforeExit", beforeExitListener);
3575
+ }
3576
+ async function drainWindowsProcessHandles(options) {
3577
+ const platform = options?.platform ?? process.platform;
3578
+ const required = options?.required ?? drainRequired;
3579
+ if (platform !== "win32" || !required)
3580
+ return;
3581
+ await (options?.wait ?? delay)(WINDOWS_LIBUV_EXIT_DRAIN_MS);
3582
+ }
3583
+
3555
3584
  // dist/native/runtime.js
3556
3585
  var require2 = createRequire(import.meta.url);
3557
3586
  var localNativePackageRoot = path5.resolve(path5.dirname(fileURLToPath(import.meta.url)), "../../packages/codegraph-native");
@@ -3581,6 +3610,7 @@ function loadBinding() {
3581
3610
  });
3582
3611
  if (loaded.binding) {
3583
3612
  const supportedLanguageIds = new Set(loaded.binding.supportedLanguageIds());
3613
+ markWindowsProcessDrainRequired();
3584
3614
  bindingState = {
3585
3615
  loaded: true,
3586
3616
  binding: loaded.binding,
@@ -25,6 +25,35 @@ function errorMessage(error) {
25
25
  return String(error);
26
26
  }
27
27
 
28
+ // dist/util/windowsProcessDrain.js
29
+ var WINDOWS_LIBUV_EXIT_DRAIN_MS = 100;
30
+ var drainRequired = false;
31
+ var beforeExitListener;
32
+ function markWindowsProcessDrainRequired() {
33
+ drainRequired = true;
34
+ ensureWindowsProcessDrainHook();
35
+ }
36
+ function delay(ms) {
37
+ return new Promise((resolve) => {
38
+ setTimeout(resolve, ms);
39
+ });
40
+ }
41
+ function ensureWindowsProcessDrainHook() {
42
+ if (process.platform !== "win32" || beforeExitListener)
43
+ return;
44
+ beforeExitListener = () => {
45
+ void drainWindowsProcessHandles();
46
+ };
47
+ process.once("beforeExit", beforeExitListener);
48
+ }
49
+ async function drainWindowsProcessHandles(options) {
50
+ const platform = options?.platform ?? process.platform;
51
+ const required = options?.required ?? drainRequired;
52
+ if (platform !== "win32" || !required)
53
+ return;
54
+ await (options?.wait ?? delay)(WINDOWS_LIBUV_EXIT_DRAIN_MS);
55
+ }
56
+
28
57
  // dist/sqlite-driver.js
29
58
  var requireNodeModule = createRequire(import.meta.url);
30
59
  var sqliteModule;
@@ -160,6 +189,7 @@ var SqliteStatement = class _SqliteStatement {
160
189
  var SqliteDatabase = class {
161
190
  db;
162
191
  statements = /* @__PURE__ */ new Map();
192
+ closed = false;
163
193
  constructor(filePath, options) {
164
194
  if (!isNodeSqliteUsable()) {
165
195
  throw nodeSqliteUnavailableError() ?? new Error("node:sqlite is unavailable");
@@ -169,6 +199,7 @@ var SqliteDatabase = class {
169
199
  readOnly: options?.readonly,
170
200
  timeout: options?.timeout ?? 5e3
171
201
  });
202
+ markWindowsProcessDrainRequired();
172
203
  if (options?.readonly) {
173
204
  const { constants } = sqlite;
174
205
  if (this.db.setAuthorizer && canInstallReadonlyAuthorizer(constants)) {
@@ -213,8 +244,11 @@ var SqliteDatabase = class {
213
244
  };
214
245
  }
215
246
  close() {
247
+ if (this.closed)
248
+ return;
216
249
  this.statements.clear();
217
250
  this.db.close();
251
+ this.closed = true;
218
252
  }
219
253
  };
220
254
  function isReadOnlySqliteError(error) {