@lzehrung/codegraph 2.1.0 → 2.1.1
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 +23 -21
- 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/explore.d.ts.map +1 -1
- package/dist/agent/explore.js +9 -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 +5 -4
- package/dist/agent/orient.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/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 +7 -0
- package/dist/agent/query-index/store.d.ts.map +1 -1
- package/dist/agent/query-index/store.js +71 -0
- package/dist/agent/query-index/store.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 +82 -78
- package/dist/agent/renamePreview.js.map +1 -1
- package/dist/agent/search.d.ts.map +1 -1
- package/dist/agent/search.js +39 -17
- 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 +19 -6
- 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 +6 -15
- package/dist/agent-tools.js.map +1 -1
- package/dist/bin/cli.js +27556 -24941
- package/dist/bin/queryIndexWorker.js +47 -6
- package/dist/bin/rawQueryWorker.js +246 -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/commandTable.d.ts.map +1 -1
- package/dist/cli/commandTable.js +15 -3
- 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 +8 -0
- 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/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/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 +9 -7
- package/dist/cli/options.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/skill.js +1 -1
- package/dist/cli/skill.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/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 +2 -2
- 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/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 +36 -18
- package/dist/duplicates/units.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.map +1 -1
- package/dist/graphs/symbol-graph-detailed.js +3 -1
- package/dist/graphs/symbol-graph-detailed.js.map +1 -1
- package/dist/impact/analyzer.d.ts.map +1 -1
- package/dist/impact/analyzer.js +15 -1
- package/dist/impact/analyzer.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.map +1 -1
- package/dist/impact/callCompatibility.js +9 -570
- package/dist/impact/callCompatibility.js.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 +98 -36
- 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 +330 -61
- package/dist/impact/report-suggestions.js.map +1 -1
- package/dist/impact/reportCompact.js +7 -0
- package/dist/impact/reportCompact.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 +61 -2
- 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/types.d.ts +7 -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 +9 -3
- package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
- package/dist/indexer/build-cache/manifest.js +77 -20
- package/dist/indexer/build-cache/manifest.js.map +1 -1
- package/dist/indexer/build-cache/module-cache.d.ts +23 -2
- package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache/module-cache.js +92 -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 +32 -8
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +333 -44
- 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 +133 -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 +154 -47
- 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 +12 -5
- package/dist/indexer/build-manifest.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/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 +7 -2
- package/dist/indexer/imports/python.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 +52 -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 +27 -16
- 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 +24 -20
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/parse-context.d.ts +1 -1
- package/dist/indexer/parse-context.d.ts.map +1 -1
- package/dist/indexer/parse-context.js +2 -2
- 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 +22 -0
- 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 +234 -0
- package/dist/installer/locks.js.map +1 -0
- package/dist/installer/registry.d.ts.map +1 -1
- package/dist/installer/registry.js +13 -230
- 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 +43 -16
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +342 -127
- 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 +121 -2
- 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/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.map +1 -1
- package/dist/review/summaries.js +13 -10
- package/dist/review/summaries.js.map +1 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +7 -2
- 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.map +1 -1
- package/dist/sqlite/schema.js.map +1 -1
- package/dist/sqlite-driver.d.ts.map +1 -1
- package/dist/sqlite-driver.js +2 -1
- 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/confinedFile.d.ts +41 -2
- package/dist/util/confinedFile.d.ts.map +1 -1
- package/dist/util/confinedFile.js +101 -2
- package/dist/util/confinedFile.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 +109 -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.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 +9 -4
- 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/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/docs/mcp.md +32 -13
- package/package.json +3 -3
package/dist/mcp/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
3
|
import fs from "node:fs/promises";
|
|
3
4
|
import { createServer } from "node:http";
|
|
4
5
|
import path from "node:path";
|
|
@@ -28,16 +29,17 @@ import { DEFAULT_BOUNDED_IMPACT_BUDGETS } from "../impact/budgets.js";
|
|
|
28
29
|
import { buildReviewReport } from "../review.js";
|
|
29
30
|
import { boundReviewReportForTransport } from "../review/types.js";
|
|
30
31
|
import { SQLITE_ARTIFACT_FILE_SIGNATURES_METADATA_KEY, queryGraphSqliteRaw } from "../sqlite.js";
|
|
32
|
+
import { boundList, countOmitted } from "../presentation/bounds.js";
|
|
31
33
|
import { isPlainRecord } from "../util/guards.js";
|
|
32
34
|
import { toProjectDisplayPath } from "../util/paths.js";
|
|
33
35
|
import { errorMessage } from "../util/errors.js";
|
|
34
|
-
import { createAgentSession, listAgentSessionFiles } from "../agent/session.js";
|
|
36
|
+
import { assertNoPrebuiltSessionWithBuildOptions, createAgentSession, listAgentSessionFiles, } from "../agent/session.js";
|
|
35
37
|
import { mapLimit } from "../util/concurrency.js";
|
|
36
38
|
import { assertRealPathCandidateWithinRoot, resolveProjectFile } from "../util/confinedFile.js";
|
|
37
39
|
import { SymbolKind } from "../indexer/types.js";
|
|
38
40
|
import { DEFAULT_WORKSPACE_SYMBOL_LIMIT, MAX_WORKSPACE_SYMBOL_LIMIT } from "../indexer/workspace-symbols.js";
|
|
39
|
-
import { assertMcpSqliteQueryResourceBounded,
|
|
40
|
-
import { DEFAULT_CALL_HIERARCHY_LIMIT, MAX_CALL_HIERARCHY_LIMIT, DEFAULT_MCP_COLLECTION_LIMIT, DEFAULT_TYPE_HIERARCHY_LIMIT, listCodegraphMcpTools, MAX_TYPE_HIERARCHY_LIMIT, MAX_MCP_COLLECTION_LIMIT, MAX_RENAME_PREVIEW_EDITS,
|
|
41
|
+
import { assertMcpSqliteQueryResourceBounded, DEFAULT_SQLITE_BYTE_LIMIT, normalizeSqliteRowLimit, } from "./sqliteGuard.js";
|
|
42
|
+
import { DEFAULT_CALL_HIERARCHY_LIMIT, MAX_CALL_HIERARCHY_LIMIT, DEFAULT_MCP_COLLECTION_LIMIT, DEFAULT_TYPE_HIERARCHY_LIMIT, listCodegraphMcpTools, MAX_TYPE_HIERARCHY_LIMIT, MAX_MCP_COLLECTION_LIMIT, MAX_RENAME_PREVIEW_EDITS, MCP_TOOL_REGISTRY, MAX_REFACTOR_PLAN_LIMIT, } from "./tools.js";
|
|
41
43
|
import { buildAllowedHostHeaders, buildAllowedOriginHostnames, closeHttpServer, emptyAllowedHostHeaderRules, formatHostForUrl, getHeaderValue, getHttpServerPort, getRequestPath, isAllowedHostHeader, listenOnHttpServer, readJsonRequestBody, waitForHttpServerClose, writeJsonResponse, writeJsonRpcError, } from "./http.js";
|
|
42
44
|
import { getCurrentNativeBindingOrigin } from "../native/runtime.js";
|
|
43
45
|
import { captureCodegraphRuntimeIdentity, createInstalledVersionChecker, } from "../runtimeIdentity.js";
|
|
@@ -47,12 +49,34 @@ import { awaitStdioMcpLifecycle, DEFAULT_MCP_STDIO_IDLE_TIMEOUT_MS } from "./std
|
|
|
47
49
|
export const DEFAULT_MCP_HTTP_SESSION_IDLE_MS = 30 * 60 * 1000;
|
|
48
50
|
export const DEFAULT_MCP_HTTP_SESSION_MAX_COUNT = 32;
|
|
49
51
|
export const DEFAULT_MCP_HTTP_SESSION_EVICTION_INTERVAL_MS = 60_000;
|
|
52
|
+
export const DEFAULT_MCP_HTTP_BODY_TIMEOUT_MS = 30_000;
|
|
53
|
+
export const DEFAULT_MCP_TOOL_TIMEOUT_MS = 30 * 60 * 1000;
|
|
54
|
+
const MAX_MCP_HTTP_BODY_TIMEOUT_MS = 2_147_483_647;
|
|
55
|
+
const MAX_MCP_TOOL_TIMEOUT_MS = 2_147_483_647;
|
|
56
|
+
export const DEFAULT_MCP_TOOL_CONCURRENCY = 4;
|
|
57
|
+
function normalizeMcpToolConcurrency(value) {
|
|
58
|
+
if (!Number.isFinite(value))
|
|
59
|
+
return DEFAULT_MCP_TOOL_CONCURRENCY;
|
|
60
|
+
return Math.max(1, Math.floor(value));
|
|
61
|
+
}
|
|
62
|
+
function assertMcpHttpBodyTimeout(value) {
|
|
63
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_MCP_HTTP_BODY_TIMEOUT_MS) {
|
|
64
|
+
throw new RangeError(`httpBodyTimeoutMs must be a positive integer no greater than ${MAX_MCP_HTTP_BODY_TIMEOUT_MS}.`);
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
function assertMcpToolTimeout(value) {
|
|
69
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > MAX_MCP_TOOL_TIMEOUT_MS) {
|
|
70
|
+
throw new RangeError(`mcpToolTimeoutMs must be a whole number from 0 through ${MAX_MCP_TOOL_TIMEOUT_MS}; 0 disables the deadline.`);
|
|
71
|
+
}
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
const legacyRequestAbortStorage = new AsyncLocalStorage();
|
|
50
75
|
const MAX_MCP_FRESHNESS_CHANGED_FILES = 25;
|
|
76
|
+
const MAX_MCP_FRESHNESS_RETRIES = 3;
|
|
51
77
|
const SQLITE_ARTIFACT_STAT_CONCURRENCY = 64;
|
|
52
78
|
function assertMcpSessionOptions(options) {
|
|
53
|
-
|
|
54
|
-
throw new Error("MCP server options cannot combine a prebuilt session with buildOptions.");
|
|
55
|
-
}
|
|
79
|
+
assertNoPrebuiltSessionWithBuildOptions(options, "MCP server options");
|
|
56
80
|
}
|
|
57
81
|
function createCodegraphMcpSession(options, root) {
|
|
58
82
|
assertMcpSessionOptions(options);
|
|
@@ -72,7 +96,7 @@ function startCodegraphMcpWarmup(session, warmup) {
|
|
|
72
96
|
}
|
|
73
97
|
return undefined;
|
|
74
98
|
}
|
|
75
|
-
async function
|
|
99
|
+
async function createWarmedCodegraphMcpResources(options) {
|
|
76
100
|
const root = path.resolve(options.root);
|
|
77
101
|
const session = createCodegraphMcpSession(options, root);
|
|
78
102
|
await startCodegraphMcpWarmup(session, options.warmup);
|
|
@@ -81,7 +105,10 @@ async function createWarmedCodegraphMcpHandlers(options) {
|
|
|
81
105
|
void host;
|
|
82
106
|
void port;
|
|
83
107
|
void onHttpListen;
|
|
84
|
-
return
|
|
108
|
+
return {
|
|
109
|
+
handlers: createCodegraphMcpHandlersForSession({ ...handlerOptions, root }, session),
|
|
110
|
+
session,
|
|
111
|
+
};
|
|
85
112
|
}
|
|
86
113
|
const MCP_HTTP_PATH = "/mcp";
|
|
87
114
|
const MAX_MCP_HTTP_BODY_BYTES = 1_000_000;
|
|
@@ -102,6 +129,8 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
102
129
|
let sqlitePath = configuredSqlitePath;
|
|
103
130
|
let sqliteOutDir = configuredSqliteOutDir;
|
|
104
131
|
let sqliteCanRefresh = configuredSqliteCanRefresh;
|
|
132
|
+
let refreshPromise;
|
|
133
|
+
let refreshEpoch = 0;
|
|
105
134
|
const relative = (file) => toProjectDisplayPath(root, file);
|
|
106
135
|
const boundedLimit = (limit, fallback, max) => {
|
|
107
136
|
if (typeof limit !== "number" || !Number.isFinite(limit))
|
|
@@ -115,7 +144,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
115
144
|
state: "stale",
|
|
116
145
|
changedFiles: boundedChangedFiles,
|
|
117
146
|
changedFileCount: changedFiles.length,
|
|
118
|
-
omittedChangedFileCount:
|
|
147
|
+
omittedChangedFileCount: countOmitted(changedFiles.length, boundedChangedFiles.length),
|
|
119
148
|
reason,
|
|
120
149
|
};
|
|
121
150
|
};
|
|
@@ -125,9 +154,16 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
125
154
|
return { state: "fresh" };
|
|
126
155
|
};
|
|
127
156
|
const withFreshness = async (run) => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
157
|
+
for (let attempt = 0; attempt < MAX_MCP_FRESHNESS_RETRIES; attempt += 1) {
|
|
158
|
+
if (refreshPromise)
|
|
159
|
+
await refreshPromise;
|
|
160
|
+
const epoch = refreshEpoch;
|
|
161
|
+
const freshness = await checkMcpFreshness();
|
|
162
|
+
const result = await run();
|
|
163
|
+
if (epoch === refreshEpoch && !refreshPromise)
|
|
164
|
+
return { ...result, freshness };
|
|
165
|
+
}
|
|
166
|
+
throw new Error("Workspace refresh changed repeatedly while serving the request; retry after refresh completes.");
|
|
131
167
|
};
|
|
132
168
|
const formatSqliteFreshnessError = (freshness) => {
|
|
133
169
|
if (freshness.state === "fresh")
|
|
@@ -286,7 +322,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
286
322
|
// Probe one entry past the display limit so `truncated` is exact
|
|
287
323
|
// rather than a `results.length === limit` heuristic (which cannot
|
|
288
324
|
// tell "exactly limit reachable files" apart from "more exist"),
|
|
289
|
-
// without re-walking the whole reachable graph for an exact total
|
|
325
|
+
// without re-walking the whole reachable graph for an exact total -
|
|
290
326
|
// see finding #44.
|
|
291
327
|
limit: limit + 1,
|
|
292
328
|
};
|
|
@@ -302,13 +338,18 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
302
338
|
targetFile = await resolveProjectFile(await realRoot, root, request.file);
|
|
303
339
|
}
|
|
304
340
|
const collected = collectEntries(snapshot.fileGraph, targetFile, queryOptions);
|
|
305
|
-
const
|
|
306
|
-
const
|
|
307
|
-
const entries = collected.slice(0, limit).map((dependency) => ({
|
|
341
|
+
const { items, omitted } = boundList(collected, limit);
|
|
342
|
+
const entries = items.map((dependency) => ({
|
|
308
343
|
file: relative(dependency.file),
|
|
309
344
|
depth: dependency.depth,
|
|
310
345
|
}));
|
|
311
|
-
return {
|
|
346
|
+
return {
|
|
347
|
+
entries,
|
|
348
|
+
limit,
|
|
349
|
+
totalSeen: collected.length,
|
|
350
|
+
truncated: Boolean(omitted),
|
|
351
|
+
omitted,
|
|
352
|
+
};
|
|
312
353
|
};
|
|
313
354
|
const calls = async (request) => {
|
|
314
355
|
const findCalls = request.direction === "callers" ? findCallersWithSession : findCalleesWithSession;
|
|
@@ -333,12 +374,15 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
333
374
|
if (result.status !== "ok") {
|
|
334
375
|
return { references: [], limit, totalSeen: 0, truncated: false, omitted: 0 };
|
|
335
376
|
}
|
|
336
|
-
const
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
377
|
+
const { items, omitted } = boundList(result.references, limit);
|
|
378
|
+
const references = items.map((reference) => ({ file: relative(reference.file), range: reference.range }));
|
|
379
|
+
return {
|
|
380
|
+
references,
|
|
381
|
+
limit,
|
|
382
|
+
totalSeen: result.references.length,
|
|
383
|
+
truncated: Boolean(omitted),
|
|
384
|
+
omitted,
|
|
385
|
+
};
|
|
342
386
|
};
|
|
343
387
|
const fileDeps = async (request) => await withFreshness(async () => {
|
|
344
388
|
const { entries, ...meta } = await collectMcpDependencyEntries(request, request.direction === "deps" ? getDependencies : getReverseDependencies);
|
|
@@ -458,7 +502,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
458
502
|
if (parseQualifiedSymbolPath(handle)) {
|
|
459
503
|
const snapshot = await session.loadProject({ symbolGraph: "skip" });
|
|
460
504
|
const resolved = requireSemanticSymbol(snapshot, handle);
|
|
461
|
-
// Probe one reference past the display limit so `truncated` is exact
|
|
505
|
+
// Probe one reference past the display limit so `truncated` is exact - see
|
|
462
506
|
// `collectMcpDependencyEntries` for the rationale (finding #44).
|
|
463
507
|
const result = await findReferences(snapshot.index, { def: resolved.def }, { maxReferences: limit + 1 });
|
|
464
508
|
return boundedReferencesFromResult(result, limit);
|
|
@@ -534,7 +578,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
534
578
|
// complete, unbounded report should call `buildReviewReport` directly.
|
|
535
579
|
return boundReviewReportForTransport(report);
|
|
536
580
|
}),
|
|
537
|
-
query_sqlite: async (request) => {
|
|
581
|
+
query_sqlite: async (request, executionOptions) => {
|
|
538
582
|
if (!sqlitePath) {
|
|
539
583
|
throw new Error("No SQLite artifact is available. Run artifact_build first or pass artifactPath.");
|
|
540
584
|
}
|
|
@@ -555,16 +599,32 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
555
599
|
}
|
|
556
600
|
const result = await queryGraphSqliteRaw(realSqlitePath, request.query, request.params ?? [], {
|
|
557
601
|
maxRows: normalizeSqliteRowLimit(request.limit),
|
|
602
|
+
maxBytes: DEFAULT_SQLITE_BYTE_LIMIT,
|
|
603
|
+
...(executionOptions?.signal ? { signal: executionOptions.signal } : {}),
|
|
558
604
|
});
|
|
559
|
-
return { ...
|
|
605
|
+
return { ...result, truncated: Boolean(result.truncated), freshness: artifactFreshness };
|
|
560
606
|
},
|
|
561
607
|
refresh_index: async (request) => {
|
|
562
608
|
const warmup = request.warmup ?? "off";
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
609
|
+
const previousRefresh = refreshPromise;
|
|
610
|
+
const refresh = (async () => {
|
|
611
|
+
if (previousRefresh)
|
|
612
|
+
await previousRefresh.catch(() => undefined);
|
|
613
|
+
++refreshEpoch;
|
|
614
|
+
session.invalidate();
|
|
615
|
+
sqlitePath = configuredSqlitePath;
|
|
616
|
+
sqliteOutDir = configuredSqliteOutDir;
|
|
617
|
+
sqliteCanRefresh = configuredSqliteCanRefresh;
|
|
618
|
+
await startCodegraphMcpWarmup(session, warmup);
|
|
619
|
+
})();
|
|
620
|
+
refreshPromise = refresh;
|
|
621
|
+
try {
|
|
622
|
+
await refresh;
|
|
623
|
+
}
|
|
624
|
+
finally {
|
|
625
|
+
if (refreshPromise === refresh)
|
|
626
|
+
refreshPromise = undefined;
|
|
627
|
+
}
|
|
568
628
|
return { refreshed: true, warmup };
|
|
569
629
|
},
|
|
570
630
|
artifact_build: async (request) => {
|
|
@@ -602,15 +662,49 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
602
662
|
},
|
|
603
663
|
};
|
|
604
664
|
}
|
|
605
|
-
|
|
665
|
+
function createMcpToolOperationTracker() {
|
|
666
|
+
let accepting = true;
|
|
667
|
+
const operations = new Set();
|
|
668
|
+
return {
|
|
669
|
+
isAccepting: () => accepting,
|
|
670
|
+
track: (operation) => {
|
|
671
|
+
if (!accepting)
|
|
672
|
+
return undefined;
|
|
673
|
+
const tracked = operation();
|
|
674
|
+
operations.add(tracked);
|
|
675
|
+
void tracked.then(() => operations.delete(tracked), () => operations.delete(tracked));
|
|
676
|
+
return tracked;
|
|
677
|
+
},
|
|
678
|
+
stop: () => {
|
|
679
|
+
accepting = false;
|
|
680
|
+
},
|
|
681
|
+
drain: async () => {
|
|
682
|
+
accepting = false;
|
|
683
|
+
await Promise.allSettled([...operations]);
|
|
684
|
+
},
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
export function createCodegraphMcpProtocolServer(handlers, runtimeIdentity = captureCodegraphRuntimeIdentity(getCurrentNativeBindingOrigin()), installedVersion = createInstalledVersionChecker(runtimeIdentity), toolCallState = { firstToolCallPending: true }, maxConcurrentToolCalls = DEFAULT_MCP_TOOL_CONCURRENCY, mcpToolTimeoutMs = DEFAULT_MCP_TOOL_TIMEOUT_MS) {
|
|
688
|
+
return createCodegraphMcpProtocolServerWithTracker(handlers, runtimeIdentity, installedVersion, toolCallState, maxConcurrentToolCalls, assertMcpToolTimeout(mcpToolTimeoutMs), createMcpToolOperationTracker());
|
|
689
|
+
}
|
|
690
|
+
function createCodegraphMcpProtocolServerWithTracker(handlers, runtimeIdentity, installedVersion, toolCallState, maxConcurrentToolCalls, mcpToolTimeoutMs, toolOperations) {
|
|
606
691
|
const server = new Server({
|
|
607
692
|
name: "codegraph",
|
|
608
693
|
version: runtimeIdentity.runningVersion,
|
|
609
694
|
}, {
|
|
610
695
|
capabilities: { tools: {}, logging: {} },
|
|
611
696
|
});
|
|
612
|
-
|
|
697
|
+
let inFlightToolCalls = 0;
|
|
698
|
+
const toolConcurrency = normalizeMcpToolConcurrency(maxConcurrentToolCalls);
|
|
699
|
+
server.setRequestHandler("tools/list", () => ({ tools: listCodegraphMcpTools() }));
|
|
613
700
|
server.setRequestHandler("tools/call", async (request, ctx) => {
|
|
701
|
+
if (!toolOperations.isAccepting()) {
|
|
702
|
+
throw new Error("MCP server is shutting down.");
|
|
703
|
+
}
|
|
704
|
+
if (inFlightToolCalls >= toolConcurrency) {
|
|
705
|
+
throw new Error("MCP tool execution is busy; retry shortly.");
|
|
706
|
+
}
|
|
707
|
+
inFlightToolCalls += 1;
|
|
614
708
|
const isFirstToolCall = toolCallState.firstToolCallPending;
|
|
615
709
|
toolCallState.firstToolCallPending = false;
|
|
616
710
|
const progressToken = isFirstToolCall ? getToolCallProgressToken(request.params) : undefined;
|
|
@@ -622,12 +716,7 @@ export function createCodegraphMcpProtocolServer(handlers, runtimeIdentity = cap
|
|
|
622
716
|
if (progressToken !== undefined) {
|
|
623
717
|
await ctx.mcpReq.notify({
|
|
624
718
|
method: "notifications/progress",
|
|
625
|
-
params: {
|
|
626
|
-
progressToken,
|
|
627
|
-
progress,
|
|
628
|
-
total: 1,
|
|
629
|
-
message,
|
|
630
|
-
},
|
|
719
|
+
params: { progressToken, progress, total: 1, message },
|
|
631
720
|
});
|
|
632
721
|
}
|
|
633
722
|
}
|
|
@@ -643,9 +732,24 @@ export function createCodegraphMcpProtocolServer(handlers, runtimeIdentity = cap
|
|
|
643
732
|
console.error(`[codegraph] installed-version check failed: ${errorMessage(error)}`);
|
|
644
733
|
}
|
|
645
734
|
try {
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
735
|
+
const toolCallAbort = createMcpToolAbortSignal([ctx.mcpReq.signal, legacyRequestAbortStorage.getStore()], request.params.name, mcpToolTimeoutMs);
|
|
736
|
+
const operation = toolOperations.track(() => callMcpTool(handlers, request.params.name, request.params.arguments ?? {}, toolCallAbort.signal));
|
|
737
|
+
if (operation === undefined) {
|
|
738
|
+
inFlightToolCalls -= 1;
|
|
739
|
+
toolCallAbort.dispose();
|
|
740
|
+
throw new Error("MCP server is shutting down.");
|
|
741
|
+
}
|
|
742
|
+
const releaseToolCall = () => {
|
|
743
|
+
inFlightToolCalls -= 1;
|
|
744
|
+
};
|
|
745
|
+
try {
|
|
746
|
+
const result = await awaitMcpToolOperation(toolCallAbort.signal, operation, releaseToolCall);
|
|
747
|
+
await emitFirstToolCallVisibility("info", 1, `Codegraph finished warming the first tool call for '${request.params.name}'.`);
|
|
748
|
+
return toToolResult(result);
|
|
749
|
+
}
|
|
750
|
+
finally {
|
|
751
|
+
toolCallAbort.dispose();
|
|
752
|
+
}
|
|
649
753
|
}
|
|
650
754
|
catch (error) {
|
|
651
755
|
await emitFirstToolCallVisibility("error", 1, `Codegraph failed while warming the first tool call for '${request.params.name}'.`);
|
|
@@ -654,12 +758,20 @@ export function createCodegraphMcpProtocolServer(handlers, runtimeIdentity = cap
|
|
|
654
758
|
});
|
|
655
759
|
return server;
|
|
656
760
|
}
|
|
657
|
-
function createCodegraphMcpProtocolFactory(handlers, runtimeIdentity) {
|
|
761
|
+
function createCodegraphMcpProtocolFactory(handlers, runtimeIdentity, maxConcurrentToolCalls = DEFAULT_MCP_TOOL_CONCURRENCY, mcpToolTimeoutMs = DEFAULT_MCP_TOOL_TIMEOUT_MS) {
|
|
658
762
|
const installedVersion = createInstalledVersionChecker(runtimeIdentity);
|
|
659
763
|
const toolCallState = { firstToolCallPending: true };
|
|
660
|
-
|
|
764
|
+
const toolOperations = createMcpToolOperationTracker();
|
|
765
|
+
const timeout = assertMcpToolTimeout(mcpToolTimeoutMs);
|
|
766
|
+
return {
|
|
767
|
+
create: () => createCodegraphMcpProtocolServerWithTracker(handlers, runtimeIdentity, installedVersion, toolCallState, maxConcurrentToolCalls, timeout, toolOperations),
|
|
768
|
+
stop: () => toolOperations.stop(),
|
|
769
|
+
drain: () => toolOperations.drain(),
|
|
770
|
+
};
|
|
661
771
|
}
|
|
662
772
|
export async function serveCodegraphMcp(options) {
|
|
773
|
+
const configuredMcpToolTimeout = options.mcpToolTimeoutMs === undefined ? DEFAULT_MCP_TOOL_TIMEOUT_MS : options.mcpToolTimeoutMs;
|
|
774
|
+
const mcpToolTimeoutMs = assertMcpToolTimeout(configuredMcpToolTimeout);
|
|
663
775
|
const port = options.port;
|
|
664
776
|
if (port !== undefined) {
|
|
665
777
|
const started = await startCodegraphMcpHttpServer({ ...options, port });
|
|
@@ -671,36 +783,46 @@ export async function serveCodegraphMcp(options) {
|
|
|
671
783
|
await waitForHttpServerClose(started.server);
|
|
672
784
|
return;
|
|
673
785
|
}
|
|
674
|
-
const handlers = await
|
|
786
|
+
const { handlers, session } = await createWarmedCodegraphMcpResources(options);
|
|
675
787
|
const runtimeIdentity = options.runtimeIdentity ?? captureCodegraphRuntimeIdentity(getCurrentNativeBindingOrigin());
|
|
676
|
-
const
|
|
677
|
-
const handle = serveStdio(
|
|
788
|
+
const protocolFactory = createCodegraphMcpProtocolFactory(handlers, runtimeIdentity, options.mcpToolConcurrency ?? DEFAULT_MCP_TOOL_CONCURRENCY, mcpToolTimeoutMs);
|
|
789
|
+
const handle = serveStdio(protocolFactory.create, {
|
|
678
790
|
legacy: "serve",
|
|
679
791
|
onerror: (error) => {
|
|
680
792
|
console.error(`[codegraph] MCP stdio error: ${error.message}`);
|
|
681
793
|
},
|
|
682
794
|
});
|
|
683
795
|
const idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_MCP_STDIO_IDLE_TIMEOUT_MS;
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
796
|
+
try {
|
|
797
|
+
await awaitStdioMcpLifecycle(handle, {
|
|
798
|
+
idleTimeoutMs,
|
|
799
|
+
onShutdown: (shutdownReason) => {
|
|
800
|
+
console.error(`[codegraph] MCP stdio shutting down (${shutdownReason})`);
|
|
801
|
+
},
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
finally {
|
|
805
|
+
protocolFactory.stop();
|
|
806
|
+
await protocolFactory.drain();
|
|
807
|
+
session.invalidate();
|
|
808
|
+
}
|
|
690
809
|
// Ensure orphaned stdio servers do not linger after the client is gone.
|
|
691
810
|
process.exitCode = 0;
|
|
692
811
|
}
|
|
693
812
|
export async function startCodegraphMcpHttpServer(options) {
|
|
813
|
+
const httpBodyTimeoutMs = assertMcpHttpBodyTimeout(options.httpBodyTimeoutMs === undefined ? DEFAULT_MCP_HTTP_BODY_TIMEOUT_MS : options.httpBodyTimeoutMs);
|
|
814
|
+
const configuredMcpToolTimeout = options.mcpToolTimeoutMs === undefined ? DEFAULT_MCP_TOOL_TIMEOUT_MS : options.mcpToolTimeoutMs;
|
|
815
|
+
const mcpToolTimeoutMs = assertMcpToolTimeout(configuredMcpToolTimeout);
|
|
694
816
|
const host = options.host ?? "127.0.0.1";
|
|
695
|
-
const handlers = await
|
|
817
|
+
const { handlers, session } = await createWarmedCodegraphMcpResources(options);
|
|
696
818
|
const runtimeIdentity = options.runtimeIdentity ?? captureCodegraphRuntimeIdentity(getCurrentNativeBindingOrigin());
|
|
697
|
-
const
|
|
819
|
+
const protocolFactory = createCodegraphMcpProtocolFactory(handlers, runtimeIdentity, options.mcpToolConcurrency ?? DEFAULT_MCP_TOOL_CONCURRENCY, mcpToolTimeoutMs);
|
|
698
820
|
const sessionStore = createLegacyMcpSessionStore({
|
|
699
821
|
idleMs: options.httpSessionIdleMs ?? DEFAULT_MCP_HTTP_SESSION_IDLE_MS,
|
|
700
822
|
maxCount: options.httpSessionMaxCount ?? DEFAULT_MCP_HTTP_SESSION_MAX_COUNT,
|
|
701
823
|
evictionIntervalMs: options.httpSessionEvictionIntervalMs ?? DEFAULT_MCP_HTTP_SESSION_EVICTION_INTERVAL_MS,
|
|
702
824
|
});
|
|
703
|
-
const modernHandler = createMcpHandler(
|
|
825
|
+
const modernHandler = createMcpHandler(protocolFactory.create, {
|
|
704
826
|
legacy: "reject",
|
|
705
827
|
onerror: (error) => {
|
|
706
828
|
console.error(`[codegraph] MCP HTTP error: ${error.message}`);
|
|
@@ -716,18 +838,31 @@ export async function startCodegraphMcpHttpServer(options) {
|
|
|
716
838
|
let closeResourcesPromise;
|
|
717
839
|
const closeResources = () => {
|
|
718
840
|
closeResourcesPromise ??= (async () => {
|
|
841
|
+
protocolFactory.stop();
|
|
719
842
|
sessionStore.stop();
|
|
720
|
-
|
|
843
|
+
try {
|
|
844
|
+
await closeMcpResources(sessionStore.sessions, modernHandler.close);
|
|
845
|
+
}
|
|
846
|
+
finally {
|
|
847
|
+
await protocolFactory.drain();
|
|
848
|
+
session.invalidate();
|
|
849
|
+
}
|
|
721
850
|
})();
|
|
722
851
|
return closeResourcesPromise;
|
|
723
852
|
};
|
|
724
853
|
const server = createServer((request, response) => {
|
|
725
|
-
void handleMcpHttpRequest(request, response, sessionStore, () => allowedHostHeaders, validateOrigin, modernNodeHandler,
|
|
854
|
+
void handleMcpHttpRequest(request, response, sessionStore, () => allowedHostHeaders, validateOrigin, modernNodeHandler, protocolFactory.create, httpBodyTimeoutMs);
|
|
726
855
|
});
|
|
727
856
|
server.on("close", () => {
|
|
728
857
|
void closeResources();
|
|
729
858
|
});
|
|
730
|
-
|
|
859
|
+
try {
|
|
860
|
+
await listenOnHttpServer(server, options.port, host);
|
|
861
|
+
}
|
|
862
|
+
catch (error) {
|
|
863
|
+
await closeResources();
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
731
866
|
const address = server.address();
|
|
732
867
|
const actualPort = getHttpServerPort(address);
|
|
733
868
|
const urlHost = formatHostForUrl(host);
|
|
@@ -747,7 +882,11 @@ export async function startCodegraphMcpHttpServer(options) {
|
|
|
747
882
|
},
|
|
748
883
|
};
|
|
749
884
|
}
|
|
750
|
-
async function handleMcpHttpRequest(request, response, sessionStore, getAllowedHostHeaders, validateOrigin, modernNodeHandler, createProtocolServer) {
|
|
885
|
+
async function handleMcpHttpRequest(request, response, sessionStore, getAllowedHostHeaders, validateOrigin, modernNodeHandler, createProtocolServer, bodyTimeoutMs) {
|
|
886
|
+
const writeClosingJsonRpcError = (statusCode, message) => {
|
|
887
|
+
response.setHeader("connection", "close");
|
|
888
|
+
writeJsonRpcError(response, statusCode, message);
|
|
889
|
+
};
|
|
751
890
|
const requestPath = getRequestPath(request);
|
|
752
891
|
if (requestPath !== MCP_HTTP_PATH) {
|
|
753
892
|
writeJsonResponse(response, 404, { error: "Not found" });
|
|
@@ -761,11 +900,15 @@ async function handleMcpHttpRequest(request, response, sessionStore, getAllowedH
|
|
|
761
900
|
return;
|
|
762
901
|
try {
|
|
763
902
|
if (request.method === "POST") {
|
|
764
|
-
const parsedBody = await readJsonRequestBody(request, MAX_MCP_HTTP_BODY_BYTES);
|
|
903
|
+
const parsedBody = await readJsonRequestBody(request, MAX_MCP_HTTP_BODY_BYTES, bodyTimeoutMs);
|
|
765
904
|
if (parsedBody.status === "too_large") {
|
|
766
905
|
writeJsonRpcError(response, 413, "MCP request body is too large");
|
|
767
906
|
return;
|
|
768
907
|
}
|
|
908
|
+
if (parsedBody.status === "timeout") {
|
|
909
|
+
writeClosingJsonRpcError(408, "MCP request body timed out");
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
769
912
|
if (parsedBody.status === "invalid_json") {
|
|
770
913
|
writeJsonRpcError(response, 400, "Invalid JSON request body");
|
|
771
914
|
return;
|
|
@@ -805,13 +948,7 @@ async function handleLegacyMcpHttpPost(request, response, body, sessionStore, cr
|
|
|
805
948
|
return;
|
|
806
949
|
}
|
|
807
950
|
sessionStore.touch(sessionId);
|
|
808
|
-
|
|
809
|
-
await handleLegacyMcpSessionRequest(session, request, response, body);
|
|
810
|
-
}
|
|
811
|
-
catch (error) {
|
|
812
|
-
await sessionStore.delete(sessionId);
|
|
813
|
-
throw error;
|
|
814
|
-
}
|
|
951
|
+
await handleLegacyMcpSessionRequest(session, request, response, body);
|
|
815
952
|
return;
|
|
816
953
|
}
|
|
817
954
|
if (!isInitializeRequest(body)) {
|
|
@@ -859,10 +996,16 @@ async function handleLegacyMcpHttpPost(request, response, body, sessionStore, cr
|
|
|
859
996
|
openSseStreams: 0,
|
|
860
997
|
};
|
|
861
998
|
sessionRef.current = session;
|
|
999
|
+
// The SDK transport reports every per-request validation rejection through onerror
|
|
1000
|
+
// too (bad Accept header, wrong Content-Type, malformed JSON, an unsupported
|
|
1001
|
+
// protocol version, ...) - each of those already answered its own request with a
|
|
1002
|
+
// 4xx response and left the transport fully usable. Deleting the session here would
|
|
1003
|
+
// tear down an otherwise healthy session over one malformed follow-up request. Only
|
|
1004
|
+
// onclose reflects the transport actually shutting down (an explicit DELETE, an
|
|
1005
|
+
// eviction we triggered, or a real fatal failure), so session teardown is driven by
|
|
1006
|
+
// onclose alone; onerror only logs.
|
|
862
1007
|
transport.onerror = (error) => {
|
|
863
1008
|
console.error(`[codegraph] MCP HTTP session transport error: ${error.message}`);
|
|
864
|
-
if (initializedSessionId !== undefined)
|
|
865
|
-
void sessionStore.delete(initializedSessionId);
|
|
866
1009
|
};
|
|
867
1010
|
transport.onclose = () => {
|
|
868
1011
|
if (initializedSessionId !== undefined)
|
|
@@ -871,6 +1014,14 @@ async function handleLegacyMcpHttpPost(request, response, body, sessionStore, cr
|
|
|
871
1014
|
try {
|
|
872
1015
|
await protocolServer.connect(transport);
|
|
873
1016
|
await handleLegacyMcpSessionRequest(session, request, response, body);
|
|
1017
|
+
if (initializedSessionId === undefined) {
|
|
1018
|
+
// The transport answered a pre-session 4xx (invalid Accept header, wrong
|
|
1019
|
+
// Content-Type, malformed JSON, ...) without throwing and without ever reaching
|
|
1020
|
+
// onsessioninitialized, so nothing else releases this capacity reservation or
|
|
1021
|
+
// closes this ad hoc protocol server/transport pair.
|
|
1022
|
+
releaseCapacityReservation();
|
|
1023
|
+
await closeMcpSession(session);
|
|
1024
|
+
}
|
|
874
1025
|
}
|
|
875
1026
|
catch (error) {
|
|
876
1027
|
if (initializedSessionId !== undefined) {
|
|
@@ -895,12 +1046,33 @@ async function handleExistingMcpSessionRequest(request, response, sessionStore)
|
|
|
895
1046
|
return;
|
|
896
1047
|
}
|
|
897
1048
|
sessionStore.touch(sessionId);
|
|
1049
|
+
await handleLegacyMcpSessionRequest(session, request, response);
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Runs one legacy HTTP request with a signal that aborts when its connection closes.
|
|
1053
|
+
* The signal is scoped to this request and is available to nested MCP tool dispatch.
|
|
1054
|
+
*/
|
|
1055
|
+
export async function runWithLegacyRequestAbortSignal(request, response, operation) {
|
|
1056
|
+
const abortController = new AbortController();
|
|
1057
|
+
let completed = false;
|
|
1058
|
+
const abortDisconnectedRequest = () => {
|
|
1059
|
+
if (completed)
|
|
1060
|
+
return;
|
|
1061
|
+
if (request.aborted || (!response.writableFinished && response.destroyed)) {
|
|
1062
|
+
abortController.abort(new Error("MCP HTTP request connection closed."));
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
request.on("aborted", abortDisconnectedRequest);
|
|
1066
|
+
request.on("close", abortDisconnectedRequest);
|
|
1067
|
+
response.on("close", abortDisconnectedRequest);
|
|
898
1068
|
try {
|
|
899
|
-
await
|
|
1069
|
+
return await legacyRequestAbortStorage.run(abortController.signal, operation);
|
|
900
1070
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1071
|
+
finally {
|
|
1072
|
+
completed = true;
|
|
1073
|
+
request.off("aborted", abortDisconnectedRequest);
|
|
1074
|
+
request.off("close", abortDisconnectedRequest);
|
|
1075
|
+
response.off("close", abortDisconnectedRequest);
|
|
904
1076
|
}
|
|
905
1077
|
}
|
|
906
1078
|
async function handleLegacyMcpSessionRequest(session, request, response, body) {
|
|
@@ -909,7 +1081,9 @@ async function handleLegacyMcpSessionRequest(session, request, response, body) {
|
|
|
909
1081
|
if (tracksSseStream)
|
|
910
1082
|
session.openSseStreams += 1;
|
|
911
1083
|
try {
|
|
912
|
-
await
|
|
1084
|
+
await runWithLegacyRequestAbortSignal(request, response, async () => {
|
|
1085
|
+
await session.transport.handleRequest(request, response, body);
|
|
1086
|
+
});
|
|
913
1087
|
}
|
|
914
1088
|
finally {
|
|
915
1089
|
session.inFlightRequests -= 1;
|
|
@@ -1019,88 +1193,129 @@ async function closeMcpResources(sessions, closeModernHandler) {
|
|
|
1019
1193
|
function isMcpNodeRequest(request) {
|
|
1020
1194
|
return request.method !== undefined && request.url !== undefined;
|
|
1021
1195
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1196
|
+
function createMcpToolAbortSignal(requestSignals, toolName, timeoutMs) {
|
|
1197
|
+
const controller = new AbortController();
|
|
1198
|
+
const listeners = [];
|
|
1199
|
+
for (const requestSignal of requestSignals) {
|
|
1200
|
+
if (requestSignal === undefined)
|
|
1201
|
+
continue;
|
|
1202
|
+
const onAbort = () => {
|
|
1203
|
+
controller.abort(requestSignal.reason);
|
|
1204
|
+
};
|
|
1205
|
+
listeners.push({ signal: requestSignal, onAbort });
|
|
1206
|
+
if (requestSignal.aborted)
|
|
1207
|
+
onAbort();
|
|
1208
|
+
else
|
|
1209
|
+
requestSignal.addEventListener("abort", onAbort, { once: true });
|
|
1210
|
+
}
|
|
1211
|
+
const timeout = timeoutMs > 0
|
|
1212
|
+
? setTimeout(() => {
|
|
1213
|
+
controller.abort(new Error(`MCP tool '${toolName}' exceeded the configured deadline of ${timeoutMs} ms.`));
|
|
1214
|
+
}, timeoutMs)
|
|
1215
|
+
: undefined;
|
|
1216
|
+
timeout?.unref?.();
|
|
1217
|
+
return {
|
|
1218
|
+
signal: controller.signal,
|
|
1219
|
+
dispose: () => {
|
|
1220
|
+
clearTimeout(timeout);
|
|
1221
|
+
for (const listener of listeners)
|
|
1222
|
+
listener.signal.removeEventListener("abort", listener.onAbort);
|
|
1223
|
+
},
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
export function awaitMcpToolOperation(signal, operation, onSettled) {
|
|
1227
|
+
void operation.then(onSettled, onSettled);
|
|
1228
|
+
return withAbortSignal(signal, operation);
|
|
1229
|
+
}
|
|
1230
|
+
function withAbortSignal(signal, operation) {
|
|
1231
|
+
if (!signal)
|
|
1232
|
+
return operation;
|
|
1233
|
+
const cancellationError = () => {
|
|
1234
|
+
const reason = signal.reason;
|
|
1235
|
+
if (reason instanceof Error && reason.name !== "AbortError")
|
|
1236
|
+
return reason;
|
|
1237
|
+
return new Error("MCP tool call was cancelled.");
|
|
1238
|
+
};
|
|
1239
|
+
if (signal.aborted)
|
|
1240
|
+
return Promise.reject(cancellationError());
|
|
1241
|
+
const cancellation = Promise.withResolvers();
|
|
1242
|
+
const onAbort = () => cancellation.reject(cancellationError());
|
|
1243
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1244
|
+
return Promise.race([operation, cancellation.promise]).finally(() => signal.removeEventListener("abort", onAbort));
|
|
1245
|
+
}
|
|
1246
|
+
export async function callMcpTool(handlers, name, input, signal) {
|
|
1247
|
+
const tool = MCP_TOOL_REGISTRY.find((entry) => entry.name === name);
|
|
1248
|
+
if (!tool)
|
|
1249
|
+
throw new Error(`Unknown MCP tool: ${name}`);
|
|
1250
|
+
switch (tool.dispatch.handler) {
|
|
1024
1251
|
case "search":
|
|
1025
|
-
return await handlers.search(parseMcpToolInput(searchSchema, input,
|
|
1252
|
+
return await handlers.search(parseMcpToolInput(searchSchema, input, name), signal);
|
|
1026
1253
|
case "workspace_symbols":
|
|
1027
|
-
return await handlers.workspace_symbols(parseMcpToolInput(workspaceSymbolsSchema, input,
|
|
1254
|
+
return await handlers.workspace_symbols(parseMcpToolInput(workspaceSymbolsSchema, input, name), signal);
|
|
1028
1255
|
case "rename_preview":
|
|
1029
|
-
return await handlers.rename_preview(parseMcpToolInput(renamePreviewSchema, input,
|
|
1256
|
+
return await handlers.rename_preview(parseMcpToolInput(renamePreviewSchema, input, name), signal);
|
|
1030
1257
|
case "refactor_plan":
|
|
1031
|
-
return await handlers.refactor_plan(parseMcpToolInput(refactorPlanSchema, input,
|
|
1258
|
+
return await handlers.refactor_plan(parseMcpToolInput(refactorPlanSchema, input, name), signal);
|
|
1032
1259
|
case "calls":
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
return await handlers.calls({ ...parseMcpToolInput(callHierarchySchema, input, name), direction: "callees" });
|
|
1260
|
+
if (tool.dispatch.direction) {
|
|
1261
|
+
return await handlers.calls({ ...parseMcpToolInput(callHierarchySchema, input, name), direction: tool.dispatch.direction }, signal);
|
|
1262
|
+
}
|
|
1263
|
+
return await handlers.calls(parseMcpToolInput(callsSchema, input, name), signal);
|
|
1038
1264
|
case "type_hierarchy":
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
direction: "supertypes",
|
|
1044
|
-
});
|
|
1045
|
-
case "subtypes":
|
|
1046
|
-
return await handlers.type_hierarchy({
|
|
1047
|
-
...parseMcpToolInput(typeHierarchySchema, input, name),
|
|
1048
|
-
direction: "subtypes",
|
|
1049
|
-
});
|
|
1265
|
+
if (tool.dispatch.direction) {
|
|
1266
|
+
return await handlers.type_hierarchy({ ...parseMcpToolInput(typeHierarchySchema, input, name), direction: tool.dispatch.direction }, signal);
|
|
1267
|
+
}
|
|
1268
|
+
return await handlers.type_hierarchy(parseMcpToolInput(typeHierarchyUnifiedSchema, input, name), signal);
|
|
1050
1269
|
case "implementations":
|
|
1051
|
-
return await handlers.implementations(parseMcpToolInput(implementationsSchema, input,
|
|
1270
|
+
return await handlers.implementations(parseMcpToolInput(implementationsSchema, input, name), signal);
|
|
1052
1271
|
case "explore":
|
|
1053
|
-
return await handlers.explore(parseMcpToolInput(exploreSchema, input,
|
|
1272
|
+
return await handlers.explore(parseMcpToolInput(exploreSchema, input, name), signal);
|
|
1054
1273
|
case "orient":
|
|
1055
|
-
return await handlers.orient(parseMcpToolInput(orientSchema, input,
|
|
1274
|
+
return await handlers.orient(parseMcpToolInput(orientSchema, input, name), signal);
|
|
1056
1275
|
case "packet_get":
|
|
1057
|
-
return await handlers.packet_get(parseMcpToolInput(packetGetSchema, input,
|
|
1276
|
+
return await handlers.packet_get(parseMcpToolInput(packetGetSchema, input, name), signal);
|
|
1058
1277
|
case "get_file":
|
|
1059
|
-
return await handlers.get_file(parseMcpToolInput(getFileSchema, input,
|
|
1278
|
+
return await handlers.get_file(parseMcpToolInput(getFileSchema, input, name), signal);
|
|
1060
1279
|
case "get_symbol":
|
|
1061
|
-
return await handlers.get_symbol(parseMcpToolInput(handleSchema, input,
|
|
1280
|
+
return await handlers.get_symbol(parseMcpToolInput(handleSchema, input, name), signal);
|
|
1062
1281
|
case "goto":
|
|
1063
|
-
return await callGotoTool(handlers, input);
|
|
1282
|
+
return await callGotoTool(handlers, input, signal);
|
|
1064
1283
|
case "refs":
|
|
1065
|
-
return await callRefsTool(handlers, input);
|
|
1284
|
+
return await callRefsTool(handlers, input, signal);
|
|
1066
1285
|
case "file_deps":
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
return await handlers.file_deps({ ...parseMcpToolInput(fileGraphSchema, input, name), direction: "rdeps" });
|
|
1286
|
+
if (tool.dispatch.direction) {
|
|
1287
|
+
return await handlers.file_deps({ ...parseMcpToolInput(fileGraphSchema, input, name), direction: tool.dispatch.direction }, signal);
|
|
1288
|
+
}
|
|
1289
|
+
return await handlers.file_deps(parseMcpToolInput(fileDepsUnifiedSchema, input, name), signal);
|
|
1072
1290
|
case "path":
|
|
1073
|
-
return await handlers.path(parseMcpToolInput(pathSchema, input,
|
|
1291
|
+
return await handlers.path(parseMcpToolInput(pathSchema, input, name), signal);
|
|
1074
1292
|
case "impact":
|
|
1075
|
-
return await handlers.impact(parseMcpToolInput(gitRangeSchema, input, name));
|
|
1293
|
+
return await handlers.impact(parseMcpToolInput(gitRangeSchema, input, name), signal);
|
|
1076
1294
|
case "review":
|
|
1077
|
-
return await handlers.review(parseMcpToolInput(reviewSchema, input,
|
|
1295
|
+
return await handlers.review(parseMcpToolInput(reviewSchema, input, name), signal);
|
|
1078
1296
|
case "query_sqlite":
|
|
1079
|
-
return await handlers.query_sqlite(parseMcpToolInput(querySqliteSchema, input,
|
|
1297
|
+
return await handlers.query_sqlite(parseMcpToolInput(querySqliteSchema, input, name), {
|
|
1298
|
+
...(signal ? { signal } : {}),
|
|
1299
|
+
});
|
|
1080
1300
|
case "refresh_index":
|
|
1081
|
-
return await handlers.refresh_index(parseMcpToolInput(refreshIndexSchema, input,
|
|
1301
|
+
return await handlers.refresh_index(parseMcpToolInput(refreshIndexSchema, input, name), signal);
|
|
1082
1302
|
case "artifact_build":
|
|
1083
|
-
return await handlers.artifact_build(parseMcpToolInput(artifactBuildSchema, input,
|
|
1084
|
-
default:
|
|
1085
|
-
throw new Error(`Unknown MCP tool: ${name}`);
|
|
1303
|
+
return await handlers.artifact_build(parseMcpToolInput(artifactBuildSchema, input, name), signal);
|
|
1086
1304
|
}
|
|
1087
1305
|
}
|
|
1088
|
-
async function callGotoTool(handlers, input) {
|
|
1306
|
+
async function callGotoTool(handlers, input, signal) {
|
|
1089
1307
|
const request = parseMcpToolInput(navigationSchema, input, "goto");
|
|
1090
1308
|
if (request.handle !== undefined)
|
|
1091
|
-
return await handlers.goto({ handle: request.handle });
|
|
1309
|
+
return await handlers.goto({ handle: request.handle }, signal);
|
|
1092
1310
|
if (request.file === undefined || request.line === undefined || request.column === undefined) {
|
|
1093
1311
|
throw new Error("goto requires either handle or file, line, and column.");
|
|
1094
1312
|
}
|
|
1095
|
-
return await handlers.goto({ file: request.file, line: request.line, column: request.column });
|
|
1313
|
+
return await handlers.goto({ file: request.file, line: request.line, column: request.column }, signal);
|
|
1096
1314
|
}
|
|
1097
|
-
async function callRefsTool(handlers, input) {
|
|
1315
|
+
async function callRefsTool(handlers, input, signal) {
|
|
1098
1316
|
const request = parseMcpToolInput(refsSchema, input, "refs");
|
|
1099
1317
|
if (request.handle !== undefined) {
|
|
1100
|
-
return await handlers.refs({
|
|
1101
|
-
handle: request.handle,
|
|
1102
|
-
...(request.limit !== undefined ? { limit: request.limit } : {}),
|
|
1103
|
-
});
|
|
1318
|
+
return await handlers.refs({ handle: request.handle, ...(request.limit !== undefined ? { limit: request.limit } : {}) }, signal);
|
|
1104
1319
|
}
|
|
1105
1320
|
if (request.file === undefined || request.line === undefined || request.column === undefined) {
|
|
1106
1321
|
throw new Error("refs requires either handle or file, line, and column.");
|
|
@@ -1110,7 +1325,7 @@ async function callRefsTool(handlers, input) {
|
|
|
1110
1325
|
line: request.line,
|
|
1111
1326
|
column: request.column,
|
|
1112
1327
|
...(request.limit !== undefined ? { limit: request.limit } : {}),
|
|
1113
|
-
});
|
|
1328
|
+
}, signal);
|
|
1114
1329
|
}
|
|
1115
1330
|
function toToolResult(value) {
|
|
1116
1331
|
return {
|