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
package/dist/cli/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // Removing it from here improves MCP server startup time significantly.
4
4
  import { Command } from 'commander';
5
5
  import { createRequire } from 'node:module';
6
- import { createLazyAction, createLbugLazyAction } from './lazy-action.js';
6
+ import { createAnalyzerLbugLazyAction, createLazyAction, createLbugLazyAction, } from './lazy-action.js';
7
7
  import { EMBEDDING_DIMS_ERROR, normalizeEmbeddingDims } from './embedding-dims.js';
8
8
  import { registerGroupCommands } from './group.js';
9
9
  import { localizeCliHelp } from './help-i18n.js';
@@ -17,7 +17,7 @@ function collectCodingAgents(value, previous) {
17
17
  program.name('gitnexus').description('GitNexus local CLI and MCP server').version(pkg.version);
18
18
  program
19
19
  .command('setup')
20
- .description('One-time setup: configure MCP for Cursor, Claude Code, Antigravity, OpenCode, Codex')
20
+ .description('One-time setup: configure MCP for Cursor, Claude Code, Antigravity, OpenCode, CodeBuddy, Qoder, Codex')
21
21
  .option('-c, --coding-agent <agents>', 'Configure only these coding agents (comma-separated or repeatable)', collectCodingAgents)
22
22
  .action(createLazyAction(() => import('./setup.js'), 'setupCommand'));
23
23
  program
@@ -53,8 +53,8 @@ program
53
53
  'Without this flag, analyze always updates the workspace index, which follows the ' +
54
54
  'checked-out working tree. Distinct from --default-branch (cosmetic base_ref).')
55
55
  .option('--no-stats', 'Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md')
56
- .option('--skip-skills', 'Skip installing standard GitNexus skill files under .claude/skills/gitnexus/. ' +
57
- 'Does not suppress community skills from --skills (those use .claude/skills/generated/). ' +
56
+ .option('--skip-skills', 'Skip installing standard GitNexus skill files directly under .claude/skills/. ' +
57
+ 'Does not suppress community skills from --skills (those use .claude/skills/gitnexus-area-*). ' +
58
58
  'Use --index-only to skip all AI-context file injection.')
59
59
  .option('--index-only', 'Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)')
60
60
  .option('--skip-git', 'Treat the provided path/cwd as the index root and skip parent git-root discovery')
@@ -119,7 +119,7 @@ program
119
119
  process.env.GITNEXUS_EMBEDDING_DIMS = dimsEnvBaseline;
120
120
  }
121
121
  })
122
- .action(createLbugLazyAction(() => import('./analyze.js'), 'analyzeCommand'));
122
+ .action(createAnalyzerLbugLazyAction(() => import('../core/analyzer-identity.js'), () => import('./analyze.js'), 'analyzeCommandWithRunnerIdentity', import.meta.url));
123
123
  program
124
124
  .command('index [path...]')
125
125
  .description('Register an existing .gitnexus/ folder into the global registry (no re-analysis needed)')
@@ -148,18 +148,31 @@ program
148
148
  program
149
149
  .command('status')
150
150
  .description('Show index status for current repo')
151
+ .option('--json', 'Emit machine-readable index and analyzer provenance')
152
+ .addHelpText('after', () => t('help.identityCache.environment'))
151
153
  .action(createLazyAction(() => import('./status.js'), 'statusCommand'));
152
154
  program
153
155
  .command('doctor')
154
156
  .description('Show runtime platform capabilities and embedding configuration')
155
157
  .action(createLazyAction(() => import('./doctor.js'), 'doctorCommand'));
158
+ program
159
+ .command('embeddings')
160
+ .description('Manage the on-demand local embedding runtime')
161
+ .command('install')
162
+ .description('Install the local embedding stack (@huggingface/transformers + onnxruntime-node) on demand. ' +
163
+ 'Heals installs where npm skipped the optional packages (e.g. behind an HTTP proxy, #2370). ' +
164
+ 'Downloads only from your configured npm registry — mirrors and proxies apply.')
165
+ .option('--cuda', "Also download the CUDA GPU binaries (runs onnxruntime-node's NuGet postinstall; " +
166
+ 'set GLOBAL_AGENT_HTTPS_PROXY behind a proxy)')
167
+ .option('--force', 'Install into the runtime prefix even when the stack already resolves')
168
+ .action(createLazyAction(() => import('./embeddings.js'), 'embeddingsInstallCommand'));
156
169
  program
157
170
  .command('clean')
158
171
  .description('Delete GitNexus index for current repo')
159
172
  .option('-f, --force', 'Skip confirmation prompt')
160
173
  .option('--all', 'Clean all indexed repos')
161
174
  .option('--branch <name>', 'Delete only the named branch index (not the workspace index)')
162
- .option('--lbug-sidecars', 'Clean quarantined LadybugDB missing-shadow WAL sidecars')
175
+ .option('--lbug-sidecars', 'Clean parked LadybugDB recovery sidecars (missing-shadow WAL quarantines and dirty-recovery parks)')
163
176
  .action(createLazyAction(() => import('./clean.js'), 'cleanCommand'));
164
177
  program
165
178
  .command('remove <target>')
@@ -181,6 +194,7 @@ program
181
194
  .option('--concurrency <n>', 'Parallel LLM calls (default: 3)', '3')
182
195
  .option('--timeout <seconds>', 'LLM request timeout in seconds (default: disabled)')
183
196
  .option('--retries <n>', 'Max LLM retry attempts per request (default: 3)')
197
+ .option('--allow-insecure-connection <host>', 'Allow exact host(s) for http:// LLM base URLs (comma-separated; HTTPS is preferred)')
184
198
  .option('--gist', 'Publish wiki as a public GitHub Gist after generation')
185
199
  .option('-v, --verbose', 'Enable verbose output (show LLM commands and responses)')
186
200
  .option('--review', 'Stop after grouping to review module structure before generating pages')
@@ -281,7 +295,7 @@ program
281
295
  .command('eval-server')
282
296
  .description('Start lightweight HTTP server for fast tool calls during evaluation')
283
297
  .option('-p, --port <port>', 'Port number', '4848')
284
- .option('--host <host>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 to expose to all interfaces)')
298
+ .option('--host <host>', 'Bind address or resolvable hostname (default: 127.0.0.1; non-loopback requires GITNEXUS_AUTH_TOKEN; hostnames resolve to IPv4)')
285
299
  .option('--idle-timeout <seconds>', 'Auto-shutdown after N seconds idle (0 = disabled)', '0')
286
300
  .action(createLbugLazyAction(() => import('./eval-server.js'), 'evalServerCommand'));
287
301
  registerGroupCommands(program);
@@ -5,3 +5,10 @@
5
5
  */
6
6
  export declare function createLazyAction<TModule extends Record<string, unknown>, TKey extends string & keyof TModule>(loader: () => Promise<TModule>, exportName: TKey): (...args: unknown[]) => Promise<void>;
7
7
  export declare function createLbugLazyAction<TModule extends Record<string, unknown>, TKey extends string & keyof TModule>(loader: () => Promise<TModule>, exportName: TKey): (...args: unknown[]) => Promise<void>;
8
+ /**
9
+ * Analyze-specific lazy action. Unlike the generic LadybugDB wrapper, this
10
+ * captures the complete analyzer receipt before probing/loading native code or
11
+ * evaluating the analyzer module graph. The target export receives that start
12
+ * receipt as its first argument and threads it to runFullAnalysis.
13
+ */
14
+ export declare function createAnalyzerLbugLazyAction<TModule extends Record<string, unknown>, TKey extends string & keyof TModule>(identityLoader: () => Promise<Pick<typeof import('../core/analyzer-identity.js'), 'captureAnalyzerIdentityBeforeLoad'>>, loader: () => Promise<TModule>, exportName: TKey, analyzerModuleUrl: string): (...args: unknown[]) => Promise<void>;
@@ -33,3 +33,30 @@ export function createLbugLazyAction(loader, exportName) {
33
33
  await action(...args);
34
34
  };
35
35
  }
36
+ /**
37
+ * Analyze-specific lazy action. Unlike the generic LadybugDB wrapper, this
38
+ * captures the complete analyzer receipt before probing/loading native code or
39
+ * evaluating the analyzer module graph. The target export receives that start
40
+ * receipt as its first argument and threads it to runFullAnalysis.
41
+ */
42
+ export function createAnalyzerLbugLazyAction(identityLoader, loader, exportName, analyzerModuleUrl) {
43
+ return async (...args) => {
44
+ const identityModule = await identityLoader();
45
+ const prepared = await identityModule.captureAnalyzerIdentityBeforeLoad(analyzerModuleUrl, async () => {
46
+ const check = checkLbugNative();
47
+ if (!check.ok)
48
+ return { check, module: null };
49
+ return { check, module: await loader() };
50
+ });
51
+ if (!prepared.loaded.check.ok) {
52
+ process.stderr.write(`\n ${prepared.loaded.check.message?.replace(/\n/g, '\n ')}\n\n`);
53
+ process.exitCode = 1;
54
+ return;
55
+ }
56
+ const action = prepared.loaded.module?.[exportName];
57
+ if (!isCallable(action)) {
58
+ throw new Error(`Lazy action export not found: ${exportName}`);
59
+ }
60
+ await action(prepared.runnerIdentity, ...args);
61
+ };
62
+ }
package/dist/cli/mcp.js CHANGED
@@ -44,10 +44,11 @@ export const mcpCommand = async (options) => {
44
44
  // stdout at module init, but transitive deps (pino, pino-pretty, the
45
45
  // worker-thread transport) could in theory, and the import-closure
46
46
  // regression test enforces the leaf invariant.
47
- const [{ startMCPServer }, { LocalBackend }, { logger }] = await Promise.all([
47
+ const [{ startMCPServer }, { LocalBackend }, { logger }, { createMcpRepositoryPolicy }] = await Promise.all([
48
48
  import('../mcp/server.js'),
49
49
  import('../mcp/local/local-backend.js'),
50
50
  import('../core/logger.js'),
51
+ import('../mcp/repository-policy.js'),
51
52
  ]);
52
53
  // Missing-optional-grammar warnings are intentionally NOT emitted here.
53
54
  // `gitnexus analyze` already warns at index time, filtered by the repo's
@@ -59,7 +60,8 @@ export const mcpCommand = async (options) => {
59
60
  // so repos indexed after the server starts are discovered automatically.
60
61
  const backend = new LocalBackend();
61
62
  await backend.init();
62
- const repos = await backend.listRepos();
63
+ const repositoryPolicy = await createMcpRepositoryPolicy(backend);
64
+ const repos = await repositoryPolicy.scopeBackend(backend).listRepos();
63
65
  if (repos.length === 0) {
64
66
  // Operator-actionable but the server still starts and serves; warn-level,
65
67
  // not error. Tools will discover newly-analyzed repos via lazy refresh.
@@ -85,6 +87,7 @@ export const mcpCommand = async (options) => {
85
87
  port,
86
88
  host: options.host ?? '127.0.0.1',
87
89
  authToken: resolveAuthToken(options.authToken, process.env),
90
+ repositoryPolicy,
88
91
  });
89
92
  }
90
93
  catch (err) {
@@ -94,5 +97,5 @@ export const mcpCommand = async (options) => {
94
97
  return;
95
98
  }
96
99
  // Start MCP server (serves all repos, discovers new ones lazily)
97
- await startMCPServer(backend);
100
+ await startMCPServer(backend, repositoryPolicy);
98
101
  };
@@ -0,0 +1,5 @@
1
+ /** Warn once if a repo has Move sources but no usable move-flow binary is reachable. */
2
+ export declare function warnIfMoveUnavailable(opts: {
3
+ repoHasMove: boolean;
4
+ context?: string;
5
+ }): void;
@@ -0,0 +1,11 @@
1
+ /** Warn once if a repo has Move sources but no usable move-flow binary is reachable. */
2
+ import { tryCreateMoveFlowClient } from '../core/move/mcp-client.js';
3
+ import { cliWarn } from './cli-message.js';
4
+ export function warnIfMoveUnavailable(opts) {
5
+ if (!opts.repoHasMove)
6
+ return;
7
+ if (tryCreateMoveFlowClient())
8
+ return;
9
+ const ctx = opts.context ? ` [${opts.context}]` : '';
10
+ cliWarn(`GitNexus${ctx}: move-flow is unavailable — .move files will not be indexed. Reinstall without GITNEXUS_SKIP_MOVE_FLOW=1, or set MOVE_FLOW to a move-flow binary from aptos-labs/aptos-ai.`, { binary: 'move-flow', context: opts.context });
11
+ }
@@ -37,6 +37,14 @@ interface SetupResult {
37
37
  * install paths copy this same list from hooks/claude/ (the canonical source).
38
38
  */
39
39
  export declare function copyHookHelpers(srcDir: string, destDir: string, label: string, result: SetupResult): Promise<string[]>;
40
+ export declare const RENAMED_SKILL_DIRS: Readonly<Record<string, readonly string[]>>;
41
+ /**
42
+ * Every legacy directory name superseded by a shipped rename. These no longer
43
+ * exist in the bundled skills/ source, but a pre-rename install left them
44
+ * behind in every editor target. Setup only warns about them (it cannot prove
45
+ * it owns the contents); uninstall's ownership-by-name contract removes them.
46
+ */
47
+ export declare const LEGACY_SKILL_DIR_NAMES: readonly string[];
40
48
  export declare const setupCommand: (options?: {
41
49
  codingAgent?: string[] | string;
42
50
  }) => Promise<void>;
package/dist/cli/setup.js CHANGED
@@ -14,7 +14,7 @@ import { promisify } from 'util';
14
14
  import { fileURLToPath } from 'url';
15
15
  import { parseTree, modify, applyEdits, parse as parseJsonc } from 'jsonc-parser';
16
16
  import { getGlobalDir } from '../storage/repo-manager.js';
17
- import { getEditorTargets, mcpTarget, skillTarget, hookTarget, detectIndentation, } from './editor-targets.js';
17
+ import { getEditorTargets, mcpTarget, skillTarget, hookTarget, detectIndentation, isEnoent, } from './editor-targets.js';
18
18
  const __filename = fileURLToPath(import.meta.url);
19
19
  const __dirname = path.dirname(__filename);
20
20
  const execFileAsync = promisify(execFile);
@@ -22,8 +22,10 @@ const execFileAsync = promisify(execFile);
22
22
  // a config that persists in the user's editor and is invoked on every MCP
23
23
  // connect. Pinning to the installed version means subsequent invocations
24
24
  // skip the npm-registry metadata roundtrip (and stay reproducible until
25
- // the user upgrades). Static configs and READMEs intentionally use
26
- // `gitnexus@latest` since they're quickstart docs, not persisted state.
25
+ // the user upgrades). The plugin skill mcp.json are likewise pinned and
26
+ // re-stamped every release by scripts/sync-plugin-manifests.mjs (#2445),
27
+ // since they too execute `gitnexus@<version>` on connect. Only the READMEs
28
+ // stay on `gitnexus@latest` — they're quickstart docs, not executed state.
27
29
  const _require = createRequire(import.meta.url);
28
30
  const _pkg = _require('../../package.json');
29
31
  if (typeof _pkg.version !== 'string' || !_pkg.version) {
@@ -66,6 +68,8 @@ const CODING_AGENT_IDS = {
66
68
  claude: 'claude',
67
69
  antigravity: 'antigravity',
68
70
  opencode: 'opencode',
71
+ codebuddy: 'codebuddy',
72
+ qoder: 'qoder',
69
73
  codex: 'codex',
70
74
  };
71
75
  const SUPPORTED_CODING_AGENTS = Object.values(CODING_AGENT_IDS);
@@ -173,7 +177,13 @@ async function mergeJsoncFile(filePath, keyPath, value) {
173
177
  try {
174
178
  raw = await fs.readFile(filePath, 'utf-8');
175
179
  }
176
- catch {
180
+ catch (err) {
181
+ // Only an absent file means "start fresh". Any other read failure (EACCES,
182
+ // EIO, cloud-placeholder faults) must not be treated as empty — the write
183
+ // below would replace the user's existing config with a gitnexus-only
184
+ // document and report success. Rethrow into the per-editor catch instead.
185
+ if (!isEnoent(err))
186
+ throw err;
177
187
  raw = '';
178
188
  }
179
189
  if (raw.trim().length === 0) {
@@ -207,6 +217,35 @@ async function dirExists(dirPath) {
207
217
  return false;
208
218
  }
209
219
  }
220
+ /**
221
+ * Detection probe: is there a non-empty regular file at this path?
222
+ * Swallows ALL errors (like dirExists) — detection gates run outside the
223
+ * per-editor try blocks, so a rethrowing probe would abort setup for every
224
+ * remaining editor. Size > 0 keeps detection aligned with the config-chain
225
+ * resolver: an empty config file is not evidence of an install, and treating
226
+ * it as one would route the write to a fresh file whose mkdir manufactures
227
+ * the editor's directory.
228
+ */
229
+ async function isNonEmptyFile(filePath) {
230
+ try {
231
+ const stat = await fs.stat(filePath);
232
+ return stat.isFile() && stat.size > 0;
233
+ }
234
+ catch {
235
+ return false;
236
+ }
237
+ }
238
+ /**
239
+ * Detection probe: does any file in the target's MCP config chain look like an
240
+ * install trace? Always walks [file, ...legacyFiles] so an editor gaining
241
+ * legacyFiles later is automatically covered (CodeBuddy and Qoder share this —
242
+ * a per-editor copy is how the root-config-only detection gap crept in, see
243
+ * PR #2368 review I4).
244
+ */
245
+ async function anyChainConfigFile(target) {
246
+ const hits = await Promise.all([target.file, ...(target.legacyFiles ?? [])].map(isNonEmptyFile));
247
+ return hits.includes(true);
248
+ }
210
249
  // ─── Editor-specific setup ─────────────────────────────────────────
211
250
  async function setupCursor(result) {
212
251
  const cursorDir = path.join(os.homedir(), '.cursor');
@@ -287,7 +326,12 @@ async function mergeHooksJsonc(filePath, entries) {
287
326
  try {
288
327
  raw = await fs.readFile(filePath, 'utf-8');
289
328
  }
290
- catch {
329
+ catch (err) {
330
+ // Same contract as mergeJsoncFile: an unreadable (non-ENOENT) settings
331
+ // file must not be rewritten as hooks-only — that would destroy every
332
+ // user setting in it. Rethrow into the hook installer's catch.
333
+ if (!isEnoent(err))
334
+ throw err;
291
335
  raw = '';
292
336
  }
293
337
  if (raw.trim().length === 0) {
@@ -365,20 +409,26 @@ export async function copyHookHelpers(srcDir, destDir, label, result) {
365
409
  return failedRequired;
366
410
  }
367
411
  /**
368
- * Install GitNexus hooks to ~/.claude/settings.json for Claude Code.
369
- * Merges hook config without overwriting existing hooks, preserving
370
- * comments and formatting in the JSONC file.
412
+ * Install GitNexus hooks for editors that use Claude Code's hooks schema.
413
+ *
414
+ * Claude Code registers hooks in ~/.claude/settings.json; Codex uses a
415
+ * dedicated ~/.codex/hooks.json with the identical {hooks: {Event: [...]}}
416
+ * JSON shape, stdin payload, and hookSpecificOutput response contract
417
+ * (https://developers.openai.com/codex/hooks), so both runtimes share this
418
+ * installer and the same bundled adapter script. Merges hook config without
419
+ * overwriting existing hooks, preserving comments and formatting.
371
420
  */
372
- async function installClaudeCodeHooks(result) {
373
- const claudeDir = path.join(os.homedir(), '.claude');
374
- if (!(await dirExists(claudeDir)))
421
+ async function installClaudeSchemaHooks(result, id) {
422
+ const hookCfg = hookTarget(id);
423
+ const settingsPath = hookCfg.settingsFile;
424
+ const label = `${hookCfg.label} hooks`;
425
+ // Gate on the editor's own config dir (~/.claude, ~/.codex) existing.
426
+ if (!(await dirExists(path.dirname(settingsPath))))
375
427
  return;
376
- const claudeHook = hookTarget('claude');
377
- const settingsPath = claudeHook.settingsFile;
378
428
  // Source hooks bundled within the gitnexus package (hooks/claude/)
379
429
  const pluginHooksPath = path.join(__dirname, '..', '..', 'hooks', 'claude');
380
- // Copy unified hook script to ~/.claude/hooks/gitnexus/
381
- const destHooksDir = claudeHook.scriptDir;
430
+ // Copy unified hook script to the editor's hooks/gitnexus/ dir
431
+ const destHooksDir = hookCfg.scriptDir;
382
432
  try {
383
433
  await fs.mkdir(destHooksDir, { recursive: true });
384
434
  const src = path.join(pluginHooksPath, 'gitnexus-hook.cjs');
@@ -389,7 +439,7 @@ async function installClaudeCodeHooks(result) {
389
439
  const normalizedCli = path.resolve(resolvedCli).replace(/\\/g, '/');
390
440
  const jsonCli = JSON.stringify(normalizedCli);
391
441
  if (!content.includes(CLI_PATH_SOURCE_LITERAL)) {
392
- result.errors.push('Claude Code hooks: gitnexus-hook.cjs no longer contains the cliPath literal to patch — the installed hook may fail to resolve the CLI. Update CLI_PATH_SOURCE_LITERAL in setup.ts.');
442
+ result.errors.push(`${label}: gitnexus-hook.cjs no longer contains the cliPath literal to patch — the installed hook may fail to resolve the CLI. Update CLI_PATH_SOURCE_LITERAL in setup.ts.`);
393
443
  }
394
444
  content = content.replace(CLI_PATH_SOURCE_LITERAL, `let cliPath = ${jsonCli};`);
395
445
  await fs.writeFile(dest, content, 'utf-8');
@@ -404,12 +454,12 @@ async function installClaudeCodeHooks(result) {
404
454
  await fs.access(dest);
405
455
  }
406
456
  catch {
407
- result.errors.push('Claude Code hooks: adapter script was not installed — skipping hook registration');
457
+ result.errors.push(`${label}: adapter script was not installed — skipping hook registration`);
408
458
  return;
409
459
  }
410
- const failedRequired = await copyHookHelpers(pluginHooksPath, destHooksDir, 'Claude Code hooks', result);
460
+ const failedRequired = await copyHookHelpers(pluginHooksPath, destHooksDir, label, result);
411
461
  if (failedRequired.length > 0) {
412
- result.errors.push(`Claude Code hooks: required helper(s) ${failedRequired.join(', ')} failed to copy — skipping hook registration`);
462
+ result.errors.push(`${label}: required helper(s) ${failedRequired.join(', ')} failed to copy — skipping hook registration`);
413
463
  return;
414
464
  }
415
465
  const hookPath = path.join(destHooksDir, 'gitnexus-hook.cjs').replace(/\\/g, '/');
@@ -425,9 +475,10 @@ async function installClaudeCodeHooks(result) {
425
475
  }
426
476
  })();
427
477
  const hookEntries = [];
428
- // NOTE: SessionStart hooks are broken on Windows (Claude Code bug #23576).
429
- // Session context is delivered via CLAUDE.md / skills instead.
430
- if (!hasGitnexusHook(parsed?.hooks, 'PreToolUse', claudeHook.needle)) {
478
+ // NOTE: SessionStart hooks are broken on Windows (Claude Code bug #23576),
479
+ // and Codex reads AGENTS.md natively. Session context is delivered via
480
+ // CLAUDE.md / AGENTS.md / skills instead.
481
+ if (!hasGitnexusHook(parsed?.hooks, 'PreToolUse', hookCfg.needle)) {
431
482
  hookEntries.push({
432
483
  eventName: 'PreToolUse',
433
484
  value: {
@@ -443,7 +494,7 @@ async function installClaudeCodeHooks(result) {
443
494
  },
444
495
  });
445
496
  }
446
- if (!hasGitnexusHook(parsed?.hooks, 'PostToolUse', claudeHook.needle)) {
497
+ if (!hasGitnexusHook(parsed?.hooks, 'PostToolUse', hookCfg.needle)) {
447
498
  hookEntries.push({
448
499
  eventName: 'PostToolUse',
449
500
  value: {
@@ -460,19 +511,19 @@ async function installClaudeCodeHooks(result) {
460
511
  });
461
512
  }
462
513
  if (hookEntries.length === 0) {
463
- result.configured.push('Claude Code hooks (already configured)');
514
+ result.configured.push(`${label} (already configured)`);
464
515
  return;
465
516
  }
466
517
  const ok = await mergeHooksJsonc(settingsPath, hookEntries);
467
518
  if (ok) {
468
- result.configured.push('Claude Code hooks (PreToolUse, PostToolUse)');
519
+ result.configured.push(`${label} (PreToolUse, PostToolUse)`);
469
520
  }
470
521
  else {
471
- result.errors.push('Claude Code hooks: settings.json is corrupt — skipping to preserve existing content');
522
+ result.errors.push(`${label}: ${path.basename(settingsPath)} is corrupt — skipping to preserve existing content`);
472
523
  }
473
524
  }
474
525
  catch (err) {
475
- result.errors.push(`Claude Code hooks: ${err.message}`);
526
+ result.errors.push(`${label}: ${err.message}`);
476
527
  }
477
528
  }
478
529
  // ─── Antigravity (Google) ──────────────────────────────────────────
@@ -660,6 +711,118 @@ async function setupOpenCode(result) {
660
711
  result.errors.push(`OpenCode: ${err.message}`);
661
712
  }
662
713
  }
714
+ /**
715
+ * Resolve which config file in a target's [file, ...legacyFiles] priority
716
+ * chain setup should write into: the first that exists, else the recommended
717
+ * `file`. CodeBuddy reads only the first existing file in its chain, so
718
+ * creating the recommended file above a populated deprecated one would shadow
719
+ * the user's existing MCP servers.
720
+ */
721
+ async function resolveMcpConfigFile(target) {
722
+ for (const candidate of [target.file, ...(target.legacyFiles ?? [])]) {
723
+ try {
724
+ const stat = await fs.stat(candidate);
725
+ // Non-empty regular files only: a 0-byte recommended file must not
726
+ // shadow a populated deprecated one (mergeJsoncFile treats empty as a
727
+ // fresh document anyway), and directories are never config candidates.
728
+ if (stat.isFile() && stat.size > 0)
729
+ return candidate;
730
+ }
731
+ catch (err) {
732
+ // ENOENT = candidate absent — try the next one. Anything else (EACCES
733
+ // on the file or a parent) is surfaced: silently skipping could route
734
+ // the write to a lower-priority file the editor never reads.
735
+ if (!isEnoent(err))
736
+ throw err;
737
+ }
738
+ }
739
+ return target.file;
740
+ }
741
+ async function setupCodeBuddy(result) {
742
+ const codebuddyDir = path.join(os.homedir(), '.codebuddy');
743
+ const target = mcpTarget('codebuddy');
744
+ // Installed = the config dir exists OR any registered MCP config file does.
745
+ // A user whose only trace is a root-level config (e.g. a legacy
746
+ // ~/.codebuddy.json) still gets configured — uninstall already handles that
747
+ // shape, so setup skipping it was an asymmetry (PR #2368 review I4).
748
+ if (!(await dirExists(codebuddyDir)) && !(await anyChainConfigFile(target))) {
749
+ result.skipped.push('CodeBuddy (not installed)');
750
+ return;
751
+ }
752
+ try {
753
+ const configFile = await resolveMcpConfigFile(target);
754
+ const ok = await mergeJsoncFile(configFile, target.keyPath, getMcpEntry());
755
+ if (ok) {
756
+ result.configured.push('CodeBuddy');
757
+ }
758
+ else {
759
+ result.errors.push(`CodeBuddy: ${path.basename(configFile)} is corrupt — skipping to preserve existing content`);
760
+ }
761
+ }
762
+ catch (err) {
763
+ result.errors.push(`CodeBuddy: ${err instanceof Error ? err.message : String(err)}`);
764
+ }
765
+ }
766
+ async function setupQoder(result) {
767
+ const qoderDir = path.join(os.homedir(), '.qoder');
768
+ const target = mcpTarget('qoder');
769
+ const { file: mcpPath, keyPath } = target;
770
+ // Same chain-aware detection as CodeBuddy: ~/.qoder.json alone counts.
771
+ if (!(await dirExists(qoderDir)) && !(await anyChainConfigFile(target))) {
772
+ result.skipped.push('Qoder (not installed)');
773
+ return;
774
+ }
775
+ try {
776
+ const ok = await mergeJsoncFile(mcpPath, keyPath, getMcpEntry());
777
+ if (ok) {
778
+ result.configured.push('Qoder');
779
+ }
780
+ else {
781
+ result.errors.push('Qoder: .qoder.json is corrupt — skipping to preserve existing content');
782
+ }
783
+ }
784
+ catch (err) {
785
+ result.errors.push(`Qoder: ${err instanceof Error ? err.message : String(err)}`);
786
+ }
787
+ }
788
+ /**
789
+ * Install global CodeBuddy skills to ~/.codebuddy/skills/
790
+ * (https://www.codebuddy.ai/docs/cli/skills — same SKILL.md layout as Claude Code).
791
+ */
792
+ async function installCodeBuddySkills(result) {
793
+ const codebuddyDir = path.join(os.homedir(), '.codebuddy');
794
+ if (!(await dirExists(codebuddyDir)))
795
+ return;
796
+ const skillsDir = skillTarget('codebuddy').dir;
797
+ try {
798
+ const installed = await installSkillsTo(skillsDir);
799
+ if (installed.length > 0) {
800
+ result.configured.push(`CodeBuddy skills (${installed.length} skills → ~/.codebuddy/skills/)`);
801
+ }
802
+ }
803
+ catch (err) {
804
+ result.errors.push(`CodeBuddy skills: ${err instanceof Error ? err.message : String(err)}`);
805
+ }
806
+ }
807
+ /**
808
+ * Install global Qoder skills to ~/.qoder/skills/
809
+ * (https://docs.qoder.com/extensions/skills — same SKILL.md layout as Claude Code).
810
+ */
811
+ async function installQoderSkills(result) {
812
+ const qoderDir = path.join(os.homedir(), '.qoder');
813
+ if (!(await dirExists(qoderDir)))
814
+ return;
815
+ const skillsDir = skillTarget('qoder').dir;
816
+ try {
817
+ const installed = await installSkillsTo(skillsDir);
818
+ if (installed.length > 0) {
819
+ result.configured.push(`Qoder skills (${installed.length} skills → ~/.qoder/skills/)`);
820
+ }
821
+ }
822
+ catch (err) {
823
+ result.errors.push(`Qoder skills: ${err instanceof Error ? err.message : String(err)}`);
824
+ }
825
+ }
663
826
  /**
664
827
  * Build a TOML section for Codex MCP config (~/.codex/config.toml).
665
828
  */
@@ -677,7 +840,12 @@ async function upsertCodexConfigToml(configPath) {
677
840
  try {
678
841
  existing = await fs.readFile(configPath, 'utf-8');
679
842
  }
680
- catch {
843
+ catch (err) {
844
+ // TOML variant of the mergeJsoncFile contract: treating a non-ENOENT read
845
+ // failure as an empty config would rewrite config.toml with only the
846
+ // gitnexus section. Rethrow into setupCodex's catch.
847
+ if (!isEnoent(err))
848
+ throw err;
681
849
  existing = '';
682
850
  }
683
851
  if (existing.includes(`[${getEditorTargets().codex.tomlSection}]`)) {
@@ -716,6 +884,16 @@ async function setupCodex(result) {
716
884
  }
717
885
  }
718
886
  // ─── Skill Installation ───────────────────────────────────────────
887
+ export const RENAMED_SKILL_DIRS = {
888
+ 'gitnexus-review': ['gitnexus-pr-review'],
889
+ };
890
+ /**
891
+ * Every legacy directory name superseded by a shipped rename. These no longer
892
+ * exist in the bundled skills/ source, but a pre-rename install left them
893
+ * behind in every editor target. Setup only warns about them (it cannot prove
894
+ * it owns the contents); uninstall's ownership-by-name contract removes them.
895
+ */
896
+ export const LEGACY_SKILL_DIR_NAMES = Object.values(RENAMED_SKILL_DIRS).flat();
719
897
  /**
720
898
  * Install GitNexus skills to a target directory.
721
899
  * Each skill is installed as {targetDir}/gitnexus-{skillName}/SKILL.md
@@ -771,15 +949,25 @@ async function installSkillsTo(targetDir) {
771
949
  if (source.isDirectory) {
772
950
  const dirSource = path.join(skillsRoot, skillName);
773
951
  await copyDirRecursive(dirSource, skillDir);
774
- installed.push(skillName);
775
952
  }
776
953
  else {
777
954
  const flatSource = path.join(skillsRoot, `${skillName}.md`);
778
955
  const content = await fs.readFile(flatSource, 'utf-8');
779
956
  await fs.mkdir(skillDir, { recursive: true });
780
957
  await fs.writeFile(path.join(skillDir, 'SKILL.md'), content, 'utf-8');
781
- installed.push(skillName);
782
958
  }
959
+ // A directory superseded by a shipped rename is warned about, never
960
+ // deleted: the installer cannot prove it owns the contents (users
961
+ // customize installed skills or hand-write their own under these
962
+ // names), so an upgrade must not destroy data.
963
+ for (const oldName of RENAMED_SKILL_DIRS[skillName] ?? []) {
964
+ const legacyDir = path.join(targetDir, oldName);
965
+ if (await dirExists(legacyDir)) {
966
+ console.log(`[gitnexus] skill "${oldName}" was renamed to "${skillName}"; ` +
967
+ `left ${legacyDir} in place — delete it manually if you have not customized it.`);
968
+ }
969
+ }
970
+ installed.push(skillName);
783
971
  }
784
972
  catch {
785
973
  // Source skill not found — skip
@@ -885,12 +1073,16 @@ export const setupCommand = async (options) => {
885
1073
  await setupAntigravity(result);
886
1074
  if (selected.has('opencode'))
887
1075
  await setupOpenCode(result);
1076
+ if (selected.has('codebuddy'))
1077
+ await setupCodeBuddy(result);
1078
+ if (selected.has('qoder'))
1079
+ await setupQoder(result);
888
1080
  if (selected.has('codex'))
889
1081
  await setupCodex(result);
890
1082
  // Install global skills for platforms that support them
891
1083
  if (selected.has('claude')) {
892
1084
  await installClaudeCodeSkills(result);
893
- await installClaudeCodeHooks(result);
1085
+ await installClaudeSchemaHooks(result, 'claude');
894
1086
  }
895
1087
  if (selected.has('antigravity')) {
896
1088
  await installAntigravitySkills(result);
@@ -900,8 +1092,14 @@ export const setupCommand = async (options) => {
900
1092
  await installCursorSkills(result);
901
1093
  if (selected.has('opencode'))
902
1094
  await installOpenCodeSkills(result);
903
- if (selected.has('codex'))
1095
+ if (selected.has('codebuddy'))
1096
+ await installCodeBuddySkills(result);
1097
+ if (selected.has('qoder'))
1098
+ await installQoderSkills(result);
1099
+ if (selected.has('codex')) {
904
1100
  await installCodexSkills(result);
1101
+ await installClaudeSchemaHooks(result, 'codex');
1102
+ }
905
1103
  // Print results
906
1104
  if (result.configured.length > 0) {
907
1105
  console.log(' Configured:');