gitnexus 1.6.9 → 1.6.10-aptos.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +211 -53
- package/dist/_shared/graph/types.d.ts +67 -3
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +4 -3
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +2 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +2 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +8 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/pipeline.d.ts +1 -1
- package/dist/_shared/pipeline.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +1 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +9 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +20 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +25 -44
- package/dist/cli/analyze.d.ts +5 -2
- package/dist/cli/analyze.js +197 -11
- package/dist/cli/clean.js +17 -3
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/doctor.d.ts +18 -0
- package/dist/cli/doctor.js +96 -5
- package/dist/cli/editor-targets.d.ts +17 -2
- package/dist/cli/editor-targets.js +44 -0
- package/dist/cli/embeddings.d.ts +12 -0
- package/dist/cli/embeddings.js +49 -0
- package/dist/cli/eval-server.d.ts +23 -1
- package/dist/cli/eval-server.js +126 -8
- package/dist/cli/help-i18n.js +6 -0
- package/dist/cli/i18n/en.d.ts +18 -8
- package/dist/cli/i18n/en.js +18 -8
- package/dist/cli/i18n/resources.d.ts +28 -8
- package/dist/cli/i18n/zh-CN.d.ts +10 -0
- package/dist/cli/i18n/zh-CN.js +18 -8
- package/dist/cli/index.js +21 -7
- package/dist/cli/lazy-action.d.ts +7 -0
- package/dist/cli/lazy-action.js +27 -0
- package/dist/cli/mcp.js +6 -3
- package/dist/cli/move-availability.d.ts +5 -0
- package/dist/cli/move-availability.js +11 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +230 -32
- package/dist/cli/skill-gen.js +38 -18
- package/dist/cli/standard-skills.d.ts +76 -0
- package/dist/cli/standard-skills.js +45 -0
- package/dist/cli/status.d.ts +4 -1
- package/dist/cli/status.js +57 -4
- package/dist/cli/tool.js +11 -0
- package/dist/cli/uninstall.js +77 -18
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +7 -1
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +27 -0
- package/dist/core/analysis-features.d.ts +21 -0
- package/dist/core/analysis-features.js +59 -0
- package/dist/core/analyzer-identity.d.ts +74 -0
- package/dist/core/analyzer-identity.js +1820 -0
- package/dist/core/augmentation/engine.js +13 -8
- package/dist/core/embeddings/embedder.d.ts +3 -2
- package/dist/core/embeddings/embedder.js +24 -7
- package/dist/core/embeddings/embedding-identity.d.ts +11 -0
- package/dist/core/embeddings/embedding-identity.js +24 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +36 -1
- package/dist/core/embeddings/embedding-pipeline.js +100 -9
- package/dist/core/embeddings/http-client.d.ts +33 -3
- package/dist/core/embeddings/http-client.js +237 -25
- package/dist/core/embeddings/node-module-compat.d.ts +25 -0
- package/dist/core/embeddings/node-module-compat.js +25 -0
- package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
- package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
- package/dist/core/embeddings/runtime-install.d.ts +119 -0
- package/dist/core/embeddings/runtime-install.js +372 -0
- package/dist/core/embeddings/runtime-support.d.ts +48 -17
- package/dist/core/embeddings/runtime-support.js +96 -0
- package/dist/core/git-staleness.js +1 -1
- package/dist/core/group/bridge-db.js +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +246 -108
- package/dist/core/group/extractors/manifest-extractor.js +4 -0
- package/dist/core/incremental/escalation-gate.d.ts +38 -0
- package/dist/core/incremental/escalation-gate.js +48 -0
- package/dist/core/incremental/shadow-candidates.d.ts +3 -3
- package/dist/core/incremental/shadow-candidates.js +3 -3
- package/dist/core/incremental/subgraph-extract.d.ts +2 -2
- package/dist/core/incremental/subgraph-extract.js +2 -2
- package/dist/core/index-freshness.d.ts +5 -0
- package/dist/core/index-freshness.js +13 -0
- package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
- package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
- package/dist/core/ingestion/cobol-processor.js +27 -26
- package/dist/core/ingestion/community-processor.d.ts +51 -1
- package/dist/core/ingestion/community-processor.js +323 -64
- package/dist/core/ingestion/emit-references.js +7 -2
- package/dist/core/ingestion/filesystem-walker.js +4 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.js +26 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
- package/dist/core/ingestion/languages/c/captures.js +56 -0
- package/dist/core/ingestion/languages/c/query.js +17 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
- package/dist/core/ingestion/languages/cobol/captures.js +93 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
- package/dist/core/ingestion/languages/cpp/captures.js +365 -75
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
- package/dist/core/ingestion/languages/csharp/captures.js +25 -0
- package/dist/core/ingestion/languages/dart/captures.js +90 -2
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
- package/dist/core/ingestion/languages/dart.js +2 -0
- package/dist/core/ingestion/languages/go/captures.js +34 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java/analysis-features.d.ts +3 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
- package/dist/core/ingestion/languages/java/captures.js +193 -17
- package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/java/package-facts.js +9 -0
- package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
- package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
- package/dist/core/ingestion/languages/java/query.js +23 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +23 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/javascript/captures.js +16 -0
- package/dist/core/ingestion/languages/javascript/query.js +21 -0
- package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
- package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.js +129 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
- package/dist/core/ingestion/languages/kotlin/captures.js +59 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
- package/dist/core/ingestion/languages/kotlin/query.js +19 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/kotlin.js +5 -6
- package/dist/core/ingestion/languages/move.d.ts +1 -0
- package/dist/core/ingestion/languages/move.js +27 -0
- package/dist/core/ingestion/languages/php/captures.js +40 -0
- package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
- package/dist/core/ingestion/languages/php/import-target.js +110 -2
- package/dist/core/ingestion/languages/php/interpret.js +10 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
- package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
- package/dist/core/ingestion/languages/python/captures.js +24 -5
- package/dist/core/ingestion/languages/python/interpret.js +4 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
- package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
- package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
- package/dist/core/ingestion/languages/ruby/captures.js +42 -0
- package/dist/core/ingestion/languages/rust/captures.js +13 -0
- package/dist/core/ingestion/languages/rust/interpret.js +18 -0
- package/dist/core/ingestion/languages/rust/query.js +9 -0
- package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
- package/dist/core/ingestion/languages/swift/captures.js +12 -0
- package/dist/core/ingestion/languages/typescript/captures.js +21 -0
- package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
- package/dist/core/ingestion/languages/typescript/query.js +37 -0
- package/dist/core/ingestion/markdown-processor.js +3 -2
- package/dist/core/ingestion/model/registration-table.js +1 -0
- package/dist/core/ingestion/parsing-processor.d.ts +3 -1
- package/dist/core/ingestion/parsing-processor.js +36 -1
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
- package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
- package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
- package/dist/core/ingestion/pipeline-phases/standalone-ingest.d.ts +10 -0
- package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
- package/dist/core/ingestion/pipeline.d.ts +4 -2
- package/dist/core/ingestion/pipeline.js +5 -2
- package/dist/core/ingestion/resolve-references.js +12 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
- package/dist/core/ingestion/scope-extractor.js +306 -43
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +3 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
- package/dist/core/ingestion/taint/typescript-model.js +34 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +23 -2
- package/dist/core/ingestion/type-extractors/jvm.js +17 -2
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
- package/dist/core/ingestion/utils/ast-helpers.js +153 -2
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
- package/dist/core/ingestion/utils/line-base.d.ts +20 -0
- package/dist/core/ingestion/utils/line-base.js +20 -0
- package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
- package/dist/core/ingestion/utils/symbol-labels.js +45 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
- package/dist/core/ingestion/workers/parse-worker.js +40 -5
- package/dist/core/ingestion/workers/result-merge.js +4 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
- package/dist/core/ingestion/workers/worker-pool.js +128 -28
- package/dist/core/lbug/csv-generator.d.ts +15 -0
- package/dist/core/lbug/csv-generator.js +124 -27
- package/dist/core/lbug/cypher-escape.d.ts +20 -0
- package/dist/core/lbug/cypher-escape.js +20 -0
- package/dist/core/lbug/extension-load-error.d.ts +67 -0
- package/dist/core/lbug/extension-load-error.js +326 -0
- package/dist/core/lbug/extension-loader.d.ts +17 -2
- package/dist/core/lbug/extension-loader.js +38 -13
- package/dist/core/lbug/lbug-adapter.d.ts +203 -2
- package/dist/core/lbug/lbug-adapter.js +527 -86
- package/dist/core/lbug/lbug-config.d.ts +56 -2
- package/dist/core/lbug/lbug-config.js +267 -7
- package/dist/core/lbug/move-columns.d.ts +7 -0
- package/dist/core/lbug/move-columns.js +86 -0
- package/dist/core/lbug/native-check.d.ts +40 -0
- package/dist/core/lbug/native-check.js +90 -0
- package/dist/core/lbug/node-table-layout.d.ts +29 -0
- package/dist/core/lbug/node-table-layout.js +119 -0
- package/dist/core/lbug/pool-adapter.d.ts +23 -1
- package/dist/core/lbug/pool-adapter.js +115 -8
- package/dist/core/lbug/schema.d.ts +4 -3
- package/dist/core/lbug/schema.js +16 -16
- package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
- package/dist/core/lbug/sidecar-recovery.js +418 -16
- package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
- package/dist/core/move/artifact-download.d.ts +19 -0
- package/dist/core/move/artifact-download.js +179 -0
- package/dist/core/move/compiler-facts.d.ts +120 -0
- package/dist/core/move/compiler-facts.js +9 -0
- package/dist/core/move/consistency.d.ts +28 -0
- package/dist/core/move/consistency.js +98 -0
- package/dist/core/move/constants.d.ts +98 -0
- package/dist/core/move/constants.js +136 -0
- package/dist/core/move/discovery.d.ts +10 -0
- package/dist/core/move/discovery.js +22 -0
- package/dist/core/move/entry-points.d.ts +14 -0
- package/dist/core/move/entry-points.js +40 -0
- package/dist/core/move/facts-mapper.d.ts +75 -0
- package/dist/core/move/facts-mapper.js +534 -0
- package/dist/core/move/install-lock.d.ts +14 -0
- package/dist/core/move/install-lock.js +102 -0
- package/dist/core/move/install.d.ts +39 -0
- package/dist/core/move/install.js +391 -0
- package/dist/core/move/mcp-client.d.ts +115 -0
- package/dist/core/move/mcp-client.js +436 -0
- package/dist/core/move/move-ingest.d.ts +49 -0
- package/dist/core/move/move-ingest.js +320 -0
- package/dist/core/move/provision.d.ts +19 -0
- package/dist/core/move/provision.js +91 -0
- package/dist/core/move/release.d.ts +6 -0
- package/dist/core/move/release.js +10 -0
- package/dist/core/move/symbol-id.d.ts +35 -0
- package/dist/core/move/symbol-id.js +65 -0
- package/dist/core/move/type-parser.d.ts +11 -0
- package/dist/core/move/type-parser.js +38 -0
- package/dist/core/platform/capabilities.d.ts +0 -1
- package/dist/core/platform/capabilities.js +39 -8
- package/dist/core/run-analyze.d.ts +3 -3
- package/dist/core/run-analyze.js +1001 -184
- package/dist/core/search/fts-indexes.d.ts +31 -0
- package/dist/core/search/fts-indexes.js +73 -0
- package/dist/core/search/fts-schema.js +2 -0
- package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
- package/dist/core/tree-sitter/safe-parse.js +21 -7
- package/dist/core/wiki/graph-queries.js +6 -5
- package/dist/core/wiki/llm-client.d.ts +8 -2
- package/dist/core/wiki/llm-client.js +41 -5
- package/dist/mcp/core/embedder.js +16 -2
- package/dist/mcp/http-transport.d.ts +5 -0
- package/dist/mcp/http-transport.js +19 -5
- package/dist/mcp/local/bean-metadata.d.ts +2 -0
- package/dist/mcp/local/bean-metadata.js +25 -0
- package/dist/mcp/local/line-display.d.ts +22 -0
- package/dist/mcp/local/line-display.js +3 -0
- package/dist/mcp/local/local-backend.d.ts +19 -1
- package/dist/mcp/local/local-backend.js +402 -155
- package/dist/mcp/local/pdg-impact.d.ts +5 -3
- package/dist/mcp/local/pdg-impact.js +5 -2
- package/dist/mcp/output-budget.d.ts +5 -0
- package/dist/mcp/output-budget.js +52 -0
- package/dist/mcp/read-only-policy.d.ts +12 -0
- package/dist/mcp/read-only-policy.js +102 -0
- package/dist/mcp/repository-policy.d.ts +34 -0
- package/dist/mcp/repository-policy.js +328 -0
- package/dist/mcp/resources.js +32 -5
- package/dist/mcp/server.d.ts +5 -2
- package/dist/mcp/server.js +29 -9
- package/dist/mcp/tools.d.ts +0 -8
- package/dist/mcp/tools.js +102 -5
- package/dist/server/analyze-job.d.ts +3 -0
- package/dist/server/analyze-job.js +17 -0
- package/dist/server/analyze-launch.d.ts +6 -0
- package/dist/server/analyze-launch.js +82 -6
- package/dist/server/analyze-worker-core.d.ts +2 -1
- package/dist/server/analyze-worker-core.js +5 -2
- package/dist/server/analyze-worker.js +29 -6
- package/dist/server/api.d.ts +30 -0
- package/dist/server/api.js +120 -34
- package/dist/server/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +4 -2
- package/dist/server/upload-ingest.js +2 -1
- package/dist/server/validation.js +2 -1
- package/dist/storage/git.d.ts +31 -0
- package/dist/storage/git.js +111 -1
- package/dist/storage/parse-cache.js +7 -1
- package/dist/storage/parsedfile-store.d.ts +8 -0
- package/dist/storage/parsedfile-store.js +165 -1
- package/dist/storage/repo-manager.d.ts +194 -2
- package/dist/storage/repo-manager.js +56 -1
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
- package/hooks/claude/gitnexus-hook.cjs +59 -9
- package/hooks/claude/pre-tool-use.sh +0 -0
- package/hooks/claude/session-start.sh +0 -0
- package/package.json +21 -15
- package/scripts/cross-platform-tests.ts +56 -0
- package/scripts/ensure-fts.ts +43 -0
- package/scripts/install-duckdb-extension.mjs +85 -24
- package/scripts/run-cross-platform.ts +61 -6
- package/scripts/shard-arg.ts +30 -0
- package/scripts/sync-plugin-manifests.mjs +192 -0
- package/skills/gitnexus-lfg/README.md +55 -0
- package/skills/gitnexus-lfg/SKILL.md +86 -0
- package/skills/gitnexus-plan/README.md +142 -0
- package/skills/gitnexus-plan/SKILL.md +348 -0
- package/skills/gitnexus-plan/references/context-ledger.md +137 -0
- package/skills/gitnexus-plan/references/context-pack.md +126 -0
- package/skills/gitnexus-plan/references/evidence-provenance.md +272 -0
- package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
- package/skills/gitnexus-plan/references/plan-template.md +201 -0
- package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2084 -0
- package/skills/gitnexus-review/SKILL.md +273 -0
- package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
- package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
- package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
- package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
- package/skills/gitnexus-work/README.md +71 -0
- package/skills/gitnexus-work/SKILL.md +269 -0
- package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
- package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
- package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
- package/web/assets/agent-Bqxn-abU.js +626 -0
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
- package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
- package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
- package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
- package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
- package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
- package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
- package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
- package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
- package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
- package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
- package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
- package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
- package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
- package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
- package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
- package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
- package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
- package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
- package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
- package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
- package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
- package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
- package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
- package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
- package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
- package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
- package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
- package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
- package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
- package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
- package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
- package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
- package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
- package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
- package/web/assets/index-CX_fADmQ.css +2 -0
- package/web/assets/index-D1Z3dGGz.js +575 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
- package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
- package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
- package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
- package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
- package/web/assets/node-Ct_zna8U.js +8 -0
- package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
- package/web/assets/preload-helper-Czpn1I53.js +1 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
- package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
- package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
- package/web/assets/sdk-CzHHH8tD.js +37 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
- package/web/assets/src-JV30wyV8.js +1 -0
- package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
- package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
- package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
- package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
- package/web/index.html +18 -10
- package/skills/gitnexus-pr-review.md +0 -163
- package/web/assets/agent-Dli_x7bU.js +0 -660
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
- package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
- package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
- package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
- package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
- package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
- package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
- package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
- package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
- package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
- package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
- package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
- package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
- package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
- package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
- package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
- package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
- package/web/assets/index-KctnI3Vq.js +0 -635
- package/web/assets/index-_lgn7hs5.css +0 -2
- package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
- package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
- package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
- package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
- package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
- package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
- package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
- package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
- package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
- package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
- package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
- package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
package/dist/cli/doctor.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type EmbeddingRuntimeResolution } from '../core/embeddings/runtime-install.js';
|
|
1
2
|
export declare function displayWidth(value: string): number;
|
|
2
3
|
export declare function padDisplayEnd(value: string, columns: number): string;
|
|
3
4
|
/**
|
|
@@ -14,8 +15,25 @@ export declare function localEmbeddingDoctorStatus(opts: {
|
|
|
14
15
|
httpMode: boolean;
|
|
15
16
|
platform?: NodeJS.Platform;
|
|
16
17
|
arch?: NodeJS.Architecture;
|
|
18
|
+
/** Injectable for tests; defaults to probing the real install. */
|
|
19
|
+
resolution?: EmbeddingRuntimeResolution | null;
|
|
20
|
+
/** Injectable for tests; defaults to this Node's registerHooks capability. */
|
|
21
|
+
prefixLoadable?: boolean;
|
|
17
22
|
}): {
|
|
18
23
|
status: string;
|
|
19
24
|
detail: string | null;
|
|
20
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Page-size lines for the `doctor` Runtime section (#1231). Pure so the
|
|
28
|
+
* warning gate can be unit-tested without running the whole command (the
|
|
29
|
+
* `localEmbeddingDoctorStatus` precedent above) — but takes the probed
|
|
30
|
+
* values as plain params rather than injectable probes, because `undefined`
|
|
31
|
+
* is a *meaningful* pageSize state here (probe unavailable / win32) and
|
|
32
|
+
* would collide with a "not provided → use default" DI convention.
|
|
33
|
+
*
|
|
34
|
+
* Returns 0 lines (page size unknown), 1 line (page size), or 2 lines
|
|
35
|
+
* (page size + non-4K warning when the installed @ladybugdb/core does not
|
|
36
|
+
* detect the OS page size at runtime).
|
|
37
|
+
*/
|
|
38
|
+
export declare function pageSizeDoctorLines(pageSize: number | undefined, ladybugVersion: string | undefined): string[];
|
|
21
39
|
export declare const doctorCommand: () => Promise<void>;
|
package/dist/cli/doctor.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { getRuntimeCapabilities, getRuntimeFingerprint } from '../core/platform/capabilities.js';
|
|
2
2
|
import { resolveEmbeddingConfig } from '../core/embeddings/config.js';
|
|
3
3
|
import { isHttpMode } from '../core/embeddings/http-client.js';
|
|
4
|
-
import { getLocalEmbeddingRuntimeBlocker } from '../core/embeddings/runtime-support.js';
|
|
4
|
+
import { getLocalEmbeddingRuntimeBlocker, localEmbeddingPrefixUnloadableMessage, localEmbeddingStackMissingMessage, } from '../core/embeddings/runtime-support.js';
|
|
5
|
+
import { isPrefixRuntimeLoadable, resolveEmbeddingRuntime, } from '../core/embeddings/runtime-install.js';
|
|
5
6
|
import { cudaRedirectDoctorStatus } from '../core/embeddings/onnxruntime-node-resolver.js';
|
|
6
|
-
import { checkLbugNative } from '../core/lbug/native-check.js';
|
|
7
|
+
import { checkLbugNative, probeFtsExtensionLoad, probeVectorExtensionLoad, } from '../core/lbug/native-check.js';
|
|
8
|
+
import { getOsPageSize, isPageSizeAwareLadybug } from '../core/lbug/lbug-config.js';
|
|
9
|
+
import { diagnoseExtensionLoad } from '../core/lbug/extension-load-error.js';
|
|
7
10
|
import { getExtensionInstallPolicy } from '../core/lbug/extension-loader.js';
|
|
8
11
|
import { t } from './i18n/index.js';
|
|
9
12
|
function isCombiningMark(codePoint) {
|
|
@@ -64,8 +67,54 @@ export function localEmbeddingDoctorStatus(opts) {
|
|
|
64
67
|
if (blocker) {
|
|
65
68
|
return { status: `✗ local embeddings unavailable on ${platform}/${arch}`, detail: blocker };
|
|
66
69
|
}
|
|
70
|
+
// The stack is an optionalDependency — npm prunes it when onnxruntime-node's
|
|
71
|
+
// postinstall can't download its CUDA binaries (proxy/firewall, #2370).
|
|
72
|
+
const resolution = opts.resolution !== undefined ? opts.resolution : resolveEmbeddingRuntime();
|
|
73
|
+
if (resolution === null) {
|
|
74
|
+
return {
|
|
75
|
+
status: '✗ optional embedding stack not installed',
|
|
76
|
+
detail: localEmbeddingStackMissingMessage(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// A prefix-sourced stack needs module.registerHooks to load; on Node < 22.15 /
|
|
80
|
+
// < 23.5 it is present but unreachable (#2372). Report loadability, not bare
|
|
81
|
+
// presence, so the diagnostic stops claiming a ✓ the loader can't honour.
|
|
82
|
+
const prefixLoadable = opts.prefixLoadable ?? isPrefixRuntimeLoadable();
|
|
83
|
+
if (resolution.source === 'runtime-prefix' && !prefixLoadable) {
|
|
84
|
+
return {
|
|
85
|
+
status: '✗ embedding stack installed in the prefix but not loadable on this Node',
|
|
86
|
+
detail: localEmbeddingPrefixUnloadableMessage(),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
67
89
|
return { status: '✓ local embeddings supported', detail: null };
|
|
68
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Page-size lines for the `doctor` Runtime section (#1231). Pure so the
|
|
93
|
+
* warning gate can be unit-tested without running the whole command (the
|
|
94
|
+
* `localEmbeddingDoctorStatus` precedent above) — but takes the probed
|
|
95
|
+
* values as plain params rather than injectable probes, because `undefined`
|
|
96
|
+
* is a *meaningful* pageSize state here (probe unavailable / win32) and
|
|
97
|
+
* would collide with a "not provided → use default" DI convention.
|
|
98
|
+
*
|
|
99
|
+
* Returns 0 lines (page size unknown), 1 line (page size), or 2 lines
|
|
100
|
+
* (page size + non-4K warning when the installed @ladybugdb/core does not
|
|
101
|
+
* detect the OS page size at runtime).
|
|
102
|
+
*/
|
|
103
|
+
export function pageSizeDoctorLines(pageSize, ladybugVersion) {
|
|
104
|
+
if (pageSize === undefined)
|
|
105
|
+
return [];
|
|
106
|
+
const lines = [` ${padDisplayEnd('page size', 10)}${pageSize}`];
|
|
107
|
+
if (pageSize > 4096 && !isPageSizeAwareLadybug(ladybugVersion)) {
|
|
108
|
+
// Don't assert "< 0.18.0" as fact when the version is unresolvable
|
|
109
|
+
// (#2424 review R2) — name the unknown state instead.
|
|
110
|
+
const versionClause = ladybugVersion === undefined
|
|
111
|
+
? 'an unknown @ladybugdb/core version (may predate 0.18.0)'
|
|
112
|
+
: `@ladybugdb/core < 0.18.0`;
|
|
113
|
+
lines.push(` ${padDisplayEnd('', 10)}⚠ non-4K page size with ${versionClause} — ` +
|
|
114
|
+
`'gitnexus analyze' may fail during COPY (#1231). Upgrade gitnexus (npm install -g gitnexus@latest).`);
|
|
115
|
+
}
|
|
116
|
+
return lines;
|
|
117
|
+
}
|
|
69
118
|
export const doctorCommand = async () => {
|
|
70
119
|
const fingerprint = getRuntimeFingerprint();
|
|
71
120
|
const capabilities = getRuntimeCapabilities();
|
|
@@ -76,6 +125,13 @@ export const doctorCommand = async () => {
|
|
|
76
125
|
console.log(` ${label('doctor.labels.node', 10)}${fingerprint.node}`);
|
|
77
126
|
console.log(` ${label('doctor.labels.gitnexus', 10)}${fingerprint.gitnexus}`);
|
|
78
127
|
console.log(` ${label('doctor.labels.ladybugdb', 10)}${fingerprint.ladybugdb ?? 'unknown'}`);
|
|
128
|
+
// OS page size next to the LadybugDB version because the two interact:
|
|
129
|
+
// @ladybugdb/core < 0.18.0 assumed 4 KiB pages in its buffer manager and
|
|
130
|
+
// crashes mid-COPY on 16 KiB/64 KiB-page kernels (#1231). Literal label
|
|
131
|
+
// (like the 'native' line below) to avoid adding i18n keys.
|
|
132
|
+
for (const line of pageSizeDoctorLines(getOsPageSize(), fingerprint.ladybugdb)) {
|
|
133
|
+
console.log(line);
|
|
134
|
+
}
|
|
79
135
|
const nativeCheck = checkLbugNative();
|
|
80
136
|
if (nativeCheck.ok) {
|
|
81
137
|
console.log(` ${padDisplayEnd('native', 10)}✓ lbugjs.node loaded`);
|
|
@@ -88,9 +144,44 @@ export const doctorCommand = async () => {
|
|
|
88
144
|
console.log('');
|
|
89
145
|
console.log(t('doctor.capabilities'));
|
|
90
146
|
console.log(` ${label('doctor.labels.graphStore', 18)}${capabilities.graph}`);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
147
|
+
// Live LOAD probe, not the static platform capability — the static value
|
|
148
|
+
// said "available" while analyze failed to load the extension (#2374).
|
|
149
|
+
const ftsProbe = nativeCheck.ok
|
|
150
|
+
? await probeFtsExtensionLoad()
|
|
151
|
+
: { loaded: false, reason: 'LadybugDB native module (lbugjs.node) failed to load' };
|
|
152
|
+
console.log(` ${label('doctor.labels.fullTextSearch', 18)}${ftsProbe.loaded ? 'available' : 'unavailable'}`);
|
|
153
|
+
if (!ftsProbe.loaded && ftsProbe.reason) {
|
|
154
|
+
console.log(` ${padDisplayEnd('', 18)}${ftsProbe.reason}`);
|
|
155
|
+
// Add an actionable remedy for recognized failure classes (#2374). The
|
|
156
|
+
// Windows missing-dependency case is the point of this: the raw error 126
|
|
157
|
+
// ("specified module could not be found") is opaque, so name the fix (VC++
|
|
158
|
+
// redist, then OpenSSL) instead of leaving the user to reinstall in vain.
|
|
159
|
+
// `unknown`'s remedy is "run doctor", which would be circular here.
|
|
160
|
+
const { kind, remedy } = diagnoseExtensionLoad(ftsProbe.reason);
|
|
161
|
+
if (kind !== 'unknown') {
|
|
162
|
+
console.log(` ${padDisplayEnd('', 18)}${remedy}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Live LOAD probe for VECTOR too (#2623). The static capability is just
|
|
166
|
+
// `platform !== 'win32'`, so it printed "available" on the very machines
|
|
167
|
+
// where analyze was failing to load the extension — the same contradiction
|
|
168
|
+
// #2374 fixed for FTS above, and exactly what #2623's reporter saw while
|
|
169
|
+
// every incremental analyze died on an unloaded VECTOR extension.
|
|
170
|
+
const vectorProbe = nativeCheck.ok
|
|
171
|
+
? await probeVectorExtensionLoad()
|
|
172
|
+
: { loaded: false, reason: 'LadybugDB native module (lbugjs.node) failed to load' };
|
|
173
|
+
console.log(` ${label('doctor.labels.vectorIndex', 18)}${vectorProbe.loaded ? 'available' : 'unavailable'}`);
|
|
174
|
+
if (!vectorProbe.loaded && vectorProbe.reason) {
|
|
175
|
+
console.log(` ${padDisplayEnd('', 18)}${vectorProbe.reason}`);
|
|
176
|
+
const { kind, remedy } = diagnoseExtensionLoad(vectorProbe.reason, 'VECTOR');
|
|
177
|
+
if (kind !== 'unknown') {
|
|
178
|
+
console.log(` ${padDisplayEnd('', 18)}${remedy}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Semantic mode follows the probe, not the platform: without a loadable
|
|
182
|
+
// VECTOR extension the index can be neither built nor queried, so search is
|
|
183
|
+
// really on exact scan no matter what the platform would allow.
|
|
184
|
+
console.log(` ${label('doctor.labels.semanticMode', 18)}${vectorProbe.loaded ? capabilities.semanticMode : 'exact-scan'}`);
|
|
94
185
|
// Surface the optional-extension install policy so offline users can see
|
|
95
186
|
// whether analyze/query will reach the network (extension.ladybugdb.com).
|
|
96
187
|
// Literal label (like the 'native' line) to avoid adding i18n keys.
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* implementations remain behaviourally symmetrical on top of this shared
|
|
16
16
|
* structure.
|
|
17
17
|
*/
|
|
18
|
-
export type EditorId = 'cursor' | 'claude' | 'antigravity' | 'opencode' | 'codex';
|
|
18
|
+
export type EditorId = 'cursor' | 'claude' | 'antigravity' | 'opencode' | 'codebuddy' | 'qoder' | 'codex';
|
|
19
19
|
/** An editor whose MCP config is a JSONC document (server keyed by name). */
|
|
20
20
|
export interface McpJsoncTarget {
|
|
21
21
|
id: EditorId;
|
|
@@ -29,6 +29,14 @@ export interface McpJsoncTarget {
|
|
|
29
29
|
* without either side needing a cast.
|
|
30
30
|
*/
|
|
31
31
|
keyPath: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Older config locations the editor still reads when `file` is absent
|
|
34
|
+
* (CodeBuddy reads only the FIRST existing file in its priority chain).
|
|
35
|
+
* Setup writes into the first existing candidate of [file, ...legacyFiles]
|
|
36
|
+
* so it never shadows a user's servers living in a deprecated file;
|
|
37
|
+
* uninstall sweeps all of them.
|
|
38
|
+
*/
|
|
39
|
+
legacyFiles?: string[];
|
|
32
40
|
}
|
|
33
41
|
/** Codex stores MCP config as a TOML table, not JSONC. */
|
|
34
42
|
export interface CodexMcpTarget {
|
|
@@ -58,7 +66,7 @@ export interface HookTarget {
|
|
|
58
66
|
scriptDir: string;
|
|
59
67
|
}
|
|
60
68
|
export interface EditorTargets {
|
|
61
|
-
/** JSONC-format MCP entries: Cursor, Claude Code, Antigravity, OpenCode. */
|
|
69
|
+
/** JSONC-format MCP entries: Cursor, Claude Code, Antigravity, OpenCode, CodeBuddy, Qoder. */
|
|
62
70
|
mcpJsonc: McpJsoncTarget[];
|
|
63
71
|
/** Codex MCP (TOML). */
|
|
64
72
|
codex: CodexMcpTarget;
|
|
@@ -80,6 +88,13 @@ export declare function mcpTarget(id: EditorId, home?: string): McpJsoncTarget;
|
|
|
80
88
|
export declare function skillTarget(id: EditorId, home?: string): SkillTarget;
|
|
81
89
|
/** Look up a single hook target by editor id (throws if unknown). */
|
|
82
90
|
export declare function hookTarget(id: EditorId, home?: string): HookTarget;
|
|
91
|
+
/**
|
|
92
|
+
* True when err is a Node fs error with code ENOENT (file/dir absent).
|
|
93
|
+
* Shared by setup and uninstall: both must swallow ONLY absence when reading
|
|
94
|
+
* editor configs — any other read/stat failure (EACCES, EIO) is surfaced so an
|
|
95
|
+
* unreadable config is never treated as empty and rewritten gitnexus-only.
|
|
96
|
+
*/
|
|
97
|
+
export declare function isEnoent(err: unknown): boolean;
|
|
83
98
|
/**
|
|
84
99
|
* Detect indentation style from file content so JSONC edits preserve the file's
|
|
85
100
|
* existing formatting. Shared by setup (writes) and uninstall (removes).
|
|
@@ -50,6 +50,26 @@ export function getEditorTargets(home = os.homedir()) {
|
|
|
50
50
|
// OpenCode nests servers under `mcp`, not `mcpServers`.
|
|
51
51
|
keyPath: ['mcp', 'gitnexus'],
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
id: 'codebuddy',
|
|
55
|
+
label: 'CodeBuddy',
|
|
56
|
+
// Recommended user-scope path per https://www.codebuddy.ai/docs/cli/mcp;
|
|
57
|
+
// CodeBuddy reads only the first existing file in this priority chain.
|
|
58
|
+
file: path.join(home, '.codebuddy', '.mcp.json'),
|
|
59
|
+
legacyFiles: [
|
|
60
|
+
path.join(home, '.codebuddy', 'mcp.json'), // deprecated
|
|
61
|
+
path.join(home, '.codebuddy.json'), // legacy
|
|
62
|
+
],
|
|
63
|
+
keyPath: ['mcpServers', 'gitnexus'],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'qoder',
|
|
67
|
+
label: 'Qoder',
|
|
68
|
+
// Qoder's documented user-scope MCP config (https://docs.qoder.com/cli/using-cli);
|
|
69
|
+
// the IDE manages MCP via its Settings UI with no documented file path.
|
|
70
|
+
file: path.join(home, '.qoder.json'),
|
|
71
|
+
keyPath: ['mcpServers', 'gitnexus'],
|
|
72
|
+
},
|
|
53
73
|
];
|
|
54
74
|
const codex = {
|
|
55
75
|
id: 'codex',
|
|
@@ -66,6 +86,10 @@ export function getEditorTargets(home = os.homedir()) {
|
|
|
66
86
|
},
|
|
67
87
|
{ id: 'cursor', label: 'Cursor', dir: path.join(home, '.cursor', 'skills') },
|
|
68
88
|
{ id: 'opencode', label: 'OpenCode', dir: path.join(home, '.config', 'opencode', 'skills') },
|
|
89
|
+
{ id: 'codebuddy', label: 'CodeBuddy', dir: path.join(home, '.codebuddy', 'skills') },
|
|
90
|
+
// Qoder skills live at ~/.qoder/skills/{name}/SKILL.md
|
|
91
|
+
// (https://docs.qoder.com/extensions/skills).
|
|
92
|
+
{ id: 'qoder', label: 'Qoder', dir: path.join(home, '.qoder', 'skills') },
|
|
69
93
|
// Codex reads skills from ~/.agents/skills (not ~/.codex).
|
|
70
94
|
{ id: 'codex', label: 'Codex', dir: path.join(home, '.agents', 'skills') },
|
|
71
95
|
];
|
|
@@ -78,6 +102,17 @@ export function getEditorTargets(home = os.homedir()) {
|
|
|
78
102
|
needle: 'gitnexus-hook',
|
|
79
103
|
scriptDir: path.join(home, '.claude', 'hooks', 'gitnexus'),
|
|
80
104
|
},
|
|
105
|
+
{
|
|
106
|
+
id: 'codex',
|
|
107
|
+
label: 'Codex',
|
|
108
|
+
// Codex hooks use Claude Code's exact {hooks: {Event: [...]}} JSON shape
|
|
109
|
+
// and hookSpecificOutput response contract, in a dedicated hooks.json
|
|
110
|
+
// (https://developers.openai.com/codex/hooks).
|
|
111
|
+
settingsFile: path.join(home, '.codex', 'hooks.json'),
|
|
112
|
+
events: ['PreToolUse', 'PostToolUse'],
|
|
113
|
+
needle: 'gitnexus-hook',
|
|
114
|
+
scriptDir: path.join(home, '.codex', 'hooks', 'gitnexus'),
|
|
115
|
+
},
|
|
81
116
|
{
|
|
82
117
|
id: 'antigravity',
|
|
83
118
|
label: 'Antigravity',
|
|
@@ -110,6 +145,15 @@ export function hookTarget(id, home) {
|
|
|
110
145
|
throw new Error(`No hook target for editor "${id}"`);
|
|
111
146
|
return t;
|
|
112
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* True when err is a Node fs error with code ENOENT (file/dir absent).
|
|
150
|
+
* Shared by setup and uninstall: both must swallow ONLY absence when reading
|
|
151
|
+
* editor configs — any other read/stat failure (EACCES, EIO) is surfaced so an
|
|
152
|
+
* unreadable config is never treated as empty and rewritten gitnexus-only.
|
|
153
|
+
*/
|
|
154
|
+
export function isEnoent(err) {
|
|
155
|
+
return err?.code === 'ENOENT';
|
|
156
|
+
}
|
|
113
157
|
/**
|
|
114
158
|
* Detect indentation style from file content so JSONC edits preserve the file's
|
|
115
159
|
* existing formatting. Shared by setup (writes) and uninstall (removes).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface EmbeddingsInstallOptions {
|
|
2
|
+
cuda?: boolean;
|
|
3
|
+
force?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* `gitnexus embeddings install [--cuda] [--force]` — fetch the optional local
|
|
7
|
+
* embedding stack on demand (#2370). Goes through the user's npm registry
|
|
8
|
+
* config (mirrors/proxies apply); with --cuda it additionally runs
|
|
9
|
+
* onnxruntime-node's postinstall to download the CUDA GPU binaries from NuGet
|
|
10
|
+
* (set GLOBAL_AGENT_HTTPS_PROXY behind a proxy).
|
|
11
|
+
*/
|
|
12
|
+
export declare const embeddingsInstallCommand: (options?: EmbeddingsInstallOptions) => Promise<void>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { cliError, cliInfo, cliWarn } from './cli-message.js';
|
|
2
|
+
import { getEmbeddingRuntimeDir, getEmbeddingStackSpecs, installEmbeddingRuntime, isPrefixRuntimeLoadable, resolveEmbeddingRuntime, } from '../core/embeddings/runtime-install.js';
|
|
3
|
+
import { localEmbeddingPrefixUnloadableMessage } from '../core/embeddings/runtime-support.js';
|
|
4
|
+
/**
|
|
5
|
+
* `gitnexus embeddings install [--cuda] [--force]` — fetch the optional local
|
|
6
|
+
* embedding stack on demand (#2370). Goes through the user's npm registry
|
|
7
|
+
* config (mirrors/proxies apply); with --cuda it additionally runs
|
|
8
|
+
* onnxruntime-node's postinstall to download the CUDA GPU binaries from NuGet
|
|
9
|
+
* (set GLOBAL_AGENT_HTTPS_PROXY behind a proxy).
|
|
10
|
+
*/
|
|
11
|
+
export const embeddingsInstallCommand = async (options = {}) => {
|
|
12
|
+
const resolved = resolveEmbeddingRuntime();
|
|
13
|
+
if (resolved?.source === 'package' && !options.force) {
|
|
14
|
+
cliInfo('The embedding stack is already installed with gitnexus itself — nothing to do.\n' +
|
|
15
|
+
'(Use --force to install a copy into the runtime prefix anyway.)');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const specs = Object.entries(getEmbeddingStackSpecs())
|
|
19
|
+
.map(([name, spec]) => `${name}@${spec}`)
|
|
20
|
+
.join(', ');
|
|
21
|
+
cliInfo(`Installing ${specs} into ${getEmbeddingRuntimeDir()} …`);
|
|
22
|
+
cliInfo(options.cuda
|
|
23
|
+
? 'CUDA mode: onnxruntime-node will download GPU binaries from NuGet ' +
|
|
24
|
+
'(set GLOBAL_AGENT_HTTPS_PROXY=<proxy-url> behind a proxy).'
|
|
25
|
+
: 'CPU mode: install scripts are skipped — only your npm registry is contacted.');
|
|
26
|
+
try {
|
|
27
|
+
await installEmbeddingRuntime({ cuda: options.cuda, onOutput: (line) => cliInfo(` ${line}`) });
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
cliError(`${err instanceof Error ? err.message : String(err)}\n`, {
|
|
31
|
+
recoveryHint: 'local-embedding-stack-missing',
|
|
32
|
+
});
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const postInstall = resolveEmbeddingRuntime();
|
|
37
|
+
if (postInstall === null) {
|
|
38
|
+
cliInfo('✗ Install completed but the stack still does not resolve — check the output above.');
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (postInstall.source === 'runtime-prefix' && !isPrefixRuntimeLoadable()) {
|
|
43
|
+
// The packages are in the prefix, but this Node has no module.registerHooks
|
|
44
|
+
// to load them — don't claim readiness the loader can't honour.
|
|
45
|
+
cliWarn(`${localEmbeddingPrefixUnloadableMessage()}\n`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
cliInfo('✓ Embedding runtime installed. `gitnexus analyze --embeddings` is ready.');
|
|
49
|
+
};
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* Usage:
|
|
17
17
|
* gitnexus eval-server # default port 4848, binds 127.0.0.1
|
|
18
18
|
* gitnexus eval-server --port 4848 # explicit port
|
|
19
|
-
* gitnexus eval-server --host 0.0.0.0
|
|
19
|
+
* GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host 0.0.0.0
|
|
20
|
+
* GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host devbox.local
|
|
20
21
|
* gitnexus eval-server --idle-timeout 300 # auto-shutdown after 300s idle
|
|
21
22
|
*
|
|
22
23
|
* READY signal format: GITNEXUS_EVAL_SERVER_READY:<host>:<port>
|
|
@@ -42,6 +43,27 @@ export interface EvalServerOptions {
|
|
|
42
43
|
* address (127.0.0.1 or ::1) at bind time rather than forcing IPv4.
|
|
43
44
|
*/
|
|
44
45
|
export declare function validateHost(raw: string): string | null;
|
|
46
|
+
type EvalServerHostLookup = (hostname: string) => Promise<string>;
|
|
47
|
+
/** Resolve a DNS bind name once so validation and listen() use the same concrete address. */
|
|
48
|
+
export declare function resolveEvalServerBindHost(raw: string, resolveHostname?: EvalServerHostLookup): Promise<string | null>;
|
|
49
|
+
/** Resolve the bearer token from the shell, then .env.local, then .env. */
|
|
50
|
+
export declare function resolveEvalServerAuthToken(env: NodeJS.ProcessEnv, cwd?: string): string | undefined;
|
|
51
|
+
/** True only for literal loopback addresses; DNS names are resolved before this check. */
|
|
52
|
+
export declare function isEvalServerLoopbackHost(host: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the bearer token for a concrete bind host. An unreadable `.env` /
|
|
55
|
+
* `.env.local` only matters when the binding actually requires a token, so
|
|
56
|
+
* loopback binds degrade to a warning instead of refusing to start; any
|
|
57
|
+
* non-loopback bind keeps the fail-closed error.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveEvalServerAuthTokenForHost(host: string, env: NodeJS.ProcessEnv, cwd?: string): {
|
|
60
|
+
token?: string;
|
|
61
|
+
warning?: string;
|
|
62
|
+
};
|
|
63
|
+
/** Refuse exposure of the eval-server query surface without authentication. */
|
|
64
|
+
export declare function assertSecureEvalServerBinding(host: string, authToken: string | undefined): void;
|
|
65
|
+
/** Validate the exact Bearer header while keeping token comparison constant-time. */
|
|
66
|
+
export declare function isEvalServerBearerAuthorized(authorization: string | string[] | undefined, authToken: string | undefined): boolean;
|
|
45
67
|
export declare function formatQueryResult(result: any): string;
|
|
46
68
|
export declare function formatContextResult(result: any): string;
|
|
47
69
|
export declare function formatImpactResult(result: any): string;
|
package/dist/cli/eval-server.js
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* Usage:
|
|
17
17
|
* gitnexus eval-server # default port 4848, binds 127.0.0.1
|
|
18
18
|
* gitnexus eval-server --port 4848 # explicit port
|
|
19
|
-
* gitnexus eval-server --host 0.0.0.0
|
|
19
|
+
* GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host 0.0.0.0
|
|
20
|
+
* GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host devbox.local
|
|
20
21
|
* gitnexus eval-server --idle-timeout 300 # auto-shutdown after 300s idle
|
|
21
22
|
*
|
|
22
23
|
* READY signal format: GITNEXUS_EVAL_SERVER_READY:<host>:<port>
|
|
@@ -30,8 +31,11 @@
|
|
|
30
31
|
*/
|
|
31
32
|
import http from 'http';
|
|
32
33
|
import crypto from 'node:crypto';
|
|
34
|
+
import { lookup } from 'node:dns/promises';
|
|
33
35
|
import { isIPv4, isIPv6 } from 'node:net';
|
|
34
|
-
import { writeSync } from 'node:fs';
|
|
36
|
+
import { readFileSync, writeSync } from 'node:fs';
|
|
37
|
+
import path from 'node:path';
|
|
38
|
+
import { parseEnv } from 'node:util';
|
|
35
39
|
import { LocalBackend, } from '../mcp/local/local-backend.js';
|
|
36
40
|
import { logger } from '../core/logger.js';
|
|
37
41
|
import { cliInfo, cliWarn, cliError } from './cli-message.js';
|
|
@@ -50,6 +54,86 @@ export function validateHost(raw) {
|
|
|
50
54
|
return raw;
|
|
51
55
|
return null;
|
|
52
56
|
}
|
|
57
|
+
function isHostname(raw) {
|
|
58
|
+
if (!raw || raw.length > 253 || /^[\d.]+$/.test(raw))
|
|
59
|
+
return false;
|
|
60
|
+
return raw
|
|
61
|
+
.split('.')
|
|
62
|
+
.every((label) => label.length > 0 &&
|
|
63
|
+
label.length <= 63 &&
|
|
64
|
+
/^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label));
|
|
65
|
+
}
|
|
66
|
+
/** Resolve a DNS bind name once so validation and listen() use the same concrete address. */
|
|
67
|
+
export async function resolveEvalServerBindHost(raw, resolveHostname = async (hostname) => (await lookup(hostname, { family: 4 })).address) {
|
|
68
|
+
const directHost = validateHost(raw);
|
|
69
|
+
if (directHost && directHost !== 'localhost')
|
|
70
|
+
return directHost;
|
|
71
|
+
if (directHost !== 'localhost' && !isHostname(raw))
|
|
72
|
+
return null;
|
|
73
|
+
try {
|
|
74
|
+
const address = await resolveHostname(raw);
|
|
75
|
+
return isIPv4(address) ? address : null;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function readAuthTokenFile(filePath) {
|
|
82
|
+
try {
|
|
83
|
+
return parseEnv(readFileSync(filePath, 'utf8')).GITNEXUS_AUTH_TOKEN?.trim() || undefined;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.code === 'ENOENT')
|
|
87
|
+
return undefined;
|
|
88
|
+
throw new Error(`Unable to read eval-server authentication from ${filePath}`, { cause: error });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Resolve the bearer token from the shell, then .env.local, then .env. */
|
|
92
|
+
export function resolveEvalServerAuthToken(env, cwd = process.cwd()) {
|
|
93
|
+
if (Object.hasOwn(env, 'GITNEXUS_AUTH_TOKEN')) {
|
|
94
|
+
return env.GITNEXUS_AUTH_TOKEN?.trim() || undefined;
|
|
95
|
+
}
|
|
96
|
+
return (readAuthTokenFile(path.join(cwd, '.env.local')) ?? readAuthTokenFile(path.join(cwd, '.env')));
|
|
97
|
+
}
|
|
98
|
+
/** True only for literal loopback addresses; DNS names are resolved before this check. */
|
|
99
|
+
export function isEvalServerLoopbackHost(host) {
|
|
100
|
+
return host === 'localhost' || host === '::1' || (isIPv4(host) && host.startsWith('127.'));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve the bearer token for a concrete bind host. An unreadable `.env` /
|
|
104
|
+
* `.env.local` only matters when the binding actually requires a token, so
|
|
105
|
+
* loopback binds degrade to a warning instead of refusing to start; any
|
|
106
|
+
* non-loopback bind keeps the fail-closed error.
|
|
107
|
+
*/
|
|
108
|
+
export function resolveEvalServerAuthTokenForHost(host, env, cwd = process.cwd()) {
|
|
109
|
+
try {
|
|
110
|
+
return { token: resolveEvalServerAuthToken(env, cwd) };
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (isEvalServerLoopbackHost(host)) {
|
|
114
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
115
|
+
return { warning: `${reason} Continuing without authentication on loopback host ${host}.` };
|
|
116
|
+
}
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Refuse exposure of the eval-server query surface without authentication. */
|
|
121
|
+
export function assertSecureEvalServerBinding(host, authToken) {
|
|
122
|
+
if (!authToken && !isEvalServerLoopbackHost(host)) {
|
|
123
|
+
throw new Error(`Refusing to start eval-server on non-loopback host ${host} without authentication. ` +
|
|
124
|
+
'Set GITNEXUS_AUTH_TOKEN or bind to 127.0.0.1, localhost, or ::1.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Validate the exact Bearer header while keeping token comparison constant-time. */
|
|
128
|
+
export function isEvalServerBearerAuthorized(authorization, authToken) {
|
|
129
|
+
if (!authToken)
|
|
130
|
+
return true;
|
|
131
|
+
const expected = Buffer.from(`Bearer ${authToken}`, 'utf8');
|
|
132
|
+
const supplied = typeof authorization === 'string' ? Buffer.from(authorization, 'utf8') : null;
|
|
133
|
+
const sameLength = supplied?.length === expected.length;
|
|
134
|
+
const candidate = sameLength && supplied ? supplied : Buffer.alloc(expected.length);
|
|
135
|
+
return crypto.timingSafeEqual(candidate, expected) && sameLength;
|
|
136
|
+
}
|
|
53
137
|
// ─── Text Formatters ──────────────────────────────────────────────────
|
|
54
138
|
// Convert structured JSON results into compact, LLM-friendly text.
|
|
55
139
|
// Design: minimize tokens, maximize actionability.
|
|
@@ -545,15 +629,38 @@ export async function evalServerCommand(options) {
|
|
|
545
629
|
const port = parseInt(options?.port || '4848');
|
|
546
630
|
const idleTimeoutSec = parseInt(options?.idleTimeout || '0');
|
|
547
631
|
const rawHost = options?.host ?? '127.0.0.1';
|
|
548
|
-
const host =
|
|
632
|
+
const host = await resolveEvalServerBindHost(rawHost);
|
|
549
633
|
if (!host) {
|
|
550
634
|
cliError(`Invalid --host value "${rawHost}":\n` +
|
|
551
|
-
` Must be an IP address or
|
|
635
|
+
` Must be an IP address or a hostname that resolves to a local IPv4 address.\n\n` +
|
|
552
636
|
` Examples:\n` +
|
|
553
637
|
` gitnexus eval-server --host 127.0.0.1 (loopback only, default)\n` +
|
|
554
|
-
` gitnexus eval-server --host 0.0.0.0
|
|
555
|
-
` gitnexus eval-server --host 192.168.1.5
|
|
556
|
-
` gitnexus eval-server --host localhost (
|
|
638
|
+
` GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host 0.0.0.0\n` +
|
|
639
|
+
` GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host 192.168.1.5\n` +
|
|
640
|
+
` gitnexus eval-server --host localhost (resolved IPv4 loopback)\n` +
|
|
641
|
+
` GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host devbox.local\n`, { flag: '--host', value: rawHost });
|
|
642
|
+
process.exit(1);
|
|
643
|
+
}
|
|
644
|
+
let authToken;
|
|
645
|
+
try {
|
|
646
|
+
const resolved = resolveEvalServerAuthTokenForHost(host, process.env);
|
|
647
|
+
authToken = resolved.token;
|
|
648
|
+
if (resolved.warning)
|
|
649
|
+
cliWarn(resolved.warning);
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
cliError(error instanceof Error
|
|
653
|
+
? error.message
|
|
654
|
+
: 'Unable to read eval-server authentication configuration.');
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
657
|
+
try {
|
|
658
|
+
assertSecureEvalServerBinding(host, authToken);
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
cliError(error instanceof Error ? error.message : 'Refusing insecure eval-server binding.', {
|
|
662
|
+
host,
|
|
663
|
+
});
|
|
557
664
|
process.exit(1);
|
|
558
665
|
}
|
|
559
666
|
const backend = new LocalBackend();
|
|
@@ -589,6 +696,13 @@ export async function evalServerCommand(options) {
|
|
|
589
696
|
// shut down locally without a token.)
|
|
590
697
|
const shutdownToken = crypto.randomBytes(24).toString('hex');
|
|
591
698
|
const server = http.createServer(async (req, res) => {
|
|
699
|
+
if (!isEvalServerBearerAuthorized(req.headers.authorization, authToken)) {
|
|
700
|
+
res.setHeader('Content-Type', 'application/json');
|
|
701
|
+
res.setHeader('WWW-Authenticate', 'Bearer');
|
|
702
|
+
res.writeHead(401);
|
|
703
|
+
res.end(JSON.stringify({ error: 'Unauthorized' }));
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
592
706
|
resetIdleTimer();
|
|
593
707
|
try {
|
|
594
708
|
// Health check
|
|
@@ -680,7 +794,7 @@ export async function evalServerCommand(options) {
|
|
|
680
794
|
` Run \`ip addr\` (Linux) or \`ipconfig\` (Windows) to list available addresses.\n\n`) +
|
|
681
795
|
` Common fixes:\n` +
|
|
682
796
|
` gitnexus eval-server --host 127.0.0.1 (loopback, this machine only)\n` +
|
|
683
|
-
` gitnexus eval-server --host 0.0.0.0
|
|
797
|
+
` GITNEXUS_AUTH_TOKEN=... gitnexus eval-server --host 0.0.0.0\n`, { code: err.code, port, host });
|
|
684
798
|
}
|
|
685
799
|
else if (err.code === 'EACCES') {
|
|
686
800
|
cliError(`\nGitNexus eval-server failed to start:\n` +
|
|
@@ -723,6 +837,9 @@ export async function evalServerCommand(options) {
|
|
|
723
837
|
` GET /health — health check`,
|
|
724
838
|
` POST /shutdown — graceful shutdown`,
|
|
725
839
|
];
|
|
840
|
+
if (authToken) {
|
|
841
|
+
bannerLines.push(' Bearer authentication enabled');
|
|
842
|
+
}
|
|
726
843
|
if (idleTimeoutSec > 0) {
|
|
727
844
|
bannerLines.push(` Auto-shutdown after ${idleTimeoutSec}s idle`);
|
|
728
845
|
}
|
|
@@ -730,6 +847,7 @@ export async function evalServerCommand(options) {
|
|
|
730
847
|
port: boundPort,
|
|
731
848
|
host,
|
|
732
849
|
idleTimeoutSec: idleTimeoutSec > 0 ? idleTimeoutSec : undefined,
|
|
850
|
+
authEnabled: Boolean(authToken),
|
|
733
851
|
endpoints: [
|
|
734
852
|
'POST /tool/query',
|
|
735
853
|
'POST /tool/context',
|
package/dist/cli/help-i18n.js
CHANGED
|
@@ -17,6 +17,8 @@ const COMMAND_DESCRIPTION_KEYS = {
|
|
|
17
17
|
list: 'help.command.list.description',
|
|
18
18
|
status: 'help.command.status.description',
|
|
19
19
|
doctor: 'help.command.doctor.description',
|
|
20
|
+
embeddings: 'help.command.embeddings.description',
|
|
21
|
+
'embeddings install': 'help.command.embeddings.install.description',
|
|
20
22
|
clean: 'help.command.clean.description',
|
|
21
23
|
remove: 'help.command.remove.description',
|
|
22
24
|
wiki: 'help.command.wiki.description',
|
|
@@ -73,6 +75,7 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
73
75
|
'mcp|--auth-token <token>': 'help.option.mcp.authToken',
|
|
74
76
|
'serve|-p, --port <port>': 'help.option.port',
|
|
75
77
|
'serve|--host <host>': 'help.option.serve.host',
|
|
78
|
+
'status|--json': 'help.option.status.json',
|
|
76
79
|
'uninstall|-f, --force': 'help.option.uninstall.force',
|
|
77
80
|
'clean|-f, --force': 'help.option.force.confirmation',
|
|
78
81
|
'clean|--all': 'help.option.clean.all',
|
|
@@ -90,6 +93,7 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
90
93
|
'wiki|--concurrency <n>': 'help.option.wiki.concurrency',
|
|
91
94
|
'wiki|--timeout <seconds>': 'help.option.wiki.timeout',
|
|
92
95
|
'wiki|--retries <n>': 'help.option.wiki.retries',
|
|
96
|
+
'wiki|--allow-insecure-connection <host>': 'help.option.wiki.allowInsecureConnection',
|
|
93
97
|
'wiki|--gist': 'help.option.wiki.gist',
|
|
94
98
|
'wiki|-v, --verbose': 'help.option.verbose',
|
|
95
99
|
'wiki|--review': 'help.option.wiki.review',
|
|
@@ -143,6 +147,8 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
143
147
|
'eval-server|-p, --port <port>': 'help.option.port',
|
|
144
148
|
'eval-server|--host <host>': 'help.option.evalServer.host',
|
|
145
149
|
'eval-server|--idle-timeout <seconds>': 'help.option.evalServer.idleTimeout',
|
|
150
|
+
'embeddings install|--cuda': 'help.option.embeddings.install.cuda',
|
|
151
|
+
'embeddings install|--force': 'help.option.embeddings.install.force',
|
|
146
152
|
'group create|--force': 'help.option.group.create.force',
|
|
147
153
|
'group sync|--skip-embeddings': 'help.option.group.sync.skipEmbeddings',
|
|
148
154
|
'group sync|--exact-only': 'help.option.group.sync.exactOnly',
|