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.
Files changed (539) hide show
  1. package/README.md +211 -53
  2. package/dist/_shared/graph/types.d.ts +67 -3
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/index.js.map +1 -1
  7. package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
  8. package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
  9. package/dist/_shared/integrations/resilient-fetch.js +4 -3
  10. package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
  11. package/dist/_shared/language-detection.d.ts.map +1 -1
  12. package/dist/_shared/language-detection.js +2 -0
  13. package/dist/_shared/language-detection.js.map +1 -1
  14. package/dist/_shared/languages.d.ts +2 -0
  15. package/dist/_shared/languages.d.ts.map +1 -1
  16. package/dist/_shared/languages.js +2 -0
  17. package/dist/_shared/languages.js.map +1 -1
  18. package/dist/_shared/lbug/schema-constants.d.ts +2 -2
  19. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  20. package/dist/_shared/lbug/schema-constants.js +8 -0
  21. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  22. package/dist/_shared/pipeline.d.ts +1 -1
  23. package/dist/_shared/pipeline.d.ts.map +1 -1
  24. package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
  25. package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
  26. package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
  27. package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
  28. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +1 -1
  29. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
  30. package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
  31. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  32. package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
  33. package/dist/_shared/scope-resolution/language-classification.js +1 -0
  34. package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
  35. package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
  36. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  37. package/dist/_shared/scope-resolution/reference-site.d.ts +9 -1
  38. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
  39. package/dist/_shared/scope-resolution/types.d.ts +20 -3
  40. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  41. package/dist/cli/ai-context.d.ts +1 -1
  42. package/dist/cli/ai-context.js +25 -44
  43. package/dist/cli/analyze.d.ts +5 -2
  44. package/dist/cli/analyze.js +197 -11
  45. package/dist/cli/clean.js +17 -3
  46. package/dist/cli/cli-message.d.ts +1 -1
  47. package/dist/cli/doctor.d.ts +18 -0
  48. package/dist/cli/doctor.js +96 -5
  49. package/dist/cli/editor-targets.d.ts +17 -2
  50. package/dist/cli/editor-targets.js +44 -0
  51. package/dist/cli/embeddings.d.ts +12 -0
  52. package/dist/cli/embeddings.js +49 -0
  53. package/dist/cli/eval-server.d.ts +23 -1
  54. package/dist/cli/eval-server.js +126 -8
  55. package/dist/cli/help-i18n.js +6 -0
  56. package/dist/cli/i18n/en.d.ts +18 -8
  57. package/dist/cli/i18n/en.js +18 -8
  58. package/dist/cli/i18n/resources.d.ts +28 -8
  59. package/dist/cli/i18n/zh-CN.d.ts +10 -0
  60. package/dist/cli/i18n/zh-CN.js +18 -8
  61. package/dist/cli/index.js +21 -7
  62. package/dist/cli/lazy-action.d.ts +7 -0
  63. package/dist/cli/lazy-action.js +27 -0
  64. package/dist/cli/mcp.js +6 -3
  65. package/dist/cli/move-availability.d.ts +5 -0
  66. package/dist/cli/move-availability.js +11 -0
  67. package/dist/cli/setup.d.ts +8 -0
  68. package/dist/cli/setup.js +230 -32
  69. package/dist/cli/skill-gen.js +38 -18
  70. package/dist/cli/standard-skills.d.ts +76 -0
  71. package/dist/cli/standard-skills.js +45 -0
  72. package/dist/cli/status.d.ts +4 -1
  73. package/dist/cli/status.js +57 -4
  74. package/dist/cli/tool.js +11 -0
  75. package/dist/cli/uninstall.js +77 -18
  76. package/dist/cli/wiki.d.ts +1 -0
  77. package/dist/cli/wiki.js +7 -1
  78. package/dist/config/ignore-service.d.ts +2 -0
  79. package/dist/config/ignore-service.js +27 -0
  80. package/dist/core/analysis-features.d.ts +21 -0
  81. package/dist/core/analysis-features.js +59 -0
  82. package/dist/core/analyzer-identity.d.ts +74 -0
  83. package/dist/core/analyzer-identity.js +1820 -0
  84. package/dist/core/augmentation/engine.js +13 -8
  85. package/dist/core/embeddings/embedder.d.ts +3 -2
  86. package/dist/core/embeddings/embedder.js +24 -7
  87. package/dist/core/embeddings/embedding-identity.d.ts +11 -0
  88. package/dist/core/embeddings/embedding-identity.js +24 -0
  89. package/dist/core/embeddings/embedding-pipeline.d.ts +36 -1
  90. package/dist/core/embeddings/embedding-pipeline.js +100 -9
  91. package/dist/core/embeddings/http-client.d.ts +33 -3
  92. package/dist/core/embeddings/http-client.js +237 -25
  93. package/dist/core/embeddings/node-module-compat.d.ts +25 -0
  94. package/dist/core/embeddings/node-module-compat.js +25 -0
  95. package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
  96. package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
  97. package/dist/core/embeddings/runtime-install.d.ts +119 -0
  98. package/dist/core/embeddings/runtime-install.js +372 -0
  99. package/dist/core/embeddings/runtime-support.d.ts +48 -17
  100. package/dist/core/embeddings/runtime-support.js +96 -0
  101. package/dist/core/git-staleness.js +1 -1
  102. package/dist/core/group/bridge-db.js +2 -0
  103. package/dist/core/group/extractors/http-patterns/python.js +246 -108
  104. package/dist/core/group/extractors/manifest-extractor.js +4 -0
  105. package/dist/core/incremental/escalation-gate.d.ts +38 -0
  106. package/dist/core/incremental/escalation-gate.js +48 -0
  107. package/dist/core/incremental/shadow-candidates.d.ts +3 -3
  108. package/dist/core/incremental/shadow-candidates.js +3 -3
  109. package/dist/core/incremental/subgraph-extract.d.ts +2 -2
  110. package/dist/core/incremental/subgraph-extract.js +2 -2
  111. package/dist/core/index-freshness.d.ts +5 -0
  112. package/dist/core/index-freshness.js +13 -0
  113. package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
  114. package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
  115. package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
  116. package/dist/core/ingestion/cobol-processor.js +27 -26
  117. package/dist/core/ingestion/community-processor.d.ts +51 -1
  118. package/dist/core/ingestion/community-processor.js +323 -64
  119. package/dist/core/ingestion/emit-references.js +7 -2
  120. package/dist/core/ingestion/filesystem-walker.js +4 -0
  121. package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
  122. package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -0
  123. package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
  124. package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
  125. package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
  126. package/dist/core/ingestion/frameworks/spring/bean-catalog.js +26 -0
  127. package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
  128. package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
  129. package/dist/core/ingestion/languages/c/captures.js +56 -0
  130. package/dist/core/ingestion/languages/c/query.js +17 -0
  131. package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
  132. package/dist/core/ingestion/languages/cobol/captures.js +93 -0
  133. package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
  134. package/dist/core/ingestion/languages/cpp/captures.js +365 -75
  135. package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
  136. package/dist/core/ingestion/languages/csharp/captures.js +25 -0
  137. package/dist/core/ingestion/languages/dart/captures.js +90 -2
  138. package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
  139. package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
  140. package/dist/core/ingestion/languages/dart.js +2 -0
  141. package/dist/core/ingestion/languages/go/captures.js +34 -0
  142. package/dist/core/ingestion/languages/index.d.ts +1 -0
  143. package/dist/core/ingestion/languages/index.js +2 -0
  144. package/dist/core/ingestion/languages/java/analysis-features.d.ts +3 -0
  145. package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
  146. package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
  147. package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
  148. package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
  149. package/dist/core/ingestion/languages/java/captures.js +193 -17
  150. package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
  151. package/dist/core/ingestion/languages/java/package-facts.js +9 -0
  152. package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
  153. package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
  154. package/dist/core/ingestion/languages/java/query.js +23 -0
  155. package/dist/core/ingestion/languages/java/scope-resolver.js +23 -0
  156. package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
  157. package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
  158. package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
  159. package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
  160. package/dist/core/ingestion/languages/java.js +3 -0
  161. package/dist/core/ingestion/languages/javascript/captures.js +16 -0
  162. package/dist/core/ingestion/languages/javascript/query.js +21 -0
  163. package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
  164. package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
  165. package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
  166. package/dist/core/ingestion/languages/jvm/package-siblings.js +129 -0
  167. package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
  168. package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
  169. package/dist/core/ingestion/languages/kotlin/captures.js +59 -0
  170. package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
  171. package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
  172. package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
  173. package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
  174. package/dist/core/ingestion/languages/kotlin/query.js +19 -0
  175. package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
  176. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
  177. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
  178. package/dist/core/ingestion/languages/kotlin.js +5 -6
  179. package/dist/core/ingestion/languages/move.d.ts +1 -0
  180. package/dist/core/ingestion/languages/move.js +27 -0
  181. package/dist/core/ingestion/languages/php/captures.js +40 -0
  182. package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
  183. package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
  184. package/dist/core/ingestion/languages/php/import-target.js +110 -2
  185. package/dist/core/ingestion/languages/php/interpret.js +10 -0
  186. package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
  187. package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
  188. package/dist/core/ingestion/languages/python/captures.js +24 -5
  189. package/dist/core/ingestion/languages/python/interpret.js +4 -0
  190. package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
  191. package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
  192. package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
  193. package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
  194. package/dist/core/ingestion/languages/ruby/captures.js +42 -0
  195. package/dist/core/ingestion/languages/rust/captures.js +13 -0
  196. package/dist/core/ingestion/languages/rust/interpret.js +18 -0
  197. package/dist/core/ingestion/languages/rust/query.js +9 -0
  198. package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
  199. package/dist/core/ingestion/languages/swift/captures.js +12 -0
  200. package/dist/core/ingestion/languages/typescript/captures.js +21 -0
  201. package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
  202. package/dist/core/ingestion/languages/typescript/query.js +37 -0
  203. package/dist/core/ingestion/markdown-processor.js +3 -2
  204. package/dist/core/ingestion/model/registration-table.js +1 -0
  205. package/dist/core/ingestion/parsing-processor.d.ts +3 -1
  206. package/dist/core/ingestion/parsing-processor.js +36 -1
  207. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  208. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  209. package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
  210. package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
  211. package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
  212. package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
  213. package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
  214. package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
  215. package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
  216. package/dist/core/ingestion/pipeline-phases/standalone-ingest.d.ts +10 -0
  217. package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
  218. package/dist/core/ingestion/pipeline.d.ts +4 -2
  219. package/dist/core/ingestion/pipeline.js +5 -2
  220. package/dist/core/ingestion/resolve-references.js +12 -0
  221. package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
  222. package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
  223. package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
  224. package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
  225. package/dist/core/ingestion/scope-extractor.js +306 -43
  226. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
  227. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
  228. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
  229. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +3 -1
  230. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
  231. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
  232. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
  233. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
  234. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
  235. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
  236. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
  237. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
  238. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
  239. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
  240. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
  241. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
  242. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
  243. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
  244. package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
  245. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  246. package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
  247. package/dist/core/ingestion/taint/typescript-model.js +34 -2
  248. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  249. package/dist/core/ingestion/tree-sitter-queries.js +23 -2
  250. package/dist/core/ingestion/type-extractors/jvm.js +17 -2
  251. package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
  252. package/dist/core/ingestion/utils/ast-helpers.js +153 -2
  253. package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
  254. package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
  255. package/dist/core/ingestion/utils/line-base.d.ts +20 -0
  256. package/dist/core/ingestion/utils/line-base.js +20 -0
  257. package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
  258. package/dist/core/ingestion/utils/symbol-labels.js +45 -0
  259. package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
  260. package/dist/core/ingestion/workers/parse-worker.js +40 -5
  261. package/dist/core/ingestion/workers/result-merge.js +4 -0
  262. package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
  263. package/dist/core/ingestion/workers/worker-pool.js +128 -28
  264. package/dist/core/lbug/csv-generator.d.ts +15 -0
  265. package/dist/core/lbug/csv-generator.js +124 -27
  266. package/dist/core/lbug/cypher-escape.d.ts +20 -0
  267. package/dist/core/lbug/cypher-escape.js +20 -0
  268. package/dist/core/lbug/extension-load-error.d.ts +67 -0
  269. package/dist/core/lbug/extension-load-error.js +326 -0
  270. package/dist/core/lbug/extension-loader.d.ts +17 -2
  271. package/dist/core/lbug/extension-loader.js +38 -13
  272. package/dist/core/lbug/lbug-adapter.d.ts +203 -2
  273. package/dist/core/lbug/lbug-adapter.js +527 -86
  274. package/dist/core/lbug/lbug-config.d.ts +56 -2
  275. package/dist/core/lbug/lbug-config.js +267 -7
  276. package/dist/core/lbug/move-columns.d.ts +7 -0
  277. package/dist/core/lbug/move-columns.js +86 -0
  278. package/dist/core/lbug/native-check.d.ts +40 -0
  279. package/dist/core/lbug/native-check.js +90 -0
  280. package/dist/core/lbug/node-table-layout.d.ts +29 -0
  281. package/dist/core/lbug/node-table-layout.js +119 -0
  282. package/dist/core/lbug/pool-adapter.d.ts +23 -1
  283. package/dist/core/lbug/pool-adapter.js +115 -8
  284. package/dist/core/lbug/schema.d.ts +4 -3
  285. package/dist/core/lbug/schema.js +16 -16
  286. package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
  287. package/dist/core/lbug/sidecar-recovery.js +418 -16
  288. package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
  289. package/dist/core/move/artifact-download.d.ts +19 -0
  290. package/dist/core/move/artifact-download.js +179 -0
  291. package/dist/core/move/compiler-facts.d.ts +120 -0
  292. package/dist/core/move/compiler-facts.js +9 -0
  293. package/dist/core/move/consistency.d.ts +28 -0
  294. package/dist/core/move/consistency.js +98 -0
  295. package/dist/core/move/constants.d.ts +98 -0
  296. package/dist/core/move/constants.js +136 -0
  297. package/dist/core/move/discovery.d.ts +10 -0
  298. package/dist/core/move/discovery.js +22 -0
  299. package/dist/core/move/entry-points.d.ts +14 -0
  300. package/dist/core/move/entry-points.js +40 -0
  301. package/dist/core/move/facts-mapper.d.ts +75 -0
  302. package/dist/core/move/facts-mapper.js +534 -0
  303. package/dist/core/move/install-lock.d.ts +14 -0
  304. package/dist/core/move/install-lock.js +102 -0
  305. package/dist/core/move/install.d.ts +39 -0
  306. package/dist/core/move/install.js +391 -0
  307. package/dist/core/move/mcp-client.d.ts +115 -0
  308. package/dist/core/move/mcp-client.js +436 -0
  309. package/dist/core/move/move-ingest.d.ts +49 -0
  310. package/dist/core/move/move-ingest.js +320 -0
  311. package/dist/core/move/provision.d.ts +19 -0
  312. package/dist/core/move/provision.js +91 -0
  313. package/dist/core/move/release.d.ts +6 -0
  314. package/dist/core/move/release.js +10 -0
  315. package/dist/core/move/symbol-id.d.ts +35 -0
  316. package/dist/core/move/symbol-id.js +65 -0
  317. package/dist/core/move/type-parser.d.ts +11 -0
  318. package/dist/core/move/type-parser.js +38 -0
  319. package/dist/core/platform/capabilities.d.ts +0 -1
  320. package/dist/core/platform/capabilities.js +39 -8
  321. package/dist/core/run-analyze.d.ts +3 -3
  322. package/dist/core/run-analyze.js +1001 -184
  323. package/dist/core/search/fts-indexes.d.ts +31 -0
  324. package/dist/core/search/fts-indexes.js +73 -0
  325. package/dist/core/search/fts-schema.js +2 -0
  326. package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
  327. package/dist/core/tree-sitter/safe-parse.js +21 -7
  328. package/dist/core/wiki/graph-queries.js +6 -5
  329. package/dist/core/wiki/llm-client.d.ts +8 -2
  330. package/dist/core/wiki/llm-client.js +41 -5
  331. package/dist/mcp/core/embedder.js +16 -2
  332. package/dist/mcp/http-transport.d.ts +5 -0
  333. package/dist/mcp/http-transport.js +19 -5
  334. package/dist/mcp/local/bean-metadata.d.ts +2 -0
  335. package/dist/mcp/local/bean-metadata.js +25 -0
  336. package/dist/mcp/local/line-display.d.ts +22 -0
  337. package/dist/mcp/local/line-display.js +3 -0
  338. package/dist/mcp/local/local-backend.d.ts +19 -1
  339. package/dist/mcp/local/local-backend.js +402 -155
  340. package/dist/mcp/local/pdg-impact.d.ts +5 -3
  341. package/dist/mcp/local/pdg-impact.js +5 -2
  342. package/dist/mcp/output-budget.d.ts +5 -0
  343. package/dist/mcp/output-budget.js +52 -0
  344. package/dist/mcp/read-only-policy.d.ts +12 -0
  345. package/dist/mcp/read-only-policy.js +102 -0
  346. package/dist/mcp/repository-policy.d.ts +34 -0
  347. package/dist/mcp/repository-policy.js +328 -0
  348. package/dist/mcp/resources.js +32 -5
  349. package/dist/mcp/server.d.ts +5 -2
  350. package/dist/mcp/server.js +29 -9
  351. package/dist/mcp/tools.d.ts +0 -8
  352. package/dist/mcp/tools.js +102 -5
  353. package/dist/server/analyze-job.d.ts +3 -0
  354. package/dist/server/analyze-job.js +17 -0
  355. package/dist/server/analyze-launch.d.ts +6 -0
  356. package/dist/server/analyze-launch.js +82 -6
  357. package/dist/server/analyze-worker-core.d.ts +2 -1
  358. package/dist/server/analyze-worker-core.js +5 -2
  359. package/dist/server/analyze-worker.js +29 -6
  360. package/dist/server/api.d.ts +30 -0
  361. package/dist/server/api.js +120 -34
  362. package/dist/server/mcp-http.d.ts +1 -1
  363. package/dist/server/mcp-http.js +4 -2
  364. package/dist/server/upload-ingest.js +2 -1
  365. package/dist/server/validation.js +2 -1
  366. package/dist/storage/git.d.ts +31 -0
  367. package/dist/storage/git.js +111 -1
  368. package/dist/storage/parse-cache.js +7 -1
  369. package/dist/storage/parsedfile-store.d.ts +8 -0
  370. package/dist/storage/parsedfile-store.js +165 -1
  371. package/dist/storage/repo-manager.d.ts +194 -2
  372. package/dist/storage/repo-manager.js +56 -1
  373. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
  374. package/hooks/claude/gitnexus-hook.cjs +59 -9
  375. package/hooks/claude/pre-tool-use.sh +0 -0
  376. package/hooks/claude/session-start.sh +0 -0
  377. package/package.json +21 -15
  378. package/scripts/cross-platform-tests.ts +56 -0
  379. package/scripts/ensure-fts.ts +43 -0
  380. package/scripts/install-duckdb-extension.mjs +85 -24
  381. package/scripts/run-cross-platform.ts +61 -6
  382. package/scripts/shard-arg.ts +30 -0
  383. package/scripts/sync-plugin-manifests.mjs +192 -0
  384. package/skills/gitnexus-lfg/README.md +55 -0
  385. package/skills/gitnexus-lfg/SKILL.md +86 -0
  386. package/skills/gitnexus-plan/README.md +142 -0
  387. package/skills/gitnexus-plan/SKILL.md +348 -0
  388. package/skills/gitnexus-plan/references/context-ledger.md +137 -0
  389. package/skills/gitnexus-plan/references/context-pack.md +126 -0
  390. package/skills/gitnexus-plan/references/evidence-provenance.md +272 -0
  391. package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
  392. package/skills/gitnexus-plan/references/plan-template.md +201 -0
  393. package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2084 -0
  394. package/skills/gitnexus-review/SKILL.md +273 -0
  395. package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
  396. package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
  397. package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
  398. package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
  399. package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
  400. package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
  401. package/skills/gitnexus-work/README.md +71 -0
  402. package/skills/gitnexus-work/SKILL.md +269 -0
  403. package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
  404. package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
  405. package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
  406. package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
  407. package/web/assets/agent-Bqxn-abU.js +626 -0
  408. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
  409. package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
  410. package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
  411. package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
  412. package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
  413. package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
  414. package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
  415. package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
  416. package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
  417. package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
  418. package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
  419. package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
  420. package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
  421. package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
  422. package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
  423. package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
  424. package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
  425. package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
  426. package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
  427. package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
  428. package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
  429. package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
  430. package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
  431. package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
  432. package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
  433. package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
  434. package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
  435. package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
  436. package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
  437. package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
  438. package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
  439. package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
  440. package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
  441. package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
  442. package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
  443. package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
  444. package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
  445. package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
  446. package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
  447. package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
  448. package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
  449. package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
  450. package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
  451. package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
  452. package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
  453. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
  454. package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
  455. package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
  456. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
  457. package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
  458. package/web/assets/index-CX_fADmQ.css +2 -0
  459. package/web/assets/index-D1Z3dGGz.js +575 -0
  460. package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
  461. package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
  462. package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
  463. package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
  464. package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
  465. package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
  466. package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
  467. package/web/assets/node-Ct_zna8U.js +8 -0
  468. package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
  469. package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
  470. package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
  471. package/web/assets/preload-helper-Czpn1I53.js +1 -0
  472. package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
  473. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
  474. package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
  475. package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  476. package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
  477. package/web/assets/sdk-CzHHH8tD.js +37 -0
  478. package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
  479. package/web/assets/src-JV30wyV8.js +1 -0
  480. package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
  481. package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
  482. package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
  483. package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
  484. package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
  485. package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
  486. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
  487. package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
  488. package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
  489. package/web/index.html +18 -10
  490. package/skills/gitnexus-pr-review.md +0 -163
  491. package/web/assets/agent-Dli_x7bU.js +0 -660
  492. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
  493. package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
  494. package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
  495. package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
  496. package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
  497. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
  498. package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
  499. package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
  500. package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
  501. package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
  502. package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
  503. package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
  504. package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
  505. package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
  506. package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
  507. package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
  508. package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
  509. package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
  510. package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
  511. package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
  512. package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
  513. package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
  514. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
  515. package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
  516. package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
  517. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
  518. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
  519. package/web/assets/index-KctnI3Vq.js +0 -635
  520. package/web/assets/index-_lgn7hs5.css +0 -2
  521. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
  522. package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
  523. package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
  524. package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
  525. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
  526. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
  527. package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
  528. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
  529. package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
  530. package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
  531. package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
  532. package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
  533. package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
  534. package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
  535. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
  536. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
  537. package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
  538. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
  539. package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
@@ -14,13 +14,102 @@ import { CircuitOpenError, ResilientFetchExhaustedError, resilientFetch } from '
14
14
  const HTTP_TIMEOUT_MS = 30_000;
15
15
  const HTTP_MAX_RETRIES = 2;
16
16
  const HTTP_RETRY_BACKOFF_MS = 1_000;
17
+ const HTTP_RETRY_CAP_MS = 5_000;
17
18
  const HTTP_BATCH_SIZE = 64;
18
19
  const DEFAULT_DIMS = 384;
19
20
  const HTTP_BREAKER_KEY = 'embeddings-http';
21
+ let lastHttpRequestStartedAt;
22
+ let httpPaceQueue = Promise.resolve();
23
+ const parsePositiveIntegerEnv = (name, fallback, max) => {
24
+ const raw = process.env[name];
25
+ if (raw === undefined || raw === '')
26
+ return fallback;
27
+ if (!/^\d+$/u.test(raw)) {
28
+ throw new Error(`${name} must be a positive integer, got "${raw}"`);
29
+ }
30
+ const parsed = Number(raw);
31
+ if (!Number.isSafeInteger(parsed) || parsed <= 0 || parsed > max) {
32
+ throw new Error(`${name} must be a positive integer <= ${max}, got "${raw}"`);
33
+ }
34
+ return parsed;
35
+ };
36
+ const parseNonNegativeIntegerEnv = (name, fallback, max) => {
37
+ const raw = process.env[name];
38
+ if (raw === undefined || raw === '')
39
+ return fallback;
40
+ if (!/^\d+$/u.test(raw)) {
41
+ throw new Error(`${name} must be a non-negative integer, got "${raw}"`);
42
+ }
43
+ const parsed = Number(raw);
44
+ if (!Number.isSafeInteger(parsed) || parsed < 0 || parsed > max) {
45
+ throw new Error(`${name} must be a non-negative integer <= ${max}, got "${raw}"`);
46
+ }
47
+ return parsed;
48
+ };
49
+ const cancelledError = () => new DOMException('Embedding request cancelled', 'AbortError');
50
+ const throwIfAborted = (signal) => {
51
+ if (signal?.aborted)
52
+ throw cancelledError();
53
+ };
54
+ const abortableSleep = (ms, signal) => {
55
+ throwIfAborted(signal);
56
+ if (ms <= 0)
57
+ return Promise.resolve();
58
+ return new Promise((resolve, reject) => {
59
+ const timer = setTimeout(() => {
60
+ signal?.removeEventListener('abort', onAbort);
61
+ resolve();
62
+ }, ms);
63
+ const onAbort = () => {
64
+ clearTimeout(timer);
65
+ signal?.removeEventListener('abort', onAbort);
66
+ reject(cancelledError());
67
+ };
68
+ signal?.addEventListener('abort', onAbort, { once: true });
69
+ });
70
+ };
71
+ const paceHttpRequest = async (minIntervalMs, signal) => {
72
+ throwIfAborted(signal);
73
+ if (minIntervalMs <= 0)
74
+ return;
75
+ const waitTurn = httpPaceQueue.then(async () => {
76
+ throwIfAborted(signal);
77
+ const waitMs = lastHttpRequestStartedAt === undefined
78
+ ? 0
79
+ : Math.max(0, lastHttpRequestStartedAt + minIntervalMs - Date.now());
80
+ await abortableSleep(waitMs, signal);
81
+ throwIfAborted(signal);
82
+ lastHttpRequestStartedAt = Date.now();
83
+ });
84
+ httpPaceQueue = waitTurn.catch(() => undefined);
85
+ await waitTurn;
86
+ };
87
+ /**
88
+ * Stable lead of a {@link readConfig} malformed dims-env error. `readConfig`
89
+ * throws a plain `Error` (not an {@link HttpEmbeddingError}) for a malformed
90
+ * `GITNEXUS_EMBEDDING_DIMS` or `GITNEXUS_EMBEDDING_REQUEST_DIMS` because it's a
91
+ * *config* mistake, not an endpoint failure — so the CLI recognizes it by this
92
+ * lead ({@link isHttpEmbeddingDimsError}) and prints a clean config message
93
+ * instead of a raw stack dump. Each var names itself so the message points the
94
+ * operator at the variable they actually set, not a sibling. See #2385.
95
+ */
96
+ const dimsEnvErrorLead = (name) => `${name} must be a positive integer`;
97
+ const EMBEDDING_DIMS_ENV_ERROR_LEAD = dimsEnvErrorLead('GITNEXUS_EMBEDDING_DIMS');
98
+ const EMBEDDING_REQUEST_DIMS_ENV_ERROR_LEAD = dimsEnvErrorLead('GITNEXUS_EMBEDDING_REQUEST_DIMS');
99
+ /**
100
+ * @internal Exported for the CLI analyze error handler. True when `message` is a
101
+ * {@link readConfig} malformed dims-env config error (a plain `Error`) — for
102
+ * either `GITNEXUS_EMBEDDING_DIMS` or `GITNEXUS_EMBEDDING_REQUEST_DIMS`.
103
+ */
104
+ export const isHttpEmbeddingDimsError = (message) => message.includes(EMBEDDING_DIMS_ENV_ERROR_LEAD) ||
105
+ message.includes(EMBEDDING_REQUEST_DIMS_ENV_ERROR_LEAD);
20
106
  /**
21
107
  * Build config from the current process.env snapshot.
22
108
  * Returns null when GITNEXUS_EMBEDDING_URL + GITNEXUS_EMBEDDING_MODEL are unset.
23
109
  * Not cached — env vars are read fresh so late configuration takes effect.
110
+ * Validates GITNEXUS_EMBEDDING_DIMS and throws on a malformed value; callers
111
+ * that only need to know whether HTTP mode is *configured* must use
112
+ * {@link isHttpMode} (a presence probe that never throws), not this.
24
113
  */
25
114
  const readConfig = () => {
26
115
  const baseUrl = process.env.GITNEXUS_EMBEDDING_URL;
@@ -31,25 +120,52 @@ const readConfig = () => {
31
120
  let dimensions;
32
121
  if (rawDims !== undefined) {
33
122
  if (!/^\d+$/.test(rawDims)) {
34
- throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
123
+ throw new Error(`${EMBEDDING_DIMS_ENV_ERROR_LEAD}, got "${rawDims}"`);
35
124
  }
36
125
  const parsed = parseInt(rawDims, 10);
37
126
  if (parsed <= 0) {
38
- throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
127
+ throw new Error(`${EMBEDDING_DIMS_ENV_ERROR_LEAD}, got "${rawDims}"`);
39
128
  }
40
129
  dimensions = parsed;
41
130
  }
131
+ const rawRequestDims = process.env.GITNEXUS_EMBEDDING_REQUEST_DIMS?.trim();
132
+ let requestDimensions = dimensions;
133
+ if (rawRequestDims) {
134
+ if (/^(omit|none|off|false|0)$/i.test(rawRequestDims)) {
135
+ requestDimensions = undefined;
136
+ }
137
+ else {
138
+ if (!/^\d+$/.test(rawRequestDims)) {
139
+ throw new Error(`${EMBEDDING_REQUEST_DIMS_ENV_ERROR_LEAD}, got "${rawRequestDims}"`);
140
+ }
141
+ const parsed = parseInt(rawRequestDims, 10);
142
+ if (parsed <= 0) {
143
+ throw new Error(`${EMBEDDING_REQUEST_DIMS_ENV_ERROR_LEAD}, got "${rawRequestDims}"`);
144
+ }
145
+ requestDimensions = parsed;
146
+ }
147
+ }
42
148
  return {
43
149
  baseUrl: baseUrl.replace(/\/+$/, ''),
44
150
  model,
45
151
  apiKey: process.env.GITNEXUS_EMBEDDING_API_KEY ?? 'unused',
46
152
  dimensions,
153
+ maxAttempts: parsePositiveIntegerEnv('GITNEXUS_EMBEDDING_MAX_ATTEMPTS', HTTP_MAX_RETRIES + 1, 20),
154
+ retryCapMs: parsePositiveIntegerEnv('GITNEXUS_EMBEDDING_RETRY_CAP_MS', HTTP_RETRY_CAP_MS, 300_000),
155
+ minIntervalMs: parseNonNegativeIntegerEnv('GITNEXUS_EMBEDDING_MIN_INTERVAL_MS', 0, 300_000),
156
+ requestDimensions,
47
157
  };
48
158
  };
49
159
  /**
50
- * Check whether HTTP embedding mode is active (env vars are set).
160
+ * Whether HTTP embedding mode is active — i.e. both `GITNEXUS_EMBEDDING_URL` and
161
+ * `GITNEXUS_EMBEDDING_MODEL` are set. A pure presence probe: it deliberately does
162
+ * NOT call {@link readConfig}, so it never throws on a malformed
163
+ * `GITNEXUS_EMBEDDING_DIMS`. This lets its ~13 call sites (analyze, doctor,
164
+ * run-analyze, embedder, mcp) probe the mode without a defensive try/catch; the
165
+ * DIMS value is validated where it is actually used (`readConfig` in
166
+ * `httpEmbed`/`httpEmbedQuery`), surfacing a recognizable config error. See #2385.
51
167
  */
52
- export const isHttpMode = () => readConfig() !== null;
168
+ export const isHttpMode = () => Boolean(process.env.GITNEXUS_EMBEDDING_URL && process.env.GITNEXUS_EMBEDDING_MODEL);
53
169
  /**
54
170
  * Return the configured embedding dimensions for HTTP mode, or undefined
55
171
  * if HTTP mode is not active or no explicit dimensions are set.
@@ -70,6 +186,68 @@ export const safeUrl = (url) => {
70
186
  return '<invalid-url>';
71
187
  }
72
188
  };
189
+ /**
190
+ * Strip credentials from an underlying transport error message before it is
191
+ * surfaced. A credential-bearing endpoint URL (`https://user:secret@host/v1`)
192
+ * makes undici throw `TypeError: Request cannot be constructed from a URL that
193
+ * includes credentials: <that full URL>`; interpolating `err.message` verbatim
194
+ * would re-leak the secret to stderr + logs even though the URL argument is
195
+ * already masked with {@link safeUrl}. First swap the exact configured `url` for
196
+ * its masked form, then strip any residual `scheme://userinfo@` the transport may
197
+ * have echoed in a normalized (non-exact) form. See #2385.
198
+ */
199
+ const sanitizeReason = (reason, url, apiKey) => {
200
+ const withoutUrlCredentials = reason
201
+ .split(url)
202
+ .join(safeUrl(url))
203
+ .replace(/([a-z][a-z0-9+.-]*:\/\/)[^/@\s]*@/gi, '$1');
204
+ return apiKey && apiKey !== 'unused'
205
+ ? withoutUrlCredentials.split(apiKey).join('[redacted]')
206
+ : withoutUrlCredentials;
207
+ };
208
+ /**
209
+ * Error thrown by this module's HTTP embedding path (`httpEmbedBatch` /
210
+ * `httpEmbed` / `httpEmbedQuery`) for any endpoint failure — a
211
+ * connection/timeout/DNS error, an open circuit, a non-OK status, an
212
+ * unparseable or wrong-shape response body, an empty response, or a dimension
213
+ * mismatch.
214
+ *
215
+ * Carrying a distinct type (rather than a plain `Error`) lets the CLI tell a
216
+ * *custom endpoint* failure apart from a HuggingFace *model download* failure
217
+ * without matching message text: the two share the same underlying network
218
+ * substrings (`fetch failed`, `ECONNREFUSED`, …), which is exactly why
219
+ * `isNetworkFetchError` in `hf-env.ts` cannot tell them apart. Keying on the
220
+ * type instead of the message is also locale-proof and survives message
221
+ * rewording. The human-readable `.message` (built with `safeUrl` and the
222
+ * underlying reason) is what the CLI surfaces to the user. See #2385.
223
+ */
224
+ export class HttpEmbeddingError extends Error {
225
+ constructor(message, options) {
226
+ super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);
227
+ this.name = 'HttpEmbeddingError';
228
+ }
229
+ }
230
+ /**
231
+ * @internal Exported for the CLI analyze error handler and unit tests.
232
+ *
233
+ * Type-guard for {@link HttpEmbeddingError}. The `name` fallback keeps the
234
+ * check working across module-realm boundaries where `instanceof` can fail
235
+ * (two loaded copies of the class) — mirroring the codebase's existing
236
+ * `err.name === 'TimeoutError'` idiom. Matches on the stable class
237
+ * discriminator, never on the human-readable (potentially localized) message.
238
+ */
239
+ export const isHttpEmbeddingError = (err) => err instanceof HttpEmbeddingError || (err instanceof Error && err.name === 'HttpEmbeddingError');
240
+ /**
241
+ * Runtime guard for a single response item. The `Array.isArray(data.data)` shape
242
+ * check only validates the outer array — a 200 body like `{"data":[null]}` passes
243
+ * it, then crashes at `new Float32Array(item.embedding)` (`httpEmbed`) or
244
+ * `items[0].embedding` (`httpEmbedQuery`) with a raw `TypeError` that escapes the
245
+ * typed boundary, landing on the CLI's generic stack-dump path — the exact class
246
+ * #2385 closes. Validate each item so every wrong-shape body stays classifiable.
247
+ */
248
+ const isEmbeddingItem = (item) => typeof item === 'object' &&
249
+ item !== null &&
250
+ Array.isArray(item.embedding);
73
251
  /**
74
252
  * Send a single batch of texts to the embedding endpoint with retry.
75
253
  *
@@ -82,11 +260,11 @@ export const safeUrl = (url) => {
82
260
  * the `dimensions` field in the request body. Endpoints that implement
83
261
  * Matryoshka truncation (OpenAI text-embedding-3-*, Cohere embed-v3,
84
262
  * Voyage) return a truncated vector at that size; endpoints that do not
85
- * recognise the field may ignore it or return 400. Leave
86
- * `GITNEXUS_EMBEDDING_DIMS` unset for strict backends that reject
87
- * unknown fields.
263
+ * recognise the field may ignore it or return 400. Set
264
+ * `GITNEXUS_EMBEDDING_REQUEST_DIMS=omit` for strict backends while keeping
265
+ * `GITNEXUS_EMBEDDING_DIMS` set to the returned vector size.
88
266
  */
89
- const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensions) => {
267
+ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensions, requestOptions = {}, maxAttempts = HTTP_MAX_RETRIES + 1, retryCapMs = HTTP_RETRY_CAP_MS, minIntervalMs = 0) => {
90
268
  const requestBody = {
91
269
  input: batch,
92
270
  model,
@@ -96,38 +274,72 @@ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensi
96
274
  }
97
275
  let resp;
98
276
  try {
277
+ throwIfAborted(requestOptions.signal);
99
278
  resp = await resilientFetch(url, {
100
279
  method: 'POST',
101
- signal: AbortSignal.timeout(HTTP_TIMEOUT_MS),
102
280
  headers: {
103
281
  'Content-Type': 'application/json',
104
282
  Authorization: `Bearer ${apiKey}`,
105
283
  },
106
284
  body: JSON.stringify(requestBody),
107
285
  }, {
286
+ fetchImpl: async (input, init) => {
287
+ await paceHttpRequest(minIntervalMs, requestOptions.signal);
288
+ throwIfAborted(requestOptions.signal);
289
+ const timeoutSignal = AbortSignal.timeout(HTTP_TIMEOUT_MS);
290
+ const signal = requestOptions.signal
291
+ ? AbortSignal.any([requestOptions.signal, timeoutSignal])
292
+ : timeoutSignal;
293
+ return globalThis.fetch(input, { ...init, signal });
294
+ },
108
295
  breakerKey: HTTP_BREAKER_KEY,
109
- retry: { maxAttempts: HTTP_MAX_RETRIES + 1, baseDelayMs: HTTP_RETRY_BACKOFF_MS },
296
+ retry: {
297
+ maxAttempts,
298
+ baseDelayMs: HTTP_RETRY_BACKOFF_MS,
299
+ capDelayMs: retryCapMs,
300
+ retryAfterCapMs: retryCapMs,
301
+ sleep: (ms) => abortableSleep(ms, requestOptions.signal),
302
+ },
110
303
  });
111
304
  }
112
305
  catch (err) {
306
+ if (requestOptions.signal?.aborted ||
307
+ (err instanceof DOMException && err.name === 'AbortError')) {
308
+ throw new HttpEmbeddingError(`Embedding request cancelled (${safeUrl(url)}, batch ${batchIndex})`, { cause: err });
309
+ }
113
310
  if (err instanceof CircuitOpenError) {
114
- throw new Error(`Embedding endpoint circuit open (${safeUrl(url)}, batch ${batchIndex}): retry in ${Math.ceil(err.retryAfterMs / 1000)}s`);
311
+ throw new HttpEmbeddingError(`Embedding endpoint circuit open (${safeUrl(url)}, batch ${batchIndex}): retry in ${Math.ceil(err.retryAfterMs / 1000)}s`, { cause: err });
115
312
  }
116
313
  if (err instanceof DOMException && err.name === 'TimeoutError') {
117
- throw new Error(`Embedding request timed out after ${HTTP_TIMEOUT_MS}ms (${safeUrl(url)}, batch ${batchIndex})`);
314
+ throw new HttpEmbeddingError(`Embedding request timed out after ${HTTP_TIMEOUT_MS}ms (${safeUrl(url)}, batch ${batchIndex})`, { cause: err });
118
315
  }
119
316
  if (err instanceof ResilientFetchExhaustedError) {
120
- throw new Error(`Embedding endpoint returned ${err.response.status} (${safeUrl(url)}, batch ${batchIndex})`);
317
+ throw new HttpEmbeddingError(`Embedding endpoint returned ${err.response.status} (${safeUrl(url)}, batch ${batchIndex})`, { cause: err });
121
318
  }
122
- const reason = err instanceof Error ? err.message : String(err);
123
- throw new Error(`Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason}`);
319
+ const reason = sanitizeReason(err instanceof Error ? err.message : String(err), url, apiKey);
320
+ const safeCause = new Error(reason);
321
+ safeCause.name = err instanceof Error ? err.name : 'EmbeddingTransportError';
322
+ throw new HttpEmbeddingError(`Embedding request failed (${safeUrl(url)}, batch ${batchIndex}): ${reason}`, { cause: safeCause });
124
323
  }
125
324
  if (!resp.ok) {
126
325
  // resilientFetch already retried 5xx/429; any non-OK response here is
127
326
  // a terminal client error (4xx other than 429).
128
- throw new Error(`Embedding endpoint returned ${resp.status} (${safeUrl(url)}, batch ${batchIndex})`);
327
+ throw new HttpEmbeddingError(`Embedding endpoint returned ${resp.status} (${safeUrl(url)}, batch ${batchIndex})`);
328
+ }
329
+ // A reachable-but-wrong endpoint (e.g. a captive portal or a non-embeddings
330
+ // service) can answer 200 with an HTML/truncated body. Parse inside the
331
+ // typed-error boundary so that lands as an endpoint failure the CLI can
332
+ // classify, not a raw SyntaxError/TypeError on the generic stack-dump path.
333
+ let data;
334
+ try {
335
+ data = (await resp.json());
336
+ }
337
+ catch (err) {
338
+ throw new HttpEmbeddingError(`Embedding endpoint returned an unparseable response (${safeUrl(url)}, batch ${batchIndex})`, { cause: err });
339
+ }
340
+ if (!Array.isArray(data?.data) || !data.data.every(isEmbeddingItem)) {
341
+ throw new HttpEmbeddingError(`Embedding endpoint returned an unexpected response shape (${safeUrl(url)}, batch ${batchIndex})`);
129
342
  }
130
- const data = (await resp.json());
131
343
  return data.data;
132
344
  };
133
345
  /**
@@ -137,7 +349,7 @@ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensi
137
349
  * @param texts - Array of texts to embed
138
350
  * @returns Array of Float32Array embedding vectors
139
351
  */
140
- export const httpEmbed = async (texts) => {
352
+ export const httpEmbed = async (texts, requestOptions = {}) => {
141
353
  if (texts.length === 0)
142
354
  return [];
143
355
  const config = readConfig();
@@ -148,9 +360,9 @@ export const httpEmbed = async (texts) => {
148
360
  for (let i = 0; i < texts.length; i += HTTP_BATCH_SIZE) {
149
361
  const batch = texts.slice(i, i + HTTP_BATCH_SIZE);
150
362
  const batchIndex = Math.floor(i / HTTP_BATCH_SIZE);
151
- const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex, config.dimensions);
363
+ const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex, config.requestDimensions, requestOptions, config.maxAttempts, config.retryCapMs, config.minIntervalMs);
152
364
  if (items.length !== batch.length) {
153
- throw new Error(`Embedding endpoint returned ${items.length} vectors for ${batch.length} texts ` +
365
+ throw new HttpEmbeddingError(`Embedding endpoint returned ${items.length} vectors for ${batch.length} texts ` +
154
366
  `(${safeUrl(url)}, batch ${batchIndex})`);
155
367
  }
156
368
  for (const item of items) {
@@ -162,7 +374,7 @@ export const httpEmbed = async (texts) => {
162
374
  const hint = config.dimensions
163
375
  ? 'Update GITNEXUS_EMBEDDING_DIMS to match your model output.'
164
376
  : `Set GITNEXUS_EMBEDDING_DIMS=${vec.length} to match your model output.`;
165
- throw new Error(`Embedding dimension mismatch: endpoint returned ${vec.length}d vector, ` +
377
+ throw new HttpEmbeddingError(`Embedding dimension mismatch: endpoint returned ${vec.length}d vector, ` +
166
378
  `but expected ${expected}d. ${hint}`);
167
379
  }
168
380
  allVectors.push(vec);
@@ -177,14 +389,14 @@ export const httpEmbed = async (texts) => {
177
389
  * @param text - Query text to embed
178
390
  * @returns Embedding vector as number array
179
391
  */
180
- export const httpEmbedQuery = async (text) => {
392
+ export const httpEmbedQuery = async (text, requestOptions = {}) => {
181
393
  const config = readConfig();
182
394
  if (!config)
183
395
  throw new Error('HTTP embedding not configured');
184
396
  const url = `${config.baseUrl}/embeddings`;
185
- const items = await httpEmbedBatch(url, [text], config.model, config.apiKey, 0, config.dimensions);
397
+ const items = await httpEmbedBatch(url, [text], config.model, config.apiKey, 0, config.requestDimensions, requestOptions, config.maxAttempts, config.retryCapMs, config.minIntervalMs);
186
398
  if (!items.length) {
187
- throw new Error(`Embedding endpoint returned empty response (${safeUrl(url)})`);
399
+ throw new HttpEmbeddingError(`Embedding endpoint returned empty response (${safeUrl(url)})`);
188
400
  }
189
401
  const embedding = items[0].embedding;
190
402
  // Same dimension checks as httpEmbed — catch mismatches before they
@@ -194,7 +406,7 @@ export const httpEmbedQuery = async (text) => {
194
406
  const hint = config.dimensions
195
407
  ? 'Update GITNEXUS_EMBEDDING_DIMS to match your model output.'
196
408
  : `Set GITNEXUS_EMBEDDING_DIMS=${embedding.length} to match your model output.`;
197
- throw new Error(`Embedding dimension mismatch: endpoint returned ${embedding.length}d vector, ` +
409
+ throw new HttpEmbeddingError(`Embedding dimension mismatch: endpoint returned ${embedding.length}d vector, ` +
198
410
  `but expected ${expected}d. ${hint}`);
199
411
  }
200
412
  return embedding;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The single access point for `module.registerHooks` (#2372).
3
+ *
4
+ * `module.registerHooks` — the synchronous ESM/CJS resolution-hook API the
5
+ * embedding-stack resolvers rely on — was added in Node 22.15.0 (and 23.5.0 on
6
+ * the 23.x line). The gitnexus engines floor is `^22.18.0 || >=24.11.0`, so
7
+ * every supported runtime exposes it — but `engines` is advisory (not
8
+ * engine-strict), so a below-floor Node (22.0–22.14, or the unsupported
9
+ * 23.0–23.4 line) can still run, where the export is absent.
10
+ *
11
+ * In this `"type": "module"` package, a *static named* import of a missing
12
+ * builtin export (`import { registerHooks } from 'node:module'`) is a
13
+ * `SyntaxError` at ESM link time — thrown before any `typeof registerHooks`
14
+ * guard in the module body can run, so every module carrying that import fails
15
+ * to load on those Node versions. This module owns the only namespace import of
16
+ * `node:module` and hands callers a value-or-`undefined` they guard at runtime,
17
+ * so the graceful-degradation path is finally reachable.
18
+ *
19
+ * `@types/node` types `registerHooks` as always-present, so `nodeModule.registerHooks`
20
+ * would type as defined while being `undefined` at runtime on older Node. The
21
+ * `Partial` narrow surfaces the real optionality without an `any` cast.
22
+ */
23
+ import * as nodeModule from 'node:module';
24
+ /** `module.registerHooks` if this Node exposes it (>=22.15 / >=23.5), else `undefined`. */
25
+ export declare const getRegisterHooks: () => typeof nodeModule.registerHooks | undefined;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The single access point for `module.registerHooks` (#2372).
3
+ *
4
+ * `module.registerHooks` — the synchronous ESM/CJS resolution-hook API the
5
+ * embedding-stack resolvers rely on — was added in Node 22.15.0 (and 23.5.0 on
6
+ * the 23.x line). The gitnexus engines floor is `^22.18.0 || >=24.11.0`, so
7
+ * every supported runtime exposes it — but `engines` is advisory (not
8
+ * engine-strict), so a below-floor Node (22.0–22.14, or the unsupported
9
+ * 23.0–23.4 line) can still run, where the export is absent.
10
+ *
11
+ * In this `"type": "module"` package, a *static named* import of a missing
12
+ * builtin export (`import { registerHooks } from 'node:module'`) is a
13
+ * `SyntaxError` at ESM link time — thrown before any `typeof registerHooks`
14
+ * guard in the module body can run, so every module carrying that import fails
15
+ * to load on those Node versions. This module owns the only namespace import of
16
+ * `node:module` and hands callers a value-or-`undefined` they guard at runtime,
17
+ * so the graceful-degradation path is finally reachable.
18
+ *
19
+ * `@types/node` types `registerHooks` as always-present, so `nodeModule.registerHooks`
20
+ * would type as defined while being `undefined` at runtime on older Node. The
21
+ * `Partial` narrow surfaces the real optionality without an `any` cast.
22
+ */
23
+ import * as nodeModule from 'node:module';
24
+ /** `module.registerHooks` if this Node exposes it (>=22.15 / >=23.5), else `undefined`. */
25
+ export const getRegisterHooks = () => nodeModule.registerHooks;
@@ -52,16 +52,17 @@
52
52
  * per-resolution cost is a single string comparison.
53
53
  *
54
54
  * `module.registerHooks` is marked `@experimental` and requires Node >= 22.15
55
- * (the gitnexus engines floor is >= 22.0.0). On older runtimes it is absent and
56
- * this is a graceful no-op: embeddings then resolve onnxruntime-common exactly
55
+ * (below the gitnexus engines floor of `^22.18.0 || >=24.11.0`). On below-floor
56
+ * runtimes it is absent and this is a graceful no-op: embeddings then resolve onnxruntime-common exactly
57
57
  * as before — fine on hoisted layouts. Any failure during installation is
58
58
  * swallowed.
59
59
  */
60
- import { registerHooks, createRequire } from 'node:module';
60
+ import { createRequire } from 'node:module';
61
61
  import { pathToFileURL } from 'node:url';
62
62
  import { join } from 'node:path';
63
63
  import { getEffectiveOnnxRuntimeNodeDir } from './onnxruntime-node-resolver.js';
64
64
  import { logger } from '../logger.js';
65
+ import { getRegisterHooks } from './node-module-compat.js';
65
66
  let attempted = false;
66
67
  /**
67
68
  * Compute the file: URL the hook redirects `onnxruntime-common` to.
@@ -98,8 +99,10 @@ export const ensureOnnxRuntimeCommonResolvable = () => {
98
99
  // initEmbedder() call, and the hook is process-global — once is enough.
99
100
  attempted = true;
100
101
  try {
101
- // Node < 22.15 (the gitnexus engines floor is >= 22.0.0): no synchronous
102
- // hooks API. Degrade gracefully — the import still works on hoisted layouts.
102
+ // Node < 22.15 / < 23.5 (below the gitnexus engines floor of
103
+ // ^22.18.0 || >=24.11.0): no synchronous hooks API. Degrade gracefully —
104
+ // the import still works on hoisted layouts.
105
+ const registerHooks = getRegisterHooks();
103
106
  if (typeof registerHooks !== 'function')
104
107
  return;
105
108
  const redirectUrl = resolveOnnxRuntimeCommonUrl();
@@ -36,8 +36,8 @@
36
36
  * So CUDA-12 hosts, Windows (DirectML), macOS, and CPU-only hosts are
37
37
  * untouched. Idempotent; any failure is swallowed and leaves the default
38
38
  * resolution exactly as before. `module.registerHooks` requires Node >= 22.15
39
- * (the gitnexus engines floor is >= 22.0.0); on older runtimes the redirect is
40
- * a no-op, but the default copy's CUDA major is still probed so an
39
+ * (below the gitnexus engines floor of `^22.18.0 || >=24.11.0`); on below-floor
40
+ * runtimes the redirect is a no-op, but the default copy's CUDA major is still probed so an
41
41
  * already-matching host (e.g. CUDA 12 + transformers' CUDA-12 build) keeps
42
42
  * auto-selecting the GPU.
43
43
  * `npm link` / symlinked local-dev checkouts are a known caveat: `resolveOurOrtNodeDir`/
@@ -51,12 +51,14 @@
51
51
  * loaded (the probe uses CJS `require.resolve`, which an ESM hook does not
52
52
  * affect) — keeping probe and runtime consistent.
53
53
  */
54
- import { registerHooks, createRequire } from 'node:module';
54
+ import { createRequire } from 'node:module';
55
55
  import { pathToFileURL } from 'node:url';
56
56
  import { existsSync } from 'node:fs';
57
57
  import { join, dirname } from 'node:path';
58
58
  import { execFileSync } from 'node:child_process';
59
59
  import { logger } from '../logger.js';
60
+ import { getEmbeddingRuntimeDir } from './runtime-install.js';
61
+ import { getRegisterHooks } from './node-module-compat.js';
60
62
  const require = createRequire(import.meta.url);
61
63
  /**
62
64
  * Read a shared object's NEEDED entries, tolerating ldd's non-zero exit when a
@@ -152,7 +154,18 @@ const resolveDefaultOrtNodeDir = () => {
152
154
  return dirname(createRequire(transformersMain).resolve('onnxruntime-node/package.json'));
153
155
  }
154
156
  catch {
155
- return null;
157
+ // On-demand runtime prefix (#2370): when the optional stack was pruned at
158
+ // install time and fetched on demand, the copy that actually loads (via
159
+ // ensureEmbeddingStackResolvable's fallback hook) lives in the prefix — so
160
+ // it IS the effective default and must be the one the CUDA probe inspects.
161
+ try {
162
+ const prefixRequire = createRequire(join(getEmbeddingRuntimeDir(), 'noop.js'));
163
+ const transformersMain = prefixRequire.resolve('@huggingface/transformers');
164
+ return dirname(createRequire(transformersMain).resolve('onnxruntime-node/package.json'));
165
+ }
166
+ catch {
167
+ return null;
168
+ }
156
169
  }
157
170
  };
158
171
  /** gitnexus' own direct top-level onnxruntime-node dir. */
@@ -161,7 +174,19 @@ const resolveOurOrtNodeDir = () => {
161
174
  return dirname(require.resolve('onnxruntime-node/package.json'));
162
175
  }
163
176
  catch {
164
- return null;
177
+ // On-demand runtime prefix (#2370): when gitnexus' own onnxruntime-node was
178
+ // pruned at install time and fetched on demand, the prefix copy IS our
179
+ // effective top-level build — so the CUDA-major redirect must be able to
180
+ // target it (mirrors resolveDefaultOrtNodeDir's fallback above). Without
181
+ // this, `embeddings install --cuda` on a pruned install downloads the GPU
182
+ // binaries but the probe still can't see them and embeddings run on CPU.
183
+ try {
184
+ const prefixRequire = createRequire(join(getEmbeddingRuntimeDir(), 'noop.js'));
185
+ return dirname(prefixRequire.resolve('onnxruntime-node/package.json'));
186
+ }
187
+ catch {
188
+ return null;
189
+ }
165
190
  }
166
191
  };
167
192
  let cached = null;
@@ -176,7 +201,7 @@ const decide = () => {
176
201
  // major is still probed: a CUDA-12 host on Node 22.0–22.14 whose default
177
202
  // build already matches must keep auto-selecting the GPU exactly as it did
178
203
  // before this redirect existed.
179
- const canRedirect = typeof registerHooks === 'function';
204
+ const canRedirect = typeof getRegisterHooks() === 'function';
180
205
  const systemMajor = detectSystemCudaMajor();
181
206
  // `defaultDir` resolving is NOT a precondition for checking `ourDir` below —
182
207
  // if transformers' own resolution fails outright (defaultMajor stays null),
@@ -264,8 +289,9 @@ export const ensureOnnxRuntimeNodeMatchesSystem = () => {
264
289
  return;
265
290
  attempted = true;
266
291
  try {
292
+ const registerHooks = getRegisterHooks();
267
293
  if (typeof registerHooks !== 'function')
268
- return; // Node < 22.15: graceful no-op
294
+ return; // Node < 22.15 / < 23.5: graceful no-op
269
295
  const d = decide();
270
296
  if (!d.redirect || !d.effectiveDir)
271
297
  return;