cgraphx 2.0.2 → 2.0.6
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/dist/.claude-template/FLOW-MAP.md +13 -3
- package/dist/.claude-template/agents/task-history.md +186 -0
- package/dist/.claude-template/commands/end.md +1 -0
- package/dist/.claude-template/skills/cgraphx-guide/SKILL.md +5 -3
- package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +8 -8
- package/dist/.claude-template/skills/cgraphx-guide/how-to-use.md +8 -8
- package/dist/.claude-template/skills/clarify-requirements/SKILL.md +13 -9
- package/dist/.claude-template/skills/db-query/SKILL.md +19 -2
- package/dist/.claude-template/skills/iboc-check/SKILL.md +51 -23
- package/dist/.claude-template/skills/iboc-check/filler-prompt.md +3 -4
- package/dist/.claude-template/skills/run-api-test/SKILL.md +15 -15
- package/dist/.claude-template/skills/run-api-test/assets/{template-test-report.md → template-/346/216/245/345/217/243/346/265/213/350/257/225/346/212/245/345/221/212.md} +4 -4
- package/dist/.claude-template/skills/run-api-test/references/bru-run.md +1 -1
- package/dist/.claude-template/skills/run-api-test/references/db-verification.md +2 -2
- package/dist/.claude-template/skills/run-api-test/references/report-format.md +6 -6
- package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +1 -1
- package/dist/.claude-template/skills/run-api-test/references/test-scope.md +6 -6
- package/dist/.claude-template/skills/run-ui-test/SKILL.md +186 -0
- package/dist/.claude-template/skills/run-ui-test/references/report-format.md +77 -0
- package/dist/.claude-template/skills/subagent-implement/SKILL.md +3 -2
- package/dist/.claude-template/skills/write-api/SKILL.md +18 -18
- package/dist/.claude-template/skills/write-api/assets/{template-api-spec.md → template-/346/216/245/345/217/243/346/265/213/350/257/225-spec.md} +1 -1
- package/dist/.claude-template/skills/write-api/references/{api-spec-format.md → /346/216/245/345/217/243/346/265/213/350/257/225-spec-format.md} +3 -3
- package/dist/.claude-template/skills/write-plan/SKILL.md +4 -2
- package/dist/.claude-template/skills/write-ui-test/SKILL.md +125 -0
- package/dist/.claude-template/skills/write-ui-test/references//347/224/250/344/276/213/350/247/204/346/240/274-format.md +94 -0
- package/dist/core/code/engine/cli/analyze-config.js +320 -0
- package/dist/core/code/engine/cli/analyze.js +1086 -0
- package/dist/core/code/engine/cli/cli-message.js +83 -0
- package/dist/core/code/engine/cli/detect-changes-format.js +58 -0
- package/dist/core/code/engine/cli/embedding-dims.js +43 -0
- package/dist/core/code/engine/cli/format-elapsed.js +12 -0
- package/dist/core/code/engine/cli/help-i18n.js +144 -0
- package/dist/core/code/engine/cli/i18n/en.js +110 -0
- package/dist/core/code/engine/cli/i18n/index.js +47 -0
- package/dist/core/code/engine/cli/i18n/resources.js +9 -0
- package/dist/core/code/engine/cli/i18n/zh-CN.js +110 -0
- package/dist/core/code/engine/cli/lazy-action.js +67 -0
- package/dist/core/code/engine/cli/optional-grammars.js +136 -0
- package/dist/core/code/engine/cli/resolve-invocation.js +76 -0
- package/dist/core/code/engine/cli/status.js +156 -0
- package/dist/core/code/engine/cli/tool.js +384 -0
- package/dist/core/code/engine/config/ignore-service.js +511 -0
- package/dist/core/code/engine/config/supported-languages.js +17 -0
- package/dist/core/code/engine/core/analysis-features.js +64 -0
- package/dist/core/code/engine/core/analyzer-identity.js +2171 -0
- package/dist/core/code/engine/core/git-staleness.js +180 -0
- package/dist/core/code/engine/core/graph/graph.js +180 -0
- package/dist/core/code/engine/core/graph/import-cycles.js +106 -0
- package/dist/core/code/engine/core/graph/types.js +2 -0
- package/dist/core/code/engine/core/index-freshness.js +12 -0
- package/dist/core/code/engine/core/ingestion/binding-accumulator.js +341 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/c-cpp.js +168 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/csharp.js +9 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/dart.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/go.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/jvm.js +54 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/php.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/python.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/ruby.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/rust.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/swift.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/typescript-javascript.js +11 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/generic.js +62 -0
- package/dist/core/code/engine/core/ingestion/call-processor.js +503 -0
- package/dist/core/code/engine/core/ingestion/call-routing.js +98 -0
- package/dist/core/code/engine/core/ingestion/call-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/cfg/callee-cell-format.js +45 -0
- package/dist/core/code/engine/core/ingestion/cfg/cfg-builder.js +202 -0
- package/dist/core/code/engine/core/ingestion/cfg/collect.js +81 -0
- package/dist/core/code/engine/core/ingestion/cfg/control-dependence.js +185 -0
- package/dist/core/code/engine/core/ingestion/cfg/control-flow-context.js +130 -0
- package/dist/core/code/engine/core/ingestion/cfg/emit.js +646 -0
- package/dist/core/code/engine/core/ingestion/cfg/post-dominators.js +182 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-def-reason-codec.js +139 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-defs-graph.js +322 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-defs.js +792 -0
- package/dist/core/code/engine/core/ingestion/cfg/synthetic-escape.js +305 -0
- package/dist/core/code/engine/core/ingestion/cfg/traversal-result.js +6 -0
- package/dist/core/code/engine/core/ingestion/cfg/types.js +14 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp-harvest.js +545 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp.js +590 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/call-site-harvest.js +356 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp-harvest.js +593 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp.js +871 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/dart-harvest.js +874 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/dart.js +840 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/go-harvest.js +625 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/go.js +642 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/java-harvest.js +517 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/java.js +816 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin-harvest.js +723 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin.js +813 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/php-harvest.js +630 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/php.js +725 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/python-harvest.js +776 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/python.js +562 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby-harvest.js +591 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby.js +760 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/rust-harvest.js +877 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/rust.js +562 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/scope-tree-harvest.js +120 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/swift-harvest.js +683 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/swift.js +791 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript-harvest.js +1060 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript.js +587 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/c-cpp.js +77 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/csharp.js +24 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/dart.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/go.js +28 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/jvm.js +67 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/php.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/python.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/ruby.js +13 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/rust.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/swift.js +21 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/typescript-javascript.js +31 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/generic.js +144 -0
- package/dist/core/code/engine/core/ingestion/class-types.js +2 -0
- package/dist/core/code/engine/core/ingestion/cluster-enricher.js +174 -0
- package/dist/core/code/engine/core/ingestion/community-processor.js +604 -0
- package/dist/core/code/engine/core/ingestion/constants.js +26 -0
- package/dist/core/code/engine/core/ingestion/cpp-ue-preprocessor.js +263 -0
- package/dist/core/code/engine/core/ingestion/csharp-namespace-gate.js +133 -0
- package/dist/core/code/engine/core/ingestion/di-extractors/index.js +38 -0
- package/dist/core/code/engine/core/ingestion/di-extractors/spring.js +310 -0
- package/dist/core/code/engine/core/ingestion/emit-references.js +244 -0
- package/dist/core/code/engine/core/ingestion/entry-point-scoring.js +201 -0
- package/dist/core/code/engine/core/ingestion/export-detection.js +244 -0
- package/dist/core/code/engine/core/ingestion/field-extractor.js +29 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/c-cpp.js +107 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/csharp.js +124 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/dart.js +99 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/go.js +102 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/helpers.js +198 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/jvm.js +172 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/python.js +94 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/ruby.js +79 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/swift.js +93 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/typescript-javascript.js +59 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/generic.js +147 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/typescript.js +266 -0
- package/dist/core/code/engine/core/ingestion/field-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/filesystem-walker.js +136 -0
- package/dist/core/code/engine/core/ingestion/finalize-orchestrator.js +159 -0
- package/dist/core/code/engine/core/ingestion/framework-detection.js +432 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/analysis-features.js +38 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/annotation-arguments.js +234 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/aop-candidates.js +88 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/aop.js +487 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/auto-configuration.js +21 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-candidates.js +189 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-catalog.js +32 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-factories.js +73 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/conditionals.js +323 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/config-bindings.js +119 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/di-metadata.js +385 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/resource-injection.js +96 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/c-cpp.js +17 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/csharp.js +46 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/dart.js +59 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/go.js +30 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/jvm.js +73 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/php.js +19 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/python.js +45 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/ruby.js +20 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/rust.js +58 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/swift.js +94 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/typescript-javascript.js +26 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/csharp.js +128 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/go.js +50 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/jvm.js +112 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/php.js +80 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/python.js +75 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/resolver-factory.js +36 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/ruby.js +20 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/rust.js +79 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/standard.js +180 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/types.js +7 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/utils.js +153 -0
- package/dist/core/code/engine/core/ingestion/import-target-adapter.js +99 -0
- package/dist/core/code/engine/core/ingestion/language-config.js +391 -0
- package/dist/core/code/engine/core/ingestion/language-provider.js +25 -0
- package/dist/core/code/engine/core/ingestion/languages/c/arity-metadata.js +98 -0
- package/dist/core/code/engine/core/ingestion/languages/c/arity.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/c/capture-side-channel.js +69 -0
- package/dist/core/code/engine/core/ingestion/languages/c/captures.js +189 -0
- package/dist/core/code/engine/core/ingestion/languages/c/header-scan.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/c/import-decomposer.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/c/import-target.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/c/index.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/c/interpret.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/c/merge-bindings.js +26 -0
- package/dist/core/code/engine/core/ingestion/languages/c/query.js +210 -0
- package/dist/core/code/engine/core/ingestion/languages/c/scope-resolver.js +112 -0
- package/dist/core/code/engine/core/ingestion/languages/c/simple-hooks.js +24 -0
- package/dist/core/code/engine/core/ingestion/languages/c/static-linkage.js +109 -0
- package/dist/core/code/engine/core/ingestion/languages/c-cpp.js +506 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/adl.js +804 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/arity-metadata.js +258 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/arity.js +37 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/capture-side-channel.js +89 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/captures.js +1975 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-extractor.js +311 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-filter.js +210 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/conversion-rank.js +163 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/file-local-linkage.js +327 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/header-scan.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/import-decomposer.js +134 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/import-target.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/index.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/inline-namespaces.js +379 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/interpret.js +239 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/member-lookup.js +470 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/merge-bindings.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/query.js +763 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/range-bindings.js +230 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/scope-resolver.js +354 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/simple-hooks.js +67 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/two-phase-lookup.js +348 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/type-classifier.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/user-defined-conversions.js +128 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/accessor-unwrap.js +67 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/arity-metadata.js +49 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/arity.js +40 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/captures.js +557 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/import-decomposer.js +96 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/import-target.js +176 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/index.js +95 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/interpret.js +150 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/merge-bindings.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/namespace-siblings.js +708 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/qualified-type-names.js +62 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/query.js +578 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/receiver-binding.js +142 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/resolution-config.js +18 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/scope-resolver.js +84 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/simple-hooks.js +81 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp.js +204 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/arity-metadata.js +38 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/arity.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/built-ins.js +37 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/cache-stats.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/captures.js +1096 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/expand-wildcards.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/extension-type-preprocess.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/import-target.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/index.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/interpret.js +101 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/merge-bindings.js +42 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/query.js +246 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/receiver-binding.js +90 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/scope-resolver.js +197 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/signature-bindings.js +54 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/simple-hooks.js +61 -0
- package/dist/core/code/engine/core/ingestion/languages/dart.js +138 -0
- package/dist/core/code/engine/core/ingestion/languages/go/arity-metadata.js +71 -0
- package/dist/core/code/engine/core/ingestion/languages/go/arity.js +17 -0
- package/dist/core/code/engine/core/ingestion/languages/go/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/go/captures.js +492 -0
- package/dist/core/code/engine/core/ingestion/languages/go/expand-wildcards.js +97 -0
- package/dist/core/code/engine/core/ingestion/languages/go/generic-type-parameters.js +146 -0
- package/dist/core/code/engine/core/ingestion/languages/go/import-decomposer.js +47 -0
- package/dist/core/code/engine/core/ingestion/languages/go/import-target.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/go/index.js +39 -0
- package/dist/core/code/engine/core/ingestion/languages/go/interface-impls.js +955 -0
- package/dist/core/code/engine/core/ingestion/languages/go/interpret.js +177 -0
- package/dist/core/code/engine/core/ingestion/languages/go/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/go/method-owners.js +131 -0
- package/dist/core/code/engine/core/ingestion/languages/go/namespace-mirror.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/go/package-clause.js +79 -0
- package/dist/core/code/engine/core/ingestion/languages/go/package-siblings.js +83 -0
- package/dist/core/code/engine/core/ingestion/languages/go/query.js +298 -0
- package/dist/core/code/engine/core/ingestion/languages/go/range-binding.js +127 -0
- package/dist/core/code/engine/core/ingestion/languages/go/receiver-binding.js +24 -0
- package/dist/core/code/engine/core/ingestion/languages/go/scope-resolver.js +75 -0
- package/dist/core/code/engine/core/ingestion/languages/go/simple-hooks.js +31 -0
- package/dist/core/code/engine/core/ingestion/languages/go/type-binding.js +279 -0
- package/dist/core/code/engine/core/ingestion/languages/go.js +160 -0
- package/dist/core/code/engine/core/ingestion/languages/index.js +66 -0
- package/dist/core/code/engine/core/ingestion/languages/java/analysis-features.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/java/arity-metadata.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/arity.js +27 -0
- package/dist/core/code/engine/core/ingestion/languages/java/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/java/capture-side-channel.js +123 -0
- package/dist/core/code/engine/core/ingestion/languages/java/captures.js +791 -0
- package/dist/core/code/engine/core/ingestion/languages/java/import-decomposer.js +88 -0
- package/dist/core/code/engine/core/ingestion/languages/java/import-target.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/java/index.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/interpret.js +146 -0
- package/dist/core/code/engine/core/ingestion/languages/java/merge-bindings.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/package-facts.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/java/package-siblings.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/java/query.js +319 -0
- package/dist/core/code/engine/core/ingestion/languages/java/receiver-binding.js +98 -0
- package/dist/core/code/engine/core/ingestion/languages/java/scope-resolver.js +213 -0
- package/dist/core/code/engine/core/ingestion/languages/java/simple-hooks.js +39 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-aop.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-bean-metadata.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-conditionals.js +52 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-config-bindings.js +222 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-di.js +165 -0
- package/dist/core/code/engine/core/ingestion/languages/java.js +192 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/arity.js +15 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/captures.js +1122 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/import-target.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/index.js +109 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/interpret.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/query.js +659 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/scope-resolver.js +78 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/simple-hooks.js +44 -0
- package/dist/core/code/engine/core/ingestion/languages/jvm/package-facts.js +46 -0
- package/dist/core/code/engine/core/ingestion/languages/jvm/package-siblings.js +200 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/arity-metadata.js +23 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/arity.js +18 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/capture-side-channel.js +160 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/captures.js +1262 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/companion-scopes.js +72 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/import-decomposer.js +40 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/import-target.js +135 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/index.js +26 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/interpret.js +75 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/merge-bindings.js +28 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/owners.js +134 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/package-facts.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/package-siblings.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/query.js +243 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/receiver-binding.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/scope-resolver.js +207 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/simple-hooks.js +42 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-aop.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-bean-metadata.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-conditionals.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-di.js +304 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin.js +189 -0
- package/dist/core/code/engine/core/ingestion/languages/php/arity-metadata.js +66 -0
- package/dist/core/code/engine/core/ingestion/languages/php/arity.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/php/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/php/captures.js +1166 -0
- package/dist/core/code/engine/core/ingestion/languages/php/import-decomposer.js +238 -0
- package/dist/core/code/engine/core/ingestion/languages/php/import-target.js +213 -0
- package/dist/core/code/engine/core/ingestion/languages/php/index.js +85 -0
- package/dist/core/code/engine/core/ingestion/languages/php/interpret.js +256 -0
- package/dist/core/code/engine/core/ingestion/languages/php/merge-bindings.js +50 -0
- package/dist/core/code/engine/core/ingestion/languages/php/namespace-siblings.js +353 -0
- package/dist/core/code/engine/core/ingestion/languages/php/query.js +391 -0
- package/dist/core/code/engine/core/ingestion/languages/php/receiver-binding.js +135 -0
- package/dist/core/code/engine/core/ingestion/languages/php/scope-resolver.js +361 -0
- package/dist/core/code/engine/core/ingestion/languages/php/simple-hooks.js +116 -0
- package/dist/core/code/engine/core/ingestion/languages/php.js +302 -0
- package/dist/core/code/engine/core/ingestion/languages/python/arity-metadata.js +49 -0
- package/dist/core/code/engine/core/ingestion/languages/python/arity.js +41 -0
- package/dist/core/code/engine/core/ingestion/languages/python/cache-stats.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/python/captures.js +299 -0
- package/dist/core/code/engine/core/ingestion/languages/python/depends-references.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/python/import-decomposer.js +115 -0
- package/dist/core/code/engine/core/ingestion/languages/python/import-target.js +440 -0
- package/dist/core/code/engine/core/ingestion/languages/python/index-stats.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/python/index.js +96 -0
- package/dist/core/code/engine/core/ingestion/languages/python/interpret.js +430 -0
- package/dist/core/code/engine/core/ingestion/languages/python/merge-bindings.js +47 -0
- package/dist/core/code/engine/core/ingestion/languages/python/query.js +323 -0
- package/dist/core/code/engine/core/ingestion/languages/python/receiver-binding.js +310 -0
- package/dist/core/code/engine/core/ingestion/languages/python/scope-resolver.js +80 -0
- package/dist/core/code/engine/core/ingestion/languages/python/simple-hooks.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/python.js +140 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/arity.js +41 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/captures.js +864 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/import-target.js +88 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/index.js +29 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/interpret.js +115 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/query.js +349 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/receiver-binding.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/scope-resolver.js +263 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/simple-hooks.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby.js +215 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/arity.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/captures.js +304 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/import-decomposer.js +167 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/import-target.js +108 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/index.js +29 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/interpret.js +201 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/method-owners.js +76 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/module-path.js +222 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/qualified-call.js +482 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/query.js +280 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/range-binding.js +687 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/receiver-binding.js +148 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/scope-resolver.js +151 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/simple-hooks.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/rust.js +183 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/arity-metadata.js +44 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/arity.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/base-type.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/captures.js +594 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/conditional-directive-preprocess.js +256 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/implicit-imports.js +60 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/import-decomposer.js +87 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/import-target.js +84 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/index.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/interpret.js +93 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/merge-bindings.js +51 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/query.js +226 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/receiver-binding.js +169 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/scope-resolver.js +192 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/sibling-type-bindings.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/signature-bindings.js +69 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/simple-hooks.js +65 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/target-grouping.js +97 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/target-siblings.js +74 -0
- package/dist/core/code/engine/core/ingestion/languages/swift.js +246 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/arity-metadata.js +106 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/arity.js +57 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/array-callback.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cache-stats.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/captures.js +956 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-export-assignment.js +535 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-module-exports.js +196 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/import-decomposer.js +374 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/import-target.js +65 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/index.js +108 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/interpret.js +344 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/merge-bindings.js +161 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/nuxt-auto-imports.js +325 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/query.js +1328 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/receiver-binding.js +201 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/scope-resolver.js +293 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/simple-hooks.js +139 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript.js +455 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/captures.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/import-target.js +61 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/index.js +55 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/scope-resolver.js +295 -0
- package/dist/core/code/engine/core/ingestion/languages/vue.js +96 -0
- package/dist/core/code/engine/core/ingestion/local-symbol-pruner.js +68 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/csharp.js +290 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/dart.js +392 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/go.js +179 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/jvm.js +350 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/php.js +306 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/python.js +312 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/ruby.js +289 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/rust.js +198 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/swift.js +286 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/typescript-javascript.js +341 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/generic.js +209 -0
- package/dist/core/code/engine/core/ingestion/method-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/model/field-registry.js +41 -0
- package/dist/core/code/engine/core/ingestion/model/index.js +52 -0
- package/dist/core/code/engine/core/ingestion/model/method-registry.js +138 -0
- package/dist/core/code/engine/core/ingestion/model/owned-members-lookup.js +46 -0
- package/dist/core/code/engine/core/ingestion/model/registration-table.js +234 -0
- package/dist/core/code/engine/core/ingestion/model/resolve.js +183 -0
- package/dist/core/code/engine/core/ingestion/model/scope-resolution-indexes.js +43 -0
- package/dist/core/code/engine/core/ingestion/model/semantic-model.js +179 -0
- package/dist/core/code/engine/core/ingestion/model/symbol-table.js +216 -0
- package/dist/core/code/engine/core/ingestion/model/type-registry.js +84 -0
- package/dist/core/code/engine/core/ingestion/mro-processor.js +709 -0
- package/dist/core/code/engine/core/ingestion/parsing-processor.js +312 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/communities.js +69 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/cross-file.js +71 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/di.js +338 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/http-api-calls.js +312 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/index.js +54 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/mro.js +40 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/orm.js +78 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/parse-impl.js +1286 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/parse.js +41 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/processes.js +193 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/prune-local-symbols.js +29 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/registry.js +52 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/routes.js +409 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/rpc-edges.js +301 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/runner.js +207 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/scan.js +49 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-aop.js +442 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-auto-configuration.js +264 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-config.js +440 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/structure.js +38 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/tools.js +89 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/types.js +40 -0
- package/dist/core/code/engine/core/ingestion/pipeline.js +152 -0
- package/dist/core/code/engine/core/ingestion/process-processor.js +325 -0
- package/dist/core/code/engine/core/ingestion/resolve-references.js +205 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/constant-resolver.js +135 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/django-root-discovery.js +221 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/django.js +428 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/expo.js +39 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/fastapi-router-bindings.js +264 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/laravel.js +501 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/middleware.js +175 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/nextjs.js +81 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/php.js +25 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/python-const-resolver.js +307 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/response-shapes.js +299 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/route-path.js +71 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/spring-shared.js +310 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/spring.js +441 -0
- package/dist/core/code/engine/core/ingestion/scope-extractor-bridge.js +60 -0
- package/dist/core/code/engine/core/ingestion/scope-extractor.js +1373 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/contract/scope-resolver.js +282 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +72 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/edges.js +194 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/ids.js +472 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +49 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +43 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +274 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +93 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/callable-value-flow.js +1240 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/compound-receiver.js +1174 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/free-call-fallback.js +873 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/imported-return-types.js +226 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/mro.js +107 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/overload-narrowing.js +441 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/property-dispatch.js +122 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +1720 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/phase.js +395 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +208 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/registry.js +49 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/run.js +632 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +112 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/resolution-outcome.js +41 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/scope/namespace-targets.js +81 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/scope/walkers.js +1835 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/unresolved-receivers.js +242 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/utils/definition-id.js +22 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/workspace-index.js +151 -0
- package/dist/core/code/engine/core/ingestion/structure-processor.js +40 -0
- package/dist/core/code/engine/core/ingestion/tree-sitter-queries.js +2244 -0
- package/dist/core/code/engine/core/ingestion/ts-js-hoc-utils.js +115 -0
- package/dist/core/code/engine/core/ingestion/type-env.js +1136 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/c-cpp.js +555 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/csharp.js +570 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/dart.js +372 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/go.js +508 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/jvm.js +875 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/php.js +537 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/python.js +477 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/ruby.js +380 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/rust.js +502 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/shared.js +843 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/swift.js +490 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/types.js +2 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/typescript.js +690 -0
- package/dist/core/code/engine/core/ingestion/utils/ast-helpers.js +1693 -0
- package/dist/core/code/engine/core/ingestion/utils/call-analysis.js +779 -0
- package/dist/core/code/engine/core/ingestion/utils/callable-flow-captures.js +932 -0
- package/dist/core/code/engine/core/ingestion/utils/callable-labels.js +49 -0
- package/dist/core/code/engine/core/ingestion/utils/deferred-resolution-profile.js +151 -0
- package/dist/core/code/engine/core/ingestion/utils/effective-ram.js +67 -0
- package/dist/core/code/engine/core/ingestion/utils/env.js +60 -0
- package/dist/core/code/engine/core/ingestion/utils/event-loop.js +9 -0
- package/dist/core/code/engine/core/ingestion/utils/graph-sort.js +103 -0
- package/dist/core/code/engine/core/ingestion/utils/heap-probe.js +45 -0
- package/dist/core/code/engine/core/ingestion/utils/heritage-marker.js +47 -0
- package/dist/core/code/engine/core/ingestion/utils/line-base.js +24 -0
- package/dist/core/code/engine/core/ingestion/utils/max-file-size.js +59 -0
- package/dist/core/code/engine/core/ingestion/utils/method-props.js +198 -0
- package/dist/core/code/engine/core/ingestion/utils/qualified-name.js +73 -0
- package/dist/core/code/engine/core/ingestion/utils/receiver-chain-captures.js +60 -0
- package/dist/core/code/engine/core/ingestion/utils/receiver-chain-codec.js +188 -0
- package/dist/core/code/engine/core/ingestion/utils/scope-tree-walk.js +36 -0
- package/dist/core/code/engine/core/ingestion/utils/symbol-labels.js +48 -0
- package/dist/core/code/engine/core/ingestion/utils/template-arguments.js +187 -0
- package/dist/core/code/engine/core/ingestion/utils/type-parameters.js +209 -0
- package/dist/core/code/engine/core/ingestion/utils/verbose.js +6 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/c-cpp.js +133 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/csharp.js +66 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/dart.js +111 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/go.js +153 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/jvm.js +145 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/php.js +61 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/python.js +104 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/ruby.js +55 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/rust.js +79 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/swift.js +91 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/typescript-javascript.js +86 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/generic.js +111 -0
- package/dist/core/code/engine/core/ingestion/variable-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/vue-sfc-extractor.js +544 -0
- package/dist/core/code/engine/core/ingestion/workers/callable-id.js +122 -0
- package/dist/core/code/engine/core/ingestion/workers/clone-safety.js +470 -0
- package/dist/core/code/engine/core/ingestion/workers/parse-worker.js +2456 -0
- package/dist/core/code/engine/core/ingestion/workers/post-result.js +90 -0
- package/dist/core/code/engine/core/ingestion/workers/quarantine.js +41 -0
- package/dist/core/code/engine/core/ingestion/workers/result-merge.js +59 -0
- package/dist/core/code/engine/core/ingestion/workers/worker-pool.js +1725 -0
- package/dist/core/code/engine/core/ingestion/workspace-config.js +139 -0
- package/dist/core/code/engine/core/lbug/conn-lock.js +72 -0
- package/dist/core/code/engine/core/lbug/csv-generator.js +710 -0
- package/dist/core/code/engine/core/lbug/cypher-escape.js +24 -0
- package/dist/core/code/engine/core/lbug/extension-load-error.js +339 -0
- package/dist/core/code/engine/core/lbug/extension-loader.js +261 -0
- package/dist/core/code/engine/core/lbug/graph-emit-sink.js +584 -0
- package/dist/core/code/engine/core/lbug/lbug-adapter.js +2703 -0
- package/dist/core/code/engine/core/lbug/lbug-config.js +1029 -0
- package/dist/core/code/engine/core/lbug/native-check.js +435 -0
- package/dist/core/code/engine/core/lbug/pool-adapter.js +973 -0
- package/dist/core/code/engine/core/lbug/query-params.js +25 -0
- package/dist/core/code/engine/core/lbug/query-result-utils.js +31 -0
- package/dist/core/code/engine/core/lbug/rel-pair-routing.js +373 -0
- package/dist/core/code/engine/core/lbug/schema.js +771 -0
- package/dist/core/code/engine/core/lbug/shutdown-helpers.js +40 -0
- package/dist/core/code/engine/core/lbug/sidecar-recovery.js +716 -0
- package/dist/core/code/engine/core/lbug/stdio-capture.js +49 -0
- package/dist/core/code/engine/core/lbug/sync-csv-writer.js +115 -0
- package/dist/core/code/engine/core/lbug/wal-checkpoint-driver.js +215 -0
- package/dist/core/code/engine/core/lbug/wal-driver-state.js +28 -0
- package/dist/core/code/engine/core/logger.js +339 -0
- package/dist/core/code/engine/core/platform/capabilities.js +91 -0
- package/dist/core/code/engine/core/run-analyze.js +1098 -0
- package/dist/core/code/engine/core/tree-sitter/parser-loader.js +281 -0
- package/dist/core/code/engine/core/tree-sitter/safe-parse.js +258 -0
- package/dist/core/code/engine/core/tree-sitter/vendored-grammars.js +64 -0
- package/dist/core/code/engine/lib/utils.js +121 -0
- package/dist/core/code/engine/mcp/core/lbug-adapter.js +27 -0
- package/dist/core/code/engine/mcp/local/aop-metadata.js +230 -0
- package/dist/core/code/engine/mcp/local/bean-metadata.js +49 -0
- package/dist/core/code/engine/mcp/local/limits.js +15 -0
- package/dist/core/code/engine/mcp/local/line-display.js +6 -0
- package/dist/core/code/engine/mcp/local/local-backend.js +4142 -0
- package/dist/core/code/engine/storage/branch-index.js +72 -0
- package/dist/core/code/engine/storage/file-hash.js +95 -0
- package/dist/core/code/engine/storage/fs-atomic.js +34 -0
- package/dist/core/code/engine/storage/git.js +555 -0
- package/dist/core/code/engine/storage/index-lock.js +664 -0
- package/dist/core/code/engine/storage/parse-cache.js +650 -0
- package/dist/core/code/engine/storage/parsedfile-store.js +620 -0
- package/dist/core/code/engine/storage/repo-manager.js +1061 -0
- package/dist/core/code/engine/storage/scope-index-store.js +247 -0
- package/dist/core/code/engine/types/pipeline.js +2 -0
- package/dist/core/code/scripts/install-duckdb-extension.mjs +125 -0
- package/dist/core/code/scripts/resolve-analyze-cmd.cjs +346 -0
- package/dist/core/code/shared/graph/types.js +8 -0
- package/dist/core/code/shared/index.js +105 -0
- package/dist/core/code/shared/integrations/circuit-breaker.js +242 -0
- package/dist/core/code/shared/integrations/resilient-fetch.js +224 -0
- package/dist/core/code/shared/integrations/retry.js +70 -0
- package/dist/core/code/shared/integrations/understand-quickly.js +145 -0
- package/dist/core/code/shared/language-detection.js +162 -0
- package/dist/core/code/shared/languages.js +27 -0
- package/dist/core/code/shared/lbug/schema-constants.js +98 -0
- package/dist/core/code/shared/mro-strategy.js +2 -0
- package/dist/core/code/shared/pipeline.js +5 -0
- package/dist/core/code/shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/core/code/shared/scope-resolution/def-index.js +53 -0
- package/dist/core/code/shared/scope-resolution/evidence-weights.js +87 -0
- package/dist/core/code/shared/scope-resolution/finalize-algorithm.js +807 -0
- package/dist/core/code/shared/scope-resolution/language-classification.js +46 -0
- package/dist/core/code/shared/scope-resolution/method-dispatch-index.js +100 -0
- package/dist/core/code/shared/scope-resolution/module-scope-index.js +59 -0
- package/dist/core/code/shared/scope-resolution/origin-priority.js +23 -0
- package/dist/core/code/shared/scope-resolution/parsed-file.js +54 -0
- package/dist/core/code/shared/scope-resolution/position-index.js +136 -0
- package/dist/core/code/shared/scope-resolution/qualified-name-index.js +77 -0
- package/dist/core/code/shared/scope-resolution/reference-site.js +24 -0
- package/dist/core/code/shared/scope-resolution/registries/class-registry.js +32 -0
- package/dist/core/code/shared/scope-resolution/registries/context.js +52 -0
- package/dist/core/code/shared/scope-resolution/registries/evidence.js +152 -0
- package/dist/core/code/shared/scope-resolution/registries/field-registry.js +33 -0
- package/dist/core/code/shared/scope-resolution/registries/lookup-core.js +392 -0
- package/dist/core/code/shared/scope-resolution/registries/lookup-qualified.js +58 -0
- package/dist/core/code/shared/scope-resolution/registries/macro-registry.js +34 -0
- package/dist/core/code/shared/scope-resolution/registries/method-registry.js +34 -0
- package/dist/core/code/shared/scope-resolution/registries/tie-breaks.js +63 -0
- package/dist/core/code/shared/scope-resolution/resolve-type-ref.js +128 -0
- package/dist/core/code/shared/scope-resolution/scope-id.js +49 -0
- package/dist/core/code/shared/scope-resolution/scope-tree.js +225 -0
- package/dist/core/code/shared/scope-resolution/symbol-definition.js +12 -0
- package/dist/core/code/shared/scope-resolution/types.js +25 -0
- package/dist/core/code/shared/test-helpers.js +17 -0
- package/dist/core/code/vendor/leiden/index.cjs +355 -0
- package/dist/core/code/vendor/leiden/utils.cjs +419 -0
- package/dist/core/dbquery/cli.d.ts.map +1 -1
- package/dist/core/dbquery/cli.js +5 -4
- package/dist/core/dbquery/cli.js.map +1 -1
- package/dist/core/dbquery/config.d.ts.map +1 -1
- package/dist/core/dbquery/config.js +39 -3
- package/dist/core/dbquery/config.js.map +1 -1
- package/dist/core/dbquery/drivers/http.d.ts +23 -0
- package/dist/core/dbquery/drivers/http.d.ts.map +1 -0
- package/dist/core/dbquery/drivers/http.js +125 -0
- package/dist/core/dbquery/drivers/http.js.map +1 -0
- package/dist/core/dbquery/drivers/mysql.js +1 -1
- package/dist/core/dbquery/drivers/mysql.js.map +1 -1
- package/dist/core/dbquery/drivers/postgres.js +1 -1
- package/dist/core/dbquery/drivers/postgres.js.map +1 -1
- package/dist/core/dbquery/executor.d.ts.map +1 -1
- package/dist/core/dbquery/executor.js +46 -12
- package/dist/core/dbquery/executor.js.map +1 -1
- package/dist/core/dbquery/format.d.ts.map +1 -1
- package/dist/core/dbquery/format.js +2 -1
- package/dist/core/dbquery/format.js.map +1 -1
- package/dist/core/dbquery/init.d.ts.map +1 -1
- package/dist/core/dbquery/init.js +7 -0
- package/dist/core/dbquery/init.js.map +1 -1
- package/dist/core/dbquery/types.d.ts +55 -7
- package/dist/core/dbquery/types.d.ts.map +1 -1
- package/dist/core/directory.d.ts +17 -0
- package/dist/core/directory.d.ts.map +1 -1
- package/dist/core/directory.js +37 -0
- package/dist/core/directory.js.map +1 -1
- package/dist/core/features/cli.d.ts.map +1 -1
- package/dist/core/features/cli.js +3 -2
- package/dist/core/features/cli.js.map +1 -1
- package/dist/core/features/scanner.d.ts +1 -1
- package/dist/core/features/scanner.d.ts.map +1 -1
- package/dist/core/features/scanner.js +20 -4
- package/dist/core/features/scanner.js.map +1 -1
- package/dist/core/markdown/cli.d.ts.map +1 -1
- package/dist/core/markdown/cli.js +9 -8
- package/dist/core/markdown/cli.js.map +1 -1
- package/dist/core/timeline/cli.d.ts.map +1 -1
- package/dist/core/timeline/cli.js +13 -6
- package/dist/core/timeline/cli.js.map +1 -1
- package/dist/core/timeline/debris.d.ts +20 -0
- package/dist/core/timeline/debris.d.ts.map +1 -0
- package/dist/core/timeline/debris.js +124 -0
- package/dist/core/timeline/debris.js.map +1 -0
- package/dist/core/timeline/hook-runner.d.ts.map +1 -1
- package/dist/core/timeline/hook-runner.js +3 -1
- package/dist/core/timeline/hook-runner.js.map +1 -1
- package/dist/core/timeline/hooks.d.ts.map +1 -1
- package/dist/core/timeline/hooks.js +13 -5
- package/dist/core/timeline/hooks.js.map +1 -1
- package/dist/core/timeline/installer.d.ts +2 -0
- package/dist/core/timeline/installer.d.ts.map +1 -1
- package/dist/core/timeline/installer.js +12 -0
- package/dist/core/timeline/installer.js.map +1 -1
- package/dist/core/timeline/project-root.d.ts +21 -0
- package/dist/core/timeline/project-root.d.ts.map +1 -0
- package/dist/core/timeline/project-root.js +83 -0
- package/dist/core/timeline/project-root.js.map +1 -0
- package/dist/web/register.d.ts.map +1 -1
- package/dist/web/register.js +2 -1
- package/dist/web/register.js.map +1 -1
- package/package.json +1 -1
- package/dist/.claude-template/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-deck/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-deck/references/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-sketch-engine/.cgraphx/timeline-current-turn.json +0 -1
- /package/dist/.claude-template/skills/run-api-test/assets/{template-test-verify.jsonl → template-/346/216/245/345/217/243/346/265/213/350/257/225/351/252/214/350/257/201.jsonl"} +0 -0
|
@@ -0,0 +1,973 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LadybugDB connection pool (core). Used by MCP, sync, search, wiki, etc.
|
|
4
|
+
*
|
|
5
|
+
* LadybugDB Adapter (Connection Pool)
|
|
6
|
+
*
|
|
7
|
+
* Manages a pool of LadybugDB databases keyed by repoId, each with
|
|
8
|
+
* multiple Connection objects for safe concurrent query execution.
|
|
9
|
+
*
|
|
10
|
+
* LadybugDB Connections are NOT thread-safe — a single Connection
|
|
11
|
+
* segfaults if concurrent .query() calls hit it simultaneously.
|
|
12
|
+
* This adapter provides a checkout/return connection pool so each
|
|
13
|
+
* concurrent query gets its own Connection from the same Database.
|
|
14
|
+
*
|
|
15
|
+
* @see https://docs.ladybugdb.com/concurrency — multiple Connections
|
|
16
|
+
* from the same Database is the officially supported concurrency pattern.
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
52
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
53
|
+
};
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.isLbugReady = exports.closeLbug = exports.executeParameterized = exports.executeQuery = exports.initLbug = exports.getMaxResidentRepos = exports.unpinRepo = exports.pinRepo = exports.touchRepo = exports.setActiveStdoutWrite = exports.realStderrWrite = exports.realStdoutWrite = void 0;
|
|
56
|
+
exports.statDbIdentity = statDbIdentity;
|
|
57
|
+
exports.dbIdentityChanged = dbIdentityChanged;
|
|
58
|
+
exports.addPoolCloseListener = addPoolCloseListener;
|
|
59
|
+
exports.silenceStdout = silenceStdout;
|
|
60
|
+
exports.restoreStdout = restoreStdout;
|
|
61
|
+
exports.initLbugWithDb = initLbugWithDb;
|
|
62
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
63
|
+
const lbug = __importStar(require("@ladybugdb/core"));
|
|
64
|
+
const lbug_adapter_js_1 = require("./lbug-adapter.js");
|
|
65
|
+
const query_result_utils_js_1 = require("./query-result-utils.js");
|
|
66
|
+
const lbug_config_js_1 = require("./lbug-config.js");
|
|
67
|
+
const sidecar_recovery_js_1 = require("./sidecar-recovery.js");
|
|
68
|
+
async function statDbIdentity(dbPath) {
|
|
69
|
+
try {
|
|
70
|
+
const s = await promises_1.default.stat(dbPath);
|
|
71
|
+
return { ino: s.ino, mtimeMs: s.mtimeMs, size: s.size };
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** True only when both identities are known AND differ. A stat failure
|
|
78
|
+
* (ENOENT during the brief unlink window of a full rebuild) yields false, so
|
|
79
|
+
* the reader keeps serving its still-valid open inode until the NEW file
|
|
80
|
+
* appears with a different identity — avoiding a churn into a failed reopen
|
|
81
|
+
* mid-rebuild. */
|
|
82
|
+
function dbIdentityChanged(prev, next) {
|
|
83
|
+
if (!prev || !next)
|
|
84
|
+
return false;
|
|
85
|
+
return prev.ino !== next.ino || prev.mtimeMs !== next.mtimeMs || prev.size !== next.size;
|
|
86
|
+
}
|
|
87
|
+
const pool = new Map();
|
|
88
|
+
const poolCloseListeners = new Set();
|
|
89
|
+
/**
|
|
90
|
+
* Subscribe to pool-close events. Returns a disposer that removes the
|
|
91
|
+
* listener (handy for tests).
|
|
92
|
+
*/
|
|
93
|
+
function addPoolCloseListener(listener) {
|
|
94
|
+
poolCloseListeners.add(listener);
|
|
95
|
+
return () => {
|
|
96
|
+
poolCloseListeners.delete(listener);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const dbCache = new Map();
|
|
100
|
+
/** Max repos in the pool (LRU eviction) */
|
|
101
|
+
const MAX_POOL_SIZE = 5;
|
|
102
|
+
/** Idle timeout before closing a repo's connections */
|
|
103
|
+
const IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
104
|
+
/** Max connections per repo (caps concurrent queries per repo) */
|
|
105
|
+
const MAX_CONNS_PER_REPO = 8;
|
|
106
|
+
/**
|
|
107
|
+
* Repos exempt from AUTOMATIC eviction (LRU + idle timeout) until explicitly
|
|
108
|
+
* unpinned. Used by bounded multi-repo operations like `group sync`, which
|
|
109
|
+
* initializes one pool per repo and then resolves cross-repo manifest/workspace
|
|
110
|
+
* links against ALL of those pools after the init loop. Without pinning, a
|
|
111
|
+
* group larger than MAX_POOL_SIZE would LRU-evict the earliest repos before
|
|
112
|
+
* resolution runs, leaving the deferred executor closures pointing at dead pool
|
|
113
|
+
* entries (issue #2189).
|
|
114
|
+
*
|
|
115
|
+
* Pins are REFERENCE-COUNTED: the map holds repoId → active lease count. This
|
|
116
|
+
* lets overlapping holders (two windows of one sync, or two concurrent
|
|
117
|
+
* `group sync` calls sharing a repo) coexist safely — the repo stays exempt
|
|
118
|
+
* until the LAST holder releases. A boolean Set could not represent "two
|
|
119
|
+
* holders," so the first release would wrongly clear a pin another holder still
|
|
120
|
+
* needs (PR #2191 review, Finding 1).
|
|
121
|
+
*
|
|
122
|
+
* Pins block only automatic eviction (LRU + idle). Explicit teardown
|
|
123
|
+
* (closeOne / closeLbug) always closes the entry and force-clears its count —
|
|
124
|
+
* teardown is authoritative. A present key always means count ≥ 1. While every
|
|
125
|
+
* pooled repo is pinned, evictLRU finds no eligible victim and the pool may
|
|
126
|
+
* transiently exceed MAX_POOL_SIZE — the same soft-cap behavior that already
|
|
127
|
+
* occurs when every entry is checked out.
|
|
128
|
+
*/
|
|
129
|
+
const pinnedRepos = new Map();
|
|
130
|
+
// 行为中性的 RSS 追踪,服务于池级 evict→reload 内存复现。两个不变量保证它在
|
|
131
|
+
// pool init/close 热路径上安全:只写 stderr(避免污染 stdout 的结果输出);
|
|
132
|
+
// CGRAPH_POOL_RSS_TRACE 门控使其默认 no-op——每次调用仅一次环境变量比较,
|
|
133
|
+
// 除非有 harness 显式开启。
|
|
134
|
+
function traceRss(event, repoId) {
|
|
135
|
+
if (process.env.CGRAPH_POOL_RSS_TRACE !== '1')
|
|
136
|
+
return;
|
|
137
|
+
const rssMb = Math.round(process.memoryUsage().rss / (1024 * 1024));
|
|
138
|
+
process.stderr.write(`[pool-rss] ${event} repo=${repoId} pool=${pool.size} dbCache=${dbCache.size} rssMB=${rssMb}\n`);
|
|
139
|
+
}
|
|
140
|
+
let idleTimer = null;
|
|
141
|
+
// Stdout 捕获状态位于 `cgraph/src/core/lbug/stdio-capture.ts` —— 一个零非
|
|
142
|
+
// `node:` 导入的叶子模块。这里重新导出相同符号,使既有的测试 mock 接缝
|
|
143
|
+
//(`cgraph/src/mcp/core/lbug-adapter.ts` 对本文件做 `export *`,8+ 个测试
|
|
144
|
+
// 文件用该路径 `vi.mock(...)`)无需改动即可继续工作。事实来源是那个叶子
|
|
145
|
+
// 模块;此处的再导出只是兼容 shim。
|
|
146
|
+
//
|
|
147
|
+
// 为什么单独拆叶子模块:PR #1383 的对抗评审发现,把这份状态放进
|
|
148
|
+
// pool-adapter.ts 会把 `@ladybugdb/core` 拖进 CLI 入口的静态导入闭包,
|
|
149
|
+
// 在 stdout 保护就绪前污染 stdout。经叶子模块中转即可断链(MCP 协议层
|
|
150
|
+
// 裁剪后哨兵注册方已移除,但该结构保留)。
|
|
151
|
+
var stdio_capture_js_1 = require("./stdio-capture.js");
|
|
152
|
+
Object.defineProperty(exports, "realStdoutWrite", { enumerable: true, get: function () { return stdio_capture_js_1.realStdoutWrite; } });
|
|
153
|
+
Object.defineProperty(exports, "realStderrWrite", { enumerable: true, get: function () { return stdio_capture_js_1.realStderrWrite; } });
|
|
154
|
+
Object.defineProperty(exports, "setActiveStdoutWrite", { enumerable: true, get: function () { return stdio_capture_js_1.setActiveStdoutWrite; } });
|
|
155
|
+
const stdio_capture_js_2 = require("./stdio-capture.js");
|
|
156
|
+
let stdoutSilenceCount = 0;
|
|
157
|
+
/** True while pre-warming connections — prevents watchdog from prematurely restoring stdout */
|
|
158
|
+
let preWarmActive = false;
|
|
159
|
+
/**
|
|
160
|
+
* Start the idle cleanup timer (runs every 60s)
|
|
161
|
+
*/
|
|
162
|
+
function ensureIdleTimer() {
|
|
163
|
+
if (idleTimer)
|
|
164
|
+
return;
|
|
165
|
+
idleTimer = setInterval(() => {
|
|
166
|
+
const now = Date.now();
|
|
167
|
+
for (const [repoId, entry] of pool) {
|
|
168
|
+
if (pinnedRepos.has(repoId))
|
|
169
|
+
continue;
|
|
170
|
+
if (now - entry.lastUsed > IDLE_TIMEOUT_MS && entry.checkedOut === 0) {
|
|
171
|
+
closeOne(repoId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}, 60_000);
|
|
175
|
+
if (idleTimer && typeof idleTimer === 'object' && 'unref' in idleTimer) {
|
|
176
|
+
idleTimer.unref();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Touch a repo to reset its idle timeout.
|
|
181
|
+
* Call this during long-running operations to prevent the connection from being closed.
|
|
182
|
+
*/
|
|
183
|
+
const touchRepo = (repoId) => {
|
|
184
|
+
const entry = pool.get(repoId);
|
|
185
|
+
if (entry) {
|
|
186
|
+
entry.lastUsed = Date.now();
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
exports.touchRepo = touchRepo;
|
|
190
|
+
/**
|
|
191
|
+
* Acquire one eviction-exemption lease on a repo (LRU + idle timeout) by
|
|
192
|
+
* incrementing its reference count. The repoId must match the key passed to
|
|
193
|
+
* initLbug (e.g. group sync leases by handle.id — the same id it inits with).
|
|
194
|
+
* Leasing a repoId before it enters the pool is allowed and protects the entry
|
|
195
|
+
* once it is created, but the lease does NOT survive a teardown: closeOne
|
|
196
|
+
* force-clears the count, so a later re-init of the same repoId starts
|
|
197
|
+
* unpinned. Each pinRepo MUST be balanced by exactly one release (the repo
|
|
198
|
+
* stays exempt until the last lease is released). See the pinnedRepos docstring
|
|
199
|
+
* for the full contract.
|
|
200
|
+
*
|
|
201
|
+
* Returns a `release` disposer (mirroring addPoolCloseListener) that releases
|
|
202
|
+
* THIS lease exactly once — calling it twice is a no-op, so it can never
|
|
203
|
+
* over-decrement a sibling holder's count. Prefer the disposer
|
|
204
|
+
* (`const release = pinRepo(id); try { … } finally { release(); }`) so the
|
|
205
|
+
* pin/release pair is leak-proof; unpinRepo remains available for callers that
|
|
206
|
+
* pair explicitly.
|
|
207
|
+
*/
|
|
208
|
+
const pinRepo = (repoId) => {
|
|
209
|
+
pinnedRepos.set(repoId, (pinnedRepos.get(repoId) ?? 0) + 1);
|
|
210
|
+
let released = false;
|
|
211
|
+
return () => {
|
|
212
|
+
if (released)
|
|
213
|
+
return;
|
|
214
|
+
released = true;
|
|
215
|
+
(0, exports.unpinRepo)(repoId);
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
exports.pinRepo = pinRepo;
|
|
219
|
+
/**
|
|
220
|
+
* Release one eviction-exemption lease on a repo. The repo becomes eligible for
|
|
221
|
+
* automatic eviction again only once its count reaches 0 (the key is deleted).
|
|
222
|
+
* Idempotent at the floor: releasing a repo with no active lease is a no-op (no
|
|
223
|
+
* negative counts). Does NOT close the repo's pool.
|
|
224
|
+
*/
|
|
225
|
+
const unpinRepo = (repoId) => {
|
|
226
|
+
const count = pinnedRepos.get(repoId);
|
|
227
|
+
if (count === undefined)
|
|
228
|
+
return;
|
|
229
|
+
if (count <= 1) {
|
|
230
|
+
pinnedRepos.delete(repoId);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
pinnedRepos.set(repoId, count - 1);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
exports.unpinRepo = unpinRepo;
|
|
237
|
+
/**
|
|
238
|
+
* Maximum number of repos a bounded multi-repo operation (e.g. group sync's
|
|
239
|
+
* windowed manifest resolution) should hold resident at once. Equals
|
|
240
|
+
* MAX_POOL_SIZE today, but exposed under an intent-named accessor so callers
|
|
241
|
+
* size their working set against "max repos a bounded op should hold" rather
|
|
242
|
+
* than coupling to the LRU eviction-cap constant, which may be tuned
|
|
243
|
+
* independently.
|
|
244
|
+
*/
|
|
245
|
+
const getMaxResidentRepos = () => MAX_POOL_SIZE;
|
|
246
|
+
exports.getMaxResidentRepos = getMaxResidentRepos;
|
|
247
|
+
/**
|
|
248
|
+
* Evict the least-recently-used repo if pool is at capacity.
|
|
249
|
+
* Pinned repos are never chosen as the eviction victim — when every eligible
|
|
250
|
+
* entry is pinned, no eviction occurs and the pool transiently exceeds
|
|
251
|
+
* MAX_POOL_SIZE (see the pinnedRepos docstring).
|
|
252
|
+
*/
|
|
253
|
+
function evictLRU() {
|
|
254
|
+
if (pool.size < MAX_POOL_SIZE)
|
|
255
|
+
return;
|
|
256
|
+
let oldestId = null;
|
|
257
|
+
let oldestTime = Infinity;
|
|
258
|
+
for (const [id, entry] of pool) {
|
|
259
|
+
if (pinnedRepos.has(id))
|
|
260
|
+
continue;
|
|
261
|
+
if (entry.checkedOut === 0 && entry.lastUsed < oldestTime) {
|
|
262
|
+
oldestTime = entry.lastUsed;
|
|
263
|
+
oldestId = id;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (oldestId) {
|
|
267
|
+
closeOne(oldestId);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Remove a repo from the pool, close its connections, and release its
|
|
272
|
+
* shared Database ref. Only closes the Database when no other repoIds
|
|
273
|
+
* reference it (refCount === 0).
|
|
274
|
+
*/
|
|
275
|
+
function closeOne(repoId) {
|
|
276
|
+
const entry = pool.get(repoId);
|
|
277
|
+
if (!entry)
|
|
278
|
+
return;
|
|
279
|
+
entry.closed = true;
|
|
280
|
+
// Reject any callers still queued for a connection: the pool is going away
|
|
281
|
+
// (re-init / teardown / LRU eviction), so they must fail fast with an
|
|
282
|
+
// actionable error instead of hanging until WAITER_TIMEOUT_MS and then
|
|
283
|
+
// surfacing a misleading "pool exhausted" (#2068 follow-up). Draining the
|
|
284
|
+
// queue also guarantees checkin() below finds no waiter expecting a
|
|
285
|
+
// connection, so a connection returned after close is simply closed.
|
|
286
|
+
if (entry.waiters.length > 0) {
|
|
287
|
+
const closedErr = new Error(`LadybugDB connection pool closed for repo "${repoId}" (re-init/teardown); retry the query.`);
|
|
288
|
+
for (const waiter of entry.waiters)
|
|
289
|
+
waiter.reject(closedErr);
|
|
290
|
+
entry.waiters.length = 0;
|
|
291
|
+
}
|
|
292
|
+
// Close available connections — fire-and-forget with .catch() to prevent
|
|
293
|
+
// unhandled rejections. Native close() returns Promise<void> but can crash
|
|
294
|
+
// the N-API destructor on macOS/Windows; deferring to process exit lets
|
|
295
|
+
// dangerouslyIgnoreUnhandledErrors absorb the crash.
|
|
296
|
+
for (const conn of entry.available) {
|
|
297
|
+
conn.close().catch(() => { });
|
|
298
|
+
}
|
|
299
|
+
entry.available.length = 0;
|
|
300
|
+
// Checked-out connections can't be closed here — they're in-flight.
|
|
301
|
+
// The checkin() function detects entry.closed and closes them on return.
|
|
302
|
+
// Only close the Database when no other repoIds reference it.
|
|
303
|
+
// External databases (injected via initLbugWithDb) are never closed here —
|
|
304
|
+
// the core adapter owns them and handles their lifecycle.
|
|
305
|
+
const shared = dbCache.get(entry.dbPath);
|
|
306
|
+
if (shared) {
|
|
307
|
+
shared.refCount--;
|
|
308
|
+
if (shared.refCount === 0) {
|
|
309
|
+
if (shared.external) {
|
|
310
|
+
// External databases are owned by the core adapter — don't close
|
|
311
|
+
// or remove from cache. Keep the entry so future initLbug() calls
|
|
312
|
+
// for the same dbPath reuse it instead of hitting a file lock.
|
|
313
|
+
shared.refCount = 0;
|
|
314
|
+
shared.vectorLoaded = false;
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
shared.db.close().catch(() => { });
|
|
318
|
+
dbCache.delete(entry.dbPath);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
pool.delete(repoId);
|
|
323
|
+
// Clear any eviction pin — the entry is gone, so the pin is meaningless and
|
|
324
|
+
// would otherwise leak across operations in a long-lived process. Teardown
|
|
325
|
+
// is authoritative: an explicit close always wins over a pin.
|
|
326
|
+
pinnedRepos.delete(repoId);
|
|
327
|
+
// Notify listeners AFTER the pool entry is gone so any cache-invalidation
|
|
328
|
+
// they perform is consistent with `isLbugReady(repoId) === false`.
|
|
329
|
+
for (const listener of poolCloseListeners) {
|
|
330
|
+
try {
|
|
331
|
+
listener(repoId);
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Isolate listener failures — teardown must complete.
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
traceRss('close', repoId);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Create a new Connection from a repo's Database.
|
|
341
|
+
* Silences stdout to prevent native module output from corrupting MCP stdio.
|
|
342
|
+
*/
|
|
343
|
+
let activeQueryCount = 0;
|
|
344
|
+
/**
|
|
345
|
+
* Silence stdout by replacing process.stdout.write with a no-op.
|
|
346
|
+
* Uses a reference counter so nested silence/restore pairs are safe.
|
|
347
|
+
* Exported so other modules (e.g. embedder) use the same mechanism instead
|
|
348
|
+
* of independently patching stdout, which causes restore-order conflicts.
|
|
349
|
+
*/
|
|
350
|
+
function silenceStdout() {
|
|
351
|
+
if (stdoutSilenceCount++ === 0) {
|
|
352
|
+
// eslint-disable-next-line no-restricted-syntax -- silencing infrastructure; replacement is a no-op
|
|
353
|
+
process.stdout.write = (() => true);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function restoreStdout() {
|
|
357
|
+
if (--stdoutSilenceCount <= 0) {
|
|
358
|
+
stdoutSilenceCount = 0;
|
|
359
|
+
// eslint-disable-next-line no-restricted-syntax -- restoring the active stdout-write handler is the silencing API contract
|
|
360
|
+
process.stdout.write = (0, stdio_capture_js_2.getActiveStdoutWrite)();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Safety watchdog: restore stdout if it gets stuck silenced (e.g. native crash
|
|
364
|
+
// inside createConnection before restoreStdout runs).
|
|
365
|
+
// Exempts active queries and pre-warm — these legitimately hold silence for
|
|
366
|
+
// longer than 1 second (queries can take up to QUERY_TIMEOUT_MS = 30s).
|
|
367
|
+
setInterval(() => {
|
|
368
|
+
if (stdoutSilenceCount > 0 && !preWarmActive && activeQueryCount === 0) {
|
|
369
|
+
stdoutSilenceCount = 0;
|
|
370
|
+
// eslint-disable-next-line no-restricted-syntax -- watchdog recovery for stuck silencing
|
|
371
|
+
process.stdout.write = (0, stdio_capture_js_2.getActiveStdoutWrite)();
|
|
372
|
+
}
|
|
373
|
+
}, 1000).unref();
|
|
374
|
+
function createConnection(db) {
|
|
375
|
+
silenceStdout();
|
|
376
|
+
try {
|
|
377
|
+
const conn = new lbug.Connection(db);
|
|
378
|
+
// Bound a single query at the engine level so a pathological query cannot
|
|
379
|
+
// hang a pooled connection past the JS-side Promise.race guard (which frees
|
|
380
|
+
// the waiter but not the native call). Matches QUERY_TIMEOUT_MS. Guarded so
|
|
381
|
+
// test doubles that don't model the engine method don't break connection
|
|
382
|
+
// creation.
|
|
383
|
+
if (typeof conn.setQueryTimeout === 'function') {
|
|
384
|
+
conn.setQueryTimeout(QUERY_TIMEOUT_MS);
|
|
385
|
+
}
|
|
386
|
+
return conn;
|
|
387
|
+
}
|
|
388
|
+
finally {
|
|
389
|
+
restoreStdout();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/** Query timeout in milliseconds */
|
|
393
|
+
const QUERY_TIMEOUT_MS = 30_000;
|
|
394
|
+
/** Waiter queue timeout in milliseconds */
|
|
395
|
+
const WAITER_TIMEOUT_MS = 15_000;
|
|
396
|
+
// Read-only open retry while `cgraph analyze` writes. Catalogued as entry 4
|
|
397
|
+
// of the lbug-config retry-budget registry.
|
|
398
|
+
const LOCK_RETRY_ATTEMPTS = 3;
|
|
399
|
+
const LOCK_RETRY_DELAY_MS = 2000;
|
|
400
|
+
// determinism: probe — existence only. `probeDatabaseForShadowReplay` calls
|
|
401
|
+
// `getAll()` purely to force the shadow replay and then discards the result;
|
|
402
|
+
// the function returns void, so no row ever reaches a caller.
|
|
403
|
+
const SHADOW_REPLAY_PROBE_QUERY = 'MATCH (n) RETURN n LIMIT 1';
|
|
404
|
+
const poolSidecarLogger = {
|
|
405
|
+
warn: (message) => {
|
|
406
|
+
(0, stdio_capture_js_2.realStderrWrite)(`${message}\n`);
|
|
407
|
+
},
|
|
408
|
+
debug: (_message) => { },
|
|
409
|
+
info: (message) => {
|
|
410
|
+
(0, stdio_capture_js_2.realStderrWrite)(`${message}\n`);
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Pool-local quarantine guard that tolerates the concurrent-peer race the
|
|
415
|
+
* direct adapter does NOT face (the direct adapter holds `acquireInitLock`,
|
|
416
|
+
* a cross-process file lock, around its quarantine calls — so any ENOENT
|
|
417
|
+
* there is a real bug, not a benign race).
|
|
418
|
+
*
|
|
419
|
+
* On ENOENT from `fs.rename`, re-inspects via `statIfExists` to confirm the
|
|
420
|
+
* WAL really is gone. If gone, returns `{ kind: 'peer-handled' }`. If the
|
|
421
|
+
* WAL is somehow still present after the ENOENT (filesystem race we don't
|
|
422
|
+
* fully model), re-throws as a classified error rather than silently
|
|
423
|
+
* returning success — preserves the lock-invariant principle at the pool
|
|
424
|
+
* sites too.
|
|
425
|
+
*
|
|
426
|
+
* On any non-ENOENT failure, classifies through `renameFailureMessage`:
|
|
427
|
+
* EACCES/EPERM/EBUSY → permission-specific message; everything else
|
|
428
|
+
* (including the LadybugDB missing-shadow error if it ever propagates here)
|
|
429
|
+
* → `shadowSidecarRecoveryMessage`.
|
|
430
|
+
*
|
|
431
|
+
* See plan: docs/plans/2026-05-21-001-fix-pr-1747-quarantine-enoent-and-large-wal-plan.md (U2)
|
|
432
|
+
*/
|
|
433
|
+
async function tryQuarantineForMissingShadow(dbPath, opts) {
|
|
434
|
+
// Refuse (throw) before renaming a live WAL when the shadow is present on
|
|
435
|
+
// disk or the orphan WAL is too large — parity with the serve path's
|
|
436
|
+
// refuseLargeWalQuarantine (issue #2382 review, Finding B). Kept OUTSIDE the
|
|
437
|
+
// try so the actionable recovery message propagates to the MCP caller rather
|
|
438
|
+
// than being re-wrapped as a rename failure.
|
|
439
|
+
await (0, sidecar_recovery_js_1.guardWalQuarantine)(dbPath, opts.reason, opts.err, poolSidecarLogger);
|
|
440
|
+
try {
|
|
441
|
+
const quarantinePath = await (0, sidecar_recovery_js_1.quarantineWalForMissingShadow)(dbPath, {
|
|
442
|
+
logger: poolSidecarLogger,
|
|
443
|
+
level: 'warn',
|
|
444
|
+
reason: opts.reason,
|
|
445
|
+
});
|
|
446
|
+
return { kind: 'quarantined', path: quarantinePath };
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
if ((0, sidecar_recovery_js_1.isMissingFsError)(err)) {
|
|
450
|
+
const walStat = await (0, sidecar_recovery_js_1.statIfExists)(`${dbPath}.wal`);
|
|
451
|
+
if (walStat === null) {
|
|
452
|
+
return { kind: 'peer-handled' };
|
|
453
|
+
}
|
|
454
|
+
// Defensive: ENOENT during rename but WAL still present afterwards.
|
|
455
|
+
// Don't silently swallow — surface a classified error. ENOENT falls
|
|
456
|
+
// through to shadowSidecarRecoveryMessage in renameFailureMessage.
|
|
457
|
+
throw new Error((0, sidecar_recovery_js_1.renameFailureMessage)(dbPath, err));
|
|
458
|
+
}
|
|
459
|
+
// Classify the rename failure itself — EACCES/EPERM/EBUSY get the
|
|
460
|
+
// permission-specific message; everything else falls through.
|
|
461
|
+
throw new Error((0, sidecar_recovery_js_1.renameFailureMessage)(dbPath, err));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
async function probeDatabaseForShadowReplay(db) {
|
|
465
|
+
const conn = createConnection(db);
|
|
466
|
+
try {
|
|
467
|
+
const queryResult = await conn.query(SHADOW_REPLAY_PROBE_QUERY);
|
|
468
|
+
const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
|
|
469
|
+
await result.getAll();
|
|
470
|
+
result.close?.();
|
|
471
|
+
}
|
|
472
|
+
finally {
|
|
473
|
+
await conn.close().catch(() => { });
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
async function replayShadowPagesWithWritableOpen(dbPath) {
|
|
477
|
+
let db;
|
|
478
|
+
try {
|
|
479
|
+
db = (0, lbug_config_js_1.createLbugDatabase)(lbug, (0, lbug_config_js_1.toNativeSafePath)(dbPath), { throwOnWalReplayFailure: false });
|
|
480
|
+
await db.init();
|
|
481
|
+
await probeDatabaseForShadowReplay(db);
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
if ((0, sidecar_recovery_js_1.isMissingShadowSidecarError)(err)) {
|
|
485
|
+
await tryQuarantineForMissingShadow(dbPath, {
|
|
486
|
+
reason: 'pool writable replay recovery',
|
|
487
|
+
err,
|
|
488
|
+
});
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
throw err;
|
|
492
|
+
}
|
|
493
|
+
finally {
|
|
494
|
+
if (db)
|
|
495
|
+
await db.close().catch(() => { });
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async function openReadOnlyDatabase(dbPath) {
|
|
499
|
+
let db;
|
|
500
|
+
silenceStdout();
|
|
501
|
+
try {
|
|
502
|
+
await (0, sidecar_recovery_js_1.preflightLbugSidecars)(dbPath, {
|
|
503
|
+
mode: 'read-only',
|
|
504
|
+
logger: poolSidecarLogger,
|
|
505
|
+
allowQuarantine: true,
|
|
506
|
+
});
|
|
507
|
+
db = (0, lbug_config_js_1.createLbugDatabase)(lbug, (0, lbug_config_js_1.toNativeSafePath)(dbPath), {
|
|
508
|
+
readOnly: true,
|
|
509
|
+
throwOnWalReplayFailure: false,
|
|
510
|
+
});
|
|
511
|
+
await db.init();
|
|
512
|
+
try {
|
|
513
|
+
await probeDatabaseForShadowReplay(db);
|
|
514
|
+
}
|
|
515
|
+
catch (err) {
|
|
516
|
+
if ((0, sidecar_recovery_js_1.isMissingShadowSidecarError)(err)) {
|
|
517
|
+
await db.close().catch(() => { });
|
|
518
|
+
db = undefined;
|
|
519
|
+
await tryQuarantineForMissingShadow(dbPath, {
|
|
520
|
+
reason: 'pool read-only recovery',
|
|
521
|
+
err,
|
|
522
|
+
});
|
|
523
|
+
await (0, sidecar_recovery_js_1.preflightLbugSidecars)(dbPath, {
|
|
524
|
+
mode: 'read-only',
|
|
525
|
+
logger: poolSidecarLogger,
|
|
526
|
+
allowQuarantine: true,
|
|
527
|
+
});
|
|
528
|
+
db = (0, lbug_config_js_1.createLbugDatabase)(lbug, (0, lbug_config_js_1.toNativeSafePath)(dbPath), {
|
|
529
|
+
readOnly: true,
|
|
530
|
+
throwOnWalReplayFailure: false,
|
|
531
|
+
});
|
|
532
|
+
await db.init();
|
|
533
|
+
await probeDatabaseForShadowReplay(db);
|
|
534
|
+
return db;
|
|
535
|
+
}
|
|
536
|
+
if (!(0, sidecar_recovery_js_1.isReadOnlyShadowReplayError)(err)) {
|
|
537
|
+
throw err;
|
|
538
|
+
}
|
|
539
|
+
await db.close().catch(() => { });
|
|
540
|
+
db = undefined;
|
|
541
|
+
await replayShadowPagesWithWritableOpen(dbPath);
|
|
542
|
+
db = (0, lbug_config_js_1.createLbugDatabase)(lbug, (0, lbug_config_js_1.toNativeSafePath)(dbPath), {
|
|
543
|
+
readOnly: true,
|
|
544
|
+
throwOnWalReplayFailure: false,
|
|
545
|
+
});
|
|
546
|
+
await db.init();
|
|
547
|
+
await probeDatabaseForShadowReplay(db);
|
|
548
|
+
}
|
|
549
|
+
return db;
|
|
550
|
+
}
|
|
551
|
+
catch (err) {
|
|
552
|
+
if (db)
|
|
553
|
+
await db.close().catch(() => { });
|
|
554
|
+
throw err;
|
|
555
|
+
}
|
|
556
|
+
finally {
|
|
557
|
+
restoreStdout();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Quarantine the .wal file and retry opening the database.
|
|
562
|
+
* Used when the initial open fails with a WAL corruption error.
|
|
563
|
+
*/
|
|
564
|
+
async function tryQuarantineAndReopen(dbPath, repoId) {
|
|
565
|
+
const walPath = dbPath + '.wal';
|
|
566
|
+
const quarantineName = `${walPath}.corrupt.${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
567
|
+
try {
|
|
568
|
+
await promises_1.default.rename(walPath, quarantineName);
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ` +
|
|
572
|
+
`Run \`cgraph analyze\` to rebuild the index. (quarantine failed)`);
|
|
573
|
+
}
|
|
574
|
+
(0, stdio_capture_js_2.realStderrWrite)(`GitNexus: LadybugDB WAL quarantined for ${repoId}; graph may be stale. ` +
|
|
575
|
+
`Run \`cgraph analyze\` to rebuild the index.\n`);
|
|
576
|
+
return await openReadOnlyDatabase(dbPath);
|
|
577
|
+
}
|
|
578
|
+
/** Deduplicates concurrent initLbug calls for the same repoId */
|
|
579
|
+
const initPromises = new Map();
|
|
580
|
+
/**
|
|
581
|
+
* Initialize (or reuse) a Database + connection pool for a specific repo.
|
|
582
|
+
* Retries on lock errors (e.g., when `cgraph analyze` is running).
|
|
583
|
+
*
|
|
584
|
+
* Concurrent calls for the same repoId are deduplicated — the second caller
|
|
585
|
+
* awaits the first's in-progress init rather than starting a redundant one.
|
|
586
|
+
*/
|
|
587
|
+
/**
|
|
588
|
+
* Returns `true` when this call (re)opened a fresh handle onto the current
|
|
589
|
+
* on-disk file, `false` when it reused/served the existing handle (unchanged,
|
|
590
|
+
* or changed-but-a-query-is-in-flight). Callers that gate their own freshness
|
|
591
|
+
* bookkeeping on "did the pool actually roll over" (LocalBackend) use the
|
|
592
|
+
* return value; callers that only need the pool ready can ignore it.
|
|
593
|
+
*/
|
|
594
|
+
const initLbug = async (repoId, dbPath) => {
|
|
595
|
+
const existing = pool.get(repoId);
|
|
596
|
+
if (existing) {
|
|
597
|
+
existing.lastUsed = Date.now();
|
|
598
|
+
// Detect an index that `analyze` rebuilt or mutated under this live read
|
|
599
|
+
// pool. Without this, the pool keeps serving the old (POSIX:
|
|
600
|
+
// unlinked-but-open) inode until LRU/idle eviction — a stale-read window
|
|
601
|
+
// of up to IDLE_TIMEOUT_MS after analyze finishes.
|
|
602
|
+
const current = await statDbIdentity(dbPath);
|
|
603
|
+
if (!dbIdentityChanged(existing.dbIdentity, current))
|
|
604
|
+
return false; // unchanged → reuse
|
|
605
|
+
// A query is in flight on this entry; closing its connection (and the
|
|
606
|
+
// shared Database at refCount 0) mid-use is a native use-after-free. Serve
|
|
607
|
+
// the current handle for this dispatch — the next initLbug that finds the
|
|
608
|
+
// entry idle (checkedOut === 0) reopens, since the identity stays divergent
|
|
609
|
+
// until then. Under sustained overlapping queries `checkedOut` may never
|
|
610
|
+
// reach 0 and `lastUsed` keeps the idle timer from evicting, so this window
|
|
611
|
+
// is bounded by the load, not IDLE_TIMEOUT_MS — the data stays consistent
|
|
612
|
+
// (a complete older snapshot), just not the newest. Callers that route
|
|
613
|
+
// freshness THROUGH initLbug (rather than calling closeLbug directly) get
|
|
614
|
+
// this guard for free; that is why LocalBackend delegates here (#2614).
|
|
615
|
+
if (existing.checkedOut > 0)
|
|
616
|
+
return false;
|
|
617
|
+
closeOne(repoId); // idle & changed → evict, then fall through to reopen the new file
|
|
618
|
+
}
|
|
619
|
+
// Deduplicate concurrent init calls for the same repoId —
|
|
620
|
+
// prevents double-init race when multiple parallel tool calls
|
|
621
|
+
// trigger initialization for the same repo simultaneously.
|
|
622
|
+
const pending = initPromises.get(repoId);
|
|
623
|
+
if (pending) {
|
|
624
|
+
await pending;
|
|
625
|
+
return true;
|
|
626
|
+
}
|
|
627
|
+
const promise = doInitLbug(repoId, dbPath);
|
|
628
|
+
initPromises.set(repoId, promise);
|
|
629
|
+
try {
|
|
630
|
+
await promise;
|
|
631
|
+
}
|
|
632
|
+
finally {
|
|
633
|
+
initPromises.delete(repoId);
|
|
634
|
+
}
|
|
635
|
+
return true;
|
|
636
|
+
};
|
|
637
|
+
exports.initLbug = initLbug;
|
|
638
|
+
/**
|
|
639
|
+
* Internal init — creates DB, pre-warms connections, loads optional extensions,
|
|
640
|
+
* then registers pool. Pool entry is registered LAST so concurrent executeQuery
|
|
641
|
+
* calls see either "not initialized" (and throw) or a fully ready pool — never
|
|
642
|
+
* a half-built one.
|
|
643
|
+
*/
|
|
644
|
+
async function doInitLbug(repoId, dbPath) {
|
|
645
|
+
// Check if database exists
|
|
646
|
+
try {
|
|
647
|
+
await promises_1.default.stat(dbPath);
|
|
648
|
+
}
|
|
649
|
+
catch {
|
|
650
|
+
throw new Error(`LadybugDB not found at ${dbPath}. Run: cgraph analyze`);
|
|
651
|
+
}
|
|
652
|
+
evictLRU();
|
|
653
|
+
// Reuse an existing native Database if another repoId already opened this path.
|
|
654
|
+
// This prevents buffer manager exhaustion from multiple mmap regions on the same file.
|
|
655
|
+
let shared = dbCache.get(dbPath);
|
|
656
|
+
if (shared && !shared.external && shared.dbIdentity) {
|
|
657
|
+
// #2614 F2: a cached read-only Database is keyed by dbPath and shared across
|
|
658
|
+
// pool consumers. If the on-disk index was rebuilt/swapped (new inode) while
|
|
659
|
+
// ANOTHER consumer still holds this handle (refCount kept it alive), reusing
|
|
660
|
+
// it serves a superseded index. Unreachable via the MCP backend (one
|
|
661
|
+
// consumer per lbugPath ⇒ refCount hits 0 ⇒ closeOne reopens fresh); a
|
|
662
|
+
// complete fix needs per-inode handles rather than a dbPath-keyed cache.
|
|
663
|
+
// Surface it so the corner is observable instead of silently stale.
|
|
664
|
+
const current = await statDbIdentity(dbPath);
|
|
665
|
+
if (dbIdentityChanged(shared.dbIdentity, current)) {
|
|
666
|
+
(0, stdio_capture_js_2.realStderrWrite)(`GitNexus: reusing a shared read-only handle for ${dbPath} whose on-disk ` +
|
|
667
|
+
`index was rebuilt while another consumer holds it — results may be stale ` +
|
|
668
|
+
`until that consumer releases it.\n`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (!shared) {
|
|
672
|
+
// Open in read-only mode — MCP server never writes to the database.
|
|
673
|
+
// This allows multiple MCP server instances to read concurrently, and
|
|
674
|
+
// avoids lock conflicts when `cgraph analyze` is writing.
|
|
675
|
+
let lastError = null;
|
|
676
|
+
for (let attempt = 1; attempt <= LOCK_RETRY_ATTEMPTS; attempt++) {
|
|
677
|
+
try {
|
|
678
|
+
const db = await openReadOnlyDatabase(dbPath);
|
|
679
|
+
shared = { db, refCount: 0, dbIdentity: await statDbIdentity(dbPath) };
|
|
680
|
+
dbCache.set(dbPath, shared);
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
catch (err) {
|
|
684
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
685
|
+
if ((0, lbug_config_js_1.isWalCorruptionError)(lastError)) {
|
|
686
|
+
try {
|
|
687
|
+
const db = await tryQuarantineAndReopen(dbPath, repoId);
|
|
688
|
+
shared = {
|
|
689
|
+
db,
|
|
690
|
+
refCount: 0,
|
|
691
|
+
dbIdentity: await statDbIdentity(dbPath),
|
|
692
|
+
};
|
|
693
|
+
dbCache.set(dbPath, shared);
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
696
|
+
catch (retryErr) {
|
|
697
|
+
throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ${lbug_config_js_1.WAL_RECOVERY_SUGGESTION} ` +
|
|
698
|
+
`(${retryErr instanceof Error ? retryErr.message : String(retryErr)})`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
if (lastError.message.startsWith('LadybugDB checkpoint sidecar is missing') ||
|
|
702
|
+
lastError.message.startsWith('LadybugDB checkpoint sidecar is present but unreachable') ||
|
|
703
|
+
lastError.message.startsWith('GitNexus could not move the LadybugDB WAL sidecar') ||
|
|
704
|
+
(0, sidecar_recovery_js_1.isMissingShadowSidecarError)(lastError)) {
|
|
705
|
+
throw lastError;
|
|
706
|
+
}
|
|
707
|
+
const isLockError = lastError.message.includes('Could not set lock') ||
|
|
708
|
+
/\block(\b|ed|ing)/i.test(lastError.message);
|
|
709
|
+
if (!isLockError || attempt === LOCK_RETRY_ATTEMPTS)
|
|
710
|
+
break;
|
|
711
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_DELAY_MS * attempt));
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (!shared) {
|
|
715
|
+
throw new Error(`LadybugDB unavailable for ${repoId}. Another process may be rebuilding the index. ` +
|
|
716
|
+
`Retry later. (${lastError?.message || 'unknown error'})`);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
shared.refCount++;
|
|
720
|
+
const db = shared.db;
|
|
721
|
+
// Pre-create the full pool upfront so createConnection() (which silences
|
|
722
|
+
// stdout) is never called lazily during active query execution.
|
|
723
|
+
// Mark preWarmActive so the watchdog timer doesn't interfere.
|
|
724
|
+
preWarmActive = true;
|
|
725
|
+
const available = [];
|
|
726
|
+
try {
|
|
727
|
+
for (let i = 0; i < MAX_CONNS_PER_REPO; i++) {
|
|
728
|
+
available.push(createConnection(db));
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
finally {
|
|
732
|
+
preWarmActive = false;
|
|
733
|
+
}
|
|
734
|
+
// Load the VECTOR extension once per shared Database, BEFORE pool
|
|
735
|
+
// registration so no concurrent checkout can grab the connection while the
|
|
736
|
+
// async load is in progress. Extension load scope is per-Database, so this
|
|
737
|
+
// one load makes QUERY_VECTOR_INDEX legal on every pooled connection.
|
|
738
|
+
// policy: 'load-only' — the read pool must never trigger a network install;
|
|
739
|
+
// analyze owns extension installation. On failure the semantic-query lane
|
|
740
|
+
// falls back to the exact scan with its own diagnostic (#2623 follow-up).
|
|
741
|
+
if (!shared.vectorLoaded) {
|
|
742
|
+
shared.vectorLoaded = await (0, lbug_adapter_js_1.loadVectorExtension)(available[0], { policy: 'load-only' });
|
|
743
|
+
}
|
|
744
|
+
// Register pool entry only after all connections are pre-warmed and the
|
|
745
|
+
// extension is loaded. Concurrent executeQuery calls see either "not initialized"
|
|
746
|
+
// (and throw cleanly) or a fully ready pool — never a half-built one.
|
|
747
|
+
// Record the on-disk identity so a later initLbug can detect an analyze
|
|
748
|
+
// rebuild/mutation and re-open onto the new file (pool staleness invalidation).
|
|
749
|
+
const dbIdentity = await statDbIdentity(dbPath);
|
|
750
|
+
pool.set(repoId, {
|
|
751
|
+
db,
|
|
752
|
+
available,
|
|
753
|
+
checkedOut: 0,
|
|
754
|
+
waiters: [],
|
|
755
|
+
lastUsed: Date.now(),
|
|
756
|
+
dbPath,
|
|
757
|
+
dbIdentity,
|
|
758
|
+
closed: false,
|
|
759
|
+
});
|
|
760
|
+
ensureIdleTimer();
|
|
761
|
+
traceRss('init', repoId);
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Initialize a pool entry from a pre-existing Database object.
|
|
765
|
+
*
|
|
766
|
+
* Used in tests to avoid the writable→close→read-only cycle that crashes
|
|
767
|
+
* on macOS due to N-API destructor segfaults. The pool adapter reuses
|
|
768
|
+
* the core adapter's writable Database instead of opening a new read-only one.
|
|
769
|
+
*
|
|
770
|
+
* The Database is registered in the shared dbCache so closeOne() decrements
|
|
771
|
+
* the refCount correctly. If the Database is already cached (e.g. another
|
|
772
|
+
* repoId already injected it), the existing entry is reused.
|
|
773
|
+
*/
|
|
774
|
+
async function initLbugWithDb(repoId, existingDb, dbPath) {
|
|
775
|
+
const existing = pool.get(repoId);
|
|
776
|
+
if (existing) {
|
|
777
|
+
existing.lastUsed = Date.now();
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
// Register in dbCache with external: true so other initLbug() calls
|
|
781
|
+
// for the same dbPath reuse this Database instead of trying to open
|
|
782
|
+
// a new one (which would fail with a file lock error).
|
|
783
|
+
// closeOne() respects the external flag and skips db.close().
|
|
784
|
+
let shared = dbCache.get(dbPath);
|
|
785
|
+
if (!shared) {
|
|
786
|
+
shared = { db: existingDb, refCount: 0, external: true };
|
|
787
|
+
dbCache.set(dbPath, shared);
|
|
788
|
+
}
|
|
789
|
+
shared.refCount++;
|
|
790
|
+
const available = [];
|
|
791
|
+
preWarmActive = true;
|
|
792
|
+
try {
|
|
793
|
+
for (let i = 0; i < MAX_CONNS_PER_REPO; i++) {
|
|
794
|
+
available.push(createConnection(existingDb));
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
finally {
|
|
798
|
+
preWarmActive = false;
|
|
799
|
+
}
|
|
800
|
+
// Load the VECTOR extension if not already loaded on this Database.
|
|
801
|
+
// policy: 'load-only' — same contract as initLbug above; the read pool
|
|
802
|
+
// must not block on a network install during query execution
|
|
803
|
+
// (#2623 follow-up).
|
|
804
|
+
if (!shared.vectorLoaded) {
|
|
805
|
+
shared.vectorLoaded = await (0, lbug_adapter_js_1.loadVectorExtension)(available[0], { policy: 'load-only' });
|
|
806
|
+
}
|
|
807
|
+
pool.set(repoId, {
|
|
808
|
+
db: existingDb,
|
|
809
|
+
available,
|
|
810
|
+
checkedOut: 0,
|
|
811
|
+
waiters: [],
|
|
812
|
+
lastUsed: Date.now(),
|
|
813
|
+
dbPath,
|
|
814
|
+
// Injected/external DB (tests) — not tracked for rebuild invalidation.
|
|
815
|
+
dbIdentity: null,
|
|
816
|
+
closed: false,
|
|
817
|
+
});
|
|
818
|
+
ensureIdleTimer();
|
|
819
|
+
traceRss('init', repoId);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Checkout a connection from the pool.
|
|
823
|
+
* Returns an available connection, or creates a new one if under the cap.
|
|
824
|
+
* If all connections are busy and at cap, queues the caller until one is returned.
|
|
825
|
+
*/
|
|
826
|
+
function checkout(entry) {
|
|
827
|
+
// Fast path: grab an available connection
|
|
828
|
+
if (entry.available.length > 0) {
|
|
829
|
+
entry.checkedOut++;
|
|
830
|
+
return Promise.resolve(entry.available.pop());
|
|
831
|
+
}
|
|
832
|
+
// Pool was pre-warmed to MAX_CONNS_PER_REPO during init. If we're here
|
|
833
|
+
// with fewer total connections, something leaked — surface the bug rather
|
|
834
|
+
// than silently creating a connection (which would silence stdout mid-query).
|
|
835
|
+
const totalConns = entry.available.length + entry.checkedOut;
|
|
836
|
+
if (totalConns < MAX_CONNS_PER_REPO) {
|
|
837
|
+
throw new Error(`Connection pool integrity error: expected ${MAX_CONNS_PER_REPO} ` +
|
|
838
|
+
`connections but found ${totalConns} (${entry.available.length} available, ` +
|
|
839
|
+
`${entry.checkedOut} checked out)`);
|
|
840
|
+
}
|
|
841
|
+
// At capacity — queue the caller with a timeout.
|
|
842
|
+
return new Promise((resolve, reject) => {
|
|
843
|
+
const waiter = {
|
|
844
|
+
resolve: (conn) => {
|
|
845
|
+
clearTimeout(timer);
|
|
846
|
+
resolve(conn);
|
|
847
|
+
},
|
|
848
|
+
reject: (err) => {
|
|
849
|
+
clearTimeout(timer);
|
|
850
|
+
reject(err);
|
|
851
|
+
},
|
|
852
|
+
};
|
|
853
|
+
const timer = setTimeout(() => {
|
|
854
|
+
const idx = entry.waiters.indexOf(waiter);
|
|
855
|
+
if (idx !== -1)
|
|
856
|
+
entry.waiters.splice(idx, 1);
|
|
857
|
+
waiter.reject(new Error(`Connection pool exhausted: timed out after ${WAITER_TIMEOUT_MS}ms waiting for a free connection`));
|
|
858
|
+
}, WAITER_TIMEOUT_MS);
|
|
859
|
+
entry.waiters.push(waiter);
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Return a connection to the pool after use.
|
|
864
|
+
* If the pool entry was closed while the connection was checked out (e.g.
|
|
865
|
+
* LRU eviction), close the orphaned connection instead of returning it.
|
|
866
|
+
* If there are queued waiters, hand the connection directly to the next one
|
|
867
|
+
* instead of putting it back in the available array (avoids race conditions).
|
|
868
|
+
*/
|
|
869
|
+
function checkin(entry, conn) {
|
|
870
|
+
if (entry.closed) {
|
|
871
|
+
// Pool entry was deleted during checkout — close the orphaned connection
|
|
872
|
+
conn.close().catch(() => { });
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
if (entry.waiters.length > 0) {
|
|
876
|
+
// Hand directly to the next waiter — no intermediate available state
|
|
877
|
+
const waiter = entry.waiters.shift();
|
|
878
|
+
waiter.resolve(conn);
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
entry.checkedOut--;
|
|
882
|
+
entry.available.push(conn);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Execute a query on a specific repo's connection pool.
|
|
887
|
+
* Automatically checks out a connection, runs the query, and returns it.
|
|
888
|
+
*/
|
|
889
|
+
/** Race a promise against a timeout */
|
|
890
|
+
function withTimeout(promise, ms, label) {
|
|
891
|
+
let timer;
|
|
892
|
+
const timeout = new Promise((_, reject) => {
|
|
893
|
+
timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
|
|
894
|
+
});
|
|
895
|
+
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
896
|
+
}
|
|
897
|
+
const executeQuery = async (repoId, cypher) => {
|
|
898
|
+
return await (0, exports.executeParameterized)(repoId, cypher, {});
|
|
899
|
+
};
|
|
900
|
+
exports.executeQuery = executeQuery;
|
|
901
|
+
/**
|
|
902
|
+
* Execute a parameterized query on a specific repo's connection pool.
|
|
903
|
+
* Uses prepare/execute pattern to prevent Cypher injection.
|
|
904
|
+
*/
|
|
905
|
+
const executeParameterized = async (repoId, cypher, params) => {
|
|
906
|
+
const entry = pool.get(repoId);
|
|
907
|
+
if (!entry) {
|
|
908
|
+
throw new Error(`LadybugDB not initialized for repo "${repoId}". Call initLbug first.`);
|
|
909
|
+
}
|
|
910
|
+
entry.lastUsed = Date.now();
|
|
911
|
+
const conn = await checkout(entry);
|
|
912
|
+
silenceStdout();
|
|
913
|
+
activeQueryCount++;
|
|
914
|
+
let queryResult;
|
|
915
|
+
try {
|
|
916
|
+
const stmt = await withTimeout(conn.prepare(cypher), QUERY_TIMEOUT_MS, 'Prepare');
|
|
917
|
+
if (!stmt.isSuccess()) {
|
|
918
|
+
const errMsg = await stmt.getErrorMessage();
|
|
919
|
+
throw new Error(`Prepare failed: ${errMsg}`);
|
|
920
|
+
}
|
|
921
|
+
queryResult = await withTimeout(conn.execute(stmt, params), QUERY_TIMEOUT_MS, 'Execute');
|
|
922
|
+
const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
|
|
923
|
+
const rows = await result.getAll();
|
|
924
|
+
return rows;
|
|
925
|
+
}
|
|
926
|
+
catch (err) {
|
|
927
|
+
if ((0, lbug_adapter_js_1.isReadOnlyDbError)(err)) {
|
|
928
|
+
// Preserve the native error as `cause` so the original frame/message is
|
|
929
|
+
// not lost behind the friendly read-only message (#2068 follow-up).
|
|
930
|
+
throw new Error('Write operations are not allowed. The pool adapter is read-only.', {
|
|
931
|
+
cause: err,
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
throw err;
|
|
935
|
+
}
|
|
936
|
+
finally {
|
|
937
|
+
// Close the native QueryResult cursor(s) before returning the connection —
|
|
938
|
+
// getAll() drains rows but does not release the native cursor, so without
|
|
939
|
+
// this the cursor leaks for the connection's lifetime (#2068 follow-up).
|
|
940
|
+
// Best-effort via the shared helper; never masks the query result or a real
|
|
941
|
+
// error.
|
|
942
|
+
if (queryResult)
|
|
943
|
+
await (0, query_result_utils_js_1.closeQueryResults)(queryResult);
|
|
944
|
+
activeQueryCount--;
|
|
945
|
+
restoreStdout();
|
|
946
|
+
checkin(entry, conn);
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
exports.executeParameterized = executeParameterized;
|
|
950
|
+
/**
|
|
951
|
+
* Close one or all repo pools.
|
|
952
|
+
* If repoId is provided, close only that repo's connections.
|
|
953
|
+
* If omitted, close all repos.
|
|
954
|
+
*/
|
|
955
|
+
const closeLbug = async (repoId) => {
|
|
956
|
+
if (repoId) {
|
|
957
|
+
closeOne(repoId);
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
for (const id of [...pool.keys()]) {
|
|
961
|
+
closeOne(id);
|
|
962
|
+
}
|
|
963
|
+
if (idleTimer) {
|
|
964
|
+
clearInterval(idleTimer);
|
|
965
|
+
idleTimer = null;
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
exports.closeLbug = closeLbug;
|
|
969
|
+
/**
|
|
970
|
+
* Check if a specific repo's pool is active
|
|
971
|
+
*/
|
|
972
|
+
const isLbugReady = (repoId) => pool.has(repoId);
|
|
973
|
+
exports.isLbugReady = isLbugReady;
|