gitnexus 1.6.11-rc.8 → 1.6.11
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 +95 -26
- package/dist/_shared/graph/types.d.ts +81 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +2 -1
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +4 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts +3 -0
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +4 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +10 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +15 -0
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +4 -0
- package/dist/cli/ai-context.js +90 -14
- package/dist/cli/analyze-config.js +14 -0
- package/dist/cli/analyze-options.d.ts +14 -0
- package/dist/cli/analyze-watch.d.ts +20 -0
- package/dist/cli/analyze-watch.js +434 -0
- package/dist/cli/analyze.js +27 -9
- package/dist/cli/auto-sync.d.ts +1 -0
- package/dist/cli/auto-sync.js +107 -0
- package/dist/cli/command-banner.d.ts +15 -0
- package/dist/cli/command-banner.js +42 -0
- package/dist/cli/detect-changes-format.js +21 -0
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.js +14 -0
- package/dist/cli/group.js +7 -1
- package/dist/cli/help-i18n.js +4 -0
- package/dist/cli/i18n/en.d.ts +18 -3
- package/dist/cli/i18n/en.js +18 -3
- package/dist/cli/i18n/resources.d.ts +33 -3
- package/dist/cli/i18n/zh-CN.d.ts +15 -0
- package/dist/cli/i18n/zh-CN.js +18 -3
- package/dist/cli/index.js +34 -7
- package/dist/cli/mcp.d.ts +15 -0
- package/dist/cli/mcp.js +44 -0
- package/dist/cli/optional-grammars.d.ts +3 -2
- package/dist/cli/optional-grammars.js +19 -3
- package/dist/cli/setup.js +41 -15
- package/dist/cli/update-notice.d.ts +34 -0
- package/dist/cli/update-notice.js +91 -0
- package/dist/cli/update.d.ts +21 -0
- package/dist/cli/update.js +93 -0
- package/dist/cli/watch.d.ts +1 -20
- package/dist/cli/watch.js +5 -371
- package/dist/core/analysis-feature-registry.d.ts +2 -0
- package/dist/core/analysis-feature-registry.js +15 -0
- package/dist/core/analyzer-identity.js +21 -3
- package/dist/core/auto-sync/analysis-worker-launch.d.ts +30 -0
- package/dist/core/auto-sync/analysis-worker-launch.js +166 -0
- package/dist/core/auto-sync/config.d.ts +33 -0
- package/dist/core/auto-sync/config.js +320 -0
- package/dist/core/auto-sync/index.d.ts +6 -0
- package/dist/core/auto-sync/index.js +6 -0
- package/dist/core/auto-sync/path-security.d.ts +9 -0
- package/dist/core/auto-sync/path-security.js +251 -0
- package/dist/core/auto-sync/repo.d.ts +1 -0
- package/dist/core/auto-sync/repo.js +6 -0
- package/dist/core/auto-sync/runner.d.ts +44 -0
- package/dist/core/auto-sync/runner.js +428 -0
- package/dist/core/auto-sync/starter.d.ts +50 -0
- package/dist/core/auto-sync/starter.js +497 -0
- package/dist/core/auto-sync/state.d.ts +37 -0
- package/dist/core/auto-sync/state.js +119 -0
- package/dist/core/group/config-parser.js +8 -1
- package/dist/core/group/cross-impact.d.ts +3 -0
- package/dist/core/group/cross-impact.js +36 -4
- package/dist/core/group/extractors/http-patterns/java.js +22 -8
- package/dist/core/group/extractors/http-patterns/kotlin.js +86 -31
- package/dist/core/group/extractors/http-patterns/node.js +145 -8
- package/dist/core/group/extractors/http-patterns/python.js +11 -7
- package/dist/core/group/extractors/http-route-extractor.js +63 -17
- package/dist/core/group/extractors/java-workspace-extractor.js +244 -31
- package/dist/core/group/group-lock.js +5 -6
- package/dist/core/group/normalization.d.ts +38 -1
- package/dist/core/group/normalization.js +59 -3
- package/dist/core/group/service.d.ts +11 -0
- package/dist/core/group/service.js +13 -1
- package/dist/core/group/storage.js +2 -2
- package/dist/core/group/sync.d.ts +24 -1
- package/dist/core/group/sync.js +46 -8
- package/dist/core/group/types.d.ts +13 -0
- package/dist/core/incremental/derived-writeback.d.ts +36 -0
- package/dist/core/incremental/derived-writeback.js +68 -0
- package/dist/core/incremental/spring-config-drift.d.ts +12 -0
- package/dist/core/incremental/spring-config-drift.js +46 -0
- package/dist/core/incremental/subgraph-extract.d.ts +7 -4
- package/dist/core/incremental/subgraph-extract.js +30 -5
- package/dist/core/ingestion/asyncapi/document.d.ts +226 -0
- package/dist/core/ingestion/asyncapi/document.js +758 -0
- package/dist/core/ingestion/asyncapi/protocol.d.ts +79 -0
- package/dist/core/ingestion/asyncapi/protocol.js +203 -0
- package/dist/core/ingestion/call-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/zig.js +4 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.d.ts +100 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.js +319 -0
- package/dist/core/ingestion/call-processor.js +3 -1
- package/dist/core/ingestion/class-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/zig.js +32 -0
- package/dist/core/ingestion/class-extractors/generic.js +4 -1
- package/dist/core/ingestion/class-types.d.ts +6 -2
- package/dist/core/ingestion/destination-key.d.ts +59 -0
- package/dist/core/ingestion/destination-key.js +61 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +6 -2
- package/dist/core/ingestion/entry-point-scoring.js +8 -44
- package/dist/core/ingestion/export-detection.d.ts +37 -0
- package/dist/core/ingestion/export-detection.js +60 -0
- package/dist/core/ingestion/field-extractors/configs/zig.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/zig.js +49 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +1 -1
- package/dist/core/ingestion/field-extractors/generic.js +12 -1
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.d.ts +26 -0
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.js +843 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +5 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +9 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +8 -1
- package/dist/core/ingestion/frameworks/spring/argument-facts.d.ts +80 -0
- package/dist/core/ingestion/frameworks/spring/argument-facts.js +85 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +1 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +2 -1
- package/dist/core/ingestion/frameworks/spring/destinations.d.ts +539 -0
- package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.d.ts +22 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.js +124 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.d.ts +78 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.js +90 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +29 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.d.ts +7 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.js +22 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.d.ts +13 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.js +26 -0
- package/dist/core/ingestion/import-resolvers/zig.d.ts +34 -0
- package/dist/core/ingestion/import-resolvers/zig.js +193 -0
- package/dist/core/ingestion/language-config.d.ts +177 -0
- package/dist/core/ingestion/language-config.js +719 -0
- package/dist/core/ingestion/language-provider.d.ts +178 -1
- package/dist/core/ingestion/language-provider.js +22 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.d.ts +62 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.js +954 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.d.ts +3 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.js +6 -1
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +8 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java/analysis-features.d.ts +1 -1
- package/dist/core/ingestion/languages/java/analysis-features.js +14 -6
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +8 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +34 -0
- package/dist/core/ingestion/languages/java/captures.js +22 -1
- package/dist/core/ingestion/languages/java/lombok-synthesizer.d.ts +42 -0
- package/dist/core/ingestion/languages/java/lombok-synthesizer.js +439 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.js +62 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +17 -1
- package/dist/core/ingestion/languages/java/spring-di.js +44 -2
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.js +62 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.d.ts +20 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.js +83 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +11 -1
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +13 -3
- package/dist/core/ingestion/languages/java.js +18 -8
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.d.ts +99 -0
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.js +173 -0
- package/dist/core/ingestion/languages/jvm/beanspec.d.ts +17 -0
- package/dist/core/ingestion/languages/jvm/beanspec.js +42 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +15 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +50 -0
- package/dist/core/ingestion/languages/kotlin/captures.js +24 -1
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.d.ts +26 -0
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.js +417 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.js +172 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.d.ts +18 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.js +411 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +51 -1
- package/dist/core/ingestion/languages/kotlin/spring-di.js +86 -6
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.js +77 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.d.ts +17 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.js +119 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +16 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +77 -2
- package/dist/core/ingestion/languages/kotlin.js +24 -0
- package/dist/core/ingestion/languages/python.js +2 -0
- package/dist/core/ingestion/languages/rust/query.js +8 -8
- package/dist/core/ingestion/languages/zig/captures.d.ts +260 -0
- package/dist/core/ingestion/languages/zig/captures.js +2070 -0
- package/dist/core/ingestion/languages/zig/index.d.ts +4 -0
- package/dist/core/ingestion/languages/zig/index.js +4 -0
- package/dist/core/ingestion/languages/zig/interpret.d.ts +36 -0
- package/dist/core/ingestion/languages/zig/interpret.js +176 -0
- package/dist/core/ingestion/languages/zig/query.d.ts +3 -0
- package/dist/core/ingestion/languages/zig/query.js +426 -0
- package/dist/core/ingestion/languages/zig/range-binding.d.ts +37 -0
- package/dist/core/ingestion/languages/zig/range-binding.js +373 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.d.ts +12 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.js +58 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.d.ts +25 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.js +143 -0
- package/dist/core/ingestion/languages/zig.d.ts +32 -0
- package/dist/core/ingestion/languages/zig.js +130 -0
- package/dist/core/ingestion/method-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/zig.js +120 -0
- package/dist/core/ingestion/method-extractors/generic.js +16 -4
- package/dist/core/ingestion/method-types.d.ts +10 -4
- package/dist/core/ingestion/model/field-registry.d.ts +3 -3
- package/dist/core/ingestion/model/field-registry.js +11 -7
- package/dist/core/ingestion/model/method-registry.d.ts +3 -3
- package/dist/core/ingestion/model/method-registry.js +13 -8
- package/dist/core/ingestion/model/registration-table.js +3 -0
- package/dist/core/ingestion/model/type-registry.js +8 -4
- package/dist/core/ingestion/pipeline-phases/di.js +47 -14
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +7 -1
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +79 -91
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +2 -1
- package/dist/core/ingestion/pipeline-phases/processes.js +39 -4
- package/dist/core/ingestion/pipeline-phases/routes.js +27 -18
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +4 -1
- package/dist/core/ingestion/pipeline-phases/runner.js +34 -14
- package/dist/core/ingestion/pipeline-phases/scan.js +82 -1
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +8 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +123 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.js +688 -0
- package/dist/core/ingestion/pipeline.d.ts +30 -1
- package/dist/core/ingestion/pipeline.js +52 -14
- package/dist/core/ingestion/resolve-references.js +5 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +16 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +10 -0
- package/dist/core/ingestion/route-extractors/java-const-resolver.d.ts +27 -1
- package/dist/core/ingestion/route-extractors/java-const-resolver.js +161 -13
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.d.ts +12 -18
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.js +214 -33
- package/dist/core/ingestion/route-extractors/kotlin-spring.d.ts +13 -0
- package/dist/core/ingestion/route-extractors/kotlin-spring.js +259 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.d.ts +6 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.js +16 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +30 -1
- package/dist/core/ingestion/route-extractors/spring-shared.js +77 -9
- package/dist/core/ingestion/route-extractors/spring.js +9 -5
- package/dist/core/ingestion/scope-extractor.js +8 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +62 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +4 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +2 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +28 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +11 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +23 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +24 -3
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +11 -1
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +26 -6
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +11 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +29 -3
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +8 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +35 -9
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +1 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +277 -9
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +7 -3
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +43 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +71 -10
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -0
- package/dist/core/ingestion/tree-sitter-queries.js +161 -0
- package/dist/core/ingestion/type-extractors/zig.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/zig.js +17 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +40 -1
- package/dist/core/ingestion/utils/ast-helpers.js +124 -6
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +9 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +75 -14
- package/dist/core/ingestion/utils/test-file-path.d.ts +28 -0
- package/dist/core/ingestion/utils/test-file-path.js +87 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.js +71 -0
- package/dist/core/ingestion/workers/parse-worker.js +85 -14
- package/dist/core/install-context.d.ts +4 -0
- package/dist/core/install-context.js +152 -0
- package/dist/core/lbug/csv-generator.d.ts +10 -1
- package/dist/core/lbug/csv-generator.js +92 -22
- package/dist/core/lbug/graph-emit-sink.d.ts +3 -2
- package/dist/core/lbug/graph-emit-sink.js +4 -2
- package/dist/core/lbug/lbug-adapter.d.ts +100 -5
- package/dist/core/lbug/lbug-adapter.js +236 -24
- package/dist/core/lbug/schema.d.ts +6 -5
- package/dist/core/lbug/schema.js +84 -22
- package/dist/core/net/url-guard.d.ts +6 -0
- package/dist/core/net/url-guard.js +147 -0
- package/dist/core/package-version.d.ts +5 -0
- package/dist/core/package-version.js +10 -0
- package/dist/core/run-analyze.d.ts +21 -4
- package/dist/core/run-analyze.js +426 -117
- package/dist/core/search/fts-indexes.d.ts +19 -1
- package/dist/core/search/fts-indexes.js +28 -1
- package/dist/core/tree-sitter/parser-loader.js +16 -0
- package/dist/core/update-cache.d.ts +39 -0
- package/dist/core/update-cache.js +141 -0
- package/dist/core/update-check.d.ts +31 -0
- package/dist/core/update-check.js +274 -0
- package/dist/mcp/local/local-backend.d.ts +27 -13
- package/dist/mcp/local/local-backend.js +148 -60
- package/dist/mcp/repository-policy.d.ts +5 -1
- package/dist/mcp/repository-policy.js +48 -4
- package/dist/mcp/resources.js +10 -1
- package/dist/mcp/server.js +8 -9
- package/dist/mcp/tools.js +32 -22
- package/dist/server/analyze-launch.d.ts +2 -0
- package/dist/server/analyze-launch.js +2 -0
- package/dist/server/analyze-worker-protocol.d.ts +6 -1
- package/dist/server/analyze-worker.d.ts +1 -0
- package/dist/server/analyze-worker.js +38 -20
- package/dist/server/api.d.ts +5 -1
- package/dist/server/api.js +105 -88
- package/dist/server/git-clone.d.ts +40 -16
- package/dist/server/git-clone.js +253 -199
- package/dist/server/grep-params.d.ts +18 -0
- package/dist/server/grep-params.js +83 -0
- package/dist/server/grep-scan.d.ts +23 -0
- package/dist/server/grep-scan.js +107 -0
- package/dist/server/grep-worker.d.ts +1 -0
- package/dist/server/grep-worker.js +12 -0
- package/dist/server/mcp-http.d.ts +8 -0
- package/dist/server/mcp-http.js +16 -1
- package/dist/server/update-controller.d.ts +29 -0
- package/dist/server/update-controller.js +82 -0
- package/dist/storage/file-lock.d.ts +15 -0
- package/dist/storage/file-lock.js +155 -0
- package/dist/storage/fs-atomic.d.ts +24 -0
- package/dist/storage/fs-atomic.js +86 -2
- package/dist/storage/global-dir.d.ts +2 -0
- package/dist/storage/global-dir.js +6 -0
- package/dist/storage/parse-cache.d.ts +45 -7
- package/dist/storage/parse-cache.js +189 -42
- package/dist/storage/parsedfile-store.d.ts +41 -60
- package/dist/storage/parsedfile-store.js +247 -171
- package/dist/storage/repo-manager.d.ts +10 -4
- package/dist/storage/repo-manager.js +35 -25
- package/dist/storage/repo-meta.d.ts +34 -0
- package/dist/storage/v8-sidecar.d.ts +48 -0
- package/dist/storage/v8-sidecar.js +347 -0
- package/dist/types/pipeline.d.ts +14 -0
- package/dist/utils/process-identity.d.ts +2 -0
- package/dist/utils/process-identity.js +35 -0
- package/package.json +10 -4
- package/scripts/assert-web-assets.mjs +35 -0
- package/scripts/build-web.js +72 -0
- package/scripts/build.js +31 -28
- package/scripts/cross-platform-tests.ts +5 -0
- package/skills/gitnexus-cli.md +5 -1
- package/web/assets/ProcessFlowModal-DAeX2BHW.js +24 -0
- package/web/assets/{abnfDiagram-QNN2D4NM-Cq2djWWe.js → abnfDiagram-PAR5IXJI-J3OdeHLl.js} +1 -1
- package/web/assets/{agent-BWAXPjC5.js → agent-BMRqXorA.js} +6 -4
- package/web/assets/architecture-7GRP2DOG-M7G3SWCO-G3sWyX6M.js +1 -0
- package/web/assets/architectureDiagram-2PNWDENW-ysKcRlGT.js +36 -0
- package/web/assets/blockDiagram-PUWGUBOA-oLXTa1lY.js +129 -0
- package/web/assets/c4Diagram-3NLNHZP5-D3iu4eC0.js +38 -0
- package/web/assets/{chunk-2SREHG4O-Dip42xOq.js → chunk-2NMSUPJH-B24w-wng.js} +1 -1
- package/web/assets/{chunk-VJFVEZTB-CX66F2ep.js → chunk-32MCUW2P-ByUyt0Sa.js} +3 -3
- package/web/assets/{chunk-4RFN2BYJ-DHHWuC-n.js → chunk-3NPNU5GP-DocZ07Sg.js} +1 -1
- package/web/assets/{chunk-XNMVGMAZ-Cg_LnPtj.js → chunk-3SMGFRGC-CAu4JRLv.js} +1 -1
- package/web/assets/{chunk-W44A43WB-BN8EQc_u.js → chunk-4CAJECRU-DRYMwG9z.js} +1 -1
- package/web/assets/chunk-4OADUZ5Q-CxrSvOwZ.js +10 -0
- package/web/assets/{chunk-DMV4VAQV-Bn6WXDSX.js → chunk-5IQCK5RY-CCMhl4so.js} +2 -2
- package/web/assets/{chunk-RRFMTAIC-CMN0wcYA.js → chunk-5MVFYWFU-Db9KvrYO.js} +1 -1
- package/web/assets/chunk-CLS4B6BI-Uvx5QNsu.js +168 -0
- package/web/assets/chunk-DZP67EKU-B3Mt380j.js +70 -0
- package/web/assets/{chunk-6L755F7B-CMhLBxi2.js → chunk-EICP7K5X-CqwE9hui.js} +1 -1
- package/web/assets/{chunk-BI6VK774-D0oaWk8V.js → chunk-GDY2UAB4-CtQQR0a8.js} +1 -1
- package/web/assets/chunk-H7VHZCWX-CE1nAmt6.js +1 -0
- package/web/assets/chunk-IJBDOHL6-BUKtY6oF.js +1 -0
- package/web/assets/{chunk-OIYT25JQ-CQ6KOZGX.js → chunk-JFFVMJIA-0fJenqia.js} +1 -1
- package/web/assets/{chunk-HNC4WDU7-DoU3KnA7.js → chunk-JZGDI5JK-BeTMSSkJ.js} +1 -1
- package/web/assets/{chunk-EQFTRU2I-1ix7TzW9.js → chunk-KD6SPIPN-Qp1Pflah.js} +1 -1
- package/web/assets/chunk-NF366YI6-CpSpya3n.js +231 -0
- package/web/assets/chunk-NUDPKBEF-CU1-BQIW.js +34 -0
- package/web/assets/{chunk-SATU7PGQ-B1zhgOvc.js → chunk-OJINMHTS-zOCQe4eI.js} +1 -1
- package/web/assets/{chunk-E5QJAATJ-dh-5CtIV.js → chunk-Q6NGPIAH-yyBomb63.js} +1 -1
- package/web/assets/chunk-QJSWEUOL-D_rf9gPD.js +128 -0
- package/web/assets/chunk-R7JDMUKV-CRoqKpD6.js +1 -0
- package/web/assets/{chunk-VE5CLXGZ-C1vB7wpY.js → chunk-RCXAM2GK-CUqrWQDV.js} +1 -1
- package/web/assets/{chunk-66DQ2XMT-CM0xjFAN.js → chunk-RT4MAWR3-zXy9-Lvt.js} +1 -1
- package/web/assets/{chunk-TZUXEDM2-B7p9AcTw.js → chunk-SFMINX4W-J2UrvMpD.js} +1 -1
- package/web/assets/{chunk-LORZLZWG-B57uGw2N.js → chunk-SLDQ463B-CHY6e_bQ.js} +2 -2
- package/web/assets/{chunk-FWYVLQTC-BgDItRzJ.js → chunk-TCEHX7R3-CXPDEVbm.js} +1 -1
- package/web/assets/{chunk-224SPVON-B8gxtXpy.js → chunk-VQC2EELJ-Dc8fIy4R.js} +1 -1
- package/web/assets/chunk-VRZKL3EH-DB3KixTQ.js +1 -0
- package/web/assets/{chunk-A7VWPJGB-B4O3oQdQ.js → chunk-VTHDQ7BV-b7FsPQZO.js} +1 -1
- package/web/assets/chunk-VY2OSTJR-Dkgc3Brg.js +2 -0
- package/web/assets/chunk-WUBWJARI-7FwILJ3k.js +2 -0
- package/web/assets/{chunk-D6VWDJW2-BxcBdZ9c.js → chunk-YBMQ5JGJ-BSnyWZmd.js} +1 -1
- package/web/assets/chunk-YDMLL4PJ-IHhMngTz.js +2 -0
- package/web/assets/chunk-Z6V44ARX-BjCEsF0Q.js +62 -0
- package/web/assets/chunk-ZJJ7VQJP-Dz089b-K.js +321 -0
- package/web/assets/chunk-ZNLK7HRR-B0iFpmW4.js +1 -0
- package/web/assets/chunk-ZQN7UHIL-Cy7KAjQt.js +1 -0
- package/web/assets/{chunk-L5GCOVLC-CE2w8Nm_.js → chunk-ZS6VBONO-DBjJO0w9.js} +2 -2
- package/web/assets/{chunk-NV3KIAZN-5yvcpMiu.js → chunk-ZUNWM646-DNRJyNPe.js} +1 -1
- package/web/assets/classDiagram-FGAMPOII-C5Ibyode.js +1 -0
- package/web/assets/classDiagram-v2-AI5RJEK4-C5Ibyode.js +1 -0
- package/web/assets/{cose-bilkent-RZA4XIPR-BHpK4Crp.js → cose-bilkent-Q72C2OJ3-DMeFXnK8.js} +1 -1
- package/web/assets/cynefin-OW5HDTMX-6OCTWOGG-vlqakYcO.js +1 -0
- package/web/assets/{cynefinDiagram-TR7LZUCG-C3Iar9lZ.js → cynefinDiagram-2OOWUY4M-BY6DZkTt.js} +1 -1
- package/web/assets/dagre-MPVFI544-DWO70fy_.js +4 -0
- package/web/assets/diagram-AE4NWXFW-f7JRVRUL.js +24 -0
- package/web/assets/{diagram-L7DVE3PN-GIRyVUtt.js → diagram-BUJID5UG-BXZv1rCS.js} +2 -2
- package/web/assets/{diagram-JCD7PQ7C-DC5-9FRr.js → diagram-C44CZ5NI-CRNfvjCq.js} +1 -1
- package/web/assets/diagram-EYOLEXXS-DZOjKQVE.js +30 -0
- package/web/assets/diagram-P7B6PWOJ-D3SQmw3_.js +3 -0
- package/web/assets/{ebnfDiagram-DRHRQJWO-D8_CI4ZF.js → ebnfDiagram-FTPZ3PV6-jKWpIDN2.js} +1 -1
- package/web/assets/erDiagram-H3ERR26V-BqJntEuJ.js +99 -0
- package/web/assets/eventmodeling-NTZA5JFV-WKSWQHFS-Bq4FqtBL.js +1 -0
- package/web/assets/flowDiagram-YHGXBVSY-Dnlk2bEu.js +1 -0
- package/web/assets/ganttDiagram-RWFTB7ED-Bl6Y1K5T.js +292 -0
- package/web/assets/gitGraph-4MIJSDKK-JH2HKYUO-B3yc4GkH.js +1 -0
- package/web/assets/gitGraphDiagram-MAR6GKOP-CkNvsrdw.js +106 -0
- package/web/assets/{index-CJDpyH-n.css → index-C2_aej58.css} +1 -1
- package/web/assets/{index-DDRie6_8.js → index-Dj3vQOHK.js} +51 -51
- package/web/assets/info-A6RAGUB7-3TX3OFWW-BM3N5_Dv.js +1 -0
- package/web/assets/infoDiagram-LV547AFH-COkFutAf.js +2 -0
- package/web/assets/{ishikawaDiagram-4JDSWWDM-DmqWtjkl.js → ishikawaDiagram-PUJQGNDS-Bb8FylSR.js} +2 -2
- package/web/assets/{journeyDiagram-QUS3FAKT-XAzVzrQW.js → journeyDiagram-EW5QJT4W-BzoHUBhM.js} +4 -4
- package/web/assets/{kanban-definition-D4L7SQKK-YurRnmYn.js → kanban-definition-JSQERAZB-Uy2Pi0yQ.js} +4 -4
- package/web/assets/katex-CZ4GXH2S-C0Fcou7U.js +257 -0
- package/web/assets/{mindmap-definition-66QP5TD6-ChrWWnil.js → mindmap-definition-VBJCLQLM-B-CnOnt_.js} +3 -3
- package/web/assets/packet-AYTQ26CC-MKII6P3Y-Bd52ZE3V.js +1 -0
- package/web/assets/{pegDiagram-YKIO5C6U-QGeQLEq2.js → pegDiagram-7WILOQTJ-D9sneKXg.js} +1 -1
- package/web/assets/pie-WAS4IAKB-6B4OPMJ5-DW5Xy69Z.js +1 -0
- package/web/assets/pieDiagram-EFA7CBSB-Dx2NQofL.js +39 -0
- package/web/assets/{quadrantDiagram-VO5QLCXA-B7098wSc.js → quadrantDiagram-WARVYA7P-DPKL9_0A.js} +3 -3
- package/web/assets/radar-RG4KPBEZ-UPTR3XUL-CkzibT2h.js +1 -0
- package/web/assets/railroad-74A4TZTK-MEFUPFMS-D9zF-mDN.js +1 -0
- package/web/assets/railroad-abnf-HS5TGJTU-R5YG2S5D-ruacjUbX.js +1 -0
- package/web/assets/railroad-ebnf-LZEXJU2U-G5QEX2L6-S1zc5OiO.js +1 -0
- package/web/assets/railroad-peg-WCYAUIDC-H5I2ZRY2-Cbcr0XzY.js +1 -0
- package/web/assets/{railroadDiagram-M77LTMSB-AXu4vxk_.js → railroadDiagram-5NIQVNLQ-DsweTo14.js} +1 -1
- package/web/assets/{requirementDiagram-RASO5HTO-B-l8InpK.js → requirementDiagram-SXREGOKZ-CXwdNSVR.js} +4 -4
- package/web/assets/{sankeyDiagram-F32LOJ6L-Kd7zjJgX.js → sankeyDiagram-VV74M2VP-CA6jtP9P.js} +3 -3
- package/web/assets/{sequenceDiagram-URATNSBD-BlcdY9DS.js → sequenceDiagram-52ZFIFDL-k_5rEbzm.js} +15 -15
- package/web/assets/src-Df5C1Nz4.js +1 -0
- package/web/assets/stateDiagram-3QAKPIVI-BejHTf31.js +1 -0
- package/web/assets/stateDiagram-v2-HN2P4RDZ-BrfoRuOc.js +1 -0
- package/web/assets/swimlanes-QLVP42QD-CQSVO5D6.js +1 -0
- package/web/assets/swimlanesDiagram-JKPDBFCN-DrWB9kcD.js +8 -0
- package/web/assets/{timeline-definition-WJXWRH4I-DUfp1R3E.js → timeline-definition-GS45XAXW-C0Ks8rPP.js} +4 -4
- package/web/assets/treeView-Q6P3EWNA-ZRJGANNQ-DmKOCo6L.js +1 -0
- package/web/assets/treemap-WGGIJYW6-K64VN5AS-DO3xY92U.js +1 -0
- package/web/assets/{vennDiagram-K3VCMQLI-Bj-FN-XS.js → vennDiagram-QIQU2ZRJ-rgPiS837.js} +3 -3
- package/web/assets/wardley-WFR3VGLG-D67OWCCH-DiDPBNft.js +1 -0
- package/web/assets/wardleyDiagram-U6YNM66N-DRVr7SPi.js +78 -0
- package/web/assets/{xychartDiagram-5VRUVLCW-CK_rbSWE.js → xychartDiagram-XJAZEDNM-COtlZzYb.js} +3 -3
- package/web/index.html +19 -17
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +0 -24
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +0 -1
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +0 -36
- package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +0 -132
- package/web/assets/c4Diagram-X2LASM7V-CnhoT4aV.js +0 -10
- package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +0 -127
- package/web/assets/chunk-5VCL7Z4A-CQ-2dYWj.js +0 -1
- package/web/assets/chunk-6BELYETK-ChsYtfHW.js +0 -1
- package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +0 -2
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +0 -32
- package/web/assets/chunk-KRXBNO2N-C-UNuKKf.js +0 -1
- package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +0 -321
- package/web/assets/chunk-LIEV3EAG-pyKGssV3.js +0 -1
- package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +0 -62
- package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +0 -10
- package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +0 -156
- package/web/assets/chunk-SZD42YQK-ijyKKVr1.js +0 -70
- package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +0 -231
- package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +0 -2
- package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +0 -1
- package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +0 -1
- package/web/assets/chunk-WJBAP47W-BckNkuEN.js +0 -1
- package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +0 -1
- package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +0 -1
- package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +0 -1
- package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +0 -4
- package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +0 -30
- package/web/assets/diagram-KFBZAVDW-Dfmf_4ti.js +0 -3
- package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +0 -24
- package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +0 -85
- package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +0 -1
- package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +0 -1
- package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +0 -292
- package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +0 -1
- package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +0 -106
- package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +0 -1
- package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +0 -2
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +0 -257
- package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +0 -1
- package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +0 -1
- package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +0 -39
- package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +0 -1
- package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +0 -1
- package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +0 -1
- package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +0 -1
- package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +0 -1
- package/web/assets/src-C5sx_gMp.js +0 -1
- package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +0 -1
- package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +0 -1
- package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +0 -2
- package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +0 -8
- package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +0 -1
- package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +0 -1
- package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +0 -1
- package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +0 -78
- /package/web/assets/{sizeCapture-5GORAGP4-BEqQzsxs.js → sizeCapture-FGA5AGYP-BEqQzsxs.js} +0 -0
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
3
4
|
import { shouldIgnorePath, loadIgnoreRules } from '../../../config/ignore-service.js';
|
|
4
5
|
import { logger } from '../../logger.js';
|
|
6
|
+
// POMs are static metadata. Parse hierarchy with a real XML parser, but do not
|
|
7
|
+
// invoke Maven or resolve the effective model. Properties, profiles, and remote
|
|
8
|
+
// parent resolution remain outside this extractor's deterministic boundary.
|
|
9
|
+
const pomParser = new XMLParser({
|
|
10
|
+
ignoreAttributes: true,
|
|
11
|
+
removeNSPrefix: true,
|
|
12
|
+
trimValues: true,
|
|
13
|
+
parseTagValue: false,
|
|
14
|
+
processEntities: false,
|
|
15
|
+
ignoreDeclaration: true,
|
|
16
|
+
ignorePiTags: true,
|
|
17
|
+
});
|
|
5
18
|
async function parseJavaManifest(repoPath) {
|
|
6
19
|
const pomPath = path.join(repoPath, 'pom.xml');
|
|
7
20
|
try {
|
|
@@ -9,13 +22,14 @@ async function parseJavaManifest(repoPath) {
|
|
|
9
22
|
return parsePom(content);
|
|
10
23
|
}
|
|
11
24
|
catch {
|
|
12
|
-
// fall through to Gradle
|
|
25
|
+
// Missing pom.xml — fall through to Gradle.
|
|
13
26
|
}
|
|
27
|
+
const gradleSidecars = await readGradleSidecars(repoPath);
|
|
14
28
|
for (const name of ['build.gradle.kts', 'build.gradle']) {
|
|
15
29
|
const gradlePath = path.join(repoPath, name);
|
|
16
30
|
try {
|
|
17
31
|
const content = await fs.readFile(gradlePath, 'utf-8');
|
|
18
|
-
return parseGradle(content, repoPath);
|
|
32
|
+
return parseGradle(content, repoPath, gradleSidecars);
|
|
19
33
|
}
|
|
20
34
|
catch {
|
|
21
35
|
continue;
|
|
@@ -23,45 +37,244 @@ async function parseJavaManifest(repoPath) {
|
|
|
23
37
|
}
|
|
24
38
|
return null;
|
|
25
39
|
}
|
|
40
|
+
async function readIfPresent(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
return await fs.readFile(filePath, 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function readGradleSidecars(repoPath) {
|
|
49
|
+
const [properties, settingsKts, settingsGroovy, catalog] = await Promise.all([
|
|
50
|
+
readIfPresent(path.join(repoPath, 'gradle.properties')),
|
|
51
|
+
readIfPresent(path.join(repoPath, 'settings.gradle.kts')),
|
|
52
|
+
readIfPresent(path.join(repoPath, 'settings.gradle')),
|
|
53
|
+
readIfPresent(path.join(repoPath, 'gradle', 'libs.versions.toml')),
|
|
54
|
+
]);
|
|
55
|
+
const sidecars = {
|
|
56
|
+
catalogLibraries: new Map(),
|
|
57
|
+
catalogBundles: new Map(),
|
|
58
|
+
};
|
|
59
|
+
const groupMatch = properties?.match(/(?:^|\n)\s*group\s*=\s*([^\s#]+)/);
|
|
60
|
+
if (groupMatch)
|
|
61
|
+
sidecars.propertiesGroup = groupMatch[1];
|
|
62
|
+
const settings = settingsKts ?? settingsGroovy;
|
|
63
|
+
const nameMatch = settings?.match(/rootProject\.name\s*=\s*['"]([^'"]+)['"]/);
|
|
64
|
+
if (nameMatch)
|
|
65
|
+
sidecars.rootProjectName = nameMatch[1];
|
|
66
|
+
if (catalog) {
|
|
67
|
+
const parsed = parseGradleVersionCatalog(catalog);
|
|
68
|
+
sidecars.catalogLibraries = parsed.libraries;
|
|
69
|
+
sidecars.catalogBundles = parsed.bundles;
|
|
70
|
+
}
|
|
71
|
+
return sidecars;
|
|
72
|
+
}
|
|
73
|
+
function catalogAccessors(alias) {
|
|
74
|
+
const dotted = alias.replace(/[-_]/g, '.');
|
|
75
|
+
const camel = alias.replace(/[-_]+([A-Za-z0-9])/g, (_, char) => char.toUpperCase());
|
|
76
|
+
return [...new Set([alias, dotted, camel])];
|
|
77
|
+
}
|
|
78
|
+
function projectAccessorToArtifactId(accessor) {
|
|
79
|
+
const last = accessor.split('.').pop();
|
|
80
|
+
return last.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`).replace(/^-/, '');
|
|
81
|
+
}
|
|
82
|
+
function moduleToGa(module) {
|
|
83
|
+
const parts = module.split(':');
|
|
84
|
+
return parts.length >= 2 ? `${parts[0]}:${parts[1]}` : undefined;
|
|
85
|
+
}
|
|
86
|
+
function parseInlineTomlTable(rhs) {
|
|
87
|
+
const fields = {};
|
|
88
|
+
for (const match of rhs.matchAll(/([A-Za-z0-9_-]+)\s*=\s*['"]([^'"]+)['"]/g)) {
|
|
89
|
+
fields[match[1]] = match[2];
|
|
90
|
+
}
|
|
91
|
+
return fields;
|
|
92
|
+
}
|
|
93
|
+
/** Default Gradle catalog (`gradle/libs.versions.toml`) — aliases only, no version resolution. */
|
|
94
|
+
function parseGradleVersionCatalog(toml) {
|
|
95
|
+
const libraries = new Map();
|
|
96
|
+
const bundles = new Map();
|
|
97
|
+
let section = 'other';
|
|
98
|
+
const addLibrary = (alias, ga) => {
|
|
99
|
+
for (const accessor of catalogAccessors(alias))
|
|
100
|
+
libraries.set(accessor, ga);
|
|
101
|
+
};
|
|
102
|
+
for (const raw of toml.split(/\r?\n/)) {
|
|
103
|
+
const line = raw.replace(/#.*$/, '').trim();
|
|
104
|
+
if (!line)
|
|
105
|
+
continue;
|
|
106
|
+
const header = line.match(/^\[([^\]]+)\]$/);
|
|
107
|
+
if (header) {
|
|
108
|
+
const name = header[1];
|
|
109
|
+
section =
|
|
110
|
+
name === 'libraries' || name.endsWith('.libraries')
|
|
111
|
+
? 'libraries'
|
|
112
|
+
: name === 'bundles' || name.endsWith('.bundles')
|
|
113
|
+
? 'bundles'
|
|
114
|
+
: 'other';
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (section === 'libraries') {
|
|
118
|
+
const dottedModule = line.match(/^([A-Za-z0-9._-]+)\.module\s*=\s*['"]([^'"]+)['"]$/);
|
|
119
|
+
if (dottedModule) {
|
|
120
|
+
const ga = moduleToGa(dottedModule[2]);
|
|
121
|
+
if (ga)
|
|
122
|
+
addLibrary(dottedModule[1], ga);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const assignment = line.match(/^([A-Za-z0-9._-]+)\s*=\s*(.+)$/);
|
|
126
|
+
if (!assignment)
|
|
127
|
+
continue;
|
|
128
|
+
const alias = assignment[1];
|
|
129
|
+
const rhs = assignment[2].trim();
|
|
130
|
+
const quoted = rhs.match(/^['"]([^'"]+)['"]$/);
|
|
131
|
+
if (quoted) {
|
|
132
|
+
const ga = moduleToGa(quoted[1]);
|
|
133
|
+
if (ga)
|
|
134
|
+
addLibrary(alias, ga);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const table = parseInlineTomlTable(rhs);
|
|
138
|
+
const ga = table.module
|
|
139
|
+
? moduleToGa(table.module)
|
|
140
|
+
: table.group && table.name
|
|
141
|
+
? `${table.group}:${table.name}`
|
|
142
|
+
: undefined;
|
|
143
|
+
if (ga)
|
|
144
|
+
addLibrary(alias, ga);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (section === 'bundles') {
|
|
148
|
+
const assignment = line.match(/^([A-Za-z0-9._-]+)\s*=\s*\[([^\]]*)\]$/);
|
|
149
|
+
if (!assignment)
|
|
150
|
+
continue;
|
|
151
|
+
const members = [...assignment[2].matchAll(/['"]([^'"]+)['"]/g)].map((match) => match[1]);
|
|
152
|
+
for (const accessor of catalogAccessors(assignment[1]))
|
|
153
|
+
bundles.set(accessor, members);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { libraries, bundles };
|
|
157
|
+
}
|
|
158
|
+
const GRADLE_GROUP_PATTERNS = [
|
|
159
|
+
/(?:^|[\n{;])\s*(?:rootProject\.)?group\s*=\s*['"]([^'"]+)['"]/,
|
|
160
|
+
/(?:^|[\n{;])\s*group\s+['"]([^'"]+)['"]/,
|
|
161
|
+
];
|
|
162
|
+
const GRADLE_COORD_CONFIGS = 'implementation|api|compileOnly|runtimeOnly|testImplementation|testApi|testCompileOnly|compile|kapt|ksp|commonMainImplementation|commonMainApi';
|
|
163
|
+
const CATALOG_ALIAS = '([A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)*)(?:\\.get\\(\\)|\\.asProvider\\(\\))?';
|
|
164
|
+
function gradleDepRe(suffix) {
|
|
165
|
+
return new RegExp(`(?:${GRADLE_COORD_CONFIGS})\\s*${suffix}`, 'g');
|
|
166
|
+
}
|
|
167
|
+
function parseGradleGroup(content) {
|
|
168
|
+
for (const pattern of GRADLE_GROUP_PATTERNS) {
|
|
169
|
+
const match = content.match(pattern);
|
|
170
|
+
if (match?.[1])
|
|
171
|
+
return match[1];
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
function asXmlNode(value) {
|
|
176
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
177
|
+
? value
|
|
178
|
+
: undefined;
|
|
179
|
+
}
|
|
180
|
+
function xmlText(value) {
|
|
181
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
182
|
+
const text = String(value).trim();
|
|
183
|
+
return text || undefined;
|
|
184
|
+
}
|
|
185
|
+
const nested = asXmlNode(value)?.['#text'];
|
|
186
|
+
if (nested === undefined)
|
|
187
|
+
return undefined;
|
|
188
|
+
return xmlText(nested);
|
|
189
|
+
}
|
|
190
|
+
function xmlChildText(node, name) {
|
|
191
|
+
return node ? xmlText(node[name]) : undefined;
|
|
192
|
+
}
|
|
193
|
+
function asList(value) {
|
|
194
|
+
if (value === undefined || value === null)
|
|
195
|
+
return [];
|
|
196
|
+
return Array.isArray(value) ? value : [value];
|
|
197
|
+
}
|
|
198
|
+
/** Direct project dependencies only — not BOM, profiles, or plugin classpath. */
|
|
199
|
+
function collectProjectDependencies(project, deps) {
|
|
200
|
+
const dependencies = asXmlNode(project.dependencies);
|
|
201
|
+
if (!dependencies)
|
|
202
|
+
return;
|
|
203
|
+
for (const dep of asList(dependencies.dependency)) {
|
|
204
|
+
const depNode = asXmlNode(dep);
|
|
205
|
+
const groupId = xmlChildText(depNode, 'groupId');
|
|
206
|
+
const artifactId = xmlChildText(depNode, 'artifactId');
|
|
207
|
+
if (groupId && artifactId)
|
|
208
|
+
deps.push(`${groupId}:${artifactId}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
26
211
|
function parsePom(content) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
212
|
+
let parsed;
|
|
213
|
+
try {
|
|
214
|
+
// parseSourceSafe guards tree-sitter's Windows SIGSEGV by switching to a
|
|
215
|
+
// chunked input callback above 16 KB; XMLParser only accepts XML text, so
|
|
216
|
+
// routing POMs through it silently yields an empty document.
|
|
217
|
+
// eslint-disable-next-line gitnexus/require-safe-parse
|
|
218
|
+
parsed = pomParser.parse(content);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
30
221
|
return null;
|
|
31
|
-
const groupId = projectGroupMatch[1].trim();
|
|
32
|
-
const artifactId = projectArtifactMatch[1].trim();
|
|
33
|
-
const deps = [];
|
|
34
|
-
const depBlocks = content.matchAll(/<dependency>\s*([\s\S]*?)<\/dependency>/g);
|
|
35
|
-
for (const block of depBlocks) {
|
|
36
|
-
const gMatch = block[1].match(/<groupId>([^<]+)<\/groupId>/);
|
|
37
|
-
const aMatch = block[1].match(/<artifactId>([^<]+)<\/artifactId>/);
|
|
38
|
-
if (gMatch && aMatch) {
|
|
39
|
-
deps.push(`${gMatch[1].trim()}:${aMatch[1].trim()}`);
|
|
40
|
-
}
|
|
41
222
|
}
|
|
223
|
+
const project = asXmlNode(asXmlNode(parsed)?.project);
|
|
224
|
+
if (!project)
|
|
225
|
+
return null;
|
|
226
|
+
// Maven inherits groupId from <parent>, but artifactId is always the
|
|
227
|
+
// project's own direct child and must never fall back to parent.artifactId.
|
|
228
|
+
const groupId = xmlChildText(project, 'groupId') ?? xmlChildText(asXmlNode(project.parent), 'groupId');
|
|
229
|
+
const artifactId = xmlChildText(project, 'artifactId');
|
|
230
|
+
if (!groupId || !artifactId)
|
|
231
|
+
return null;
|
|
232
|
+
const deps = [];
|
|
233
|
+
collectProjectDependencies(project, deps);
|
|
42
234
|
return { groupId, artifactId, deps: [...new Set(deps)] };
|
|
43
235
|
}
|
|
44
|
-
function parseGradle(content, repoPath) {
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const groupId = groupMatch ? groupMatch[1] : '';
|
|
236
|
+
function parseGradle(content, repoPath, sidecars = { catalogLibraries: new Map(), catalogBundles: new Map() }) {
|
|
237
|
+
// Static text + default catalog file. Do not execute Gradle.
|
|
238
|
+
const groupId = parseGradleGroup(content) ?? sidecars.propertiesGroup ?? '';
|
|
48
239
|
if (!groupId)
|
|
49
240
|
return null;
|
|
50
|
-
const artifactId =
|
|
241
|
+
const artifactId = sidecars.rootProjectName ?? path.basename(repoPath);
|
|
242
|
+
const { catalogLibraries, catalogBundles } = sidecars;
|
|
51
243
|
const deps = [];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
244
|
+
const pushCatalogAlias = (alias) => {
|
|
245
|
+
const ga = catalogLibraries.get(alias);
|
|
246
|
+
if (ga)
|
|
247
|
+
deps.push(ga);
|
|
248
|
+
};
|
|
249
|
+
const namedPattern = gradleDepRe(`(?:\\(\\s*)?(?:group\\s*=\\s*['"](?<group1>[^'"]+)['"]\\s*,\\s*name\\s*=\\s*['"](?<name1>[^'"]+)['"]|name\\s*=\\s*['"](?<name2>[^'"]+)['"]\\s*,\\s*group\\s*=\\s*['"](?<group2>[^'"]+)['"]|group:\\s*['"](?<group3>[^'"]+)['"]\\s*,\\s*name:\\s*['"](?<name3>[^'"]+)['"]|name:\\s*['"](?<name4>[^'"]+)['"]\\s*,\\s*group:\\s*['"](?<group4>[^'"]+)['"])`);
|
|
250
|
+
for (const match of content.matchAll(namedPattern)) {
|
|
251
|
+
const group = match.groups?.group1 ?? match.groups?.group2 ?? match.groups?.group3 ?? match.groups?.group4;
|
|
252
|
+
const name = match.groups?.name1 ?? match.groups?.name2 ?? match.groups?.name3 ?? match.groups?.name4;
|
|
253
|
+
if (group && name)
|
|
254
|
+
deps.push(`${group}:${name}`);
|
|
255
|
+
}
|
|
256
|
+
for (const match of content.matchAll(gradleDepRe(`(?:\\(\\s*)?libs(?:\\.libraries)?\\.(?!bundles\\.|plugins\\.)${CATALOG_ALIAS}`))) {
|
|
257
|
+
pushCatalogAlias(match[1]);
|
|
258
|
+
}
|
|
259
|
+
for (const match of content.matchAll(gradleDepRe(`(?:\\(\\s*)?libs\\.bundles\\.${CATALOG_ALIAS}`))) {
|
|
260
|
+
for (const member of catalogBundles.get(match[1]) ?? []) {
|
|
261
|
+
for (const accessor of catalogAccessors(member))
|
|
262
|
+
pushCatalogAlias(accessor);
|
|
58
263
|
}
|
|
59
264
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
265
|
+
for (const match of content.matchAll(gradleDepRe(`\\(\\s*projects\\.([A-Za-z][A-Za-z0-9.]*)`))) {
|
|
266
|
+
deps.push(`${groupId}:${projectAccessorToArtifactId(match[1])}`);
|
|
267
|
+
}
|
|
268
|
+
for (const match of content.matchAll(gradleDepRe(`(?:\\(\\s*['"]([^'"]+)['"]\\s*\\)|['"]([^'"]+)['"])`))) {
|
|
269
|
+
const coord = match[1] ?? match[2];
|
|
270
|
+
if (!coord)
|
|
271
|
+
continue;
|
|
272
|
+
const parts = coord.split(':');
|
|
273
|
+
if (parts.length >= 2)
|
|
274
|
+
deps.push(`${parts[0]}:${parts[1]}`);
|
|
275
|
+
}
|
|
276
|
+
for (const match of content.matchAll(gradleDepRe(`(?:\\(\\s*)?project\\s*\\(\\s*['"]([^'"]+)['"]\\s*\\)`))) {
|
|
277
|
+
deps.push(`${groupId}:${match[1].replace(/^:/, '')}`);
|
|
65
278
|
}
|
|
66
279
|
return { groupId, artifactId, deps: [...new Set(deps)] };
|
|
67
280
|
}
|
|
@@ -21,12 +21,11 @@
|
|
|
21
21
|
* else claims: group directories live under `~/.gitnexus/groups/<name>` (or
|
|
22
22
|
* `$GITNEXUS_HOME`), never under a repo's `.gitnexus[/branches/<slug>]`.
|
|
23
23
|
*
|
|
24
|
-
* WHY IT FAILS CLOSED,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* initiated, and its lost update destroys contracts rather than a registry field.
|
|
24
|
+
* WHY IT FAILS CLOSED, like the registry lock. `withRegistryLock` also
|
|
25
|
+
* refuses to continue unlocked on timeout: a lost registry update can drop a
|
|
26
|
+
* concurrent registration. A group sync still fails closed for additional
|
|
27
|
+
* reasons — it is long, expensive, operator-initiated, and a lost update
|
|
28
|
+
* destroys contracts rather than a registry field.
|
|
30
29
|
* A sync that cannot be protected must not run at all, and there are three
|
|
31
30
|
* distinct ways it can fail to be protected; all three throw
|
|
32
31
|
* {@link GroupSyncLockError}:
|
|
@@ -1,3 +1,40 @@
|
|
|
1
|
-
import type { CrossLink, StoredContract } from './types.js';
|
|
1
|
+
import type { CrossLink, CrossLinkEndpoint, StoredContract } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* True when a link endpoint carries no resolved graph symbol — empty
|
|
4
|
+
* `symbolUid` or a missing/empty `symbolRef`.
|
|
5
|
+
*
|
|
6
|
+
* Sync marks a cross-link `degraded: true` when this holds for the PROVIDER
|
|
7
|
+
* endpoint (`to`): the contract boundary is proven, but the empty uid can
|
|
8
|
+
* never match a Phase-1 impact symbol id, so cross-repo fan-out across the
|
|
9
|
+
* link silently yields nothing (the classic case is a provider whose handler
|
|
10
|
+
* failed to resolve, leaving `symbolName` degraded to the file name with one
|
|
11
|
+
* pseudo-symbol carrying every route in that file). Consumer-side (`from`)
|
|
12
|
+
* emptiness is deliberately NOT degraded — several extractors (topics, grpc)
|
|
13
|
+
* legitimately emit consumer contracts without a per-call symbol, and the
|
|
14
|
+
* anchor that matters for far-side fan-out is the provider's.
|
|
15
|
+
*
|
|
16
|
+
* Kept next to the endpoint merge logic because `dedupeCrossLinks` must
|
|
17
|
+
* re-derive the flag after a merge: `mergeEndpoints` backfills `symbolUid`
|
|
18
|
+
* from the losing twin, which can invalidate a flag carried in from the winner.
|
|
19
|
+
*
|
|
20
|
+
* NOT unresolved: a deterministic `manifest::<repo>::<contractId>` synthetic
|
|
21
|
+
* uid (see `manifestSymbolUid`). Manifest endpoints fall back to it precisely
|
|
22
|
+
* when the graph has no symbol for them — its empty `symbolRef.filePath` would
|
|
23
|
+
* otherwise trip the check below — yet cross-impact anchors those links by
|
|
24
|
+
* design (#2722: the crossing is preserved with `fanout_status:
|
|
25
|
+
* 'not_attempted'` instead of silently yielding cross=0). The prefix is the
|
|
26
|
+
* canonical discriminator — real indexer uids never start with `manifest::`
|
|
27
|
+
* — and `cross-impact.ts` branches on the same test. Encoding the exemption
|
|
28
|
+
* HERE (not at the sync marking call site) keeps marking and the post-merge
|
|
29
|
+
* re-derivation from drifting apart, and keeps the flag's meaning exactly what
|
|
30
|
+
* `types.ts` documents: "distinct from manifest::… synthetic UIDs".
|
|
31
|
+
*/
|
|
32
|
+
export declare function isUnresolvedEndpoint(endpoint: CrossLinkEndpoint): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Derive `degraded` from the provider endpoint. Present (`true`) only when
|
|
35
|
+
* unresolved; deleted otherwise so contracts.json stays "carried only when
|
|
36
|
+
* meaningful" (`'degraded' in link === false` for anchored links).
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyDegradedFlag(link: CrossLink): CrossLink;
|
|
2
39
|
export declare function dedupeContracts(items: StoredContract[]): StoredContract[];
|
|
3
40
|
export declare function dedupeCrossLinks(items: CrossLink[]): CrossLink[];
|
|
@@ -83,6 +83,59 @@ function crossLinkKey(link) {
|
|
|
83
83
|
endpointKey(link.to),
|
|
84
84
|
].join('\0');
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* True when a link endpoint carries no resolved graph symbol — empty
|
|
88
|
+
* `symbolUid` or a missing/empty `symbolRef`.
|
|
89
|
+
*
|
|
90
|
+
* Sync marks a cross-link `degraded: true` when this holds for the PROVIDER
|
|
91
|
+
* endpoint (`to`): the contract boundary is proven, but the empty uid can
|
|
92
|
+
* never match a Phase-1 impact symbol id, so cross-repo fan-out across the
|
|
93
|
+
* link silently yields nothing (the classic case is a provider whose handler
|
|
94
|
+
* failed to resolve, leaving `symbolName` degraded to the file name with one
|
|
95
|
+
* pseudo-symbol carrying every route in that file). Consumer-side (`from`)
|
|
96
|
+
* emptiness is deliberately NOT degraded — several extractors (topics, grpc)
|
|
97
|
+
* legitimately emit consumer contracts without a per-call symbol, and the
|
|
98
|
+
* anchor that matters for far-side fan-out is the provider's.
|
|
99
|
+
*
|
|
100
|
+
* Kept next to the endpoint merge logic because `dedupeCrossLinks` must
|
|
101
|
+
* re-derive the flag after a merge: `mergeEndpoints` backfills `symbolUid`
|
|
102
|
+
* from the losing twin, which can invalidate a flag carried in from the winner.
|
|
103
|
+
*
|
|
104
|
+
* NOT unresolved: a deterministic `manifest::<repo>::<contractId>` synthetic
|
|
105
|
+
* uid (see `manifestSymbolUid`). Manifest endpoints fall back to it precisely
|
|
106
|
+
* when the graph has no symbol for them — its empty `symbolRef.filePath` would
|
|
107
|
+
* otherwise trip the check below — yet cross-impact anchors those links by
|
|
108
|
+
* design (#2722: the crossing is preserved with `fanout_status:
|
|
109
|
+
* 'not_attempted'` instead of silently yielding cross=0). The prefix is the
|
|
110
|
+
* canonical discriminator — real indexer uids never start with `manifest::`
|
|
111
|
+
* — and `cross-impact.ts` branches on the same test. Encoding the exemption
|
|
112
|
+
* HERE (not at the sync marking call site) keeps marking and the post-merge
|
|
113
|
+
* re-derivation from drifting apart, and keeps the flag's meaning exactly what
|
|
114
|
+
* `types.ts` documents: "distinct from manifest::… synthetic UIDs".
|
|
115
|
+
*/
|
|
116
|
+
export function isUnresolvedEndpoint(endpoint) {
|
|
117
|
+
if (endpoint.symbolUid.startsWith('manifest::'))
|
|
118
|
+
return false;
|
|
119
|
+
return (!endpoint.symbolUid ||
|
|
120
|
+
!endpoint.symbolRef ||
|
|
121
|
+
!endpoint.symbolRef.filePath ||
|
|
122
|
+
!endpoint.symbolRef.name);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Derive `degraded` from the provider endpoint. Present (`true`) only when
|
|
126
|
+
* unresolved; deleted otherwise so contracts.json stays "carried only when
|
|
127
|
+
* meaningful" (`'degraded' in link === false` for anchored links).
|
|
128
|
+
*/
|
|
129
|
+
export function applyDegradedFlag(link) {
|
|
130
|
+
const next = { ...link };
|
|
131
|
+
if (isUnresolvedEndpoint(next.to)) {
|
|
132
|
+
next.degraded = true;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
delete next.degraded;
|
|
136
|
+
}
|
|
137
|
+
return next;
|
|
138
|
+
}
|
|
86
139
|
export function dedupeContracts(items) {
|
|
87
140
|
const deduped = new Map();
|
|
88
141
|
for (const contract of items) {
|
|
@@ -104,12 +157,15 @@ export function dedupeCrossLinks(items) {
|
|
|
104
157
|
const keepIncoming = link.confidence > existing.confidence;
|
|
105
158
|
const primary = keepIncoming ? link : existing;
|
|
106
159
|
const secondary = keepIncoming ? existing : link;
|
|
107
|
-
|
|
160
|
+
const merged = {
|
|
108
161
|
...primary,
|
|
109
162
|
confidence: Math.max(existing.confidence, link.confidence),
|
|
110
163
|
from: mergeEndpoints(primary.from, secondary.from),
|
|
111
164
|
to: mergeEndpoints(primary.to, secondary.to),
|
|
112
|
-
}
|
|
165
|
+
};
|
|
166
|
+
// Re-derive after mergeEndpoints: a richer twin can backfill `to.symbolUid`
|
|
167
|
+
// and must not leave a stale `degraded` flag on an now-anchored link.
|
|
168
|
+
deduped.set(key, applyDegradedFlag(merged));
|
|
113
169
|
}
|
|
114
|
-
return [...deduped.values()];
|
|
170
|
+
return [...deduped.values()].map(applyDegradedFlag);
|
|
115
171
|
}
|
|
@@ -15,6 +15,17 @@ export interface GroupToolPort {
|
|
|
15
15
|
resolveRepo(repoParam?: string): Promise<GroupRepoHandle>;
|
|
16
16
|
impact(repo: GroupRepoHandle, params: {
|
|
17
17
|
target: string;
|
|
18
|
+
/**
|
|
19
|
+
* Target-selector params, same semantics as the single-repo `impact`
|
|
20
|
+
* tool: `target_uid` is the zero-ambiguity lookup (it wins over the
|
|
21
|
+
* name), `file_path`/`kind` narrow a name shared by several symbols
|
|
22
|
+
* (e.g. same-named Api/Impl/Controller layers). The port implementation
|
|
23
|
+
* consumes them directly; the Phase-1 caller in cross-impact.ts is
|
|
24
|
+
* responsible for threading them from the MCP `impact` args.
|
|
25
|
+
*/
|
|
26
|
+
target_uid?: string;
|
|
27
|
+
file_path?: string;
|
|
28
|
+
kind?: string;
|
|
18
29
|
direction: 'upstream' | 'downstream';
|
|
19
30
|
maxDepth?: number;
|
|
20
31
|
relationTypes?: string[];
|
|
@@ -301,8 +301,9 @@ export class GroupService {
|
|
|
301
301
|
// group tools never need it — so deferring it here keeps that closure off
|
|
302
302
|
// MCP server startup entirely and off every non-sync group call. The CLI
|
|
303
303
|
// already does exactly this at `cli/group.ts`'s sync command.
|
|
304
|
-
const { syncGroup } = await import('./sync.js');
|
|
304
|
+
const { syncGroup, formatGroupSyncAmbiguousError } = await import('./sync.js');
|
|
305
305
|
const { GroupSyncLockError } = await import('./group-lock.js');
|
|
306
|
+
const { RegistryAmbiguousTargetError } = await import('../../storage/repo-manager.js');
|
|
306
307
|
let result;
|
|
307
308
|
try {
|
|
308
309
|
result = await syncGroup(config, {
|
|
@@ -315,6 +316,9 @@ export class GroupService {
|
|
|
315
316
|
});
|
|
316
317
|
}
|
|
317
318
|
catch (err) {
|
|
319
|
+
if (err instanceof RegistryAmbiguousTargetError) {
|
|
320
|
+
return { error: formatGroupSyncAmbiguousError(err) };
|
|
321
|
+
}
|
|
318
322
|
// Fails closed (R9): this sync could not be protected against a concurrent
|
|
319
323
|
// one, so it did not run and wrote nothing. Return it through the same
|
|
320
324
|
// error channel a missing group uses — NEVER as a success payload of zeroes,
|
|
@@ -337,6 +341,14 @@ export class GroupService {
|
|
|
337
341
|
// can otherwise see contract counts that disagree with this payload, with
|
|
338
342
|
// nothing here explaining why the write was skipped.
|
|
339
343
|
registryOutcome: result.registryOutcome,
|
|
344
|
+
// Data-quality signals surfaced from the sync run: links whose provider
|
|
345
|
+
// endpoint never resolved to a graph symbol, per-repo extraction
|
|
346
|
+
// failures with reasons, and operator warnings (e.g. bridge.lbug write
|
|
347
|
+
// failed after contracts.json was written). Always present so MCP
|
|
348
|
+
// consumers can branch on them without existence checks.
|
|
349
|
+
degradedLinks: result.degradedLinks,
|
|
350
|
+
failedRepos: result.failedRepos,
|
|
351
|
+
warnings: result.warnings,
|
|
340
352
|
};
|
|
341
353
|
}
|
|
342
354
|
async groupContracts(params) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as fsp from 'node:fs/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
4
|
import { writeFileAtomic } from '../../storage/fs-atomic.js';
|
|
5
|
+
import { getGlobalDir } from '../../storage/global-dir.js';
|
|
6
6
|
export const CONTRACTS_FILE = 'contracts.json';
|
|
7
7
|
export function getDefaultGitnexusDir() {
|
|
8
|
-
return
|
|
8
|
+
return getGlobalDir();
|
|
9
9
|
}
|
|
10
10
|
export function getGroupsBaseDir(gitnexusDir) {
|
|
11
11
|
return path.join(gitnexusDir || getDefaultGitnexusDir(), 'groups');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type RegistryEntry } from '../../storage/repo-manager.js';
|
|
1
|
+
import { RegistryAmbiguousTargetError, type RegistryEntry } from '../../storage/repo-manager.js';
|
|
2
2
|
import type { GroupConfig, RepoHandle, RepoSnapshot, StoredContract, CrossLink, GroupManifestLink, MatchType } from './types.js';
|
|
3
3
|
export interface SyncOptions {
|
|
4
4
|
extractorOverride?: ((repo: RepoHandle) => Promise<StoredContract[]>) | (() => Promise<StoredContract[]>);
|
|
@@ -47,6 +47,27 @@ export interface SyncResult {
|
|
|
47
47
|
* none of that repo's contracts are in `contracts`.
|
|
48
48
|
*/
|
|
49
49
|
unreadableRepos: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Cross-links whose provider endpoint has no resolved graph symbol
|
|
52
|
+
* (`degraded: true` on the link — see `isUnresolvedEndpoint`). The boundary
|
|
53
|
+
* is proven but cross-impact fan-out cannot anchor it; the usual remedy is
|
|
54
|
+
* re-analyzing the provider repo so its handlers resolve.
|
|
55
|
+
*/
|
|
56
|
+
degradedLinks: number;
|
|
57
|
+
/**
|
|
58
|
+
* Repos whose per-repo extraction threw (init, an extractor, or the
|
|
59
|
+
* snapshot read). Each still lands in `unreadableRepos` (group path) —
|
|
60
|
+
* unchanged downstream semantics — but carries its failure reason here: the
|
|
61
|
+
* catch used to swallow the exception, leaving contracts already pushed by
|
|
62
|
+
* earlier extractors in this iteration as silent half-repo data. `repo` is
|
|
63
|
+
* that same group path (e.g. `app/backend`), not the registry display name.
|
|
64
|
+
*/
|
|
65
|
+
failedRepos: Array<{
|
|
66
|
+
repo: string;
|
|
67
|
+
reason: string;
|
|
68
|
+
}>;
|
|
69
|
+
/** Operator-facing run warnings (e.g. bridge.lbug write failed after contracts.json was written). */
|
|
70
|
+
warnings: string[];
|
|
50
71
|
repoSnapshots: Record<string, RepoSnapshot>;
|
|
51
72
|
/**
|
|
52
73
|
* Matching stages this run was asked to skip. Populated on EVERY outcome,
|
|
@@ -64,6 +85,8 @@ export interface SyncResult {
|
|
|
64
85
|
registryOutcome: RegistryWriteOutcome;
|
|
65
86
|
}
|
|
66
87
|
export declare function stableRepoPoolId(entry: RegistryEntry, allEntries: RegistryEntry[]): string;
|
|
88
|
+
/** Operator copy for group sync — unique `--name`, not a path in yaml. */
|
|
89
|
+
export declare function formatGroupSyncAmbiguousError(err: RegistryAmbiguousTargetError): string;
|
|
67
90
|
/** A batch of manifest links whose referenced in-group repos fit one resident window. */
|
|
68
91
|
export interface ManifestWindow {
|
|
69
92
|
links: GroupManifestLink[];
|