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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type AnalyzeOptions as CoreAnalyzeOptions } from '../core/run-analyze.js';
|
|
2
|
+
import type { AnalyzerRunnerIdentity } from '../storage/repo-manager.js';
|
|
3
|
+
import type { AnalyzeOptions } from './analyze-options.js';
|
|
4
|
+
import { type WatchRefreshError } from './watch-queue.js';
|
|
5
|
+
export type WatchCliOptions = AnalyzeOptions;
|
|
6
|
+
export declare function isRelevantWatchPath(filePath: string): boolean;
|
|
7
|
+
export interface WatchEnvironmentBaseline {
|
|
8
|
+
readonly maxFileSize: string | undefined;
|
|
9
|
+
readonly workerTimeout: string | undefined;
|
|
10
|
+
readonly verbose: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveWatchOptions(repoPath: string, cli: WatchCliOptions, baseline: WatchEnvironmentBaseline, reportIgnoredConfig?: (names: readonly string[]) => void): Promise<CoreAnalyzeOptions>;
|
|
13
|
+
export interface WatchFileLoop {
|
|
14
|
+
readonly waitForIdle: () => Promise<void>;
|
|
15
|
+
readonly close: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function shouldStopAfterWatchRefreshFailure(error: unknown, paths: readonly string[]): boolean;
|
|
18
|
+
/** Start the real filesystem watcher with bounded, serialized refreshes. */
|
|
19
|
+
export declare function startWatchFileLoop(repoPath: string, debounceMs: number, refresh: (paths: readonly string[]) => Promise<void>, onError: WatchRefreshError, onWatcherError?: (error: unknown) => void): Promise<WatchFileLoop>;
|
|
20
|
+
export declare function watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap: AnalyzerRunnerIdentity, inputPath?: string, cliOptions?: WatchCliOptions): Promise<void>;
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
/** Local incremental watch (`gitnexus analyze --watch`). Remote auto-sync lives in `auto-sync.ts`. */
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import { watch } from 'chokidar';
|
|
5
|
+
import { createWatchIgnorePredicate } from '../config/ignore-service.js';
|
|
6
|
+
import { analyzeFailureMayHaveMutatedLiveIndex, runFullAnalysis, } from '../core/run-analyze.js';
|
|
7
|
+
import { getGitRoot, hasGitDir } from '../storage/git.js';
|
|
8
|
+
import { GITNEXUS_DIR } from '../storage/repo-meta.js';
|
|
9
|
+
import { loadAnalyzeConfigStrict, mergeAnalyzeOptions, validateBranchName, } from './analyze-config.js';
|
|
10
|
+
import { ensureHeap } from './analyze.js';
|
|
11
|
+
import { cliError, cliInfo, cliWarn } from './cli-message.js';
|
|
12
|
+
import { WATCH_FULL_REFRESH_PATH, WatchRefreshQueue, } from './watch-queue.js';
|
|
13
|
+
const DEFAULT_DEBOUNCE_MS = 300;
|
|
14
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
15
|
+
const MAX_FILE_SIZE_KB = 32 * 1024;
|
|
16
|
+
const TRANSIENT_WATCH_ERROR_CODES = new Set(['EACCES', 'ENOENT', 'ENOTDIR', 'EPERM']);
|
|
17
|
+
function posixWatchPath(filePath) {
|
|
18
|
+
return filePath.replace(/\\/g, '/').replace(/^\.\/+/, '');
|
|
19
|
+
}
|
|
20
|
+
export function isRelevantWatchPath(filePath) {
|
|
21
|
+
const normalized = posixWatchPath(filePath);
|
|
22
|
+
return (normalized.length > 0 &&
|
|
23
|
+
normalized !== '.' &&
|
|
24
|
+
!normalized.startsWith('../') &&
|
|
25
|
+
!path.posix.isAbsolute(normalized) &&
|
|
26
|
+
!path.win32.isAbsolute(filePath));
|
|
27
|
+
}
|
|
28
|
+
function isIgnoreControlPath(filePath) {
|
|
29
|
+
const normalized = posixWatchPath(filePath);
|
|
30
|
+
return normalized === '.gitignore' || normalized === '.gitnexusignore';
|
|
31
|
+
}
|
|
32
|
+
function isConfigControlPath(filePath) {
|
|
33
|
+
return posixWatchPath(filePath) === '.gitnexusrc';
|
|
34
|
+
}
|
|
35
|
+
function isAnalyzerOwnedWatchPath(filePath) {
|
|
36
|
+
const normalized = posixWatchPath(filePath).replace(/\/+$/, '');
|
|
37
|
+
return normalized === GITNEXUS_DIR || normalized.startsWith(`${GITNEXUS_DIR}/`);
|
|
38
|
+
}
|
|
39
|
+
function repoRelativeWatchPath(repoPath, candidate) {
|
|
40
|
+
const relative = path.relative(repoPath, candidate).replace(/\\/g, '/');
|
|
41
|
+
if (!relative || relative.startsWith('../') || path.isAbsolute(relative))
|
|
42
|
+
return null;
|
|
43
|
+
return relative;
|
|
44
|
+
}
|
|
45
|
+
function setEnvironment(name, value) {
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
delete process.env[name];
|
|
48
|
+
else
|
|
49
|
+
process.env[name] = value;
|
|
50
|
+
}
|
|
51
|
+
function positiveInteger(value, flag, maximum) {
|
|
52
|
+
if (value === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
const parsed = Number(value);
|
|
55
|
+
if (!Number.isInteger(parsed) || parsed < 1)
|
|
56
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
57
|
+
if (maximum !== undefined && parsed > maximum) {
|
|
58
|
+
throw new Error(`${flag} must not exceed ${maximum}`);
|
|
59
|
+
}
|
|
60
|
+
return parsed;
|
|
61
|
+
}
|
|
62
|
+
export async function resolveWatchOptions(repoPath, cli, baseline, reportIgnoredConfig = () => { }) {
|
|
63
|
+
const config = (await loadAnalyzeConfigStrict(repoPath)) ?? {};
|
|
64
|
+
const merged = mergeAnalyzeOptions(cli, config);
|
|
65
|
+
const unsupported = [
|
|
66
|
+
['--force', cli.force],
|
|
67
|
+
['--no-parse-cache', cli.parseCache === false],
|
|
68
|
+
['--repair-fts', cli.repairFts],
|
|
69
|
+
['--embeddings', cli.embeddings],
|
|
70
|
+
['--drop-embeddings', cli.dropEmbeddings],
|
|
71
|
+
['--skills', cli.skills],
|
|
72
|
+
['--default-branch', cli.defaultBranch],
|
|
73
|
+
['--skip-agents-md', cli.skipAgentsMd],
|
|
74
|
+
['--skip-skills', cli.skipSkills],
|
|
75
|
+
['--no-stats', cli.stats === false],
|
|
76
|
+
['--self-commit', cli.selfCommit],
|
|
77
|
+
['--index-only', cli.indexOnly],
|
|
78
|
+
['--skip-git', cli.skipGit],
|
|
79
|
+
['--spring-actuator', cli.springActuator],
|
|
80
|
+
// Rejected under --watch for the same reason as --spring-actuator: the
|
|
81
|
+
// watcher reacts to source changes, and nothing watches an out-of-band
|
|
82
|
+
// document directory. Honouring the flag here would read the documents once
|
|
83
|
+
// and then quietly serve a stale answer for the rest of the session.
|
|
84
|
+
['--asyncapi-spec', cli.asyncapiSpec],
|
|
85
|
+
['walCheckpointThreshold', cli.walCheckpointThreshold],
|
|
86
|
+
['embeddingThreads', cli.embeddingThreads],
|
|
87
|
+
['embeddingBatchSize', cli.embeddingBatchSize],
|
|
88
|
+
['embeddingSubBatchSize', cli.embeddingSubBatchSize],
|
|
89
|
+
['embeddingDevice', cli.embeddingDevice],
|
|
90
|
+
['embeddingBaseUrl', cli.embeddingBaseUrl],
|
|
91
|
+
['embeddingModel', cli.embeddingModel],
|
|
92
|
+
['--embedding-auth-token', cli.embeddingAuthToken],
|
|
93
|
+
['--embedding-dims', cli.embeddingDims],
|
|
94
|
+
].filter(([, value]) => value !== undefined && value !== false);
|
|
95
|
+
if (unsupported.length > 0) {
|
|
96
|
+
throw new Error(`analyze --watch does not support ${unsupported.map(([name]) => name).join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
reportIgnoredConfig([
|
|
99
|
+
['embeddings', config.embeddings],
|
|
100
|
+
['dropEmbeddings', config.dropEmbeddings],
|
|
101
|
+
['defaultBranch', config.defaultBranch],
|
|
102
|
+
['skipAgentsMd', config.skipAgentsMd !== undefined],
|
|
103
|
+
['skipSkills', config.skipSkills !== undefined],
|
|
104
|
+
['stats', config.stats !== undefined],
|
|
105
|
+
['springActuator', config.springActuator],
|
|
106
|
+
['walCheckpointThreshold', config.walCheckpointThreshold],
|
|
107
|
+
['embeddingThreads', config.embeddingThreads],
|
|
108
|
+
['embeddingBatchSize', config.embeddingBatchSize],
|
|
109
|
+
['embeddingSubBatchSize', config.embeddingSubBatchSize],
|
|
110
|
+
['embeddingDevice', config.embeddingDevice],
|
|
111
|
+
['embeddingBaseUrl', config.embeddingBaseUrl],
|
|
112
|
+
['embeddingModel', config.embeddingModel],
|
|
113
|
+
]
|
|
114
|
+
.filter(([, value]) => value !== undefined && value !== false)
|
|
115
|
+
.map(([name]) => String(name)));
|
|
116
|
+
const branch = merged.branch === undefined ? undefined : validateBranchName(merged.branch, '--branch');
|
|
117
|
+
const workerPoolSize = positiveInteger(merged.workers, '--workers');
|
|
118
|
+
const workerTimeoutSeconds = positiveInteger(merged.workerTimeout, 'workerTimeout');
|
|
119
|
+
const maxFileSize = positiveInteger(merged.maxFileSize, 'maxFileSize', MAX_FILE_SIZE_KB);
|
|
120
|
+
setEnvironment('GITNEXUS_MAX_FILE_SIZE', maxFileSize === undefined ? baseline.maxFileSize : String(maxFileSize));
|
|
121
|
+
if (workerTimeoutSeconds !== undefined) {
|
|
122
|
+
process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS = String(workerTimeoutSeconds * 1000);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
setEnvironment('GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS', baseline.workerTimeout);
|
|
126
|
+
}
|
|
127
|
+
setEnvironment('GITNEXUS_VERBOSE', merged.verbose ? '1' : baseline.verbose);
|
|
128
|
+
return {
|
|
129
|
+
pdg: merged.pdg,
|
|
130
|
+
branch,
|
|
131
|
+
registryName: merged.name,
|
|
132
|
+
allowDuplicateName: merged.allowDuplicateName,
|
|
133
|
+
workerPoolSize,
|
|
134
|
+
fetchWrappers: merged.fetchWrappers,
|
|
135
|
+
skipAgentsMd: true,
|
|
136
|
+
skipSkills: true,
|
|
137
|
+
noStats: true,
|
|
138
|
+
atomicIncremental: process.platform !== 'win32',
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function refreshSummary(result, observedPaths, durationMs, lastSuccessfulRefreshAt) {
|
|
142
|
+
const measured = result.incrementalStats;
|
|
143
|
+
const changed = measured?.changedFiles ?? (result.alreadyUpToDate ? 0 : observedPaths.length);
|
|
144
|
+
const reparsed = measured?.reparsedFiles ??
|
|
145
|
+
(typeof result.pipelineResult?.reparsedFileCount === 'number'
|
|
146
|
+
? result.pipelineResult.reparsedFileCount
|
|
147
|
+
: 0);
|
|
148
|
+
const dependents = measured?.affectedDependents ?? 0;
|
|
149
|
+
const mode = measured?.writeMode ?? (result.alreadyUpToDate ? 'no-op' : 'full');
|
|
150
|
+
return (`Refresh complete: ${changed} changed, ${reparsed} re-parsed, ` +
|
|
151
|
+
`${dependents} affected dependent(s), ${durationMs}ms, ${mode}; ` +
|
|
152
|
+
`last success ${lastSuccessfulRefreshAt}`);
|
|
153
|
+
}
|
|
154
|
+
async function waitUntilReady(watcher) {
|
|
155
|
+
await new Promise((resolve, reject) => {
|
|
156
|
+
const ready = () => {
|
|
157
|
+
watcher.off('error', failed);
|
|
158
|
+
resolve();
|
|
159
|
+
};
|
|
160
|
+
const failed = (error) => {
|
|
161
|
+
watcher.off('ready', ready);
|
|
162
|
+
reject(error);
|
|
163
|
+
};
|
|
164
|
+
watcher.once('ready', ready);
|
|
165
|
+
watcher.once('error', failed);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
class WatchControlReloadError extends Error {
|
|
169
|
+
constructor(cause) {
|
|
170
|
+
super(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
171
|
+
this.name = 'WatchControlReloadError';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export function shouldStopAfterWatchRefreshFailure(error, paths) {
|
|
175
|
+
return (paths.length > 0 &&
|
|
176
|
+
!(error instanceof WatchControlReloadError) &&
|
|
177
|
+
analyzeFailureMayHaveMutatedLiveIndex(error));
|
|
178
|
+
}
|
|
179
|
+
/** Start the real filesystem watcher with bounded, serialized refreshes. */
|
|
180
|
+
export async function startWatchFileLoop(repoPath, debounceMs, refresh, onError, onWatcherError = (error) => onError(error, [])) {
|
|
181
|
+
let ignorePath = await createWatchIgnorePredicate(repoPath);
|
|
182
|
+
let ignoreControlValid = true;
|
|
183
|
+
let rearmPending = false;
|
|
184
|
+
let closed = false;
|
|
185
|
+
const queue = new WatchRefreshQueue(async (paths) => {
|
|
186
|
+
if (paths.some(isIgnoreControlPath) || !ignoreControlValid) {
|
|
187
|
+
const retryingInvalidControls = !ignoreControlValid;
|
|
188
|
+
try {
|
|
189
|
+
ignorePath = await createWatchIgnorePredicate(repoPath);
|
|
190
|
+
ignoreControlValid = true;
|
|
191
|
+
rearmPending = true;
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
ignoreControlValid = false;
|
|
195
|
+
throw new WatchControlReloadError(retryingInvalidControls
|
|
196
|
+
? new Error('Ignore controls remain invalid; fix them before indexing more changes.', {
|
|
197
|
+
cause: error,
|
|
198
|
+
})
|
|
199
|
+
: error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Re-arm before refreshing, never after: the refresh reads the whole
|
|
203
|
+
// repository, so a write that lands while the replacement watcher is
|
|
204
|
+
// arming is still picked up by this refresh, and a write that lands
|
|
205
|
+
// afterwards is reported by the armed watcher.
|
|
206
|
+
if (rearmPending)
|
|
207
|
+
await rearmWatcher();
|
|
208
|
+
await refresh(paths);
|
|
209
|
+
}, onError, debounceMs, {
|
|
210
|
+
maxWaitMs: Math.max(2_000, debounceMs * 10),
|
|
211
|
+
maxPendingPaths: 1_000,
|
|
212
|
+
holdEventsUntilInitialRefresh: true,
|
|
213
|
+
isPriorityPath: (filePath) => isIgnoreControlPath(filePath) || isConfigControlPath(filePath),
|
|
214
|
+
});
|
|
215
|
+
const createWatcher = () => {
|
|
216
|
+
const created = watch(repoPath, {
|
|
217
|
+
ignoreInitial: true,
|
|
218
|
+
atomic: true,
|
|
219
|
+
followSymlinks: false,
|
|
220
|
+
awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 20 },
|
|
221
|
+
ignored: (candidate, stats) => {
|
|
222
|
+
const relative = repoRelativeWatchPath(repoPath, candidate);
|
|
223
|
+
if (relative !== null && isAnalyzerOwnedWatchPath(relative))
|
|
224
|
+
return true;
|
|
225
|
+
if (relative !== null && (isIgnoreControlPath(relative) || isConfigControlPath(relative))) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
return ignorePath(candidate, stats?.isDirectory() ?? false);
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
// Events from an instance being retired are kept: they overlap with the
|
|
232
|
+
// replacement's coverage and the queue coalesces the duplicates.
|
|
233
|
+
created.on('all', (event, changedPath) => {
|
|
234
|
+
if (event !== 'add' && event !== 'change' && event !== 'unlink')
|
|
235
|
+
return;
|
|
236
|
+
const relative = repoRelativeWatchPath(repoPath, changedPath);
|
|
237
|
+
if (relative && isRelevantWatchPath(relative) && !isAnalyzerOwnedWatchPath(relative)) {
|
|
238
|
+
queue.enqueue(relative);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
created.on('error', (error) => {
|
|
242
|
+
// Replacement failures before the swap are reported through `waitUntilReady`.
|
|
243
|
+
if (created !== watcher)
|
|
244
|
+
return;
|
|
245
|
+
// Chokidar can surface a transient EPERM on Windows while an ignored
|
|
246
|
+
// analyzer-owned path is replaced. Re-arm the watcher and force one
|
|
247
|
+
// bounded catch-up refresh so a missed event cannot leave the graph
|
|
248
|
+
// stale. Other watcher errors may mean coverage was lost and stay fatal.
|
|
249
|
+
if (TRANSIENT_WATCH_ERROR_CODES.has(error.code ?? '')) {
|
|
250
|
+
rearmPending = true;
|
|
251
|
+
queue.enqueue(WATCH_FULL_REFRESH_PATH);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
onWatcherError(error);
|
|
255
|
+
});
|
|
256
|
+
return created;
|
|
257
|
+
};
|
|
258
|
+
let watcher = createWatcher();
|
|
259
|
+
// Chokidar emits `ready` once per instance and `add()` returns before the
|
|
260
|
+
// rescan it starts has finished, with no signal for that completion. A file
|
|
261
|
+
// an ignore-rule reload has just unignored is therefore still unregistered
|
|
262
|
+
// when `add()` returns, and because `ignoreInitial` suppresses the `add` the
|
|
263
|
+
// rescan would emit, an immediate rewrite of that file is dropped for good
|
|
264
|
+
// (reproduced on chokidar 4 and 5). So re-arm by arming a replacement
|
|
265
|
+
// watcher and awaiting its `ready` instead. The outgoing instance keeps
|
|
266
|
+
// reporting until the replacement is armed, so the swap has no blind window,
|
|
267
|
+
// and a replacement that fails to arm leaves the working instance in place.
|
|
268
|
+
const rearmWatcher = async () => {
|
|
269
|
+
rearmPending = false;
|
|
270
|
+
if (closed)
|
|
271
|
+
return;
|
|
272
|
+
const replacement = createWatcher();
|
|
273
|
+
try {
|
|
274
|
+
await waitUntilReady(replacement);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
rearmPending = true;
|
|
278
|
+
try {
|
|
279
|
+
await replacement.close();
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// The instance never became live; the arm error is the one to report.
|
|
283
|
+
}
|
|
284
|
+
throw new WatchControlReloadError(new Error('Unable to re-arm the filesystem watcher', { cause: error }));
|
|
285
|
+
}
|
|
286
|
+
const retired = watcher;
|
|
287
|
+
watcher = replacement;
|
|
288
|
+
await retired.close();
|
|
289
|
+
// `close()` can land between arming the replacement and the swap above.
|
|
290
|
+
if (closed)
|
|
291
|
+
await replacement.close();
|
|
292
|
+
};
|
|
293
|
+
try {
|
|
294
|
+
await waitUntilReady(watcher);
|
|
295
|
+
await queue.runInitial();
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
closed = true;
|
|
299
|
+
await watcher.close();
|
|
300
|
+
await queue.close();
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
waitForIdle: () => queue.waitForIdle(),
|
|
305
|
+
close: async () => {
|
|
306
|
+
closed = true;
|
|
307
|
+
await watcher.close();
|
|
308
|
+
await queue.close();
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
export async function watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, cliOptions = {}) {
|
|
313
|
+
if (await ensureHeap({ cleanForwardedTermination: true }))
|
|
314
|
+
return;
|
|
315
|
+
const requestedRepoPath = inputPath ? path.resolve(inputPath) : getGitRoot(process.cwd());
|
|
316
|
+
if (requestedRepoPath === null || !hasGitDir(requestedRepoPath)) {
|
|
317
|
+
cliError(' gitnexus analyze --watch requires a Git repository.');
|
|
318
|
+
process.exitCode = 1;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const repoPath = await fs.realpath(requestedRepoPath);
|
|
322
|
+
const baselineEnvironment = {
|
|
323
|
+
maxFileSize: process.env.GITNEXUS_MAX_FILE_SIZE,
|
|
324
|
+
workerTimeout: process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS,
|
|
325
|
+
verbose: process.env.GITNEXUS_VERBOSE,
|
|
326
|
+
};
|
|
327
|
+
try {
|
|
328
|
+
let ignoredConfigSignature;
|
|
329
|
+
const reportIgnoredConfig = (names) => {
|
|
330
|
+
const signature = [...names].sort().join(',');
|
|
331
|
+
if (signature === ignoredConfigSignature)
|
|
332
|
+
return;
|
|
333
|
+
ignoredConfigSignature = signature;
|
|
334
|
+
if (names.length > 0) {
|
|
335
|
+
cliWarn(`Watch mode ignores unsupported .gitnexusrc settings: ${names.join(', ')}.`);
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
let debounceMs;
|
|
339
|
+
let analyzeOptions;
|
|
340
|
+
try {
|
|
341
|
+
debounceMs =
|
|
342
|
+
positiveInteger(cliOptions.debounce ?? String(DEFAULT_DEBOUNCE_MS), '--debounce', MAX_TIMER_DELAY_MS) ?? DEFAULT_DEBOUNCE_MS;
|
|
343
|
+
analyzeOptions = await resolveWatchOptions(repoPath, cliOptions, baselineEnvironment, reportIgnoredConfig);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
cliError(` ${error instanceof Error ? error.message : String(error)}`);
|
|
347
|
+
process.exitCode = 1;
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
let stopWatching;
|
|
351
|
+
const stopped = new Promise((resolve) => {
|
|
352
|
+
stopWatching = resolve;
|
|
353
|
+
});
|
|
354
|
+
const stop = () => stopWatching();
|
|
355
|
+
process.once('SIGINT', stop);
|
|
356
|
+
process.once('SIGTERM', stop);
|
|
357
|
+
try {
|
|
358
|
+
let loop;
|
|
359
|
+
let fatalRefreshError;
|
|
360
|
+
let configControlValid = true;
|
|
361
|
+
let lastSuccessfulRefreshAt;
|
|
362
|
+
try {
|
|
363
|
+
loop = await startWatchFileLoop(repoPath, debounceMs, async (paths) => {
|
|
364
|
+
if (paths.some(isConfigControlPath) || !configControlValid) {
|
|
365
|
+
const retryingInvalidConfig = !configControlValid;
|
|
366
|
+
try {
|
|
367
|
+
analyzeOptions = await resolveWatchOptions(repoPath, cliOptions, baselineEnvironment, reportIgnoredConfig);
|
|
368
|
+
configControlValid = true;
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
configControlValid = false;
|
|
372
|
+
throw new WatchControlReloadError(retryingInvalidConfig
|
|
373
|
+
? new Error('Configuration remains invalid; fix it before indexing more changes.', {
|
|
374
|
+
cause: error,
|
|
375
|
+
})
|
|
376
|
+
: error);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const startedAt = Date.now();
|
|
380
|
+
const result = await runFullAnalysis(repoPath, analyzeOptions, {
|
|
381
|
+
onProgress: () => { },
|
|
382
|
+
onLog: process.env.GITNEXUS_VERBOSE === '1'
|
|
383
|
+
? (message) => cliInfo(` ${message}`)
|
|
384
|
+
: undefined,
|
|
385
|
+
}, runnerIdentityAtBootstrap);
|
|
386
|
+
lastSuccessfulRefreshAt = new Date().toISOString();
|
|
387
|
+
if (paths.length === 0) {
|
|
388
|
+
cliInfo(result.alreadyUpToDate
|
|
389
|
+
? `Watching ${repoPath}; index is up to date.`
|
|
390
|
+
: `Watching ${repoPath}; initial index ready in ${Date.now() - startedAt}ms.`);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
cliInfo(refreshSummary(result, paths, Date.now() - startedAt, lastSuccessfulRefreshAt));
|
|
394
|
+
}
|
|
395
|
+
}, (error, paths) => {
|
|
396
|
+
const detail = paths.length > 0 ? ` (${paths.length} queued path(s))` : '';
|
|
397
|
+
if (shouldStopAfterWatchRefreshFailure(error, paths)) {
|
|
398
|
+
fatalRefreshError = error;
|
|
399
|
+
cliError(`Refresh failed${detail}: ${error instanceof Error ? error.message : String(error)}. ` +
|
|
400
|
+
'Watch mode is stopping because the live index may have been updated in place.');
|
|
401
|
+
stopWatching();
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
const lastSuccess = lastSuccessfulRefreshAt ?? 'none yet';
|
|
405
|
+
cliWarn(`Refresh failed${detail}: ${error instanceof Error ? error.message : String(error)}. ` +
|
|
406
|
+
`Retry scheduled; last success ${lastSuccess}.`);
|
|
407
|
+
}, (error) => {
|
|
408
|
+
fatalRefreshError = error;
|
|
409
|
+
cliError(`Watcher failed: ${error instanceof Error ? error.message : String(error)}. ` +
|
|
410
|
+
'Watch mode is stopping.');
|
|
411
|
+
stopWatching();
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
cliError(` Unable to start watcher: ${error instanceof Error ? error.message : String(error)}`);
|
|
416
|
+
process.exitCode = 1;
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
await stopped;
|
|
420
|
+
await loop.close();
|
|
421
|
+
if (fatalRefreshError !== undefined)
|
|
422
|
+
process.exitCode = 1;
|
|
423
|
+
}
|
|
424
|
+
finally {
|
|
425
|
+
process.removeListener('SIGINT', stop);
|
|
426
|
+
process.removeListener('SIGTERM', stop);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
finally {
|
|
430
|
+
setEnvironment('GITNEXUS_MAX_FILE_SIZE', baselineEnvironment.maxFileSize);
|
|
431
|
+
setEnvironment('GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS', baselineEnvironment.workerTimeout);
|
|
432
|
+
setEnvironment('GITNEXUS_VERBOSE', baselineEnvironment.verbose);
|
|
433
|
+
}
|
|
434
|
+
}
|
package/dist/cli/analyze.js
CHANGED
|
@@ -524,6 +524,8 @@ const ANALYZE_CLI_ENV_KEYS = [
|
|
|
524
524
|
'GITNEXUS_EMBEDDING_SUB_BATCH_SIZE',
|
|
525
525
|
'GITNEXUS_EMBEDDING_DEVICE',
|
|
526
526
|
'GITNEXUS_ANALYZE_PROGRESS_ACTIVE',
|
|
527
|
+
'GITNEXUS_ANALYZER_IDENTITY_IN_PROCESS_GUARDS',
|
|
528
|
+
'GITNEXUS_RESOLVE_DEF_GRAPH_ID_MEMO',
|
|
527
529
|
'GITNEXUS_EMBEDDING_URL',
|
|
528
530
|
'GITNEXUS_EMBEDDING_MODEL',
|
|
529
531
|
'GITNEXUS_EMBEDDING_API_KEY',
|
|
@@ -600,14 +602,13 @@ export const analyzeCommand = async (inputPath, options, runnerIdentityAtBootstr
|
|
|
600
602
|
export const analyzeCommandWithRunnerIdentity = async (runnerIdentityAtBootstrap, inputPath, options) => analyzeCommand(inputPath, options, runnerIdentityAtBootstrap);
|
|
601
603
|
export async function analyzeOrWatchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options = {}) {
|
|
602
604
|
if (options.watch) {
|
|
603
|
-
const { watchCommandWithRunnerIdentity } = await import('./watch.js');
|
|
605
|
+
const { watchCommandWithRunnerIdentity } = await import('./analyze-watch.js');
|
|
604
606
|
await watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
|
|
605
607
|
return;
|
|
606
608
|
}
|
|
607
609
|
await analyzeCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
|
|
608
610
|
}
|
|
609
611
|
const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstrap) => {
|
|
610
|
-
console.log('\n GitNexus Analyzer\n');
|
|
611
612
|
// ── Resolve the target repo root ──────────────────────────────────
|
|
612
613
|
// Resolved FIRST because `.gitnexusrc` is read from the repo root (not the
|
|
613
614
|
// caller's cwd), and config can set defaults that the validation below
|
|
@@ -784,6 +785,16 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
784
785
|
!setPositiveEnv('--embedding-sub-batch-size', 'GITNEXUS_EMBEDDING_SUB_BATCH_SIZE', options.embeddingSubBatchSize)) {
|
|
785
786
|
return;
|
|
786
787
|
}
|
|
788
|
+
// An empty value resolves to the repository root, so `--asyncapi-spec ""`
|
|
789
|
+
// walks the whole tree — defeating the module's own rule that there is no
|
|
790
|
+
// glob-based auto-discovery, and spending the walk budget on `node_modules`.
|
|
791
|
+
// The HTTP entry point already rejects exactly this value; two doors onto one
|
|
792
|
+
// option must not hold different rules.
|
|
793
|
+
if (options.asyncapiSpec !== undefined && options.asyncapiSpec.trim() === '') {
|
|
794
|
+
cliError(' --asyncapi-spec must be a non-empty path.\n');
|
|
795
|
+
process.exitCode = 1;
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
787
798
|
if (options.embeddingDevice) {
|
|
788
799
|
const allowed = new Set(['auto', 'cpu', 'dml', 'cuda', 'wasm']);
|
|
789
800
|
if (!allowed.has(options.embeddingDevice)) {
|
|
@@ -928,9 +939,9 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
928
939
|
}
|
|
929
940
|
}
|
|
930
941
|
}
|
|
931
|
-
if (options.repairFts && options.force) {
|
|
932
|
-
cliError(' Cannot combine `--repair-fts` with
|
|
933
|
-
'Use `--repair-fts` for fast FTS-only repair
|
|
942
|
+
if (options.repairFts && (options.force || options.parseCache === false)) {
|
|
943
|
+
cliError(' Cannot combine `--repair-fts` with a full rebuild. ' +
|
|
944
|
+
'Use `--repair-fts` alone for fast FTS-only repair.\n');
|
|
934
945
|
process.exitCode = 1;
|
|
935
946
|
return;
|
|
936
947
|
}
|
|
@@ -1072,10 +1083,11 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1072
1083
|
const skipAgentsMd = skipAll || options.skipAgentsMd;
|
|
1073
1084
|
const skipSkills = skipAll || options.skipSkills;
|
|
1074
1085
|
const runOptions = {
|
|
1075
|
-
// Pipeline re-index — OR'd with --skills because skill generation
|
|
1076
|
-
//
|
|
1077
|
-
//
|
|
1078
|
-
force: options.force || options.skills,
|
|
1086
|
+
// Pipeline re-index — OR'd with --skills because skill generation needs
|
|
1087
|
+
// a fresh pipelineResult, and with --no-parse-cache because bypassing
|
|
1088
|
+
// parser output is meaningful only when the pipeline runs.
|
|
1089
|
+
force: options.force || options.skills || options.parseCache === false,
|
|
1090
|
+
useParseCache: options.parseCache !== false,
|
|
1079
1091
|
repairFts: options.repairFts,
|
|
1080
1092
|
embeddings: embeddingsEnabled,
|
|
1081
1093
|
embeddingsNodeLimit,
|
|
@@ -1112,6 +1124,8 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1112
1124
|
// Extra fetch-wrapper names from `.gitnexusrc` (#1589/#1852 residual);
|
|
1113
1125
|
// forwarded to the routes phase consumer scan.
|
|
1114
1126
|
fetchWrappers: options.fetchWrappers,
|
|
1127
|
+
springActuatorPath: options.springActuator,
|
|
1128
|
+
asyncApiSpecPath: options.asyncapiSpec,
|
|
1115
1129
|
// The CLI always process.exit()s after this returns (success path at the
|
|
1116
1130
|
// end of analyzeCommandImpl, error/interrupt paths via process.exit too),
|
|
1117
1131
|
// so the finalize close skips the native conn/db close — it can double-free
|
|
@@ -1173,6 +1187,9 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1173
1187
|
console.error = origError;
|
|
1174
1188
|
bar.stop();
|
|
1175
1189
|
console.log(' Already up to date\n');
|
|
1190
|
+
if (runOptions.registryName) {
|
|
1191
|
+
console.log(` Registry name: ${result.repoName}\n`);
|
|
1192
|
+
}
|
|
1176
1193
|
if (baseRefRefreshed.length > 0) {
|
|
1177
1194
|
console.log(` Updated base_ref to "${resolvedDefaultBranch}" in ${baseRefRefreshed.join(', ')}\n`);
|
|
1178
1195
|
}
|
|
@@ -1247,6 +1264,7 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1247
1264
|
// exercised on the `--skills` path by analyze-no-stats-bridge.test.ts.
|
|
1248
1265
|
noStats: options.stats === false,
|
|
1249
1266
|
hasPdg: options.pdg === true,
|
|
1267
|
+
hasSpringActuator: options.springActuator !== undefined,
|
|
1250
1268
|
});
|
|
1251
1269
|
}
|
|
1252
1270
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function autoSyncCommand(action?: string): Promise<void>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/** Remote auto-sync CLI (`gitnexus auto-sync`). Local incremental watch lives in `analyze-watch.ts`. */
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { getAutoSyncConfigPath, getAutoSyncMutexPath, readAutoSyncWatchStatus, resetAutoSyncState, startAutoSyncWatch, stopAutoSyncWatch, } from '../core/auto-sync/index.js';
|
|
5
|
+
export async function autoSyncCommand(action = 'start') {
|
|
6
|
+
if (action === 'init') {
|
|
7
|
+
await initWatchConfig();
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (action === 'reset') {
|
|
11
|
+
if (!(await resetAutoSyncState())) {
|
|
12
|
+
process.stderr.write(`[auto-sync] Cannot reset analysis state while the watch mutex is held. Confirm no watch process is running, then remove ${getAutoSyncMutexPath()}.\n`);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
process.stdout.write('[auto-sync] Reset analysis state.\n');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (action === 'status') {
|
|
20
|
+
printStatus(await readAutoSyncWatchStatus());
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (action === 'stop') {
|
|
24
|
+
if ((await stopAutoSyncWatch()) !== 'stopped')
|
|
25
|
+
process.exitCode = 1;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (action === 'restart') {
|
|
29
|
+
const result = await stopAutoSyncWatch();
|
|
30
|
+
if (result === 'refused' || result === 'timeout') {
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
await startWatchProcess();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (action !== 'start') {
|
|
38
|
+
process.stderr.write(`[auto-sync] Unknown auto-sync action: ${action}\n`);
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
await startWatchProcess();
|
|
43
|
+
}
|
|
44
|
+
async function startWatchProcess() {
|
|
45
|
+
const handle = await startAutoSyncWatch();
|
|
46
|
+
if (!handle) {
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const stop = () => {
|
|
51
|
+
void handle.stop().then(() => {
|
|
52
|
+
process.stderr.write('[auto-sync] Watch stopped.\n');
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}, (error) => {
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
process.stderr.write(`[auto-sync] Failed to stop watch: ${message}\n`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
process.once('SIGINT', stop);
|
|
61
|
+
process.once('SIGTERM', stop);
|
|
62
|
+
}
|
|
63
|
+
function printStatus(status) {
|
|
64
|
+
const parts = [`state=${status.state}`];
|
|
65
|
+
if (status.pid)
|
|
66
|
+
parts.push(`pid=${status.pid}`);
|
|
67
|
+
if (status.configPath)
|
|
68
|
+
parts.push(`config=${status.configPath}`);
|
|
69
|
+
if (status.message)
|
|
70
|
+
parts.push(`message=${status.message}`);
|
|
71
|
+
parts.push(`updated_at=${status.updatedAt}`);
|
|
72
|
+
process.stdout.write(`${parts.join(' ')}\n`);
|
|
73
|
+
}
|
|
74
|
+
async function initWatchConfig() {
|
|
75
|
+
const configPath = getAutoSyncConfigPath();
|
|
76
|
+
try {
|
|
77
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
78
|
+
await fs.writeFile(configPath, defaultSyncConfig(path.resolve(path.dirname(configPath), 'repos')), {
|
|
79
|
+
flag: 'wx',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
if (err.code === 'EEXIST') {
|
|
84
|
+
process.stderr.write(`[auto-sync] Config already exists: ${configPath}\n`);
|
|
85
|
+
process.exitCode = 1;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
process.stdout.write(`[auto-sync] Created ${configPath}\n`);
|
|
91
|
+
}
|
|
92
|
+
function defaultSyncConfig(localPath) {
|
|
93
|
+
return [
|
|
94
|
+
'sync_interval_minutes: 10',
|
|
95
|
+
'max_concurrency: 1',
|
|
96
|
+
'repo_git_timeout: 10s',
|
|
97
|
+
'analyze_timeout: 5m',
|
|
98
|
+
'analyze_failure_threshold: 3',
|
|
99
|
+
'projects:',
|
|
100
|
+
` - local_path: ${localPath}`,
|
|
101
|
+
' branches: [master, main]',
|
|
102
|
+
' overwrite_local_changes: false',
|
|
103
|
+
' remote_urls:',
|
|
104
|
+
' - git@github.com:owner/repo.git',
|
|
105
|
+
'',
|
|
106
|
+
].join('\n');
|
|
107
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-line identity printed before every CLI action:
|
|
3
|
+
* `GitNexus Analyzer (1.6.10)`. Goes to stderr so stdout stays
|
|
4
|
+
* pipe/JSON-safe (`gitnexus query … | jq`, `status --json`).
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from 'commander';
|
|
7
|
+
export declare function installedCliVersion(): string;
|
|
8
|
+
export declare function commandDisplayName(name: string): string;
|
|
9
|
+
export declare function commandBannerTitle(command: Command): string;
|
|
10
|
+
export declare function formatCommandBanner(title: string, version?: string): string;
|
|
11
|
+
export interface WriteCommandBannerDependencies {
|
|
12
|
+
write?: (text: string) => void;
|
|
13
|
+
version?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function writeCommandBanner(command: Command, deps?: WriteCommandBannerDependencies): void;
|