gitnexus 1.6.11-rc.8 → 1.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/README.md +95 -26
  2. package/dist/_shared/graph/types.d.ts +81 -2
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -1
  5. package/dist/_shared/integrations/circuit-breaker.js.map +1 -1
  6. package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
  7. package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
  8. package/dist/_shared/language-detection.d.ts.map +1 -1
  9. package/dist/_shared/language-detection.js +2 -0
  10. package/dist/_shared/language-detection.js.map +1 -1
  11. package/dist/_shared/languages.d.ts +2 -1
  12. package/dist/_shared/languages.d.ts.map +1 -1
  13. package/dist/_shared/languages.js +1 -0
  14. package/dist/_shared/languages.js.map +1 -1
  15. package/dist/_shared/lbug/schema-constants.d.ts +2 -2
  16. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  17. package/dist/_shared/lbug/schema-constants.js +4 -0
  18. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  19. package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
  20. package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -0
  21. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  22. package/dist/_shared/scope-resolution/language-classification.d.ts +3 -0
  23. package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
  24. package/dist/_shared/scope-resolution/language-classification.js +4 -0
  25. package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
  26. package/dist/_shared/scope-resolution/reference-site.d.ts +10 -0
  27. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
  28. package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -1
  29. package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -1
  30. package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
  31. package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
  32. package/dist/_shared/scope-resolution/types.d.ts +15 -0
  33. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  34. package/dist/cli/ai-context.d.ts +4 -0
  35. package/dist/cli/ai-context.js +90 -14
  36. package/dist/cli/analyze-config.js +14 -0
  37. package/dist/cli/analyze-options.d.ts +14 -0
  38. package/dist/cli/analyze-watch.d.ts +20 -0
  39. package/dist/cli/analyze-watch.js +434 -0
  40. package/dist/cli/analyze.js +27 -9
  41. package/dist/cli/auto-sync.d.ts +1 -0
  42. package/dist/cli/auto-sync.js +107 -0
  43. package/dist/cli/command-banner.d.ts +15 -0
  44. package/dist/cli/command-banner.js +42 -0
  45. package/dist/cli/detect-changes-format.js +21 -0
  46. package/dist/cli/doctor.d.ts +7 -0
  47. package/dist/cli/doctor.js +14 -0
  48. package/dist/cli/group.js +7 -1
  49. package/dist/cli/help-i18n.js +4 -0
  50. package/dist/cli/i18n/en.d.ts +18 -3
  51. package/dist/cli/i18n/en.js +18 -3
  52. package/dist/cli/i18n/resources.d.ts +33 -3
  53. package/dist/cli/i18n/zh-CN.d.ts +15 -0
  54. package/dist/cli/i18n/zh-CN.js +18 -3
  55. package/dist/cli/index.js +34 -7
  56. package/dist/cli/mcp.d.ts +15 -0
  57. package/dist/cli/mcp.js +44 -0
  58. package/dist/cli/optional-grammars.d.ts +3 -2
  59. package/dist/cli/optional-grammars.js +19 -3
  60. package/dist/cli/setup.js +41 -15
  61. package/dist/cli/update-notice.d.ts +34 -0
  62. package/dist/cli/update-notice.js +91 -0
  63. package/dist/cli/update.d.ts +21 -0
  64. package/dist/cli/update.js +93 -0
  65. package/dist/cli/watch.d.ts +1 -20
  66. package/dist/cli/watch.js +5 -371
  67. package/dist/core/analysis-feature-registry.d.ts +2 -0
  68. package/dist/core/analysis-feature-registry.js +15 -0
  69. package/dist/core/analyzer-identity.js +21 -3
  70. package/dist/core/auto-sync/analysis-worker-launch.d.ts +30 -0
  71. package/dist/core/auto-sync/analysis-worker-launch.js +166 -0
  72. package/dist/core/auto-sync/config.d.ts +33 -0
  73. package/dist/core/auto-sync/config.js +320 -0
  74. package/dist/core/auto-sync/index.d.ts +6 -0
  75. package/dist/core/auto-sync/index.js +6 -0
  76. package/dist/core/auto-sync/path-security.d.ts +9 -0
  77. package/dist/core/auto-sync/path-security.js +251 -0
  78. package/dist/core/auto-sync/repo.d.ts +1 -0
  79. package/dist/core/auto-sync/repo.js +6 -0
  80. package/dist/core/auto-sync/runner.d.ts +44 -0
  81. package/dist/core/auto-sync/runner.js +428 -0
  82. package/dist/core/auto-sync/starter.d.ts +50 -0
  83. package/dist/core/auto-sync/starter.js +497 -0
  84. package/dist/core/auto-sync/state.d.ts +37 -0
  85. package/dist/core/auto-sync/state.js +119 -0
  86. package/dist/core/group/config-parser.js +8 -1
  87. package/dist/core/group/cross-impact.d.ts +3 -0
  88. package/dist/core/group/cross-impact.js +36 -4
  89. package/dist/core/group/extractors/http-patterns/java.js +22 -8
  90. package/dist/core/group/extractors/http-patterns/kotlin.js +86 -31
  91. package/dist/core/group/extractors/http-patterns/node.js +145 -8
  92. package/dist/core/group/extractors/http-patterns/python.js +11 -7
  93. package/dist/core/group/extractors/http-route-extractor.js +63 -17
  94. package/dist/core/group/extractors/java-workspace-extractor.js +244 -31
  95. package/dist/core/group/group-lock.js +5 -6
  96. package/dist/core/group/normalization.d.ts +38 -1
  97. package/dist/core/group/normalization.js +59 -3
  98. package/dist/core/group/service.d.ts +11 -0
  99. package/dist/core/group/service.js +13 -1
  100. package/dist/core/group/storage.js +2 -2
  101. package/dist/core/group/sync.d.ts +24 -1
  102. package/dist/core/group/sync.js +46 -8
  103. package/dist/core/group/types.d.ts +13 -0
  104. package/dist/core/incremental/derived-writeback.d.ts +36 -0
  105. package/dist/core/incremental/derived-writeback.js +68 -0
  106. package/dist/core/incremental/spring-config-drift.d.ts +12 -0
  107. package/dist/core/incremental/spring-config-drift.js +46 -0
  108. package/dist/core/incremental/subgraph-extract.d.ts +7 -4
  109. package/dist/core/incremental/subgraph-extract.js +30 -5
  110. package/dist/core/ingestion/asyncapi/document.d.ts +226 -0
  111. package/dist/core/ingestion/asyncapi/document.js +758 -0
  112. package/dist/core/ingestion/asyncapi/protocol.d.ts +79 -0
  113. package/dist/core/ingestion/asyncapi/protocol.js +203 -0
  114. package/dist/core/ingestion/call-extractors/configs/zig.d.ts +2 -0
  115. package/dist/core/ingestion/call-extractors/configs/zig.js +4 -0
  116. package/dist/core/ingestion/call-extractors/zig-static-gating.d.ts +100 -0
  117. package/dist/core/ingestion/call-extractors/zig-static-gating.js +319 -0
  118. package/dist/core/ingestion/call-processor.js +3 -1
  119. package/dist/core/ingestion/class-extractors/configs/zig.d.ts +2 -0
  120. package/dist/core/ingestion/class-extractors/configs/zig.js +32 -0
  121. package/dist/core/ingestion/class-extractors/generic.js +4 -1
  122. package/dist/core/ingestion/class-types.d.ts +6 -2
  123. package/dist/core/ingestion/destination-key.d.ts +59 -0
  124. package/dist/core/ingestion/destination-key.js +61 -0
  125. package/dist/core/ingestion/entry-point-scoring.d.ts +6 -2
  126. package/dist/core/ingestion/entry-point-scoring.js +8 -44
  127. package/dist/core/ingestion/export-detection.d.ts +37 -0
  128. package/dist/core/ingestion/export-detection.js +60 -0
  129. package/dist/core/ingestion/field-extractors/configs/zig.d.ts +8 -0
  130. package/dist/core/ingestion/field-extractors/configs/zig.js +49 -0
  131. package/dist/core/ingestion/field-extractors/generic.d.ts +1 -1
  132. package/dist/core/ingestion/field-extractors/generic.js +12 -1
  133. package/dist/core/ingestion/frameworks/spring/actuator-runtime.d.ts +26 -0
  134. package/dist/core/ingestion/frameworks/spring/actuator-runtime.js +843 -0
  135. package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +5 -0
  136. package/dist/core/ingestion/frameworks/spring/analysis-features.js +9 -0
  137. package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +8 -1
  138. package/dist/core/ingestion/frameworks/spring/argument-facts.d.ts +80 -0
  139. package/dist/core/ingestion/frameworks/spring/argument-facts.js +85 -0
  140. package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +1 -0
  141. package/dist/core/ingestion/frameworks/spring/config-bindings.js +2 -1
  142. package/dist/core/ingestion/frameworks/spring/destinations.d.ts +539 -0
  143. package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
  144. package/dist/core/ingestion/frameworks/spring/dynamic-lookups.d.ts +22 -0
  145. package/dist/core/ingestion/frameworks/spring/dynamic-lookups.js +124 -0
  146. package/dist/core/ingestion/frameworks/spring/message-producers.d.ts +78 -0
  147. package/dist/core/ingestion/frameworks/spring/message-producers.js +90 -0
  148. package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +29 -0
  149. package/dist/core/ingestion/frameworks/spring/vendor-prefixes.d.ts +7 -0
  150. package/dist/core/ingestion/frameworks/spring/vendor-prefixes.js +22 -0
  151. package/dist/core/ingestion/import-resolvers/configs/zig.d.ts +13 -0
  152. package/dist/core/ingestion/import-resolvers/configs/zig.js +26 -0
  153. package/dist/core/ingestion/import-resolvers/zig.d.ts +34 -0
  154. package/dist/core/ingestion/import-resolvers/zig.js +193 -0
  155. package/dist/core/ingestion/language-config.d.ts +177 -0
  156. package/dist/core/ingestion/language-config.js +719 -0
  157. package/dist/core/ingestion/language-provider.d.ts +178 -1
  158. package/dist/core/ingestion/language-provider.js +22 -0
  159. package/dist/core/ingestion/languages/csharp/razor-view-components.d.ts +62 -0
  160. package/dist/core/ingestion/languages/csharp/razor-view-components.js +954 -0
  161. package/dist/core/ingestion/languages/csharp/resolution-config.d.ts +3 -0
  162. package/dist/core/ingestion/languages/csharp/resolution-config.js +6 -1
  163. package/dist/core/ingestion/languages/csharp/scope-resolver.js +8 -0
  164. package/dist/core/ingestion/languages/index.d.ts +1 -0
  165. package/dist/core/ingestion/languages/index.js +2 -0
  166. package/dist/core/ingestion/languages/java/analysis-features.d.ts +1 -1
  167. package/dist/core/ingestion/languages/java/analysis-features.js +14 -6
  168. package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +8 -0
  169. package/dist/core/ingestion/languages/java/capture-side-channel.js +34 -0
  170. package/dist/core/ingestion/languages/java/captures.js +22 -1
  171. package/dist/core/ingestion/languages/java/lombok-synthesizer.d.ts +42 -0
  172. package/dist/core/ingestion/languages/java/lombok-synthesizer.js +439 -0
  173. package/dist/core/ingestion/languages/java/scope-resolver.js +2 -0
  174. package/dist/core/ingestion/languages/java/spring-actuator.d.ts +2 -0
  175. package/dist/core/ingestion/languages/java/spring-actuator.js +62 -0
  176. package/dist/core/ingestion/languages/java/spring-di.d.ts +17 -1
  177. package/dist/core/ingestion/languages/java/spring-di.js +44 -2
  178. package/dist/core/ingestion/languages/java/spring-dynamic-lookup.d.ts +8 -0
  179. package/dist/core/ingestion/languages/java/spring-dynamic-lookup.js +62 -0
  180. package/dist/core/ingestion/languages/java/spring-message-producers.d.ts +20 -0
  181. package/dist/core/ingestion/languages/java/spring-message-producers.js +83 -0
  182. package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +11 -1
  183. package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +13 -3
  184. package/dist/core/ingestion/languages/java.js +18 -8
  185. package/dist/core/ingestion/languages/jvm/accessor-synthesis.d.ts +99 -0
  186. package/dist/core/ingestion/languages/jvm/accessor-synthesis.js +173 -0
  187. package/dist/core/ingestion/languages/jvm/beanspec.d.ts +17 -0
  188. package/dist/core/ingestion/languages/jvm/beanspec.js +42 -0
  189. package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +15 -0
  190. package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +50 -0
  191. package/dist/core/ingestion/languages/kotlin/captures.js +24 -1
  192. package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.d.ts +26 -0
  193. package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.js +417 -0
  194. package/dist/core/ingestion/languages/kotlin/scope-resolver.js +4 -0
  195. package/dist/core/ingestion/languages/kotlin/spring-actuator.d.ts +4 -0
  196. package/dist/core/ingestion/languages/kotlin/spring-actuator.js +172 -0
  197. package/dist/core/ingestion/languages/kotlin/spring-config-bindings.d.ts +18 -0
  198. package/dist/core/ingestion/languages/kotlin/spring-config-bindings.js +411 -0
  199. package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +51 -1
  200. package/dist/core/ingestion/languages/kotlin/spring-di.js +86 -6
  201. package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.d.ts +8 -0
  202. package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.js +77 -0
  203. package/dist/core/ingestion/languages/kotlin/spring-message-producers.d.ts +17 -0
  204. package/dist/core/ingestion/languages/kotlin/spring-message-producers.js +119 -0
  205. package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +16 -0
  206. package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +77 -2
  207. package/dist/core/ingestion/languages/kotlin.js +24 -0
  208. package/dist/core/ingestion/languages/python.js +2 -0
  209. package/dist/core/ingestion/languages/rust/query.js +8 -8
  210. package/dist/core/ingestion/languages/zig/captures.d.ts +260 -0
  211. package/dist/core/ingestion/languages/zig/captures.js +2070 -0
  212. package/dist/core/ingestion/languages/zig/index.d.ts +4 -0
  213. package/dist/core/ingestion/languages/zig/index.js +4 -0
  214. package/dist/core/ingestion/languages/zig/interpret.d.ts +36 -0
  215. package/dist/core/ingestion/languages/zig/interpret.js +176 -0
  216. package/dist/core/ingestion/languages/zig/query.d.ts +3 -0
  217. package/dist/core/ingestion/languages/zig/query.js +426 -0
  218. package/dist/core/ingestion/languages/zig/range-binding.d.ts +37 -0
  219. package/dist/core/ingestion/languages/zig/range-binding.js +373 -0
  220. package/dist/core/ingestion/languages/zig/scope-resolver.d.ts +12 -0
  221. package/dist/core/ingestion/languages/zig/scope-resolver.js +58 -0
  222. package/dist/core/ingestion/languages/zig/simple-hooks.d.ts +25 -0
  223. package/dist/core/ingestion/languages/zig/simple-hooks.js +143 -0
  224. package/dist/core/ingestion/languages/zig.d.ts +32 -0
  225. package/dist/core/ingestion/languages/zig.js +130 -0
  226. package/dist/core/ingestion/method-extractors/configs/zig.d.ts +2 -0
  227. package/dist/core/ingestion/method-extractors/configs/zig.js +120 -0
  228. package/dist/core/ingestion/method-extractors/generic.js +16 -4
  229. package/dist/core/ingestion/method-types.d.ts +10 -4
  230. package/dist/core/ingestion/model/field-registry.d.ts +3 -3
  231. package/dist/core/ingestion/model/field-registry.js +11 -7
  232. package/dist/core/ingestion/model/method-registry.d.ts +3 -3
  233. package/dist/core/ingestion/model/method-registry.js +13 -8
  234. package/dist/core/ingestion/model/registration-table.js +3 -0
  235. package/dist/core/ingestion/model/type-registry.js +8 -4
  236. package/dist/core/ingestion/pipeline-phases/di.js +47 -14
  237. package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
  238. package/dist/core/ingestion/pipeline-phases/index.js +1 -0
  239. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +7 -1
  240. package/dist/core/ingestion/pipeline-phases/parse-impl.js +79 -91
  241. package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
  242. package/dist/core/ingestion/pipeline-phases/processes.d.ts +2 -1
  243. package/dist/core/ingestion/pipeline-phases/processes.js +39 -4
  244. package/dist/core/ingestion/pipeline-phases/routes.js +27 -18
  245. package/dist/core/ingestion/pipeline-phases/runner.d.ts +4 -1
  246. package/dist/core/ingestion/pipeline-phases/runner.js +34 -14
  247. package/dist/core/ingestion/pipeline-phases/scan.js +82 -1
  248. package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +2 -0
  249. package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +8 -0
  250. package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +123 -0
  251. package/dist/core/ingestion/pipeline-phases/spring-destinations.js +688 -0
  252. package/dist/core/ingestion/pipeline.d.ts +30 -1
  253. package/dist/core/ingestion/pipeline.js +52 -14
  254. package/dist/core/ingestion/resolve-references.js +5 -0
  255. package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +16 -0
  256. package/dist/core/ingestion/route-extractors/constant-resolver.js +10 -0
  257. package/dist/core/ingestion/route-extractors/java-const-resolver.d.ts +27 -1
  258. package/dist/core/ingestion/route-extractors/java-const-resolver.js +161 -13
  259. package/dist/core/ingestion/route-extractors/kotlin-const-resolver.d.ts +12 -18
  260. package/dist/core/ingestion/route-extractors/kotlin-const-resolver.js +214 -33
  261. package/dist/core/ingestion/route-extractors/kotlin-spring.d.ts +13 -0
  262. package/dist/core/ingestion/route-extractors/kotlin-spring.js +259 -0
  263. package/dist/core/ingestion/route-extractors/python-decorator-handler.d.ts +6 -0
  264. package/dist/core/ingestion/route-extractors/python-decorator-handler.js +16 -0
  265. package/dist/core/ingestion/route-extractors/spring-shared.d.ts +30 -1
  266. package/dist/core/ingestion/route-extractors/spring-shared.js +77 -9
  267. package/dist/core/ingestion/route-extractors/spring.js +9 -5
  268. package/dist/core/ingestion/scope-extractor.js +8 -0
  269. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +62 -0
  270. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +4 -0
  271. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +2 -0
  272. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +28 -0
  273. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +11 -2
  274. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +23 -2
  275. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +24 -3
  276. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +11 -1
  277. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +26 -6
  278. package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +11 -0
  279. package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +29 -3
  280. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +8 -1
  281. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +35 -9
  282. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +1 -4
  283. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +277 -9
  284. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
  285. package/dist/core/ingestion/scope-resolution/pipeline/run.js +7 -3
  286. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +43 -9
  287. package/dist/core/ingestion/scope-resolution/scope/walkers.js +71 -10
  288. package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -0
  289. package/dist/core/ingestion/tree-sitter-queries.js +161 -0
  290. package/dist/core/ingestion/type-extractors/zig.d.ts +2 -0
  291. package/dist/core/ingestion/type-extractors/zig.js +17 -0
  292. package/dist/core/ingestion/utils/ast-helpers.d.ts +40 -1
  293. package/dist/core/ingestion/utils/ast-helpers.js +124 -6
  294. package/dist/core/ingestion/utils/callable-flow-captures.d.ts +9 -0
  295. package/dist/core/ingestion/utils/callable-flow-captures.js +75 -14
  296. package/dist/core/ingestion/utils/test-file-path.d.ts +28 -0
  297. package/dist/core/ingestion/utils/test-file-path.js +87 -0
  298. package/dist/core/ingestion/variable-extractors/configs/zig.d.ts +2 -0
  299. package/dist/core/ingestion/variable-extractors/configs/zig.js +71 -0
  300. package/dist/core/ingestion/workers/parse-worker.js +85 -14
  301. package/dist/core/install-context.d.ts +4 -0
  302. package/dist/core/install-context.js +152 -0
  303. package/dist/core/lbug/csv-generator.d.ts +10 -1
  304. package/dist/core/lbug/csv-generator.js +92 -22
  305. package/dist/core/lbug/graph-emit-sink.d.ts +3 -2
  306. package/dist/core/lbug/graph-emit-sink.js +4 -2
  307. package/dist/core/lbug/lbug-adapter.d.ts +100 -5
  308. package/dist/core/lbug/lbug-adapter.js +236 -24
  309. package/dist/core/lbug/schema.d.ts +6 -5
  310. package/dist/core/lbug/schema.js +84 -22
  311. package/dist/core/net/url-guard.d.ts +6 -0
  312. package/dist/core/net/url-guard.js +147 -0
  313. package/dist/core/package-version.d.ts +5 -0
  314. package/dist/core/package-version.js +10 -0
  315. package/dist/core/run-analyze.d.ts +21 -4
  316. package/dist/core/run-analyze.js +426 -117
  317. package/dist/core/search/fts-indexes.d.ts +19 -1
  318. package/dist/core/search/fts-indexes.js +28 -1
  319. package/dist/core/tree-sitter/parser-loader.js +16 -0
  320. package/dist/core/update-cache.d.ts +39 -0
  321. package/dist/core/update-cache.js +141 -0
  322. package/dist/core/update-check.d.ts +31 -0
  323. package/dist/core/update-check.js +274 -0
  324. package/dist/mcp/local/local-backend.d.ts +27 -13
  325. package/dist/mcp/local/local-backend.js +148 -60
  326. package/dist/mcp/repository-policy.d.ts +5 -1
  327. package/dist/mcp/repository-policy.js +48 -4
  328. package/dist/mcp/resources.js +10 -1
  329. package/dist/mcp/server.js +8 -9
  330. package/dist/mcp/tools.js +32 -22
  331. package/dist/server/analyze-launch.d.ts +2 -0
  332. package/dist/server/analyze-launch.js +2 -0
  333. package/dist/server/analyze-worker-protocol.d.ts +6 -1
  334. package/dist/server/analyze-worker.d.ts +1 -0
  335. package/dist/server/analyze-worker.js +38 -20
  336. package/dist/server/api.d.ts +5 -1
  337. package/dist/server/api.js +105 -88
  338. package/dist/server/git-clone.d.ts +40 -16
  339. package/dist/server/git-clone.js +253 -199
  340. package/dist/server/grep-params.d.ts +18 -0
  341. package/dist/server/grep-params.js +83 -0
  342. package/dist/server/grep-scan.d.ts +23 -0
  343. package/dist/server/grep-scan.js +107 -0
  344. package/dist/server/grep-worker.d.ts +1 -0
  345. package/dist/server/grep-worker.js +12 -0
  346. package/dist/server/mcp-http.d.ts +8 -0
  347. package/dist/server/mcp-http.js +16 -1
  348. package/dist/server/update-controller.d.ts +29 -0
  349. package/dist/server/update-controller.js +82 -0
  350. package/dist/storage/file-lock.d.ts +15 -0
  351. package/dist/storage/file-lock.js +155 -0
  352. package/dist/storage/fs-atomic.d.ts +24 -0
  353. package/dist/storage/fs-atomic.js +86 -2
  354. package/dist/storage/global-dir.d.ts +2 -0
  355. package/dist/storage/global-dir.js +6 -0
  356. package/dist/storage/parse-cache.d.ts +45 -7
  357. package/dist/storage/parse-cache.js +189 -42
  358. package/dist/storage/parsedfile-store.d.ts +41 -60
  359. package/dist/storage/parsedfile-store.js +247 -171
  360. package/dist/storage/repo-manager.d.ts +10 -4
  361. package/dist/storage/repo-manager.js +35 -25
  362. package/dist/storage/repo-meta.d.ts +34 -0
  363. package/dist/storage/v8-sidecar.d.ts +48 -0
  364. package/dist/storage/v8-sidecar.js +347 -0
  365. package/dist/types/pipeline.d.ts +14 -0
  366. package/dist/utils/process-identity.d.ts +2 -0
  367. package/dist/utils/process-identity.js +35 -0
  368. package/package.json +10 -4
  369. package/scripts/assert-web-assets.mjs +35 -0
  370. package/scripts/build-web.js +72 -0
  371. package/scripts/build.js +31 -28
  372. package/scripts/cross-platform-tests.ts +5 -0
  373. package/skills/gitnexus-cli.md +5 -1
  374. package/web/assets/ProcessFlowModal-DAeX2BHW.js +24 -0
  375. package/web/assets/{abnfDiagram-QNN2D4NM-Cq2djWWe.js → abnfDiagram-PAR5IXJI-J3OdeHLl.js} +1 -1
  376. package/web/assets/{agent-BWAXPjC5.js → agent-BMRqXorA.js} +6 -4
  377. package/web/assets/architecture-7GRP2DOG-M7G3SWCO-G3sWyX6M.js +1 -0
  378. package/web/assets/architectureDiagram-2PNWDENW-ysKcRlGT.js +36 -0
  379. package/web/assets/blockDiagram-PUWGUBOA-oLXTa1lY.js +129 -0
  380. package/web/assets/c4Diagram-3NLNHZP5-D3iu4eC0.js +38 -0
  381. package/web/assets/{chunk-2SREHG4O-Dip42xOq.js → chunk-2NMSUPJH-B24w-wng.js} +1 -1
  382. package/web/assets/{chunk-VJFVEZTB-CX66F2ep.js → chunk-32MCUW2P-ByUyt0Sa.js} +3 -3
  383. package/web/assets/{chunk-4RFN2BYJ-DHHWuC-n.js → chunk-3NPNU5GP-DocZ07Sg.js} +1 -1
  384. package/web/assets/{chunk-XNMVGMAZ-Cg_LnPtj.js → chunk-3SMGFRGC-CAu4JRLv.js} +1 -1
  385. package/web/assets/{chunk-W44A43WB-BN8EQc_u.js → chunk-4CAJECRU-DRYMwG9z.js} +1 -1
  386. package/web/assets/chunk-4OADUZ5Q-CxrSvOwZ.js +10 -0
  387. package/web/assets/{chunk-DMV4VAQV-Bn6WXDSX.js → chunk-5IQCK5RY-CCMhl4so.js} +2 -2
  388. package/web/assets/{chunk-RRFMTAIC-CMN0wcYA.js → chunk-5MVFYWFU-Db9KvrYO.js} +1 -1
  389. package/web/assets/chunk-CLS4B6BI-Uvx5QNsu.js +168 -0
  390. package/web/assets/chunk-DZP67EKU-B3Mt380j.js +70 -0
  391. package/web/assets/{chunk-6L755F7B-CMhLBxi2.js → chunk-EICP7K5X-CqwE9hui.js} +1 -1
  392. package/web/assets/{chunk-BI6VK774-D0oaWk8V.js → chunk-GDY2UAB4-CtQQR0a8.js} +1 -1
  393. package/web/assets/chunk-H7VHZCWX-CE1nAmt6.js +1 -0
  394. package/web/assets/chunk-IJBDOHL6-BUKtY6oF.js +1 -0
  395. package/web/assets/{chunk-OIYT25JQ-CQ6KOZGX.js → chunk-JFFVMJIA-0fJenqia.js} +1 -1
  396. package/web/assets/{chunk-HNC4WDU7-DoU3KnA7.js → chunk-JZGDI5JK-BeTMSSkJ.js} +1 -1
  397. package/web/assets/{chunk-EQFTRU2I-1ix7TzW9.js → chunk-KD6SPIPN-Qp1Pflah.js} +1 -1
  398. package/web/assets/chunk-NF366YI6-CpSpya3n.js +231 -0
  399. package/web/assets/chunk-NUDPKBEF-CU1-BQIW.js +34 -0
  400. package/web/assets/{chunk-SATU7PGQ-B1zhgOvc.js → chunk-OJINMHTS-zOCQe4eI.js} +1 -1
  401. package/web/assets/{chunk-E5QJAATJ-dh-5CtIV.js → chunk-Q6NGPIAH-yyBomb63.js} +1 -1
  402. package/web/assets/chunk-QJSWEUOL-D_rf9gPD.js +128 -0
  403. package/web/assets/chunk-R7JDMUKV-CRoqKpD6.js +1 -0
  404. package/web/assets/{chunk-VE5CLXGZ-C1vB7wpY.js → chunk-RCXAM2GK-CUqrWQDV.js} +1 -1
  405. package/web/assets/{chunk-66DQ2XMT-CM0xjFAN.js → chunk-RT4MAWR3-zXy9-Lvt.js} +1 -1
  406. package/web/assets/{chunk-TZUXEDM2-B7p9AcTw.js → chunk-SFMINX4W-J2UrvMpD.js} +1 -1
  407. package/web/assets/{chunk-LORZLZWG-B57uGw2N.js → chunk-SLDQ463B-CHY6e_bQ.js} +2 -2
  408. package/web/assets/{chunk-FWYVLQTC-BgDItRzJ.js → chunk-TCEHX7R3-CXPDEVbm.js} +1 -1
  409. package/web/assets/{chunk-224SPVON-B8gxtXpy.js → chunk-VQC2EELJ-Dc8fIy4R.js} +1 -1
  410. package/web/assets/chunk-VRZKL3EH-DB3KixTQ.js +1 -0
  411. package/web/assets/{chunk-A7VWPJGB-B4O3oQdQ.js → chunk-VTHDQ7BV-b7FsPQZO.js} +1 -1
  412. package/web/assets/chunk-VY2OSTJR-Dkgc3Brg.js +2 -0
  413. package/web/assets/chunk-WUBWJARI-7FwILJ3k.js +2 -0
  414. package/web/assets/{chunk-D6VWDJW2-BxcBdZ9c.js → chunk-YBMQ5JGJ-BSnyWZmd.js} +1 -1
  415. package/web/assets/chunk-YDMLL4PJ-IHhMngTz.js +2 -0
  416. package/web/assets/chunk-Z6V44ARX-BjCEsF0Q.js +62 -0
  417. package/web/assets/chunk-ZJJ7VQJP-Dz089b-K.js +321 -0
  418. package/web/assets/chunk-ZNLK7HRR-B0iFpmW4.js +1 -0
  419. package/web/assets/chunk-ZQN7UHIL-Cy7KAjQt.js +1 -0
  420. package/web/assets/{chunk-L5GCOVLC-CE2w8Nm_.js → chunk-ZS6VBONO-DBjJO0w9.js} +2 -2
  421. package/web/assets/{chunk-NV3KIAZN-5yvcpMiu.js → chunk-ZUNWM646-DNRJyNPe.js} +1 -1
  422. package/web/assets/classDiagram-FGAMPOII-C5Ibyode.js +1 -0
  423. package/web/assets/classDiagram-v2-AI5RJEK4-C5Ibyode.js +1 -0
  424. package/web/assets/{cose-bilkent-RZA4XIPR-BHpK4Crp.js → cose-bilkent-Q72C2OJ3-DMeFXnK8.js} +1 -1
  425. package/web/assets/cynefin-OW5HDTMX-6OCTWOGG-vlqakYcO.js +1 -0
  426. package/web/assets/{cynefinDiagram-TR7LZUCG-C3Iar9lZ.js → cynefinDiagram-2OOWUY4M-BY6DZkTt.js} +1 -1
  427. package/web/assets/dagre-MPVFI544-DWO70fy_.js +4 -0
  428. package/web/assets/diagram-AE4NWXFW-f7JRVRUL.js +24 -0
  429. package/web/assets/{diagram-L7DVE3PN-GIRyVUtt.js → diagram-BUJID5UG-BXZv1rCS.js} +2 -2
  430. package/web/assets/{diagram-JCD7PQ7C-DC5-9FRr.js → diagram-C44CZ5NI-CRNfvjCq.js} +1 -1
  431. package/web/assets/diagram-EYOLEXXS-DZOjKQVE.js +30 -0
  432. package/web/assets/diagram-P7B6PWOJ-D3SQmw3_.js +3 -0
  433. package/web/assets/{ebnfDiagram-DRHRQJWO-D8_CI4ZF.js → ebnfDiagram-FTPZ3PV6-jKWpIDN2.js} +1 -1
  434. package/web/assets/erDiagram-H3ERR26V-BqJntEuJ.js +99 -0
  435. package/web/assets/eventmodeling-NTZA5JFV-WKSWQHFS-Bq4FqtBL.js +1 -0
  436. package/web/assets/flowDiagram-YHGXBVSY-Dnlk2bEu.js +1 -0
  437. package/web/assets/ganttDiagram-RWFTB7ED-Bl6Y1K5T.js +292 -0
  438. package/web/assets/gitGraph-4MIJSDKK-JH2HKYUO-B3yc4GkH.js +1 -0
  439. package/web/assets/gitGraphDiagram-MAR6GKOP-CkNvsrdw.js +106 -0
  440. package/web/assets/{index-CJDpyH-n.css → index-C2_aej58.css} +1 -1
  441. package/web/assets/{index-DDRie6_8.js → index-Dj3vQOHK.js} +51 -51
  442. package/web/assets/info-A6RAGUB7-3TX3OFWW-BM3N5_Dv.js +1 -0
  443. package/web/assets/infoDiagram-LV547AFH-COkFutAf.js +2 -0
  444. package/web/assets/{ishikawaDiagram-4JDSWWDM-DmqWtjkl.js → ishikawaDiagram-PUJQGNDS-Bb8FylSR.js} +2 -2
  445. package/web/assets/{journeyDiagram-QUS3FAKT-XAzVzrQW.js → journeyDiagram-EW5QJT4W-BzoHUBhM.js} +4 -4
  446. package/web/assets/{kanban-definition-D4L7SQKK-YurRnmYn.js → kanban-definition-JSQERAZB-Uy2Pi0yQ.js} +4 -4
  447. package/web/assets/katex-CZ4GXH2S-C0Fcou7U.js +257 -0
  448. package/web/assets/{mindmap-definition-66QP5TD6-ChrWWnil.js → mindmap-definition-VBJCLQLM-B-CnOnt_.js} +3 -3
  449. package/web/assets/packet-AYTQ26CC-MKII6P3Y-Bd52ZE3V.js +1 -0
  450. package/web/assets/{pegDiagram-YKIO5C6U-QGeQLEq2.js → pegDiagram-7WILOQTJ-D9sneKXg.js} +1 -1
  451. package/web/assets/pie-WAS4IAKB-6B4OPMJ5-DW5Xy69Z.js +1 -0
  452. package/web/assets/pieDiagram-EFA7CBSB-Dx2NQofL.js +39 -0
  453. package/web/assets/{quadrantDiagram-VO5QLCXA-B7098wSc.js → quadrantDiagram-WARVYA7P-DPKL9_0A.js} +3 -3
  454. package/web/assets/radar-RG4KPBEZ-UPTR3XUL-CkzibT2h.js +1 -0
  455. package/web/assets/railroad-74A4TZTK-MEFUPFMS-D9zF-mDN.js +1 -0
  456. package/web/assets/railroad-abnf-HS5TGJTU-R5YG2S5D-ruacjUbX.js +1 -0
  457. package/web/assets/railroad-ebnf-LZEXJU2U-G5QEX2L6-S1zc5OiO.js +1 -0
  458. package/web/assets/railroad-peg-WCYAUIDC-H5I2ZRY2-Cbcr0XzY.js +1 -0
  459. package/web/assets/{railroadDiagram-M77LTMSB-AXu4vxk_.js → railroadDiagram-5NIQVNLQ-DsweTo14.js} +1 -1
  460. package/web/assets/{requirementDiagram-RASO5HTO-B-l8InpK.js → requirementDiagram-SXREGOKZ-CXwdNSVR.js} +4 -4
  461. package/web/assets/{sankeyDiagram-F32LOJ6L-Kd7zjJgX.js → sankeyDiagram-VV74M2VP-CA6jtP9P.js} +3 -3
  462. package/web/assets/{sequenceDiagram-URATNSBD-BlcdY9DS.js → sequenceDiagram-52ZFIFDL-k_5rEbzm.js} +15 -15
  463. package/web/assets/src-Df5C1Nz4.js +1 -0
  464. package/web/assets/stateDiagram-3QAKPIVI-BejHTf31.js +1 -0
  465. package/web/assets/stateDiagram-v2-HN2P4RDZ-BrfoRuOc.js +1 -0
  466. package/web/assets/swimlanes-QLVP42QD-CQSVO5D6.js +1 -0
  467. package/web/assets/swimlanesDiagram-JKPDBFCN-DrWB9kcD.js +8 -0
  468. package/web/assets/{timeline-definition-WJXWRH4I-DUfp1R3E.js → timeline-definition-GS45XAXW-C0Ks8rPP.js} +4 -4
  469. package/web/assets/treeView-Q6P3EWNA-ZRJGANNQ-DmKOCo6L.js +1 -0
  470. package/web/assets/treemap-WGGIJYW6-K64VN5AS-DO3xY92U.js +1 -0
  471. package/web/assets/{vennDiagram-K3VCMQLI-Bj-FN-XS.js → vennDiagram-QIQU2ZRJ-rgPiS837.js} +3 -3
  472. package/web/assets/wardley-WFR3VGLG-D67OWCCH-DiDPBNft.js +1 -0
  473. package/web/assets/wardleyDiagram-U6YNM66N-DRVr7SPi.js +78 -0
  474. package/web/assets/{xychartDiagram-5VRUVLCW-CK_rbSWE.js → xychartDiagram-XJAZEDNM-COtlZzYb.js} +3 -3
  475. package/web/index.html +19 -17
  476. package/web/assets/ProcessFlowModal-Badh2Pbg.js +0 -24
  477. package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +0 -1
  478. package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +0 -36
  479. package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +0 -132
  480. package/web/assets/c4Diagram-X2LASM7V-CnhoT4aV.js +0 -10
  481. package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +0 -127
  482. package/web/assets/chunk-5VCL7Z4A-CQ-2dYWj.js +0 -1
  483. package/web/assets/chunk-6BELYETK-ChsYtfHW.js +0 -1
  484. package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +0 -2
  485. package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +0 -32
  486. package/web/assets/chunk-KRXBNO2N-C-UNuKKf.js +0 -1
  487. package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +0 -321
  488. package/web/assets/chunk-LIEV3EAG-pyKGssV3.js +0 -1
  489. package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +0 -62
  490. package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +0 -10
  491. package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +0 -156
  492. package/web/assets/chunk-SZD42YQK-ijyKKVr1.js +0 -70
  493. package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +0 -231
  494. package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +0 -2
  495. package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +0 -1
  496. package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +0 -1
  497. package/web/assets/chunk-WJBAP47W-BckNkuEN.js +0 -1
  498. package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +0 -1
  499. package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +0 -1
  500. package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +0 -1
  501. package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +0 -4
  502. package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +0 -30
  503. package/web/assets/diagram-KFBZAVDW-Dfmf_4ti.js +0 -3
  504. package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +0 -24
  505. package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +0 -85
  506. package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +0 -1
  507. package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +0 -1
  508. package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +0 -292
  509. package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +0 -1
  510. package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +0 -106
  511. package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +0 -1
  512. package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +0 -2
  513. package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +0 -257
  514. package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +0 -1
  515. package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +0 -1
  516. package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +0 -39
  517. package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +0 -1
  518. package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +0 -1
  519. package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +0 -1
  520. package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +0 -1
  521. package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +0 -1
  522. package/web/assets/src-C5sx_gMp.js +0 -1
  523. package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +0 -1
  524. package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +0 -1
  525. package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +0 -2
  526. package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +0 -8
  527. package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +0 -1
  528. package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +0 -1
  529. package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +0 -1
  530. package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +0 -78
  531. /package/web/assets/{sizeCapture-5GORAGP4-BEqQzsxs.js → sizeCapture-FGA5AGYP-BEqQzsxs.js} +0 -0
@@ -0,0 +1,20 @@
1
+ import { type AnalyzeOptions as CoreAnalyzeOptions } from '../core/run-analyze.js';
2
+ import type { AnalyzerRunnerIdentity } from '../storage/repo-manager.js';
3
+ import type { AnalyzeOptions } from './analyze-options.js';
4
+ import { type WatchRefreshError } from './watch-queue.js';
5
+ export type WatchCliOptions = AnalyzeOptions;
6
+ export declare function isRelevantWatchPath(filePath: string): boolean;
7
+ export interface WatchEnvironmentBaseline {
8
+ readonly maxFileSize: string | undefined;
9
+ readonly workerTimeout: string | undefined;
10
+ readonly verbose: string | undefined;
11
+ }
12
+ export declare function resolveWatchOptions(repoPath: string, cli: WatchCliOptions, baseline: WatchEnvironmentBaseline, reportIgnoredConfig?: (names: readonly string[]) => void): Promise<CoreAnalyzeOptions>;
13
+ export interface WatchFileLoop {
14
+ readonly waitForIdle: () => Promise<void>;
15
+ readonly close: () => Promise<void>;
16
+ }
17
+ export declare function shouldStopAfterWatchRefreshFailure(error: unknown, paths: readonly string[]): boolean;
18
+ /** Start the real filesystem watcher with bounded, serialized refreshes. */
19
+ export declare function startWatchFileLoop(repoPath: string, debounceMs: number, refresh: (paths: readonly string[]) => Promise<void>, onError: WatchRefreshError, onWatcherError?: (error: unknown) => void): Promise<WatchFileLoop>;
20
+ export declare function watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap: AnalyzerRunnerIdentity, inputPath?: string, cliOptions?: WatchCliOptions): Promise<void>;
@@ -0,0 +1,434 @@
1
+ /** Local incremental watch (`gitnexus analyze --watch`). Remote auto-sync lives in `auto-sync.ts`. */
2
+ import path from 'node:path';
3
+ import fs from 'node:fs/promises';
4
+ import { watch } from 'chokidar';
5
+ import { createWatchIgnorePredicate } from '../config/ignore-service.js';
6
+ import { analyzeFailureMayHaveMutatedLiveIndex, runFullAnalysis, } from '../core/run-analyze.js';
7
+ import { getGitRoot, hasGitDir } from '../storage/git.js';
8
+ import { GITNEXUS_DIR } from '../storage/repo-meta.js';
9
+ import { loadAnalyzeConfigStrict, mergeAnalyzeOptions, validateBranchName, } from './analyze-config.js';
10
+ import { ensureHeap } from './analyze.js';
11
+ import { cliError, cliInfo, cliWarn } from './cli-message.js';
12
+ import { WATCH_FULL_REFRESH_PATH, WatchRefreshQueue, } from './watch-queue.js';
13
+ const DEFAULT_DEBOUNCE_MS = 300;
14
+ const MAX_TIMER_DELAY_MS = 2_147_483_647;
15
+ const MAX_FILE_SIZE_KB = 32 * 1024;
16
+ const TRANSIENT_WATCH_ERROR_CODES = new Set(['EACCES', 'ENOENT', 'ENOTDIR', 'EPERM']);
17
+ function posixWatchPath(filePath) {
18
+ return filePath.replace(/\\/g, '/').replace(/^\.\/+/, '');
19
+ }
20
+ export function isRelevantWatchPath(filePath) {
21
+ const normalized = posixWatchPath(filePath);
22
+ return (normalized.length > 0 &&
23
+ normalized !== '.' &&
24
+ !normalized.startsWith('../') &&
25
+ !path.posix.isAbsolute(normalized) &&
26
+ !path.win32.isAbsolute(filePath));
27
+ }
28
+ function isIgnoreControlPath(filePath) {
29
+ const normalized = posixWatchPath(filePath);
30
+ return normalized === '.gitignore' || normalized === '.gitnexusignore';
31
+ }
32
+ function isConfigControlPath(filePath) {
33
+ return posixWatchPath(filePath) === '.gitnexusrc';
34
+ }
35
+ function isAnalyzerOwnedWatchPath(filePath) {
36
+ const normalized = posixWatchPath(filePath).replace(/\/+$/, '');
37
+ return normalized === GITNEXUS_DIR || normalized.startsWith(`${GITNEXUS_DIR}/`);
38
+ }
39
+ function repoRelativeWatchPath(repoPath, candidate) {
40
+ const relative = path.relative(repoPath, candidate).replace(/\\/g, '/');
41
+ if (!relative || relative.startsWith('../') || path.isAbsolute(relative))
42
+ return null;
43
+ return relative;
44
+ }
45
+ function setEnvironment(name, value) {
46
+ if (value === undefined)
47
+ delete process.env[name];
48
+ else
49
+ process.env[name] = value;
50
+ }
51
+ function positiveInteger(value, flag, maximum) {
52
+ if (value === undefined)
53
+ return undefined;
54
+ const parsed = Number(value);
55
+ if (!Number.isInteger(parsed) || parsed < 1)
56
+ throw new Error(`${flag} must be a positive integer`);
57
+ if (maximum !== undefined && parsed > maximum) {
58
+ throw new Error(`${flag} must not exceed ${maximum}`);
59
+ }
60
+ return parsed;
61
+ }
62
+ export async function resolveWatchOptions(repoPath, cli, baseline, reportIgnoredConfig = () => { }) {
63
+ const config = (await loadAnalyzeConfigStrict(repoPath)) ?? {};
64
+ const merged = mergeAnalyzeOptions(cli, config);
65
+ const unsupported = [
66
+ ['--force', cli.force],
67
+ ['--no-parse-cache', cli.parseCache === false],
68
+ ['--repair-fts', cli.repairFts],
69
+ ['--embeddings', cli.embeddings],
70
+ ['--drop-embeddings', cli.dropEmbeddings],
71
+ ['--skills', cli.skills],
72
+ ['--default-branch', cli.defaultBranch],
73
+ ['--skip-agents-md', cli.skipAgentsMd],
74
+ ['--skip-skills', cli.skipSkills],
75
+ ['--no-stats', cli.stats === false],
76
+ ['--self-commit', cli.selfCommit],
77
+ ['--index-only', cli.indexOnly],
78
+ ['--skip-git', cli.skipGit],
79
+ ['--spring-actuator', cli.springActuator],
80
+ // Rejected under --watch for the same reason as --spring-actuator: the
81
+ // watcher reacts to source changes, and nothing watches an out-of-band
82
+ // document directory. Honouring the flag here would read the documents once
83
+ // and then quietly serve a stale answer for the rest of the session.
84
+ ['--asyncapi-spec', cli.asyncapiSpec],
85
+ ['walCheckpointThreshold', cli.walCheckpointThreshold],
86
+ ['embeddingThreads', cli.embeddingThreads],
87
+ ['embeddingBatchSize', cli.embeddingBatchSize],
88
+ ['embeddingSubBatchSize', cli.embeddingSubBatchSize],
89
+ ['embeddingDevice', cli.embeddingDevice],
90
+ ['embeddingBaseUrl', cli.embeddingBaseUrl],
91
+ ['embeddingModel', cli.embeddingModel],
92
+ ['--embedding-auth-token', cli.embeddingAuthToken],
93
+ ['--embedding-dims', cli.embeddingDims],
94
+ ].filter(([, value]) => value !== undefined && value !== false);
95
+ if (unsupported.length > 0) {
96
+ throw new Error(`analyze --watch does not support ${unsupported.map(([name]) => name).join(', ')}`);
97
+ }
98
+ reportIgnoredConfig([
99
+ ['embeddings', config.embeddings],
100
+ ['dropEmbeddings', config.dropEmbeddings],
101
+ ['defaultBranch', config.defaultBranch],
102
+ ['skipAgentsMd', config.skipAgentsMd !== undefined],
103
+ ['skipSkills', config.skipSkills !== undefined],
104
+ ['stats', config.stats !== undefined],
105
+ ['springActuator', config.springActuator],
106
+ ['walCheckpointThreshold', config.walCheckpointThreshold],
107
+ ['embeddingThreads', config.embeddingThreads],
108
+ ['embeddingBatchSize', config.embeddingBatchSize],
109
+ ['embeddingSubBatchSize', config.embeddingSubBatchSize],
110
+ ['embeddingDevice', config.embeddingDevice],
111
+ ['embeddingBaseUrl', config.embeddingBaseUrl],
112
+ ['embeddingModel', config.embeddingModel],
113
+ ]
114
+ .filter(([, value]) => value !== undefined && value !== false)
115
+ .map(([name]) => String(name)));
116
+ const branch = merged.branch === undefined ? undefined : validateBranchName(merged.branch, '--branch');
117
+ const workerPoolSize = positiveInteger(merged.workers, '--workers');
118
+ const workerTimeoutSeconds = positiveInteger(merged.workerTimeout, 'workerTimeout');
119
+ const maxFileSize = positiveInteger(merged.maxFileSize, 'maxFileSize', MAX_FILE_SIZE_KB);
120
+ setEnvironment('GITNEXUS_MAX_FILE_SIZE', maxFileSize === undefined ? baseline.maxFileSize : String(maxFileSize));
121
+ if (workerTimeoutSeconds !== undefined) {
122
+ process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS = String(workerTimeoutSeconds * 1000);
123
+ }
124
+ else {
125
+ setEnvironment('GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS', baseline.workerTimeout);
126
+ }
127
+ setEnvironment('GITNEXUS_VERBOSE', merged.verbose ? '1' : baseline.verbose);
128
+ return {
129
+ pdg: merged.pdg,
130
+ branch,
131
+ registryName: merged.name,
132
+ allowDuplicateName: merged.allowDuplicateName,
133
+ workerPoolSize,
134
+ fetchWrappers: merged.fetchWrappers,
135
+ skipAgentsMd: true,
136
+ skipSkills: true,
137
+ noStats: true,
138
+ atomicIncremental: process.platform !== 'win32',
139
+ };
140
+ }
141
+ function refreshSummary(result, observedPaths, durationMs, lastSuccessfulRefreshAt) {
142
+ const measured = result.incrementalStats;
143
+ const changed = measured?.changedFiles ?? (result.alreadyUpToDate ? 0 : observedPaths.length);
144
+ const reparsed = measured?.reparsedFiles ??
145
+ (typeof result.pipelineResult?.reparsedFileCount === 'number'
146
+ ? result.pipelineResult.reparsedFileCount
147
+ : 0);
148
+ const dependents = measured?.affectedDependents ?? 0;
149
+ const mode = measured?.writeMode ?? (result.alreadyUpToDate ? 'no-op' : 'full');
150
+ return (`Refresh complete: ${changed} changed, ${reparsed} re-parsed, ` +
151
+ `${dependents} affected dependent(s), ${durationMs}ms, ${mode}; ` +
152
+ `last success ${lastSuccessfulRefreshAt}`);
153
+ }
154
+ async function waitUntilReady(watcher) {
155
+ await new Promise((resolve, reject) => {
156
+ const ready = () => {
157
+ watcher.off('error', failed);
158
+ resolve();
159
+ };
160
+ const failed = (error) => {
161
+ watcher.off('ready', ready);
162
+ reject(error);
163
+ };
164
+ watcher.once('ready', ready);
165
+ watcher.once('error', failed);
166
+ });
167
+ }
168
+ class WatchControlReloadError extends Error {
169
+ constructor(cause) {
170
+ super(cause instanceof Error ? cause.message : String(cause), { cause });
171
+ this.name = 'WatchControlReloadError';
172
+ }
173
+ }
174
+ export function shouldStopAfterWatchRefreshFailure(error, paths) {
175
+ return (paths.length > 0 &&
176
+ !(error instanceof WatchControlReloadError) &&
177
+ analyzeFailureMayHaveMutatedLiveIndex(error));
178
+ }
179
+ /** Start the real filesystem watcher with bounded, serialized refreshes. */
180
+ export async function startWatchFileLoop(repoPath, debounceMs, refresh, onError, onWatcherError = (error) => onError(error, [])) {
181
+ let ignorePath = await createWatchIgnorePredicate(repoPath);
182
+ let ignoreControlValid = true;
183
+ let rearmPending = false;
184
+ let closed = false;
185
+ const queue = new WatchRefreshQueue(async (paths) => {
186
+ if (paths.some(isIgnoreControlPath) || !ignoreControlValid) {
187
+ const retryingInvalidControls = !ignoreControlValid;
188
+ try {
189
+ ignorePath = await createWatchIgnorePredicate(repoPath);
190
+ ignoreControlValid = true;
191
+ rearmPending = true;
192
+ }
193
+ catch (error) {
194
+ ignoreControlValid = false;
195
+ throw new WatchControlReloadError(retryingInvalidControls
196
+ ? new Error('Ignore controls remain invalid; fix them before indexing more changes.', {
197
+ cause: error,
198
+ })
199
+ : error);
200
+ }
201
+ }
202
+ // Re-arm before refreshing, never after: the refresh reads the whole
203
+ // repository, so a write that lands while the replacement watcher is
204
+ // arming is still picked up by this refresh, and a write that lands
205
+ // afterwards is reported by the armed watcher.
206
+ if (rearmPending)
207
+ await rearmWatcher();
208
+ await refresh(paths);
209
+ }, onError, debounceMs, {
210
+ maxWaitMs: Math.max(2_000, debounceMs * 10),
211
+ maxPendingPaths: 1_000,
212
+ holdEventsUntilInitialRefresh: true,
213
+ isPriorityPath: (filePath) => isIgnoreControlPath(filePath) || isConfigControlPath(filePath),
214
+ });
215
+ const createWatcher = () => {
216
+ const created = watch(repoPath, {
217
+ ignoreInitial: true,
218
+ atomic: true,
219
+ followSymlinks: false,
220
+ awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 20 },
221
+ ignored: (candidate, stats) => {
222
+ const relative = repoRelativeWatchPath(repoPath, candidate);
223
+ if (relative !== null && isAnalyzerOwnedWatchPath(relative))
224
+ return true;
225
+ if (relative !== null && (isIgnoreControlPath(relative) || isConfigControlPath(relative))) {
226
+ return false;
227
+ }
228
+ return ignorePath(candidate, stats?.isDirectory() ?? false);
229
+ },
230
+ });
231
+ // Events from an instance being retired are kept: they overlap with the
232
+ // replacement's coverage and the queue coalesces the duplicates.
233
+ created.on('all', (event, changedPath) => {
234
+ if (event !== 'add' && event !== 'change' && event !== 'unlink')
235
+ return;
236
+ const relative = repoRelativeWatchPath(repoPath, changedPath);
237
+ if (relative && isRelevantWatchPath(relative) && !isAnalyzerOwnedWatchPath(relative)) {
238
+ queue.enqueue(relative);
239
+ }
240
+ });
241
+ created.on('error', (error) => {
242
+ // Replacement failures before the swap are reported through `waitUntilReady`.
243
+ if (created !== watcher)
244
+ return;
245
+ // Chokidar can surface a transient EPERM on Windows while an ignored
246
+ // analyzer-owned path is replaced. Re-arm the watcher and force one
247
+ // bounded catch-up refresh so a missed event cannot leave the graph
248
+ // stale. Other watcher errors may mean coverage was lost and stay fatal.
249
+ if (TRANSIENT_WATCH_ERROR_CODES.has(error.code ?? '')) {
250
+ rearmPending = true;
251
+ queue.enqueue(WATCH_FULL_REFRESH_PATH);
252
+ return;
253
+ }
254
+ onWatcherError(error);
255
+ });
256
+ return created;
257
+ };
258
+ let watcher = createWatcher();
259
+ // Chokidar emits `ready` once per instance and `add()` returns before the
260
+ // rescan it starts has finished, with no signal for that completion. A file
261
+ // an ignore-rule reload has just unignored is therefore still unregistered
262
+ // when `add()` returns, and because `ignoreInitial` suppresses the `add` the
263
+ // rescan would emit, an immediate rewrite of that file is dropped for good
264
+ // (reproduced on chokidar 4 and 5). So re-arm by arming a replacement
265
+ // watcher and awaiting its `ready` instead. The outgoing instance keeps
266
+ // reporting until the replacement is armed, so the swap has no blind window,
267
+ // and a replacement that fails to arm leaves the working instance in place.
268
+ const rearmWatcher = async () => {
269
+ rearmPending = false;
270
+ if (closed)
271
+ return;
272
+ const replacement = createWatcher();
273
+ try {
274
+ await waitUntilReady(replacement);
275
+ }
276
+ catch (error) {
277
+ rearmPending = true;
278
+ try {
279
+ await replacement.close();
280
+ }
281
+ catch {
282
+ // The instance never became live; the arm error is the one to report.
283
+ }
284
+ throw new WatchControlReloadError(new Error('Unable to re-arm the filesystem watcher', { cause: error }));
285
+ }
286
+ const retired = watcher;
287
+ watcher = replacement;
288
+ await retired.close();
289
+ // `close()` can land between arming the replacement and the swap above.
290
+ if (closed)
291
+ await replacement.close();
292
+ };
293
+ try {
294
+ await waitUntilReady(watcher);
295
+ await queue.runInitial();
296
+ }
297
+ catch (error) {
298
+ closed = true;
299
+ await watcher.close();
300
+ await queue.close();
301
+ throw error;
302
+ }
303
+ return {
304
+ waitForIdle: () => queue.waitForIdle(),
305
+ close: async () => {
306
+ closed = true;
307
+ await watcher.close();
308
+ await queue.close();
309
+ },
310
+ };
311
+ }
312
+ export async function watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, cliOptions = {}) {
313
+ if (await ensureHeap({ cleanForwardedTermination: true }))
314
+ return;
315
+ const requestedRepoPath = inputPath ? path.resolve(inputPath) : getGitRoot(process.cwd());
316
+ if (requestedRepoPath === null || !hasGitDir(requestedRepoPath)) {
317
+ cliError(' gitnexus analyze --watch requires a Git repository.');
318
+ process.exitCode = 1;
319
+ return;
320
+ }
321
+ const repoPath = await fs.realpath(requestedRepoPath);
322
+ const baselineEnvironment = {
323
+ maxFileSize: process.env.GITNEXUS_MAX_FILE_SIZE,
324
+ workerTimeout: process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS,
325
+ verbose: process.env.GITNEXUS_VERBOSE,
326
+ };
327
+ try {
328
+ let ignoredConfigSignature;
329
+ const reportIgnoredConfig = (names) => {
330
+ const signature = [...names].sort().join(',');
331
+ if (signature === ignoredConfigSignature)
332
+ return;
333
+ ignoredConfigSignature = signature;
334
+ if (names.length > 0) {
335
+ cliWarn(`Watch mode ignores unsupported .gitnexusrc settings: ${names.join(', ')}.`);
336
+ }
337
+ };
338
+ let debounceMs;
339
+ let analyzeOptions;
340
+ try {
341
+ debounceMs =
342
+ positiveInteger(cliOptions.debounce ?? String(DEFAULT_DEBOUNCE_MS), '--debounce', MAX_TIMER_DELAY_MS) ?? DEFAULT_DEBOUNCE_MS;
343
+ analyzeOptions = await resolveWatchOptions(repoPath, cliOptions, baselineEnvironment, reportIgnoredConfig);
344
+ }
345
+ catch (error) {
346
+ cliError(` ${error instanceof Error ? error.message : String(error)}`);
347
+ process.exitCode = 1;
348
+ return;
349
+ }
350
+ let stopWatching;
351
+ const stopped = new Promise((resolve) => {
352
+ stopWatching = resolve;
353
+ });
354
+ const stop = () => stopWatching();
355
+ process.once('SIGINT', stop);
356
+ process.once('SIGTERM', stop);
357
+ try {
358
+ let loop;
359
+ let fatalRefreshError;
360
+ let configControlValid = true;
361
+ let lastSuccessfulRefreshAt;
362
+ try {
363
+ loop = await startWatchFileLoop(repoPath, debounceMs, async (paths) => {
364
+ if (paths.some(isConfigControlPath) || !configControlValid) {
365
+ const retryingInvalidConfig = !configControlValid;
366
+ try {
367
+ analyzeOptions = await resolveWatchOptions(repoPath, cliOptions, baselineEnvironment, reportIgnoredConfig);
368
+ configControlValid = true;
369
+ }
370
+ catch (error) {
371
+ configControlValid = false;
372
+ throw new WatchControlReloadError(retryingInvalidConfig
373
+ ? new Error('Configuration remains invalid; fix it before indexing more changes.', {
374
+ cause: error,
375
+ })
376
+ : error);
377
+ }
378
+ }
379
+ const startedAt = Date.now();
380
+ const result = await runFullAnalysis(repoPath, analyzeOptions, {
381
+ onProgress: () => { },
382
+ onLog: process.env.GITNEXUS_VERBOSE === '1'
383
+ ? (message) => cliInfo(` ${message}`)
384
+ : undefined,
385
+ }, runnerIdentityAtBootstrap);
386
+ lastSuccessfulRefreshAt = new Date().toISOString();
387
+ if (paths.length === 0) {
388
+ cliInfo(result.alreadyUpToDate
389
+ ? `Watching ${repoPath}; index is up to date.`
390
+ : `Watching ${repoPath}; initial index ready in ${Date.now() - startedAt}ms.`);
391
+ }
392
+ else {
393
+ cliInfo(refreshSummary(result, paths, Date.now() - startedAt, lastSuccessfulRefreshAt));
394
+ }
395
+ }, (error, paths) => {
396
+ const detail = paths.length > 0 ? ` (${paths.length} queued path(s))` : '';
397
+ if (shouldStopAfterWatchRefreshFailure(error, paths)) {
398
+ fatalRefreshError = error;
399
+ cliError(`Refresh failed${detail}: ${error instanceof Error ? error.message : String(error)}. ` +
400
+ 'Watch mode is stopping because the live index may have been updated in place.');
401
+ stopWatching();
402
+ return;
403
+ }
404
+ const lastSuccess = lastSuccessfulRefreshAt ?? 'none yet';
405
+ cliWarn(`Refresh failed${detail}: ${error instanceof Error ? error.message : String(error)}. ` +
406
+ `Retry scheduled; last success ${lastSuccess}.`);
407
+ }, (error) => {
408
+ fatalRefreshError = error;
409
+ cliError(`Watcher failed: ${error instanceof Error ? error.message : String(error)}. ` +
410
+ 'Watch mode is stopping.');
411
+ stopWatching();
412
+ });
413
+ }
414
+ catch (error) {
415
+ cliError(` Unable to start watcher: ${error instanceof Error ? error.message : String(error)}`);
416
+ process.exitCode = 1;
417
+ return;
418
+ }
419
+ await stopped;
420
+ await loop.close();
421
+ if (fatalRefreshError !== undefined)
422
+ process.exitCode = 1;
423
+ }
424
+ finally {
425
+ process.removeListener('SIGINT', stop);
426
+ process.removeListener('SIGTERM', stop);
427
+ }
428
+ }
429
+ finally {
430
+ setEnvironment('GITNEXUS_MAX_FILE_SIZE', baselineEnvironment.maxFileSize);
431
+ setEnvironment('GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS', baselineEnvironment.workerTimeout);
432
+ setEnvironment('GITNEXUS_VERBOSE', baselineEnvironment.verbose);
433
+ }
434
+ }
@@ -524,6 +524,8 @@ const ANALYZE_CLI_ENV_KEYS = [
524
524
  'GITNEXUS_EMBEDDING_SUB_BATCH_SIZE',
525
525
  'GITNEXUS_EMBEDDING_DEVICE',
526
526
  'GITNEXUS_ANALYZE_PROGRESS_ACTIVE',
527
+ 'GITNEXUS_ANALYZER_IDENTITY_IN_PROCESS_GUARDS',
528
+ 'GITNEXUS_RESOLVE_DEF_GRAPH_ID_MEMO',
527
529
  'GITNEXUS_EMBEDDING_URL',
528
530
  'GITNEXUS_EMBEDDING_MODEL',
529
531
  'GITNEXUS_EMBEDDING_API_KEY',
@@ -600,14 +602,13 @@ export const analyzeCommand = async (inputPath, options, runnerIdentityAtBootstr
600
602
  export const analyzeCommandWithRunnerIdentity = async (runnerIdentityAtBootstrap, inputPath, options) => analyzeCommand(inputPath, options, runnerIdentityAtBootstrap);
601
603
  export async function analyzeOrWatchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options = {}) {
602
604
  if (options.watch) {
603
- const { watchCommandWithRunnerIdentity } = await import('./watch.js');
605
+ const { watchCommandWithRunnerIdentity } = await import('./analyze-watch.js');
604
606
  await watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
605
607
  return;
606
608
  }
607
609
  await analyzeCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
608
610
  }
609
611
  const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstrap) => {
610
- console.log('\n GitNexus Analyzer\n');
611
612
  // ── Resolve the target repo root ──────────────────────────────────
612
613
  // Resolved FIRST because `.gitnexusrc` is read from the repo root (not the
613
614
  // caller's cwd), and config can set defaults that the validation below
@@ -784,6 +785,16 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
784
785
  !setPositiveEnv('--embedding-sub-batch-size', 'GITNEXUS_EMBEDDING_SUB_BATCH_SIZE', options.embeddingSubBatchSize)) {
785
786
  return;
786
787
  }
788
+ // An empty value resolves to the repository root, so `--asyncapi-spec ""`
789
+ // walks the whole tree — defeating the module's own rule that there is no
790
+ // glob-based auto-discovery, and spending the walk budget on `node_modules`.
791
+ // The HTTP entry point already rejects exactly this value; two doors onto one
792
+ // option must not hold different rules.
793
+ if (options.asyncapiSpec !== undefined && options.asyncapiSpec.trim() === '') {
794
+ cliError(' --asyncapi-spec must be a non-empty path.\n');
795
+ process.exitCode = 1;
796
+ return;
797
+ }
787
798
  if (options.embeddingDevice) {
788
799
  const allowed = new Set(['auto', 'cpu', 'dml', 'cuda', 'wasm']);
789
800
  if (!allowed.has(options.embeddingDevice)) {
@@ -928,9 +939,9 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
928
939
  }
929
940
  }
930
941
  }
931
- if (options.repairFts && options.force) {
932
- cliError(' Cannot combine `--repair-fts` with `--force`. ' +
933
- 'Use `--repair-fts` for fast FTS-only repair, or `--force` for a full rebuild.\n');
942
+ if (options.repairFts && (options.force || options.parseCache === false)) {
943
+ cliError(' Cannot combine `--repair-fts` with a full rebuild. ' +
944
+ 'Use `--repair-fts` alone for fast FTS-only repair.\n');
934
945
  process.exitCode = 1;
935
946
  return;
936
947
  }
@@ -1072,10 +1083,11 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
1072
1083
  const skipAgentsMd = skipAll || options.skipAgentsMd;
1073
1084
  const skipSkills = skipAll || options.skipSkills;
1074
1085
  const runOptions = {
1075
- // Pipeline re-index — OR'd with --skills because skill generation
1076
- // needs a fresh pipelineResult. Has no bearing on the registry
1077
- // collision guard (see allowDuplicateName below).
1078
- force: options.force || options.skills,
1086
+ // Pipeline re-index — OR'd with --skills because skill generation needs
1087
+ // a fresh pipelineResult, and with --no-parse-cache because bypassing
1088
+ // parser output is meaningful only when the pipeline runs.
1089
+ force: options.force || options.skills || options.parseCache === false,
1090
+ useParseCache: options.parseCache !== false,
1079
1091
  repairFts: options.repairFts,
1080
1092
  embeddings: embeddingsEnabled,
1081
1093
  embeddingsNodeLimit,
@@ -1112,6 +1124,8 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
1112
1124
  // Extra fetch-wrapper names from `.gitnexusrc` (#1589/#1852 residual);
1113
1125
  // forwarded to the routes phase consumer scan.
1114
1126
  fetchWrappers: options.fetchWrappers,
1127
+ springActuatorPath: options.springActuator,
1128
+ asyncApiSpecPath: options.asyncapiSpec,
1115
1129
  // The CLI always process.exit()s after this returns (success path at the
1116
1130
  // end of analyzeCommandImpl, error/interrupt paths via process.exit too),
1117
1131
  // so the finalize close skips the native conn/db close — it can double-free
@@ -1173,6 +1187,9 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
1173
1187
  console.error = origError;
1174
1188
  bar.stop();
1175
1189
  console.log(' Already up to date\n');
1190
+ if (runOptions.registryName) {
1191
+ console.log(` Registry name: ${result.repoName}\n`);
1192
+ }
1176
1193
  if (baseRefRefreshed.length > 0) {
1177
1194
  console.log(` Updated base_ref to "${resolvedDefaultBranch}" in ${baseRefRefreshed.join(', ')}\n`);
1178
1195
  }
@@ -1247,6 +1264,7 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
1247
1264
  // exercised on the `--skills` path by analyze-no-stats-bridge.test.ts.
1248
1265
  noStats: options.stats === false,
1249
1266
  hasPdg: options.pdg === true,
1267
+ hasSpringActuator: options.springActuator !== undefined,
1250
1268
  });
1251
1269
  }
1252
1270
  }
@@ -0,0 +1 @@
1
+ export declare function autoSyncCommand(action?: string): Promise<void>;
@@ -0,0 +1,107 @@
1
+ /** Remote auto-sync CLI (`gitnexus auto-sync`). Local incremental watch lives in `analyze-watch.ts`. */
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { getAutoSyncConfigPath, getAutoSyncMutexPath, readAutoSyncWatchStatus, resetAutoSyncState, startAutoSyncWatch, stopAutoSyncWatch, } from '../core/auto-sync/index.js';
5
+ export async function autoSyncCommand(action = 'start') {
6
+ if (action === 'init') {
7
+ await initWatchConfig();
8
+ return;
9
+ }
10
+ if (action === 'reset') {
11
+ if (!(await resetAutoSyncState())) {
12
+ process.stderr.write(`[auto-sync] Cannot reset analysis state while the watch mutex is held. Confirm no watch process is running, then remove ${getAutoSyncMutexPath()}.\n`);
13
+ process.exitCode = 1;
14
+ return;
15
+ }
16
+ process.stdout.write('[auto-sync] Reset analysis state.\n');
17
+ return;
18
+ }
19
+ if (action === 'status') {
20
+ printStatus(await readAutoSyncWatchStatus());
21
+ return;
22
+ }
23
+ if (action === 'stop') {
24
+ if ((await stopAutoSyncWatch()) !== 'stopped')
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ if (action === 'restart') {
29
+ const result = await stopAutoSyncWatch();
30
+ if (result === 'refused' || result === 'timeout') {
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ await startWatchProcess();
35
+ return;
36
+ }
37
+ if (action !== 'start') {
38
+ process.stderr.write(`[auto-sync] Unknown auto-sync action: ${action}\n`);
39
+ process.exitCode = 1;
40
+ return;
41
+ }
42
+ await startWatchProcess();
43
+ }
44
+ async function startWatchProcess() {
45
+ const handle = await startAutoSyncWatch();
46
+ if (!handle) {
47
+ process.exitCode = 1;
48
+ return;
49
+ }
50
+ const stop = () => {
51
+ void handle.stop().then(() => {
52
+ process.stderr.write('[auto-sync] Watch stopped.\n');
53
+ process.exit(0);
54
+ }, (error) => {
55
+ const message = error instanceof Error ? error.message : String(error);
56
+ process.stderr.write(`[auto-sync] Failed to stop watch: ${message}\n`);
57
+ process.exit(1);
58
+ });
59
+ };
60
+ process.once('SIGINT', stop);
61
+ process.once('SIGTERM', stop);
62
+ }
63
+ function printStatus(status) {
64
+ const parts = [`state=${status.state}`];
65
+ if (status.pid)
66
+ parts.push(`pid=${status.pid}`);
67
+ if (status.configPath)
68
+ parts.push(`config=${status.configPath}`);
69
+ if (status.message)
70
+ parts.push(`message=${status.message}`);
71
+ parts.push(`updated_at=${status.updatedAt}`);
72
+ process.stdout.write(`${parts.join(' ')}\n`);
73
+ }
74
+ async function initWatchConfig() {
75
+ const configPath = getAutoSyncConfigPath();
76
+ try {
77
+ await fs.mkdir(path.dirname(configPath), { recursive: true });
78
+ await fs.writeFile(configPath, defaultSyncConfig(path.resolve(path.dirname(configPath), 'repos')), {
79
+ flag: 'wx',
80
+ });
81
+ }
82
+ catch (err) {
83
+ if (err.code === 'EEXIST') {
84
+ process.stderr.write(`[auto-sync] Config already exists: ${configPath}\n`);
85
+ process.exitCode = 1;
86
+ return;
87
+ }
88
+ throw err;
89
+ }
90
+ process.stdout.write(`[auto-sync] Created ${configPath}\n`);
91
+ }
92
+ function defaultSyncConfig(localPath) {
93
+ return [
94
+ 'sync_interval_minutes: 10',
95
+ 'max_concurrency: 1',
96
+ 'repo_git_timeout: 10s',
97
+ 'analyze_timeout: 5m',
98
+ 'analyze_failure_threshold: 3',
99
+ 'projects:',
100
+ ` - local_path: ${localPath}`,
101
+ ' branches: [master, main]',
102
+ ' overwrite_local_changes: false',
103
+ ' remote_urls:',
104
+ ' - git@github.com:owner/repo.git',
105
+ '',
106
+ ].join('\n');
107
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * One-line identity printed before every CLI action:
3
+ * `GitNexus Analyzer (1.6.10)`. Goes to stderr so stdout stays
4
+ * pipe/JSON-safe (`gitnexus query … | jq`, `status --json`).
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function installedCliVersion(): string;
8
+ export declare function commandDisplayName(name: string): string;
9
+ export declare function commandBannerTitle(command: Command): string;
10
+ export declare function formatCommandBanner(title: string, version?: string): string;
11
+ export interface WriteCommandBannerDependencies {
12
+ write?: (text: string) => void;
13
+ version?: string;
14
+ }
15
+ export declare function writeCommandBanner(command: Command, deps?: WriteCommandBannerDependencies): void;