gitnexus 1.6.9 → 1.6.10-aptos.0
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 +211 -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 +197 -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 +10 -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 +5 -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 +28 -0
- package/dist/core/move/consistency.js +98 -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 +49 -0
- package/dist/core/move/move-ingest.js +320 -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 +3 -3
- package/dist/core/run-analyze.js +1001 -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/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,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a 1-based source line number to the 0-based convention used by
|
|
3
|
+
* GraphNode `startLine`/`endLine`.
|
|
4
|
+
*
|
|
5
|
+
* The graph layer stores line numbers 0-based (tree-sitter `startPosition.row`),
|
|
6
|
+
* and this is load-bearing: the taint/PDG/CFG join and the MCP consumers all add
|
|
7
|
+
* `+ 1` to recover 1-based (see `summary-harvest-driver.ts` — "Function/Method
|
|
8
|
+
* node startLine is 0-based"). Most emitters get 0-based for free from
|
|
9
|
+
* tree-sitter. The exceptions are the regex-based COBOL/JCL processors (their
|
|
10
|
+
* parsers use `lineNum = i + 1`) and the scope-capture path (`Capture` ranges
|
|
11
|
+
* are 1-based per RFC §2.1). Those must convert to 0-based when they build a
|
|
12
|
+
* graph node, or the exact-content slice in `csv-generator.ts` drops the
|
|
13
|
+
* symbol's declaration line (#2379) and reported line numbers are off (#2377).
|
|
14
|
+
*
|
|
15
|
+
* Apply this ONLY at the graph-node `startLine:`/`endLine:` assignment. The
|
|
16
|
+
* parser-internal 1-based values (`.line`, `prog.startLine`) stay 1-based —
|
|
17
|
+
* they feed `L${line}` node/edge IDs and line-range containment checks that
|
|
18
|
+
* must not shift. The clamp guards degenerate inputs (line 0 / empty files).
|
|
19
|
+
*/
|
|
20
|
+
export declare const toZeroBasedLine: (oneBasedLine: number) => number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a 1-based source line number to the 0-based convention used by
|
|
3
|
+
* GraphNode `startLine`/`endLine`.
|
|
4
|
+
*
|
|
5
|
+
* The graph layer stores line numbers 0-based (tree-sitter `startPosition.row`),
|
|
6
|
+
* and this is load-bearing: the taint/PDG/CFG join and the MCP consumers all add
|
|
7
|
+
* `+ 1` to recover 1-based (see `summary-harvest-driver.ts` — "Function/Method
|
|
8
|
+
* node startLine is 0-based"). Most emitters get 0-based for free from
|
|
9
|
+
* tree-sitter. The exceptions are the regex-based COBOL/JCL processors (their
|
|
10
|
+
* parsers use `lineNum = i + 1`) and the scope-capture path (`Capture` ranges
|
|
11
|
+
* are 1-based per RFC §2.1). Those must convert to 0-based when they build a
|
|
12
|
+
* graph node, or the exact-content slice in `csv-generator.ts` drops the
|
|
13
|
+
* symbol's declaration line (#2379) and reported line numbers are off (#2377).
|
|
14
|
+
*
|
|
15
|
+
* Apply this ONLY at the graph-node `startLine:`/`endLine:` assignment. The
|
|
16
|
+
* parser-internal 1-based values (`.line`, `prog.startLine`) stay 1-based —
|
|
17
|
+
* they feed `L${line}` node/edge IDs and line-range containment checks that
|
|
18
|
+
* must not shift. The clamp guards degenerate inputs (line 0 / empty files).
|
|
19
|
+
*/
|
|
20
|
+
export const toZeroBasedLine = (oneBasedLine) => Math.max(0, oneBasedLine - 1);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NodeLabel } from '../../../_shared/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Graph-node labels that represent a resolvable code symbol — a definition with
|
|
4
|
+
* its own source span (function, type, member, module-like container).
|
|
5
|
+
*
|
|
6
|
+
* These get EXACT source-span content in the FTS index: `csv-generator.ts`
|
|
7
|
+
* slices exactly `[startLine, endLine]` for them (no ±2 padding), while every
|
|
8
|
+
* other label keeps the context window. That exactness depends on the 0-based
|
|
9
|
+
* `startLine`/`endLine` invariant enforced by `line-base.ts` — the slice is only
|
|
10
|
+
* correct because all emitters store 0-based lines. Keep the two together.
|
|
11
|
+
*
|
|
12
|
+
* Single source of truth so the set can't silently drift the way the inline copy
|
|
13
|
+
* did in #2379.
|
|
14
|
+
*
|
|
15
|
+
* NOTE: `group/extractors/manifest-extractor.ts`'s `CUSTOM_CONTRACT_RESOLVE_QUERY`
|
|
16
|
+
* carries a near-identical hand-list that is intentionally a SUBSET — it excludes
|
|
17
|
+
* `Namespace`, `Variable`, `Module`. Unifying the two needs a contract-resolution
|
|
18
|
+
* behavior check (would widen which nodes resolve as contract symbols), so it is
|
|
19
|
+
* deliberately left separate for now.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SYMBOL_NODE_LABELS: ReadonlySet<NodeLabel>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-node labels that represent a resolvable code symbol — a definition with
|
|
3
|
+
* its own source span (function, type, member, module-like container).
|
|
4
|
+
*
|
|
5
|
+
* These get EXACT source-span content in the FTS index: `csv-generator.ts`
|
|
6
|
+
* slices exactly `[startLine, endLine]` for them (no ±2 padding), while every
|
|
7
|
+
* other label keeps the context window. That exactness depends on the 0-based
|
|
8
|
+
* `startLine`/`endLine` invariant enforced by `line-base.ts` — the slice is only
|
|
9
|
+
* correct because all emitters store 0-based lines. Keep the two together.
|
|
10
|
+
*
|
|
11
|
+
* Single source of truth so the set can't silently drift the way the inline copy
|
|
12
|
+
* did in #2379.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: `group/extractors/manifest-extractor.ts`'s `CUSTOM_CONTRACT_RESOLVE_QUERY`
|
|
15
|
+
* carries a near-identical hand-list that is intentionally a SUBSET — it excludes
|
|
16
|
+
* `Namespace`, `Variable`, `Module`. Unifying the two needs a contract-resolution
|
|
17
|
+
* behavior check (would widen which nodes resolve as contract symbols), so it is
|
|
18
|
+
* deliberately left separate for now.
|
|
19
|
+
*/
|
|
20
|
+
export const SYMBOL_NODE_LABELS = new Set([
|
|
21
|
+
'Function',
|
|
22
|
+
'Method',
|
|
23
|
+
'Class',
|
|
24
|
+
'Interface',
|
|
25
|
+
'CodeElement',
|
|
26
|
+
'Struct',
|
|
27
|
+
'Enum',
|
|
28
|
+
'Macro',
|
|
29
|
+
'Typedef',
|
|
30
|
+
'Union',
|
|
31
|
+
'Namespace',
|
|
32
|
+
'Trait',
|
|
33
|
+
'Impl',
|
|
34
|
+
'TypeAlias',
|
|
35
|
+
'Const',
|
|
36
|
+
'Static',
|
|
37
|
+
'Variable',
|
|
38
|
+
'Property',
|
|
39
|
+
'Record',
|
|
40
|
+
'Delegate',
|
|
41
|
+
'Annotation',
|
|
42
|
+
'Constructor',
|
|
43
|
+
'Template',
|
|
44
|
+
'Module',
|
|
45
|
+
]);
|
|
@@ -113,6 +113,21 @@ export interface ExtractedDecoratorRoute {
|
|
|
113
113
|
* participate in `include_router(prefix=...)` joining.
|
|
114
114
|
*/
|
|
115
115
|
decoratorReceiver?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Raw text of a non-literal decorator path argument (`#2391`), e.g.
|
|
118
|
+
* `API_V1_WIDGETS_GET` or `API_V1 + "/widgets"`. Present only when the
|
|
119
|
+
* decorator's first argument was NOT a string literal, in which case
|
|
120
|
+
* `routePath` is empty and parse-impl resolves the constant cross-file (or
|
|
121
|
+
* drops the route on failure). Absent for ordinary string-literal routes.
|
|
122
|
+
*/
|
|
123
|
+
routePathExpr?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Parsed operand list for {@link routePathExpr} — an identifier reference or a
|
|
126
|
+
* `+`-concatenation, in the {@link Operand} shape the constant resolver folds.
|
|
127
|
+
* `undefined` when the expression was not a foldable string form (e.g. an
|
|
128
|
+
* attribute access), in which case the route is dropped at resolution.
|
|
129
|
+
*/
|
|
130
|
+
routePathOperands?: Operand[];
|
|
116
131
|
/**
|
|
117
132
|
* FastAPI `app.include_router(prefix='/x')` prefix that applies to
|
|
118
133
|
* this route. Filled by parse-impl after cross-file aggregation; the
|
|
@@ -131,6 +146,17 @@ export interface ExtractedDecoratorRoute {
|
|
|
131
146
|
*/
|
|
132
147
|
handlerName?: string;
|
|
133
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* One Python file's module-level string constants (#2391), used by parse-impl to
|
|
151
|
+
* resolve non-literal decorator route paths cross-file. `constants` is the
|
|
152
|
+
* `Map`-based {@link ModuleConstants} shape — it survives the worker
|
|
153
|
+
* `postMessage` boundary (structured clone) and the parse cache
|
|
154
|
+
* (`mapReplacer`/`mapReviver`) without conversion.
|
|
155
|
+
*/
|
|
156
|
+
export interface ExtractedModuleConstants {
|
|
157
|
+
filePath: string;
|
|
158
|
+
constants: ModuleConstants;
|
|
159
|
+
}
|
|
134
160
|
export interface ExtractedToolDef {
|
|
135
161
|
filePath: string;
|
|
136
162
|
toolName: string;
|
|
@@ -211,6 +237,13 @@ export interface ParseWorkerResult {
|
|
|
211
237
|
* predate the field; consumers must guard with `if (… ?? [])`).
|
|
212
238
|
*/
|
|
213
239
|
routerModuleAliases?: ExtractedRouterModuleAlias[];
|
|
240
|
+
/**
|
|
241
|
+
* Per-file Python module-level string constants (#2391). parse-impl aggregates
|
|
242
|
+
* these into a repo-wide, file-path-keyed map and resolves each decorator
|
|
243
|
+
* route's non-literal path expression against it. Optional for cache backward
|
|
244
|
+
* compatibility (older entries predate the field; consumers guard with `?? []`).
|
|
245
|
+
*/
|
|
246
|
+
moduleConstants?: ExtractedModuleConstants[];
|
|
214
247
|
toolDefs: ExtractedToolDef[];
|
|
215
248
|
ormQueries: ExtractedORMQuery[];
|
|
216
249
|
constructorBindings: FileConstructorBindings[];
|
|
@@ -256,3 +289,4 @@ export interface ParseWorkerInput {
|
|
|
256
289
|
* Appends results to the provided array (avoids allocation when no matches).
|
|
257
290
|
*/
|
|
258
291
|
export declare function extractORMQueries(filePath: string, content: string, out: ExtractedORMQuery[]): void;
|
|
292
|
+
import { type ModuleConstants, type Operand } from '../route-extractors/python-const-resolver.js';
|
|
@@ -751,6 +751,7 @@ export function extractORMQueries(filePath, content, out) {
|
|
|
751
751
|
// per file; this module does not re-export it. Downstream consumers
|
|
752
752
|
// import the function and its types directly from `route-extractors/`.
|
|
753
753
|
import { extractFastAPIRouterBindings } from '../route-extractors/fastapi-router-bindings.js';
|
|
754
|
+
import { extractPythonModuleConstants, parseConstOperands, } from '../route-extractors/python-const-resolver.js';
|
|
754
755
|
/**
|
|
755
756
|
* Report a non-fatal worker issue to the pool over IPC so a caught error is not
|
|
756
757
|
* invisible to the operator (#2264). The pool logs it on the main thread AND
|
|
@@ -813,7 +814,7 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
813
814
|
try {
|
|
814
815
|
tree = parseSourceSafe(parser, parseContent, undefined, {
|
|
815
816
|
bufferSize: getTreeSitterBufferSize(parseContent),
|
|
816
|
-
});
|
|
817
|
+
}, file.path);
|
|
817
818
|
}
|
|
818
819
|
catch (err) {
|
|
819
820
|
reportWarning(`Failed to parse file ${file.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -986,6 +987,12 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
986
987
|
if (captureMap['decorator'] && captureMap['decorator.name']) {
|
|
987
988
|
const decoratorName = captureMap['decorator.name'].text;
|
|
988
989
|
const decoratorArg = captureMap['decorator.arg']?.text;
|
|
990
|
+
// #2391: the first positional arg captured as either a string node
|
|
991
|
+
// (`arg_str`, present even for the empty-string literal `""` which has no
|
|
992
|
+
// `string_content`) or a non-literal expression (`arg_expr`: an
|
|
993
|
+
// identifier or a `+`-concatenation).
|
|
994
|
+
const decoratorArgStr = captureMap['decorator.arg_str'];
|
|
995
|
+
const decoratorArgExpr = captureMap['decorator.arg_expr'];
|
|
989
996
|
const decoratorReceiver = captureMap['decorator.receiver']?.text;
|
|
990
997
|
const decoratorNode = captureMap['decorator'];
|
|
991
998
|
// Store by the decorator's end line — the definition follows immediately after
|
|
@@ -994,19 +1001,39 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
994
1001
|
arg: decoratorArg,
|
|
995
1002
|
});
|
|
996
1003
|
if (ROUTE_DECORATOR_NAMES.has(decoratorName)) {
|
|
997
|
-
const routePath = decoratorArg || '';
|
|
998
1004
|
const method = decoratorName.replace('Mapping', '').toUpperCase();
|
|
999
1005
|
const httpMethod = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].includes(method)
|
|
1000
1006
|
? method
|
|
1001
1007
|
: 'GET';
|
|
1002
|
-
|
|
1008
|
+
const base = {
|
|
1003
1009
|
filePath: file.path,
|
|
1004
|
-
routePath,
|
|
1005
1010
|
httpMethod,
|
|
1006
1011
|
decoratorName,
|
|
1007
1012
|
lineNumber: decoratorNode.startPosition.row + lineOffset,
|
|
1008
1013
|
...(decoratorReceiver ? { decoratorReceiver } : {}),
|
|
1009
|
-
}
|
|
1014
|
+
};
|
|
1015
|
+
if (decoratorArgStr) {
|
|
1016
|
+
// String-literal path (the fast path, unchanged). Empty-string
|
|
1017
|
+
// literal `""` has no `string_content` → `decoratorArg` undefined →
|
|
1018
|
+
// routePath '' (a valid path under an APIRouter prefix).
|
|
1019
|
+
result.decoratorRoutes.push({ ...base, routePath: decoratorArg ?? '' });
|
|
1020
|
+
}
|
|
1021
|
+
else if (decoratorArgExpr) {
|
|
1022
|
+
// #2391 non-literal path (imported/composed constant). Emit the raw
|
|
1023
|
+
// expression + its operands for cross-file resolution in parse-impl;
|
|
1024
|
+
// `routePath` stays empty until resolved (or the route is dropped).
|
|
1025
|
+
const operands = decoratorArgExpr.type === 'identifier'
|
|
1026
|
+
? [{ kind: 'ref', name: decoratorArgExpr.text }]
|
|
1027
|
+
: parseConstOperands(decoratorArgExpr);
|
|
1028
|
+
result.decoratorRoutes.push({
|
|
1029
|
+
...base,
|
|
1030
|
+
routePath: '',
|
|
1031
|
+
routePathExpr: decoratorArgExpr.text,
|
|
1032
|
+
...(operands ? { routePathOperands: operands } : {}),
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
// Otherwise the first arg is absent or an unsupported shape
|
|
1036
|
+
// (attribute access, call, …) → skip; never a phantom `POST /`.
|
|
1010
1037
|
}
|
|
1011
1038
|
// MCP/RPC tool detection: @mcp.tool(), @app.tool(), @server.tool()
|
|
1012
1039
|
if (decoratorName === 'tool') {
|
|
@@ -1839,6 +1866,14 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1839
1866
|
// came from a `@router.<verb>` decorator. Python-only.
|
|
1840
1867
|
if (language === SupportedLanguages.Python) {
|
|
1841
1868
|
extractFastAPIRouterBindings(file.path, parseContent, result.routerIncludes, result.routerImports, (result.routerModuleAliases ??= []), (result.routerConstructorPrefixes ??= []));
|
|
1869
|
+
// #2391: harvest module-level string constants + from-imports so parse-impl
|
|
1870
|
+
// can resolve non-literal decorator route paths cross-file. Only emit for
|
|
1871
|
+
// files that carry something resolvable (a constant definition or an import
|
|
1872
|
+
// binding) to keep the aggregate bounded on large repos.
|
|
1873
|
+
const constants = extractPythonModuleConstants(tree);
|
|
1874
|
+
if (constants.literals.size > 0 || constants.exprs.size > 0 || constants.imports.size > 0) {
|
|
1875
|
+
(result.moduleConstants ??= []).push({ filePath: file.path, constants });
|
|
1876
|
+
}
|
|
1842
1877
|
}
|
|
1843
1878
|
// Language-specific decorator route extraction via provider hook.
|
|
1844
1879
|
// The provider's extractDecoratorRoutes walks the AST for framework-specific
|
|
@@ -32,6 +32,10 @@ export const mergeResult = (target, src) => {
|
|
|
32
32
|
target.routerModuleAliases ??= [];
|
|
33
33
|
appendAll(target.routerModuleAliases, src.routerModuleAliases);
|
|
34
34
|
}
|
|
35
|
+
if (src.moduleConstants) {
|
|
36
|
+
target.moduleConstants ??= [];
|
|
37
|
+
appendAll(target.moduleConstants, src.moduleConstants);
|
|
38
|
+
}
|
|
35
39
|
if (src.springTypes) {
|
|
36
40
|
target.springTypes ??= [];
|
|
37
41
|
appendAll(target.springTypes, src.springTypes);
|
|
@@ -99,6 +99,19 @@ export interface WorkerPoolOptions {
|
|
|
99
99
|
* created. Default `Math.max(3, poolSize)`.
|
|
100
100
|
*/
|
|
101
101
|
consecutiveFailureThreshold?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Startup budget in milliseconds for a replacement worker to emit the
|
|
104
|
+
* `{type:'ready'}` handshake before the pool treats it as a startup
|
|
105
|
+
* crash (see {@link waitForWorkerReady}). Default 5000; also overridable
|
|
106
|
+
* via `GITNEXUS_WORKER_READY_TIMEOUT_MS`, mirroring
|
|
107
|
+
* `GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS`. On a slow or heavily loaded
|
|
108
|
+
* host, a full pool of workers cold-starting concurrently can
|
|
109
|
+
* legitimately need more than 5s to load the native grammar bindings —
|
|
110
|
+
* without the override every slot times out and the pool misclassifies
|
|
111
|
+
* the slow start as a deterministic startup crash-loop, aborting the
|
|
112
|
+
* whole analyze.
|
|
113
|
+
*/
|
|
114
|
+
workerReadyTimeoutMs?: number;
|
|
102
115
|
/**
|
|
103
116
|
* Test-only injection point for the Worker constructor. When provided,
|
|
104
117
|
* the pool uses this factory instead of `new Worker(workerUrl)`. Production
|
|
@@ -135,6 +148,19 @@ export interface WorkerPoolOptions {
|
|
|
135
148
|
pdg?: boolean;
|
|
136
149
|
/** Per-function source-line cap for worker-side CFG construction (0 ⇒ no cap). */
|
|
137
150
|
pdgMaxFunctionLines?: number;
|
|
151
|
+
/**
|
|
152
|
+
* Max wall time `terminate()` waits for a retired worker that has NOT yet
|
|
153
|
+
* reached a JS-visible safe point before giving up on terminating it
|
|
154
|
+
* (#2432). Terminating a worker thread that is inside an N-API call aborts
|
|
155
|
+
* the whole process (`Napi::Error` → `std::terminate` → SIGABRT) — and the
|
|
156
|
+
* same abort fires at plain process exit, so the drain is what makes
|
|
157
|
+
* shutdown safe. On expiry the worker is left running (unref'd, with its
|
|
158
|
+
* at-safe-point terminate listener still armed) and a diagnostic is logged.
|
|
159
|
+
* Default 30000ms — above the C++ capture budget
|
|
160
|
+
* (`GITNEXUS_CPP_CAPTURE_BUDGET_MS`, 20000ms) so the drain converges for
|
|
161
|
+
* the known pathological class. 0 ⇒ no wait (test hook).
|
|
162
|
+
*/
|
|
163
|
+
shutdownDrainMs?: number;
|
|
138
164
|
}
|
|
139
165
|
export declare class WorkerPoolDispatchError extends Error {
|
|
140
166
|
/**
|
|
@@ -193,6 +219,8 @@ interface ResolvedWorkerPoolOptions {
|
|
|
193
219
|
maxRespawnsPerSlot: number;
|
|
194
220
|
maxCumulativeTimeoutMs: number;
|
|
195
221
|
consecutiveFailureThreshold: number;
|
|
222
|
+
shutdownDrainMs: number;
|
|
223
|
+
workerReadyTimeoutMs: number;
|
|
196
224
|
}
|
|
197
225
|
export declare function resolveWorkerPoolOptions(options?: WorkerPoolOptions, poolSize?: number): ResolvedWorkerPoolOptions;
|
|
198
226
|
/**
|
|
@@ -116,17 +116,7 @@ const DEFAULT_TIMEOUT_BACKOFF_FACTOR = 2;
|
|
|
116
116
|
const DEFAULT_MAX_RESPAWNS_PER_SLOT = 3;
|
|
117
117
|
const DEFAULT_MAX_CUMULATIVE_TIMEOUT_FACTOR = 5;
|
|
118
118
|
const DEFAULT_CONSECUTIVE_FAILURE_THRESHOLD_FLOOR = 3;
|
|
119
|
-
|
|
120
|
-
* Bounded wait for a replacement worker to emit the `{type:'ready'}`
|
|
121
|
-
* handshake from `parse-worker.ts`. Trusting Node's `online` event alone
|
|
122
|
-
* lets a worker that crashes during top-of-script init slip past pool
|
|
123
|
-
* startup — the pool only notices on the first dispatch's idle timeout
|
|
124
|
-
* (default 30s). 5 seconds is a generous budget for parser + grammar
|
|
125
|
-
* imports; if the worker hasn't reported ready by then, it's almost
|
|
126
|
-
* certainly stuck or crashed and the pool should surface the failure
|
|
127
|
-
* fast rather than wait out the dispatch idle timeout.
|
|
128
|
-
*/
|
|
129
|
-
const WORKER_READY_TIMEOUT_MS = 5_000;
|
|
119
|
+
const DEFAULT_WORKER_READY_TIMEOUT_MS = 5_000;
|
|
130
120
|
/**
|
|
131
121
|
* Default upper bound on auto-resolved pool size. Past 16 workers the
|
|
132
122
|
* dominant cost shifts from worker-side parsing to main-thread merge /
|
|
@@ -231,6 +221,8 @@ function nonNegativeInteger(value) {
|
|
|
231
221
|
? Math.floor(parsed)
|
|
232
222
|
: undefined;
|
|
233
223
|
}
|
|
224
|
+
/** See {@link WorkerPoolOptions.shutdownDrainMs}. */
|
|
225
|
+
const DEFAULT_SHUTDOWN_DRAIN_MS = 30_000;
|
|
234
226
|
export function resolveWorkerPoolOptions(options = {}, poolSize) {
|
|
235
227
|
const subBatchIdleTimeoutMs = positiveInteger(options.subBatchIdleTimeoutMs) ??
|
|
236
228
|
positiveInteger(process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS) ??
|
|
@@ -252,6 +244,12 @@ export function resolveWorkerPoolOptions(options = {}, poolSize) {
|
|
|
252
244
|
consecutiveFailureThreshold: positiveInteger(options.consecutiveFailureThreshold) ??
|
|
253
245
|
positiveInteger(process.env.GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD) ??
|
|
254
246
|
Math.max(DEFAULT_CONSECUTIVE_FAILURE_THRESHOLD_FLOOR, poolSize ?? 0),
|
|
247
|
+
shutdownDrainMs: nonNegativeInteger(options.shutdownDrainMs) ??
|
|
248
|
+
nonNegativeInteger(process.env.GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS) ??
|
|
249
|
+
DEFAULT_SHUTDOWN_DRAIN_MS,
|
|
250
|
+
workerReadyTimeoutMs: positiveInteger(options.workerReadyTimeoutMs) ??
|
|
251
|
+
positiveInteger(process.env.GITNEXUS_WORKER_READY_TIMEOUT_MS) ??
|
|
252
|
+
DEFAULT_WORKER_READY_TIMEOUT_MS,
|
|
255
253
|
};
|
|
256
254
|
}
|
|
257
255
|
/**
|
|
@@ -347,6 +345,27 @@ function captureWorkerStderr(worker) {
|
|
|
347
345
|
// A stderr stream error must never crash the pool.
|
|
348
346
|
stream.on('error', () => undefined);
|
|
349
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Forward a worker's piped stdout to the parent process's stdout, so worker
|
|
350
|
+
* logs stay visible now that the production factory spawns with
|
|
351
|
+
* `{ stdout: true }`. Workers with INHERITED stdout have been observed to
|
|
352
|
+
* crash silently during top-of-script init (exit code 1, nothing on stderr,
|
|
353
|
+
* roughly half of a concurrently spawned pool) on macOS 26.5 under both
|
|
354
|
+
* Node 22 and 26; piping stdout eliminates the crash entirely. Piping also
|
|
355
|
+
* matches the existing stderr handling, so worker output no longer races the
|
|
356
|
+
* parent's raw fd. No-op when the worker has no `stdout` stream (test
|
|
357
|
+
* factories).
|
|
358
|
+
*/
|
|
359
|
+
function forwardWorkerStdout(worker) {
|
|
360
|
+
const stream = worker.stdout;
|
|
361
|
+
if (!stream)
|
|
362
|
+
return;
|
|
363
|
+
stream.on('data', (chunk) => {
|
|
364
|
+
process.stdout.write(chunk);
|
|
365
|
+
});
|
|
366
|
+
// A stdout stream error must never crash the pool.
|
|
367
|
+
stream.on('error', () => undefined);
|
|
368
|
+
}
|
|
350
369
|
/** Captured stderr tail for a worker, trimmed; '' when nothing was captured. */
|
|
351
370
|
function workerStderrTail(worker) {
|
|
352
371
|
return workerStderrTails.get(worker)?.text.trim() ?? '';
|
|
@@ -383,13 +402,14 @@ function workerErrorReason(workerIndex, message, stack) {
|
|
|
383
402
|
* (parser/grammar import failure, missing native binding) slip past
|
|
384
403
|
* pool startup. The pool then only noticed the dead replacement on the
|
|
385
404
|
* first dispatch's idle timeout (default 30s) — a long stall masking
|
|
386
|
-
* an actual crash. This handshake bounds the wait at
|
|
387
|
-
* {@link
|
|
388
|
-
* `error` / `exit` / `messageerror` events directly.
|
|
389
|
-
* wired the same way: a V8 deserialization failure
|
|
390
|
-
* treated as worker death and rejects the readiness
|
|
405
|
+
* an actual crash. This handshake bounds the wait at `readyTimeoutMs`
|
|
406
|
+
* (see {@link WorkerPoolOptions.workerReadyTimeoutMs}) and surfaces init
|
|
407
|
+
* failures as `error` / `exit` / `messageerror` events directly.
|
|
408
|
+
* `messageerror` is wired the same way: a V8 deserialization failure
|
|
409
|
+
* during startup is treated as worker death and rejects the readiness
|
|
410
|
+
* promise.
|
|
391
411
|
*/
|
|
392
|
-
function waitForWorkerReady(worker) {
|
|
412
|
+
function waitForWorkerReady(worker, readyTimeoutMs) {
|
|
393
413
|
return new Promise((resolve, reject) => {
|
|
394
414
|
const cleanup = () => {
|
|
395
415
|
clearTimeout(timer);
|
|
@@ -427,8 +447,8 @@ function waitForWorkerReady(worker) {
|
|
|
427
447
|
// access can fire from the listeners.
|
|
428
448
|
const timer = setTimeout(() => {
|
|
429
449
|
cleanup();
|
|
430
|
-
reject(new Error(withStderr(worker, `Replacement worker did not report ready within ${
|
|
431
|
-
},
|
|
450
|
+
reject(new Error(withStderr(worker, `Replacement worker did not report ready within ${readyTimeoutMs}ms — likely crashed during top-of-script init (slow host? raise GITNEXUS_WORKER_READY_TIMEOUT_MS)`)));
|
|
451
|
+
}, readyTimeoutMs);
|
|
432
452
|
worker.on('message', onMessage);
|
|
433
453
|
worker.once('error', onError);
|
|
434
454
|
worker.once('exit', onExit);
|
|
@@ -558,6 +578,10 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
558
578
|
: undefined;
|
|
559
579
|
const spawnWorker = options?.workerFactory ??
|
|
560
580
|
((url) => new Worker(url, {
|
|
581
|
+
// Piped (not inherited) stdio: stderr for crash capture (#1741),
|
|
582
|
+
// stdout because inherited stdout triggers silent startup crashes on
|
|
583
|
+
// some hosts (see forwardWorkerStdout).
|
|
584
|
+
stdout: true,
|
|
561
585
|
stderr: true,
|
|
562
586
|
workerData: workerStoreData,
|
|
563
587
|
// The CFG visitors build per-function control-flow graphs by RECURSIVE
|
|
@@ -571,10 +595,11 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
571
595
|
// try/catch) and only that function's PDG is skipped, never a crash.
|
|
572
596
|
resourceLimits: { stackSizeMb: 16 },
|
|
573
597
|
}));
|
|
574
|
-
/** Spawn + wire
|
|
598
|
+
/** Spawn + wire stdio capture/forwarding in one step (used by all spawn sites). */
|
|
575
599
|
const spawnAndCapture = (url) => {
|
|
576
600
|
const worker = spawnWorker(url);
|
|
577
601
|
captureWorkerStderr(worker);
|
|
602
|
+
forwardWorkerStdout(worker);
|
|
578
603
|
return worker;
|
|
579
604
|
};
|
|
580
605
|
const workers = new Array(size);
|
|
@@ -608,13 +633,50 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
608
633
|
// Set by `terminate()` (below). Also read by the self-healing startup loop so
|
|
609
634
|
// a terminate during startup aborts pending backoff/retries (#1741).
|
|
610
635
|
let terminated = false;
|
|
636
|
+
/** Resolves `true` when `promise` settles within `ms`, else `false`. The
|
|
637
|
+
* timer is unref'd so an expiring drain never holds the process open. */
|
|
638
|
+
const settledWithin = (promise, ms) => {
|
|
639
|
+
if (ms <= 0)
|
|
640
|
+
return Promise.resolve(false);
|
|
641
|
+
return new Promise((resolve) => {
|
|
642
|
+
const timer = setTimeout(() => resolve(false), ms);
|
|
643
|
+
timer.unref?.();
|
|
644
|
+
void promise.then(() => {
|
|
645
|
+
clearTimeout(timer);
|
|
646
|
+
resolve(true);
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
};
|
|
611
650
|
const terminateTrackedWorkers = async (liveWorkers) => {
|
|
612
651
|
const retired = Array.from(retiredWorkers);
|
|
613
652
|
await Promise.all([
|
|
614
653
|
...liveWorkers.map((worker) => worker?.terminate().catch(() => undefined)),
|
|
615
|
-
...retired.map((record) =>
|
|
654
|
+
...retired.map(async (record) => {
|
|
655
|
+
// #2432: a retired worker that has not reached a JS-visible safe
|
|
656
|
+
// point may be inside an N-API call — terminating it aborts the
|
|
657
|
+
// WHOLE process (`Napi::Error` → std::terminate → SIGABRT). Drain:
|
|
658
|
+
// wait (bounded) for its safe point; on expiry leave it running —
|
|
659
|
+
// it is unref'd and its at-safe-point terminate listener stays
|
|
660
|
+
// armed — and log which file wedged it.
|
|
661
|
+
if (!record.safeToTerminate) {
|
|
662
|
+
const drained = await settledWithin(record.safePoint, poolOptions.shutdownDrainMs);
|
|
663
|
+
if (!drained) {
|
|
664
|
+
logger.warn({
|
|
665
|
+
workerIndex: record.workerIndex,
|
|
666
|
+
reason: record.reason,
|
|
667
|
+
drainMs: poolOptions.shutdownDrainMs,
|
|
668
|
+
}, `Worker ${record.workerIndex} is still inside native code after the ` +
|
|
669
|
+
`${poolOptions.shutdownDrainMs}ms shutdown drain; leaving it un-terminated ` +
|
|
670
|
+
`to avoid a native abort (#2432). It will be terminated at its next safe point.`);
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
await record.terminate();
|
|
675
|
+
}),
|
|
616
676
|
]);
|
|
617
|
-
|
|
677
|
+
// Undrained records stay tracked so a repeated shutdown call can retry
|
|
678
|
+
// their (now possibly safe) terminate; record.terminate() removes each
|
|
679
|
+
// drained record via its cleanup.
|
|
618
680
|
};
|
|
619
681
|
for (let i = 0; i < size; i++) {
|
|
620
682
|
workers[i] = spawnAndCapture(workerUrl);
|
|
@@ -665,7 +727,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
665
727
|
if (!worker)
|
|
666
728
|
return; // terminated mid-startup
|
|
667
729
|
try {
|
|
668
|
-
await waitForWorkerReady(worker);
|
|
730
|
+
await waitForWorkerReady(worker, poolOptions.workerReadyTimeoutMs);
|
|
669
731
|
anyWorkerReachedReady = true;
|
|
670
732
|
return; // ready — slot stays in activeSlots
|
|
671
733
|
}
|
|
@@ -709,7 +771,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
709
771
|
const initialReadyGate = Promise.allSettled(workers.map((_, i) => bringSlotReady(i))).then(() => undefined);
|
|
710
772
|
const dispatch = async (items, onProgress, chunkHash) => {
|
|
711
773
|
// Await the initial-spawn readiness gate (F13). On first dispatch
|
|
712
|
-
// this blocks for up to
|
|
774
|
+
// this blocks for up to poolOptions.workerReadyTimeoutMs while every initial
|
|
713
775
|
// worker's `{type:'ready'}` handshake is checked; on subsequent
|
|
714
776
|
// dispatches the promise is already settled and resolves
|
|
715
777
|
// synchronously. Slots whose initial worker crashed in top-of-
|
|
@@ -788,6 +850,18 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
788
850
|
const retireWorkerAfterTimeout = (worker, workerIndex, reason) => {
|
|
789
851
|
let cleaned = false;
|
|
790
852
|
let terminateStarted = false;
|
|
853
|
+
let resolveSafePoint;
|
|
854
|
+
const safePoint = new Promise((resolve) => {
|
|
855
|
+
resolveSafePoint = resolve;
|
|
856
|
+
});
|
|
857
|
+
// A message/messageerror proves the worker is executing JS again; an
|
|
858
|
+
// exit/error means the thread is gone. Either way `worker.terminate()`
|
|
859
|
+
// can no longer land mid-N-API call (#2432), so shutdown's drain may
|
|
860
|
+
// stop waiting.
|
|
861
|
+
function markSafeToTerminate() {
|
|
862
|
+
record.safeToTerminate = true;
|
|
863
|
+
resolveSafePoint();
|
|
864
|
+
}
|
|
791
865
|
function cleanupRetired() {
|
|
792
866
|
if (cleaned)
|
|
793
867
|
return;
|
|
@@ -806,6 +880,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
806
880
|
await worker.terminate().catch(() => undefined);
|
|
807
881
|
}
|
|
808
882
|
function terminateWhenBackInJs() {
|
|
883
|
+
markSafeToTerminate();
|
|
809
884
|
void terminateRetired();
|
|
810
885
|
}
|
|
811
886
|
function onRetiredMessage(raw) {
|
|
@@ -816,8 +891,14 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
816
891
|
terminateWhenBackInJs();
|
|
817
892
|
}
|
|
818
893
|
}
|
|
819
|
-
const onRetiredError = () =>
|
|
820
|
-
|
|
894
|
+
const onRetiredError = () => {
|
|
895
|
+
markSafeToTerminate();
|
|
896
|
+
cleanupRetired();
|
|
897
|
+
};
|
|
898
|
+
const onRetiredExit = () => {
|
|
899
|
+
markSafeToTerminate();
|
|
900
|
+
cleanupRetired();
|
|
901
|
+
};
|
|
821
902
|
const onRetiredMessageError = () => terminateWhenBackInJs();
|
|
822
903
|
const record = {
|
|
823
904
|
worker,
|
|
@@ -825,6 +906,8 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
825
906
|
reason,
|
|
826
907
|
cleanup: cleanupRetired,
|
|
827
908
|
terminate: terminateRetired,
|
|
909
|
+
safeToTerminate: false,
|
|
910
|
+
safePoint,
|
|
828
911
|
};
|
|
829
912
|
retiredWorkers.add(record);
|
|
830
913
|
worker.on('message', onRetiredMessage);
|
|
@@ -851,7 +934,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
851
934
|
return false;
|
|
852
935
|
const replacement = spawnAndCapture(workerUrl);
|
|
853
936
|
try {
|
|
854
|
-
await waitForWorkerReady(replacement);
|
|
937
|
+
await waitForWorkerReady(replacement, poolOptions.workerReadyTimeoutMs);
|
|
855
938
|
}
|
|
856
939
|
catch (err) {
|
|
857
940
|
await replacement.terminate().catch(() => undefined);
|
|
@@ -890,8 +973,25 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
890
973
|
const liveWorkers = workers.slice();
|
|
891
974
|
for (let i = 0; i < workers.length; i++)
|
|
892
975
|
workers[i] = undefined;
|
|
976
|
+
// #2432: a live worker with a job in flight may be inside an N-API
|
|
977
|
+
// call — direct terminate risks the same native abort as the retired
|
|
978
|
+
// case. Route busy workers through the retire path (terminate at
|
|
979
|
+
// their next JS-visible safe point); idle workers are parked in the
|
|
980
|
+
// JS event loop and terminate safely right away.
|
|
981
|
+
const idleWorkers = [];
|
|
982
|
+
for (let i = 0; i < liveWorkers.length; i++) {
|
|
983
|
+
const worker = liveWorkers[i];
|
|
984
|
+
if (worker === undefined)
|
|
985
|
+
continue;
|
|
986
|
+
if (busySlots.has(i)) {
|
|
987
|
+
retireWorkerAfterTimeout(worker, i, 'circuit breaker tripped with job in flight');
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
idleWorkers.push(worker);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
893
993
|
activeSlots.clear();
|
|
894
|
-
void terminateTrackedWorkers(
|
|
994
|
+
void terminateTrackedWorkers(idleWorkers);
|
|
895
995
|
};
|
|
896
996
|
const maybeDone = () => {
|
|
897
997
|
if (stopped)
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { GraphNode, GraphRelationship } from '../../_shared/index.js';
|
|
15
15
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
16
16
|
import { NodeTableName } from './schema.js';
|
|
17
|
+
import { type LayoutTableName } from './node-table-layout.js';
|
|
17
18
|
/**
|
|
18
19
|
* Flush buffered rows to disk once the buffered chunk reaches this many bytes.
|
|
19
20
|
* Byte-bounded rather than row-count-bounded: row size ranges from a few dozen
|
|
@@ -49,6 +50,14 @@ export declare const shouldFlushCSVBuffer: (byteCount: number) => boolean;
|
|
|
49
50
|
export declare const sanitizeUTF8: (str: string) => string;
|
|
50
51
|
export declare const escapeCSVField: (value: string | number | undefined | null) => string;
|
|
51
52
|
export declare const escapeCSVNumber: (value: number | undefined | null, defaultValue?: number) => string;
|
|
53
|
+
/**
|
|
54
|
+
* LadybugDB STRING[] literal inside a quoted CSV field. Elements containing a
|
|
55
|
+
* list metacharacter (' , [ ]) are single-quoted so comma-bearing types like
|
|
56
|
+
* `Table<address, u64>` survive as one element. LadybugDB keeps the quotes on
|
|
57
|
+
* read, so user-facing columns must strip them (see moveResources fieldList).
|
|
58
|
+
*/
|
|
59
|
+
export declare const escapeCSVStringArray: (value: unknown) => string;
|
|
60
|
+
export declare const escapeCSVBoolean: (value: unknown) => string;
|
|
52
61
|
export declare const isBinaryContent: (content: string) => boolean;
|
|
53
62
|
/**
|
|
54
63
|
* Flatten newlines and tabs to single spaces for FTS-indexed text columns
|
|
@@ -77,6 +86,12 @@ export declare const isBinaryContent: (content: string) => boolean;
|
|
|
77
86
|
* otherwise fail to match whitespace-normalized indexed content.
|
|
78
87
|
*/
|
|
79
88
|
export declare const normalizeFtsText: (text: string) => string;
|
|
89
|
+
/**
|
|
90
|
+
* Encode a row from the same ordered layout that owns its DDL, CSV header,
|
|
91
|
+
* and COPY column list. These tables are shared across languages, so missing
|
|
92
|
+
* optional properties deliberately serialize to typed defaults.
|
|
93
|
+
*/
|
|
94
|
+
export declare const buildLayoutNodeRow: (table: LayoutTableName, node: GraphNode, content: string) => string;
|
|
80
95
|
/** Canonical relationship CSV header — shared by the emit pass and the
|
|
81
96
|
* `splitRelCsvByLabelPair` differential oracle. */
|
|
82
97
|
export declare const REL_CSV_HEADER = "from,to,type,confidence,reason,step";
|