gitnexus 1.6.11-rc.8 → 1.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -26
- package/dist/_shared/graph/types.d.ts +81 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +2 -1
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +4 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts +3 -0
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +4 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +10 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +15 -0
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +4 -0
- package/dist/cli/ai-context.js +90 -14
- package/dist/cli/analyze-config.js +14 -0
- package/dist/cli/analyze-options.d.ts +14 -0
- package/dist/cli/analyze-watch.d.ts +20 -0
- package/dist/cli/analyze-watch.js +434 -0
- package/dist/cli/analyze.js +27 -9
- package/dist/cli/auto-sync.d.ts +1 -0
- package/dist/cli/auto-sync.js +107 -0
- package/dist/cli/command-banner.d.ts +15 -0
- package/dist/cli/command-banner.js +42 -0
- package/dist/cli/detect-changes-format.js +21 -0
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.js +14 -0
- package/dist/cli/group.js +7 -1
- package/dist/cli/help-i18n.js +4 -0
- package/dist/cli/i18n/en.d.ts +18 -3
- package/dist/cli/i18n/en.js +18 -3
- package/dist/cli/i18n/resources.d.ts +33 -3
- package/dist/cli/i18n/zh-CN.d.ts +15 -0
- package/dist/cli/i18n/zh-CN.js +18 -3
- package/dist/cli/index.js +34 -7
- package/dist/cli/mcp.d.ts +15 -0
- package/dist/cli/mcp.js +44 -0
- package/dist/cli/optional-grammars.d.ts +3 -2
- package/dist/cli/optional-grammars.js +19 -3
- package/dist/cli/setup.js +41 -15
- package/dist/cli/update-notice.d.ts +34 -0
- package/dist/cli/update-notice.js +91 -0
- package/dist/cli/update.d.ts +21 -0
- package/dist/cli/update.js +93 -0
- package/dist/cli/watch.d.ts +1 -20
- package/dist/cli/watch.js +5 -371
- package/dist/core/analysis-feature-registry.d.ts +2 -0
- package/dist/core/analysis-feature-registry.js +15 -0
- package/dist/core/analyzer-identity.js +21 -3
- package/dist/core/auto-sync/analysis-worker-launch.d.ts +30 -0
- package/dist/core/auto-sync/analysis-worker-launch.js +166 -0
- package/dist/core/auto-sync/config.d.ts +33 -0
- package/dist/core/auto-sync/config.js +320 -0
- package/dist/core/auto-sync/index.d.ts +6 -0
- package/dist/core/auto-sync/index.js +6 -0
- package/dist/core/auto-sync/path-security.d.ts +9 -0
- package/dist/core/auto-sync/path-security.js +251 -0
- package/dist/core/auto-sync/repo.d.ts +1 -0
- package/dist/core/auto-sync/repo.js +6 -0
- package/dist/core/auto-sync/runner.d.ts +44 -0
- package/dist/core/auto-sync/runner.js +428 -0
- package/dist/core/auto-sync/starter.d.ts +50 -0
- package/dist/core/auto-sync/starter.js +497 -0
- package/dist/core/auto-sync/state.d.ts +37 -0
- package/dist/core/auto-sync/state.js +119 -0
- package/dist/core/group/config-parser.js +8 -1
- package/dist/core/group/cross-impact.d.ts +3 -0
- package/dist/core/group/cross-impact.js +36 -4
- package/dist/core/group/extractors/http-patterns/java.js +22 -8
- package/dist/core/group/extractors/http-patterns/kotlin.js +86 -31
- package/dist/core/group/extractors/http-patterns/node.js +145 -8
- package/dist/core/group/extractors/http-patterns/python.js +11 -7
- package/dist/core/group/extractors/http-route-extractor.js +63 -17
- package/dist/core/group/extractors/java-workspace-extractor.js +244 -31
- package/dist/core/group/group-lock.js +5 -6
- package/dist/core/group/normalization.d.ts +38 -1
- package/dist/core/group/normalization.js +59 -3
- package/dist/core/group/service.d.ts +11 -0
- package/dist/core/group/service.js +13 -1
- package/dist/core/group/storage.js +2 -2
- package/dist/core/group/sync.d.ts +24 -1
- package/dist/core/group/sync.js +46 -8
- package/dist/core/group/types.d.ts +13 -0
- package/dist/core/incremental/derived-writeback.d.ts +36 -0
- package/dist/core/incremental/derived-writeback.js +68 -0
- package/dist/core/incremental/spring-config-drift.d.ts +12 -0
- package/dist/core/incremental/spring-config-drift.js +46 -0
- package/dist/core/incremental/subgraph-extract.d.ts +7 -4
- package/dist/core/incremental/subgraph-extract.js +30 -5
- package/dist/core/ingestion/asyncapi/document.d.ts +226 -0
- package/dist/core/ingestion/asyncapi/document.js +758 -0
- package/dist/core/ingestion/asyncapi/protocol.d.ts +79 -0
- package/dist/core/ingestion/asyncapi/protocol.js +203 -0
- package/dist/core/ingestion/call-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/zig.js +4 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.d.ts +100 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.js +319 -0
- package/dist/core/ingestion/call-processor.js +3 -1
- package/dist/core/ingestion/class-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/zig.js +32 -0
- package/dist/core/ingestion/class-extractors/generic.js +4 -1
- package/dist/core/ingestion/class-types.d.ts +6 -2
- package/dist/core/ingestion/destination-key.d.ts +59 -0
- package/dist/core/ingestion/destination-key.js +61 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +6 -2
- package/dist/core/ingestion/entry-point-scoring.js +8 -44
- package/dist/core/ingestion/export-detection.d.ts +37 -0
- package/dist/core/ingestion/export-detection.js +60 -0
- package/dist/core/ingestion/field-extractors/configs/zig.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/zig.js +49 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +1 -1
- package/dist/core/ingestion/field-extractors/generic.js +12 -1
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.d.ts +26 -0
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.js +843 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +5 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +9 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +8 -1
- package/dist/core/ingestion/frameworks/spring/argument-facts.d.ts +80 -0
- package/dist/core/ingestion/frameworks/spring/argument-facts.js +85 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +1 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +2 -1
- package/dist/core/ingestion/frameworks/spring/destinations.d.ts +539 -0
- package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.d.ts +22 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.js +124 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.d.ts +78 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.js +90 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +29 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.d.ts +7 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.js +22 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.d.ts +13 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.js +26 -0
- package/dist/core/ingestion/import-resolvers/zig.d.ts +34 -0
- package/dist/core/ingestion/import-resolvers/zig.js +193 -0
- package/dist/core/ingestion/language-config.d.ts +177 -0
- package/dist/core/ingestion/language-config.js +719 -0
- package/dist/core/ingestion/language-provider.d.ts +178 -1
- package/dist/core/ingestion/language-provider.js +22 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.d.ts +62 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.js +954 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.d.ts +3 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.js +6 -1
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +8 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java/analysis-features.d.ts +1 -1
- package/dist/core/ingestion/languages/java/analysis-features.js +14 -6
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +8 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +34 -0
- package/dist/core/ingestion/languages/java/captures.js +22 -1
- package/dist/core/ingestion/languages/java/lombok-synthesizer.d.ts +42 -0
- package/dist/core/ingestion/languages/java/lombok-synthesizer.js +439 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.js +62 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +17 -1
- package/dist/core/ingestion/languages/java/spring-di.js +44 -2
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.js +62 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.d.ts +20 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.js +83 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +11 -1
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +13 -3
- package/dist/core/ingestion/languages/java.js +18 -8
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.d.ts +99 -0
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.js +173 -0
- package/dist/core/ingestion/languages/jvm/beanspec.d.ts +17 -0
- package/dist/core/ingestion/languages/jvm/beanspec.js +42 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +15 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +50 -0
- package/dist/core/ingestion/languages/kotlin/captures.js +24 -1
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.d.ts +26 -0
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.js +417 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.js +172 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.d.ts +18 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.js +411 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +51 -1
- package/dist/core/ingestion/languages/kotlin/spring-di.js +86 -6
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.js +77 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.d.ts +17 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.js +119 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +16 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +77 -2
- package/dist/core/ingestion/languages/kotlin.js +24 -0
- package/dist/core/ingestion/languages/python.js +2 -0
- package/dist/core/ingestion/languages/rust/query.js +8 -8
- package/dist/core/ingestion/languages/zig/captures.d.ts +260 -0
- package/dist/core/ingestion/languages/zig/captures.js +2070 -0
- package/dist/core/ingestion/languages/zig/index.d.ts +4 -0
- package/dist/core/ingestion/languages/zig/index.js +4 -0
- package/dist/core/ingestion/languages/zig/interpret.d.ts +36 -0
- package/dist/core/ingestion/languages/zig/interpret.js +176 -0
- package/dist/core/ingestion/languages/zig/query.d.ts +3 -0
- package/dist/core/ingestion/languages/zig/query.js +426 -0
- package/dist/core/ingestion/languages/zig/range-binding.d.ts +37 -0
- package/dist/core/ingestion/languages/zig/range-binding.js +373 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.d.ts +12 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.js +58 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.d.ts +25 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.js +143 -0
- package/dist/core/ingestion/languages/zig.d.ts +32 -0
- package/dist/core/ingestion/languages/zig.js +130 -0
- package/dist/core/ingestion/method-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/zig.js +120 -0
- package/dist/core/ingestion/method-extractors/generic.js +16 -4
- package/dist/core/ingestion/method-types.d.ts +10 -4
- package/dist/core/ingestion/model/field-registry.d.ts +3 -3
- package/dist/core/ingestion/model/field-registry.js +11 -7
- package/dist/core/ingestion/model/method-registry.d.ts +3 -3
- package/dist/core/ingestion/model/method-registry.js +13 -8
- package/dist/core/ingestion/model/registration-table.js +3 -0
- package/dist/core/ingestion/model/type-registry.js +8 -4
- package/dist/core/ingestion/pipeline-phases/di.js +47 -14
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +7 -1
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +79 -91
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +2 -1
- package/dist/core/ingestion/pipeline-phases/processes.js +39 -4
- package/dist/core/ingestion/pipeline-phases/routes.js +27 -18
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +4 -1
- package/dist/core/ingestion/pipeline-phases/runner.js +34 -14
- package/dist/core/ingestion/pipeline-phases/scan.js +82 -1
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +8 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +123 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.js +688 -0
- package/dist/core/ingestion/pipeline.d.ts +30 -1
- package/dist/core/ingestion/pipeline.js +52 -14
- package/dist/core/ingestion/resolve-references.js +5 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +16 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +10 -0
- package/dist/core/ingestion/route-extractors/java-const-resolver.d.ts +27 -1
- package/dist/core/ingestion/route-extractors/java-const-resolver.js +161 -13
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.d.ts +12 -18
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.js +214 -33
- package/dist/core/ingestion/route-extractors/kotlin-spring.d.ts +13 -0
- package/dist/core/ingestion/route-extractors/kotlin-spring.js +259 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.d.ts +6 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.js +16 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +30 -1
- package/dist/core/ingestion/route-extractors/spring-shared.js +77 -9
- package/dist/core/ingestion/route-extractors/spring.js +9 -5
- package/dist/core/ingestion/scope-extractor.js +8 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +62 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +4 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +2 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +28 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +11 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +23 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +24 -3
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +11 -1
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +26 -6
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +11 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +29 -3
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +8 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +35 -9
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +1 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +277 -9
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +7 -3
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +43 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +71 -10
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -0
- package/dist/core/ingestion/tree-sitter-queries.js +161 -0
- package/dist/core/ingestion/type-extractors/zig.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/zig.js +17 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +40 -1
- package/dist/core/ingestion/utils/ast-helpers.js +124 -6
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +9 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +75 -14
- package/dist/core/ingestion/utils/test-file-path.d.ts +28 -0
- package/dist/core/ingestion/utils/test-file-path.js +87 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.js +71 -0
- package/dist/core/ingestion/workers/parse-worker.js +85 -14
- package/dist/core/install-context.d.ts +4 -0
- package/dist/core/install-context.js +152 -0
- package/dist/core/lbug/csv-generator.d.ts +10 -1
- package/dist/core/lbug/csv-generator.js +92 -22
- package/dist/core/lbug/graph-emit-sink.d.ts +3 -2
- package/dist/core/lbug/graph-emit-sink.js +4 -2
- package/dist/core/lbug/lbug-adapter.d.ts +100 -5
- package/dist/core/lbug/lbug-adapter.js +236 -24
- package/dist/core/lbug/schema.d.ts +6 -5
- package/dist/core/lbug/schema.js +84 -22
- package/dist/core/net/url-guard.d.ts +6 -0
- package/dist/core/net/url-guard.js +147 -0
- package/dist/core/package-version.d.ts +5 -0
- package/dist/core/package-version.js +10 -0
- package/dist/core/run-analyze.d.ts +21 -4
- package/dist/core/run-analyze.js +426 -117
- package/dist/core/search/fts-indexes.d.ts +19 -1
- package/dist/core/search/fts-indexes.js +28 -1
- package/dist/core/tree-sitter/parser-loader.js +16 -0
- package/dist/core/update-cache.d.ts +39 -0
- package/dist/core/update-cache.js +141 -0
- package/dist/core/update-check.d.ts +31 -0
- package/dist/core/update-check.js +274 -0
- package/dist/mcp/local/local-backend.d.ts +27 -13
- package/dist/mcp/local/local-backend.js +148 -60
- package/dist/mcp/repository-policy.d.ts +5 -1
- package/dist/mcp/repository-policy.js +48 -4
- package/dist/mcp/resources.js +10 -1
- package/dist/mcp/server.js +8 -9
- package/dist/mcp/tools.js +32 -22
- package/dist/server/analyze-launch.d.ts +2 -0
- package/dist/server/analyze-launch.js +2 -0
- package/dist/server/analyze-worker-protocol.d.ts +6 -1
- package/dist/server/analyze-worker.d.ts +1 -0
- package/dist/server/analyze-worker.js +38 -20
- package/dist/server/api.d.ts +5 -1
- package/dist/server/api.js +105 -88
- package/dist/server/git-clone.d.ts +40 -16
- package/dist/server/git-clone.js +253 -199
- package/dist/server/grep-params.d.ts +18 -0
- package/dist/server/grep-params.js +83 -0
- package/dist/server/grep-scan.d.ts +23 -0
- package/dist/server/grep-scan.js +107 -0
- package/dist/server/grep-worker.d.ts +1 -0
- package/dist/server/grep-worker.js +12 -0
- package/dist/server/mcp-http.d.ts +8 -0
- package/dist/server/mcp-http.js +16 -1
- package/dist/server/update-controller.d.ts +29 -0
- package/dist/server/update-controller.js +82 -0
- package/dist/storage/file-lock.d.ts +15 -0
- package/dist/storage/file-lock.js +155 -0
- package/dist/storage/fs-atomic.d.ts +24 -0
- package/dist/storage/fs-atomic.js +86 -2
- package/dist/storage/global-dir.d.ts +2 -0
- package/dist/storage/global-dir.js +6 -0
- package/dist/storage/parse-cache.d.ts +45 -7
- package/dist/storage/parse-cache.js +189 -42
- package/dist/storage/parsedfile-store.d.ts +41 -60
- package/dist/storage/parsedfile-store.js +247 -171
- package/dist/storage/repo-manager.d.ts +10 -4
- package/dist/storage/repo-manager.js +35 -25
- package/dist/storage/repo-meta.d.ts +34 -0
- package/dist/storage/v8-sidecar.d.ts +48 -0
- package/dist/storage/v8-sidecar.js +347 -0
- package/dist/types/pipeline.d.ts +14 -0
- package/dist/utils/process-identity.d.ts +2 -0
- package/dist/utils/process-identity.js +35 -0
- package/package.json +10 -4
- package/scripts/assert-web-assets.mjs +35 -0
- package/scripts/build-web.js +72 -0
- package/scripts/build.js +31 -28
- package/scripts/cross-platform-tests.ts +5 -0
- package/skills/gitnexus-cli.md +5 -1
- package/web/assets/ProcessFlowModal-DAeX2BHW.js +24 -0
- package/web/assets/{abnfDiagram-QNN2D4NM-Cq2djWWe.js → abnfDiagram-PAR5IXJI-J3OdeHLl.js} +1 -1
- package/web/assets/{agent-BWAXPjC5.js → agent-BMRqXorA.js} +6 -4
- package/web/assets/architecture-7GRP2DOG-M7G3SWCO-G3sWyX6M.js +1 -0
- package/web/assets/architectureDiagram-2PNWDENW-ysKcRlGT.js +36 -0
- package/web/assets/blockDiagram-PUWGUBOA-oLXTa1lY.js +129 -0
- package/web/assets/c4Diagram-3NLNHZP5-D3iu4eC0.js +38 -0
- package/web/assets/{chunk-2SREHG4O-Dip42xOq.js → chunk-2NMSUPJH-B24w-wng.js} +1 -1
- package/web/assets/{chunk-VJFVEZTB-CX66F2ep.js → chunk-32MCUW2P-ByUyt0Sa.js} +3 -3
- package/web/assets/{chunk-4RFN2BYJ-DHHWuC-n.js → chunk-3NPNU5GP-DocZ07Sg.js} +1 -1
- package/web/assets/{chunk-XNMVGMAZ-Cg_LnPtj.js → chunk-3SMGFRGC-CAu4JRLv.js} +1 -1
- package/web/assets/{chunk-W44A43WB-BN8EQc_u.js → chunk-4CAJECRU-DRYMwG9z.js} +1 -1
- package/web/assets/chunk-4OADUZ5Q-CxrSvOwZ.js +10 -0
- package/web/assets/{chunk-DMV4VAQV-Bn6WXDSX.js → chunk-5IQCK5RY-CCMhl4so.js} +2 -2
- package/web/assets/{chunk-RRFMTAIC-CMN0wcYA.js → chunk-5MVFYWFU-Db9KvrYO.js} +1 -1
- package/web/assets/chunk-CLS4B6BI-Uvx5QNsu.js +168 -0
- package/web/assets/chunk-DZP67EKU-B3Mt380j.js +70 -0
- package/web/assets/{chunk-6L755F7B-CMhLBxi2.js → chunk-EICP7K5X-CqwE9hui.js} +1 -1
- package/web/assets/{chunk-BI6VK774-D0oaWk8V.js → chunk-GDY2UAB4-CtQQR0a8.js} +1 -1
- package/web/assets/chunk-H7VHZCWX-CE1nAmt6.js +1 -0
- package/web/assets/chunk-IJBDOHL6-BUKtY6oF.js +1 -0
- package/web/assets/{chunk-OIYT25JQ-CQ6KOZGX.js → chunk-JFFVMJIA-0fJenqia.js} +1 -1
- package/web/assets/{chunk-HNC4WDU7-DoU3KnA7.js → chunk-JZGDI5JK-BeTMSSkJ.js} +1 -1
- package/web/assets/{chunk-EQFTRU2I-1ix7TzW9.js → chunk-KD6SPIPN-Qp1Pflah.js} +1 -1
- package/web/assets/chunk-NF366YI6-CpSpya3n.js +231 -0
- package/web/assets/chunk-NUDPKBEF-CU1-BQIW.js +34 -0
- package/web/assets/{chunk-SATU7PGQ-B1zhgOvc.js → chunk-OJINMHTS-zOCQe4eI.js} +1 -1
- package/web/assets/{chunk-E5QJAATJ-dh-5CtIV.js → chunk-Q6NGPIAH-yyBomb63.js} +1 -1
- package/web/assets/chunk-QJSWEUOL-D_rf9gPD.js +128 -0
- package/web/assets/chunk-R7JDMUKV-CRoqKpD6.js +1 -0
- package/web/assets/{chunk-VE5CLXGZ-C1vB7wpY.js → chunk-RCXAM2GK-CUqrWQDV.js} +1 -1
- package/web/assets/{chunk-66DQ2XMT-CM0xjFAN.js → chunk-RT4MAWR3-zXy9-Lvt.js} +1 -1
- package/web/assets/{chunk-TZUXEDM2-B7p9AcTw.js → chunk-SFMINX4W-J2UrvMpD.js} +1 -1
- package/web/assets/{chunk-LORZLZWG-B57uGw2N.js → chunk-SLDQ463B-CHY6e_bQ.js} +2 -2
- package/web/assets/{chunk-FWYVLQTC-BgDItRzJ.js → chunk-TCEHX7R3-CXPDEVbm.js} +1 -1
- package/web/assets/{chunk-224SPVON-B8gxtXpy.js → chunk-VQC2EELJ-Dc8fIy4R.js} +1 -1
- package/web/assets/chunk-VRZKL3EH-DB3KixTQ.js +1 -0
- package/web/assets/{chunk-A7VWPJGB-B4O3oQdQ.js → chunk-VTHDQ7BV-b7FsPQZO.js} +1 -1
- package/web/assets/chunk-VY2OSTJR-Dkgc3Brg.js +2 -0
- package/web/assets/chunk-WUBWJARI-7FwILJ3k.js +2 -0
- package/web/assets/{chunk-D6VWDJW2-BxcBdZ9c.js → chunk-YBMQ5JGJ-BSnyWZmd.js} +1 -1
- package/web/assets/chunk-YDMLL4PJ-IHhMngTz.js +2 -0
- package/web/assets/chunk-Z6V44ARX-BjCEsF0Q.js +62 -0
- package/web/assets/chunk-ZJJ7VQJP-Dz089b-K.js +321 -0
- package/web/assets/chunk-ZNLK7HRR-B0iFpmW4.js +1 -0
- package/web/assets/chunk-ZQN7UHIL-Cy7KAjQt.js +1 -0
- package/web/assets/{chunk-L5GCOVLC-CE2w8Nm_.js → chunk-ZS6VBONO-DBjJO0w9.js} +2 -2
- package/web/assets/{chunk-NV3KIAZN-5yvcpMiu.js → chunk-ZUNWM646-DNRJyNPe.js} +1 -1
- package/web/assets/classDiagram-FGAMPOII-C5Ibyode.js +1 -0
- package/web/assets/classDiagram-v2-AI5RJEK4-C5Ibyode.js +1 -0
- package/web/assets/{cose-bilkent-RZA4XIPR-BHpK4Crp.js → cose-bilkent-Q72C2OJ3-DMeFXnK8.js} +1 -1
- package/web/assets/cynefin-OW5HDTMX-6OCTWOGG-vlqakYcO.js +1 -0
- package/web/assets/{cynefinDiagram-TR7LZUCG-C3Iar9lZ.js → cynefinDiagram-2OOWUY4M-BY6DZkTt.js} +1 -1
- package/web/assets/dagre-MPVFI544-DWO70fy_.js +4 -0
- package/web/assets/diagram-AE4NWXFW-f7JRVRUL.js +24 -0
- package/web/assets/{diagram-L7DVE3PN-GIRyVUtt.js → diagram-BUJID5UG-BXZv1rCS.js} +2 -2
- package/web/assets/{diagram-JCD7PQ7C-DC5-9FRr.js → diagram-C44CZ5NI-CRNfvjCq.js} +1 -1
- package/web/assets/diagram-EYOLEXXS-DZOjKQVE.js +30 -0
- package/web/assets/diagram-P7B6PWOJ-D3SQmw3_.js +3 -0
- package/web/assets/{ebnfDiagram-DRHRQJWO-D8_CI4ZF.js → ebnfDiagram-FTPZ3PV6-jKWpIDN2.js} +1 -1
- package/web/assets/erDiagram-H3ERR26V-BqJntEuJ.js +99 -0
- package/web/assets/eventmodeling-NTZA5JFV-WKSWQHFS-Bq4FqtBL.js +1 -0
- package/web/assets/flowDiagram-YHGXBVSY-Dnlk2bEu.js +1 -0
- package/web/assets/ganttDiagram-RWFTB7ED-Bl6Y1K5T.js +292 -0
- package/web/assets/gitGraph-4MIJSDKK-JH2HKYUO-B3yc4GkH.js +1 -0
- package/web/assets/gitGraphDiagram-MAR6GKOP-CkNvsrdw.js +106 -0
- package/web/assets/{index-CJDpyH-n.css → index-C2_aej58.css} +1 -1
- package/web/assets/{index-DDRie6_8.js → index-Dj3vQOHK.js} +51 -51
- package/web/assets/info-A6RAGUB7-3TX3OFWW-BM3N5_Dv.js +1 -0
- package/web/assets/infoDiagram-LV547AFH-COkFutAf.js +2 -0
- package/web/assets/{ishikawaDiagram-4JDSWWDM-DmqWtjkl.js → ishikawaDiagram-PUJQGNDS-Bb8FylSR.js} +2 -2
- package/web/assets/{journeyDiagram-QUS3FAKT-XAzVzrQW.js → journeyDiagram-EW5QJT4W-BzoHUBhM.js} +4 -4
- package/web/assets/{kanban-definition-D4L7SQKK-YurRnmYn.js → kanban-definition-JSQERAZB-Uy2Pi0yQ.js} +4 -4
- package/web/assets/katex-CZ4GXH2S-C0Fcou7U.js +257 -0
- package/web/assets/{mindmap-definition-66QP5TD6-ChrWWnil.js → mindmap-definition-VBJCLQLM-B-CnOnt_.js} +3 -3
- package/web/assets/packet-AYTQ26CC-MKII6P3Y-Bd52ZE3V.js +1 -0
- package/web/assets/{pegDiagram-YKIO5C6U-QGeQLEq2.js → pegDiagram-7WILOQTJ-D9sneKXg.js} +1 -1
- package/web/assets/pie-WAS4IAKB-6B4OPMJ5-DW5Xy69Z.js +1 -0
- package/web/assets/pieDiagram-EFA7CBSB-Dx2NQofL.js +39 -0
- package/web/assets/{quadrantDiagram-VO5QLCXA-B7098wSc.js → quadrantDiagram-WARVYA7P-DPKL9_0A.js} +3 -3
- package/web/assets/radar-RG4KPBEZ-UPTR3XUL-CkzibT2h.js +1 -0
- package/web/assets/railroad-74A4TZTK-MEFUPFMS-D9zF-mDN.js +1 -0
- package/web/assets/railroad-abnf-HS5TGJTU-R5YG2S5D-ruacjUbX.js +1 -0
- package/web/assets/railroad-ebnf-LZEXJU2U-G5QEX2L6-S1zc5OiO.js +1 -0
- package/web/assets/railroad-peg-WCYAUIDC-H5I2ZRY2-Cbcr0XzY.js +1 -0
- package/web/assets/{railroadDiagram-M77LTMSB-AXu4vxk_.js → railroadDiagram-5NIQVNLQ-DsweTo14.js} +1 -1
- package/web/assets/{requirementDiagram-RASO5HTO-B-l8InpK.js → requirementDiagram-SXREGOKZ-CXwdNSVR.js} +4 -4
- package/web/assets/{sankeyDiagram-F32LOJ6L-Kd7zjJgX.js → sankeyDiagram-VV74M2VP-CA6jtP9P.js} +3 -3
- package/web/assets/{sequenceDiagram-URATNSBD-BlcdY9DS.js → sequenceDiagram-52ZFIFDL-k_5rEbzm.js} +15 -15
- package/web/assets/src-Df5C1Nz4.js +1 -0
- package/web/assets/stateDiagram-3QAKPIVI-BejHTf31.js +1 -0
- package/web/assets/stateDiagram-v2-HN2P4RDZ-BrfoRuOc.js +1 -0
- package/web/assets/swimlanes-QLVP42QD-CQSVO5D6.js +1 -0
- package/web/assets/swimlanesDiagram-JKPDBFCN-DrWB9kcD.js +8 -0
- package/web/assets/{timeline-definition-WJXWRH4I-DUfp1R3E.js → timeline-definition-GS45XAXW-C0Ks8rPP.js} +4 -4
- package/web/assets/treeView-Q6P3EWNA-ZRJGANNQ-DmKOCo6L.js +1 -0
- package/web/assets/treemap-WGGIJYW6-K64VN5AS-DO3xY92U.js +1 -0
- package/web/assets/{vennDiagram-K3VCMQLI-Bj-FN-XS.js → vennDiagram-QIQU2ZRJ-rgPiS837.js} +3 -3
- package/web/assets/wardley-WFR3VGLG-D67OWCCH-DiDPBNft.js +1 -0
- package/web/assets/wardleyDiagram-U6YNM66N-DRVr7SPi.js +78 -0
- package/web/assets/{xychartDiagram-5VRUVLCW-CK_rbSWE.js → xychartDiagram-XJAZEDNM-COtlZzYb.js} +3 -3
- package/web/index.html +19 -17
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +0 -24
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +0 -1
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +0 -36
- package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +0 -132
- package/web/assets/c4Diagram-X2LASM7V-CnhoT4aV.js +0 -10
- package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +0 -127
- package/web/assets/chunk-5VCL7Z4A-CQ-2dYWj.js +0 -1
- package/web/assets/chunk-6BELYETK-ChsYtfHW.js +0 -1
- package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +0 -2
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +0 -32
- package/web/assets/chunk-KRXBNO2N-C-UNuKKf.js +0 -1
- package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +0 -321
- package/web/assets/chunk-LIEV3EAG-pyKGssV3.js +0 -1
- package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +0 -62
- package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +0 -10
- package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +0 -156
- package/web/assets/chunk-SZD42YQK-ijyKKVr1.js +0 -70
- package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +0 -231
- package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +0 -2
- package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +0 -1
- package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +0 -1
- package/web/assets/chunk-WJBAP47W-BckNkuEN.js +0 -1
- package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +0 -1
- package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +0 -1
- package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +0 -1
- package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +0 -4
- package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +0 -30
- package/web/assets/diagram-KFBZAVDW-Dfmf_4ti.js +0 -3
- package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +0 -24
- package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +0 -85
- package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +0 -1
- package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +0 -1
- package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +0 -292
- package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +0 -1
- package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +0 -106
- package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +0 -1
- package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +0 -2
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +0 -257
- package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +0 -1
- package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +0 -1
- package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +0 -39
- package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +0 -1
- package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +0 -1
- package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +0 -1
- package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +0 -1
- package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +0 -1
- package/web/assets/src-C5sx_gMp.js +0 -1
- package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +0 -1
- package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +0 -1
- package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +0 -2
- package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +0 -8
- package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +0 -1
- package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +0 -1
- package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +0 -1
- package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +0 -78
- /package/web/assets/{sizeCapture-5GORAGP4-BEqQzsxs.js → sizeCapture-FGA5AGYP-BEqQzsxs.js} +0 -0
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
*
|
|
25
25
|
* ## Shape
|
|
26
26
|
*
|
|
27
|
-
* `<storagePath>/parsedfile-store/<shardId>.
|
|
28
|
-
* a
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* `<storagePath>/parsedfile-store/<shardId>.v8` — one shard per parse chunk,
|
|
28
|
+
* a V8 envelope of `ParsedFile[]` (Scope.bindings / Scope.typeBindings stay
|
|
29
|
+
* `Map`s). The store is cleared at the start of each parse and after
|
|
30
|
+
* scope-resolution consumes it, so it never lingers and never goes stale
|
|
31
|
+
* across runs.
|
|
32
32
|
*
|
|
33
33
|
* ## Durable sibling store (`parsedfile-cache/`, warm-cache coverage)
|
|
34
34
|
*
|
|
@@ -41,19 +41,21 @@
|
|
|
41
41
|
* that gap we ALSO write the worker's ParsedFiles to a second, CONTENT-ADDRESSED
|
|
42
42
|
* store keyed by the parse chunk hash (`getDurableParsedFileDir`), which mirrors
|
|
43
43
|
* the parse cache's lifecycle (persists across runs, pruned by `usedKeys`,
|
|
44
|
-
* version-tied via `PARSE_CACHE_VERSION`). On a warm hit the chunk's
|
|
45
|
-
* shards are
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* version-tied via `PARSE_CACHE_VERSION`). On a warm hit the chunk's immutable
|
|
45
|
+
* durable shards are hardlinked (or atomically copied) into the run store after
|
|
46
|
+
* their envelope metadata proves complete coverage. That pins a stable snapshot
|
|
47
|
+
* before workers are skipped, even when another branch refreshes the shared
|
|
48
|
+
* durable directory concurrently.
|
|
49
49
|
*/
|
|
50
|
-
import { promises as fs, mkdirSync
|
|
50
|
+
import { promises as fs, mkdirSync } from 'node:fs';
|
|
51
51
|
import path from 'node:path';
|
|
52
52
|
import v8 from 'node:v8';
|
|
53
53
|
import vm from 'node:vm';
|
|
54
54
|
import { isValidReceiverChain } from '../core/ingestion/utils/receiver-chain-codec.js';
|
|
55
55
|
import { logger } from '../core/logger.js';
|
|
56
|
-
import {
|
|
56
|
+
import { mapReviver } from './parse-cache.js';
|
|
57
|
+
import { linkOrCopyFile } from './fs-atomic.js';
|
|
58
|
+
import { inspectV8Cache, tryLoadV8Cache, writeV8CacheFile, writeV8CacheFileSync, } from './v8-sidecar.js';
|
|
57
59
|
const STORE_DIRNAME = 'parsedfile-store';
|
|
58
60
|
const DURABLE_DIRNAME = 'parsedfile-cache';
|
|
59
61
|
const DURABLE_INDEX_FILENAME = 'index.json';
|
|
@@ -148,32 +150,28 @@ export const getParsedFileStoreDir = (storagePath) => path.join(storagePath, STO
|
|
|
148
150
|
export const clearParsedFileStore = async (storagePath) => {
|
|
149
151
|
await fs.rm(getParsedFileStoreDir(storagePath), { recursive: true, force: true });
|
|
150
152
|
};
|
|
153
|
+
const isV8ShardName = (name) => name.endsWith('.v8') && !name.includes('.v8.');
|
|
154
|
+
const shardPath = (storagePath, shardId) => path.join(getParsedFileStoreDir(storagePath), `${shardId}.v8`);
|
|
155
|
+
const shardFilePaths = (parsedFiles) => parsedFiles.map((pf) => pf.filePath);
|
|
156
|
+
const LOAD_YIELD_EVERY_SHARDS = 128;
|
|
151
157
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* sync (`persistParsedFileShardSync`) writers go through this so the two paths
|
|
155
|
-
* are guaranteed byte-identical — the shards must round-trip through the same
|
|
156
|
-
* `mapReviver`, and matching bytes by having both authors type the same
|
|
157
|
-
* `mapReplacer` call would be a coincidence, not a guarantee.
|
|
158
|
+
* Test seam for #3086. Production always calls {@link forceGc}; unit tests
|
|
159
|
+
* replace `run` to count cadence without requiring `--expose-gc`.
|
|
158
160
|
*/
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
export const parsedFileLoadGc = {
|
|
162
|
+
run: forceGc,
|
|
163
|
+
/** V8 envelope bytes visited between GCs (#3086). Tests may lower this. */
|
|
164
|
+
byteBudget: 128 * 1024 * 1024,
|
|
163
165
|
};
|
|
164
|
-
const shardPath = (storagePath, shardId) => path.join(getParsedFileStoreDir(storagePath), `${shardId}.json`);
|
|
165
166
|
/**
|
|
166
|
-
* Write one parse chunk's `ParsedFile[]` to the store as a single shard
|
|
167
|
-
* No-op for an empty chunk. `shardId` must be unique within a run.
|
|
168
|
-
* main-thread no-store-disabled fallback and any non-worker writer; the worker
|
|
169
|
-
* store path uses {@link persistParsedFileShardSync}.
|
|
167
|
+
* Write one parse chunk's `ParsedFile[]` to the store as a single `.v8` shard.
|
|
168
|
+
* No-op for an empty chunk. `shardId` must be unique within a run.
|
|
170
169
|
*/
|
|
171
170
|
export const persistParsedFileChunk = async (storagePath, shardId, parsedFiles) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return;
|
|
171
|
+
if (parsedFiles.length === 0)
|
|
172
|
+
return true;
|
|
175
173
|
await fs.mkdir(getParsedFileStoreDir(storagePath), { recursive: true });
|
|
176
|
-
|
|
174
|
+
return writeV8CacheFile(shardPath(storagePath, shardId), parsedFiles, shardFilePaths(parsedFiles));
|
|
177
175
|
};
|
|
178
176
|
// Per-process set of store dirs we've already `mkdir`ed, so the sync worker
|
|
179
177
|
// writer (called once per job, many times into the same dir) doesn't issue a
|
|
@@ -181,130 +179,106 @@ export const persistParsedFileChunk = async (storagePath, shardId, parsedFiles)
|
|
|
181
179
|
const createdStoreDirs = new Set();
|
|
182
180
|
/**
|
|
183
181
|
* Synchronous shard writer for use INSIDE a parse worker (#1983 parallel
|
|
184
|
-
* serialization).
|
|
185
|
-
*
|
|
186
|
-
* through the synchronous per-file extract loop. Produces byte-identical shards
|
|
187
|
-
* to {@link persistParsedFileChunk} via the shared {@link serializeParsedFileShard}.
|
|
188
|
-
* No-op for an empty chunk. `shardId` must be globally unique for the run (the
|
|
189
|
-
* worker uses `w<threadId>-<seq>`); a duplicate would silently overwrite.
|
|
182
|
+
* serialization). Returns false on write failure so the worker can keep
|
|
183
|
+
* ParsedFiles in the result instead of dropping them.
|
|
190
184
|
*/
|
|
191
185
|
export const persistParsedFileShardSync = (storagePath, shardId, parsedFiles) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return;
|
|
186
|
+
if (parsedFiles.length === 0)
|
|
187
|
+
return true;
|
|
195
188
|
const dir = getParsedFileStoreDir(storagePath);
|
|
196
189
|
if (!createdStoreDirs.has(dir)) {
|
|
197
190
|
mkdirSync(dir, { recursive: true });
|
|
198
191
|
createdStoreDirs.add(dir);
|
|
199
192
|
}
|
|
200
|
-
|
|
193
|
+
return writeV8CacheFileSync(shardPath(storagePath, shardId), parsedFiles, shardFilePaths(parsedFiles));
|
|
201
194
|
};
|
|
202
|
-
|
|
203
|
-
* Stream the store and return the `ParsedFile`s whose `filePath` is in
|
|
204
|
-
* `wantPaths`, keyed by path. Loads one shard at a time and retains only the
|
|
205
|
-
* matching entries, so peak heap is bounded by (matched set) + (one shard)
|
|
206
|
-
* rather than the whole store. Returns an empty map when the store is absent
|
|
207
|
-
* (e.g. tests, or a run with no worker pool) — callers fall back to a fresh
|
|
208
|
-
* extract for the missing files.
|
|
209
|
-
*/
|
|
210
|
-
export const loadParsedFilesForPaths = async (storagePath, wantPaths) => {
|
|
211
|
-
const out = new Map();
|
|
212
|
-
if (wantPaths.size === 0)
|
|
213
|
-
return out;
|
|
214
|
-
const dir = getParsedFileStoreDir(storagePath);
|
|
215
|
-
let shards;
|
|
195
|
+
const listV8Shards = async (dir) => {
|
|
216
196
|
try {
|
|
217
|
-
|
|
197
|
+
return (await fs.readdir(dir)).filter(isV8ShardName).map((name) => path.join(dir, name));
|
|
218
198
|
}
|
|
219
199
|
catch {
|
|
220
|
-
return
|
|
200
|
+
return [];
|
|
221
201
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
202
|
+
};
|
|
203
|
+
export const loadParsedFilesForPaths = async (storagePath, wantPaths) => {
|
|
204
|
+
const out = new Map();
|
|
205
|
+
if (wantPaths.size === 0)
|
|
206
|
+
return out;
|
|
207
|
+
const shardPaths = await listV8Shards(getParsedFileStoreDir(storagePath));
|
|
225
208
|
const pool = new Map();
|
|
226
209
|
let droppedSites = 0;
|
|
227
210
|
let filesWithDroppedSites = 0;
|
|
228
211
|
let droppedChains = 0;
|
|
229
212
|
let rejectedFiles = 0;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const raw = await fs.readFile(path.join(dir, shards[i]), 'utf-8');
|
|
240
|
-
parsed = JSON.parse(raw, reviver);
|
|
213
|
+
let bytesSinceGc = 0;
|
|
214
|
+
let shardsSinceYield = 0;
|
|
215
|
+
const maybeYieldAndGc = async (forceByteGc) => {
|
|
216
|
+
if (forceByteGc) {
|
|
217
|
+
parsedFileLoadGc.run();
|
|
218
|
+
bytesSinceGc = 0;
|
|
219
|
+
shardsSinceYield = 0;
|
|
220
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
221
|
+
return;
|
|
241
222
|
}
|
|
242
|
-
|
|
243
|
-
|
|
223
|
+
shardsSinceYield++;
|
|
224
|
+
if (shardsSinceYield >= LOAD_YIELD_EVERY_SHARDS) {
|
|
225
|
+
shardsSinceYield = 0;
|
|
226
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
244
227
|
}
|
|
245
|
-
|
|
228
|
+
};
|
|
229
|
+
for (const shardFull of shardPaths) {
|
|
230
|
+
const loaded = await tryLoadV8Cache(shardFull, pool, wantPaths);
|
|
231
|
+
if (loaded === undefined) {
|
|
232
|
+
await maybeYieldAndGc(false);
|
|
246
233
|
continue;
|
|
247
|
-
for (const pf of parsed) {
|
|
248
|
-
if (!pf || typeof pf.filePath !== 'string' || !wantPaths.has(pf.filePath))
|
|
249
|
-
continue;
|
|
250
|
-
const flow = sanitizeCallableFlowSites(pf.callableFlowSites);
|
|
251
|
-
if (flow === undefined) {
|
|
252
|
-
// non-array garbage → distrust the file, re-extract
|
|
253
|
-
rejectedFiles++;
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
const chains = sanitizeReceiverChains(pf.referenceSites);
|
|
257
|
-
if (chains === undefined) {
|
|
258
|
-
rejectedFiles++;
|
|
259
|
-
continue;
|
|
260
|
-
}
|
|
261
|
-
if (flow.dropped === 0 && chains.dropped === 0) {
|
|
262
|
-
out.set(pf.filePath, pf);
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
droppedSites += flow.dropped;
|
|
266
|
-
droppedChains += chains.dropped;
|
|
267
|
-
filesWithDroppedSites++;
|
|
268
|
-
out.set(pf.filePath, {
|
|
269
|
-
...pf,
|
|
270
|
-
...(flow.dropped === 0 ? {} : { callableFlowSites: flow.sites }),
|
|
271
|
-
...(chains.dropped === 0 ? {} : { referenceSites: chains.sites }),
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
234
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
forceGc();
|
|
280
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
235
|
+
if (loaded.kind === 'skip') {
|
|
236
|
+
bytesSinceGc += loaded.bytes;
|
|
237
|
+
await maybeYieldAndGc(bytesSinceGc >= parsedFileLoadGc.byteBudget);
|
|
238
|
+
continue;
|
|
281
239
|
}
|
|
240
|
+
bytesSinceGc += loaded.bytes;
|
|
241
|
+
const parsed = Array.isArray(loaded.value) ? loaded.value : undefined;
|
|
242
|
+
const crossedBudget = bytesSinceGc >= parsedFileLoadGc.byteBudget;
|
|
243
|
+
if (Array.isArray(parsed)) {
|
|
244
|
+
for (const pf of parsed) {
|
|
245
|
+
if (!pf || typeof pf.filePath !== 'string' || !wantPaths.has(pf.filePath))
|
|
246
|
+
continue;
|
|
247
|
+
const flow = sanitizeCallableFlowSites(pf.callableFlowSites);
|
|
248
|
+
if (flow === undefined) {
|
|
249
|
+
rejectedFiles++;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
const chains = sanitizeReceiverChains(pf.referenceSites);
|
|
253
|
+
if (chains === undefined) {
|
|
254
|
+
rejectedFiles++;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (flow.dropped === 0 && chains.dropped === 0) {
|
|
258
|
+
out.set(pf.filePath, pf);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
droppedSites += flow.dropped;
|
|
262
|
+
droppedChains += chains.dropped;
|
|
263
|
+
filesWithDroppedSites++;
|
|
264
|
+
out.set(pf.filePath, {
|
|
265
|
+
...pf,
|
|
266
|
+
...(flow.dropped === 0 ? {} : { callableFlowSites: flow.sites }),
|
|
267
|
+
...(chains.dropped === 0 ? {} : { referenceSites: chains.sites }),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
await maybeYieldAndGc(crossedBudget);
|
|
282
273
|
}
|
|
283
274
|
if (droppedSites > 0 || droppedChains > 0) {
|
|
284
|
-
// Facts for the dropped sites are omitted this run (the file itself is
|
|
285
|
-
// retained, so no re-extract happens) — surface it so a recurring drop
|
|
286
|
-
// on every warm load is observable rather than silent (#2522 review).
|
|
287
275
|
logger.warn({ droppedSites, droppedChains, files: filesWithDroppedSites }, 'parsedfile-store: dropped malformed/over-bound sites at load; files retained without those facts');
|
|
288
276
|
}
|
|
289
277
|
if (rejectedFiles > 0) {
|
|
290
|
-
// The other half of the same defect. A rejected file silently falls back to
|
|
291
|
-
// a fresh extract EVERY load, so a writer that keeps minting what this
|
|
292
|
-
// reader keeps refusing is a permanent warm-cache miss that costs real time
|
|
293
|
-
// and says nothing about why.
|
|
294
278
|
logger.warn({ rejectedFiles }, 'parsedfile-store: rejected shard entries at load (untrusted shape); those files re-extract every run');
|
|
295
279
|
}
|
|
296
280
|
return out;
|
|
297
281
|
};
|
|
298
|
-
/**
|
|
299
|
-
* Treat the durable ParsedFile store as an untrusted serialization boundary.
|
|
300
|
-
* Sanitation is per-SITE, not per-file: one malformed or over-bound fact drops
|
|
301
|
-
* only itself (counted, logged by the caller), so a legitimately pathological
|
|
302
|
-
* source file cannot push its whole ParsedFile into a permanent, silent
|
|
303
|
-
* warm-cache-miss reparse loop (#2522 review). Only a non-array field —
|
|
304
|
-
* i.e. garbage that says the serialization itself is untrustworthy — rejects
|
|
305
|
-
* the file, and `undefined` (never emitted / no facts) passes through.
|
|
306
|
-
* Returns `undefined` for the reject-file case.
|
|
307
|
-
*/
|
|
308
282
|
function sanitizeCallableFlowSites(value) {
|
|
309
283
|
if (value === undefined)
|
|
310
284
|
return { sites: undefined, dropped: 0 };
|
|
@@ -486,9 +460,6 @@ export const prepareDurableParsedFileChunk = async (durableDir, chunkHash) => {
|
|
|
486
460
|
await fs.rm(dir, { recursive: true, force: true });
|
|
487
461
|
await fs.mkdir(dir, { recursive: true });
|
|
488
462
|
};
|
|
489
|
-
// Per-process set of durable chunk subdirs already `mkdir`ed (mirrors
|
|
490
|
-
// `createdStoreDirs`) so the worker doesn't `mkdirSync` on every shard.
|
|
491
|
-
const createdDurableDirs = new Set();
|
|
492
463
|
/**
|
|
493
464
|
* Synchronous durable-shard writer for use INSIDE a parse worker, alongside
|
|
494
465
|
* {@link persistParsedFileShardSync}. Writes the SAME bytes to a content-addressed
|
|
@@ -498,63 +469,85 @@ const createdDurableDirs = new Set();
|
|
|
498
469
|
* uniqueness that makes the run-scoped `w<tid>-<seq>` name safe, prefixed by
|
|
499
470
|
* content. No-op for an empty chunk.
|
|
500
471
|
*/
|
|
472
|
+
const createdDurableDirs = new Set();
|
|
501
473
|
export const persistDurableParsedFileShardSync = (durableDir, chunkHash, threadId, shardSeq, parsedFiles) => {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
return;
|
|
474
|
+
if (parsedFiles.length === 0)
|
|
475
|
+
return true;
|
|
505
476
|
const dir = durableChunkDir(durableDir, chunkHash);
|
|
506
477
|
if (!createdDurableDirs.has(dir)) {
|
|
507
478
|
mkdirSync(dir, { recursive: true });
|
|
508
479
|
createdDurableDirs.add(dir);
|
|
509
480
|
}
|
|
510
|
-
|
|
481
|
+
const dest = path.join(dir, `${chunkHash}-w${threadId}-${shardSeq}.v8`);
|
|
482
|
+
return writeV8CacheFileSync(dest, parsedFiles, shardFilePaths(parsedFiles));
|
|
511
483
|
};
|
|
512
484
|
/**
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
* coverage. The durable shard names already carry the chunk hash, so they never
|
|
518
|
-
* collide with the worker's run-scoped `w<tid>-<seq>` shards. Returns the number
|
|
519
|
-
* of shards restored (0 ⇒ no durable coverage for this chunk; caller treats it
|
|
520
|
-
* as a miss).
|
|
485
|
+
* Validate and snapshot one durable chunk into the run store. Every envelope
|
|
486
|
+
* must be runtime-compatible and integrity-valid, and together they must match
|
|
487
|
+
* the path coverage recorded when the durable index was published. Linking
|
|
488
|
+
* before returning pins the inodes against concurrent branch-cache rotation.
|
|
521
489
|
*/
|
|
522
|
-
export const
|
|
523
|
-
const
|
|
524
|
-
|
|
490
|
+
export const durableChunkHasShards = async (runStoragePath, chunkHash, expectedPaths) => {
|
|
491
|
+
const sourceDir = durableChunkDir(getDurableParsedFileDir(runStoragePath), chunkHash);
|
|
492
|
+
const shards = await listV8Shards(sourceDir);
|
|
493
|
+
if (shards.length === 0 || expectedPaths.size === 0)
|
|
494
|
+
return false;
|
|
495
|
+
const runDir = getParsedFileStoreDir(runStoragePath);
|
|
525
496
|
try {
|
|
526
|
-
|
|
497
|
+
await fs.mkdir(runDir, { recursive: true });
|
|
527
498
|
}
|
|
528
499
|
catch {
|
|
529
|
-
return
|
|
500
|
+
return false;
|
|
530
501
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
502
|
+
const restored = [];
|
|
503
|
+
const covered = new Set();
|
|
504
|
+
const rollback = async () => {
|
|
505
|
+
await Promise.all(restored.map((filePath) => fs.rm(filePath, { force: true }).catch(() => { })));
|
|
506
|
+
return false;
|
|
507
|
+
};
|
|
508
|
+
for (const sourcePath of shards) {
|
|
509
|
+
const name = path.basename(sourcePath);
|
|
510
|
+
const destinationPath = path.join(runDir, name);
|
|
511
|
+
try {
|
|
512
|
+
await linkOrCopyFile(sourcePath, destinationPath);
|
|
513
|
+
restored.push(destinationPath);
|
|
514
|
+
}
|
|
515
|
+
catch {
|
|
516
|
+
return rollback();
|
|
517
|
+
}
|
|
518
|
+
const inspected = await inspectV8Cache(destinationPath);
|
|
519
|
+
if (!inspected)
|
|
520
|
+
return rollback();
|
|
521
|
+
for (const filePath of inspected.paths) {
|
|
522
|
+
if (!expectedPaths.has(filePath))
|
|
523
|
+
return rollback();
|
|
524
|
+
covered.add(filePath);
|
|
525
|
+
}
|
|
537
526
|
}
|
|
538
|
-
|
|
527
|
+
if (covered.size !== expectedPaths.size)
|
|
528
|
+
return rollback();
|
|
529
|
+
return true;
|
|
539
530
|
};
|
|
540
|
-
/**
|
|
541
|
-
* Read the durable index and return the set of chunk hashes it vouches for,
|
|
542
|
-
* gated on `expectedVersion` (`PARSE_CACHE_VERSION`). A version mismatch or a
|
|
543
|
-
* missing/corrupt index returns the empty set — the caller then treats every
|
|
544
|
-
* chunk as a durable miss and re-dispatches workers (NEVER the main-thread
|
|
545
|
-
* `extractParsedFile` fallback), which rewrites the durable store under the new
|
|
546
|
-
* version. Mirrors `loadParseCache`'s version-invalidation contract.
|
|
547
|
-
*/
|
|
548
531
|
export const loadDurableParsedFileIndex = async (durableDir, expectedVersion) => {
|
|
549
532
|
try {
|
|
550
533
|
const raw = await fs.readFile(path.join(durableDir, DURABLE_INDEX_FILENAME), 'utf-8');
|
|
551
534
|
const idx = JSON.parse(raw);
|
|
552
|
-
if (idx
|
|
553
|
-
return new
|
|
554
|
-
|
|
535
|
+
if (!isRecord(idx) || idx.version !== expectedVersion || !isRecord(idx.entries)) {
|
|
536
|
+
return new Map();
|
|
537
|
+
}
|
|
538
|
+
const entries = new Map();
|
|
539
|
+
for (const [key, paths] of Object.entries(idx.entries)) {
|
|
540
|
+
if (!Array.isArray(paths) ||
|
|
541
|
+
paths.length === 0 ||
|
|
542
|
+
paths.some((filePath) => typeof filePath !== 'string')) {
|
|
543
|
+
return new Map();
|
|
544
|
+
}
|
|
545
|
+
entries.set(key, new Set(paths));
|
|
546
|
+
}
|
|
547
|
+
return entries;
|
|
555
548
|
}
|
|
556
549
|
catch {
|
|
557
|
-
return new
|
|
550
|
+
return new Map();
|
|
558
551
|
}
|
|
559
552
|
};
|
|
560
553
|
/**
|
|
@@ -562,9 +555,9 @@ export const loadDurableParsedFileIndex = async (durableDir, expectedVersion) =>
|
|
|
562
555
|
* be the parse cache's surviving on-disk keys (so the two stores stay coherent:
|
|
563
556
|
* a chunk is "cached" iff BOTH its parse-cache shard and its durable shards
|
|
564
557
|
* exist; a quarantined chunk — no parse-cache shard — drops its durable subdir
|
|
565
|
-
* here and re-dispatches next run). Only
|
|
566
|
-
*
|
|
567
|
-
*
|
|
558
|
+
* here and re-dispatches next run). Only chunks whose envelopes all validate
|
|
559
|
+
* are indexed, together with their exact persisted path coverage (never vouch
|
|
560
|
+
* for a missing/corrupt shard). The index write is tmp+rename atomic.
|
|
568
561
|
*/
|
|
569
562
|
export const pruneAndSaveDurableParsedFileStore = async (durableDir, version, keepKeys) => {
|
|
570
563
|
let entries;
|
|
@@ -574,17 +567,30 @@ export const pruneAndSaveDurableParsedFileStore = async (durableDir, version, ke
|
|
|
574
567
|
catch {
|
|
575
568
|
return; // nothing written this run
|
|
576
569
|
}
|
|
577
|
-
const survivors =
|
|
570
|
+
const survivors = {};
|
|
578
571
|
for (const name of entries) {
|
|
579
572
|
if (name === DURABLE_INDEX_FILENAME)
|
|
580
573
|
continue;
|
|
581
574
|
const full = path.join(durableDir, name);
|
|
582
575
|
if (keepKeys.has(name)) {
|
|
583
576
|
try {
|
|
584
|
-
const shards =
|
|
577
|
+
const shards = await listV8Shards(full);
|
|
585
578
|
if (shards.length > 0) {
|
|
586
|
-
|
|
587
|
-
|
|
579
|
+
const covered = new Set();
|
|
580
|
+
let valid = true;
|
|
581
|
+
for (const shard of shards) {
|
|
582
|
+
const inspected = await inspectV8Cache(shard);
|
|
583
|
+
if (!inspected) {
|
|
584
|
+
valid = false;
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
for (const filePath of inspected.paths)
|
|
588
|
+
covered.add(filePath);
|
|
589
|
+
}
|
|
590
|
+
if (valid && covered.size > 0) {
|
|
591
|
+
survivors[name] = [...covered].sort();
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
588
594
|
}
|
|
589
595
|
}
|
|
590
596
|
catch {
|
|
@@ -593,9 +599,79 @@ export const pruneAndSaveDurableParsedFileStore = async (durableDir, version, ke
|
|
|
593
599
|
}
|
|
594
600
|
await fs.rm(full, { recursive: true, force: true });
|
|
595
601
|
}
|
|
596
|
-
const idx = { version,
|
|
602
|
+
const idx = { version, entries: survivors };
|
|
597
603
|
const tmp = path.join(durableDir, `${DURABLE_INDEX_FILENAME}.tmp`);
|
|
598
604
|
await fs.mkdir(durableDir, { recursive: true });
|
|
599
605
|
await fs.writeFile(tmp, JSON.stringify(idx), 'utf-8');
|
|
600
606
|
await fs.rename(tmp, path.join(durableDir, DURABLE_INDEX_FILENAME));
|
|
601
607
|
};
|
|
608
|
+
/**
|
|
609
|
+
* Overlay this run's staged durable ParsedFile chunks onto the live store,
|
|
610
|
+
* then prune the live tree to `keepKeys`. Live chunks this run did not rewrite
|
|
611
|
+
* (other branches, unused hashes) stay until prune. No-op overlay when the
|
|
612
|
+
* staged dir is missing.
|
|
613
|
+
*/
|
|
614
|
+
export const mergeStagedDurableParsedFileStore = async (liveStoragePath, stagedStoragePath, version, keepKeys) => {
|
|
615
|
+
const liveDir = getDurableParsedFileDir(liveStoragePath);
|
|
616
|
+
if (stagedStoragePath === liveStoragePath) {
|
|
617
|
+
await pruneAndSaveDurableParsedFileStore(liveDir, version, keepKeys);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
const stagedDir = getDurableParsedFileDir(stagedStoragePath);
|
|
621
|
+
await fs.mkdir(liveDir, { recursive: true });
|
|
622
|
+
let stagedEntries = [];
|
|
623
|
+
try {
|
|
624
|
+
stagedEntries = await fs.readdir(stagedDir);
|
|
625
|
+
}
|
|
626
|
+
catch {
|
|
627
|
+
await pruneAndSaveDurableParsedFileStore(liveDir, version, keepKeys);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
for (const name of stagedEntries) {
|
|
631
|
+
if (name === DURABLE_INDEX_FILENAME)
|
|
632
|
+
continue;
|
|
633
|
+
const from = path.join(stagedDir, name);
|
|
634
|
+
const to = path.join(liveDir, name);
|
|
635
|
+
await replaceDurableChunkDir(from, to);
|
|
636
|
+
}
|
|
637
|
+
await pruneAndSaveDurableParsedFileStore(liveDir, version, keepKeys);
|
|
638
|
+
};
|
|
639
|
+
/** Move `from` onto `to` without deleting `to` until the new tree is in place. */
|
|
640
|
+
const replaceDurableChunkDir = async (from, to) => {
|
|
641
|
+
try {
|
|
642
|
+
await fs.rename(from, to);
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
catch {
|
|
646
|
+
/* dest exists, or the rename is cross-device */
|
|
647
|
+
}
|
|
648
|
+
const backup = `${to}.replacing`;
|
|
649
|
+
await fs.rm(backup, { recursive: true, force: true });
|
|
650
|
+
let backedUp = false;
|
|
651
|
+
try {
|
|
652
|
+
await fs.rename(to, backup);
|
|
653
|
+
backedUp = true;
|
|
654
|
+
}
|
|
655
|
+
catch {
|
|
656
|
+
/* dest was missing */
|
|
657
|
+
}
|
|
658
|
+
try {
|
|
659
|
+
try {
|
|
660
|
+
await fs.rename(from, to);
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
await fs.cp(from, to, { recursive: true });
|
|
664
|
+
await fs.rm(from, { recursive: true, force: true });
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
catch (err) {
|
|
668
|
+
if (backedUp) {
|
|
669
|
+
await fs.rm(to, { recursive: true, force: true }).catch(() => { });
|
|
670
|
+
await fs.rename(backup, to).catch(() => { });
|
|
671
|
+
}
|
|
672
|
+
throw err;
|
|
673
|
+
}
|
|
674
|
+
if (backedUp) {
|
|
675
|
+
await fs.rm(backup, { recursive: true, force: true });
|
|
676
|
+
}
|
|
677
|
+
};
|
|
@@ -19,6 +19,7 @@ export { branchSlug, resolveBranchPlacement };
|
|
|
19
19
|
export type { BranchSummary };
|
|
20
20
|
export { getStoragePath, INDEX_METADATA_FILE, isMissingFilesystemError, loadMeta };
|
|
21
21
|
export type { AnalyzerRunnerIdentity, RepoMeta };
|
|
22
|
+
export { getGlobalDir } from './global-dir.js';
|
|
22
23
|
/**
|
|
23
24
|
* Normalise a repo path for registry comparison across platforms
|
|
24
25
|
* (#664 review feedback from @evander-wang).
|
|
@@ -206,10 +207,6 @@ export declare function isReadOnlyFilesystemError(err: unknown): boolean;
|
|
|
206
207
|
* Keep .gitnexus/ ignored. It contains local index state and caches.
|
|
207
208
|
*/
|
|
208
209
|
export declare const ensureGitNexusIgnored: (repoPath: string) => Promise<void>;
|
|
209
|
-
/**
|
|
210
|
-
* Get the path to the global GitNexus directory
|
|
211
|
-
*/
|
|
212
|
-
export declare const getGlobalDir: () => string;
|
|
213
210
|
/**
|
|
214
211
|
* Get the path to the global registry file
|
|
215
212
|
*/
|
|
@@ -475,6 +472,15 @@ export declare const assertSafeStoragePath: (entry: RegistryEntry) => void;
|
|
|
475
472
|
* `GITNEXUS_HOME`.
|
|
476
473
|
*/
|
|
477
474
|
export declare const resolveRegistryEntry: (entries: RegistryEntry[], target: string) => RegistryEntry;
|
|
475
|
+
/**
|
|
476
|
+
* Name-only registry match (the name tier of {@link resolveRegistryEntry},
|
|
477
|
+
* without path matching). Used by `group.yaml` member *values*, which are
|
|
478
|
+
* registry aliases, not filesystem paths.
|
|
479
|
+
*
|
|
480
|
+
* Zero matches → `undefined` (caller treats as missing). One match → that
|
|
481
|
+
* entry. Two or more → {@link RegistryAmbiguousTargetError}.
|
|
482
|
+
*/
|
|
483
|
+
export declare const findRegistryEntryByName: (entries: RegistryEntry[], name: string) => RegistryEntry | undefined;
|
|
478
484
|
/**
|
|
479
485
|
* List all registered repos from the global registry.
|
|
480
486
|
*
|