gitnexus 1.6.10-rc.21 → 1.6.10-rc.211
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 +212 -22
- package/dist/_shared/graph/types.d.ts +27 -8
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +4 -3
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +1 -1
- package/dist/_shared/index.js.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 +19 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +23 -10
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/_shared/language-detection.d.ts.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 +3 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +6 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +316 -37
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +124 -1
- 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/lookup-core.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +58 -2
- package/dist/_shared/scope-resolution/registries/lookup-core.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/symbol-definition.d.ts +47 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +297 -5
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +10 -2
- package/dist/cli/ai-context.js +128 -61
- package/dist/cli/analyze-config.d.ts +1 -1
- package/dist/cli/analyze-options.d.ts +131 -0
- package/dist/cli/analyze-options.js +1 -0
- package/dist/cli/analyze.d.ts +25 -114
- package/dist/cli/analyze.js +194 -36
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/detect-changes-format.js +19 -2
- package/dist/cli/doctor.d.ts +23 -0
- package/dist/cli/doctor.js +72 -9
- package/dist/cli/editor-targets.js +6 -0
- package/dist/cli/eval-server.d.ts +23 -1
- package/dist/cli/eval-server.js +128 -9
- package/dist/cli/format-symbol.d.ts +15 -0
- package/dist/cli/format-symbol.js +17 -0
- package/dist/cli/generated-skill.d.ts +17 -0
- package/dist/cli/generated-skill.js +1 -0
- package/dist/cli/group.js +23 -2
- package/dist/cli/help-i18n.js +3 -0
- package/dist/cli/i18n/en.d.ts +17 -8
- package/dist/cli/i18n/en.js +19 -8
- package/dist/cli/i18n/resources.d.ts +26 -8
- package/dist/cli/i18n/zh-CN.d.ts +9 -0
- package/dist/cli/i18n/zh-CN.js +17 -8
- package/dist/cli/index.js +16 -9
- package/dist/cli/lazy-action.d.ts +7 -0
- package/dist/cli/lazy-action.js +27 -0
- package/dist/cli/mcp.js +6 -3
- package/dist/cli/resolve-invocation.d.ts +7 -3
- package/dist/cli/resolve-invocation.js +7 -3
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +30 -7
- package/dist/cli/skill-gen.d.ts +1 -6
- package/dist/cli/skill-gen.js +88 -18
- package/dist/cli/standard-skills.d.ts +76 -0
- package/dist/cli/standard-skills.js +45 -0
- package/dist/cli/status.d.ts +4 -1
- package/dist/cli/status.js +57 -4
- package/dist/cli/tool.d.ts +1 -0
- package/dist/cli/tool.js +75 -7
- package/dist/cli/uninstall.js +7 -2
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +59 -10
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +31 -4
- package/dist/core/analysis-features.d.ts +21 -0
- package/dist/core/analysis-features.js +59 -0
- package/dist/core/analyzer-identity.d.ts +154 -0
- package/dist/core/analyzer-identity.js +2158 -0
- package/dist/core/augmentation/engine.js +95 -76
- package/dist/core/embedding-checkpoint.d.ts +143 -0
- package/dist/core/embedding-checkpoint.js +221 -0
- package/dist/core/embedding-count.d.ts +61 -0
- package/dist/core/embedding-count.js +69 -0
- package/dist/core/embeddings/ast-utils.js +9 -1
- package/dist/core/embeddings/embedder.d.ts +3 -2
- package/dist/core/embeddings/embedder.js +8 -5
- package/dist/core/embeddings/embedding-identity.d.ts +11 -0
- package/dist/core/embeddings/embedding-identity.js +24 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +24 -1
- package/dist/core/embeddings/embedding-pipeline.js +341 -19
- package/dist/core/embeddings/http-client.d.ts +10 -2
- package/dist/core/embeddings/http-client.js +282 -47
- package/dist/core/embeddings/node-module-compat.d.ts +4 -2
- package/dist/core/embeddings/node-module-compat.js +4 -2
- package/dist/core/embeddings/onnxruntime-common-resolver.js +5 -5
- package/dist/core/embeddings/onnxruntime-node-resolver.js +2 -2
- package/dist/core/embeddings/runtime-install.js +1 -1
- package/dist/core/git-staleness.js +1 -1
- package/dist/core/graph/graph.js +3 -0
- package/dist/core/graph/import-cycles.d.ts +194 -3
- package/dist/core/graph/import-cycles.js +522 -73
- package/dist/core/graph/types.d.ts +18 -0
- package/dist/core/group/bridge-db.js +5 -27
- package/dist/core/group/cross-impact.d.ts +21 -0
- package/dist/core/group/cross-impact.js +128 -15
- package/dist/core/group/cross-trace.js +27 -16
- package/dist/core/group/extractors/http-patterns/java.js +91 -14
- package/dist/core/group/extractors/http-patterns/node.js +19 -0
- package/dist/core/group/extractors/http-patterns/types.d.ts +8 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +1 -0
- package/dist/core/group/extractors/http-route-extractor.js +122 -48
- package/dist/core/group/extractors/include-extractor.js +20 -2
- package/dist/core/group/extractors/manifest-extractor.d.ts +1 -1
- package/dist/core/group/extractors/manifest-extractor.js +7 -7
- package/dist/core/group/service.js +10 -1
- package/dist/core/group/storage.js +2 -33
- package/dist/core/group/types.d.ts +18 -0
- package/dist/core/incremental/subgraph-extract.d.ts +9 -6
- package/dist/core/incremental/subgraph-extract.js +33 -10
- package/dist/core/index-freshness.d.ts +80 -0
- package/dist/core/index-freshness.js +120 -0
- package/dist/core/ingestion/call-processor.d.ts +13 -1
- package/dist/core/ingestion/call-processor.js +110 -3
- package/dist/core/ingestion/cfg/callee-cell-format.d.ts +42 -0
- package/dist/core/ingestion/cfg/callee-cell-format.js +42 -0
- package/dist/core/ingestion/cfg/emit.d.ts +8 -23
- package/dist/core/ingestion/cfg/emit.js +9 -23
- package/dist/core/ingestion/class-extractors/configs/go.js +10 -5
- package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
- package/dist/core/ingestion/cluster-enricher.js +8 -4
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
- package/dist/core/ingestion/community-processor.d.ts +21 -3
- package/dist/core/ingestion/community-processor.js +88 -83
- package/dist/core/ingestion/di-extractors/index.d.ts +22 -34
- package/dist/core/ingestion/di-extractors/index.js +17 -18
- package/dist/core/ingestion/di-extractors/spring.d.ts +27 -5
- package/dist/core/ingestion/di-extractors/spring.js +87 -3
- package/dist/core/ingestion/di-extractors/types.d.ts +60 -0
- package/dist/core/ingestion/di-extractors/types.js +15 -0
- package/dist/core/ingestion/emit-references.js +4 -0
- package/dist/core/ingestion/filesystem-walker.js +16 -12
- package/dist/core/ingestion/finalize-orchestrator.js +1 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +9 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +41 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.d.ts +13 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +227 -0
- package/dist/core/ingestion/frameworks/spring/aop-candidates.d.ts +15 -0
- package/dist/core/ingestion/frameworks/spring/aop-candidates.js +85 -0
- package/dist/core/ingestion/frameworks/spring/aop.d.ts +118 -0
- package/dist/core/ingestion/frameworks/spring/aop.js +476 -0
- package/dist/core/ingestion/frameworks/spring/auto-configuration.d.ts +8 -0
- package/dist/core/ingestion/frameworks/spring/auto-configuration.js +16 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.js +27 -0
- package/dist/core/ingestion/frameworks/spring/bean-factories.d.ts +33 -0
- package/dist/core/ingestion/frameworks/spring/bean-factories.js +65 -0
- package/dist/core/ingestion/frameworks/spring/conditionals.d.ts +25 -0
- package/dist/core/ingestion/frameworks/spring/conditionals.js +319 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.d.ts +48 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.js +379 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +28 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.js +152 -0
- package/dist/core/ingestion/frameworks/spring/resource-injection.d.ts +5 -0
- package/dist/core/ingestion/frameworks/spring/resource-injection.js +91 -0
- package/dist/core/ingestion/import-resolvers/configs/csharp.js +5 -1
- package/dist/core/ingestion/import-resolvers/configs/swift.js +13 -0
- package/dist/core/ingestion/import-resolvers/csharp.d.ts +9 -1
- package/dist/core/ingestion/import-resolvers/csharp.js +234 -27
- package/dist/core/ingestion/import-resolvers/go.d.ts +11 -1
- package/dist/core/ingestion/import-resolvers/go.js +44 -17
- package/dist/core/ingestion/import-resolvers/jvm.d.ts +2 -2
- package/dist/core/ingestion/import-resolvers/node-workspace-packages.d.ts +90 -0
- package/dist/core/ingestion/import-resolvers/node-workspace-packages.js +428 -0
- package/dist/core/ingestion/import-resolvers/package-dir-index.d.ts +124 -0
- package/dist/core/ingestion/import-resolvers/package-dir-index.js +223 -0
- package/dist/core/ingestion/import-resolvers/pass-cache.d.ts +50 -0
- package/dist/core/ingestion/import-resolvers/pass-cache.js +60 -0
- package/dist/core/ingestion/import-resolvers/per-file-set.d.ts +71 -0
- package/dist/core/ingestion/import-resolvers/per-file-set.js +11 -0
- package/dist/core/ingestion/import-resolvers/php.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/php.js +27 -8
- package/dist/core/ingestion/import-resolvers/python-file-index.d.ts +201 -0
- package/dist/core/ingestion/import-resolvers/python-file-index.js +302 -0
- package/dist/core/ingestion/import-resolvers/python.js +25 -6
- package/dist/core/ingestion/import-resolvers/ruby.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/rust.d.ts +2 -2
- package/dist/core/ingestion/import-resolvers/standard.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/types.d.ts +1 -12
- package/dist/core/ingestion/import-resolvers/utils.d.ts +65 -6
- package/dist/core/ingestion/import-resolvers/utils.js +215 -36
- package/dist/core/ingestion/import-resolvers/workspace-file-index.d.ts +72 -0
- package/dist/core/ingestion/import-resolvers/workspace-file-index.js +58 -0
- package/dist/core/ingestion/language-config.d.ts +20 -1
- package/dist/core/ingestion/language-config.js +18 -23
- package/dist/core/ingestion/language-provider.d.ts +133 -7
- package/dist/core/ingestion/languages/c/captures.js +63 -0
- package/dist/core/ingestion/languages/c/import-target.js +12 -16
- package/dist/core/ingestion/languages/c/query.js +17 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +26 -19
- package/dist/core/ingestion/languages/c/static-linkage.js +12 -16
- package/dist/core/ingestion/languages/c-cpp.js +13 -0
- package/dist/core/ingestion/languages/cobol/captures.js +93 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +34 -20
- package/dist/core/ingestion/languages/cobol.js +13 -0
- package/dist/core/ingestion/languages/cpp/adl.d.ts +2 -2
- package/dist/core/ingestion/languages/cpp/adl.js +67 -44
- package/dist/core/ingestion/languages/cpp/captures.js +222 -3
- package/dist/core/ingestion/languages/cpp/file-local-linkage.js +11 -15
- package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +28 -8
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +242 -68
- package/dist/core/ingestion/languages/cpp/interpret.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/interpret.js +126 -6
- package/dist/core/ingestion/languages/cpp/query.js +106 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +62 -20
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.d.ts +2 -15
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.js +18 -10
- package/dist/core/ingestion/languages/csharp/captures.js +44 -0
- package/dist/core/ingestion/languages/csharp/import-target.js +46 -72
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +5 -1
- package/dist/core/ingestion/languages/csharp/query.js +25 -5
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +75 -2
- package/dist/core/ingestion/languages/dart/captures.d.ts +10 -0
- package/dist/core/ingestion/languages/dart/captures.js +686 -16
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
- package/dist/core/ingestion/languages/dart/import-target.js +32 -9
- package/dist/core/ingestion/languages/dart/index.d.ts +1 -1
- package/dist/core/ingestion/languages/dart/index.js +1 -1
- package/dist/core/ingestion/languages/dart/query.js +98 -1
- package/dist/core/ingestion/languages/dart/scope-resolver.js +14 -3
- package/dist/core/ingestion/languages/dart/simple-hooks.js +9 -0
- package/dist/core/ingestion/languages/dart.js +8 -1
- package/dist/core/ingestion/languages/go/captures.js +142 -3
- package/dist/core/ingestion/languages/go/generic-type-parameters.d.ts +31 -0
- package/dist/core/ingestion/languages/go/generic-type-parameters.js +140 -0
- package/dist/core/ingestion/languages/go/import-target.d.ts +3 -10
- package/dist/core/ingestion/languages/go/import-target.js +34 -30
- package/dist/core/ingestion/languages/go/index.d.ts +1 -1
- package/dist/core/ingestion/languages/go/interface-impls.d.ts +9 -1
- package/dist/core/ingestion/languages/go/interface-impls.js +693 -87
- package/dist/core/ingestion/languages/go/interpret.d.ts +2 -0
- package/dist/core/ingestion/languages/go/interpret.js +22 -8
- package/dist/core/ingestion/languages/go/method-owners.js +31 -12
- package/dist/core/ingestion/languages/go/package-clause.d.ts +46 -0
- package/dist/core/ingestion/languages/go/package-clause.js +75 -0
- package/dist/core/ingestion/languages/go/package-siblings.js +7 -11
- package/dist/core/ingestion/languages/go/query.js +56 -3
- package/dist/core/ingestion/languages/go/scope-resolver.js +39 -0
- package/dist/core/ingestion/languages/go.js +9 -0
- package/dist/core/ingestion/languages/java/analysis-features.d.ts +7 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +25 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +38 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +124 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
- package/dist/core/ingestion/languages/java/captures.js +321 -49
- package/dist/core/ingestion/languages/java/import-target.d.ts +49 -9
- package/dist/core/ingestion/languages/java/import-target.js +68 -88
- package/dist/core/ingestion/languages/java/interpret.js +3 -2
- package/dist/core/ingestion/languages/java/module-resolution.d.ts +62 -0
- package/dist/core/ingestion/languages/java/module-resolution.js +142 -0
- package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/java/package-facts.js +9 -0
- package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
- package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
- package/dist/core/ingestion/languages/java/query.js +39 -3
- package/dist/core/ingestion/languages/java/record-components.d.ts +14 -0
- package/dist/core/ingestion/languages/java/record-components.js +185 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +35 -2
- package/dist/core/ingestion/languages/java/spring-aop.d.ts +12 -0
- package/dist/core/ingestion/languages/java/spring-aop.js +49 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/java/spring-conditionals.d.ts +11 -0
- package/dist/core/ingestion/languages/java/spring-conditionals.js +48 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +20 -0
- package/dist/core/ingestion/languages/java/spring-di.js +160 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +7 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +32 -0
- package/dist/core/ingestion/languages/java.js +76 -3
- package/dist/core/ingestion/languages/javascript/captures.d.ts +6 -1
- package/dist/core/ingestion/languages/javascript/captures.js +278 -4
- package/dist/core/ingestion/languages/javascript/import-target.d.ts +17 -21
- package/dist/core/ingestion/languages/javascript/import-target.js +24 -41
- package/dist/core/ingestion/languages/javascript/index.d.ts +54 -5
- package/dist/core/ingestion/languages/javascript/index.js +54 -5
- package/dist/core/ingestion/languages/javascript/query.d.ts +1 -0
- package/dist/core/ingestion/languages/javascript/query.js +232 -5
- package/dist/core/ingestion/languages/javascript/scope-resolver.js +12 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.js +2 -1
- package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
- package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.js +197 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +40 -3
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +111 -8
- package/dist/core/ingestion/languages/kotlin/captures.js +112 -0
- package/dist/core/ingestion/languages/kotlin/import-target.d.ts +8 -1
- package/dist/core/ingestion/languages/kotlin/import-target.js +20 -123
- package/dist/core/ingestion/languages/kotlin/index.d.ts +1 -0
- package/dist/core/ingestion/languages/kotlin/index.js +1 -0
- package/dist/core/ingestion/languages/kotlin/module-resolution.d.ts +22 -0
- package/dist/core/ingestion/languages/kotlin/module-resolution.js +108 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
- package/dist/core/ingestion/languages/kotlin/query.js +47 -2
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +36 -3
- package/dist/core/ingestion/languages/kotlin/spring-aop.d.ts +12 -0
- package/dist/core/ingestion/languages/kotlin/spring-aop.js +64 -0
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/kotlin/spring-conditionals.d.ts +12 -0
- package/dist/core/ingestion/languages/kotlin/spring-conditionals.js +49 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +20 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.js +299 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +10 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +41 -0
- package/dist/core/ingestion/languages/kotlin.js +5 -6
- package/dist/core/ingestion/languages/php/captures.d.ts +5 -0
- package/dist/core/ingestion/languages/php/captures.js +359 -51
- package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
- package/dist/core/ingestion/languages/php/import-target.js +229 -7
- package/dist/core/ingestion/languages/php/interpret.js +10 -0
- package/dist/core/ingestion/languages/php/query.js +31 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
- package/dist/core/ingestion/languages/python/arity-metadata.d.ts +1 -0
- package/dist/core/ingestion/languages/python/arity-metadata.js +1 -0
- package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
- package/dist/core/ingestion/languages/python/captures.js +53 -5
- package/dist/core/ingestion/languages/python/import-decomposer.js +22 -1
- package/dist/core/ingestion/languages/python/import-target.d.ts +42 -1
- package/dist/core/ingestion/languages/python/import-target.js +277 -91
- package/dist/core/ingestion/languages/python/index.d.ts +1 -1
- package/dist/core/ingestion/languages/python/index.js +1 -1
- package/dist/core/ingestion/languages/python/interpret.d.ts +52 -0
- package/dist/core/ingestion/languages/python/interpret.js +249 -3
- package/dist/core/ingestion/languages/python/query.js +9 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +17 -2
- package/dist/core/ingestion/languages/python/receiver-binding.js +192 -2
- package/dist/core/ingestion/languages/python/scope-resolver.js +27 -4
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
- package/dist/core/ingestion/languages/python/simple-hooks.js +9 -5
- package/dist/core/ingestion/languages/ruby/captures.js +200 -0
- package/dist/core/ingestion/languages/ruby/import-target.js +7 -5
- package/dist/core/ingestion/languages/ruby/query.js +93 -0
- package/dist/core/ingestion/languages/ruby/scope-resolver.js +2 -0
- package/dist/core/ingestion/languages/ruby/simple-hooks.d.ts +1 -1
- package/dist/core/ingestion/languages/ruby/simple-hooks.js +22 -1
- package/dist/core/ingestion/languages/rust/captures.js +52 -1
- package/dist/core/ingestion/languages/rust/interpret.js +18 -0
- package/dist/core/ingestion/languages/rust/method-owners.js +11 -1
- package/dist/core/ingestion/languages/rust/module-path.d.ts +126 -0
- package/dist/core/ingestion/languages/rust/module-path.js +214 -0
- package/dist/core/ingestion/languages/rust/qualified-call.d.ts +41 -0
- package/dist/core/ingestion/languages/rust/qualified-call.js +481 -0
- package/dist/core/ingestion/languages/rust/query.js +48 -6
- package/dist/core/ingestion/languages/rust/range-binding.d.ts +1 -11
- package/dist/core/ingestion/languages/rust/range-binding.js +149 -63
- package/dist/core/ingestion/languages/rust/scope-resolver.js +21 -2
- package/dist/core/ingestion/languages/rust.js +17 -0
- package/dist/core/ingestion/languages/swift/captures.js +99 -3
- package/dist/core/ingestion/languages/swift/conditional-directive-preprocess.d.ts +48 -0
- package/dist/core/ingestion/languages/swift/conditional-directive-preprocess.js +253 -0
- package/dist/core/ingestion/languages/swift/import-target.js +4 -9
- package/dist/core/ingestion/languages/swift/query.js +17 -0
- package/dist/core/ingestion/languages/swift/receiver-binding.d.ts +8 -0
- package/dist/core/ingestion/languages/swift/receiver-binding.js +6 -2
- package/dist/core/ingestion/languages/swift.js +2 -0
- package/dist/core/ingestion/languages/typescript/captures.d.ts +90 -1
- package/dist/core/ingestion/languages/typescript/captures.js +288 -5
- package/dist/core/ingestion/languages/typescript/cjs-export-assignment.d.ts +134 -0
- package/dist/core/ingestion/languages/typescript/cjs-export-assignment.js +523 -0
- package/dist/core/ingestion/languages/typescript/cjs-module-exports.d.ts +54 -0
- package/dist/core/ingestion/languages/typescript/cjs-module-exports.js +191 -0
- package/dist/core/ingestion/languages/typescript/file-candidates.d.ts +29 -0
- package/dist/core/ingestion/languages/typescript/file-candidates.js +70 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.d.ts +28 -1
- package/dist/core/ingestion/languages/typescript/import-decomposer.js +125 -10
- package/dist/core/ingestion/languages/typescript/import-target.d.ts +25 -37
- package/dist/core/ingestion/languages/typescript/import-target.js +24 -26
- package/dist/core/ingestion/languages/typescript/interpret.d.ts +21 -1
- package/dist/core/ingestion/languages/typescript/interpret.js +45 -5
- package/dist/core/ingestion/languages/typescript/module-resolution.d.ts +48 -0
- package/dist/core/ingestion/languages/typescript/module-resolution.js +171 -0
- package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
- package/dist/core/ingestion/languages/typescript/query.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript/query.js +340 -14
- package/dist/core/ingestion/languages/typescript/receiver-binding.d.ts +17 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.js +27 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.js +27 -40
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +0 -10
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +22 -22
- package/dist/core/ingestion/languages/typescript/tsconfig.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/tsconfig.js +291 -0
- package/dist/core/ingestion/languages/typescript.js +87 -1
- package/dist/core/ingestion/languages/vue/import-target.d.ts +6 -22
- package/dist/core/ingestion/languages/vue/import-target.js +11 -47
- package/dist/core/ingestion/languages/vue/scope-resolver.js +4 -2
- package/dist/core/ingestion/local-symbol-pruner.js +11 -11
- package/dist/core/ingestion/method-extractors/configs/csharp.js +1 -0
- package/dist/core/ingestion/method-extractors/generic.js +1 -0
- package/dist/core/ingestion/method-types.d.ts +16 -0
- package/dist/core/ingestion/parsing-processor.js +32 -1
- package/dist/core/ingestion/pipeline-phases/di.d.ts +8 -33
- package/dist/core/ingestion/pipeline-phases/di.js +275 -157
- package/dist/core/ingestion/pipeline-phases/index.d.ts +3 -0
- package/dist/core/ingestion/pipeline-phases/index.js +3 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +158 -3
- package/dist/core/ingestion/pipeline-phases/parse.js +5 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +11 -2
- package/dist/core/ingestion/pipeline-phases/processes.js +102 -7
- package/dist/core/ingestion/pipeline-phases/routes.js +56 -10
- package/dist/core/ingestion/pipeline-phases/spring-aop.d.ts +34 -0
- package/dist/core/ingestion/pipeline-phases/spring-aop.js +439 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +34 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +255 -0
- package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +7 -0
- package/dist/core/ingestion/pipeline.d.ts +27 -3
- package/dist/core/ingestion/pipeline.js +62 -12
- package/dist/core/ingestion/process-processor.d.ts +109 -2
- package/dist/core/ingestion/process-processor.js +464 -52
- package/dist/core/ingestion/resolve-references.d.ts +6 -1
- package/dist/core/ingestion/resolve-references.js +78 -6
- package/dist/core/ingestion/route-extractors/data-route-table.d.ts +25 -0
- package/dist/core/ingestion/route-extractors/data-route-table.js +864 -0
- package/dist/core/ingestion/route-extractors/dispatch-guard.d.ts +96 -0
- package/dist/core/ingestion/route-extractors/dispatch-guard.js +1184 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +11 -0
- package/dist/core/ingestion/route-extractors/spring-shared.js +89 -0
- package/dist/core/ingestion/route-extractors/spring.js +109 -24
- package/dist/core/ingestion/scope-extractor-bridge.js +9 -1
- package/dist/core/ingestion/scope-extractor.d.ts +22 -7
- package/dist/core/ingestion/scope-extractor.js +617 -59
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +381 -22
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +16 -5
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +15 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +53 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +20 -15
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +275 -41
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.d.ts +123 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +171 -17
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.d.ts +56 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +130 -32
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +30 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +46 -3
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +64 -0
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1233 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +107 -5
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +590 -33
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +19 -4
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +160 -4
- package/dist/core/ingestion/scope-resolution/passes/imported-value-refs.d.ts +34 -0
- package/dist/core/ingestion/scope-resolution/passes/imported-value-refs.js +62 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +64 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +118 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +109 -8
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +931 -92
- package/dist/core/ingestion/scope-resolution/passes/return-shape-members.d.ts +58 -0
- package/dist/core/ingestion/scope-resolution/passes/return-shape-members.js +458 -0
- package/dist/core/ingestion/scope-resolution/passes/unique-name-properties.d.ts +180 -0
- package/dist/core/ingestion/scope-resolution/passes/unique-name-properties.js +418 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +34 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +82 -38
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +61 -1
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +384 -48
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +112 -2
- package/dist/core/ingestion/scope-resolution/resolution-outcome.js +38 -1
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.d.ts +25 -3
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.js +36 -16
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +210 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +968 -56
- package/dist/core/ingestion/scope-resolution/summary-maps.d.ts +28 -0
- package/dist/core/ingestion/scope-resolution/summary-maps.js +50 -0
- package/dist/core/ingestion/scope-resolution/undecided-satisfaction.d.ts +55 -0
- package/dist/core/ingestion/scope-resolution/undecided-satisfaction.js +37 -0
- package/dist/core/ingestion/scope-resolution/unresolved-receivers.d.ts +109 -0
- package/dist/core/ingestion/scope-resolution/unresolved-receivers.js +204 -0
- package/dist/core/ingestion/scope-resolution/utils/definition-id.d.ts +13 -0
- package/dist/core/ingestion/scope-resolution/utils/definition-id.js +19 -0
- package/dist/core/ingestion/scope-resolution/utils/generic-instantiation.d.ts +171 -0
- package/dist/core/ingestion/scope-resolution/utils/generic-instantiation.js +218 -0
- package/dist/core/ingestion/scope-resolution/workspace-index-types.d.ts +34 -0
- package/dist/core/ingestion/scope-resolution/workspace-index-types.js +15 -0
- package/dist/core/ingestion/scope-resolution/workspace-index.d.ts +7 -20
- package/dist/core/ingestion/taint/typescript-model.js +34 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +688 -5
- package/dist/core/ingestion/type-env.js +11 -7
- package/dist/core/ingestion/type-extractors/jvm.js +17 -2
- package/dist/core/ingestion/type-extractors/shared.d.ts +17 -0
- package/dist/core/ingestion/type-extractors/shared.js +16 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +12 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +20 -0
- package/dist/core/ingestion/type-extractors/typescript.js +26 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +311 -14
- package/dist/core/ingestion/utils/ast-helpers.js +745 -48
- package/dist/core/ingestion/utils/call-analysis.d.ts +27 -22
- package/dist/core/ingestion/utils/call-analysis.js +202 -7
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +153 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +928 -0
- package/dist/core/ingestion/utils/callable-labels.d.ts +25 -0
- package/dist/core/ingestion/utils/callable-labels.js +31 -0
- package/dist/core/ingestion/utils/effective-ram.d.ts +40 -0
- package/dist/core/ingestion/utils/effective-ram.js +58 -0
- package/dist/core/ingestion/utils/line-base.d.ts +14 -0
- package/dist/core/ingestion/utils/line-base.js +14 -0
- package/dist/core/ingestion/utils/method-props.d.ts +27 -4
- package/dist/core/ingestion/utils/method-props.js +29 -4
- package/dist/core/ingestion/utils/receiver-chain-captures.d.ts +31 -0
- package/dist/core/ingestion/utils/receiver-chain-captures.js +57 -0
- package/dist/core/ingestion/utils/receiver-chain-codec.d.ts +89 -0
- package/dist/core/ingestion/utils/receiver-chain-codec.js +182 -0
- package/dist/core/ingestion/utils/scope-tree-walk.d.ts +22 -0
- package/dist/core/ingestion/utils/scope-tree-walk.js +33 -0
- package/dist/core/ingestion/utils/template-arguments.d.ts +96 -0
- package/dist/core/ingestion/utils/template-arguments.js +196 -0
- package/dist/core/ingestion/utils/type-parameters.d.ts +49 -0
- package/dist/core/ingestion/utils/type-parameters.js +206 -0
- package/dist/core/ingestion/workers/callable-id.d.ts +72 -0
- package/dist/core/ingestion/workers/callable-id.js +116 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +14 -1
- package/dist/core/ingestion/workers/parse-worker.js +409 -39
- package/dist/core/ingestion/workers/worker-pool.d.ts +34 -27
- package/dist/core/ingestion/workers/worker-pool.js +133 -25
- package/dist/core/lbug/csv-generator.d.ts +27 -0
- package/dist/core/lbug/csv-generator.js +80 -17
- package/dist/core/lbug/extension-load-error.d.ts +2 -2
- package/dist/core/lbug/extension-load-error.js +44 -27
- package/dist/core/lbug/extension-loader.d.ts +29 -0
- package/dist/core/lbug/extension-loader.js +32 -7
- package/dist/core/lbug/graph-emit-sink.d.ts +264 -0
- package/dist/core/lbug/graph-emit-sink.js +581 -0
- package/dist/core/lbug/lbug-adapter.d.ts +337 -3
- package/dist/core/lbug/lbug-adapter.js +772 -67
- package/dist/core/lbug/lbug-config.d.ts +93 -6
- package/dist/core/lbug/lbug-config.js +269 -9
- package/dist/core/lbug/native-check.d.ts +39 -0
- package/dist/core/lbug/native-check.js +323 -46
- package/dist/core/lbug/pdg-emit-sink.d.ts +13 -4
- package/dist/core/lbug/pdg-emit-sink.js +21 -111
- package/dist/core/lbug/pool-adapter.d.ts +23 -1
- package/dist/core/lbug/pool-adapter.js +115 -7
- package/dist/core/lbug/query-batch.d.ts +75 -0
- package/dist/core/lbug/query-batch.js +102 -0
- package/dist/core/lbug/rel-pair-routing.d.ts +160 -2
- package/dist/core/lbug/rel-pair-routing.js +228 -10
- package/dist/core/lbug/schema.d.ts +162 -3
- package/dist/core/lbug/schema.js +392 -157
- package/dist/core/lbug/sidecar-recovery.d.ts +1 -0
- package/dist/core/lbug/sidecar-recovery.js +1 -1
- package/dist/core/lbug/sync-csv-writer.d.ts +47 -0
- package/dist/core/lbug/sync-csv-writer.js +108 -0
- package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
- package/dist/core/platform/capabilities.d.ts +0 -1
- package/dist/core/platform/capabilities.js +12 -7
- package/dist/core/run-analyze.d.ts +150 -3
- package/dist/core/run-analyze.js +1562 -151
- package/dist/core/search/bm25-index.d.ts +11 -0
- package/dist/core/search/bm25-index.js +60 -26
- package/dist/core/search/fts-indexes.d.ts +167 -2
- package/dist/core/search/fts-indexes.js +264 -10
- package/dist/core/wiki/graph-queries.js +145 -112
- package/dist/core/wiki/llm-client.d.ts +37 -5
- package/dist/core/wiki/llm-client.js +88 -17
- package/dist/core/wiki/prompts.d.ts +19 -0
- package/dist/core/wiki/prompts.js +20 -1
- package/dist/lib/utils.d.ts +113 -0
- package/dist/lib/utils.js +185 -0
- package/dist/mcp/http-transport.d.ts +5 -0
- package/dist/mcp/http-transport.js +19 -5
- package/dist/mcp/local/aop-metadata.d.ts +77 -0
- package/dist/mcp/local/aop-metadata.js +227 -0
- package/dist/mcp/local/bean-metadata.d.ts +3 -0
- package/dist/mcp/local/bean-metadata.js +46 -0
- package/dist/mcp/local/local-backend.d.ts +167 -6
- package/dist/mcp/local/local-backend.js +1756 -405
- package/dist/mcp/local/path-predicate.d.ts +19 -0
- package/dist/mcp/local/path-predicate.js +21 -0
- package/dist/mcp/local/pdg-impact.d.ts +132 -10
- package/dist/mcp/local/pdg-impact.js +391 -98
- package/dist/mcp/output-budget.d.ts +5 -0
- package/dist/mcp/output-budget.js +52 -0
- package/dist/mcp/read-only-policy.d.ts +12 -0
- package/dist/mcp/read-only-policy.js +102 -0
- package/dist/mcp/repository-policy.d.ts +35 -0
- package/dist/mcp/repository-policy.js +333 -0
- package/dist/mcp/resources.js +34 -7
- package/dist/mcp/server.d.ts +5 -2
- package/dist/mcp/server.js +48 -18
- package/dist/mcp/tools.d.ts +8 -8
- package/dist/mcp/tools.js +91 -20
- package/dist/server/analyze-job.d.ts +40 -2
- package/dist/server/analyze-job.js +30 -2
- package/dist/server/analyze-launch.d.ts +1 -1
- package/dist/server/analyze-launch.js +79 -10
- package/dist/server/analyze-worker-core.d.ts +3 -2
- package/dist/server/analyze-worker-core.js +15 -3
- package/dist/server/analyze-worker-ipc.d.ts +1 -1
- package/dist/server/analyze-worker-ipc.js +4 -0
- package/dist/server/analyze-worker-protocol.d.ts +59 -0
- package/dist/server/analyze-worker-protocol.js +1 -0
- package/dist/server/analyze-worker.d.ts +1 -17
- package/dist/server/analyze-worker.js +29 -6
- package/dist/server/api.d.ts +2 -11
- package/dist/server/api.js +200 -155
- package/dist/server/embed-run-outcome.d.ts +89 -0
- package/dist/server/embed-run-outcome.js +88 -0
- package/dist/server/git-clone.js +6 -2
- package/dist/server/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +4 -2
- package/dist/server/middleware.d.ts +116 -9
- package/dist/server/middleware.js +291 -22
- package/dist/server/sse-progress.d.ts +41 -0
- package/dist/server/sse-progress.js +125 -0
- package/dist/server/upload-ingest.js +2 -1
- package/dist/server/validation.js +2 -1
- package/dist/storage/branch-index.d.ts +11 -6
- package/dist/storage/branch-index.js +15 -7
- package/dist/storage/file-hash.js +2 -2
- package/dist/storage/fs-atomic.d.ts +25 -0
- package/dist/storage/fs-atomic.js +42 -0
- package/dist/storage/git.d.ts +165 -0
- package/dist/storage/git.js +352 -3
- package/dist/storage/index-lock.d.ts +83 -0
- package/dist/storage/index-lock.js +654 -0
- package/dist/storage/parse-cache.js +482 -1
- package/dist/storage/parsedfile-store.d.ts +8 -0
- package/dist/storage/parsedfile-store.js +235 -1
- package/dist/storage/repo-manager.d.ts +29 -309
- package/dist/storage/repo-manager.js +187 -165
- package/dist/storage/repo-meta.d.ts +530 -0
- package/dist/storage/repo-meta.js +100 -0
- package/dist/types/pipeline.d.ts +37 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +1 -1
- package/hooks/claude/gitnexus-hook.cjs +1 -1
- package/hooks/claude/resolve-analyze-cmd.cjs +80 -13
- package/package.json +20 -12
- package/scripts/cross-platform-shard.ts +143 -0
- package/scripts/cross-platform-tests.ts +94 -0
- package/scripts/ensure-fts.ts +14 -3
- package/scripts/run-cross-platform.ts +36 -10
- package/scripts/sync-plugin-manifests.mjs +192 -0
- package/skills/gitnexus-cli.md +3 -3
- package/skills/gitnexus-debugging.md +37 -7
- package/skills/gitnexus-exploring.md +26 -4
- package/skills/gitnexus-impact-analysis.md +71 -10
- package/skills/gitnexus-lfg/README.md +55 -0
- package/skills/gitnexus-lfg/SKILL.md +86 -0
- package/skills/gitnexus-plan/README.md +147 -0
- package/skills/gitnexus-plan/SKILL.md +348 -0
- package/skills/gitnexus-plan/references/context-ledger.md +137 -0
- package/skills/gitnexus-plan/references/context-pack.md +126 -0
- package/skills/gitnexus-plan/references/evidence-provenance.md +309 -0
- package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
- package/skills/gitnexus-plan/references/plan-template.md +201 -0
- package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2366 -0
- package/skills/gitnexus-refactoring.md +48 -5
- package/skills/gitnexus-review/SKILL.md +279 -0
- package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
- package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
- package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
- package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
- package/skills/gitnexus-taint-analysis.md +13 -7
- package/skills/gitnexus-work/README.md +71 -0
- package/skills/gitnexus-work/SKILL.md +272 -0
- package/skills/gitnexus-work/references/evidence-provenance.md +309 -0
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2366 -0
- package/vendor/leiden/utils.cjs +28 -1
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +24 -0
- package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
- package/web/assets/abnfDiagram-QNN2D4NM-Cq2djWWe.js +1 -0
- package/web/assets/agent-DIzEQ1JJ.js +626 -0
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +1 -0
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +36 -0
- package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +132 -0
- package/web/assets/{c4Diagram-Y2BXMSZH-DOXVs7-C.js → c4Diagram-X2LASM7V-CnhoT4aV.js} +6 -6
- package/web/assets/chunk-224SPVON-B8gxtXpy.js +1 -0
- package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +127 -0
- package/web/assets/chunk-2SREHG4O-Dip42xOq.js +1 -0
- package/web/assets/chunk-4RFN2BYJ-DHHWuC-n.js +1 -0
- package/web/assets/chunk-66DQ2XMT-CM0xjFAN.js +1 -0
- package/web/assets/chunk-6BELYETK-ChsYtfHW.js +1 -0
- package/web/assets/chunk-6L755F7B-CMhLBxi2.js +1 -0
- package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +2 -0
- package/web/assets/chunk-A7VWPJGB-B4O3oQdQ.js +1 -0
- package/web/assets/chunk-BI6VK774-D0oaWk8V.js +1 -0
- package/web/assets/chunk-D6VWDJW2-BxcBdZ9c.js +2 -0
- package/web/assets/chunk-DMV4VAQV-Bn6WXDSX.js +4 -0
- package/web/assets/chunk-E5QJAATJ-dh-5CtIV.js +2 -0
- package/web/assets/chunk-EQFTRU2I-1ix7TzW9.js +2 -0
- package/web/assets/chunk-FWYVLQTC-BgDItRzJ.js +1 -0
- package/web/assets/chunk-HNC4WDU7-DoU3KnA7.js +1 -0
- package/web/assets/chunk-L5GCOVLC-CE2w8Nm_.js +161 -0
- package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +321 -0
- package/web/assets/chunk-LORZLZWG-B57uGw2N.js +88 -0
- package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +62 -0
- package/web/assets/chunk-NV3KIAZN-5yvcpMiu.js +1 -0
- package/web/assets/chunk-OIYT25JQ-CQ6KOZGX.js +1 -0
- package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +10 -0
- package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +156 -0
- package/web/assets/chunk-RRFMTAIC-CMN0wcYA.js +1 -0
- package/web/assets/{chunk-RLI5ZMPA-CkXZ0y0U.js → chunk-SATU7PGQ-B1zhgOvc.js} +1 -1
- package/web/assets/chunk-STOV2HOB-GnExfzIX.js +1 -0
- package/web/assets/chunk-SZD42YQK-ijyKKVr1.js +70 -0
- package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +231 -0
- package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +2 -0
- package/web/assets/chunk-TZUXEDM2-B7p9AcTw.js +1 -0
- package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +1 -0
- package/web/assets/{chunk-6764PJDD-C7xxk063.js → chunk-VE5CLXGZ-C1vB7wpY.js} +1 -1
- package/web/assets/chunk-VJFVEZTB-CX66F2ep.js +206 -0
- package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +1 -0
- package/web/assets/chunk-WJBAP47W-BckNkuEN.js +1 -0
- package/web/assets/chunk-XNMVGMAZ-Cg_LnPtj.js +1 -0
- package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +1 -0
- package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +1 -0
- package/web/assets/{cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js → cose-bilkent-RZA4XIPR-BHpK4Crp.js} +1 -1
- package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +1 -0
- package/web/assets/cynefinDiagram-TR7LZUCG-C3Iar9lZ.js +62 -0
- package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +4 -0
- package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +30 -0
- package/web/assets/diagram-JCD7PQ7C-DC5-9FRr.js +24 -0
- package/web/assets/diagram-KFBZAVDW-Dfmf_4ti.js +3 -0
- package/web/assets/diagram-L7DVE3PN-GIRyVUtt.js +41 -0
- package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +24 -0
- package/web/assets/ebnfDiagram-DRHRQJWO-D8_CI4ZF.js +1 -0
- package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +85 -0
- package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +1 -0
- package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +1 -0
- package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +292 -0
- package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +1 -0
- package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +106 -0
- package/web/assets/{index-B4eB4dNZ.js → index-BBNl0qfX.js} +51 -51
- package/web/assets/index-CJDpyH-n.css +2 -0
- package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +1 -0
- package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-BLjivjXL.js → ishikawaDiagram-4JDSWWDM-DmqWtjkl.js} +6 -6
- package/web/assets/{journeyDiagram-M6C3CM3L-Cetgs3NH.js → journeyDiagram-QUS3FAKT-XAzVzrQW.js} +6 -6
- package/web/assets/{kanban-definition-75IXJCU3-DMlCaIpf.js → kanban-definition-D4L7SQKK-YurRnmYn.js} +27 -27
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +257 -0
- package/web/assets/{mindmap-definition-2TDM6QVE-B4GbXQBc.js → mindmap-definition-66QP5TD6-ChrWWnil.js} +29 -29
- package/web/assets/node-Ct_zna8U.js +8 -0
- package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +1 -0
- package/web/assets/pegDiagram-YKIO5C6U-QGeQLEq2.js +1 -0
- package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +1 -0
- package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +39 -0
- package/web/assets/preload-helper-Czpn1I53.js +1 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-B1TQnlm0.js → quadrantDiagram-VO5QLCXA-B7098wSc.js} +6 -6
- package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +1 -0
- package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +1 -0
- package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +1 -0
- package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +1 -0
- package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +1 -0
- package/web/assets/railroadDiagram-M77LTMSB-AXu4vxk_.js +1 -0
- package/web/assets/requirementDiagram-RASO5HTO-B-l8InpK.js +84 -0
- package/web/assets/sankeyDiagram-F32LOJ6L-Kd7zjJgX.js +40 -0
- package/web/assets/sdk-CzHHH8tD.js +37 -0
- package/web/assets/sequenceDiagram-URATNSBD-BlcdY9DS.js +162 -0
- package/web/assets/sizeCapture-5GORAGP4-BEqQzsxs.js +1 -0
- package/web/assets/src-C5sx_gMp.js +1 -0
- package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +1 -0
- package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +1 -0
- package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +2 -0
- package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +8 -0
- package/web/assets/timeline-definition-WJXWRH4I-DUfp1R3E.js +120 -0
- package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +1 -0
- package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +1 -0
- package/web/assets/vennDiagram-K3VCMQLI-Bj-FN-XS.js +34 -0
- package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +1 -0
- package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +78 -0
- package/web/assets/xychartDiagram-5VRUVLCW-CK_rbSWE.js +7 -0
- package/web/index.html +17 -15
- package/dist/core/ingestion/languages/python/index-stats.d.ts +0 -18
- package/dist/core/ingestion/languages/python/index-stats.js +0 -25
- package/skills/gitnexus-pr-review.md +0 -163
- package/web/assets/ProcessFlowModal-Dna7GkwO.js +0 -22
- package/web/assets/agent-DNYDy-KA.js +0 -660
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-BU5ZRITg.js +0 -36
- package/web/assets/blockDiagram-7IZFK4PR-Dut1BpTV.js +0 -132
- package/web/assets/chunk-2T2R6R2M-pkw2oXHH.js +0 -4
- package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +0 -1
- package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +0 -321
- package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +0 -159
- package/web/assets/chunk-67TQ5CYL-zxhDWgyF.js +0 -124
- package/web/assets/chunk-7J6CGLKN-AmkN8jJN.js +0 -10
- package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +0 -1
- package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +0 -1
- package/web/assets/chunk-INKRHTLW-D9BM9HWZ.js +0 -70
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +0 -1
- package/web/assets/chunk-KGFNY3KK-tD2F6wxK.js +0 -62
- package/web/assets/chunk-KGYTTC2M-zm6n242I.js +0 -1
- package/web/assets/chunk-KNLZD3CH-BGlP6X9R.js +0 -1
- package/web/assets/chunk-LCXTWHL2-Ba9JK-6F.js +0 -231
- package/web/assets/chunk-LII3EMHJ-EGx-eBIu.js +0 -1
- package/web/assets/chunk-LRIF4GLE-C3_PqUBq.js +0 -1
- package/web/assets/chunk-QA3QBVWF-D4cSJBf6.js +0 -2
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +0 -1
- package/web/assets/chunk-RG4AUYOV-OqBBMwuQ.js +0 -206
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +0 -1
- package/web/assets/chunk-T2UQINTJ-BJusEiGe.js +0 -1
- package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +0 -1
- package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +0 -1
- package/web/assets/chunk-UY5QBCOK-BCpUlARQ.js +0 -1
- package/web/assets/chunk-VU6ZFW4Y-BeXVk45_.js +0 -2
- package/web/assets/chunk-ZXARS5L4-BI_qR2Nm.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-D9zSIg0x.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-D9zSIg0x.js +0 -1
- package/web/assets/dagre-ND4H6XIP-CpcV5kbl.js +0 -4
- package/web/assets/diagram-3NCE3AQN-6SMxBRpj.js +0 -43
- package/web/assets/diagram-GF46GFSD-BZEdNcRZ.js +0 -24
- package/web/assets/diagram-HNR7UZ2L-DxKW2a2Y.js +0 -3
- package/web/assets/diagram-QXG6HAR7-HfTHcXX_.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-CyijUS8r.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-D0fvpWEX.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-Bvr9bbhk.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-TzODrLzv.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-ONQSwJIY.js +0 -106
- package/web/assets/index-CX_fADmQ.css +0 -2
- package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-DIPVUIQ6.js +0 -2
- package/web/assets/katex-K3KEBU37-qRQBy-EZ.js +0 -261
- package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +0 -1
- package/web/assets/pieDiagram-CU6KROY3-D3YC_xyg.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +0 -1
- package/web/assets/requirementDiagram-JXO7QTGE-f8wczLQf.js +0 -84
- package/web/assets/sankeyDiagram-URQDO5SZ-BTxzG5j0.js +0 -40
- package/web/assets/sequenceDiagram-VS2MUI6T-DuamM-IR.js +0 -162
- package/web/assets/src-BNCXICdA.js +0 -1
- package/web/assets/stateDiagram-7D4R322I-Ch2pEUcw.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-7ANuoZLL.js +0 -1
- package/web/assets/timeline-definition-O6YCAMPW-07BR8R8G.js +0 -120
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +0 -1
- package/web/assets/vennDiagram-MWXL3ELB-BQX2ossk.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-CGIJBBiK.js +0 -78
- package/web/assets/xychartDiagram-N2JHSOCM-B3HNMuWp.js +0 -7
- /package/web/assets/{chunk-7W6UQGC5-pyKGssV3.js → chunk-LIEV3EAG-pyKGssV3.js} +0 -0
|
@@ -1,6 +1,468 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Elementary import-cycle enumeration.
|
|
3
|
+
*
|
|
4
|
+
* ## What is reported
|
|
5
|
+
*
|
|
6
|
+
* Every *elementary* cycle of the file-import graph — a closed walk that visits
|
|
7
|
+
* no file twice — is reported exactly once. Self-imports (`a -> a`) and
|
|
8
|
+
* two-file cycles count. Cycles that are nested inside, or that overlap with,
|
|
9
|
+
* other cycles are each reported separately: a strongly connected component
|
|
10
|
+
* with three mutually-importing files contributes five cycles, not one.
|
|
11
|
+
*
|
|
12
|
+
* This replaces an earlier implementation that returned ONE representative
|
|
13
|
+
* cycle per cyclic strongly connected component. That made the reported count a
|
|
14
|
+
* count of tangles, not of cycles, and it hid every cycle in a component but
|
|
15
|
+
* the first — including cycles that a reader would have to break separately.
|
|
16
|
+
* The tangle count is still available, as `componentCount`, under a name that
|
|
17
|
+
* says what it is.
|
|
18
|
+
*
|
|
19
|
+
* The scale of what the old shape hid, measured on GitNexus itself (2,079
|
|
20
|
+
* files, 5,320 initialization-forcing import edges): it reported 11 cycles.
|
|
21
|
+
* There are 27,939, spread across those same 11 components. It showed 11 of
|
|
22
|
+
* them and 27,928 were invisible.
|
|
23
|
+
*
|
|
24
|
+
* ## Algorithm
|
|
25
|
+
*
|
|
26
|
+
* Donald B. Johnson, "Finding all the elementary circuits of a directed graph",
|
|
27
|
+
* SIAM J. Comput. 4(1), 1975 — SCC decomposition plus a backtracking search
|
|
28
|
+
* guarded by the `blocked` flag and the `B` sets, which together guarantee that
|
|
29
|
+
* no fruitless path is explored twice between two circuit outputs. That is what
|
|
30
|
+
* buys the O((n + e)(c + 1)) bound for `c` circuits: the cost is proportional
|
|
31
|
+
* to the answer, not to the size of the search space.
|
|
32
|
+
*
|
|
33
|
+
* SCCs come from an iterative Tarjan pass rather than the Kosaraju pass this
|
|
34
|
+
* module used before. Johnson recomputes SCCs on each induced subgraph as the
|
|
35
|
+
* root advances, and Tarjan needs only the forward adjacency, so nothing has to
|
|
36
|
+
* rebuild a reverse graph once per root.
|
|
37
|
+
*
|
|
38
|
+
* ## How this differs from madge
|
|
39
|
+
*
|
|
40
|
+
* madge's `circular()` walks depth-first from every node carrying its ancestor
|
|
41
|
+
* path and records `ancestors.slice(indexOf(dep))` whenever it reaches an
|
|
42
|
+
* ancestor. It also marks nodes visited *globally* and skips them on later
|
|
43
|
+
* walks, so once a node has been traversed, cycles reachable only by entering
|
|
44
|
+
* it from a different predecessor are never seen. madge therefore reports many
|
|
45
|
+
* cycles but not all of them, and which ones it misses depends on iteration
|
|
46
|
+
* order. Johnson's is strictly stronger: it is complete.
|
|
47
|
+
*
|
|
48
|
+
* The practical consequence is that GitNexus reports MORE cycles than madge on
|
|
49
|
+
* the same graph, and the two counts should not be expected to agree. Anyone
|
|
50
|
+
* reconciling the two is not looking at a bug here.
|
|
51
|
+
*
|
|
52
|
+
* ## Determinism
|
|
53
|
+
*
|
|
54
|
+
* Adjacency lists and the node order are sorted (default string order, matching
|
|
55
|
+
* `Array.prototype.sort`), the search visits neighbours in that order, and the
|
|
56
|
+
* finished list is sorted element-wise. Same input, same output, byte for byte.
|
|
57
|
+
*
|
|
58
|
+
* ## Rotation normalization
|
|
59
|
+
*
|
|
60
|
+
* `[a, b, c, a]` and `[b, c, a, b]` are the same cycle and must be emitted
|
|
61
|
+
* once. That is structural here rather than a post-hoc dedup pass: Johnson's
|
|
62
|
+
* search for circuits rooted at `s` runs on the subgraph induced by the nodes
|
|
63
|
+
* that sort at or after `s`, so every node of an emitted circuit sorts at or
|
|
64
|
+
* after its root. Each cycle is therefore emitted exactly once, rooted at — and
|
|
65
|
+
* closed back onto — its own lexicographically smallest node. No other rotation
|
|
66
|
+
* of it can ever be produced.
|
|
67
|
+
*
|
|
68
|
+
* ## Bounds
|
|
69
|
+
*
|
|
70
|
+
* The number of elementary cycles is exponential in the worst case, so the
|
|
71
|
+
* search is bounded twice: by the number of cycles (`IMPORT_CYCLE_LIMIT`) and
|
|
72
|
+
* by the work spent finding them (`IMPORT_CYCLE_WORK_LIMIT`). The second is not
|
|
73
|
+
* redundant — Johnson's is output-sensitive, so a graph that yields few cycles
|
|
74
|
+
* per root can burn unbounded time while staying far under the cycle cap.
|
|
75
|
+
*
|
|
76
|
+
* Exceeding either bound abandons the enumeration. What a partial run had
|
|
77
|
+
* accumulated is discarded rather than returned, because a partial list of
|
|
78
|
+
* elementary cycles is indistinguishable from a complete one at the call site
|
|
79
|
+
* and would be read as "these are all of them". What is returned instead is a
|
|
80
|
+
* different KIND of list — one representative cycle per cyclic component, the
|
|
81
|
+
* old pre-enumeration answer — under `enumeration: 'component-representatives'`
|
|
82
|
+
* so the difference is machine-readable and not merely documented. Only a run
|
|
83
|
+
* that dies inside the decomposition itself reports nothing at all.
|
|
84
|
+
*/
|
|
85
|
+
import { compareCodeUnits } from '../../lib/utils.js';
|
|
86
|
+
/**
|
|
87
|
+
* Elementary cycles reported before the search fails closed.
|
|
88
|
+
*
|
|
89
|
+
* The binding constraint is response size, not time. THE MEASUREMENT THAT SETS
|
|
90
|
+
* THIS NUMBER, on GitNexus itself — 2,079 files, 5,320 initialization-forcing
|
|
91
|
+
* import edges: complete enumeration finds 27,939 elementary cycles across 11
|
|
92
|
+
* components in 241ms. Fast. But those cycles average 13 files each, so
|
|
93
|
+
* serializing them is 400,877 path entries — a 21.8 MB JSON response for a tool
|
|
94
|
+
* whose result is read by an agent. Time was never going to stop that, and
|
|
95
|
+
* neither was the work budget (the same run spends 6.3M of its 10M).
|
|
96
|
+
*
|
|
97
|
+
* Keep that measurement next to this constant. Without it the cap looks like an
|
|
98
|
+
* arbitrary round number and gets raised or deleted by someone who has only
|
|
99
|
+
* ever seen it not fire.
|
|
100
|
+
*
|
|
101
|
+
* So the cap is set where the answer stops being consumable rather than where
|
|
102
|
+
* the machine stops coping. Past 10,000 cycles the ten-thousandth path tells a
|
|
103
|
+
* reader nothing the first hundred did not, and what a reader acts on is
|
|
104
|
+
* `componentCount` plus one cycle per component — which is exactly what a
|
|
105
|
+
* report over the cap degrades to, rather than to nothing.
|
|
106
|
+
*/
|
|
107
|
+
export const IMPORT_CYCLE_LIMIT = 10_000;
|
|
108
|
+
/**
|
|
109
|
+
* Units of search effort allowed before the search fails closed — edges
|
|
110
|
+
* examined, nodes scanned per root, and emitted cycle nodes at
|
|
111
|
+
* `EMITTED_NODE_COST` each — counted across the SCC passes and the circuit
|
|
112
|
+
* search alike.
|
|
113
|
+
*
|
|
114
|
+
* The cycle cap alone does NOT bound this. Johnson's is output-sensitive at
|
|
115
|
+
* O((n + e)(c + 1)), so producing `c` cycles still scales with the graph: a
|
|
116
|
+
* component of mutually-importing neighbours yields one or two cycles per root,
|
|
117
|
+
* so an SCC pass runs per node and the total is quadratic while the cycle count
|
|
118
|
+
* stays low. `check` admits import graphs up to 100k edges, so that shape is
|
|
119
|
+
* reachable, and there it is minutes of work under a cycle cap that never
|
|
120
|
+
* trips. The reverse gap is just as real: a single 50k-file component produces
|
|
121
|
+
* cycles 50k files long, and 10k of those exhaust the heap. One bound cannot
|
|
122
|
+
* see both, which is why there are two.
|
|
123
|
+
*
|
|
124
|
+
* Measured on this implementation against the mutual-import chain — the shape
|
|
125
|
+
* that spends the whole budget, where every unit buys a fresh SCC pass over a
|
|
126
|
+
* barely-smaller component — the rate is 2.9-5.2M units/second (5.2M at 10k
|
|
127
|
+
* nodes, 2.9M at 50k; it falls as the component grows). So 10M buys roughly
|
|
128
|
+
* 1.9-3.5s of enumeration on this hardware. That is the one shape where a user
|
|
129
|
+
* waits, and it is the number to re-measure if this constant is ever moved.
|
|
130
|
+
*
|
|
131
|
+
* It sits far above what real import graphs cost: a 100k-file acyclic graph
|
|
132
|
+
* spends 220k units, and 20k independent three-file tangles spend 576k. Only a
|
|
133
|
+
* component both large and densely tangled reaches the cap, and that
|
|
134
|
+
* component's honest answer is "too tangled to enumerate", not a
|
|
135
|
+
* silently-shortened list.
|
|
136
|
+
*/
|
|
137
|
+
export const IMPORT_CYCLE_WORK_LIMIT = 10_000_000;
|
|
138
|
+
/**
|
|
139
|
+
* Work charged per node of an emitted cycle, relative to one edge examination.
|
|
140
|
+
*
|
|
141
|
+
* Emitted nodes are retained for the lifetime of the call and then sorted and
|
|
142
|
+
* serialized, so they are the term that decides peak memory, while examined
|
|
143
|
+
* edges cost nothing but time. Without a weight here, a graph whose cycles are
|
|
144
|
+
* tens of thousands of files long exhausts the heap while both bounds still
|
|
145
|
+
* read as comfortably unspent.
|
|
146
|
+
*/
|
|
147
|
+
const EMITTED_NODE_COST = 10;
|
|
148
|
+
function buildGraph(edges) {
|
|
149
|
+
const targetsBySource = new Map();
|
|
150
|
+
for (const { source, target } of edges) {
|
|
151
|
+
if (!source || !target)
|
|
152
|
+
continue;
|
|
153
|
+
const targets = targetsBySource.get(source) ?? new Set();
|
|
154
|
+
targets.add(target);
|
|
155
|
+
targetsBySource.set(source, targets);
|
|
156
|
+
if (!targetsBySource.has(target))
|
|
157
|
+
targetsBySource.set(target, new Set());
|
|
158
|
+
}
|
|
159
|
+
const adjacency = new Map();
|
|
160
|
+
const selfLoops = new Set();
|
|
161
|
+
for (const [source, targets] of targetsBySource) {
|
|
162
|
+
adjacency.set(source, [...targets].sort());
|
|
163
|
+
if (targets.has(source))
|
|
164
|
+
selfLoops.add(source);
|
|
165
|
+
}
|
|
166
|
+
return { adjacency, nodes: [...adjacency.keys()].sort(), selfLoops };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Charge `amount` units of search effort. Returns true once the budget is
|
|
170
|
+
* spent, which every caller must honour — a bulk charge that is not checked
|
|
171
|
+
* would let the search run on past the bound it just crossed.
|
|
172
|
+
*/
|
|
173
|
+
function overBudget(search, amount = 1) {
|
|
174
|
+
search.work += amount;
|
|
175
|
+
if (search.work <= search.workLimit)
|
|
176
|
+
return false;
|
|
177
|
+
search.exceeded = 'work';
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Strongly connected components of the subgraph induced by `allowed`, via an
|
|
182
|
+
* iterative Tarjan. Iterative because import graphs reach 10^5 files and a
|
|
183
|
+
* recursive walk would blow the stack long before that.
|
|
184
|
+
*
|
|
185
|
+
* `roots` fixes the order the outer loop starts from, which is what makes the
|
|
186
|
+
* component set — and so Johnson's choice of root — deterministic.
|
|
187
|
+
*
|
|
188
|
+
* Abandons the pass and returns a partial list if the work budget runs out, so
|
|
189
|
+
* every caller must check `search.exceeded` before using the result.
|
|
190
|
+
*/
|
|
191
|
+
function stronglyConnectedComponents(roots, adjacency, allowed, search) {
|
|
192
|
+
const index = new Map();
|
|
193
|
+
const lowLink = new Map();
|
|
194
|
+
const onStack = new Set();
|
|
195
|
+
const pending = [];
|
|
196
|
+
const components = [];
|
|
197
|
+
let counter = 0;
|
|
198
|
+
// One pass over the roots happens even for a component with no edges left.
|
|
199
|
+
if (overBudget(search, roots.length))
|
|
200
|
+
return components;
|
|
201
|
+
for (const root of roots) {
|
|
202
|
+
if (index.has(root))
|
|
203
|
+
continue;
|
|
204
|
+
index.set(root, counter);
|
|
205
|
+
lowLink.set(root, counter);
|
|
206
|
+
counter += 1;
|
|
207
|
+
pending.push(root);
|
|
208
|
+
onStack.add(root);
|
|
209
|
+
const frames = [{ node: root, nextIndex: 0 }];
|
|
210
|
+
while (frames.length > 0) {
|
|
211
|
+
const frame = frames[frames.length - 1];
|
|
212
|
+
const neighbors = adjacency.get(frame.node) ?? [];
|
|
213
|
+
if (frame.nextIndex < neighbors.length) {
|
|
214
|
+
const next = neighbors[frame.nextIndex];
|
|
215
|
+
frame.nextIndex += 1;
|
|
216
|
+
if (overBudget(search))
|
|
217
|
+
return components;
|
|
218
|
+
if (!allowed.has(next))
|
|
219
|
+
continue;
|
|
220
|
+
if (!index.has(next)) {
|
|
221
|
+
index.set(next, counter);
|
|
222
|
+
lowLink.set(next, counter);
|
|
223
|
+
counter += 1;
|
|
224
|
+
pending.push(next);
|
|
225
|
+
onStack.add(next);
|
|
226
|
+
frames.push({ node: next, nextIndex: 0 });
|
|
227
|
+
}
|
|
228
|
+
else if (onStack.has(next)) {
|
|
229
|
+
lowLink.set(frame.node, Math.min(lowLink.get(frame.node), index.get(next)));
|
|
230
|
+
}
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
frames.pop();
|
|
234
|
+
const node = frame.node;
|
|
235
|
+
if (lowLink.get(node) === index.get(node)) {
|
|
236
|
+
const component = [];
|
|
237
|
+
for (;;) {
|
|
238
|
+
const member = pending.pop();
|
|
239
|
+
onStack.delete(member);
|
|
240
|
+
component.push(member);
|
|
241
|
+
if (member === node)
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
components.push(component);
|
|
245
|
+
}
|
|
246
|
+
if (frames.length > 0) {
|
|
247
|
+
const parent = frames[frames.length - 1].node;
|
|
248
|
+
lowLink.set(parent, Math.min(lowLink.get(parent), lowLink.get(node)));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return components;
|
|
253
|
+
}
|
|
254
|
+
/** A component that contains at least one cycle: two-plus members, or a self-import. */
|
|
255
|
+
function isCyclic(component, selfLoops) {
|
|
256
|
+
return component.length > 1 || selfLoops.has(component[0]);
|
|
257
|
+
}
|
|
258
|
+
function leastNode(nodes) {
|
|
259
|
+
let least = nodes[0];
|
|
260
|
+
for (const node of nodes)
|
|
261
|
+
if (node < least)
|
|
262
|
+
least = node;
|
|
263
|
+
return least;
|
|
264
|
+
}
|
|
265
|
+
/** Order components by their least node. Components are disjoint, so this is total. */
|
|
266
|
+
function byLeastNode(left, right) {
|
|
267
|
+
const leftLeast = leastNode(left);
|
|
268
|
+
const rightLeast = leastNode(right);
|
|
269
|
+
return compareCodeUnits(leftLeast, rightLeast);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Johnson's `UNBLOCK`, iterative. Lifts `node` and everything transitively
|
|
273
|
+
* waiting on it out of `blocked`, so a path that was abandoned as fruitless
|
|
274
|
+
* becomes explorable again once the reason it was fruitless is gone.
|
|
275
|
+
*/
|
|
276
|
+
function unblock(node, blocked, blockedBy) {
|
|
277
|
+
const stack = [node];
|
|
278
|
+
while (stack.length > 0) {
|
|
279
|
+
const current = stack.pop();
|
|
280
|
+
blocked.delete(current);
|
|
281
|
+
const waiting = blockedBy.get(current);
|
|
282
|
+
if (waiting === undefined || waiting.size === 0)
|
|
283
|
+
continue;
|
|
284
|
+
for (const dependent of waiting) {
|
|
285
|
+
if (blocked.has(dependent))
|
|
286
|
+
stack.push(dependent);
|
|
287
|
+
}
|
|
288
|
+
waiting.clear();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Johnson's `CIRCUIT`, iterative — enumerate the elementary circuits rooted at
|
|
293
|
+
* `root` inside `allowed`.
|
|
294
|
+
*
|
|
295
|
+
* Every circuit found here starts and ends at `root`, and `root` is the least
|
|
296
|
+
* node of `allowed` by construction, which is where the rotation guarantee in
|
|
297
|
+
* the module docblock comes from.
|
|
298
|
+
*/
|
|
299
|
+
function enumerateCircuitsFrom(root, adjacency, allowed, search) {
|
|
300
|
+
const blocked = new Set([root]);
|
|
301
|
+
const blockedBy = new Map();
|
|
302
|
+
const path = [root];
|
|
303
|
+
// `neighbors` rides the frame: the list is fixed for a node, while this loop
|
|
304
|
+
// re-enters per DFS STEP — ~2.6M iterations against 395k pushes on this
|
|
305
|
+
// repository, so looking it up per iteration re-hashes the path each time.
|
|
306
|
+
const frames = [
|
|
307
|
+
{ node: root, nextIndex: 0, foundCircuit: false, neighbors: adjacency.get(root) ?? [] },
|
|
308
|
+
];
|
|
309
|
+
while (frames.length > 0) {
|
|
310
|
+
// Budget spent: return rather than unwind. Everything this function owns is
|
|
311
|
+
// local and it returns void, so draining the stack would run the full
|
|
312
|
+
// `blockedBy` bookkeeping (or an `unblock` walk) per frame, to no effect,
|
|
313
|
+
// on exactly the graphs already judged too expensive.
|
|
314
|
+
if (search.exceeded !== null)
|
|
315
|
+
return;
|
|
316
|
+
const frame = frames[frames.length - 1];
|
|
317
|
+
const neighbors = frame.neighbors;
|
|
318
|
+
if (frame.nextIndex < neighbors.length) {
|
|
319
|
+
const next = neighbors[frame.nextIndex];
|
|
320
|
+
frame.nextIndex += 1;
|
|
321
|
+
if (overBudget(search))
|
|
322
|
+
continue;
|
|
323
|
+
if (!allowed.has(next))
|
|
324
|
+
continue;
|
|
325
|
+
if (next === root) {
|
|
326
|
+
// `path` is the elementary path root -> ... -> frame.node; closing it
|
|
327
|
+
// back onto the root yields the cycle in the documented shape. A
|
|
328
|
+
// self-import lands here on the first step with path === [root].
|
|
329
|
+
search.cycles.push([...path, root]);
|
|
330
|
+
frame.foundCircuit = true;
|
|
331
|
+
// One-past, matching the edge-limit guard in `check`: `cycleLimit`
|
|
332
|
+
// cycles is an acceptable answer, and it takes finding one MORE to
|
|
333
|
+
// prove the graph overflowed. Stopping at `>= cycleLimit` would fail a
|
|
334
|
+
// graph that has exactly that many cycles and could have been reported
|
|
335
|
+
// in full.
|
|
336
|
+
//
|
|
337
|
+
// Tested before the emission charge so that a graph over both bounds
|
|
338
|
+
// reports the cycle cap, which is the one a reader can act on, rather
|
|
339
|
+
// than whichever happened to trip first.
|
|
340
|
+
if (search.cycles.length > search.cycleLimit) {
|
|
341
|
+
search.exceeded = 'cycles';
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
// A found cycle is not merely traversed: it is copied, retained until
|
|
345
|
+
// the call returns, sorted, and serialized into an MCP response. So it
|
|
346
|
+
// is charged at EMITTED_NODE_COST per node, not 1. This is what bounds
|
|
347
|
+
// MEMORY as well as time — 10,000 cycles is a modest cap when cycles
|
|
348
|
+
// are four files long and a heap-exhausting one when a single strongly
|
|
349
|
+
// connected component is 50,000 files around.
|
|
350
|
+
overBudget(search, (path.length + 1) * EMITTED_NODE_COST);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (!blocked.has(next)) {
|
|
354
|
+
blocked.add(next);
|
|
355
|
+
path.push(next);
|
|
356
|
+
frames.push({
|
|
357
|
+
node: next,
|
|
358
|
+
nextIndex: 0,
|
|
359
|
+
foundCircuit: false,
|
|
360
|
+
neighbors: adjacency.get(next) ?? [],
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
// Leaving `frame.node`. If it reached the root, it may lie on further
|
|
366
|
+
// circuits, so it and its waiters go back in play. If it did not, it is
|
|
367
|
+
// recorded as a dead end on each of its successors: it stays blocked until
|
|
368
|
+
// one of them is unblocked, which is the pruning that makes Johnson's
|
|
369
|
+
// output-sensitive rather than exponential in the graph size.
|
|
370
|
+
frames.pop();
|
|
371
|
+
path.pop();
|
|
372
|
+
if (frame.foundCircuit) {
|
|
373
|
+
unblock(frame.node, blocked, blockedBy);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
for (const next of neighbors) {
|
|
377
|
+
if (!allowed.has(next))
|
|
378
|
+
continue;
|
|
379
|
+
// `set` only when the entry is created: re-setting an existing key
|
|
380
|
+
// re-hashes the path string for no effect, and this runs once per
|
|
381
|
+
// out-edge of every unwound frame — measured at 1.06M redundant
|
|
382
|
+
// `Map.set` calls on this repository's own import graph.
|
|
383
|
+
let waiting = blockedBy.get(next);
|
|
384
|
+
if (waiting === undefined) {
|
|
385
|
+
waiting = new Set();
|
|
386
|
+
blockedBy.set(next, waiting);
|
|
387
|
+
}
|
|
388
|
+
waiting.add(frame.node);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (frames.length > 0 && frame.foundCircuit) {
|
|
392
|
+
frames[frames.length - 1].foundCircuit = true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Johnson's outer loop over one cyclic component: search the circuits rooted at
|
|
398
|
+
* the component's least node, drop that node, and repeat on whatever cyclic
|
|
399
|
+
* components the remainder falls into.
|
|
400
|
+
*
|
|
401
|
+
* Dropping the root is the whole rotation guarantee. Every cycle left after the
|
|
402
|
+
* drop consists of nodes greater than every root taken so far, so when the
|
|
403
|
+
* component holding it finally has that cycle's own minimum as its least node,
|
|
404
|
+
* the cycle is emitted once, rooted there. No other rotation is reachable,
|
|
405
|
+
* because the other rotations' starting nodes have already been excluded or are
|
|
406
|
+
* not the component's least.
|
|
407
|
+
*
|
|
408
|
+
* Re-decomposing the REMAINDER rather than the original node range also keeps
|
|
409
|
+
* each pass proportional to what is left: a tangle that falls apart when its
|
|
410
|
+
* busiest file is removed stops costing anything immediately.
|
|
411
|
+
*/
|
|
412
|
+
function enumerateComponentCycles(component, graph, search) {
|
|
413
|
+
// Components still to search. Pushed so that they pop in increasing order of
|
|
414
|
+
// least node — see the sort below.
|
|
415
|
+
const stack = [[...component]];
|
|
416
|
+
while (stack.length > 0 && search.exceeded === null) {
|
|
417
|
+
const current = stack.pop();
|
|
418
|
+
const root = leastNode(current);
|
|
419
|
+
// Scanning for the root and materializing the allowed set both cost one
|
|
420
|
+
// pass over the component, and both happen once per root, so they are the
|
|
421
|
+
// O(n^2) term on a component that never splits. Charged, or the budget
|
|
422
|
+
// would not see the work it exists to bound.
|
|
423
|
+
if (overBudget(search, current.length))
|
|
424
|
+
return;
|
|
425
|
+
enumerateCircuitsFrom(root, graph.adjacency, new Set(current), search);
|
|
426
|
+
if (search.exceeded !== null)
|
|
427
|
+
return;
|
|
428
|
+
const remaining = current.filter((node) => node !== root);
|
|
429
|
+
if (remaining.length === 0)
|
|
430
|
+
continue;
|
|
431
|
+
// Deliberately NOT re-sorted: the SCC set is independent of the order its
|
|
432
|
+
// roots are visited in, `leastNode` picks Johnson's root regardless, and
|
|
433
|
+
// the finished cycle list is sorted at the end. Sorting here would add an
|
|
434
|
+
// O(n log n) term to every root for no observable difference.
|
|
435
|
+
const decomposed = stronglyConnectedComponents(remaining, graph.adjacency, new Set(remaining), search);
|
|
436
|
+
// Same rule as above the call: once the budget is spent the `while` will
|
|
437
|
+
// refuse to pop whatever we push, so the filter/decorate/sort is waste.
|
|
438
|
+
if (search.exceeded !== null)
|
|
439
|
+
return;
|
|
440
|
+
const subComponents = decomposed
|
|
441
|
+
.filter((subComponent) => isCyclic(subComponent, graph.selfLoops))
|
|
442
|
+
.map((subComponent) => ({ least: leastNode(subComponent), nodes: subComponent }))
|
|
443
|
+
// Descending, so the stack pops them in increasing order of least node —
|
|
444
|
+
// Johnson's root order, and what makes a budget-stopped run stop at a
|
|
445
|
+
// deterministic point rather than wherever iteration happened to be.
|
|
446
|
+
.sort((a, b) => -compareCodeUnits(a.least, b.least));
|
|
447
|
+
for (const subComponent of subComponents)
|
|
448
|
+
stack.push(subComponent.nodes);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* The shortest cycle through a component's least node, by breadth-first search
|
|
453
|
+
* across the component.
|
|
454
|
+
*
|
|
455
|
+
* This is the fallback when a bound stops the full enumeration: one concrete,
|
|
456
|
+
* checkable cycle naming each tangle. It is also exactly what this module
|
|
457
|
+
* returned for every component before elementary enumeration existed, so the
|
|
458
|
+
* degraded answer is no worse than the old complete answer.
|
|
459
|
+
*
|
|
460
|
+
* Linear in the component, and it runs only after the decomposition has already
|
|
461
|
+
* succeeded, so it cannot fail the way the enumeration did. The budget is
|
|
462
|
+
*/
|
|
463
|
+
function representativeCycle(component, adjacency) {
|
|
2
464
|
const allowed = new Set(component);
|
|
3
|
-
const start = component
|
|
465
|
+
const start = leastNode(component);
|
|
4
466
|
const parents = new Map([[start, null]]);
|
|
5
467
|
const queue = [start];
|
|
6
468
|
for (let index = 0; index < queue.length; index += 1) {
|
|
@@ -24,80 +486,67 @@ function findCyclePath(component, adjacency) {
|
|
|
24
486
|
queue.push(next);
|
|
25
487
|
}
|
|
26
488
|
}
|
|
27
|
-
|
|
489
|
+
// Unreachable: every component reaching here is cyclic, and BFS from its
|
|
490
|
+
// least node inside the component must close. Thrown rather than returned
|
|
491
|
+
// empty so a future change that breaks the invariant is loud.
|
|
492
|
+
throw new Error('Invariant violation: no cycle found through cyclic component root.');
|
|
493
|
+
}
|
|
494
|
+
/** Element-wise lexicographic order, so the finished list is byte-stable. */
|
|
495
|
+
function compareCycles(left, right) {
|
|
496
|
+
const shared = Math.min(left.length, right.length);
|
|
497
|
+
for (let index = 0; index < shared; index += 1) {
|
|
498
|
+
const order = compareCodeUnits(left[index], right[index]);
|
|
499
|
+
if (order !== 0)
|
|
500
|
+
return order;
|
|
501
|
+
}
|
|
502
|
+
return left.length - right.length;
|
|
28
503
|
}
|
|
29
504
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
505
|
+
* Enumerate every elementary cycle in the file import graph.
|
|
506
|
+
*
|
|
507
|
+
* The result is discriminated on `enumeration`; see `ImportCycleReport` for
|
|
508
|
+
* what each variant carries. Past either bound the enumeration is discarded
|
|
509
|
+
* rather than truncated — see the module docblock for the algorithm, the
|
|
510
|
+
* rotation rule, and why a partial cycle list is not a safe thing to return.
|
|
32
511
|
*/
|
|
33
|
-
export function findImportCycles(edges) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
for (const [source, targets] of sortedAdjacency) {
|
|
49
|
-
for (const target of targets)
|
|
50
|
-
reverseAdjacency.get(target).push(source);
|
|
51
|
-
}
|
|
52
|
-
for (const sources of reverseAdjacency.values())
|
|
53
|
-
sources.sort();
|
|
54
|
-
const visited = new Set();
|
|
55
|
-
const finishOrder = [];
|
|
56
|
-
const components = [];
|
|
57
|
-
for (const start of [...sortedAdjacency.keys()].sort()) {
|
|
58
|
-
if (visited.has(start))
|
|
59
|
-
continue;
|
|
60
|
-
visited.add(start);
|
|
61
|
-
const stack = [{ node: start, nextIndex: 0 }];
|
|
62
|
-
while (stack.length > 0) {
|
|
63
|
-
const frame = stack[stack.length - 1];
|
|
64
|
-
const neighbors = sortedAdjacency.get(frame.node) ?? [];
|
|
65
|
-
if (frame.nextIndex < neighbors.length) {
|
|
66
|
-
const next = neighbors[frame.nextIndex++];
|
|
67
|
-
if (!visited.has(next)) {
|
|
68
|
-
visited.add(next);
|
|
69
|
-
stack.push({ node: next, nextIndex: 0 });
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
finishOrder.push(frame.node);
|
|
74
|
-
stack.pop();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
512
|
+
export function findImportCycles(edges, cycleLimit = IMPORT_CYCLE_LIMIT, workLimit = IMPORT_CYCLE_WORK_LIMIT) {
|
|
513
|
+
const graph = buildGraph(edges);
|
|
514
|
+
const allNodes = new Set(graph.nodes);
|
|
515
|
+
const search = { cycles: [], cycleLimit, workLimit, work: 0, exceeded: null };
|
|
516
|
+
const decomposition = stronglyConnectedComponents(graph.nodes, graph.adjacency, allNodes, search);
|
|
517
|
+
// Only a decomposition that ran to completion has a trustworthy count; one
|
|
518
|
+
// abandoned mid-pass would undercount silently.
|
|
519
|
+
const decompositionComplete = search.exceeded === null;
|
|
520
|
+
const cyclicComponents = decomposition
|
|
521
|
+
.filter((component) => isCyclic(component, graph.selfLoops))
|
|
522
|
+
.sort(byLeastNode);
|
|
523
|
+
for (const component of cyclicComponents) {
|
|
524
|
+
if (search.exceeded !== null)
|
|
525
|
+
break;
|
|
526
|
+
enumerateComponentCycles(component, graph, search);
|
|
77
527
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
component
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
component.sort();
|
|
97
|
-
components.push(component);
|
|
528
|
+
if (search.exceeded !== null) {
|
|
529
|
+
const reason = search.exceeded;
|
|
530
|
+
const limit = reason === 'cycles' ? cycleLimit : workLimit;
|
|
531
|
+
if (!decompositionComplete)
|
|
532
|
+
return { enumeration: 'none', reason, limit };
|
|
533
|
+
// Whatever the abandoned enumeration accumulated is discarded — it is a
|
|
534
|
+
// partial list of elementary cycles and would read as a complete one.
|
|
535
|
+
// Representatives are a different KIND of list, one per component, and the
|
|
536
|
+
// report says so in the type.
|
|
537
|
+
return {
|
|
538
|
+
enumeration: 'component-representatives',
|
|
539
|
+
cycles: cyclicComponents
|
|
540
|
+
.map((component) => representativeCycle(component, graph.adjacency))
|
|
541
|
+
.sort(compareCycles),
|
|
542
|
+
componentCount: cyclicComponents.length,
|
|
543
|
+
reason,
|
|
544
|
+
limit,
|
|
545
|
+
};
|
|
98
546
|
}
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
.sort(
|
|
102
|
-
.
|
|
547
|
+
return {
|
|
548
|
+
enumeration: 'complete',
|
|
549
|
+
cycles: search.cycles.sort(compareCycles),
|
|
550
|
+
componentCount: cyclicComponents.length,
|
|
551
|
+
};
|
|
103
552
|
}
|
|
@@ -25,6 +25,17 @@ export interface KnowledgeGraph {
|
|
|
25
25
|
iterRelationshipsByType: (type: RelationshipType) => IterableIterator<GraphRelationship>;
|
|
26
26
|
forEachNode: (fn: (node: GraphNode) => void) => void;
|
|
27
27
|
forEachRelationship: (fn: (rel: GraphRelationship) => void) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Zero-allocation relationship scan: fields, not objects (#2680).
|
|
30
|
+
*
|
|
31
|
+
* The whole-graph scans (the local-symbol pruner, community detection,
|
|
32
|
+
* process extraction) read only these four fields, and materializing a
|
|
33
|
+
* `GraphRelationship` per edge just to read them dominates iteration cost once
|
|
34
|
+
* relationships are held columnar — measured at ~90 ms per analyze on a
|
|
35
|
+
* million-edge graph. Prefer this over `forEachRelationship` in any pass that
|
|
36
|
+
* walks every edge and needs no other field.
|
|
37
|
+
*/
|
|
38
|
+
forEachRelationshipFields: (fn: (sourceId: string, targetId: string, type: RelationshipType, confidence: number) => void) => void;
|
|
28
39
|
getNode: (id: string) => GraphNode | undefined;
|
|
29
40
|
nodeCount: number;
|
|
30
41
|
relationshipCount: number;
|
|
@@ -32,5 +43,12 @@ export interface KnowledgeGraph {
|
|
|
32
43
|
addRelationship: (relationship: GraphRelationship) => void;
|
|
33
44
|
removeNode: (nodeId: string) => boolean;
|
|
34
45
|
removeNodesByFile: (filePath: string) => number;
|
|
46
|
+
/**
|
|
47
|
+
* Removes the relationship with this id, returning whether it existed.
|
|
48
|
+
*
|
|
49
|
+
* Implementations that offload relationships out of memory cannot always tell
|
|
50
|
+
* "absent" from "already written out" — `GraphEmitSink` deliberately throws
|
|
51
|
+
* rather than answering `false` for an edge it can no longer recall (#2680).
|
|
52
|
+
*/
|
|
35
53
|
removeRelationship: (relationshipId: string) => boolean;
|
|
36
54
|
}
|