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,1029 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.waitForWindowsHandleRelease = exports.sleep = exports._isTestFixturePathForTest = exports.isOpenRetryExhausted = exports.LBUG_OPEN_RETRY_EXHAUSTED = exports.HANDLE_RELEASE_PROBE_DELAY_MS = exports.HANDLE_RELEASE_PROBE_ATTEMPTS = exports.classifyDeleteAllError = exports.isLbugCheckpointBusyError = exports.isDbBusyError = exports.getOsPageSize = exports._setOsPageSizeForTests = exports.isPageSizeAwareLadybug = exports.isLbugPageSizeFrameError = exports.isLbugCheckpointIoError = exports.WAL_RECOVERY_SUGGESTION = exports.bufferPoolExhaustionRemedy = exports.getEffectiveBufferPoolSize = exports.setBufferPoolSizeHint = exports.estimateBufferPool = exports.granuleRatio = exports.parseWalCheckpointThreshold = exports.LBUG_MAX_DB_SIZE = void 0;
|
|
7
|
+
exports.cleanupNativePathJunctions = cleanupNativePathJunctions;
|
|
8
|
+
exports.toNativeSafePath = toNativeSafePath;
|
|
9
|
+
exports.resolveNativeSafeStorageDir = resolveNativeSafeStorageDir;
|
|
10
|
+
exports.isWalCorruptionError = isWalCorruptionError;
|
|
11
|
+
exports.createLbugDatabase = createLbugDatabase;
|
|
12
|
+
exports.openLbugConnection = openLbugConnection;
|
|
13
|
+
exports.closeLbugConnection = closeLbugConnection;
|
|
14
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const os_1 = __importDefault(require("os"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
19
|
+
const child_process_1 = require("child_process");
|
|
20
|
+
const worker_threads_1 = require("worker_threads");
|
|
21
|
+
const logger_js_1 = require("../logger.js");
|
|
22
|
+
// ─── Windows non-ASCII path workaround (#1811) ───────────────────────────────
|
|
23
|
+
//
|
|
24
|
+
// KuzuDB's native C++ layer on Windows uses CreateFileA (ANSI), not
|
|
25
|
+
// CreateFileW. Non-ASCII path bytes from Node.js (UTF-8) are
|
|
26
|
+
// misinterpreted via the system's Active Code Page (e.g. GBK), producing
|
|
27
|
+
// a garbled path — "Error 3: The system cannot find the path."
|
|
28
|
+
//
|
|
29
|
+
// Layered workaround:
|
|
30
|
+
// 1. Try 8.3 short-name form (fast, no persistent state)
|
|
31
|
+
// 2. Fall back to an NTFS junction from an ASCII temp path
|
|
32
|
+
// 3. If both fail, log a diagnostic and return the original path
|
|
33
|
+
const NON_ASCII_RE = /[^\x00-\x7F]/;
|
|
34
|
+
const JUNCTION_PREFIX = 'gitnexus-junction-';
|
|
35
|
+
const activeJunctions = new Set();
|
|
36
|
+
let cleanupRegistered = false;
|
|
37
|
+
let orphanScanDone = false;
|
|
38
|
+
function junctionHash(targetDir) {
|
|
39
|
+
return crypto_1.default.createHash('sha256').update(targetDir).digest('hex').slice(0, 16);
|
|
40
|
+
}
|
|
41
|
+
function tryShortPath(p) {
|
|
42
|
+
try {
|
|
43
|
+
// Pass the path via environment variable so the command string is
|
|
44
|
+
// static — avoids CodeQL command-injection taint (the path never
|
|
45
|
+
// appears in the shell command text).
|
|
46
|
+
const result = (0, child_process_1.execFileSync)('cmd.exe', ['/c', 'for %I in ("%CGRAPH_SP%") do @echo %~sI'], {
|
|
47
|
+
encoding: 'utf-8',
|
|
48
|
+
timeout: 5000,
|
|
49
|
+
windowsHide: true,
|
|
50
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
51
|
+
env: { ...process.env, CGRAPH_SP: p },
|
|
52
|
+
});
|
|
53
|
+
const shortPath = result.trim();
|
|
54
|
+
if (shortPath &&
|
|
55
|
+
!NON_ASCII_RE.test(shortPath) &&
|
|
56
|
+
(!shortPath.includes('?') || p.includes('?'))) {
|
|
57
|
+
return shortPath;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 8.3 unavailable or cmd failed
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function tryJunction(targetDir, leaf) {
|
|
66
|
+
const hash = junctionHash(targetDir);
|
|
67
|
+
const junctionLink = path_1.default.join(os_1.default.tmpdir(), `${JUNCTION_PREFIX}${hash}`);
|
|
68
|
+
if (fs_1.default.existsSync(junctionLink)) {
|
|
69
|
+
try {
|
|
70
|
+
const existing = fs_1.default.readlinkSync(junctionLink);
|
|
71
|
+
if (path_1.default.resolve(existing) === path_1.default.resolve(targetDir)) {
|
|
72
|
+
activeJunctions.add(junctionLink);
|
|
73
|
+
return path_1.default.join(junctionLink, leaf);
|
|
74
|
+
}
|
|
75
|
+
fs_1.default.rmSync(junctionLink, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Stale or broken junction — remove and recreate
|
|
79
|
+
try {
|
|
80
|
+
fs_1.default.rmSync(junctionLink, { recursive: true, force: true });
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
/* best effort */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
fs_1.default.symlinkSync(targetDir, junctionLink, 'junction');
|
|
89
|
+
activeJunctions.add(junctionLink);
|
|
90
|
+
return path_1.default.join(junctionLink, leaf);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
if (err.code === 'EEXIST') {
|
|
94
|
+
try {
|
|
95
|
+
const existing = fs_1.default.readlinkSync(junctionLink);
|
|
96
|
+
if (path_1.default.resolve(existing) === path_1.default.resolve(targetDir)) {
|
|
97
|
+
activeJunctions.add(junctionLink);
|
|
98
|
+
return path_1.default.join(junctionLink, leaf);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
/* cannot verify — fall through */
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
function registerCleanupHandlers() {
|
|
109
|
+
if (cleanupRegistered)
|
|
110
|
+
return;
|
|
111
|
+
cleanupRegistered = true;
|
|
112
|
+
process.on('exit', () => cleanupNativePathJunctions());
|
|
113
|
+
for (const signal of ['SIGTERM', 'SIGINT']) {
|
|
114
|
+
process.on(signal, () => {
|
|
115
|
+
cleanupNativePathJunctions();
|
|
116
|
+
if (process.platform === 'win32') {
|
|
117
|
+
process.exit(signal === 'SIGINT' ? 130 : 143);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
process.kill(process.pid, signal);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function scanOrphanedJunctions() {
|
|
126
|
+
if (orphanScanDone)
|
|
127
|
+
return;
|
|
128
|
+
orphanScanDone = true;
|
|
129
|
+
try {
|
|
130
|
+
const tmpdir = os_1.default.tmpdir();
|
|
131
|
+
const entries = fs_1.default.readdirSync(tmpdir);
|
|
132
|
+
for (const entry of entries) {
|
|
133
|
+
if (!entry.startsWith(JUNCTION_PREFIX))
|
|
134
|
+
continue;
|
|
135
|
+
const junctionPath = path_1.default.join(tmpdir, entry);
|
|
136
|
+
try {
|
|
137
|
+
const target = fs_1.default.readlinkSync(junctionPath);
|
|
138
|
+
try {
|
|
139
|
+
fs_1.default.lstatSync(target);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
fs_1.default.rmSync(junctionPath, { recursive: true, force: true });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Not a symlink/junction or unreadable — leave it
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// tmpdir unreadable — skip scan
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function cleanupNativePathJunctions() {
|
|
155
|
+
for (const junctionPath of activeJunctions) {
|
|
156
|
+
try {
|
|
157
|
+
fs_1.default.rmSync(junctionPath, { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Best effort — EPERM on Windows is common during exit
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
activeJunctions.clear();
|
|
164
|
+
}
|
|
165
|
+
function toNativeSafePath(p) {
|
|
166
|
+
if (process.platform !== 'win32')
|
|
167
|
+
return p;
|
|
168
|
+
if (!NON_ASCII_RE.test(p))
|
|
169
|
+
return p;
|
|
170
|
+
if (worker_threads_1.isMainThread) {
|
|
171
|
+
scanOrphanedJunctions();
|
|
172
|
+
registerCleanupHandlers();
|
|
173
|
+
}
|
|
174
|
+
const shortPath = tryShortPath(p);
|
|
175
|
+
if (shortPath)
|
|
176
|
+
return shortPath;
|
|
177
|
+
if (!worker_threads_1.isMainThread) {
|
|
178
|
+
logger_js_1.logger.warn(`GitNexus: non-ASCII path in worker thread — junction fallback skipped. ` +
|
|
179
|
+
`Path: "${p}". 8.3 short names may need to be enabled on this volume.`);
|
|
180
|
+
return p;
|
|
181
|
+
}
|
|
182
|
+
const targetDir = path_1.default.dirname(p);
|
|
183
|
+
const leaf = path_1.default.basename(p);
|
|
184
|
+
if (fs_1.default.existsSync(targetDir)) {
|
|
185
|
+
const junctionResult = tryJunction(targetDir, leaf);
|
|
186
|
+
if (junctionResult)
|
|
187
|
+
return junctionResult;
|
|
188
|
+
}
|
|
189
|
+
logger_js_1.logger.warn(`GitNexus: non-ASCII path "${p}" could not be converted to an ASCII-safe form. ` +
|
|
190
|
+
'LadybugDB may fail with "Cannot open file." To fix: move the repo to a path ' +
|
|
191
|
+
'without CJK/Unicode characters, or enable 8.3 short names on this volume ' +
|
|
192
|
+
'(fsutil 8dot3name set 0).');
|
|
193
|
+
return p;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Resolve the on-disk CSV staging dir for `<storagePath>/<subdir>`, applying the
|
|
197
|
+
* same ASCII-safe relocation `toNativeSafePath` enables: on Windows with a
|
|
198
|
+
* non-ASCII storage path, LadybugDB's bulk COPY cannot open files under that
|
|
199
|
+
* path, so the dir is relocated under `os.tmpdir()`. Shared by the structural
|
|
200
|
+
* `csv/` dir and the streaming `pdg-csv/` dir (#2202) so the two can never
|
|
201
|
+
* diverge on platform handling; the `gitnexus-<subdir>-` prefix keeps their tmp
|
|
202
|
+
* locations distinct and recognizable.
|
|
203
|
+
*
|
|
204
|
+
* The relocated dir is created with `fs.mkdtempSync` (a unique, mode-0700,
|
|
205
|
+
* guaranteed-not-pre-existing suffix) rather than a deterministic
|
|
206
|
+
* `gitnexus-<subdir>-<hash>` name. A predictable name in the world-readable OS
|
|
207
|
+
* temp dir is information-disclosure-prone and pre-plantable
|
|
208
|
+
* (CWE-377/378 / CodeQL `js/insecure-temporary-file`); mkdtemp's random suffix
|
|
209
|
+
* is the documented mitigation and is what reaches the streaming sink's
|
|
210
|
+
* `fs.openSync`. The non-Windows / ASCII path stays a pure `path.join` (no dir
|
|
211
|
+
* created) and is byte-identical to before.
|
|
212
|
+
*/
|
|
213
|
+
function resolveNativeSafeStorageDir(storagePath, subdir) {
|
|
214
|
+
if (process.platform === 'win32' && NON_ASCII_RE.test(storagePath)) {
|
|
215
|
+
// 8.3-shorten the tmpdir base first (a non-ASCII Windows *profile* path can
|
|
216
|
+
// make os.tmpdir() itself non-ASCII), THEN mkdtemp so the returned path —
|
|
217
|
+
// the one that flows into fs.openSync — is provably mkdtemp-sourced (random,
|
|
218
|
+
// exclusive) and clears the insecure-temp-file dataflow.
|
|
219
|
+
const base = toNativeSafePath(os_1.default.tmpdir());
|
|
220
|
+
return fs_1.default.mkdtempSync(path_1.default.join(base, `gitnexus-${subdir}-`));
|
|
221
|
+
}
|
|
222
|
+
return path_1.default.join(storagePath, subdir);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Shared configuration for `@ladybugdb/core` `Database` construction.
|
|
226
|
+
*
|
|
227
|
+
* Two values changed meaningfully in `@ladybugdb/core` 0.16.0 and need to be
|
|
228
|
+
* pinned explicitly by every caller, otherwise GitNexus regresses:
|
|
229
|
+
*
|
|
230
|
+
* 1. `maxDBSize` defaults to `0`, which the native runtime interprets as
|
|
231
|
+
* "use the platform's full mmap address space" — typically 8 TB on
|
|
232
|
+
* 64-bit Linux. Constrained environments (CI runners, containers, WSL)
|
|
233
|
+
* cannot reserve that much address space and crash with
|
|
234
|
+
* `Buffer manager exception: Mmap for size 8796093022208 failed.`
|
|
235
|
+
* See LadybugDB upstream JSDoc:
|
|
236
|
+
* > "introduced temporarily for now to get around with the default 8TB
|
|
237
|
+
* > mmap address space limit some environment".
|
|
238
|
+
*
|
|
239
|
+
* 2. `enableCompression` flipped its default from `false` (0.15.x) to
|
|
240
|
+
* `true` (0.16.0). Existing call sites that relied on the positional
|
|
241
|
+
* default must now pass `false` explicitly to preserve behaviour.
|
|
242
|
+
*
|
|
243
|
+
* 3. `bufferManagerSize` (not a 0.16.0 change, same pin-explicitly
|
|
244
|
+
* principle): `0` means "native default", and the native default buffer
|
|
245
|
+
* pool is 80% of physical RAM. A long-lived `cgraph mcp` process or a
|
|
246
|
+
* large incremental analyze can balloon to that ceiling and OOM-kill the
|
|
247
|
+
* host session (#2557), so GitNexus pins an explicit bounded pool — see
|
|
248
|
+
* `resolveBufferManagerSize`.
|
|
249
|
+
*
|
|
250
|
+
* Putting these in one shared module guarantees every `new lbug.Database(...)`
|
|
251
|
+
* call site agrees on the same ceilings and behaviour.
|
|
252
|
+
*/
|
|
253
|
+
/**
|
|
254
|
+
* Upper bound for any single GitNexus LadybugDB file (graph index, group
|
|
255
|
+
* bridge, install scratch, test fixture). 16 GiB is intentionally generous
|
|
256
|
+
* for real-world code graphs (the GitNexus self-index uses < 50 MiB) while
|
|
257
|
+
* remaining far below any 64-bit OS mmap ceiling.
|
|
258
|
+
*
|
|
259
|
+
* Override with the `CGRAPH_LBUG_MAX_DB_SIZE` environment variable when
|
|
260
|
+
* indexing genuinely huge monorepos. Values are coerced to a positive
|
|
261
|
+
* integer; anything invalid falls back to the default.
|
|
262
|
+
*/
|
|
263
|
+
exports.LBUG_MAX_DB_SIZE = (() => {
|
|
264
|
+
const raw = process.env.CGRAPH_LBUG_MAX_DB_SIZE;
|
|
265
|
+
if (raw) {
|
|
266
|
+
const parsed = Number(raw);
|
|
267
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
268
|
+
return Math.floor(parsed);
|
|
269
|
+
}
|
|
270
|
+
return 16 * 1024 * 1024 * 1024;
|
|
271
|
+
})();
|
|
272
|
+
const parseWalCheckpointThreshold = (raw) => {
|
|
273
|
+
if (raw === undefined)
|
|
274
|
+
return undefined;
|
|
275
|
+
const normalized = raw.trim();
|
|
276
|
+
if (normalized.length === 0)
|
|
277
|
+
return undefined;
|
|
278
|
+
const parsed = Number(normalized);
|
|
279
|
+
if (!Number.isInteger(parsed) || parsed < -1)
|
|
280
|
+
return undefined;
|
|
281
|
+
return parsed;
|
|
282
|
+
};
|
|
283
|
+
exports.parseWalCheckpointThreshold = parseWalCheckpointThreshold;
|
|
284
|
+
/**
|
|
285
|
+
* Default GitNexus WAL auto-checkpoint threshold in bytes (64 MiB).
|
|
286
|
+
*
|
|
287
|
+
* Larger than Ladybug's stock ~16 MiB to reduce checkpoint rename/remove
|
|
288
|
+
* churn under heavy analyze write load — the original race that motivated
|
|
289
|
+
* issue #1741 triggered at the stock threshold. README examples in
|
|
290
|
+
* `README.md` and `cgraph/README.md` and the recovery hint in
|
|
291
|
+
* `analyze.ts` MUST stay in sync with this value.
|
|
292
|
+
*/
|
|
293
|
+
const DEFAULT_WAL_CHECKPOINT_THRESHOLD = 64 * 1024 * 1024;
|
|
294
|
+
const resolveCheckpointThreshold = () => {
|
|
295
|
+
const raw = process.env.CGRAPH_WAL_CHECKPOINT_THRESHOLD;
|
|
296
|
+
if (raw === undefined)
|
|
297
|
+
return DEFAULT_WAL_CHECKPOINT_THRESHOLD;
|
|
298
|
+
const parsed = (0, exports.parseWalCheckpointThreshold)(raw);
|
|
299
|
+
if (parsed !== undefined)
|
|
300
|
+
return parsed;
|
|
301
|
+
// Non-empty but unparseable input: warn the operator and fall back. Mirrors
|
|
302
|
+
// the CLI's `--wal-checkpoint-threshold` validation (which hard-errors)
|
|
303
|
+
// but the env-var path stays soft to preserve "set once in your shell"
|
|
304
|
+
// ergonomics across mixed-version invocations.
|
|
305
|
+
if (raw.trim().length > 0) {
|
|
306
|
+
logger_js_1.logger.warn({ rawValue: raw, fallback: DEFAULT_WAL_CHECKPOINT_THRESHOLD }, `Ignoring invalid CGRAPH_WAL_CHECKPOINT_THRESHOLD=${raw}; expected integer >= -1; falling back to default (${DEFAULT_WAL_CHECKPOINT_THRESHOLD}).`);
|
|
307
|
+
}
|
|
308
|
+
return DEFAULT_WAL_CHECKPOINT_THRESHOLD;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* Default ceiling for the LadybugDB buffer pool in bytes (#2557).
|
|
312
|
+
*
|
|
313
|
+
* The pool is a page cache with eviction, so the ceiling trades throughput
|
|
314
|
+
* on very large working sets for a machine that stays alive: 2 GiB is
|
|
315
|
+
* ~40× the GitNexus self-index, while the native 80%-of-RAM default let a
|
|
316
|
+
* `detect_changes` call grow a 105 MiB on-disk index to 19.5 GiB RSS and
|
|
317
|
+
* OOM-kill the reporter's session. The `min` with 80% of `os.totalmem()`
|
|
318
|
+
* keeps sub-2.5-GiB machines at the native-equivalent bound (no regression
|
|
319
|
+
* there); the 64 MiB floor keeps tiny containers above any plausible
|
|
320
|
+
* native minimum pool size.
|
|
321
|
+
*/
|
|
322
|
+
const DEFAULT_BUFFER_POOL_CAP = 2 * 1024 * 1024 * 1024;
|
|
323
|
+
const BUFFER_POOL_FLOOR = 64 * 1024 * 1024;
|
|
324
|
+
// COPY-safety floor for the adaptive hint (below). LadybugDB's bulk COPY needs
|
|
325
|
+
// working buffer-pool memory that scales with the repo: a 64 MiB pool fails
|
|
326
|
+
// ("buffer pool is full and no memory could be freed") on any non-trivial repo,
|
|
327
|
+
// and even the ~1800-file GitNexus checkout needs ≥256 MiB. So the adaptive
|
|
328
|
+
// size never drops a repo below this — a distinct, higher floor than
|
|
329
|
+
// BUFFER_POOL_FLOOR, which only guards defaultBufferPoolSize on tiny-RAM
|
|
330
|
+
// machines. It is still clamped up to defaultBufferPoolSize, so a machine whose
|
|
331
|
+
// default is below this floor keeps its default rather than over-committing.
|
|
332
|
+
const ADAPTIVE_POOL_FLOOR = 256 * 1024 * 1024;
|
|
333
|
+
const parseBufferPoolSize = (raw) => {
|
|
334
|
+
if (raw === undefined)
|
|
335
|
+
return undefined;
|
|
336
|
+
const normalized = raw.trim();
|
|
337
|
+
if (normalized.length === 0)
|
|
338
|
+
return undefined;
|
|
339
|
+
const parsed = Number(normalized);
|
|
340
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
341
|
+
return undefined;
|
|
342
|
+
return Math.floor(parsed);
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* The buffer-manager frame size compiled into every shipped `@ladybugdb/core`
|
|
346
|
+
* binary (`LBUG_PAGE_SIZE_LOG2 = 12` in the engine's CMake) — frames are 4 KiB
|
|
347
|
+
* on every platform, independent of the OS page size.
|
|
348
|
+
*/
|
|
349
|
+
const LBUG_ASSUMED_FRAME_SIZE = 4096;
|
|
350
|
+
/**
|
|
351
|
+
* How much the OS page size amplifies buffer-pool consumption (#2631).
|
|
352
|
+
*
|
|
353
|
+
* LadybugDB's VM region charges pool budget per DISCARD GRANULE, not per
|
|
354
|
+
* frame: `discardGranuleSize = max(frameSize, osPageSize)` (vm_region.cpp),
|
|
355
|
+
* `claimFrame` bills the whole granule when its first 4 KiB frame becomes
|
|
356
|
+
* resident, and `releaseFrame` refunds only when the granule's LAST frame
|
|
357
|
+
* leaves. On a 64 KiB-page kernel (aarch64 openEuler — Ascend hosts) that is
|
|
358
|
+
* 16 frames per granule: scattered access is billed up to 16× its real bytes,
|
|
359
|
+
* and whole eviction passes can evict frames yet refund nothing — which is
|
|
360
|
+
* exactly the engine's "buffer pool is full and no memory could be freed"
|
|
361
|
+
* throw. Apple Silicon macOS (16 KiB pages) is the same mechanism at 4×.
|
|
362
|
+
*
|
|
363
|
+
* So the ANALYZE-path pool sizes (the per-element estimate, the COPY-safety
|
|
364
|
+
* floor, and the cap the hint is clamped against) are scaled by this ratio:
|
|
365
|
+
* the budget must cover worst-case granule charging or COPY dies on non-4K
|
|
366
|
+
* hosts with a pool that would be ample on x86. The hintless default
|
|
367
|
+
* (defaultBufferPoolSize — MCP serve, doctor, native-check) is deliberately
|
|
368
|
+
* NOT scaled: the pool is a native eager allocation committed at DB open
|
|
369
|
+
* (measured — see POOL_BYTES_PER_ELEMENT below), so scaling the global
|
|
370
|
+
* default would revert the #2557 OOM cap on every 16 KiB/64 KiB host. If the
|
|
371
|
+
* engine ever charges per-frame (or ships page-size-matched frames), this
|
|
372
|
+
* collapses back to 1 and the scaling disappears.
|
|
373
|
+
*
|
|
374
|
+
* Fail-safe: an undetectable page size (win32 — where the granule mechanism
|
|
375
|
+
* is absent anyway — or a failed `getconf`) means ratio 1, i.e. today's
|
|
376
|
+
* behavior.
|
|
377
|
+
*/
|
|
378
|
+
const granuleRatio = (pageSize = (0, exports.getOsPageSize)()) => {
|
|
379
|
+
if (pageSize === undefined || !Number.isFinite(pageSize))
|
|
380
|
+
return 1;
|
|
381
|
+
return Math.max(1, Math.floor(pageSize / LBUG_ASSUMED_FRAME_SIZE));
|
|
382
|
+
};
|
|
383
|
+
exports.granuleRatio = granuleRatio;
|
|
384
|
+
/**
|
|
385
|
+
* Hintless pool default — MCP serve, doctor, native-check, any open without a
|
|
386
|
+
* per-run hint. Deliberately UNSCALED (#2557): the pool is an eager native
|
|
387
|
+
* allocation at DB open, so a page-size-scaled default would hand a
|
|
388
|
+
* long-lived `cgraph mcp` on a 16 KiB/64 KiB host up to 80% of RAM — the
|
|
389
|
+
* exact OOM exposure the 2 GiB cap was added to remove.
|
|
390
|
+
*/
|
|
391
|
+
const defaultBufferPoolSize = () => Math.min(DEFAULT_BUFFER_POOL_CAP, Math.max(BUFFER_POOL_FLOOR, Math.floor(os_1.default.totalmem() * 0.8)));
|
|
392
|
+
/**
|
|
393
|
+
* Upper bound for the ANALYZE-path (hinted) pool: the #2557 cap scaled by the
|
|
394
|
+
* granule ratio, still bounded by 80% of RAM. Scaling only this bound — and
|
|
395
|
+
* not defaultBufferPoolSize — is what lets the #2631 fix take effect during
|
|
396
|
+
* the bulk COPY without touching hintless opens: with an unscaled cap the
|
|
397
|
+
* min() below would clamp the scaled COPY floor straight back to 2 GiB.
|
|
398
|
+
*/
|
|
399
|
+
const scaledAnalyzePoolCap = (pageSize) => Math.min(DEFAULT_BUFFER_POOL_CAP * (0, exports.granuleRatio)(pageSize), Math.max(BUFFER_POOL_FLOOR, Math.floor(os_1.default.totalmem() * 0.8)));
|
|
400
|
+
/**
|
|
401
|
+
* Clamp an adaptive pool request to [ADAPTIVE_POOL_FLOOR × granuleRatio,
|
|
402
|
+
* scaledAnalyzePoolCap]. The lower bound keeps LadybugDB's COPY viable
|
|
403
|
+
* (scaled because the granule accounting inflates consumption on non-4K
|
|
404
|
+
* hosts, see granuleRatio); the upper bound means the hint can never exceed
|
|
405
|
+
* the page-size-scaled #2557 cap or 80% of RAM — and on a machine whose cap
|
|
406
|
+
* is below the COPY floor, the cap wins, so the pool is never over-committed.
|
|
407
|
+
* On 4 KiB hosts (ratio 1) this is byte-identical to clamping against the
|
|
408
|
+
* hintless default.
|
|
409
|
+
*/
|
|
410
|
+
const clampBufferPool = (bytes, pageSize = (0, exports.getOsPageSize)()) => Math.min(scaledAnalyzePoolCap(pageSize), Math.max(ADAPTIVE_POOL_FLOOR * (0, exports.granuleRatio)(pageSize), Math.floor(bytes)));
|
|
411
|
+
/**
|
|
412
|
+
* Buffer-pool bytes to provision per graph element (node + relationship).
|
|
413
|
+
*
|
|
414
|
+
* The fixed 2 GiB default is far larger than most repos' working set, and
|
|
415
|
+
* LadybugDB eagerly commits the pool at DB open — measured: a full
|
|
416
|
+
* `analyze --force` of the GitNexus checkout takes ~51 s with the 2 GiB pool
|
|
417
|
+
* vs ~35 s with the ~414 MiB this factor yields (31% faster; the oversized
|
|
418
|
+
* pool's commit dominates). The pool is a page cache over the on-disk index,
|
|
419
|
+
* which scales with node/edge count, so a per-element budget sizes it to the
|
|
420
|
+
* repo. Kept generous so the whole index stays resident (no COPY thrash) and
|
|
421
|
+
* always clamped to at least ADAPTIVE_POOL_FLOOR; tuned by timing a real
|
|
422
|
+
* large-repo `analyze --force` at this factor vs a forced 2 GiB pool (the pool
|
|
423
|
+
* is a native eager allocation, measured with a real analyze, not a build-free
|
|
424
|
+
* bench — see the emit-path COPY timing note in bench/emit-persistence).
|
|
425
|
+
*/
|
|
426
|
+
const POOL_BYTES_PER_ELEMENT = 4 * 1024;
|
|
427
|
+
/**
|
|
428
|
+
* Size the buffer pool to an estimated graph size (node + relationship count),
|
|
429
|
+
* clamped to [ADAPTIVE_POOL_FLOOR, scaledAnalyzePoolCap], with every term
|
|
430
|
+
* scaled by granuleRatio (#2631): on non-4K hosts the engine bills pool
|
|
431
|
+
* budget per OS-page-sized granule, so the same graph consumes up to
|
|
432
|
+
* pageSize/4096 × the budget it needs on x86. On 4 KiB hosts the ratio is 1
|
|
433
|
+
* and this is byte-identical to the pre-#2631 behavior. The estimate is never
|
|
434
|
+
* above the page-size-scaled #2557 cap bounded by 80% of RAM, never below the
|
|
435
|
+
* scaled COPY-safety floor; the hintless default stays unscaled.
|
|
436
|
+
*
|
|
437
|
+
* `pageSize` is a test seam (the pageSizeDoctorLines convention); production
|
|
438
|
+
* callers omit it and get the memoized real OS page size.
|
|
439
|
+
*/
|
|
440
|
+
const estimateBufferPool = (graphElementCount, pageSize = (0, exports.getOsPageSize)()) => clampBufferPool(graphElementCount * POOL_BYTES_PER_ELEMENT * (0, exports.granuleRatio)(pageSize), pageSize);
|
|
441
|
+
exports.estimateBufferPool = estimateBufferPool;
|
|
442
|
+
/**
|
|
443
|
+
* Optional per-run buffer-pool size hint (bytes). The analyze orchestrator sets
|
|
444
|
+
* it once the graph size is known (after the pipeline, before the DB open) so
|
|
445
|
+
* the pool is sized to the repo instead of the fixed 2 GiB default, and clears
|
|
446
|
+
* it at run end. Non-analyze opens (MCP serve, `native-check` `:memory:`) never
|
|
447
|
+
* set it and keep the default.
|
|
448
|
+
*/
|
|
449
|
+
let bufferPoolSizeHint;
|
|
450
|
+
/** Set (bytes) or clear (`undefined`) the per-run buffer-pool size hint. */
|
|
451
|
+
const setBufferPoolSizeHint = (bytes) => {
|
|
452
|
+
bufferPoolSizeHint = bytes;
|
|
453
|
+
};
|
|
454
|
+
exports.setBufferPoolSizeHint = setBufferPoolSizeHint;
|
|
455
|
+
/**
|
|
456
|
+
* Resolve the `bufferManagerSize` passed to every `new lbug.Database(...)`.
|
|
457
|
+
* `CGRAPH_LBUG_BUFFER_POOL_SIZE` (bytes) overrides everything; `0` is a
|
|
458
|
+
* deliberate escape hatch that restores LadybugDB's native unbounded
|
|
459
|
+
* 80%-of-RAM default. With no env override, a per-run `setBufferPoolSizeHint`
|
|
460
|
+
* (clamped to [floor, default]) sizes the pool to the repo; otherwise the
|
|
461
|
+
* default. Resolved at call time (not module load) so tests can stub the env
|
|
462
|
+
* var, the hint, and `os.totalmem`.
|
|
463
|
+
*/
|
|
464
|
+
const resolveBufferManagerSize = () => {
|
|
465
|
+
const raw = process.env.CGRAPH_LBUG_BUFFER_POOL_SIZE;
|
|
466
|
+
if (raw === undefined) {
|
|
467
|
+
return bufferPoolSizeHint !== undefined
|
|
468
|
+
? clampBufferPool(bufferPoolSizeHint)
|
|
469
|
+
: defaultBufferPoolSize();
|
|
470
|
+
}
|
|
471
|
+
const parsed = parseBufferPoolSize(raw);
|
|
472
|
+
if (parsed !== undefined)
|
|
473
|
+
return parsed;
|
|
474
|
+
// Non-empty but unparseable input: warn the operator and fall back —
|
|
475
|
+
// mirrors the CGRAPH_WAL_CHECKPOINT_THRESHOLD env path above.
|
|
476
|
+
if (raw.trim().length > 0) {
|
|
477
|
+
logger_js_1.logger.warn({ rawValue: raw, fallback: defaultBufferPoolSize() }, `Ignoring invalid CGRAPH_LBUG_BUFFER_POOL_SIZE=${raw}; expected integer >= 0 (bytes; 0 restores the native 80%-of-RAM default); falling back to the platform default pool size.`);
|
|
478
|
+
}
|
|
479
|
+
return defaultBufferPoolSize();
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Doctor-facing view of the pool size the next Database open would get
|
|
483
|
+
* (#2631): env override > clamped hint > unscaled hintless default. Read-only;
|
|
484
|
+
* doctor prints it next to the page-size lines so support triage sees the
|
|
485
|
+
* sizing inputs at a glance. `0` is the pass-through sentinel for LadybugDB's
|
|
486
|
+
* native 80%-of-RAM default — callers must label it, not print "0 MiB".
|
|
487
|
+
*/
|
|
488
|
+
const getEffectiveBufferPoolSize = () => resolveBufferManagerSize();
|
|
489
|
+
exports.getEffectiveBufferPoolSize = getEffectiveBufferPoolSize;
|
|
490
|
+
/**
|
|
491
|
+
* Matches the engine's buffer-pool exhaustion throw (buffer_manager.cpp:
|
|
492
|
+
* "Unable to allocate memory! The buffer pool is full and no memory could be
|
|
493
|
+
* freed!"). Distinct from isLbugPageSizeFrameError above, which matches the
|
|
494
|
+
* madvise/frame-release failure class.
|
|
495
|
+
*/
|
|
496
|
+
const BUFFER_POOL_EXHAUSTION_RE = /buffer pool is full|unable to allocate memory/i;
|
|
497
|
+
const formatMiB = (bytes) => `${Math.round(bytes / (1024 * 1024))} MiB`;
|
|
498
|
+
/**
|
|
499
|
+
* Actionable remedy for a buffer-pool exhaustion error (#2631), or undefined
|
|
500
|
+
* when `message` is not that class. Cause → consequence → remedy, the
|
|
501
|
+
* diagnoseExtensionLoad convention: names the effective pool, the override
|
|
502
|
+
* knob, and — on non-4K hosts — the granule amplification that makes the
|
|
503
|
+
* budget exhaust early (the reporter's Ascend/aarch64 64 KiB kernel billed a
|
|
504
|
+
* pool up to 16× faster than the same analyze on x86).
|
|
505
|
+
*/
|
|
506
|
+
const bufferPoolExhaustionRemedy = (message, pageSize = (0, exports.getOsPageSize)()) => {
|
|
507
|
+
if (!BUFFER_POOL_EXHAUSTION_RE.test(message))
|
|
508
|
+
return undefined;
|
|
509
|
+
const ratio = (0, exports.granuleRatio)(pageSize);
|
|
510
|
+
const pool = resolveBufferManagerSize();
|
|
511
|
+
// 0 is the pass-through sentinel (CGRAPH_LBUG_BUFFER_POOL_SIZE=0 →
|
|
512
|
+
// LadybugDB's native 80%-of-RAM default) — "0 MiB" would be nonsense in the
|
|
513
|
+
// very triage text this remedy exists to provide.
|
|
514
|
+
const poolLabel = pool === 0 ? "LadybugDB's native 80%-of-RAM default" : formatMiB(pool);
|
|
515
|
+
const pageNote = ratio > 1
|
|
516
|
+
? ` This host's ${(pageSize ?? 0) / 1024} KiB OS page size makes the engine bill pool ` +
|
|
517
|
+
`memory in ${(pageSize ?? 0) / 1024} KiB granules — up to ${ratio}× faster budget use ` +
|
|
518
|
+
`than a 4 KiB-page host running the same analyze.`
|
|
519
|
+
: '';
|
|
520
|
+
return (`The LadybugDB buffer pool (${poolLabel}) was exhausted during the bulk COPY.` +
|
|
521
|
+
pageNote +
|
|
522
|
+
` Set CGRAPH_LBUG_BUFFER_POOL_SIZE=<bytes> to raise it (e.g. ${4 * 1024 * 1024 * 1024}` +
|
|
523
|
+
` for 4 GiB); 0 restores LadybugDB's native 80%-of-RAM default.`);
|
|
524
|
+
};
|
|
525
|
+
exports.bufferPoolExhaustionRemedy = bufferPoolExhaustionRemedy;
|
|
526
|
+
/** Matches WAL corruption errors from the LadybugDB engine. */
|
|
527
|
+
const WAL_CORRUPTION_RE = /corrupt(ed)?\s+wal|invalid\s+wal\s+record|wal.*corrupt|checksum.*wal/i;
|
|
528
|
+
exports.WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `cgraph analyze --force` to rebuild the index.';
|
|
529
|
+
function isWalCorruptionError(err) {
|
|
530
|
+
if (!err)
|
|
531
|
+
return false;
|
|
532
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
533
|
+
return WAL_CORRUPTION_RE.test(msg);
|
|
534
|
+
}
|
|
535
|
+
// ─── Ladybug WAL checkpoint IO error matchers ───────────────────────────────
|
|
536
|
+
//
|
|
537
|
+
// Matched against LadybugDB v0.18.0 (see `cgraph/package.json`
|
|
538
|
+
// @ladybugdb/core). Strict regexes encode local_file_system.cpp wording
|
|
539
|
+
// verified at that version. Two-tier strategy: strict matchers first so we
|
|
540
|
+
// only fire on real checkpoint-rotation shapes; a permissive fallback
|
|
541
|
+
// catches future Ladybug message drift so the recovery hint keeps surfacing
|
|
542
|
+
// even if upstream wording changes.
|
|
543
|
+
//
|
|
544
|
+
// From Ladybug native LocalFileSystem exceptions (`local_file_system.cpp`),
|
|
545
|
+
// surfaced in Node as:
|
|
546
|
+
// "Runtime exception: IO exception: Error renaming file ..."
|
|
547
|
+
// "Runtime exception: IO exception: Error removing directory or file ..."
|
|
548
|
+
// We only match checkpoint-rotation shapes:
|
|
549
|
+
// - "<db>.wal -> <db>.wal.checkpoint" rename failures
|
|
550
|
+
// - "<db>.wal.checkpoint" remove failures
|
|
551
|
+
// Example matches:
|
|
552
|
+
// "Runtime exception: IO exception: Error renaming file /x/lbug.wal to /x/lbug.wal.checkpoint. ErrorMessage: Permission denied"
|
|
553
|
+
// "Runtime exception: IO exception: Error removing directory or file /x/lbug.wal.checkpoint. Error Message: Permission denied"
|
|
554
|
+
// Matching is case-insensitive to remain robust across wrappers/platforms.
|
|
555
|
+
const LBUG_CHECKPOINT_RENAME_RE = /^runtime exception: io exception:\s*error renaming file\s+.+?\.wal\s+to\s+.+?\.wal\.checkpoint(?:\.|\s|$)/i;
|
|
556
|
+
const LBUG_CHECKPOINT_REMOVE_RE = /^runtime exception: io exception:\s*error removing directory or file\s+.+?\.wal\.checkpoint(?:\.|\s|$)/i;
|
|
557
|
+
/**
|
|
558
|
+
* Permissive fallback: any IO-exception-shaped message that mentions a
|
|
559
|
+
* `.wal.checkpoint` path. Catches future Ladybug message drift (different
|
|
560
|
+
* verb, additional preamble, locale variation) so the recovery hint keeps
|
|
561
|
+
* surfacing even if the strict regexes go stale.
|
|
562
|
+
*/
|
|
563
|
+
const LBUG_CHECKPOINT_PERMISSIVE_RE = /io exception.*\.wal\.checkpoint/i;
|
|
564
|
+
/**
|
|
565
|
+
* True when `err` looks like a Ladybug WAL-checkpoint rotation/remove IO
|
|
566
|
+
* failure. Tries strict matchers first (renames + removes), then falls
|
|
567
|
+
* back to the permissive matcher.
|
|
568
|
+
*/
|
|
569
|
+
const isLbugCheckpointIoError = (err) => {
|
|
570
|
+
if (!err)
|
|
571
|
+
return false;
|
|
572
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
573
|
+
if (LBUG_CHECKPOINT_RENAME_RE.test(msg) || LBUG_CHECKPOINT_REMOVE_RE.test(msg))
|
|
574
|
+
return true;
|
|
575
|
+
return LBUG_CHECKPOINT_PERMISSIVE_RE.test(msg);
|
|
576
|
+
};
|
|
577
|
+
exports.isLbugCheckpointIoError = isLbugCheckpointIoError;
|
|
578
|
+
// ─── Ladybug non-4K page-size frame-release matcher (#1231) ─────────────────
|
|
579
|
+
//
|
|
580
|
+
// LadybugDB <= 0.17.x hardcoded a 4 KiB OS-page assumption in its buffer
|
|
581
|
+
// manager: evicting a frame released physical memory with
|
|
582
|
+
// `madvise(frame, frameSize, MADV_DONTNEED)` on 4 KiB-aligned frame
|
|
583
|
+
// addresses (verified by disassembling `VMRegion::releaseFrame` in
|
|
584
|
+
// @ladybugdb/core-linux-arm64 0.17.1 — `mov w2, #0x4` = MADV_DONTNEED,
|
|
585
|
+
// throw on non-zero return). On kernels with 16 KiB pages (Raspberry Pi 5
|
|
586
|
+
// default 2712 kernel, Asahi Linux) or 64 KiB pages (some enterprise arm64
|
|
587
|
+
// distros), madvise rejects addresses that are not multiples of the real
|
|
588
|
+
// page size with EINVAL, surfacing as:
|
|
589
|
+
// "Buffer manager exception: Releasing physical memory associated with a
|
|
590
|
+
// frame failed with error code -1: Invalid argument."
|
|
591
|
+
// which aborts `cgraph analyze` mid-COPY.
|
|
592
|
+
//
|
|
593
|
+
// @ladybugdb/core 0.18.0 rewrote the release path with runtime OS-page-size
|
|
594
|
+
// detection and discard-granule-aligned madvise (new binary strings:
|
|
595
|
+
// "Failed to detect the operating system page size.", "Unsupported page
|
|
596
|
+
// size combination: frame size {}, discard granule size {}, frame group
|
|
597
|
+
// size {}."), so upgrading is the fix. The residual 0.18.0 guard
|
|
598
|
+
// ("Unsupported page size combination") is matched here too so exotic
|
|
599
|
+
// configurations receive the same actionable guidance instead of a raw
|
|
600
|
+
// native message.
|
|
601
|
+
const LBUG_FRAME_RELEASE_RE = /releasing physical memory associated with a frame failed/i;
|
|
602
|
+
const LBUG_PAGE_COMBO_RE = /unsupported page size combination/i;
|
|
603
|
+
/**
|
|
604
|
+
* True when `err` looks like the LadybugDB buffer manager failing to release
|
|
605
|
+
* frame memory — the failure mode of a 4 KiB page-size assumption on a
|
|
606
|
+
* 16 KiB/64 KiB-page kernel (#1231). Deliberately does NOT match the
|
|
607
|
+
* generic "buffer pool is full" exhaustion error: that one is handled as a
|
|
608
|
+
* SIZING problem — though since #2631 we know page size drives sizing too
|
|
609
|
+
* (the engine bills pool budget per OS-page-sized discard granule, so non-4K
|
|
610
|
+
* hosts exhaust the same budget up to pageSize/4096× earlier; see
|
|
611
|
+
* granuleRatio, which scales the pool accordingly, and
|
|
612
|
+
* bufferPoolExhaustionRemedy, which explains it to the operator).
|
|
613
|
+
*/
|
|
614
|
+
const isLbugPageSizeFrameError = (err) => {
|
|
615
|
+
if (!err)
|
|
616
|
+
return false;
|
|
617
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
618
|
+
return LBUG_FRAME_RELEASE_RE.test(msg) || LBUG_PAGE_COMBO_RE.test(msg);
|
|
619
|
+
};
|
|
620
|
+
exports.isLbugPageSizeFrameError = isLbugPageSizeFrameError;
|
|
621
|
+
/**
|
|
622
|
+
* True when the given `@ladybugdb/core` version contains the runtime
|
|
623
|
+
* OS-page-size detection introduced in 0.18.0 (see the matcher comment
|
|
624
|
+
* above). Unknown/unparseable versions return false so callers err on the
|
|
625
|
+
* side of showing the upgrade hint.
|
|
626
|
+
*/
|
|
627
|
+
const isPageSizeAwareLadybug = (version) => {
|
|
628
|
+
if (!version)
|
|
629
|
+
return false;
|
|
630
|
+
const m = /^(\d+)\.(\d+)/.exec(version.trim());
|
|
631
|
+
if (!m)
|
|
632
|
+
return false;
|
|
633
|
+
const major = Number(m[1]);
|
|
634
|
+
const minor = Number(m[2]);
|
|
635
|
+
return major > 0 || minor >= 18;
|
|
636
|
+
};
|
|
637
|
+
exports.isPageSizeAwareLadybug = isPageSizeAwareLadybug;
|
|
638
|
+
// `undefined` = not probed yet; `null` = probed and unavailable. Cached
|
|
639
|
+
// because analyze error paths and doctor may both ask, and getconf forks.
|
|
640
|
+
let cachedOsPageSize;
|
|
641
|
+
/**
|
|
642
|
+
* Test seam (the `_captureLogger` convention): pin the memoized OS page size
|
|
643
|
+
* so sizing tests are host-independent — without this they would silently
|
|
644
|
+
* drift on 16 KiB-page Apple Silicon runners. `number` pins a value, `null`
|
|
645
|
+
* pins "undetectable", `undefined` clears the memo so the next call re-probes.
|
|
646
|
+
*/
|
|
647
|
+
const _setOsPageSizeForTests = (pageSize) => {
|
|
648
|
+
cachedOsPageSize = pageSize;
|
|
649
|
+
};
|
|
650
|
+
exports._setOsPageSizeForTests = _setOsPageSizeForTests;
|
|
651
|
+
/**
|
|
652
|
+
* OS memory page size in bytes, or `undefined` when it cannot be determined
|
|
653
|
+
* (Windows, missing getconf, sandboxed exec). Node exposes no page-size API,
|
|
654
|
+
* so this shells out to POSIX `getconf PAGE_SIZE` — same execFileSync shape
|
|
655
|
+
* as the Windows 8.3 short-path probe above, but with a tighter timeout and
|
|
656
|
+
* an explicit killSignal (see the options comment below).
|
|
657
|
+
*/
|
|
658
|
+
const getOsPageSize = () => {
|
|
659
|
+
if (cachedOsPageSize !== undefined)
|
|
660
|
+
return cachedOsPageSize ?? undefined;
|
|
661
|
+
if (process.platform === 'win32') {
|
|
662
|
+
// Windows allocation granularity is not what madvise alignment is about;
|
|
663
|
+
// the #1231 failure mode is POSIX-only.
|
|
664
|
+
cachedOsPageSize = null;
|
|
665
|
+
return undefined;
|
|
666
|
+
}
|
|
667
|
+
try {
|
|
668
|
+
// killSignal SIGKILL (first use in this repo): the default SIGTERM is
|
|
669
|
+
// catchable, so a signal-trapping child held the "5s" timeout for 9s in
|
|
670
|
+
// review reproduction — SIGKILL makes the timeout real for everything
|
|
671
|
+
// except a child stuck in uninterruptible I/O (D state). 2000ms, not
|
|
672
|
+
// 5000: doctor runs this probe on its happy path and real getconf
|
|
673
|
+
// answers in ~2ms, but keep margin for loaded Pi-class hardware — a
|
|
674
|
+
// too-tight ceiling would silently drop the very #1231 diagnostics this
|
|
675
|
+
// probe exists to provide (the catch caches the failure). (#2424 review)
|
|
676
|
+
const out = (0, child_process_1.execFileSync)('getconf', ['PAGE_SIZE'], {
|
|
677
|
+
encoding: 'utf-8',
|
|
678
|
+
timeout: 2000,
|
|
679
|
+
killSignal: 'SIGKILL',
|
|
680
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
681
|
+
});
|
|
682
|
+
const parsed = Number(out.trim());
|
|
683
|
+
cachedOsPageSize = Number.isInteger(parsed) && parsed > 0 ? parsed : null;
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
cachedOsPageSize = null;
|
|
687
|
+
}
|
|
688
|
+
return cachedOsPageSize ?? undefined;
|
|
689
|
+
};
|
|
690
|
+
exports.getOsPageSize = getOsPageSize;
|
|
691
|
+
/**
|
|
692
|
+
* Return true when the error message indicates that a LadybugDB write
|
|
693
|
+
* transaction could not proceed due to lock contention — either a file
|
|
694
|
+
* lock that could not be acquired (either at construction time,
|
|
695
|
+
* `new lbug.Database(...)` raising from `local_file_system.cpp`, or during
|
|
696
|
+
* a query, another writer holds the exclusive lock), or a same-process
|
|
697
|
+
* write transaction rejected because another write transaction is already
|
|
698
|
+
* active on the connection.
|
|
699
|
+
*
|
|
700
|
+
* Lives here (not in `lbug-adapter.ts`) so both the construction-time
|
|
701
|
+
* retry (`openWithLockRetry` in this file) and the query-time retry
|
|
702
|
+
* (`withLbugDb` in `lbug-adapter.ts`) consult the same matcher. Callers
|
|
703
|
+
* import directly from this module — no re-export to keep in sync.
|
|
704
|
+
*/
|
|
705
|
+
const isDbBusyError = (err) => {
|
|
706
|
+
const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
707
|
+
// `lock` already subsumes `could not set lock`; the broader term is kept
|
|
708
|
+
// because graph-DB transient errors include "deadlock", "lock contention",
|
|
709
|
+
// and the LadybugDB native module's "could not set lock on file" — all of
|
|
710
|
+
// which deserve a retry. LadybugDB also reports same-process writer
|
|
711
|
+
// contention without the words "busy" or "lock".
|
|
712
|
+
//
|
|
713
|
+
// "only one write transaction at a time" was observed against LadybugDB
|
|
714
|
+
// 0.18.0 (see cgraph/package.json @ladybugdb/core).
|
|
715
|
+
//
|
|
716
|
+
// If a non-transient lock-shaped error ever surfaces (e.g., "lock file
|
|
717
|
+
// missing" during recovery), tighten this matcher rather than raising the
|
|
718
|
+
// retry budget.
|
|
719
|
+
return (msg.includes('busy') ||
|
|
720
|
+
msg.includes('lock') ||
|
|
721
|
+
msg.includes('already in use') ||
|
|
722
|
+
msg.includes('only one write transaction at a time'));
|
|
723
|
+
};
|
|
724
|
+
exports.isDbBusyError = isDbBusyError;
|
|
725
|
+
/**
|
|
726
|
+
* True when a WAL-checkpoint IO error ALSO carries a busy/lock signal — the
|
|
727
|
+
* rotation failed because another handle (a `cgraph mcp` server, or this
|
|
728
|
+
* process's own reader) holds the store's WAL open, rather than a permanent
|
|
729
|
+
* disk error. Reuses `isDbBusyError`'s already-tested keyword set instead of a
|
|
730
|
+
* fresh regex, so an unmatched message degrades to "IO error" rather than
|
|
731
|
+
* silently claiming a held-open cause. (#2599)
|
|
732
|
+
*/
|
|
733
|
+
const isLbugCheckpointBusyError = (err) => {
|
|
734
|
+
if (!(0, exports.isLbugCheckpointIoError)(err))
|
|
735
|
+
return false;
|
|
736
|
+
// Anchor to real held-open wording rather than isDbBusyError's broad
|
|
737
|
+
// `.includes('lock')`, which matches the DB PATH embedded in the checkpoint
|
|
738
|
+
// error message (e.g. a repo under `blockchain-app`) and would misclassify a
|
|
739
|
+
// pure disk fault as held-open (#2614 LOW).
|
|
740
|
+
const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
741
|
+
return (msg.includes('could not set lock') ||
|
|
742
|
+
msg.includes('lock is held') ||
|
|
743
|
+
msg.includes('being used by another process') ||
|
|
744
|
+
msg.includes('is busy'));
|
|
745
|
+
};
|
|
746
|
+
exports.isLbugCheckpointBusyError = isLbugCheckpointBusyError;
|
|
747
|
+
/**
|
|
748
|
+
* Classify an error thrown while clearing all relationships of one type
|
|
749
|
+
* before an incremental re-write (`deleteAllRelationshipsOfType` in
|
|
750
|
+
* `lbug-adapter.ts` — the `deleteAllInjects` / `deleteAllCallSummaries` /
|
|
751
|
+
* `deleteAllInterprocTaintPaths` family).
|
|
752
|
+
*
|
|
753
|
+
* - `'benign-missing-table'`: the CodeRelation table does not exist yet
|
|
754
|
+
* (freshly-initialized DB) — the delete-all is a no-op, stay silent.
|
|
755
|
+
* - `'rethrow'`: ANY other failure (lock, disk, closed connection, native
|
|
756
|
+
* error) leaves stale rows that the subsequent re-extract then DUPLICATES
|
|
757
|
+
* (CodeRelation has no PK), so the caller must abort the writeback
|
|
758
|
+
* (#2084 review P2-5).
|
|
759
|
+
*
|
|
760
|
+
* Pure classification, extracted here (next to the other error matchers) so
|
|
761
|
+
* the load-bearing regex/branch is unit-testable without a native DB —
|
|
762
|
+
* driving a synthetic failure through the real singleton connection would
|
|
763
|
+
* break every later test in the shared integration suite (#2200 review).
|
|
764
|
+
*/
|
|
765
|
+
const classifyDeleteAllError = (err) => {
|
|
766
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
767
|
+
return /no table|not exist|not found|does not exist|Table .* does not exist/i.test(msg)
|
|
768
|
+
? 'benign-missing-table'
|
|
769
|
+
: 'rethrow';
|
|
770
|
+
};
|
|
771
|
+
exports.classifyDeleteAllError = classifyDeleteAllError;
|
|
772
|
+
function createLbugDatabase(lbugModule, databasePath, options = {}) {
|
|
773
|
+
// .d.ts declares fewer args than the native constructor accepts.
|
|
774
|
+
return new lbugModule.Database(databasePath, resolveBufferManagerSize(), // bufferManagerSize (#2557: default min(2 GiB, 80% RAM); CGRAPH_LBUG_BUFFER_POOL_SIZE overrides; 0 restores the native 80%-of-RAM default)
|
|
775
|
+
false, // enableCompression (pinned for v0.16.0)
|
|
776
|
+
options.readOnly ?? false, exports.LBUG_MAX_DB_SIZE, true, // autoCheckpoint (always on)
|
|
777
|
+
resolveCheckpointThreshold(), // checkpointThreshold (default 64 MiB; override with CGRAPH_WAL_CHECKPOINT_THRESHOLD; -1 keeps Ladybug stock ~16 MiB)
|
|
778
|
+
options.throwOnWalReplayFailure ?? true, true);
|
|
779
|
+
}
|
|
780
|
+
// ─── Lock-busy retry tuning knobs ───────────────────────────────────────────
|
|
781
|
+
//
|
|
782
|
+
// All four GitNexus retry pairs that touch native LadybugDB locks live with
|
|
783
|
+
// a comment cross-reference here so an SRE tuning Windows flakes finds them
|
|
784
|
+
// in one grep:
|
|
785
|
+
//
|
|
786
|
+
// 1. OPEN_LOCK_RETRY_ATTEMPTS / OPEN_LOCK_RETRY_DELAY_MS (this file)
|
|
787
|
+
// → `new lbug.Database()` constructor lock failures
|
|
788
|
+
// 2. HANDLE_RELEASE_PROBE_ATTEMPTS / HANDLE_RELEASE_PROBE_DELAY_MS (this file)
|
|
789
|
+
// → post-close fs.open probe to absorb Windows handle-release lag; also
|
|
790
|
+
// the shared budget for wipeLbugDbFiles' ENOENT-verified removal
|
|
791
|
+
// (lbug-adapter.ts) and the dirty-recovery sidecar park's
|
|
792
|
+
// rename/rm retries (sidecar-recovery.ts) — same lock class
|
|
793
|
+
// 3. DB_LOCK_RETRY_ATTEMPTS / DB_LOCK_RETRY_DELAY_MS (lbug-adapter.ts withLbugDb)
|
|
794
|
+
// → query-time busy/lock retry around already-open connections
|
|
795
|
+
//
|
|
796
|
+
// `new lbug.Database()` calls into the native module which performs an
|
|
797
|
+
// OS-level exclusive lock on `<dbPath>`. On Windows that lock can fail
|
|
798
|
+
// for reasons specific to the OS (Defender briefly opens new files,
|
|
799
|
+
// libuv handle release lags the JS-side close). 5 attempts × 100ms
|
|
800
|
+
// linear back-off (max sleep 100+200+300+400 = 1s, plus 5 ctor RTTs
|
|
801
|
+
// of 10–50ms each = ~1.0–1.2s worst case) clears the typical
|
|
802
|
+
// AV-scanner hold without masking real cross-process conflicts.
|
|
803
|
+
//
|
|
804
|
+
// Source: https://github.com/LadybugDB/ladybug/blob/v0.18.0/src/common/file_system/local_file_system.cpp#L127
|
|
805
|
+
// (v0.18.0 appends " (Error: <code>)" / " (Lock is held by PID X)" on POSIX,
|
|
806
|
+
// but the "Could not set lock on file : " prefix `isDbBusyError` substring-
|
|
807
|
+
// matches on is unchanged.)
|
|
808
|
+
const OPEN_LOCK_RETRY_ATTEMPTS = 5;
|
|
809
|
+
const OPEN_LOCK_RETRY_DELAY_MS = 100;
|
|
810
|
+
// Exported (this shipping review, FIX 1/2): the dirty-recovery sidecar park
|
|
811
|
+
// (sidecar-recovery.ts) and the ENOENT-verified wipe (lbug-adapter.ts
|
|
812
|
+
// wipeLbugDbFiles) retry the SAME Windows handle-release/AV lock class, and
|
|
813
|
+
// their previous private mirror constants were documentation-coupled copies
|
|
814
|
+
// that could drift from this tuning-knob registry silently.
|
|
815
|
+
exports.HANDLE_RELEASE_PROBE_ATTEMPTS = 5;
|
|
816
|
+
exports.HANDLE_RELEASE_PROBE_DELAY_MS = 50;
|
|
817
|
+
const HANDLE_RELEASE_LOCK_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);
|
|
818
|
+
// Retry-budget registry, part 2 (retry-budget consolidation): the remaining
|
|
819
|
+
// open-time lock retries live next to their call sites but are catalogued here
|
|
820
|
+
// so all lbug retry budgets surface in one grep. They retry the same lock class
|
|
821
|
+
// as 1–3 ("Could not set lock" while a writer rebuilds the index):
|
|
822
|
+
// 4. LOCK_RETRY_ATTEMPTS / LOCK_RETRY_DELAY_MS (pool-adapter.ts)
|
|
823
|
+
// → read pool's read-only open while `cgraph analyze` is writing
|
|
824
|
+
// (3 attempts, linear 2s·n back-off ≈ 6s total)
|
|
825
|
+
// 5. LBUG_OPEN_RETRY_ATTEMPTS / _BASE_MS / _MAX_MS (group/bridge-db.ts)
|
|
826
|
+
// → cross-repo bridge RO open race (10 attempts, linear 100ms·n capped
|
|
827
|
+
// at 500ms ≈ 3.5s total)
|
|
828
|
+
// Kept in-file (not moved here) so explicit `lbug-config` test mocks don't have
|
|
829
|
+
// to enumerate them; change a budget in its call site and update this catalogue.
|
|
830
|
+
/**
|
|
831
|
+
* Test-fixture directory prefixes recognized by `isTestFixturePath`.
|
|
832
|
+
*
|
|
833
|
+
* IMPORTANT: this list must stay in sync with the prefixes passed to
|
|
834
|
+
* `createTempDir` in `cgraph/test/helpers/test-db.ts` and the prefixes
|
|
835
|
+
* used by `withTestLbugDB` (`cgraph/test/helpers/test-indexed-db.ts`).
|
|
836
|
+
* If you add a new test that passes a custom prefix to `createTempDir`,
|
|
837
|
+
* add it here too — otherwise the stale-sidecar sweep silently won't
|
|
838
|
+
* fire for that fixture and CI flakes return.
|
|
839
|
+
*
|
|
840
|
+
* The default `createTempDir('gitnexus-test-')` and the lbug variant
|
|
841
|
+
* `'gitnexus-lbug-'` cover today's call sites.
|
|
842
|
+
*/
|
|
843
|
+
const TEST_FIXTURE_PREFIXES = ['gitnexus-lbug-', 'gitnexus-test-'];
|
|
844
|
+
/**
|
|
845
|
+
* Marker symbol attached to lock errors after `openWithLockRetry` exhausts
|
|
846
|
+
* its budget. `withLbugDb`'s outer query-time retry consults this so it
|
|
847
|
+
* does not re-retry a path that just spent up to ~1.5s in the open-time
|
|
848
|
+
* loop — preventing 6s tail latencies (3× outer × 5× inner attempts).
|
|
849
|
+
*
|
|
850
|
+
* The symbol is internal to GitNexus; consumers should treat the underlying
|
|
851
|
+
* error message as the user-visible signal.
|
|
852
|
+
*/
|
|
853
|
+
exports.LBUG_OPEN_RETRY_EXHAUSTED = Symbol.for('gitnexus.lbug.openRetryExhausted');
|
|
854
|
+
const isOpenRetryExhausted = (err) => {
|
|
855
|
+
if (err === null || err === undefined || typeof err !== 'object')
|
|
856
|
+
return false;
|
|
857
|
+
return err[exports.LBUG_OPEN_RETRY_EXHAUSTED] === true;
|
|
858
|
+
};
|
|
859
|
+
exports.isOpenRetryExhausted = isOpenRetryExhausted;
|
|
860
|
+
const tagOpenRetryExhausted = (err) => {
|
|
861
|
+
if (err && typeof err === 'object') {
|
|
862
|
+
err[exports.LBUG_OPEN_RETRY_EXHAUSTED] = true;
|
|
863
|
+
}
|
|
864
|
+
return err;
|
|
865
|
+
};
|
|
866
|
+
/**
|
|
867
|
+
* True when `dbPath` resolves to a recognized test fixture under the OS
|
|
868
|
+
* temp directory. Used to gate the stale-sidecar sweep so production
|
|
869
|
+
* paths never have their `.wal` / `.lock` files deleted.
|
|
870
|
+
*
|
|
871
|
+
* Defensive shape:
|
|
872
|
+
* - `path.resolve` normalizes `..` segments before the prefix check, so
|
|
873
|
+
* `<tmp>/gitnexus-lbug-x/../../etc/passwd` is rejected.
|
|
874
|
+
* - The tmpRoot check trims any trailing separator returned by some
|
|
875
|
+
* Windows TMP configurations (`C:\Users\X\Temp\`) so the startsWith
|
|
876
|
+
* comparison stays correct.
|
|
877
|
+
* - Only the IMMEDIATE parent directory is matched against the prefix
|
|
878
|
+
* list. An ancestor walk would let a tmpdir whose own basename starts
|
|
879
|
+
* with `gitnexus-lbug-` accept arbitrary nested paths under it.
|
|
880
|
+
*/
|
|
881
|
+
const isTestFixturePath = (dbPath) => {
|
|
882
|
+
const tmpRoot = os_1.default.tmpdir().replace(new RegExp(`${path_1.default.sep === '\\' ? '\\\\' : path_1.default.sep}+$`), '');
|
|
883
|
+
const resolved = path_1.default.resolve(dbPath);
|
|
884
|
+
if (!resolved.startsWith(tmpRoot + path_1.default.sep) && resolved !== tmpRoot)
|
|
885
|
+
return false;
|
|
886
|
+
const parentBase = path_1.default.basename(path_1.default.dirname(resolved));
|
|
887
|
+
return TEST_FIXTURE_PREFIXES.some((p) => parentBase.startsWith(p));
|
|
888
|
+
};
|
|
889
|
+
/** Exported only for direct unit testing — production callers use `openWithLockRetry`. */
|
|
890
|
+
exports._isTestFixturePathForTest = isTestFixturePath;
|
|
891
|
+
// Exported alongside HANDLE_RELEASE_PROBE_* (this shipping review, FIX 1/2)
|
|
892
|
+
// so the consumers of the shared retry budget do not each grow a private copy.
|
|
893
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
894
|
+
exports.sleep = sleep;
|
|
895
|
+
/**
|
|
896
|
+
* Attempt to remove stale `.wal` / `.lock` sidecars that a previous aborted
|
|
897
|
+
* test run may have left behind. Best-effort: ENOENT is normal, anything
|
|
898
|
+
* else is swallowed so the caller's retry can surface the original error.
|
|
899
|
+
*/
|
|
900
|
+
const sweepStaleSidecars = async (dbPath) => {
|
|
901
|
+
for (const suffix of ['.wal', '.lock']) {
|
|
902
|
+
try {
|
|
903
|
+
await promises_1.default.unlink(dbPath + suffix);
|
|
904
|
+
}
|
|
905
|
+
catch {
|
|
906
|
+
/* missing sidecar or permission error — let the open retry surface it */
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
/**
|
|
911
|
+
* Run `construct` with bounded retries when `new lbug.Database(...)` throws
|
|
912
|
+
* a busy/lock error. The original (loop-captured) error is preferred over
|
|
913
|
+
* any post-sweep error so triage sees the real LadybugDB lock message.
|
|
914
|
+
* On exhaustion the rethrown error is tagged via
|
|
915
|
+
* `LBUG_OPEN_RETRY_EXHAUSTED` so the outer query-time retry in
|
|
916
|
+
* `withLbugDb` skips re-retrying a freshly-exhausted path.
|
|
917
|
+
*/
|
|
918
|
+
const openWithLockRetry = async (construct, dbPath) => {
|
|
919
|
+
let originalLockError;
|
|
920
|
+
for (let attempt = 1; attempt <= OPEN_LOCK_RETRY_ATTEMPTS; attempt++) {
|
|
921
|
+
try {
|
|
922
|
+
return construct();
|
|
923
|
+
}
|
|
924
|
+
catch (err) {
|
|
925
|
+
if (!(0, exports.isDbBusyError)(err))
|
|
926
|
+
throw err;
|
|
927
|
+
originalLockError = err;
|
|
928
|
+
if (attempt === OPEN_LOCK_RETRY_ATTEMPTS)
|
|
929
|
+
break;
|
|
930
|
+
await (0, exports.sleep)(OPEN_LOCK_RETRY_DELAY_MS * attempt);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
// Final defense: only for recognized test fixtures, sweep stale sidecars
|
|
934
|
+
// (a prior aborted test run can leave a `.wal` lock that survives the
|
|
935
|
+
// tmp dir cleanup). Production paths never reach this branch — the guard
|
|
936
|
+
// requires the immediate parent dir to match a test prefix AND the
|
|
937
|
+
// resolved path to live under the OS temp directory.
|
|
938
|
+
if (isTestFixturePath(dbPath)) {
|
|
939
|
+
await sweepStaleSidecars(dbPath);
|
|
940
|
+
try {
|
|
941
|
+
return construct();
|
|
942
|
+
}
|
|
943
|
+
catch {
|
|
944
|
+
// Intentionally do NOT overwrite originalLockError. The user-actionable
|
|
945
|
+
// signal is "we exhausted lock retries" — a different error from the
|
|
946
|
+
// post-sweep attempt is less useful than the lock failure that drove
|
|
947
|
+
// the sweep in the first place.
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
throw tagOpenRetryExhausted(originalLockError);
|
|
951
|
+
};
|
|
952
|
+
async function openLbugConnection(lbugModule, databasePath, options = {}) {
|
|
953
|
+
const safePath = toNativeSafePath(databasePath);
|
|
954
|
+
let db;
|
|
955
|
+
try {
|
|
956
|
+
db = await openWithLockRetry(() => createLbugDatabase(lbugModule, safePath, options), safePath);
|
|
957
|
+
return { db, conn: new lbugModule.Connection(db) };
|
|
958
|
+
}
|
|
959
|
+
catch (err) {
|
|
960
|
+
if (db)
|
|
961
|
+
await db.close().catch(() => { });
|
|
962
|
+
throw err;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
async function closeLbugConnection(handle) {
|
|
966
|
+
await handle.conn.close().catch(() => { });
|
|
967
|
+
await handle.db.close().catch(() => { });
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Probe `dbPath` AND its `.wal` sidecar after `db.close()` so any
|
|
971
|
+
* residual native file handle surfaces as EBUSY/EPERM/EACCES and the
|
|
972
|
+
* bounded retry absorbs the release lag. Windows-only — Linux/macOS do
|
|
973
|
+
* not exhibit this race.
|
|
974
|
+
*
|
|
975
|
+
* Both files matter. Empirically, on rapid open→close→reopen cycles the
|
|
976
|
+
* main `dbPath` handle releases first; the `.wal` handle from the
|
|
977
|
+
* previous Database lingers and the new Database's first write (CREATE
|
|
978
|
+
* NODE TABLE during schema init) fails with "Could not set lock on
|
|
979
|
+
* file". Probing both makes safeClose actually return when the kernel
|
|
980
|
+
* is fully done with the path.
|
|
981
|
+
*
|
|
982
|
+
* Returns `true` when both probes succeeded (or skipped on non-lock
|
|
983
|
+
* errors / missing files). Returns `false` when either probe exhausted
|
|
984
|
+
* its budget with a lock code still in flight.
|
|
985
|
+
*
|
|
986
|
+
* Defensive shape:
|
|
987
|
+
* - Opens read+write (`'r+'`) so the probe actually surfaces exclusive
|
|
988
|
+
* locks held by the previous Database. A read-only probe (`'r'`) is
|
|
989
|
+
* insufficient — Windows will grant read access while the previous
|
|
990
|
+
* handle's exclusive write lock is still in flight, which lets
|
|
991
|
+
* `safeClose` return before the next CREATE NODE TABLE can lock the
|
|
992
|
+
* file.
|
|
993
|
+
* - `try/finally` around `handle.close()` guarantees no fd leak even
|
|
994
|
+
* if close itself throws.
|
|
995
|
+
*/
|
|
996
|
+
const waitForWindowsHandleRelease = async (dbPath) => {
|
|
997
|
+
const mainReleased = await probeSinglePath(dbPath);
|
|
998
|
+
const walReleased = await probeSinglePath(dbPath + '.wal');
|
|
999
|
+
return mainReleased && walReleased;
|
|
1000
|
+
};
|
|
1001
|
+
exports.waitForWindowsHandleRelease = waitForWindowsHandleRelease;
|
|
1002
|
+
const probeSinglePath = async (filePath) => {
|
|
1003
|
+
for (let attempt = 1; attempt <= exports.HANDLE_RELEASE_PROBE_ATTEMPTS; attempt++) {
|
|
1004
|
+
let handle;
|
|
1005
|
+
try {
|
|
1006
|
+
handle = await promises_1.default.open(filePath, 'r+');
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
1009
|
+
catch (err) {
|
|
1010
|
+
const code = err?.code;
|
|
1011
|
+
if (!code || !HANDLE_RELEASE_LOCK_CODES.has(code))
|
|
1012
|
+
return true; // ENOENT / unrelated → not our problem
|
|
1013
|
+
if (attempt === exports.HANDLE_RELEASE_PROBE_ATTEMPTS)
|
|
1014
|
+
return false;
|
|
1015
|
+
await (0, exports.sleep)(exports.HANDLE_RELEASE_PROBE_DELAY_MS * attempt);
|
|
1016
|
+
}
|
|
1017
|
+
finally {
|
|
1018
|
+
if (handle) {
|
|
1019
|
+
try {
|
|
1020
|
+
await handle.close();
|
|
1021
|
+
}
|
|
1022
|
+
catch {
|
|
1023
|
+
/* swallow — caller cannot do anything useful with a probe-close failure */
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
return false;
|
|
1029
|
+
};
|