gitnexus 1.6.9 → 1.6.10-aptos.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -53
- package/dist/_shared/graph/types.d.ts +67 -3
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +4 -3
- 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 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +2 -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 +8 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/pipeline.d.ts +1 -1
- package/dist/_shared/pipeline.d.ts.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/finalize-algorithm.d.ts +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +1 -0
- package/dist/_shared/scope-resolution/language-classification.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 +9 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +20 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +25 -44
- package/dist/cli/analyze.d.ts +5 -2
- package/dist/cli/analyze.js +205 -11
- package/dist/cli/clean.js +17 -3
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/doctor.d.ts +18 -0
- package/dist/cli/doctor.js +96 -5
- package/dist/cli/editor-targets.d.ts +17 -2
- package/dist/cli/editor-targets.js +44 -0
- package/dist/cli/embeddings.d.ts +12 -0
- package/dist/cli/embeddings.js +49 -0
- package/dist/cli/eval-server.d.ts +23 -1
- package/dist/cli/eval-server.js +126 -8
- package/dist/cli/help-i18n.js +6 -0
- package/dist/cli/i18n/en.d.ts +18 -8
- package/dist/cli/i18n/en.js +18 -8
- package/dist/cli/i18n/resources.d.ts +28 -8
- package/dist/cli/i18n/zh-CN.d.ts +10 -0
- package/dist/cli/i18n/zh-CN.js +18 -8
- package/dist/cli/index.js +21 -7
- 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/move-availability.d.ts +5 -0
- package/dist/cli/move-availability.js +11 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +230 -32
- package/dist/cli/skill-gen.js +38 -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.js +11 -0
- package/dist/cli/uninstall.js +77 -18
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +7 -1
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +27 -0
- package/dist/core/analysis-features.d.ts +21 -0
- package/dist/core/analysis-features.js +59 -0
- package/dist/core/analyzer-identity.d.ts +74 -0
- package/dist/core/analyzer-identity.js +1820 -0
- package/dist/core/augmentation/engine.js +13 -8
- package/dist/core/embeddings/embedder.d.ts +3 -2
- package/dist/core/embeddings/embedder.js +24 -7
- 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 +36 -1
- package/dist/core/embeddings/embedding-pipeline.js +100 -9
- package/dist/core/embeddings/http-client.d.ts +33 -3
- package/dist/core/embeddings/http-client.js +237 -25
- package/dist/core/embeddings/node-module-compat.d.ts +25 -0
- package/dist/core/embeddings/node-module-compat.js +25 -0
- package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
- package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
- package/dist/core/embeddings/runtime-install.d.ts +119 -0
- package/dist/core/embeddings/runtime-install.js +372 -0
- package/dist/core/embeddings/runtime-support.d.ts +48 -17
- package/dist/core/embeddings/runtime-support.js +96 -0
- package/dist/core/git-staleness.js +1 -1
- package/dist/core/group/bridge-db.js +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +246 -108
- package/dist/core/group/extractors/manifest-extractor.js +4 -0
- package/dist/core/incremental/escalation-gate.d.ts +38 -0
- package/dist/core/incremental/escalation-gate.js +48 -0
- package/dist/core/incremental/shadow-candidates.d.ts +3 -3
- package/dist/core/incremental/shadow-candidates.js +3 -3
- package/dist/core/incremental/subgraph-extract.d.ts +2 -2
- package/dist/core/incremental/subgraph-extract.js +2 -2
- package/dist/core/index-freshness.d.ts +5 -0
- package/dist/core/index-freshness.js +13 -0
- package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
- package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
- package/dist/core/ingestion/cobol-processor.js +27 -26
- package/dist/core/ingestion/community-processor.d.ts +51 -1
- package/dist/core/ingestion/community-processor.js +323 -64
- package/dist/core/ingestion/emit-references.js +7 -2
- package/dist/core/ingestion/filesystem-walker.js +4 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -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 +26 -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/languages/c/captures.js +56 -0
- package/dist/core/ingestion/languages/c/query.js +17 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
- package/dist/core/ingestion/languages/cobol/captures.js +93 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
- package/dist/core/ingestion/languages/cpp/captures.js +365 -75
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
- package/dist/core/ingestion/languages/csharp/captures.js +25 -0
- package/dist/core/ingestion/languages/dart/captures.js +90 -2
- 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.js +2 -0
- package/dist/core/ingestion/languages/go/captures.js +34 -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 +3 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
- package/dist/core/ingestion/languages/java/captures.js +193 -17
- 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 +23 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +23 -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-config-bindings.d.ts +23 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/javascript/captures.js +16 -0
- package/dist/core/ingestion/languages/javascript/query.js +21 -0
- 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 +129 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
- package/dist/core/ingestion/languages/kotlin/captures.js +59 -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 +19 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
- 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.js +5 -6
- package/dist/core/ingestion/languages/move.d.ts +1 -0
- package/dist/core/ingestion/languages/move.js +27 -0
- package/dist/core/ingestion/languages/php/captures.js +40 -0
- 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 +110 -2
- package/dist/core/ingestion/languages/php/interpret.js +10 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
- package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
- package/dist/core/ingestion/languages/python/captures.js +24 -5
- package/dist/core/ingestion/languages/python/interpret.js +4 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
- package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
- package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
- package/dist/core/ingestion/languages/ruby/captures.js +42 -0
- package/dist/core/ingestion/languages/rust/captures.js +13 -0
- package/dist/core/ingestion/languages/rust/interpret.js +18 -0
- package/dist/core/ingestion/languages/rust/query.js +9 -0
- package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
- package/dist/core/ingestion/languages/swift/captures.js +12 -0
- package/dist/core/ingestion/languages/typescript/captures.js +21 -0
- package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
- package/dist/core/ingestion/languages/typescript/query.js +37 -0
- package/dist/core/ingestion/markdown-processor.js +3 -2
- package/dist/core/ingestion/model/registration-table.js +1 -0
- package/dist/core/ingestion/parsing-processor.d.ts +3 -1
- package/dist/core/ingestion/parsing-processor.js +36 -1
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
- package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
- 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/standalone-ingest.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
- package/dist/core/ingestion/pipeline.d.ts +4 -2
- package/dist/core/ingestion/pipeline.js +14 -2
- package/dist/core/ingestion/resolve-references.js +12 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
- package/dist/core/ingestion/scope-extractor.js +306 -43
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
- 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 +3 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
- package/dist/core/ingestion/taint/typescript-model.js +34 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +23 -2
- package/dist/core/ingestion/type-extractors/jvm.js +17 -2
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
- package/dist/core/ingestion/utils/ast-helpers.js +153 -2
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
- package/dist/core/ingestion/utils/line-base.d.ts +20 -0
- package/dist/core/ingestion/utils/line-base.js +20 -0
- package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
- package/dist/core/ingestion/utils/symbol-labels.js +45 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
- package/dist/core/ingestion/workers/parse-worker.js +40 -5
- package/dist/core/ingestion/workers/result-merge.js +4 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
- package/dist/core/ingestion/workers/worker-pool.js +128 -28
- package/dist/core/lbug/csv-generator.d.ts +15 -0
- package/dist/core/lbug/csv-generator.js +124 -27
- package/dist/core/lbug/cypher-escape.d.ts +20 -0
- package/dist/core/lbug/cypher-escape.js +20 -0
- package/dist/core/lbug/extension-load-error.d.ts +67 -0
- package/dist/core/lbug/extension-load-error.js +326 -0
- package/dist/core/lbug/extension-loader.d.ts +17 -2
- package/dist/core/lbug/extension-loader.js +38 -13
- package/dist/core/lbug/lbug-adapter.d.ts +203 -2
- package/dist/core/lbug/lbug-adapter.js +527 -86
- package/dist/core/lbug/lbug-config.d.ts +56 -2
- package/dist/core/lbug/lbug-config.js +267 -7
- package/dist/core/lbug/move-columns.d.ts +7 -0
- package/dist/core/lbug/move-columns.js +86 -0
- package/dist/core/lbug/native-check.d.ts +40 -0
- package/dist/core/lbug/native-check.js +90 -0
- package/dist/core/lbug/node-table-layout.d.ts +29 -0
- package/dist/core/lbug/node-table-layout.js +119 -0
- package/dist/core/lbug/pool-adapter.d.ts +23 -1
- package/dist/core/lbug/pool-adapter.js +115 -8
- package/dist/core/lbug/schema.d.ts +4 -3
- package/dist/core/lbug/schema.js +16 -16
- package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
- package/dist/core/lbug/sidecar-recovery.js +418 -16
- package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
- package/dist/core/move/artifact-download.d.ts +19 -0
- package/dist/core/move/artifact-download.js +179 -0
- package/dist/core/move/compiler-facts.d.ts +120 -0
- package/dist/core/move/compiler-facts.js +9 -0
- package/dist/core/move/consistency.d.ts +74 -0
- package/dist/core/move/consistency.js +182 -0
- package/dist/core/move/constants.d.ts +98 -0
- package/dist/core/move/constants.js +136 -0
- package/dist/core/move/discovery.d.ts +10 -0
- package/dist/core/move/discovery.js +22 -0
- package/dist/core/move/entry-points.d.ts +14 -0
- package/dist/core/move/entry-points.js +40 -0
- package/dist/core/move/facts-mapper.d.ts +75 -0
- package/dist/core/move/facts-mapper.js +534 -0
- package/dist/core/move/install-lock.d.ts +14 -0
- package/dist/core/move/install-lock.js +102 -0
- package/dist/core/move/install.d.ts +39 -0
- package/dist/core/move/install.js +391 -0
- package/dist/core/move/mcp-client.d.ts +115 -0
- package/dist/core/move/mcp-client.js +436 -0
- package/dist/core/move/move-ingest.d.ts +52 -0
- package/dist/core/move/move-ingest.js +403 -0
- package/dist/core/move/provision.d.ts +19 -0
- package/dist/core/move/provision.js +91 -0
- package/dist/core/move/release.d.ts +6 -0
- package/dist/core/move/release.js +10 -0
- package/dist/core/move/symbol-id.d.ts +35 -0
- package/dist/core/move/symbol-id.js +65 -0
- package/dist/core/move/type-parser.d.ts +11 -0
- package/dist/core/move/type-parser.js +38 -0
- package/dist/core/platform/capabilities.d.ts +0 -1
- package/dist/core/platform/capabilities.js +39 -8
- package/dist/core/run-analyze.d.ts +9 -3
- package/dist/core/run-analyze.js +1002 -184
- package/dist/core/search/fts-indexes.d.ts +31 -0
- package/dist/core/search/fts-indexes.js +73 -0
- package/dist/core/search/fts-schema.js +2 -0
- package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
- package/dist/core/tree-sitter/safe-parse.js +21 -7
- package/dist/core/wiki/graph-queries.js +6 -5
- package/dist/core/wiki/llm-client.d.ts +8 -2
- package/dist/core/wiki/llm-client.js +41 -5
- package/dist/mcp/core/embedder.js +16 -2
- package/dist/mcp/http-transport.d.ts +5 -0
- package/dist/mcp/http-transport.js +19 -5
- package/dist/mcp/local/bean-metadata.d.ts +2 -0
- package/dist/mcp/local/bean-metadata.js +25 -0
- package/dist/mcp/local/line-display.d.ts +22 -0
- package/dist/mcp/local/line-display.js +3 -0
- package/dist/mcp/local/local-backend.d.ts +19 -1
- package/dist/mcp/local/local-backend.js +402 -155
- package/dist/mcp/local/pdg-impact.d.ts +5 -3
- package/dist/mcp/local/pdg-impact.js +5 -2
- 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 +34 -0
- package/dist/mcp/repository-policy.js +328 -0
- package/dist/mcp/resources.js +32 -5
- package/dist/mcp/server.d.ts +5 -2
- package/dist/mcp/server.js +29 -9
- package/dist/mcp/tools.d.ts +0 -8
- package/dist/mcp/tools.js +102 -5
- package/dist/server/analyze-job.d.ts +3 -0
- package/dist/server/analyze-job.js +17 -0
- package/dist/server/analyze-launch.d.ts +6 -0
- package/dist/server/analyze-launch.js +82 -6
- package/dist/server/analyze-worker-core.d.ts +2 -1
- package/dist/server/analyze-worker-core.js +5 -2
- package/dist/server/analyze-worker.js +29 -6
- package/dist/server/api.d.ts +30 -0
- package/dist/server/api.js +120 -34
- package/dist/server/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +4 -2
- package/dist/server/upload-ingest.js +2 -1
- package/dist/server/validation.js +2 -1
- package/dist/storage/git.d.ts +31 -0
- package/dist/storage/git.js +111 -1
- package/dist/storage/parse-cache.js +7 -1
- package/dist/storage/parsedfile-store.d.ts +8 -0
- package/dist/storage/parsedfile-store.js +165 -1
- package/dist/storage/repo-manager.d.ts +194 -2
- package/dist/storage/repo-manager.js +56 -1
- package/dist/types/pipeline.d.ts +7 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
- package/hooks/claude/gitnexus-hook.cjs +59 -9
- package/hooks/claude/pre-tool-use.sh +0 -0
- package/hooks/claude/session-start.sh +0 -0
- package/package.json +21 -15
- package/scripts/cross-platform-tests.ts +56 -0
- package/scripts/ensure-fts.ts +43 -0
- package/scripts/install-duckdb-extension.mjs +85 -24
- package/scripts/run-cross-platform.ts +61 -6
- package/scripts/shard-arg.ts +30 -0
- package/scripts/sync-plugin-manifests.mjs +192 -0
- package/skills/gitnexus-lfg/README.md +55 -0
- package/skills/gitnexus-lfg/SKILL.md +86 -0
- package/skills/gitnexus-plan/README.md +142 -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 +272 -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 +2084 -0
- package/skills/gitnexus-review/SKILL.md +273 -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-work/README.md +71 -0
- package/skills/gitnexus-work/SKILL.md +269 -0
- package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
- package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
- package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
- package/web/assets/agent-Bqxn-abU.js +626 -0
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
- package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
- package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
- package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
- package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
- package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
- package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
- package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
- package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
- package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
- package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
- package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
- package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
- package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
- package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
- package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
- package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
- package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
- package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
- package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
- package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
- package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
- package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
- package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
- package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
- package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
- package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
- package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
- package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
- package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
- package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
- package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
- package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
- package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
- package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
- package/web/assets/index-CX_fADmQ.css +2 -0
- package/web/assets/index-D1Z3dGGz.js +575 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
- package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
- package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
- package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
- package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
- package/web/assets/node-Ct_zna8U.js +8 -0
- package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
- package/web/assets/preload-helper-Czpn1I53.js +1 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
- package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
- package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
- package/web/assets/sdk-CzHHH8tD.js +37 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
- package/web/assets/src-JV30wyV8.js +1 -0
- package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
- package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
- package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
- package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
- package/web/index.html +18 -10
- package/skills/gitnexus-pr-review.md +0 -163
- package/web/assets/agent-Dli_x7bU.js +0 -660
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
- package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
- package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
- package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
- package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
- package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
- package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
- package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
- package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
- package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
- package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
- package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
- package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
- package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
- package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
- package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
- package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
- package/web/assets/index-KctnI3Vq.js +0 -635
- package/web/assets/index-_lgn7hs5.css +0 -2
- package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
- package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
- package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
- package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
- package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
- package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
- package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
- package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
- package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
- package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
- package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
- package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase: springConfig
|
|
3
|
+
*
|
|
4
|
+
* Adds key-only nodes for statically readable Spring
|
|
5
|
+
* `application*.properties` / `application*.yml` / `application*.yaml` files.
|
|
6
|
+
* Language-specific ScopeResolver hooks attach consumers later. Configuration
|
|
7
|
+
* values are deliberately never copied into the graph because they may contain
|
|
8
|
+
* credentials and key identity is sufficient for impact analysis.
|
|
9
|
+
*
|
|
10
|
+
* @deps structure
|
|
11
|
+
* @reads Spring application configuration files
|
|
12
|
+
* @writes Property nodes and DEFINES edges
|
|
13
|
+
*/
|
|
14
|
+
import fs from 'node:fs/promises';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
import { SPRING_CONFIG_DESCRIPTION } from '../frameworks/spring/config-bindings.js';
|
|
18
|
+
import { generateId } from '../../../lib/utils.js';
|
|
19
|
+
import { getPhaseOutput } from './types.js';
|
|
20
|
+
const require = createRequire(import.meta.url);
|
|
21
|
+
const yaml = require('js-yaml');
|
|
22
|
+
// js-yaml 5 dropped DEFAULT_SCHEMA; CORE plus these tags is what it used to be, so
|
|
23
|
+
// explicitly tagged values keep parsing instead of throwing (an unknown tag aborts
|
|
24
|
+
// the whole file). None of them can execute code.
|
|
25
|
+
const SPRING_YAML_SCHEMA = yaml.CORE_SCHEMA.withTags(yaml.mergeTag, yaml.timestampTag, yaml.binaryTag, yaml.omapTag, yaml.pairsTag, yaml.setTag);
|
|
26
|
+
const MAX_CONFIG_FILE_BYTES = 2 * 1024 * 1024;
|
|
27
|
+
const MAX_YAML_TRAVERSAL_DEPTH = 128;
|
|
28
|
+
const MAX_YAML_TRAVERSAL_NODES = 100_000;
|
|
29
|
+
/** Match only Spring Boot's conventional application config file names. */
|
|
30
|
+
export function classifySpringConfigFile(filePath) {
|
|
31
|
+
const base = path.posix.basename(filePath.replaceAll('\\', '/'));
|
|
32
|
+
const match = /^application(?:-([^.]+))?\.(properties|ya?ml)$/i.exec(base);
|
|
33
|
+
if (match === null)
|
|
34
|
+
return null;
|
|
35
|
+
return {
|
|
36
|
+
filePath,
|
|
37
|
+
...(match[1] ? { profile: match[1] } : {}),
|
|
38
|
+
format: match[2].toLowerCase() === 'properties' ? 'properties' : 'yaml',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function unescapePropertyKey(raw) {
|
|
42
|
+
return raw
|
|
43
|
+
.replace(/\\u([0-9a-fA-F]{4})/g, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
|
|
44
|
+
.replace(/\\([:=#!\\ ])/g, '$1');
|
|
45
|
+
}
|
|
46
|
+
function logicalPropertiesLines(content) {
|
|
47
|
+
const physical = content.split(/\r?\n/);
|
|
48
|
+
const logical = [];
|
|
49
|
+
let current = '';
|
|
50
|
+
let startLine = 1;
|
|
51
|
+
for (let index = 0; index < physical.length; index++) {
|
|
52
|
+
const line = physical[index];
|
|
53
|
+
if (current.length === 0)
|
|
54
|
+
startLine = index + 1;
|
|
55
|
+
current += current.length === 0 ? line : line.trimStart();
|
|
56
|
+
let trailingBackslashes = 0;
|
|
57
|
+
for (let cursor = current.length - 1; cursor >= 0 && current[cursor] === '\\'; cursor--) {
|
|
58
|
+
trailingBackslashes++;
|
|
59
|
+
}
|
|
60
|
+
if (trailingBackslashes % 2 === 1) {
|
|
61
|
+
current = current.slice(0, -1);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
logical.push({ text: current, line: startLine });
|
|
65
|
+
current = '';
|
|
66
|
+
}
|
|
67
|
+
if (current.length > 0)
|
|
68
|
+
logical.push({ text: current, line: startLine });
|
|
69
|
+
return logical;
|
|
70
|
+
}
|
|
71
|
+
/** Parse `.properties` keys without retaining their values. */
|
|
72
|
+
export function parseSpringProperties(content, filePath, profile) {
|
|
73
|
+
const keys = [];
|
|
74
|
+
const seen = new Set();
|
|
75
|
+
for (const logical of logicalPropertiesLines(content)) {
|
|
76
|
+
const trimmed = logical.text.trimStart();
|
|
77
|
+
if (trimmed.length === 0 || trimmed.startsWith('#') || trimmed.startsWith('!'))
|
|
78
|
+
continue;
|
|
79
|
+
let separator = -1;
|
|
80
|
+
let escaped = false;
|
|
81
|
+
for (let index = 0; index < trimmed.length; index++) {
|
|
82
|
+
const char = trimmed[index];
|
|
83
|
+
if (!escaped && (char === '=' || char === ':' || /\s/.test(char))) {
|
|
84
|
+
separator = index;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
escaped = !escaped && char === '\\';
|
|
88
|
+
if (char !== '\\')
|
|
89
|
+
escaped = false;
|
|
90
|
+
}
|
|
91
|
+
const rawKey = (separator === -1 ? trimmed : trimmed.slice(0, separator)).trim();
|
|
92
|
+
const key = unescapePropertyKey(rawKey);
|
|
93
|
+
if (key.length === 0 || seen.has(key))
|
|
94
|
+
continue;
|
|
95
|
+
seen.add(key);
|
|
96
|
+
keys.push({
|
|
97
|
+
key,
|
|
98
|
+
filePath,
|
|
99
|
+
line: logical.line,
|
|
100
|
+
...(profile ? { profile } : {}),
|
|
101
|
+
format: 'properties',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return keys;
|
|
105
|
+
}
|
|
106
|
+
function consumeYamlTraversalBudget(state, depth) {
|
|
107
|
+
if (depth > MAX_YAML_TRAVERSAL_DEPTH) {
|
|
108
|
+
throw new Error(`Spring YAML traversal depth exceeds ${MAX_YAML_TRAVERSAL_DEPTH}`);
|
|
109
|
+
}
|
|
110
|
+
state.remainingNodes--;
|
|
111
|
+
if (state.remainingNodes < 0) {
|
|
112
|
+
throw new Error(`Spring YAML traversal exceeds ${MAX_YAML_TRAVERSAL_NODES} nodes`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function isObjectValue(value) {
|
|
116
|
+
return value !== null && typeof value === 'object';
|
|
117
|
+
}
|
|
118
|
+
// Aliases are resolved to their anchor event by name while the tree is built,
|
|
119
|
+
// so following one here is a single pointer hop.
|
|
120
|
+
function resolveYamlAliasEvent(event) {
|
|
121
|
+
return event?.aliasOf ?? event;
|
|
122
|
+
}
|
|
123
|
+
function yamlMappingPairs(event) {
|
|
124
|
+
const pairs = [];
|
|
125
|
+
for (let index = 0; index + 1 < event.children.length; index += 2) {
|
|
126
|
+
const keyEvent = event.children[index];
|
|
127
|
+
const valueEvent = event.children[index + 1];
|
|
128
|
+
if (keyEvent.kind !== 'scalar')
|
|
129
|
+
continue;
|
|
130
|
+
pairs.push({ key: String(keyEvent.result), keyEvent, valueEvent });
|
|
131
|
+
}
|
|
132
|
+
return pairs;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* First match in a pre-order walk of `event`, following sequences and `<<` merge
|
|
136
|
+
* chains. Iterative: children are pushed in reverse so the explicit stack pops
|
|
137
|
+
* them in declaration order, which is what makes "first match" mean the same
|
|
138
|
+
* thing it did when this recursed.
|
|
139
|
+
*/
|
|
140
|
+
function findYamlMappingLocation(event, key, traversal) {
|
|
141
|
+
const visited = new Set();
|
|
142
|
+
const stack = [{ event, depth: 0 }];
|
|
143
|
+
while (stack.length > 0) {
|
|
144
|
+
const step = stack.pop();
|
|
145
|
+
if (step === undefined)
|
|
146
|
+
break;
|
|
147
|
+
consumeYamlTraversalBudget(traversal, step.depth);
|
|
148
|
+
const resolved = resolveYamlAliasEvent(step.event);
|
|
149
|
+
if (resolved === undefined || visited.has(resolved))
|
|
150
|
+
continue;
|
|
151
|
+
visited.add(resolved);
|
|
152
|
+
if (resolved.kind === 'sequence') {
|
|
153
|
+
for (let index = resolved.children.length - 1; index >= 0; index--) {
|
|
154
|
+
stack.push({ event: resolved.children[index], depth: step.depth + 1 });
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (resolved.kind !== 'mapping')
|
|
159
|
+
continue;
|
|
160
|
+
const pairs = yamlMappingPairs(resolved);
|
|
161
|
+
const direct = pairs.find((pair) => pair.key === key);
|
|
162
|
+
if (direct !== undefined) {
|
|
163
|
+
return { valueEvent: direct.valueEvent, line: direct.keyEvent.startLine };
|
|
164
|
+
}
|
|
165
|
+
const merges = pairs.filter((pair) => pair.key === '<<');
|
|
166
|
+
for (let index = merges.length - 1; index >= 0; index--) {
|
|
167
|
+
stack.push({ event: merges[index].valueEvent, depth: step.depth + 1 });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Flatten a document to `dotted.key -> line`, iteratively. Children are pushed in
|
|
174
|
+
* reverse so the stack pops them in declaration order, keeping `out` in the same
|
|
175
|
+
* insertion order — and the traversal budget consumed in the same sequence — as
|
|
176
|
+
* the recursive walk this replaced.
|
|
177
|
+
*/
|
|
178
|
+
function flattenYamlValue(value, event, prefix, out, traversal) {
|
|
179
|
+
const stack = [
|
|
180
|
+
{ kind: 'visit', value, event, prefix, sourceLine: event?.startLine ?? 1, depth: 0 },
|
|
181
|
+
];
|
|
182
|
+
while (stack.length > 0) {
|
|
183
|
+
const step = stack.pop();
|
|
184
|
+
if (step === undefined)
|
|
185
|
+
break;
|
|
186
|
+
if (step.kind === 'leave') {
|
|
187
|
+
traversal.activeObjects.delete(step.object);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const { value: current, prefix: currentPrefix, sourceLine, depth } = step;
|
|
191
|
+
consumeYamlTraversalBudget(traversal, depth);
|
|
192
|
+
const resolvedEvent = resolveYamlAliasEvent(step.event);
|
|
193
|
+
const trackedObject = isObjectValue(current) ? current : undefined;
|
|
194
|
+
if (trackedObject !== undefined) {
|
|
195
|
+
if (traversal.activeObjects.has(trackedObject))
|
|
196
|
+
continue;
|
|
197
|
+
traversal.activeObjects.add(trackedObject);
|
|
198
|
+
stack.push({ kind: 'leave', object: trackedObject });
|
|
199
|
+
}
|
|
200
|
+
if (Array.isArray(current)) {
|
|
201
|
+
if (current.length === 0 && currentPrefix.length > 0 && !out.has(currentPrefix)) {
|
|
202
|
+
out.set(currentPrefix, sourceLine);
|
|
203
|
+
}
|
|
204
|
+
for (let index = current.length - 1; index >= 0; index--) {
|
|
205
|
+
stack.push({
|
|
206
|
+
kind: 'visit',
|
|
207
|
+
value: current[index],
|
|
208
|
+
event: resolvedEvent?.children[index],
|
|
209
|
+
prefix: `${currentPrefix}[${index}]`,
|
|
210
|
+
sourceLine,
|
|
211
|
+
depth: depth + 1,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (current !== null &&
|
|
217
|
+
typeof current === 'object' &&
|
|
218
|
+
(resolvedEvent?.kind === 'mapping' || resolvedEvent === undefined)) {
|
|
219
|
+
// js-yaml 5 builds `!!set` as a native Set, whose members are not own
|
|
220
|
+
// properties; v4 built a plain `{member: null}` object. Enumerate them so a
|
|
221
|
+
// tagged set still contributes one key per member instead of a bare leaf.
|
|
222
|
+
const entries = current instanceof Set
|
|
223
|
+
? [...current].map((member) => [String(member), null])
|
|
224
|
+
: Object.entries(current);
|
|
225
|
+
if (entries.length === 0 && currentPrefix.length > 0 && !out.has(currentPrefix)) {
|
|
226
|
+
out.set(currentPrefix, sourceLine);
|
|
227
|
+
}
|
|
228
|
+
for (let index = entries.length - 1; index >= 0; index--) {
|
|
229
|
+
const [key, nested] = entries[index];
|
|
230
|
+
const location = findYamlMappingLocation(resolvedEvent, key, traversal);
|
|
231
|
+
stack.push({
|
|
232
|
+
kind: 'visit',
|
|
233
|
+
value: nested,
|
|
234
|
+
event: location?.valueEvent,
|
|
235
|
+
prefix: currentPrefix.length === 0 ? key : `${currentPrefix}.${key}`,
|
|
236
|
+
sourceLine: location?.line ?? sourceLine,
|
|
237
|
+
depth: depth + 1,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (currentPrefix.length > 0 && !out.has(currentPrefix))
|
|
243
|
+
out.set(currentPrefix, sourceLine);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// js-yaml 5 reports node positions as source offsets; map them to 1-based lines.
|
|
247
|
+
function makeLineResolver(source) {
|
|
248
|
+
const lineStarts = [0];
|
|
249
|
+
for (let index = 0; index < source.length; index++) {
|
|
250
|
+
if (source[index] === '\n')
|
|
251
|
+
lineStarts.push(index + 1);
|
|
252
|
+
}
|
|
253
|
+
return (offset) => {
|
|
254
|
+
let low = 0;
|
|
255
|
+
let high = lineStarts.length - 1;
|
|
256
|
+
let line = 0;
|
|
257
|
+
while (low <= high) {
|
|
258
|
+
const mid = (low + high) >> 1;
|
|
259
|
+
if (lineStarts[mid] <= offset) {
|
|
260
|
+
line = mid;
|
|
261
|
+
low = mid + 1;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
high = mid - 1;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return line + 1;
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Rebuild the parse tree from js-yaml 5's event stream (v4's `listener` option
|
|
272
|
+
* was removed). Returns each document's root event, with aliases already
|
|
273
|
+
* resolved to their anchor event so merged/aliased keys keep the line where
|
|
274
|
+
* they were declared.
|
|
275
|
+
*
|
|
276
|
+
* One node per event, so this pass is bounded by MAX_CONFIG_FILE_BYTES alone —
|
|
277
|
+
* MAX_YAML_TRAVERSAL_NODES governs the later walk, which can revisit a shared
|
|
278
|
+
* anchor many times and so needs a budget this linear pass does not.
|
|
279
|
+
*/
|
|
280
|
+
function buildYamlEventTree(events, source) {
|
|
281
|
+
const lineOf = makeLineResolver(source);
|
|
282
|
+
const anchors = new Map();
|
|
283
|
+
const stack = [];
|
|
284
|
+
const documentRoots = [];
|
|
285
|
+
const anchorName = (start, end) => start >= 0 && end > start ? source.slice(start, end) : null;
|
|
286
|
+
const attach = (node) => {
|
|
287
|
+
stack[stack.length - 1]?.children.push(node);
|
|
288
|
+
};
|
|
289
|
+
const register = (name, node) => {
|
|
290
|
+
if (name !== null)
|
|
291
|
+
anchors.set(name, node);
|
|
292
|
+
};
|
|
293
|
+
for (const event of events) {
|
|
294
|
+
switch (event.type) {
|
|
295
|
+
case yaml.EVENT_DOCUMENT:
|
|
296
|
+
// Anchors are document-scoped. constructFromEvents already rejects a
|
|
297
|
+
// cross-document alias before we get here, so this only keeps the two
|
|
298
|
+
// layers from disagreeing.
|
|
299
|
+
anchors.clear();
|
|
300
|
+
stack.push({
|
|
301
|
+
startLine: 1,
|
|
302
|
+
kind: null,
|
|
303
|
+
result: undefined,
|
|
304
|
+
aliasOf: undefined,
|
|
305
|
+
children: [],
|
|
306
|
+
});
|
|
307
|
+
break;
|
|
308
|
+
case yaml.EVENT_MAPPING:
|
|
309
|
+
case yaml.EVENT_SEQUENCE: {
|
|
310
|
+
const node = {
|
|
311
|
+
startLine: lineOf(event.start),
|
|
312
|
+
kind: event.type === yaml.EVENT_MAPPING ? 'mapping' : 'sequence',
|
|
313
|
+
result: undefined,
|
|
314
|
+
aliasOf: undefined,
|
|
315
|
+
children: [],
|
|
316
|
+
};
|
|
317
|
+
register(anchorName(event.anchorStart, event.anchorEnd), node);
|
|
318
|
+
attach(node);
|
|
319
|
+
stack.push(node);
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case yaml.EVENT_SCALAR: {
|
|
323
|
+
const node = {
|
|
324
|
+
startLine: lineOf(event.valueStart),
|
|
325
|
+
kind: 'scalar',
|
|
326
|
+
result: yaml.getScalarValue(source, event),
|
|
327
|
+
aliasOf: undefined,
|
|
328
|
+
children: [],
|
|
329
|
+
};
|
|
330
|
+
register(anchorName(event.anchorStart, event.anchorEnd), node);
|
|
331
|
+
attach(node);
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
case yaml.EVENT_ALIAS: {
|
|
335
|
+
const target = anchors.get(anchorName(event.anchorStart, event.anchorEnd) ?? '');
|
|
336
|
+
attach({ startLine: 1, kind: 'alias', result: undefined, aliasOf: target, children: [] });
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
case yaml.EVENT_POP: {
|
|
340
|
+
const done = stack.pop();
|
|
341
|
+
// Documents are the only top-level containers, so a pop that empties the
|
|
342
|
+
// stack closes a document; its single child is the document's root value.
|
|
343
|
+
if (done !== undefined && stack.length === 0)
|
|
344
|
+
documentRoots.push(done.children[0]);
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return documentRoots;
|
|
350
|
+
}
|
|
351
|
+
/** Parse and flatten YAML leaves without retaining their values. */
|
|
352
|
+
export function parseSpringYaml(content, filePath, profile) {
|
|
353
|
+
const flattened = new Map();
|
|
354
|
+
const traversal = {
|
|
355
|
+
remainingNodes: MAX_YAML_TRAVERSAL_NODES,
|
|
356
|
+
activeObjects: new Set(),
|
|
357
|
+
};
|
|
358
|
+
const events = yaml.parseEvents(content, { maxDepth: MAX_YAML_TRAVERSAL_DEPTH });
|
|
359
|
+
const documents = yaml.constructFromEvents(events, {
|
|
360
|
+
source: content,
|
|
361
|
+
schema: SPRING_YAML_SCHEMA,
|
|
362
|
+
json: true,
|
|
363
|
+
});
|
|
364
|
+
const documentEvents = buildYamlEventTree(events, content);
|
|
365
|
+
documents.forEach((document, index) => flattenYamlValue(document, documentEvents[index], '', flattened, traversal));
|
|
366
|
+
return [...flattened.entries()]
|
|
367
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
368
|
+
.map(([key, line]) => ({
|
|
369
|
+
key,
|
|
370
|
+
filePath,
|
|
371
|
+
line,
|
|
372
|
+
...(profile ? { profile } : {}),
|
|
373
|
+
format: 'yaml',
|
|
374
|
+
}));
|
|
375
|
+
}
|
|
376
|
+
function configKeyNodeId(entry) {
|
|
377
|
+
return generateId('Property', `spring-config:${entry.filePath}:${entry.key}`);
|
|
378
|
+
}
|
|
379
|
+
async function readConfigKeys(repoPath, scannedFiles) {
|
|
380
|
+
const keys = [];
|
|
381
|
+
for (const scanned of scannedFiles) {
|
|
382
|
+
const classified = classifySpringConfigFile(scanned.path);
|
|
383
|
+
if (classified === null || scanned.size > MAX_CONFIG_FILE_BYTES)
|
|
384
|
+
continue;
|
|
385
|
+
try {
|
|
386
|
+
const content = await fs.readFile(path.join(repoPath, scanned.path), 'utf8');
|
|
387
|
+
keys.push(...(classified.format === 'properties'
|
|
388
|
+
? parseSpringProperties(content, classified.filePath, classified.profile)
|
|
389
|
+
: parseSpringYaml(content, classified.filePath, classified.profile)));
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
// Malformed configuration is not a reason to fail the entire code index.
|
|
393
|
+
// Fail closed: no keys and therefore no misleading bindings for this file.
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return keys;
|
|
397
|
+
}
|
|
398
|
+
export const springConfigPhase = {
|
|
399
|
+
name: 'springConfig',
|
|
400
|
+
deps: ['structure'],
|
|
401
|
+
async execute(ctx, deps) {
|
|
402
|
+
const { scannedFiles } = getPhaseOutput(deps, 'structure');
|
|
403
|
+
const configKeys = await readConfigKeys(ctx.repoPath, scannedFiles);
|
|
404
|
+
for (const entry of configKeys) {
|
|
405
|
+
const nodeId = configKeyNodeId(entry);
|
|
406
|
+
ctx.graph.addNode({
|
|
407
|
+
id: nodeId,
|
|
408
|
+
label: 'Property',
|
|
409
|
+
properties: {
|
|
410
|
+
name: entry.key,
|
|
411
|
+
filePath: entry.filePath,
|
|
412
|
+
startLine: entry.line,
|
|
413
|
+
endLine: entry.line,
|
|
414
|
+
description: entry.profile
|
|
415
|
+
? `${SPRING_CONFIG_DESCRIPTION} (profile: ${entry.profile})`
|
|
416
|
+
: SPRING_CONFIG_DESCRIPTION,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
const fileId = generateId('File', entry.filePath);
|
|
420
|
+
if (ctx.graph.getNode(fileId) !== undefined) {
|
|
421
|
+
ctx.graph.addRelationship({
|
|
422
|
+
id: generateId('DEFINES', `${fileId}->${nodeId}`),
|
|
423
|
+
sourceId: fileId,
|
|
424
|
+
targetId: nodeId,
|
|
425
|
+
type: 'DEFINES',
|
|
426
|
+
confidence: 1,
|
|
427
|
+
reason: 'spring-config:key',
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return { configKeys: configKeys.length };
|
|
432
|
+
},
|
|
433
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PipelinePhase } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared output contract for compiler-backed or otherwise standalone ingesters.
|
|
4
|
+
* Claimed files are excluded from the generic parser to prevent duplicate nodes.
|
|
5
|
+
*/
|
|
6
|
+
export interface StandaloneIngestOutput {
|
|
7
|
+
readonly ingestedFiles: ReadonlySet<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Operator-actionable warnings the ingester wants surfaced in the persistent
|
|
10
|
+
* CLI summary (e.g. a package it had to skip or ingest at degraded fidelity).
|
|
11
|
+
* Language-neutral: the pipeline passes these through without interpreting.
|
|
12
|
+
*/
|
|
13
|
+
readonly ingestWarnings?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/** Default no-op used when the caller does not supply a standalone ingester. */
|
|
16
|
+
export declare const emptyStandaloneIngestPhase: PipelinePhase<StandaloneIngestOutput>;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type PipelineProgress } from '../../_shared/index.js';
|
|
18
18
|
import { PipelineResult } from '../../types/pipeline.js';
|
|
19
|
-
import { type PipelinePhase } from './pipeline-phases/index.js';
|
|
19
|
+
import { type StandaloneIngestOutput, type PipelinePhase } from './pipeline-phases/index.js';
|
|
20
20
|
export interface PipelineOptions {
|
|
21
21
|
/**
|
|
22
22
|
* Skip MRO, community detection, and process extraction for faster test runs.
|
|
@@ -186,6 +186,8 @@ export interface PipelineOptions {
|
|
|
186
186
|
* `process.env` state across invocations. When undefined, the env var decides.
|
|
187
187
|
*/
|
|
188
188
|
keepLocalValueSymbols?: boolean;
|
|
189
|
+
/** Optional compiler-backed or otherwise standalone ingester. */
|
|
190
|
+
standaloneIngestPhase?: PipelinePhase<StandaloneIngestOutput>;
|
|
189
191
|
/**
|
|
190
192
|
* Extra fetch-wrapper function names to treat as HTTP consumers, threaded
|
|
191
193
|
* from `.gitnexusrc` `fetchWrappers` via `AnalyzeOptions` (#1589/#1852
|
|
@@ -201,7 +203,7 @@ export interface PipelineOptions {
|
|
|
201
203
|
*
|
|
202
204
|
* Phase dependency graph:
|
|
203
205
|
*
|
|
204
|
-
* scan → structure → [markdown, cobol] → parse → [routes, tools, orm]
|
|
206
|
+
* scan → structure → [standaloneIngest, springConfig, markdown, cobol] → parse → [routes, tools, orm]
|
|
205
207
|
* → crossFile → scopeResolution → pruneLocalSymbols
|
|
206
208
|
* → mro → di → communities → processes
|
|
207
209
|
*
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
* See ARCHITECTURE.md for the full phase dependency diagram.
|
|
16
16
|
*/
|
|
17
17
|
import { createKnowledgeGraph } from '../graph/graph.js';
|
|
18
|
-
import { runPipeline, getPhaseOutput, scanPhase, structurePhase, markdownPhase, cobolPhase, parsePhase, routesPhase, toolsPhase, ormPhase, crossFilePhase, scopeResolutionPhase, pruneLocalSymbolsPhase, taintSummariesPhase, callSummariesPhase, mroPhase, diPhase, communitiesPhase, processesPhase, PhaseRegistry, } from './pipeline-phases/index.js';
|
|
18
|
+
import { runPipeline, getPhaseOutput, scanPhase, structurePhase, emptyStandaloneIngestPhase, markdownPhase, cobolPhase, parsePhase, routesPhase, toolsPhase, ormPhase, crossFilePhase, scopeResolutionPhase, springConfigPhase, pruneLocalSymbolsPhase, taintSummariesPhase, callSummariesPhase, mroPhase, diPhase, communitiesPhase, processesPhase, PhaseRegistry, } from './pipeline-phases/index.js';
|
|
19
19
|
// ── Phase registry ─────────────────────────────────────────────────────────
|
|
20
20
|
/**
|
|
21
21
|
* All pipeline phases with their dependency relationships.
|
|
22
22
|
*
|
|
23
23
|
* Phase dependency graph:
|
|
24
24
|
*
|
|
25
|
-
* scan → structure → [markdown, cobol] → parse → [routes, tools, orm]
|
|
25
|
+
* scan → structure → [standaloneIngest, springConfig, markdown, cobol] → parse → [routes, tools, orm]
|
|
26
26
|
* → crossFile → scopeResolution → pruneLocalSymbols
|
|
27
27
|
* → mro → di → communities → processes
|
|
28
28
|
*
|
|
@@ -37,9 +37,12 @@ import { runPipeline, getPhaseOutput, scanPhase, structurePhase, markdownPhase,
|
|
|
37
37
|
* options combination.
|
|
38
38
|
*/
|
|
39
39
|
export function buildPhaseList(options) {
|
|
40
|
+
const { standaloneIngestPhase = emptyStandaloneIngestPhase } = options ?? {};
|
|
40
41
|
return (new PhaseRegistry()
|
|
41
42
|
.register(scanPhase)
|
|
42
43
|
.register(structurePhase)
|
|
44
|
+
.register(standaloneIngestPhase)
|
|
45
|
+
.register(springConfigPhase)
|
|
43
46
|
.register(markdownPhase)
|
|
44
47
|
.register(cobolPhase)
|
|
45
48
|
.register(parsePhase)
|
|
@@ -78,6 +81,14 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
|
78
81
|
const { totalFiles, usedWorkerPool } = getPhaseOutput(results, 'parse');
|
|
79
82
|
let communityResult;
|
|
80
83
|
let processResult;
|
|
84
|
+
// Standalone-ingest warnings, passed through opaquely (language-neutral).
|
|
85
|
+
let ingestWarnings;
|
|
86
|
+
try {
|
|
87
|
+
ingestWarnings = getPhaseOutput(results, 'standaloneIngest').ingestWarnings;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* phase filtered out of this run — nothing to surface */
|
|
91
|
+
}
|
|
81
92
|
const scopeResolutionOutput = getPhaseOutput(results, 'scopeResolution');
|
|
82
93
|
const resolutionOutcomes = scopeResolutionOutput.resolutionOutcomes;
|
|
83
94
|
// Streamed PDG-emit manifest (#2202): present only when streaming was on.
|
|
@@ -107,5 +118,6 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
|
107
118
|
resolutionOutcomes,
|
|
108
119
|
usedWorkerPool,
|
|
109
120
|
pdgEmitManifest,
|
|
121
|
+
ingestWarnings,
|
|
110
122
|
};
|
|
111
123
|
};
|
|
@@ -66,6 +66,12 @@ export function resolveReferenceSites(input) {
|
|
|
66
66
|
let referencesEmitted = 0;
|
|
67
67
|
let unresolved = 0;
|
|
68
68
|
for (const site of scopes.referenceSites) {
|
|
69
|
+
// value-ref sites resolve post-finalize (imports live in finalized
|
|
70
|
+
// bindings the registries can't see — same reason free calls need
|
|
71
|
+
// `emitFreeCallFallback`). `emitPropertyDispatchCalls` owns their
|
|
72
|
+
// resolution and emission entirely (#2437).
|
|
73
|
+
if (site.kind === 'value-ref')
|
|
74
|
+
continue;
|
|
69
75
|
sitesProcessed++;
|
|
70
76
|
const resolutions = lookupForSite(site, classRegistry, methodRegistry, fieldRegistry, macroRegistry);
|
|
71
77
|
if (resolutions.length === 0) {
|
|
@@ -113,6 +119,7 @@ export function resolveReferenceSites(input) {
|
|
|
113
119
|
* | `type-reference` | ClassRegistry | CLASS_KINDS |
|
|
114
120
|
* | `read`/`write` | FieldRegistry | FIELD_KINDS |
|
|
115
121
|
* | `import-use` | tiered fallback | METHOD ∪ CLASS ∪ FIELD |
|
|
122
|
+
* | `value-ref` | (skipped here) | post-finalize walker in `emitPropertyDispatchCalls` |
|
|
116
123
|
* | `macro` | MacroRegistry | MACRO_KINDS (`Macro` only) |
|
|
117
124
|
*
|
|
118
125
|
* `macro` has its own single-kind registry so a macro invocation
|
|
@@ -166,6 +173,11 @@ function lookupForSite(site, classRegistry, methodRegistry, fieldRegistry, macro
|
|
|
166
173
|
return methodHits;
|
|
167
174
|
return fieldRegistry.lookup(site.name, site.inScope);
|
|
168
175
|
}
|
|
176
|
+
case 'value-ref': {
|
|
177
|
+
// Unreachable — filtered before lookup (post-finalize resolution in
|
|
178
|
+
// `emitPropertyDispatchCalls`, #2437). Kept for switch exhaustiveness.
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
169
181
|
case 'macro': {
|
|
170
182
|
// Macro-only namespace: resolves against `Macro`-labeled defs, never
|
|
171
183
|
// functions. No receiver, no arity — see `MacroRegistry`.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language-agnostic string-constant folding for route-path resolution (#2391).
|
|
3
|
+
*
|
|
4
|
+
* Route decorators/annotations frequently build their path from a constant rather
|
|
5
|
+
* than a string literal — `@router.post(API_V1_WIDGETS_GET)` (Python),
|
|
6
|
+
* `@GetMapping(PathConstants.WIDGETS)` (Spring), and the Kotlin/C# equivalents are
|
|
7
|
+
* the same shape. This module folds such a constant — or an inline
|
|
8
|
+
* `+`-concatenation — to its literal value, following `+` operands and import
|
|
9
|
+
* chains across a repo-wide, file-keyed constant map.
|
|
10
|
+
*
|
|
11
|
+
* The FOLD is language-neutral: it walks {@link Operand} lists and
|
|
12
|
+
* {@link ModuleConstants} that ANY language's extractor can produce, and defers
|
|
13
|
+
* the one language-specific decision — mapping an import specifier to the file it
|
|
14
|
+
* refers to — to a caller-supplied {@link ImportResolver}. A language binding
|
|
15
|
+
* (e.g. `python-const-resolver.ts`) provides that resolver plus a tree →
|
|
16
|
+
* {@link ModuleConstants} extractor and, if wanted, thin pre-bound wrappers.
|
|
17
|
+
*
|
|
18
|
+
* This mirrors how `route-path.ts` (URL normalization) and `spring-shared.ts`
|
|
19
|
+
* (annotation primitives) are shared across the ingestion and group layers and
|
|
20
|
+
* across languages: the reusable core lives in one place; per-language semantics
|
|
21
|
+
* plug in. It deliberately does NOT reuse `ScopeResolver` (which resolves symbol
|
|
22
|
+
* IDENTITIES, not literal string VALUES) or the `--pdg` `REACHING_DEF` layer
|
|
23
|
+
* (intra-procedural, function-local, def→use reachability — not module-level
|
|
24
|
+
* cross-file value folding).
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* One term of a constant's right-hand side. A `+`-concatenation
|
|
28
|
+
* (`A + "/b" + C`) becomes an ordered `Operand[]`; a bare literal is a
|
|
29
|
+
* single-element list.
|
|
30
|
+
*/
|
|
31
|
+
export type Operand = {
|
|
32
|
+
readonly kind: 'literal';
|
|
33
|
+
readonly value: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: 'ref';
|
|
36
|
+
readonly name: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* A `from <module> import <name> [as <local>]` (or the language's equivalent)
|
|
40
|
+
* binding. `module` is the import specifier as written (e.g. `.constants`,
|
|
41
|
+
* `..pkg.constants`, `api.constants`) so the {@link ImportResolver} can apply
|
|
42
|
+
* language-specific rules; `originalName` is the exported name in the target
|
|
43
|
+
* module (pre-alias). The map key is the local (in-file) name.
|
|
44
|
+
*/
|
|
45
|
+
export interface ImportBinding {
|
|
46
|
+
readonly module: string;
|
|
47
|
+
readonly originalName: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* String-valued module-level constants of one source file. `literals` are
|
|
51
|
+
* fully-resolved (`X = "/a"`); `exprs` are unresolved operand lists
|
|
52
|
+
* (`X = A + "/b"`); `imports` maps a local name to the module it was imported
|
|
53
|
+
* from. All string keys are the in-file (local) names.
|
|
54
|
+
*/
|
|
55
|
+
export interface ModuleConstants {
|
|
56
|
+
readonly literals: Map<string, string>;
|
|
57
|
+
readonly exprs: Map<string, readonly Operand[]>;
|
|
58
|
+
readonly imports: Map<string, ImportBinding>;
|
|
59
|
+
}
|
|
60
|
+
/** Repo-wide map: unique file key (e.g. `app/constants.py`) → that file's
|
|
61
|
+
* {@link ModuleConstants}. */
|
|
62
|
+
export type RepoConstants = ReadonlyMap<string, ModuleConstants>;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve an import specifier (as written) from `importingFileKey` to the unique
|
|
65
|
+
* repo file key it refers to, or `null` when it cannot be pinned to exactly one
|
|
66
|
+
* file. This is the sole language-specific dependency of the fold: Python uses
|
|
67
|
+
* leading-dot relative imports + `.py`-suffix rules; a JVM binding would use
|
|
68
|
+
* package/classpath rules. Returning `null` on ambiguity keeps the fold honest —
|
|
69
|
+
* an unresolvable or ambiguous import floors to skip, never a wrong path.
|
|
70
|
+
*/
|
|
71
|
+
export type ImportResolver = (importingFileKey: string, moduleSpec: string, repoKeys: ReadonlySet<string>) => string | null;
|
|
72
|
+
/**
|
|
73
|
+
* Resolve a single named constant referenced in `fileKey` to its literal string
|
|
74
|
+
* value, folding `+` concatenation and following import chains via
|
|
75
|
+
* `resolveImport`, or `null` when it cannot be fully folded.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveConstant(fileKey: string, name: string, repo: RepoConstants, resolveImport: ImportResolver): string | null;
|
|
78
|
+
/**
|
|
79
|
+
* Resolve an inline operand list (an unnamed `+`-expression captured directly at
|
|
80
|
+
* a decorator/annotation argument, e.g. `@router.get(API_V1 + "/widgets")`)
|
|
81
|
+
* against `fileKey`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveOperands(fileKey: string, operands: readonly Operand[], repo: RepoConstants, resolveImport: ImportResolver): string | null;
|