@lzehrung/codegraph 2.3.14 → 2.3.16
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.
- package/README.md +1 -1
- package/codegraph-skill/codegraph/SKILL.md +11 -3
- package/dist/agent/query-index/workerPool.d.ts.map +1 -1
- package/dist/agent/query-index/workerPool.js +2 -0
- package/dist/agent/query-index/workerPool.js.map +1 -1
- package/dist/bin/cli.js +381 -174
- package/dist/bin/queryIndexWorker.js +30 -0
- package/dist/bin/rawQueryWorker.js +34 -0
- package/dist/cli/commandTable.d.ts.map +1 -1
- package/dist/cli/commandTable.js +14 -1
- package/dist/cli/commandTable.js.map +1 -1
- package/dist/cli/help.d.ts +4 -4
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +8 -7
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/mcp.js +11 -6
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +3 -2
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/orient.d.ts +6 -2
- package/dist/cli/orient.d.ts.map +1 -1
- package/dist/cli/orient.js +13 -1
- package/dist/cli/orient.js.map +1 -1
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +21 -7
- package/dist/cli/progress.js.map +1 -1
- package/dist/cli/server.d.ts.map +1 -1
- package/dist/cli/server.js +6 -2
- package/dist/cli/server.js.map +1 -1
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +148 -28
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/types.d.ts +2 -0
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/mcp/handlers.d.ts +6 -1
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +13 -9
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/protocol.d.ts.map +1 -1
- package/dist/mcp/protocol.js +1 -1
- package/dist/mcp/protocol.js.map +1 -1
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +2 -0
- package/dist/native/runtime.js.map +1 -1
- package/dist/sqlite/rawQueryWorkerPool.d.ts.map +1 -1
- package/dist/sqlite/rawQueryWorkerPool.js +10 -6
- package/dist/sqlite/rawQueryWorkerPool.js.map +1 -1
- package/dist/sqlite-driver.d.ts +1 -0
- package/dist/sqlite-driver.d.ts.map +1 -1
- package/dist/sqlite-driver.js +6 -0
- package/dist/sqlite-driver.js.map +1 -1
- package/dist/util/projectFiles.d.ts.map +1 -1
- package/dist/util/projectFiles.js +10 -1
- package/dist/util/projectFiles.js.map +1 -1
- package/dist/util/windowsProcessDrain.d.ts +23 -0
- package/dist/util/windowsProcessDrain.d.ts.map +1 -0
- package/dist/util/windowsProcessDrain.js +51 -0
- package/dist/util/windowsProcessDrain.js.map +1 -0
- package/dist/worker/nativeWorkerPool.d.ts.map +1 -1
- package/dist/worker/nativeWorkerPool.js +2 -0
- package/dist/worker/nativeWorkerPool.js.map +1 -1
- package/docs/mcp.md +9 -9
- package/package.json +3 -3
|
@@ -414,15 +414,67 @@ function emitIndexCheckActivity(opts, activity, current = 0, total = 0) {
|
|
|
414
414
|
total,
|
|
415
415
|
});
|
|
416
416
|
}
|
|
417
|
-
|
|
418
|
-
|
|
417
|
+
function emitIndexBuildActivity(opts, activity, current, total) {
|
|
418
|
+
opts?.onProgress?.({
|
|
419
|
+
type: "progress",
|
|
420
|
+
phase: "update",
|
|
421
|
+
mode: "build",
|
|
422
|
+
message: activity,
|
|
423
|
+
activity,
|
|
424
|
+
current,
|
|
425
|
+
total,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Names and times a post-parse persistence phase (cache write, manifest, graph finalize,
|
|
430
|
+
* snapshot write) so the interactive spinner shows what is happening instead of freezing at
|
|
431
|
+
* the last "Indexed N/N files" count, and so `--report` exposes each phase's cost.
|
|
432
|
+
*/
|
|
433
|
+
async function timeIndexBuildPhase(args) {
|
|
434
|
+
if (args.buildStartedAt !== undefined) {
|
|
435
|
+
emitIndexBuildActivity(args.opts, args.activity, args.current, args.total);
|
|
436
|
+
}
|
|
437
|
+
const startedAt = performance.now();
|
|
438
|
+
const result = await args.fn();
|
|
439
|
+
recordBuildTimingStep(args.timings, { name: args.stepName, ms: Math.round(performance.now() - startedAt) });
|
|
440
|
+
return result;
|
|
441
|
+
}
|
|
442
|
+
function createCountedCheckProgress(opts, activity, total) {
|
|
443
|
+
emitIndexCheckActivity(opts, activity, 0, total);
|
|
444
|
+
let completed = 0;
|
|
445
|
+
return () => {
|
|
446
|
+
completed += 1;
|
|
447
|
+
if (completed === total || completed % 100 === 0) {
|
|
448
|
+
emitIndexCheckActivity(opts, activity, completed, total);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
const TRANSIENT_BUILD_TIMING_STEP_NAMES = {
|
|
453
|
+
"git-list": true,
|
|
454
|
+
"git-ignore": true,
|
|
455
|
+
"filesystem-scan": true,
|
|
456
|
+
"cache-probe": true,
|
|
457
|
+
"persist-cache": true,
|
|
458
|
+
"workspace-manifests": true,
|
|
459
|
+
"index-manifest": true,
|
|
460
|
+
finalize: true,
|
|
461
|
+
"snapshot-write": true,
|
|
462
|
+
};
|
|
463
|
+
/**
|
|
464
|
+
* Clears named step timings and coarse discovery fields left over from a prior build that
|
|
465
|
+
* reused the same `BuildReport` object (for example an MCP session's `buildOptions.report`
|
|
466
|
+
* across `refresh_index` calls), so a reused report never mixes this build's steps with a
|
|
467
|
+
* previous one's.
|
|
468
|
+
*/
|
|
469
|
+
function resetTransientBuildTimings(timings) {
|
|
419
470
|
if (!timings)
|
|
420
471
|
return;
|
|
421
472
|
delete timings.gitListMs;
|
|
422
473
|
delete timings.filesystemScanMs;
|
|
423
474
|
delete timings.sourceDiscoveryMs;
|
|
424
475
|
delete timings.metadataDiscoveryMs;
|
|
425
|
-
|
|
476
|
+
delete timings.cacheProbeMs;
|
|
477
|
+
const remaining = (timings.steps ?? []).filter((step) => !Object.hasOwn(TRANSIENT_BUILD_TIMING_STEP_NAMES, step.name));
|
|
426
478
|
if (remaining.length) {
|
|
427
479
|
timings.steps = remaining;
|
|
428
480
|
return;
|
|
@@ -534,6 +586,12 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
534
586
|
? projectIndexManifestEntries(cachedGraphEntries ?? [])
|
|
535
587
|
: new Map();
|
|
536
588
|
const modules = new Map();
|
|
589
|
+
const moduleCacheAvailable = opts?.cache !== "disk" || diskModuleCacheExists(projectRoot, opts);
|
|
590
|
+
const shouldReportFileCacheCheck = Boolean(helperOpts?.reportDiscoveryProgress);
|
|
591
|
+
const reportFileCacheCheck = shouldReportFileCacheCheck
|
|
592
|
+
? createCountedCheckProgress(opts, "Checking file cache", normalizedFiles.length)
|
|
593
|
+
: () => undefined;
|
|
594
|
+
const cacheProbeStart = performance.now();
|
|
537
595
|
const gitAvailable = await isGitRepo(projectRoot);
|
|
538
596
|
const needsPersistentSignatures = cacheEnabled || useManifest;
|
|
539
597
|
const useGitSignatures = gitAvailable && needsPersistentSignatures;
|
|
@@ -580,7 +638,6 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
580
638
|
// Cache lookup determines the work a full build will actually parse. Complete that cheap phase
|
|
581
639
|
// before starting Piscina, so a warm build does not bootstrap workers and partial hits bound
|
|
582
640
|
// the pool to real parse misses rather than the input file list.
|
|
583
|
-
const moduleCacheAvailable = opts?.cache !== "disk" || diskModuleCacheExists(projectRoot, opts);
|
|
584
641
|
const cacheProbes = new Map(await mapLimit(normalizedFiles, conc, async (file) => {
|
|
585
642
|
try {
|
|
586
643
|
let sigInfo = fileSignatures.get(file);
|
|
@@ -616,7 +673,15 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
616
673
|
catch (error) {
|
|
617
674
|
return [file, { error }];
|
|
618
675
|
}
|
|
676
|
+
finally {
|
|
677
|
+
reportFileCacheCheck();
|
|
678
|
+
}
|
|
619
679
|
}));
|
|
680
|
+
if (timings) {
|
|
681
|
+
const cacheProbeMs = Math.round(performance.now() - cacheProbeStart);
|
|
682
|
+
timings.cacheProbeMs = cacheProbeMs;
|
|
683
|
+
recordBuildTimingStep(timings, { name: "cache-probe", ms: cacheProbeMs });
|
|
684
|
+
}
|
|
620
685
|
const cacheMisses = Array.from(cacheProbes, ([file, probe]) => !("error" in probe) && !probe.mod ? file : null).filter((file) => file !== null);
|
|
621
686
|
const workerSetup = await setupWorkerPool(opts, countNativeWorkerEligibleFiles(cacheMisses, opts?.languageExtensions));
|
|
622
687
|
try {
|
|
@@ -658,6 +723,8 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
658
723
|
buildStartedAt = performance.now();
|
|
659
724
|
emitIndexLifecycleProgress(opts, "start", "build", totalFiles);
|
|
660
725
|
};
|
|
726
|
+
if (cacheMisses.length)
|
|
727
|
+
ensureBuildProgressStarted();
|
|
661
728
|
const fileResults = await mapLimit(normalizedFiles, conc, async (file) => {
|
|
662
729
|
try {
|
|
663
730
|
const cacheProbe = cacheProbes.get(file);
|
|
@@ -823,9 +890,32 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
823
890
|
pendingCacheWrites.push(cacheWrite);
|
|
824
891
|
}
|
|
825
892
|
if (pendingCacheWrites.length) {
|
|
826
|
-
|
|
893
|
+
if (opts?.cache === "disk") {
|
|
894
|
+
await timeIndexBuildPhase({
|
|
895
|
+
opts,
|
|
896
|
+
timings,
|
|
897
|
+
buildStartedAt,
|
|
898
|
+
stepName: "persist-cache",
|
|
899
|
+
activity: "Writing disk cache",
|
|
900
|
+
current: totalFiles,
|
|
901
|
+
total: totalFiles,
|
|
902
|
+
fn: () => writeModulesToCache(projectRoot, pendingCacheWrites, opts),
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
writeModulesToCache(projectRoot, pendingCacheWrites, opts);
|
|
907
|
+
}
|
|
827
908
|
}
|
|
828
|
-
const workspaceManifestEdges = await
|
|
909
|
+
const workspaceManifestEdges = await timeIndexBuildPhase({
|
|
910
|
+
opts,
|
|
911
|
+
timings,
|
|
912
|
+
buildStartedAt,
|
|
913
|
+
stepName: "workspace-manifests",
|
|
914
|
+
activity: "Resolving workspace manifests",
|
|
915
|
+
current: totalFiles,
|
|
916
|
+
total: totalFiles,
|
|
917
|
+
fn: () => collectWorkspaceManifestDependencyEdges(projectRoot, normalizedFiles.filter((file) => path.basename(file) === "package.json"), opts?.discovery, opts?.logLevel),
|
|
918
|
+
});
|
|
829
919
|
appendUniqueGraphEdges(workspaceManifestEdges);
|
|
830
920
|
if (timings)
|
|
831
921
|
timings.graphMs = Math.round(performance.now() - graphStart);
|
|
@@ -845,16 +935,27 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
845
935
|
}
|
|
846
936
|
}
|
|
847
937
|
if (manifestEntries) {
|
|
848
|
-
await
|
|
849
|
-
projectRoot,
|
|
938
|
+
await timeIndexBuildPhase({
|
|
850
939
|
opts,
|
|
851
|
-
graphOptions,
|
|
852
|
-
...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
|
|
853
|
-
files: manifestEntries,
|
|
854
940
|
timings,
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
941
|
+
buildStartedAt,
|
|
942
|
+
stepName: "index-manifest",
|
|
943
|
+
activity: "Writing index manifest",
|
|
944
|
+
current: totalFiles,
|
|
945
|
+
total: totalFiles,
|
|
946
|
+
fn: () => writeIndexManifestSnapshot({
|
|
947
|
+
projectRoot,
|
|
948
|
+
opts,
|
|
949
|
+
graphOptions,
|
|
950
|
+
...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
|
|
951
|
+
files: manifestEntries,
|
|
952
|
+
timings,
|
|
953
|
+
manifestReport: report?.manifest,
|
|
954
|
+
...(helperOpts?.transientFiles !== undefined ? { transientFiles: helperOpts.transientFiles } : {}),
|
|
955
|
+
...(helperOpts?.symlinkDirectories !== undefined
|
|
956
|
+
? { symlinkDirectories: helperOpts.symlinkDirectories }
|
|
957
|
+
: {}),
|
|
958
|
+
}),
|
|
858
959
|
});
|
|
859
960
|
}
|
|
860
961
|
const indexManifestEntries = manifestEntries
|
|
@@ -863,22 +964,40 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
863
964
|
return [file, { ...entry, ...(cacheSig ? { cacheSig } : {}) }];
|
|
864
965
|
}))
|
|
865
966
|
: manifestEntriesForIndex;
|
|
866
|
-
const index = await
|
|
867
|
-
projectRoot,
|
|
868
|
-
normalizedProjectRoot,
|
|
967
|
+
const index = await timeIndexBuildPhase({
|
|
869
968
|
opts,
|
|
870
969
|
timings,
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
970
|
+
buildStartedAt,
|
|
971
|
+
stepName: "finalize",
|
|
972
|
+
activity: "Finalizing project graph",
|
|
973
|
+
current: totalFiles,
|
|
974
|
+
total: totalFiles,
|
|
975
|
+
fn: () => finalizeProjectIndex({
|
|
976
|
+
projectRoot,
|
|
977
|
+
normalizedProjectRoot,
|
|
978
|
+
opts,
|
|
979
|
+
timings,
|
|
980
|
+
totalStart,
|
|
981
|
+
graph,
|
|
982
|
+
modules,
|
|
983
|
+
parsedMap,
|
|
984
|
+
bloomFilterCache,
|
|
985
|
+
...(projectFiles !== undefined ? { projectFiles } : {}),
|
|
986
|
+
buildReport: report,
|
|
987
|
+
manifestEntries: indexManifestEntries,
|
|
988
|
+
}),
|
|
879
989
|
});
|
|
880
990
|
if (manifestEntries) {
|
|
881
|
-
await
|
|
991
|
+
await timeIndexBuildPhase({
|
|
992
|
+
opts,
|
|
993
|
+
timings,
|
|
994
|
+
buildStartedAt,
|
|
995
|
+
stepName: "snapshot-write",
|
|
996
|
+
activity: "Writing project snapshot",
|
|
997
|
+
current: totalFiles,
|
|
998
|
+
total: totalFiles,
|
|
999
|
+
fn: () => writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot)),
|
|
1000
|
+
});
|
|
882
1001
|
}
|
|
883
1002
|
if (buildStartedAt !== undefined) {
|
|
884
1003
|
// Report the whole operation the caller waited on. Discovery runs before the first
|
|
@@ -896,7 +1015,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
896
1015
|
}
|
|
897
1016
|
async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpts) {
|
|
898
1017
|
const timings = opts?.report ? (opts.report.timings ??= {}) : undefined;
|
|
899
|
-
|
|
1018
|
+
resetTransientBuildTimings(timings);
|
|
900
1019
|
await initializeFileIdentityCaseSensitivity(projectRoot);
|
|
901
1020
|
try {
|
|
902
1021
|
const useDiskCache = (opts?.cache ?? "off") === "disk";
|
|
@@ -972,6 +1091,7 @@ async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpt
|
|
|
972
1091
|
manifestMode: useDiskCache ? "read-write" : "off",
|
|
973
1092
|
warnNoFilesMessage: `Warning: No files found in project root: ${projectRoot}. Check codegraph.config.json globs and CLI --include-glob/--ignore-glob filters. Diagnostic: codegraph doctor`,
|
|
974
1093
|
...(helperOpts?.ignoreExistingManifest ? { ignoreExistingManifest: true } : {}),
|
|
1094
|
+
...(helperOpts?.reportDiscoveryProgress ? { reportDiscoveryProgress: true } : {}),
|
|
975
1095
|
projectFiles,
|
|
976
1096
|
transientFiles,
|
|
977
1097
|
...(discoveredSymlinkDirectories !== undefined ? { symlinkDirectories: discoveredSymlinkDirectories } : {}),
|
|
@@ -1070,7 +1190,7 @@ export async function buildProjectIndexIncremental(projectRoot, rawOpts) {
|
|
|
1070
1190
|
graphOptions.fast = false;
|
|
1071
1191
|
const { normalizedProjectRoot, report, timings, totalStart, cacheMode, cacheEnabled, onFallbackImportExtraction } = createIndexBuildRunState(projectRoot, opts, graphOptions);
|
|
1072
1192
|
const discoveryTimings = opts?.report ? (opts.report.timings ??= {}) : undefined;
|
|
1073
|
-
|
|
1193
|
+
resetTransientBuildTimings(discoveryTimings);
|
|
1074
1194
|
let checkProgressActive = false;
|
|
1075
1195
|
const startCheckProgress = () => {
|
|
1076
1196
|
if (checkProgressActive)
|