@lzehrung/codegraph 2.1.0 → 2.1.2
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 +27 -29
- package/codegraph-skill/codegraph/SKILL.md +27 -26
- package/dist/agent/artifact.d.ts.map +1 -1
- package/dist/agent/artifact.js +105 -14
- package/dist/agent/artifact.js.map +1 -1
- package/dist/agent/candidateTests.d.ts +12 -0
- package/dist/agent/candidateTests.d.ts.map +1 -0
- package/dist/agent/candidateTests.js +17 -0
- package/dist/agent/candidateTests.js.map +1 -0
- package/dist/agent/explain.d.ts +3 -0
- package/dist/agent/explain.d.ts.map +1 -1
- package/dist/agent/explain.js +8 -0
- package/dist/agent/explain.js.map +1 -1
- package/dist/agent/explore.d.ts.map +1 -1
- package/dist/agent/explore.js +11 -6
- package/dist/agent/explore.js.map +1 -1
- package/dist/agent/fileView.d.ts.map +1 -1
- package/dist/agent/fileView.js +113 -120
- package/dist/agent/fileView.js.map +1 -1
- package/dist/agent/orient.d.ts.map +1 -1
- package/dist/agent/orient.js +7 -4
- package/dist/agent/orient.js.map +1 -1
- package/dist/agent/packet.d.ts.map +1 -1
- package/dist/agent/packet.js +5 -12
- package/dist/agent/packet.js.map +1 -1
- package/dist/agent/query-index/candidates.d.ts +13 -2
- package/dist/agent/query-index/candidates.d.ts.map +1 -1
- package/dist/agent/query-index/candidates.js +28 -39
- package/dist/agent/query-index/candidates.js.map +1 -1
- package/dist/agent/query-index/content.d.ts +1 -1
- package/dist/agent/query-index/content.js +4 -4
- package/dist/agent/query-index/content.js.map +1 -1
- package/dist/agent/query-index/schema.d.ts.map +1 -1
- package/dist/agent/query-index/schema.js.map +1 -1
- package/dist/agent/query-index/sessionStore.d.ts.map +1 -1
- package/dist/agent/query-index/sessionStore.js +42 -26
- package/dist/agent/query-index/sessionStore.js.map +1 -1
- package/dist/agent/query-index/store.d.ts +10 -4
- package/dist/agent/query-index/store.d.ts.map +1 -1
- package/dist/agent/query-index/store.js +115 -10
- package/dist/agent/query-index/store.js.map +1 -1
- package/dist/agent/query-index/update.d.ts.map +1 -1
- package/dist/agent/query-index/update.js +24 -9
- package/dist/agent/query-index/update.js.map +1 -1
- package/dist/agent/refactorPlan.d.ts.map +1 -1
- package/dist/agent/refactorPlan.js +6 -14
- package/dist/agent/refactorPlan.js.map +1 -1
- package/dist/agent/renamePreview.d.ts +2 -5
- package/dist/agent/renamePreview.d.ts.map +1 -1
- package/dist/agent/renamePreview.js +133 -80
- package/dist/agent/renamePreview.js.map +1 -1
- package/dist/agent/search.d.ts +3 -1
- package/dist/agent/search.d.ts.map +1 -1
- package/dist/agent/search.js +103 -35
- package/dist/agent/search.js.map +1 -1
- package/dist/agent/semanticSymbols.d.ts.map +1 -1
- package/dist/agent/semanticSymbols.js +2 -1
- package/dist/agent/semanticSymbols.js.map +1 -1
- package/dist/agent/session.d.ts +4 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +20 -7
- package/dist/agent/session.js.map +1 -1
- package/dist/agent-tools.d.ts +1 -1
- package/dist/agent-tools.d.ts.map +1 -1
- package/dist/agent-tools.js +12 -21
- package/dist/agent-tools.js.map +1 -1
- package/dist/bin/cli.js +29242 -25373
- package/dist/bin/queryIndexWorker.js +131 -42
- package/dist/bin/rawQueryWorker.js +270 -0
- package/dist/chunking/chunkFile.d.ts +5 -0
- package/dist/chunking/chunkFile.d.ts.map +1 -1
- package/dist/chunking/chunkFile.js +14 -15
- package/dist/chunking/chunkFile.js.map +1 -1
- package/dist/cli/affected.d.ts.map +1 -1
- package/dist/cli/affected.js +17 -10
- package/dist/cli/affected.js.map +1 -1
- package/dist/cli/callHierarchy.d.ts.map +1 -1
- package/dist/cli/callHierarchy.js +9 -2
- package/dist/cli/callHierarchy.js.map +1 -1
- package/dist/cli/commandTable.d.ts.map +1 -1
- package/dist/cli/commandTable.js +16 -4
- package/dist/cli/commandTable.js.map +1 -1
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +166 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/graph.d.ts +2 -1
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +60 -16
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/graphDelta.d.ts +2 -1
- package/dist/cli/graphDelta.d.ts.map +1 -1
- package/dist/cli/graphDelta.js +5 -0
- package/dist/cli/graphDelta.js.map +1 -1
- package/dist/cli/grep.d.ts +1 -1
- package/dist/cli/grep.d.ts.map +1 -1
- package/dist/cli/grep.js +14 -4
- package/dist/cli/grep.js.map +1 -1
- package/dist/cli/help.d.ts +34 -34
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +17 -8
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/impact.d.ts +2 -1
- package/dist/cli/impact.d.ts.map +1 -1
- package/dist/cli/impact.js +5 -0
- package/dist/cli/impact.js.map +1 -1
- package/dist/cli/index.d.ts +2 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/indexPolicy.d.ts.map +1 -1
- package/dist/cli/indexPolicy.js.map +1 -1
- package/dist/cli/inspect.d.ts +2 -1
- package/dist/cli/inspect.d.ts.map +1 -1
- package/dist/cli/inspect.js +25 -13
- package/dist/cli/inspect.js.map +1 -1
- package/dist/cli/install.js +1 -1
- package/dist/cli/install.js.map +1 -1
- package/dist/cli/invocationContext.d.ts.map +1 -1
- package/dist/cli/invocationContext.js +3 -0
- package/dist/cli/invocationContext.js.map +1 -1
- package/dist/cli/links.d.ts +2 -0
- package/dist/cli/links.d.ts.map +1 -1
- package/dist/cli/links.js +1 -1
- package/dist/cli/links.js.map +1 -1
- package/dist/cli/navigation.d.ts +41 -1
- package/dist/cli/navigation.d.ts.map +1 -1
- package/dist/cli/navigation.js +4 -1
- package/dist/cli/navigation.js.map +1 -1
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +32 -11
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/renamePreview.d.ts.map +1 -1
- package/dist/cli/renamePreview.js +7 -1
- package/dist/cli/renamePreview.js.map +1 -1
- package/dist/cli/review.d.ts +2 -1
- package/dist/cli/review.d.ts.map +1 -1
- package/dist/cli/review.js +5 -0
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/rootPolicy.d.ts.map +1 -1
- package/dist/cli/rootPolicy.js +36 -3
- package/dist/cli/rootPolicy.js.map +1 -1
- package/dist/cli/skill.js +2 -2
- package/dist/cli/skill.js.map +1 -1
- package/dist/cli/sql.js +1 -1
- package/dist/cli/symbols.d.ts.map +1 -1
- package/dist/cli/symbols.js +4 -2
- package/dist/cli/symbols.js.map +1 -1
- package/dist/cli/viewer.d.ts.map +1 -1
- package/dist/cli/viewer.js +46 -34
- package/dist/cli/viewer.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +36 -16
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -3
- package/dist/config.js.map +1 -1
- package/dist/documentLinks/check.d.ts +2 -1
- package/dist/documentLinks/check.d.ts.map +1 -1
- package/dist/documentLinks/check.js +22 -11
- package/dist/documentLinks/check.js.map +1 -1
- package/dist/duplicate-token-normalization.d.ts.map +1 -1
- package/dist/duplicate-token-normalization.js +10 -2
- package/dist/duplicate-token-normalization.js.map +1 -1
- package/dist/duplicates/scoring.d.ts +0 -10
- package/dist/duplicates/scoring.d.ts.map +1 -1
- package/dist/duplicates/scoring.js +9 -9
- package/dist/duplicates/scoring.js.map +1 -1
- package/dist/duplicates/types.d.ts +2 -0
- package/dist/duplicates/types.d.ts.map +1 -1
- package/dist/duplicates/unitCache.d.ts +15 -9
- package/dist/duplicates/unitCache.d.ts.map +1 -1
- package/dist/duplicates/unitCache.js +184 -33
- package/dist/duplicates/unitCache.js.map +1 -1
- package/dist/duplicates/units.d.ts +6 -15
- package/dist/duplicates/units.d.ts.map +1 -1
- package/dist/duplicates/units.js +42 -20
- package/dist/duplicates/units.js.map +1 -1
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +59 -0
- package/dist/duplicates.js.map +1 -1
- package/dist/frameworks/angularjs.d.ts.map +1 -1
- package/dist/frameworks/angularjs.js +18 -12
- package/dist/frameworks/angularjs.js.map +1 -1
- package/dist/graph-builder.d.ts.map +1 -1
- package/dist/graph-builder.js +12 -9
- package/dist/graph-builder.js.map +1 -1
- package/dist/graph-edge-collector.d.ts +1 -0
- package/dist/graph-edge-collector.d.ts.map +1 -1
- package/dist/graph-edge-collector.js +1 -1
- package/dist/graph-edge-collector.js.map +1 -1
- package/dist/graphs/grep.d.ts.map +1 -1
- package/dist/graphs/grep.js +7 -2
- package/dist/graphs/grep.js.map +1 -1
- package/dist/graphs/specifiers.d.ts.map +1 -1
- package/dist/graphs/specifiers.js +8 -2
- package/dist/graphs/specifiers.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed.d.ts +10 -1
- package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed.js +21 -5
- package/dist/graphs/symbol-graph-detailed.js.map +1 -1
- package/dist/impact/analyzer.d.ts.map +1 -1
- package/dist/impact/analyzer.js +19 -2
- package/dist/impact/analyzer.js.map +1 -1
- package/dist/impact/budgets.d.ts.map +1 -1
- package/dist/impact/budgets.js +5 -3
- package/dist/impact/budgets.js.map +1 -1
- package/dist/impact/call-compatibility/textScanner.d.ts +23 -0
- package/dist/impact/call-compatibility/textScanner.d.ts.map +1 -0
- package/dist/impact/call-compatibility/textScanner.js +615 -0
- package/dist/impact/call-compatibility/textScanner.js.map +1 -0
- package/dist/impact/callCompatibility.d.ts +8 -1
- package/dist/impact/callCompatibility.d.ts.map +1 -1
- package/dist/impact/callCompatibility.js +64 -587
- package/dist/impact/callCompatibility.js.map +1 -1
- package/dist/impact/context.d.ts.map +1 -1
- package/dist/impact/context.js +4 -1
- package/dist/impact/context.js.map +1 -1
- package/dist/impact/direct.d.ts +1 -1
- package/dist/impact/direct.d.ts.map +1 -1
- package/dist/impact/direct.js +7 -6
- package/dist/impact/direct.js.map +1 -1
- package/dist/impact/index.d.ts +6 -0
- package/dist/impact/index.d.ts.map +1 -1
- package/dist/impact/index.js +0 -8
- package/dist/impact/index.js.map +1 -1
- package/dist/impact/map.js +2 -2
- package/dist/impact/map.js.map +1 -1
- package/dist/impact/memberResolutionCoverage.d.ts.map +1 -1
- package/dist/impact/memberResolutionCoverage.js +5 -1
- package/dist/impact/memberResolutionCoverage.js.map +1 -1
- package/dist/impact/parse.d.ts.map +1 -1
- package/dist/impact/parse.js +108 -37
- package/dist/impact/parse.js.map +1 -1
- package/dist/impact/referenceCache.js +1 -1
- package/dist/impact/referenceCache.js.map +1 -1
- package/dist/impact/report-suggestions.d.ts.map +1 -1
- package/dist/impact/report-suggestions.js +347 -72
- package/dist/impact/report-suggestions.js.map +1 -1
- package/dist/impact/report.d.ts.map +1 -1
- package/dist/impact/report.js +13 -2
- package/dist/impact/report.js.map +1 -1
- package/dist/impact/reportCompact.d.ts.map +1 -1
- package/dist/impact/reportCompact.js +8 -0
- package/dist/impact/reportCompact.js.map +1 -1
- package/dist/impact/reportFull.d.ts.map +1 -1
- package/dist/impact/reportFull.js +1 -0
- package/dist/impact/reportFull.js.map +1 -1
- package/dist/impact/reportParts.d.ts +9 -0
- package/dist/impact/reportParts.d.ts.map +1 -1
- package/dist/impact/severity.d.ts +3 -2
- package/dist/impact/severity.d.ts.map +1 -1
- package/dist/impact/severity.js +16 -5
- package/dist/impact/severity.js.map +1 -1
- package/dist/impact/streaming.d.ts +32 -2
- package/dist/impact/streaming.d.ts.map +1 -1
- package/dist/impact/streaming.js +62 -3
- package/dist/impact/streaming.js.map +1 -1
- package/dist/impact/suggestions.d.ts.map +1 -1
- package/dist/impact/suggestions.js +1 -1
- package/dist/impact/suggestions.js.map +1 -1
- package/dist/impact/transitive.d.ts.map +1 -1
- package/dist/impact/transitive.js +13 -5
- package/dist/impact/transitive.js.map +1 -1
- package/dist/impact/types.d.ts +21 -20
- package/dist/impact/types.d.ts.map +1 -1
- package/dist/impact/types.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/indexer/build-cache/location.d.ts +19 -0
- package/dist/indexer/build-cache/location.d.ts.map +1 -0
- package/dist/indexer/build-cache/location.js +132 -0
- package/dist/indexer/build-cache/location.js.map +1 -0
- package/dist/indexer/build-cache/manifest.d.ts +14 -6
- package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
- package/dist/indexer/build-cache/manifest.js +194 -30
- package/dist/indexer/build-cache/manifest.js.map +1 -1
- package/dist/indexer/build-cache/module-cache.d.ts +24 -2
- package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache/module-cache.js +98 -32
- package/dist/indexer/build-cache/module-cache.js.map +1 -1
- package/dist/indexer/build-cache/options.d.ts +3 -1
- package/dist/indexer/build-cache/options.d.ts.map +1 -1
- package/dist/indexer/build-cache/options.js +10 -2
- package/dist/indexer/build-cache/options.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.d.ts +33 -13
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +472 -91
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer/build-cache/reports.d.ts.map +1 -1
- package/dist/indexer/build-cache/reports.js +10 -1
- package/dist/indexer/build-cache/reports.js.map +1 -1
- package/dist/indexer/build-cache/resolver-environment.d.ts +9 -0
- package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -0
- package/dist/indexer/build-cache/resolver-environment.js +160 -0
- package/dist/indexer/build-cache/resolver-environment.js.map +1 -0
- package/dist/indexer/build-cache.d.ts +4 -3
- package/dist/indexer/build-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache.js +4 -3
- package/dist/indexer/build-cache.js.map +1 -1
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +268 -96
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/build-manifest.d.ts +1 -0
- package/dist/indexer/build-manifest.d.ts.map +1 -1
- package/dist/indexer/build-manifest.js +15 -5
- package/dist/indexer/build-manifest.js.map +1 -1
- package/dist/indexer/build-workers.d.ts +1 -1
- package/dist/indexer/build-workers.d.ts.map +1 -1
- package/dist/indexer/build-workers.js +57 -42
- package/dist/indexer/build-workers.js.map +1 -1
- package/dist/indexer/call-hierarchy.d.ts.map +1 -1
- package/dist/indexer/call-hierarchy.js.map +1 -1
- package/dist/indexer/finalize.d.ts.map +1 -1
- package/dist/indexer/finalize.js +7 -4
- package/dist/indexer/finalize.js.map +1 -1
- package/dist/indexer/import-types.d.ts +8 -0
- package/dist/indexer/import-types.d.ts.map +1 -1
- package/dist/indexer/imports/jsTextImports.d.ts.map +1 -1
- package/dist/indexer/imports/jsTextImports.js +14 -6
- package/dist/indexer/imports/jsTextImports.js.map +1 -1
- package/dist/indexer/imports/languageSpecific.d.ts.map +1 -1
- package/dist/indexer/imports/languageSpecific.js +10 -5
- package/dist/indexer/imports/languageSpecific.js.map +1 -1
- package/dist/indexer/imports/nativeCaptures.d.ts.map +1 -1
- package/dist/indexer/imports/nativeCaptures.js +4 -1
- package/dist/indexer/imports/nativeCaptures.js.map +1 -1
- package/dist/indexer/imports/python.d.ts.map +1 -1
- package/dist/indexer/imports/python.js +19 -9
- package/dist/indexer/imports/python.js.map +1 -1
- package/dist/indexer/incremental-plan.d.ts +2 -1
- package/dist/indexer/incremental-plan.d.ts.map +1 -1
- package/dist/indexer/incremental-plan.js +7 -4
- package/dist/indexer/incremental-plan.js.map +1 -1
- package/dist/indexer/load-current-index.d.ts.map +1 -1
- package/dist/indexer/load-current-index.js.map +1 -1
- package/dist/indexer/locals-and-exports.d.ts.map +1 -1
- package/dist/indexer/locals-and-exports.js +77 -22
- package/dist/indexer/locals-and-exports.js.map +1 -1
- package/dist/indexer/navigation-goto.d.ts.map +1 -1
- package/dist/indexer/navigation-goto.js +26 -16
- package/dist/indexer/navigation-goto.js.map +1 -1
- package/dist/indexer/navigation-local.d.ts.map +1 -1
- package/dist/indexer/navigation-local.js +7 -4
- package/dist/indexer/navigation-local.js.map +1 -1
- package/dist/indexer/navigation-references.d.ts +1 -1
- package/dist/indexer/navigation-references.d.ts.map +1 -1
- package/dist/indexer/navigation-references.js +34 -17
- package/dist/indexer/navigation-references.js.map +1 -1
- package/dist/indexer/navigation-resolve.d.ts.map +1 -1
- package/dist/indexer/navigation-resolve.js +116 -53
- package/dist/indexer/navigation-resolve.js.map +1 -1
- package/dist/indexer/navigation.d.ts +2 -1
- package/dist/indexer/navigation.d.ts.map +1 -1
- package/dist/indexer/navigation.js +34 -20
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/parse-context.d.ts +2 -2
- package/dist/indexer/parse-context.d.ts.map +1 -1
- package/dist/indexer/parse-context.js +25 -4
- package/dist/indexer/parse-context.js.map +1 -1
- package/dist/indexer/reference-context.d.ts +2 -2
- package/dist/indexer/reference-context.d.ts.map +1 -1
- package/dist/indexer/reference-context.js +4 -2
- package/dist/indexer/reference-context.js.map +1 -1
- package/dist/indexer/scope-types.d.ts +3 -0
- package/dist/indexer/scope-types.d.ts.map +1 -1
- package/dist/indexer/scope.js +37 -38
- package/dist/indexer/scope.js.map +1 -1
- package/dist/indexer/shared.d.ts.map +1 -1
- package/dist/indexer/shared.js +3 -1
- package/dist/indexer/shared.js.map +1 -1
- package/dist/indexer/type-hierarchy.d.ts.map +1 -1
- package/dist/indexer/type-hierarchy.js +12 -8
- package/dist/indexer/type-hierarchy.js.map +1 -1
- package/dist/indexer/types.d.ts +27 -1
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/indexer/workspace-symbols.d.ts.map +1 -1
- package/dist/indexer/workspace-symbols.js +5 -3
- package/dist/indexer/workspace-symbols.js.map +1 -1
- package/dist/installer/locks.d.ts +10 -0
- package/dist/installer/locks.d.ts.map +1 -0
- package/dist/installer/locks.js +232 -0
- package/dist/installer/locks.js.map +1 -0
- package/dist/installer/registry.d.ts.map +1 -1
- package/dist/installer/registry.js +75 -235
- package/dist/installer/registry.js.map +1 -1
- package/dist/languages/definitions/csharp.d.ts.map +1 -1
- package/dist/languages/definitions/csharp.js +8 -0
- package/dist/languages/definitions/csharp.js.map +1 -1
- package/dist/languages/definitions/java.d.ts.map +1 -1
- package/dist/languages/definitions/java.js +3 -0
- package/dist/languages/definitions/java.js.map +1 -1
- package/dist/languages/definitions/python.d.ts.map +1 -1
- package/dist/languages/definitions/python.js +2 -0
- package/dist/languages/definitions/python.js.map +1 -1
- package/dist/languages/definitions/rust.d.ts.map +1 -1
- package/dist/languages/definitions/rust.js +2 -0
- package/dist/languages/definitions/rust.js.map +1 -1
- package/dist/languages/importStatementParsers.d.ts +2 -0
- package/dist/languages/importStatementParsers.d.ts.map +1 -1
- package/dist/languages/importStatementParsers.js +24 -10
- package/dist/languages/importStatementParsers.js.map +1 -1
- package/dist/mcp/http.d.ts +3 -1
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/http.js +69 -20
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/server.d.ts +58 -16
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +447 -140
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +51 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +129 -3
- package/dist/mcp/tools.js.map +1 -1
- package/dist/native/byteIndex.d.ts +26 -0
- package/dist/native/byteIndex.d.ts.map +1 -0
- package/dist/native/byteIndex.js +70 -0
- package/dist/native/byteIndex.js.map +1 -0
- package/dist/native/projectedTree.d.ts +3 -2
- package/dist/native/projectedTree.d.ts.map +1 -1
- package/dist/native/projectedTree.js +6 -50
- package/dist/native/projectedTree.js.map +1 -1
- package/dist/native/queryResults.d.ts +7 -1
- package/dist/native/queryResults.d.ts.map +1 -1
- package/dist/native/queryResults.js +13 -5
- package/dist/native/queryResults.js.map +1 -1
- package/dist/review/candidates.d.ts.map +1 -1
- package/dist/review/candidates.js +4 -1
- package/dist/review/candidates.js.map +1 -1
- package/dist/review/changes.d.ts +2 -0
- package/dist/review/changes.d.ts.map +1 -1
- package/dist/review/changes.js +10 -0
- package/dist/review/changes.js.map +1 -1
- package/dist/review/deleted.d.ts.map +1 -1
- package/dist/review/deleted.js +20 -2
- package/dist/review/deleted.js.map +1 -1
- package/dist/review/summaries.d.ts +5 -0
- package/dist/review/summaries.d.ts.map +1 -1
- package/dist/review/summaries.js +32 -21
- package/dist/review/summaries.js.map +1 -1
- package/dist/review/types.d.ts +3 -1
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js +8 -1
- package/dist/review/types.js.map +1 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +14 -5
- package/dist/review.js.map +1 -1
- package/dist/session.d.ts +20 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +76 -16
- package/dist/session.js.map +1 -1
- package/dist/sql/types.d.ts.map +1 -1
- package/dist/sqlite/query.d.ts +29 -0
- package/dist/sqlite/query.d.ts.map +1 -1
- package/dist/sqlite/query.js +98 -11
- package/dist/sqlite/query.js.map +1 -1
- package/dist/sqlite/rawQueryWorker.d.ts +22 -0
- package/dist/sqlite/rawQueryWorker.d.ts.map +1 -0
- package/dist/sqlite/rawQueryWorker.js +31 -0
- package/dist/sqlite/rawQueryWorker.js.map +1 -0
- package/dist/sqlite/rawQueryWorkerPool.d.ts +66 -0
- package/dist/sqlite/rawQueryWorkerPool.d.ts.map +1 -0
- package/dist/sqlite/rawQueryWorkerPool.js +142 -0
- package/dist/sqlite/rawQueryWorkerPool.js.map +1 -0
- package/dist/sqlite/schema.d.ts +2 -1
- package/dist/sqlite/schema.d.ts.map +1 -1
- package/dist/sqlite/schema.js +15 -1
- package/dist/sqlite/schema.js.map +1 -1
- package/dist/sqlite/write.d.ts.map +1 -1
- package/dist/sqlite/write.js +15 -0
- package/dist/sqlite/write.js.map +1 -1
- package/dist/sqlite-driver.d.ts +11 -0
- package/dist/sqlite-driver.d.ts.map +1 -1
- package/dist/sqlite-driver.js +28 -2
- package/dist/sqlite-driver.js.map +1 -1
- package/dist/sqlite.d.ts +1 -1
- package/dist/sqlite.d.ts.map +1 -1
- package/dist/sqlite.js +1 -1
- package/dist/sqlite.js.map +1 -1
- package/dist/util/bloomFilter.d.ts +3 -2
- package/dist/util/bloomFilter.d.ts.map +1 -1
- package/dist/util/bloomFilter.js +8 -8
- package/dist/util/bloomFilter.js.map +1 -1
- package/dist/util/concurrency.d.ts +1 -0
- package/dist/util/concurrency.d.ts.map +1 -1
- package/dist/util/concurrency.js +9 -2
- package/dist/util/concurrency.js.map +1 -1
- package/dist/util/confinedFile.d.ts +42 -2
- package/dist/util/confinedFile.d.ts.map +1 -1
- package/dist/util/confinedFile.js +114 -3
- package/dist/util/confinedFile.js.map +1 -1
- package/dist/util/errors.d.ts +2 -0
- package/dist/util/errors.d.ts.map +1 -1
- package/dist/util/errors.js +18 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/util/git.d.ts +2 -0
- package/dist/util/git.d.ts.map +1 -1
- package/dist/util/git.js +174 -26
- package/dist/util/git.js.map +1 -1
- package/dist/util/identifiers.d.ts +75 -0
- package/dist/util/identifiers.d.ts.map +1 -0
- package/dist/util/identifiers.js +82 -0
- package/dist/util/identifiers.js.map +1 -0
- package/dist/util/paths.d.ts.map +1 -1
- package/dist/util/paths.js +45 -9
- package/dist/util/paths.js.map +1 -1
- package/dist/util/projectFiles.d.ts.map +1 -1
- package/dist/util/projectFiles.js +43 -14
- package/dist/util/projectFiles.js.map +1 -1
- package/dist/util/resolution/jvm.d.ts.map +1 -1
- package/dist/util/resolution/jvm.js +20 -9
- package/dist/util/resolution/jvm.js.map +1 -1
- package/dist/util/resolution/php.d.ts.map +1 -1
- package/dist/util/resolution/php.js +6 -5
- package/dist/util/resolution/php.js.map +1 -1
- package/dist/util/resolution/tsconfig.d.ts.map +1 -1
- package/dist/util/resolution/tsconfig.js +26 -12
- package/dist/util/resolution/tsconfig.js.map +1 -1
- package/dist/util/rustTestModules.d.ts.map +1 -1
- package/dist/util/rustTestModules.js +4 -2
- package/dist/util/rustTestModules.js.map +1 -1
- package/dist/util/specifiers.d.ts.map +1 -1
- package/dist/util/specifiers.js +10 -3
- package/dist/util/specifiers.js.map +1 -1
- package/dist/util/sqliteSchema.d.ts.map +1 -1
- package/dist/util/sqliteSchema.js +10 -1
- package/dist/util/sqliteSchema.js.map +1 -1
- package/dist/worker/nativeExtractWorker.d.ts +4 -2
- package/dist/worker/nativeExtractWorker.d.ts.map +1 -1
- package/dist/worker/nativeExtractWorker.js +12 -11
- package/dist/worker/nativeExtractWorker.js.map +1 -1
- package/docs/mcp.md +35 -14
- package/package.json +3 -3
|
@@ -4,12 +4,14 @@ import fsp from "node:fs/promises";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { performance } from "node:perf_hooks";
|
|
6
6
|
import { languageExtensionPatterns, supportForFile } from "../languages.js";
|
|
7
|
+
import { isJsTsLanguage } from "../languages/js-family.js";
|
|
7
8
|
import { loadWorkspaceConfig, resolveWorkspacePackage } from "../util/workspace.js";
|
|
8
9
|
import { DEFAULT_PROJECT_PATTERNS, discoverProjectFiles, listProjectFiles, } from "../util/projectFiles.js";
|
|
9
10
|
import { getGitHead, isGitRepo, getGitBlobHashes, listChangedFiles } from "../util/git.js";
|
|
10
|
-
import {
|
|
11
|
-
import { assertFilePathWithinRoot, fileIdentityKey, initializeFileIdentityCaseSensitivity, normalizePath, } from "../util/paths.js";
|
|
11
|
+
import { clearResolutionCaches, resolveSpecifier } from "../util/resolution.js";
|
|
12
|
+
import { assertFilePathWithinRoot, fileIdentityKey, initializeFileIdentityCaseSensitivity, isFilePathWithinRoot, normalizePath, } from "../util/paths.js";
|
|
12
13
|
import { mapLimit } from "../util/concurrency.js";
|
|
14
|
+
import { readConfinedUtf8File } from "../util/confinedFile.js";
|
|
13
15
|
import { resolveWorkerThreadCount } from "../util/workerThreads.js";
|
|
14
16
|
import { logWithLevel } from "../logging.js";
|
|
15
17
|
import { collectGraph } from "../graph-builder.js";
|
|
@@ -26,8 +28,9 @@ import { initNativeBackendReport } from "../native/nativeBackendReport.js";
|
|
|
26
28
|
import { closeDuplicateUnitCacheDatabase } from "../duplicates.js";
|
|
27
29
|
import { isNativeRequiredUnavailableError } from "../native/treeSitterNative.js";
|
|
28
30
|
import { isNodeSqliteUnavailableError } from "../sqlite-driver.js";
|
|
29
|
-
import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, verifyManifestEntries, writeProjectIndexSnapshot, writeToCache, } from "./build-cache.js";
|
|
30
|
-
import {
|
|
31
|
+
import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, fileSignatureFromSource, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeIndexedFileInputsWithinRoot, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, tryLoadProjectSnapshotModules, verifyManifestEntries, writeModulesToCache, writeProjectIndexSnapshot, writeToCache, } from "./build-cache.js";
|
|
32
|
+
import { computeResolverEnvironmentFingerprint } from "./build-cache/resolver-environment.js";
|
|
33
|
+
import { cacheRoot } from "./build-cache/location.js";
|
|
31
34
|
import { SymbolKind, } from "./types.js";
|
|
32
35
|
import { isNonNativeParserUnavailableError, isParserSyntaxTree } from "../parserBackend.js";
|
|
33
36
|
import { isUnsupportedParserInputError } from "../languages/filePrep.js";
|
|
@@ -35,7 +38,7 @@ import { buildSqlFactCache, buildSqlModuleIndex, sqlCorpusSignature } from "../s
|
|
|
35
38
|
import { finalizeProjectIndex } from "./finalize.js";
|
|
36
39
|
import { toManifestFileEntry, writeIndexManifestSnapshot } from "./build-manifest.js";
|
|
37
40
|
import { prepareFileContextForBuild, setupWorkerPool, teardownWorkerPool, } from "./build-workers.js";
|
|
38
|
-
import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, collectDeletedTrackedFileDependents, collectTrackedFileDependents, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
|
|
41
|
+
import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, buildTrackedFileReverseDependencies, collectDeletedTrackedFileDependents, collectTrackedFileDependents, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
|
|
39
42
|
import { parsedCacheMaxEntries, setParsedCacheEntry } from "./parsed-cache.js";
|
|
40
43
|
function initParserBackendDegradationReport(report) {
|
|
41
44
|
if (!report)
|
|
@@ -74,13 +77,17 @@ function recordParserBackendDegradation(report, entry) {
|
|
|
74
77
|
return;
|
|
75
78
|
parserReport.files.push(entry);
|
|
76
79
|
}
|
|
80
|
+
function isConfinedFileReadError(error) {
|
|
81
|
+
return (error instanceof Error &&
|
|
82
|
+
/outside project root|possible path confinement race|changed between verification and open|confined file target/u.test(error.message));
|
|
83
|
+
}
|
|
77
84
|
function createEmptyModuleIndex(file) {
|
|
78
85
|
return { file, exports: [], imports: [], locals: [] };
|
|
79
86
|
}
|
|
80
87
|
async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot, graphOptions, workspaceConfig, logLevel) {
|
|
81
88
|
if (!support.supportsCrossModuleSymbols)
|
|
82
89
|
return;
|
|
83
|
-
if (support.id
|
|
90
|
+
if (!isJsTsLanguage(support.id))
|
|
84
91
|
return;
|
|
85
92
|
const { matchPath } = await import("../util/resolution.js").then((mod) => mod.loadNearestTsconfigFor(file, projectRoot, logLevel));
|
|
86
93
|
for (const entry of mod.exports) {
|
|
@@ -88,29 +95,43 @@ async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot,
|
|
|
88
95
|
continue;
|
|
89
96
|
}
|
|
90
97
|
if (entry.fromModule.startsWith(".")) {
|
|
98
|
+
entry.moduleSpecifier ??= entry.fromModule;
|
|
91
99
|
const resolved = await resolveSpecifier(file, entry.fromModule, projectRoot, matchPath, workspaceConfig, {
|
|
92
100
|
resolveNodeModules: !!graphOptions.resolveNodeModules,
|
|
93
101
|
...(graphOptions.resolutionHints ? { resolutionHints: graphOptions.resolutionHints } : {}),
|
|
94
102
|
});
|
|
95
|
-
if (typeof resolved === "string")
|
|
103
|
+
if (typeof resolved === "string" && isFilePathWithinRoot(projectRoot, resolved))
|
|
96
104
|
entry.fromModule = resolved;
|
|
97
105
|
continue;
|
|
98
106
|
}
|
|
99
107
|
const pkgResolved = await resolveWorkspacePackage(entry.fromModule, workspaceConfig);
|
|
100
|
-
if (pkgResolved)
|
|
101
|
-
entry.
|
|
108
|
+
if (pkgResolved) {
|
|
109
|
+
entry.moduleSpecifier ??= entry.fromModule;
|
|
110
|
+
if (isFilePathWithinRoot(projectRoot, pkgResolved))
|
|
111
|
+
entry.fromModule = pkgResolved;
|
|
112
|
+
}
|
|
102
113
|
}
|
|
103
114
|
}
|
|
104
115
|
async function buildIndexedModuleForFile(args) {
|
|
105
|
-
const prepared = await prepareFileContextForBuild(args.file, args.support, args.opts, args.workerSetup, args.report);
|
|
116
|
+
const prepared = await prepareFileContextForBuild(args.file, args.support, args.opts, args.workerSetup, args.report, args.confinedRoot, args.projectRoot, args.trustedSource);
|
|
106
117
|
const { source, sup, nativeQueries, embeddedBlocks } = prepared;
|
|
107
118
|
let resolvedLang = prepared.lang;
|
|
108
119
|
let tree;
|
|
109
|
-
const graphOnlyLanguage = isGraphOnlyLanguage(sup.id)
|
|
120
|
+
const graphOnlyLanguage = isGraphOnlyLanguage(sup.id), nativeSourceLimitFallback = prepared.nativeFallbackReason === "queryFailure" &&
|
|
121
|
+
!!prepared.nativeError?.startsWith("source exceeds native byte limit");
|
|
110
122
|
if (prepared.syntaxTree) {
|
|
111
|
-
|
|
123
|
+
const parsedTree = new ProjectedSyntaxTree(source, prepared.syntaxTree);
|
|
124
|
+
tree = parsedTree;
|
|
125
|
+
setParsedCacheEntry(args.parsedMap, args.file, {
|
|
126
|
+
source,
|
|
127
|
+
tree: parsedTree,
|
|
128
|
+
sup,
|
|
129
|
+
...(resolvedLang ? { lang: resolvedLang } : {}),
|
|
130
|
+
...(embeddedBlocks ? { embeddedBlocks } : {}),
|
|
131
|
+
nativeQueries,
|
|
132
|
+
}, args.parsedCacheMaxEntries);
|
|
112
133
|
}
|
|
113
|
-
else if (!nativeQueries && !graphOnlyLanguage && sup.id !== "sql") {
|
|
134
|
+
else if (!nativeQueries && !graphOnlyLanguage && sup.id !== "sql" && !nativeSourceLimitFallback) {
|
|
114
135
|
const parseAttempt = attemptParsePreparedFileContext(prepared);
|
|
115
136
|
const parsed = parseAttempt.parsed;
|
|
116
137
|
if (parsed) {
|
|
@@ -135,14 +156,24 @@ async function buildIndexedModuleForFile(args) {
|
|
|
135
156
|
if (parsed) {
|
|
136
157
|
tree = parsed.tree;
|
|
137
158
|
resolvedLang = parsed.lang ?? resolvedLang;
|
|
159
|
+
setParsedCacheEntry(args.parsedMap, args.file, parsed, args.parsedCacheMaxEntries);
|
|
138
160
|
}
|
|
139
161
|
}
|
|
140
162
|
const lacksParserContext = !nativeQueries && !tree;
|
|
141
|
-
if (args.bloomFilterCache) {
|
|
142
|
-
const filter = buildBloomFilterFromSource(source, sup
|
|
163
|
+
if (args.bloomFilterCache && !nativeSourceLimitFallback) {
|
|
164
|
+
const filter = buildBloomFilterFromSource(source, sup);
|
|
143
165
|
args.bloomFilterCache.set(args.file, filter);
|
|
144
166
|
}
|
|
145
|
-
|
|
167
|
+
// Single builder so an option added here always reaches both the primary source and
|
|
168
|
+
// every embedded (SFC) block, instead of one path silently missing a future option.
|
|
169
|
+
const sharedImportOptions = {
|
|
170
|
+
graphOptions: args.graphOptions,
|
|
171
|
+
...(args.opts?.native ? { native: args.opts.native } : {}),
|
|
172
|
+
...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
|
|
173
|
+
...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
|
|
174
|
+
...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
|
|
175
|
+
};
|
|
176
|
+
const imports = nativeSourceLimitFallback || sup.id === "sql"
|
|
146
177
|
? []
|
|
147
178
|
: await collectImportsForFile(args.file, args.projectRoot, {
|
|
148
179
|
source,
|
|
@@ -150,21 +181,13 @@ async function buildIndexedModuleForFile(args) {
|
|
|
150
181
|
sup,
|
|
151
182
|
...(resolvedLang ? { lang: resolvedLang } : {}),
|
|
152
183
|
...(nativeQueries !== undefined ? { nativeQueries } : {}),
|
|
153
|
-
|
|
154
|
-
...(args.opts?.native ? { native: args.opts.native } : {}),
|
|
155
|
-
...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
|
|
156
|
-
...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
|
|
157
|
-
...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
|
|
184
|
+
...sharedImportOptions,
|
|
158
185
|
});
|
|
159
186
|
for (const block of embeddedBlocks ?? []) {
|
|
160
187
|
imports.push(...(await collectImportsForFile(args.file, args.projectRoot, {
|
|
161
188
|
source: block.source,
|
|
162
189
|
sup: block.sup,
|
|
163
|
-
|
|
164
|
-
...(args.opts?.native ? { native: args.opts.native } : {}),
|
|
165
|
-
...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
|
|
166
|
-
...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
|
|
167
|
-
...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
|
|
190
|
+
...sharedImportOptions,
|
|
168
191
|
})));
|
|
169
192
|
}
|
|
170
193
|
collectJsonDependencies(imports, args.jsonDependencies);
|
|
@@ -187,14 +210,16 @@ async function buildIndexedModuleForFile(args) {
|
|
|
187
210
|
await resolveCrossModuleSymbolExports(args.file, mod, sup, args.projectRoot, args.graphOptions, args.workspaceConfig, args.opts?.logLevel);
|
|
188
211
|
const sigInfo = args.fileSignatures.get(args.file);
|
|
189
212
|
const cacheable = !prepared.nativeFallbackReason && !lacksParserContext;
|
|
213
|
+
let cacheWrite;
|
|
190
214
|
if (sigInfo && cacheable) {
|
|
191
215
|
const cacheSig = args.cacheEnabled
|
|
192
|
-
? await moduleCacheSignatureForFile(args.file, sigInfo, args.opts)
|
|
216
|
+
? await moduleCacheSignatureForFile(args.file, sigInfo, args.opts, args.resolverEnvironmentFingerprint)
|
|
193
217
|
: sigInfo.cacheSig;
|
|
194
|
-
|
|
218
|
+
cacheWrite = { file: args.file, sig: cacheSig, mod };
|
|
195
219
|
}
|
|
196
220
|
return {
|
|
197
221
|
module: mod,
|
|
222
|
+
...(cacheWrite !== undefined ? { cacheWrite } : {}),
|
|
198
223
|
graphContext: {
|
|
199
224
|
source,
|
|
200
225
|
sup,
|
|
@@ -242,19 +267,24 @@ function graphEdgeKey(edge) {
|
|
|
242
267
|
const target = edge.to.type === "file" ? `file:${fileIdentityKey(edge.to.path)}` : `external:${edge.to.name}`;
|
|
243
268
|
return `${from}::${target}::${edge.raw ?? ""}::${edge.typeOnly ? 1 : 0}`;
|
|
244
269
|
}
|
|
245
|
-
async function moduleCacheSignatureForFile(file, sigInfo, opts) {
|
|
270
|
+
async function moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint) {
|
|
246
271
|
const baseSignature = await cacheSignatureForFile(file, sigInfo, opts);
|
|
247
272
|
const normalizedExtensions = normalizeLanguageExtensions(opts?.languageExtensions);
|
|
248
|
-
|
|
273
|
+
const resolveNodeModules = normalizeGraphOptions(opts?.graph).resolveNodeModules;
|
|
274
|
+
if (!normalizedExtensions && !resolveNodeModules)
|
|
249
275
|
return baseSignature;
|
|
250
276
|
// Combine via a hash rather than raw concatenation: the disk cache stores this string in a
|
|
251
277
|
// SQLite TEXT column, and node:sqlite's DatabaseSync silently truncates TEXT bind parameters
|
|
252
278
|
// at embedded NUL bytes, so a raw separator character risks the stored and freshly-computed
|
|
253
279
|
// signatures never matching (permanent cache miss) if either baseSignature or the serialized
|
|
254
|
-
// extensions ever contained one.
|
|
280
|
+
// extensions ever contained one. A cached ModuleIndex's ImportBinding.resolved values differ
|
|
281
|
+
// depending on whether resolveNodeModules was on at write time (resolved node_modules targets
|
|
282
|
+
// vs. external), so that state and the environment that produced it must be part of the key.
|
|
255
283
|
const hash = crypto.createHash("sha1");
|
|
256
284
|
hash.update(baseSignature);
|
|
257
|
-
hash.update(JSON.stringify(Object.entries(normalizedExtensions)));
|
|
285
|
+
hash.update(JSON.stringify(Object.entries(normalizedExtensions ?? {})));
|
|
286
|
+
hash.update(resolveNodeModules ? "\0resolveNodeModules" : "");
|
|
287
|
+
hash.update(resolverEnvironmentFingerprint === null ? "\0resolverEnvironmentTooLarge" : (resolverEnvironmentFingerprint ?? ""));
|
|
258
288
|
return hash.digest("hex");
|
|
259
289
|
}
|
|
260
290
|
function projectPatternsForLanguageExtensions(opts) {
|
|
@@ -325,21 +355,25 @@ function expandStarImports(modules, opts) {
|
|
|
325
355
|
}
|
|
326
356
|
}
|
|
327
357
|
function toProjectIndexManifestEntry(entry) {
|
|
358
|
+
// A git signature alone is already a strong content identity (`fileSignature()` derives
|
|
359
|
+
// `cacheSig` the same way: `gitSig ?? contentHash ?? sig`), so entries sourced from the disk
|
|
360
|
+
// manifest (which does not persist `cacheSig`) still get one whenever `gitSig` is available.
|
|
361
|
+
const cacheSig = entry.cacheSig ?? entry.gitSig;
|
|
328
362
|
return {
|
|
329
363
|
sig: entry.sig,
|
|
330
364
|
...(entry.gitSig ? { gitSig: entry.gitSig } : {}),
|
|
365
|
+
...(cacheSig ? { cacheSig } : {}),
|
|
331
366
|
};
|
|
332
367
|
}
|
|
333
368
|
function projectIndexManifestEntries(entries) {
|
|
334
369
|
return new Map(Array.from(entries, ([file, entry]) => [file, toProjectIndexManifestEntry(entry)]));
|
|
335
370
|
}
|
|
336
371
|
function createIndexBuildRunState(projectRoot, opts, graphOptions = normalizeGraphOptions(opts?.graph)) {
|
|
337
|
-
const report = opts?.report;
|
|
338
|
-
|
|
339
|
-
initNativeBackendReport(report);
|
|
372
|
+
const report = opts?.report ?? { timings: {} };
|
|
373
|
+
initNativeBackendReport(report);
|
|
340
374
|
const cacheMode = opts?.cache ?? "off";
|
|
341
375
|
return {
|
|
342
|
-
normalizedProjectRoot: normalizePath(projectRoot),
|
|
376
|
+
normalizedProjectRoot: normalizePath(path.resolve(projectRoot)),
|
|
343
377
|
report,
|
|
344
378
|
timings: report?.timings,
|
|
345
379
|
totalStart: performance.now(),
|
|
@@ -371,7 +405,14 @@ function buildConcurrency(opts) {
|
|
|
371
405
|
async function prepareFileSignatures(args) {
|
|
372
406
|
const entries = await mapLimit(args.files, args.concurrency, async (file) => {
|
|
373
407
|
const gitSig = args.gitSigMap.get(file);
|
|
374
|
-
const
|
|
408
|
+
const source = args.confinedRoot
|
|
409
|
+
? await readConfinedUtf8File(args.confinedRoot, args.projectRoot, file)
|
|
410
|
+
: undefined;
|
|
411
|
+
if (source !== undefined) {
|
|
412
|
+
args.trustedSources?.set(file, source);
|
|
413
|
+
return [file, fileSignatureFromSource(source, gitSig)];
|
|
414
|
+
}
|
|
415
|
+
const sigInfo = await fileSignature(file, args.needsContentHash ? args.opts?.cacheStrict : false, gitSig, {
|
|
375
416
|
forceContentHash: args.cacheEnabled && !gitSig,
|
|
376
417
|
});
|
|
377
418
|
return [file, sigInfo];
|
|
@@ -382,7 +423,7 @@ async function buildProjectIndexFromExport(projectRoot, opts, helperOpts) {
|
|
|
382
423
|
return buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpts);
|
|
383
424
|
}
|
|
384
425
|
async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperOpts) {
|
|
385
|
-
|
|
426
|
+
clearResolutionCaches();
|
|
386
427
|
await initializeFileIdentityCaseSensitivity(projectRoot);
|
|
387
428
|
const { normalizedProjectRoot, report, timings, totalStart, cacheMode, cacheEnabled, graphOptions, onFallbackImportExtraction, } = createIndexBuildRunState(projectRoot, opts);
|
|
388
429
|
const manifestMode = helperOpts?.manifestMode ?? "off";
|
|
@@ -390,7 +431,11 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
390
431
|
const shouldWriteManifest = manifestMode === "read-write";
|
|
391
432
|
const projectFiles = helperOpts?.projectFiles;
|
|
392
433
|
initManifestReport(report, useManifest, false);
|
|
393
|
-
const
|
|
434
|
+
const confinedRoot = helperOpts?.confineReads ? await fsp.realpath(projectRoot) : undefined;
|
|
435
|
+
const [trustedSources, normalizedFiles] = [
|
|
436
|
+
confinedRoot ? new Map() : undefined,
|
|
437
|
+
Array.from(new Set(normalizeIndexedFileInputs(projectRoot, rawFiles ?? [], "Index file"))),
|
|
438
|
+
];
|
|
394
439
|
if (!normalizedFiles.length && helperOpts?.warnNoFilesMessage) {
|
|
395
440
|
logWithLevel(opts?.logLevel, "warn", helperOpts.warnNoFilesMessage);
|
|
396
441
|
}
|
|
@@ -398,11 +443,21 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
398
443
|
if (fileReport)
|
|
399
444
|
fileReport.total = normalizedFiles.length;
|
|
400
445
|
const manifestStart = performance.now();
|
|
401
|
-
const manifest = useManifest && !helperOpts?.ignoreExistingManifest ? await loadManifest(projectRoot, opts) : null;
|
|
446
|
+
const manifest = useManifest && !helperOpts?.ignoreExistingManifest ? await loadManifest(projectRoot, opts, report) : null;
|
|
402
447
|
const manifestFiles = sanitizeManifestEntriesForRoot(projectRoot, manifest?.files);
|
|
403
448
|
const manifestOptionDiffs = manifest ? diffBuildOptions(manifest.buildOptions, opts) : [];
|
|
404
449
|
const languageExtensionsChanged = manifestOptionDiffs.includes("languageExtensions");
|
|
405
450
|
const implementationChanged = manifestOptionDiffs.includes("implementation");
|
|
451
|
+
let resolverEnvironmentFingerprint;
|
|
452
|
+
let resolverEnvironmentMatchesManifest = true;
|
|
453
|
+
if (cacheEnabled && graphOptions.resolveNodeModules) {
|
|
454
|
+
resolverEnvironmentFingerprint = await computeResolverEnvironmentFingerprint(projectRoot, normalizedFiles);
|
|
455
|
+
if (useManifest) {
|
|
456
|
+
resolverEnvironmentMatchesManifest =
|
|
457
|
+
resolverEnvironmentFingerprint !== null &&
|
|
458
|
+
manifest?.resolverEnvironmentFingerprint === resolverEnvironmentFingerprint;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
406
461
|
if (timings && useManifest) {
|
|
407
462
|
timings.manifestMs = Math.round(performance.now() - manifestStart);
|
|
408
463
|
}
|
|
@@ -426,13 +481,14 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
426
481
|
const cachedGraphEntries = manifest &&
|
|
427
482
|
!languageExtensionsChanged &&
|
|
428
483
|
!implementationChanged &&
|
|
484
|
+
resolverEnvironmentMatchesManifest &&
|
|
429
485
|
graphOptionsEqual(manifest.graphOptions, graphOptions)
|
|
430
486
|
? new Map(Object.entries(manifestFiles).filter(([file]) => !staleCachedEdgeFiles.has(file)))
|
|
431
487
|
: undefined;
|
|
488
|
+
const manifestEntries = shouldWriteManifest ? new Map() : undefined;
|
|
432
489
|
if (report?.manifest) {
|
|
433
490
|
report.manifest.reused = !!cachedGraphEntries;
|
|
434
491
|
}
|
|
435
|
-
const manifestEntries = shouldWriteManifest ? new Map() : undefined;
|
|
436
492
|
const manifestEntriesForIndex = useManifest
|
|
437
493
|
? projectIndexManifestEntries(cachedGraphEntries ?? [])
|
|
438
494
|
: new Map();
|
|
@@ -455,11 +511,14 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
455
511
|
})
|
|
456
512
|
.sort((left, right) => left.localeCompare(right));
|
|
457
513
|
const fileSignatures = await prepareFileSignatures({
|
|
514
|
+
projectRoot,
|
|
458
515
|
files: sqlFiles,
|
|
459
516
|
opts,
|
|
460
517
|
gitSigMap,
|
|
461
518
|
cacheEnabled,
|
|
519
|
+
needsContentHash: true,
|
|
462
520
|
concurrency: conc,
|
|
521
|
+
...(confinedRoot ? { confinedRoot, trustedSources } : {}),
|
|
463
522
|
});
|
|
464
523
|
const sqlCorpusSig = sqlCorpusSignature(sqlFiles, fileSignatures);
|
|
465
524
|
let sqlFactCachePromise;
|
|
@@ -482,7 +541,9 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
482
541
|
const bloomFilterCache = useBloomFilters
|
|
483
542
|
? new (await import("../util/bloomFilter.js")).BloomFilterCache()
|
|
484
543
|
: undefined;
|
|
485
|
-
const persistedBloomFilters = bloomFilterCache
|
|
544
|
+
const persistedBloomFilters = bloomFilterCache
|
|
545
|
+
? await tryLoadPersistedBloomFilters(projectRoot, opts, report)
|
|
546
|
+
: null;
|
|
486
547
|
const parsedMap = new Map();
|
|
487
548
|
const workspaceConfig = await loadWorkspaceConfig(projectRoot);
|
|
488
549
|
const parseStart = performance.now();
|
|
@@ -509,9 +570,16 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
509
570
|
let sigInfo = fileSignatures.get(file);
|
|
510
571
|
if (!sigInfo) {
|
|
511
572
|
const gitSig = gitSigMap.get(file);
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
573
|
+
const source = confinedRoot ? await readConfinedUtf8File(confinedRoot, projectRoot, file) : undefined;
|
|
574
|
+
if (source !== undefined) {
|
|
575
|
+
trustedSources?.set(file, source);
|
|
576
|
+
sigInfo = fileSignatureFromSource(source, gitSig);
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
sigInfo = await fileSignature(file, opts?.cacheStrict, gitSig, {
|
|
580
|
+
forceContentHash: cacheEnabled && !gitSig,
|
|
581
|
+
});
|
|
582
|
+
}
|
|
515
583
|
fileSignatures.set(file, sigInfo);
|
|
516
584
|
}
|
|
517
585
|
manifestEntriesForIndex.set(file, toProjectIndexManifestEntry(sigInfo));
|
|
@@ -520,8 +588,13 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
520
588
|
if (initialManifestEntry)
|
|
521
589
|
manifestEntries.set(file, initialManifestEntry);
|
|
522
590
|
}
|
|
523
|
-
const cacheSig = cacheEnabled
|
|
524
|
-
|
|
591
|
+
const cacheSig = cacheEnabled
|
|
592
|
+
? await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint)
|
|
593
|
+
: sigInfo.cacheSig;
|
|
594
|
+
const canReuseModuleCache = cacheEnabled && (!graphOptions.resolveNodeModules || resolverEnvironmentFingerprint !== null);
|
|
595
|
+
let mod = canReuseModuleCache
|
|
596
|
+
? tryLoadFromCache(projectRoot, file, cacheSig, opts, report)
|
|
597
|
+
: null;
|
|
525
598
|
if (mod && fileReport) {
|
|
526
599
|
fileReport.cached = (fileReport.cached ?? 0) + 1;
|
|
527
600
|
}
|
|
@@ -555,7 +628,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
555
628
|
...(sqlFactCache ? { sqlFactCache } : {}),
|
|
556
629
|
});
|
|
557
630
|
if (bloomFilterCache) {
|
|
558
|
-
const persistedFilter = persistedBloomFilters?.get(file);
|
|
631
|
+
const persistedFilter = persistedBloomFilters?.get(file, sigInfo);
|
|
559
632
|
if (persistedFilter) {
|
|
560
633
|
bloomFilterCache.set(file, persistedFilter);
|
|
561
634
|
}
|
|
@@ -565,15 +638,16 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
565
638
|
bloomFilterCache.set(file, filter);
|
|
566
639
|
}
|
|
567
640
|
}
|
|
568
|
-
return [file, mod, edges];
|
|
641
|
+
return [file, mod, edges, undefined];
|
|
569
642
|
}
|
|
570
643
|
if (fileReport)
|
|
571
644
|
fileReport.parsed = (fileReport.parsed ?? 0) + 1;
|
|
572
645
|
const support = supportForFile(file, opts?.languageExtensions);
|
|
573
646
|
if (!support)
|
|
574
|
-
return [file, createEmptyModuleIndex(file), []];
|
|
647
|
+
return [file, createEmptyModuleIndex(file), [], undefined];
|
|
575
648
|
ensureBuildProgressStarted();
|
|
576
649
|
let graphContext;
|
|
650
|
+
let cacheWrite;
|
|
577
651
|
if (!mod) {
|
|
578
652
|
const built = await buildIndexedModuleForFile({
|
|
579
653
|
file,
|
|
@@ -584,6 +658,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
584
658
|
graphOptions,
|
|
585
659
|
workspaceConfig,
|
|
586
660
|
workerSetup,
|
|
661
|
+
...(resolverEnvironmentFingerprint !== undefined ? { resolverEnvironmentFingerprint } : {}),
|
|
587
662
|
parsedMap,
|
|
588
663
|
parsedCacheMaxEntries: parsedCacheMaxEntries(opts),
|
|
589
664
|
jsonDependencies,
|
|
@@ -591,9 +666,11 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
591
666
|
onFallbackImportExtraction,
|
|
592
667
|
fileSignatures,
|
|
593
668
|
cacheEnabled,
|
|
669
|
+
...(confinedRoot ? { confinedRoot, trustedSource: trustedSources?.get(file) } : {}),
|
|
594
670
|
});
|
|
595
671
|
mod = built.module;
|
|
596
672
|
graphContext = built.graphContext;
|
|
673
|
+
cacheWrite = built.cacheWrite;
|
|
597
674
|
}
|
|
598
675
|
else {
|
|
599
676
|
collectJsonDependencies(mod.imports, jsonDependencies);
|
|
@@ -619,13 +696,15 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
619
696
|
allFiles: normalizedFiles,
|
|
620
697
|
...(sqlFactCache ? { sqlFactCache } : {}),
|
|
621
698
|
});
|
|
622
|
-
return [file, mod ?? createEmptyModuleIndex(file), edges];
|
|
699
|
+
return [file, mod ?? createEmptyModuleIndex(file), edges, cacheWrite];
|
|
623
700
|
}
|
|
624
701
|
catch (error) {
|
|
625
702
|
if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
|
|
626
703
|
throw error;
|
|
704
|
+
if (isConfinedFileReadError(error))
|
|
705
|
+
throw error;
|
|
627
706
|
if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) {
|
|
628
|
-
return [file, createEmptyModuleIndex(file), []];
|
|
707
|
+
return [file, createEmptyModuleIndex(file), [], undefined];
|
|
629
708
|
}
|
|
630
709
|
recordFileFailure(report, file, error);
|
|
631
710
|
logWithLevel(opts?.logLevel, "warn", `Warning: Failed to process file ${file}:`, error);
|
|
@@ -662,11 +741,17 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
662
741
|
graph.nodes.add(edge.to.path);
|
|
663
742
|
}
|
|
664
743
|
};
|
|
665
|
-
|
|
744
|
+
const pendingCacheWrites = [];
|
|
745
|
+
for (const [file, mod, edges, cacheWrite] of fileResults) {
|
|
666
746
|
modules.set(fileIdentityKey(file), mod);
|
|
667
747
|
appendUniqueGraphEdges(edges);
|
|
748
|
+
if (cacheWrite)
|
|
749
|
+
pendingCacheWrites.push(cacheWrite);
|
|
750
|
+
}
|
|
751
|
+
if (pendingCacheWrites.length) {
|
|
752
|
+
writeModulesToCache(projectRoot, pendingCacheWrites, opts);
|
|
668
753
|
}
|
|
669
|
-
const workspaceManifestEdges = await collectWorkspaceManifestDependencyEdges(projectRoot,
|
|
754
|
+
const workspaceManifestEdges = await collectWorkspaceManifestDependencyEdges(projectRoot, normalizedFiles.filter((file) => path.basename(file) === "package.json"), opts?.discovery, opts?.logLevel);
|
|
670
755
|
appendUniqueGraphEdges(workspaceManifestEdges);
|
|
671
756
|
if (timings)
|
|
672
757
|
timings.graphMs = Math.round(performance.now() - graphStart);
|
|
@@ -674,11 +759,23 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
674
759
|
ensureJsonModule(modules, jsonPath);
|
|
675
760
|
}
|
|
676
761
|
expandStarImports(modules, opts);
|
|
762
|
+
if (manifestEntries) {
|
|
763
|
+
for (const [file, signature] of fileSignatures) {
|
|
764
|
+
if (manifestEntries.has(file))
|
|
765
|
+
continue;
|
|
766
|
+
manifestEntries.set(file, {
|
|
767
|
+
sig: signature.sig,
|
|
768
|
+
...(signature.gitSig ? { gitSig: signature.gitSig } : {}),
|
|
769
|
+
edges: [],
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
677
773
|
if (manifestEntries) {
|
|
678
774
|
await writeIndexManifestSnapshot({
|
|
679
775
|
projectRoot,
|
|
680
776
|
opts,
|
|
681
777
|
graphOptions,
|
|
778
|
+
...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
|
|
682
779
|
files: manifestEntries,
|
|
683
780
|
timings,
|
|
684
781
|
manifestReport: report?.manifest,
|
|
@@ -686,6 +783,12 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
686
783
|
...(helperOpts?.symlinkDirectories !== undefined ? { symlinkDirectories: helperOpts.symlinkDirectories } : {}),
|
|
687
784
|
});
|
|
688
785
|
}
|
|
786
|
+
const indexManifestEntries = manifestEntries
|
|
787
|
+
? projectIndexManifestEntries(Array.from(manifestEntries, ([file, entry]) => {
|
|
788
|
+
const cacheSig = fileSignatures.get(file)?.cacheSig;
|
|
789
|
+
return [file, { ...entry, ...(cacheSig ? { cacheSig } : {}) }];
|
|
790
|
+
}))
|
|
791
|
+
: manifestEntriesForIndex;
|
|
689
792
|
const index = await finalizeProjectIndex({
|
|
690
793
|
projectRoot,
|
|
691
794
|
normalizedProjectRoot,
|
|
@@ -698,10 +801,10 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
698
801
|
bloomFilterCache,
|
|
699
802
|
...(projectFiles !== undefined ? { projectFiles } : {}),
|
|
700
803
|
buildReport: report,
|
|
701
|
-
manifestEntries:
|
|
804
|
+
manifestEntries: indexManifestEntries,
|
|
702
805
|
});
|
|
703
806
|
if (manifestEntries) {
|
|
704
|
-
await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries));
|
|
807
|
+
await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot));
|
|
705
808
|
}
|
|
706
809
|
if (buildStartedAt !== undefined) {
|
|
707
810
|
emitIndexLifecycleProgress(opts, "complete", "build", index.byFile.size, performance.now() - buildStartedAt);
|
|
@@ -721,34 +824,29 @@ async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpt
|
|
|
721
824
|
// full-tree symlink probe. Off and memory modes never read or write this disk
|
|
722
825
|
// manifest, keeping read-only builds from mutating the project root. A missing or
|
|
723
826
|
// unusable manifest falls back to probing once.
|
|
724
|
-
//
|
|
725
|
-
//
|
|
726
|
-
// otherwise never be discovered. `--cache-strict`/`--cache-verify` are explicit asks
|
|
727
|
-
// for maximum correctness over speed, so both force a fresh probe here too.
|
|
827
|
+
// The manifest records the project-root directory mtime alongside symlink hints. A changed
|
|
828
|
+
// root mtime triggers the cheap full-tree probe, while strict modes always probe.
|
|
728
829
|
const wantsMaxSymlinkCorrectness = !!opts?.cacheStrict || !!opts?.cacheVerify;
|
|
729
830
|
const symlinkHintManifest = helperOpts?.ignoreExistingManifest || wantsMaxSymlinkCorrectness || !useDiskCache
|
|
730
831
|
? null
|
|
731
832
|
: await loadManifest(projectRoot, opts);
|
|
732
|
-
const
|
|
833
|
+
const rootMtime = symlinkHintManifest ? (await fsp.stat(projectRoot)).mtimeMs : undefined;
|
|
834
|
+
const symlinkHintIsFresh = symlinkHintManifest?.symlinkDirectoriesRootMtimeMs !== undefined &&
|
|
835
|
+
rootMtime === symlinkHintManifest.symlinkDirectoriesRootMtimeMs;
|
|
836
|
+
const knownSymlinkDirectories = symlinkHintIsFresh ? symlinkHintManifest?.symlinkDirectories : undefined;
|
|
733
837
|
let discoveredSymlinkDirectories = knownSymlinkDirectories;
|
|
734
838
|
const onSymlinkDirectoriesDiscovered = (directories) => {
|
|
735
839
|
discoveredSymlinkDirectories = Array.from(directories);
|
|
736
840
|
};
|
|
737
841
|
// When the hint is unknown, listProjectFiles() and discoverProjectFiles() must run
|
|
738
|
-
// sequentially rather than in Promise.all
|
|
739
|
-
// full-tree symlink probe concurrently, since the callback only reports back after
|
|
740
|
-
// listProjectFiles() resolves, too late to inform a probe discoverProjectFiles()
|
|
741
|
-
// already started on its own. Sequencing costs a little parallelism on that one
|
|
742
|
-
// cold-start case, but avoids paying for two full-tree walks instead of one. Once a
|
|
743
|
-
// hint is known (the common warm case), both calls skip probing entirely, so running
|
|
744
|
-
// them sequentially here costs no meaningful time either way.
|
|
842
|
+
// sequentially rather than in Promise.all to avoid duplicate full-tree probes.
|
|
745
843
|
const discoveredFiles = await listProjectFiles(projectRoot, projectPatternsForLanguageExtensions(opts), {
|
|
746
844
|
...opts?.discovery,
|
|
747
845
|
...(opts?.logLevel ? { logLevel: opts.logLevel } : {}),
|
|
748
846
|
...(knownSymlinkDirectories !== undefined ? { knownSymlinkDirectories } : {}),
|
|
749
847
|
onSymlinkDirectoriesDiscovered,
|
|
750
848
|
});
|
|
751
|
-
const additionalFileCandidates =
|
|
849
|
+
const additionalFileCandidates = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
|
|
752
850
|
const additionalFileExistence = await probePathExistence(additionalFileCandidates, buildConcurrency(opts));
|
|
753
851
|
const additionalFiles = additionalFileCandidates.filter((file) => additionalFileExistence.get(file));
|
|
754
852
|
const discoveredFileSet = new Set(discoveredFiles);
|
|
@@ -795,9 +893,11 @@ export async function buildProjectIndex(projectRoot, opts) {
|
|
|
795
893
|
export async function buildProjectIndexFromFiles(projectRoot, inputFiles, opts) {
|
|
796
894
|
try {
|
|
797
895
|
const useDiskCache = (opts?.cache ?? "off") === "disk";
|
|
798
|
-
|
|
896
|
+
const normalizedInputFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, inputFiles, "Index file");
|
|
897
|
+
return await buildIndexFromFileListShared(projectRoot, normalizedInputFiles, opts, {
|
|
799
898
|
manifestMode: useDiskCache ? "read-only" : "off",
|
|
800
899
|
warnNoFilesMessage: `Warning: No files provided for indexing in ${projectRoot}. Check the explicit file list and include/ignore filters. Diagnostic: codegraph doctor`,
|
|
900
|
+
confineReads: true,
|
|
801
901
|
});
|
|
802
902
|
}
|
|
803
903
|
finally {
|
|
@@ -838,7 +938,7 @@ async function buildDeclaredScopeIndex(projectRoot, scopeFiles, opts) {
|
|
|
838
938
|
*/
|
|
839
939
|
export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
840
940
|
await initializeFileIdentityCaseSensitivity(projectRoot);
|
|
841
|
-
|
|
941
|
+
clearResolutionCaches();
|
|
842
942
|
const graphOptions = normalizeGraphOptions(opts?.graph);
|
|
843
943
|
const strictIncremental = opts?.incrementalStrict ?? false;
|
|
844
944
|
if (strictIncremental && graphOptions.fast)
|
|
@@ -889,7 +989,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
889
989
|
}
|
|
890
990
|
startCheckProgress();
|
|
891
991
|
const manifestStart = performance.now();
|
|
892
|
-
const manifest = await loadManifest(projectRoot, opts);
|
|
992
|
+
const manifest = await loadManifest(projectRoot, opts, report);
|
|
893
993
|
if (timings)
|
|
894
994
|
timings.manifestMs = Math.round(performance.now() - manifestStart);
|
|
895
995
|
const manifestUsed = !!manifest;
|
|
@@ -907,8 +1007,21 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
907
1007
|
const currentConfigHashResult = await computeConfigHash(projectRoot, opts?.logLevel);
|
|
908
1008
|
const currentConfigHash = recordConfigHashResult(manifestReport, currentConfigHashResult, opts?.logLevel);
|
|
909
1009
|
const configChanged = !!currentConfigHashResult.error || !manifest?.configHash || currentConfigHash !== manifest.configHash;
|
|
1010
|
+
let resolverEnvironmentFingerprint;
|
|
1011
|
+
let resolverEnvironmentMatchesManifest = true;
|
|
1012
|
+
if (manifest && graphOptions.resolveNodeModules) {
|
|
1013
|
+
resolverEnvironmentFingerprint = await computeResolverEnvironmentFingerprint(projectRoot, Object.keys(manifest.files));
|
|
1014
|
+
resolverEnvironmentMatchesManifest =
|
|
1015
|
+
resolverEnvironmentFingerprint !== null &&
|
|
1016
|
+
manifest.resolverEnvironmentFingerprint === resolverEnvironmentFingerprint;
|
|
1017
|
+
}
|
|
910
1018
|
const requiresFullRebuild = optionDiffs.some((diff) => diff === "discovery" || diff === "native" || diff === "implementation" || diff === "languageExtensions");
|
|
911
|
-
|
|
1019
|
+
const graphOptionsChanged = !graphOptionsEqual(manifest?.graphOptions, graphOptions);
|
|
1020
|
+
if (!manifest ||
|
|
1021
|
+
graphOptionsChanged ||
|
|
1022
|
+
configChanged ||
|
|
1023
|
+
requiresFullRebuild ||
|
|
1024
|
+
!resolverEnvironmentMatchesManifest) {
|
|
912
1025
|
if (manifest && configChanged) {
|
|
913
1026
|
logWithLevel(opts?.logLevel, "warn", "Configuration changed, rebuilding index...");
|
|
914
1027
|
}
|
|
@@ -920,6 +1033,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
920
1033
|
else if (configChanged) {
|
|
921
1034
|
reason = "configChanged";
|
|
922
1035
|
}
|
|
1036
|
+
else if (!graphOptionsChanged && !resolverEnvironmentMatchesManifest) {
|
|
1037
|
+
reason = "resolverEnvironmentChanged";
|
|
1038
|
+
}
|
|
923
1039
|
manifestReport.reason = reason;
|
|
924
1040
|
manifestReport.reused = false;
|
|
925
1041
|
}
|
|
@@ -979,9 +1095,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
979
1095
|
const trackedEntryKeys = Object.keys(trackedEntries);
|
|
980
1096
|
let manifestRequiresSanitization = manifestFileKeys.length !== trackedEntryKeys.length ||
|
|
981
1097
|
manifestFileKeys.some((file) => !Object.hasOwn(trackedEntries, file));
|
|
982
|
-
const explicitFiles =
|
|
983
|
-
const additionalFiles =
|
|
984
|
-
const previousTransientFiles = sanitizeManifestTransientFilesForRoot(projectRoot, manifest.transientFiles).filter((file) => Object.hasOwn(trackedEntries, file));
|
|
1098
|
+
const explicitFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.files ?? [], "Incremental file");
|
|
1099
|
+
const additionalFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
|
|
1100
|
+
const previousTransientFiles = sanitizeManifestTransientFilesForRoot(projectRoot, projectRoot, manifest.transientFiles).filter((file) => Object.hasOwn(trackedEntries, file));
|
|
985
1101
|
const previousTransientFileSet = new Set(previousTransientFiles);
|
|
986
1102
|
const needsGitScan = !!opts?.gitBase || !!opts?.changedSince;
|
|
987
1103
|
const gitFiles = needsGitScan ? await listChangedFiles(projectRoot, buildIncrementalGitDiffOptions(opts)) : [];
|
|
@@ -1067,6 +1183,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1067
1183
|
projectRoot,
|
|
1068
1184
|
opts,
|
|
1069
1185
|
graphOptions,
|
|
1186
|
+
...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
|
|
1070
1187
|
files: {},
|
|
1071
1188
|
timings,
|
|
1072
1189
|
manifestReport,
|
|
@@ -1087,6 +1204,10 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1087
1204
|
};
|
|
1088
1205
|
}
|
|
1089
1206
|
const changedFiles = new Set();
|
|
1207
|
+
if (!resolverEnvironmentMatchesManifest) {
|
|
1208
|
+
for (const file of allFiles)
|
|
1209
|
+
changedFiles.add(file);
|
|
1210
|
+
}
|
|
1090
1211
|
const markAsChanged = (file) => {
|
|
1091
1212
|
if (allFiles.has(file))
|
|
1092
1213
|
changedFiles.add(file);
|
|
@@ -1109,7 +1230,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1109
1230
|
const explicitFileSet = new Set(explicitFiles);
|
|
1110
1231
|
const explicitFilesCoverAllFiles = explicitFileSet.size === allFiles.size && [...allFiles].every((file) => explicitFileSet.has(file));
|
|
1111
1232
|
const explicitFilesAreChangeInputs = !opts?.filesAreProjectScope;
|
|
1112
|
-
if (explicitFileSet.size && explicitFilesAreChangeInputs && (!explicitFilesCoverAllFiles || report)) {
|
|
1233
|
+
if (explicitFileSet.size && explicitFilesAreChangeInputs && (!explicitFilesCoverAllFiles || opts?.report)) {
|
|
1113
1234
|
explicitFileSet.forEach(markAsChanged);
|
|
1114
1235
|
}
|
|
1115
1236
|
dependentFilesOfDeletedTracked.forEach(markAsChanged);
|
|
@@ -1119,7 +1240,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1119
1240
|
if (changedFiles.size || deletedTrackedFiles.size || manifestRequiresSanitization)
|
|
1120
1241
|
return null;
|
|
1121
1242
|
const manifestEntryMap = new Map(Object.entries(trackedEntries));
|
|
1122
|
-
const snapshotLoad = await tryLoadProjectIndexSnapshot(projectRoot, opts, manifestEntryMap);
|
|
1243
|
+
const snapshotLoad = await tryLoadProjectIndexSnapshot(projectRoot, opts, manifestEntryMap, report);
|
|
1123
1244
|
if (!snapshotLoad)
|
|
1124
1245
|
return null;
|
|
1125
1246
|
const snapshot = snapshotLoad.index;
|
|
@@ -1199,10 +1320,12 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1199
1320
|
})
|
|
1200
1321
|
: new Map();
|
|
1201
1322
|
const fileSignatures = await prepareFileSignatures({
|
|
1323
|
+
projectRoot,
|
|
1202
1324
|
files: Array.from(allFiles),
|
|
1203
1325
|
opts,
|
|
1204
1326
|
gitSigMap,
|
|
1205
1327
|
cacheEnabled,
|
|
1328
|
+
needsContentHash: cacheEnabled || manifestUsed || opts?.cacheStrict === true,
|
|
1206
1329
|
concurrency: conc,
|
|
1207
1330
|
});
|
|
1208
1331
|
const modules = new Map();
|
|
@@ -1223,8 +1346,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1223
1346
|
changedFiles.add(file);
|
|
1224
1347
|
}
|
|
1225
1348
|
}
|
|
1349
|
+
const reverseDeps = buildTrackedFileReverseDependencies(trackedEntries);
|
|
1226
1350
|
const invalidateCachedDependents = () => {
|
|
1227
|
-
const dependentFilesOfChanged = collectTrackedFileDependents(trackedEntries, changedFiles);
|
|
1351
|
+
const dependentFilesOfChanged = collectTrackedFileDependents(trackedEntries, changedFiles, reverseDeps);
|
|
1228
1352
|
for (const file of dependentFilesOfChanged) {
|
|
1229
1353
|
const key = fileIdentityKey(file);
|
|
1230
1354
|
if (modules.has(key)) {
|
|
@@ -1248,20 +1372,32 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1248
1372
|
completeCheckProgress(allFiles.size);
|
|
1249
1373
|
return unchangedSnapshot;
|
|
1250
1374
|
}
|
|
1251
|
-
const
|
|
1375
|
+
const snapshotModules = cacheEnabled
|
|
1376
|
+
? await tryLoadProjectSnapshotModules(projectRoot, opts, fileSignatures, report)
|
|
1377
|
+
: null;
|
|
1378
|
+
const persistedBloomFilters = bloomFilterCache
|
|
1379
|
+
? await tryLoadPersistedBloomFilters(projectRoot, opts, report)
|
|
1380
|
+
: null;
|
|
1252
1381
|
for (const file of allFiles) {
|
|
1253
1382
|
if (changedFiles.has(file))
|
|
1254
1383
|
continue;
|
|
1255
1384
|
const sigInfo = fileSignatures.get(file);
|
|
1256
|
-
|
|
1257
|
-
const
|
|
1385
|
+
let cached = null;
|
|
1386
|
+
const snapshotMod = snapshotModules?.get(fileIdentityKey(file));
|
|
1387
|
+
if (snapshotMod) {
|
|
1388
|
+
cached = snapshotMod;
|
|
1389
|
+
}
|
|
1390
|
+
else if (cacheEnabled) {
|
|
1391
|
+
const cacheSig = await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint);
|
|
1392
|
+
cached = tryLoadFromCache(projectRoot, file, cacheSig, opts, report);
|
|
1393
|
+
}
|
|
1258
1394
|
if (cached) {
|
|
1259
1395
|
if (fileReport)
|
|
1260
1396
|
fileReport.cached = (fileReport.cached ?? 0) + 1;
|
|
1261
1397
|
modules.set(fileIdentityKey(file), cached);
|
|
1262
1398
|
collectJsonDependencies(cached.imports, jsonDependencies);
|
|
1263
1399
|
if (bloomFilterCache) {
|
|
1264
|
-
const persistedFilter = persistedBloomFilters?.get(file);
|
|
1400
|
+
const persistedFilter = persistedBloomFilters?.get(file, sigInfo);
|
|
1265
1401
|
if (persistedFilter) {
|
|
1266
1402
|
bloomFilterCache.set(file, persistedFilter);
|
|
1267
1403
|
}
|
|
@@ -1312,8 +1448,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1312
1448
|
onFallbackImportExtraction,
|
|
1313
1449
|
fileSignatures,
|
|
1314
1450
|
cacheEnabled,
|
|
1451
|
+
...(resolverEnvironmentFingerprint !== undefined ? { resolverEnvironmentFingerprint } : {}),
|
|
1315
1452
|
});
|
|
1316
|
-
return [file, built.module];
|
|
1453
|
+
return [file, built.module, built.cacheWrite];
|
|
1317
1454
|
}
|
|
1318
1455
|
catch (error) {
|
|
1319
1456
|
if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
|
|
@@ -1323,7 +1460,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1323
1460
|
}
|
|
1324
1461
|
recordFileFailure(report, file, error);
|
|
1325
1462
|
logWithLevel(opts?.logLevel, "warn", `Warning: Failed to process file ${file}:`, error);
|
|
1326
|
-
return [file, createEmptyModuleIndex(file)];
|
|
1463
|
+
return [file, createEmptyModuleIndex(file), undefined];
|
|
1327
1464
|
}
|
|
1328
1465
|
finally {
|
|
1329
1466
|
if (opts?.onProgress) {
|
|
@@ -1338,8 +1475,14 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1338
1475
|
}
|
|
1339
1476
|
}
|
|
1340
1477
|
});
|
|
1341
|
-
|
|
1478
|
+
const pendingIncrementalCacheWrites = [];
|
|
1479
|
+
for (const [file, mod, cacheWrite] of fileResults) {
|
|
1342
1480
|
modules.set(fileIdentityKey(file), mod);
|
|
1481
|
+
if (cacheWrite)
|
|
1482
|
+
pendingIncrementalCacheWrites.push(cacheWrite);
|
|
1483
|
+
}
|
|
1484
|
+
if (pendingIncrementalCacheWrites.length) {
|
|
1485
|
+
writeModulesToCache(projectRoot, pendingIncrementalCacheWrites, opts);
|
|
1343
1486
|
}
|
|
1344
1487
|
if (timings)
|
|
1345
1488
|
timings.parseMs = Math.round(performance.now() - parseStart);
|
|
@@ -1349,7 +1492,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1349
1492
|
}
|
|
1350
1493
|
expandStarImports(modules, opts);
|
|
1351
1494
|
const retainedTrackedEntries = Object.entries(trackedEntries).filter(([file]) => !deletedTrackedFiles.has(file));
|
|
1352
|
-
const cachedGraphEntries =
|
|
1495
|
+
const cachedGraphEntries = resolverEnvironmentMatchesManifest
|
|
1496
|
+
? new Map(retainedTrackedEntries)
|
|
1497
|
+
: new Map();
|
|
1353
1498
|
const manifestEntries = new Map(cachedGraphEntries);
|
|
1354
1499
|
const baseGraph = cachedGraphEntries.size > 0 ? { nodes: new Set(), edges: [] } : undefined;
|
|
1355
1500
|
if (baseGraph) {
|
|
@@ -1385,6 +1530,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1385
1530
|
dynamicImportHeuristics: !!graphOptions.dynamicImportHeuristics,
|
|
1386
1531
|
...(opts?.native ? { native: opts.native } : {}),
|
|
1387
1532
|
...(opts?.languageExtensions ? { languageExtensions: opts.languageExtensions } : {}),
|
|
1533
|
+
threads: conc,
|
|
1388
1534
|
...(opts?.logLevel ? { logLevel: opts.logLevel } : {}),
|
|
1389
1535
|
...(graphOptions.resolutionHints ? { resolutionHints: graphOptions.resolutionHints } : {}),
|
|
1390
1536
|
allFiles: Array.from(allFiles),
|
|
@@ -1402,10 +1548,21 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1402
1548
|
});
|
|
1403
1549
|
if (timings)
|
|
1404
1550
|
timings.graphMs = Math.round(performance.now() - graphStart);
|
|
1551
|
+
for (const file of new Set([...changedFiles, ...transientFiles])) {
|
|
1552
|
+
const signature = fileSignatures.get(file);
|
|
1553
|
+
if (!signature || manifestEntries.has(file))
|
|
1554
|
+
continue;
|
|
1555
|
+
manifestEntries.set(file, {
|
|
1556
|
+
sig: signature.sig,
|
|
1557
|
+
...(signature.gitSig ? { gitSig: signature.gitSig } : {}),
|
|
1558
|
+
edges: [],
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1405
1561
|
await writeIndexManifestSnapshot({
|
|
1406
1562
|
projectRoot,
|
|
1407
1563
|
opts,
|
|
1408
1564
|
graphOptions,
|
|
1565
|
+
...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
|
|
1409
1566
|
files: manifestEntries,
|
|
1410
1567
|
timings,
|
|
1411
1568
|
manifestReport,
|
|
@@ -1422,10 +1579,20 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
1422
1579
|
modules,
|
|
1423
1580
|
parsedMap,
|
|
1424
1581
|
bloomFilterCache,
|
|
1425
|
-
manifestEntries: projectIndexManifestEntries(
|
|
1582
|
+
manifestEntries: projectIndexManifestEntries(
|
|
1583
|
+
// `manifestEntries` (a `ManifestFileEntry`) never carries `cacheSig` -- that field
|
|
1584
|
+
// only lives on `FileSignature`. Overlay each entry with the `cacheSig` this build
|
|
1585
|
+
// actually computed (content-hash-derived for non-git files, since caching is enabled
|
|
1586
|
+
// whenever this path runs) so incremental writes preserve the same strong identity a
|
|
1587
|
+
// cold build produces, instead of leaving snapshot/bloom reuse to fall back to the
|
|
1588
|
+
// weak `mtime:size` `sig`.
|
|
1589
|
+
Array.from(manifestEntries, ([file, entry]) => {
|
|
1590
|
+
const cacheSig = fileSignatures.get(file)?.cacheSig;
|
|
1591
|
+
return [file, { ...entry, ...(cacheSig ? { cacheSig } : {}) }];
|
|
1592
|
+
})),
|
|
1426
1593
|
buildReport: report,
|
|
1427
1594
|
});
|
|
1428
|
-
await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries));
|
|
1595
|
+
await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot));
|
|
1429
1596
|
if (updateStartedAt !== undefined) {
|
|
1430
1597
|
emitIndexLifecycleProgress(opts, "complete", "update", index.byFile.size, performance.now() - updateStartedAt);
|
|
1431
1598
|
}
|
|
@@ -1458,8 +1625,8 @@ export async function buildGraphDelta(projectRoot, opts) {
|
|
|
1458
1625
|
const strictIncremental = opts?.incrementalStrict ?? false;
|
|
1459
1626
|
if (strictIncremental && graphOptions.fast)
|
|
1460
1627
|
graphOptions.fast = false;
|
|
1461
|
-
const explicitFiles =
|
|
1462
|
-
const additionalFiles =
|
|
1628
|
+
const explicitFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.files ?? [], "Graph delta file");
|
|
1629
|
+
const additionalFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional graph delta file");
|
|
1463
1630
|
const needsGitScan = !!opts?.gitBase || !!opts?.changedSince;
|
|
1464
1631
|
const gitFiles = needsGitScan ? await listChangedFiles(projectRoot, buildIncrementalGitDiffOptions(opts)) : [];
|
|
1465
1632
|
const { trackedFiles } = await partitionTrackedManifestFiles(trackedEntries);
|
|
@@ -1484,14 +1651,19 @@ export async function buildGraphDelta(projectRoot, opts) {
|
|
|
1484
1651
|
}
|
|
1485
1652
|
const candidateExistence = await probePathExistence([...explicitFiles, ...additionalFiles, ...manifestDiffFiles, ...gitFiles], buildConcurrency(opts));
|
|
1486
1653
|
const existsInCandidateSnapshot = (file) => candidateExistence.get(file) ?? false;
|
|
1487
|
-
const
|
|
1654
|
+
const normalizeChangedFiles = (files) => files.map((file) => {
|
|
1655
|
+
if (!existsInCandidateSnapshot(file))
|
|
1656
|
+
return file;
|
|
1657
|
+
const [normalizedFile] = normalizeIndexedFileInputs(projectRoot, [file], "Graph delta file");
|
|
1658
|
+
return normalizedFile ?? file;
|
|
1659
|
+
}), normalizedManifestDiffFiles = normalizeChangedFiles(manifestDiffFiles), normalizedGitFiles = normalizeChangedFiles(gitFiles), existingExplicitFiles = explicitFiles.filter(existsInCandidateSnapshot);
|
|
1488
1660
|
const existingAdditionalFiles = additionalFiles.filter(existsInCandidateSnapshot);
|
|
1489
1661
|
const allFiles = new Set([
|
|
1490
1662
|
...trackedFiles,
|
|
1491
1663
|
...existingExplicitFiles,
|
|
1492
1664
|
...existingAdditionalFiles,
|
|
1493
|
-
...
|
|
1494
|
-
...
|
|
1665
|
+
...normalizedManifestDiffFiles.filter((_, index) => existsInCandidateSnapshot(manifestDiffFiles[index])),
|
|
1666
|
+
...normalizedGitFiles.filter((_, index) => existsInCandidateSnapshot(gitFiles[index])),
|
|
1495
1667
|
]);
|
|
1496
1668
|
const changedFiles = new Set();
|
|
1497
1669
|
const changedFileKeys = new Set();
|
|
@@ -1503,8 +1675,8 @@ export async function buildGraphDelta(projectRoot, opts) {
|
|
|
1503
1675
|
changedFiles.add(file);
|
|
1504
1676
|
};
|
|
1505
1677
|
existingExplicitFiles.forEach(addChangedFile);
|
|
1506
|
-
|
|
1507
|
-
|
|
1678
|
+
normalizedManifestDiffFiles.forEach(addChangedFile);
|
|
1679
|
+
normalizedGitFiles.forEach(addChangedFile);
|
|
1508
1680
|
if (languageExtensionsChanged) {
|
|
1509
1681
|
for (const file of trackedFiles) {
|
|
1510
1682
|
if (languageSupportChangedForFile(file))
|