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
@@ -260,6 +260,9 @@ export const FUNCTION_NODE_TYPES = new Set([
260
260
  // Dart
261
261
  'function_signature',
262
262
  'method_signature',
263
+ // Zig: `test "…" { }` bodies are callable scopes — calls inside attribute
264
+ // to the test, not the file. Named via methodExtractor.extractFunctionName.
265
+ 'test_declaration',
263
266
  ]);
264
267
  /**
265
268
  * AST node types that represent a class-like container (for HAS_METHOD edge extraction).
@@ -308,6 +311,9 @@ export const CLASS_CONTAINER_TYPES = new Set([
308
311
  // Go
309
312
  'struct_type',
310
313
  'interface_type',
314
+ // Zig
315
+ 'union_declaration',
316
+ 'opaque_declaration',
311
317
  ]);
312
318
  /**
313
319
  * Node types whose OWN node id must not be re-keyed by an enclosing-scope
@@ -374,6 +380,12 @@ export const CONTAINER_TYPE_TO_LABEL = {
374
380
  companion_object: 'Class',
375
381
  struct_type: 'Struct',
376
382
  interface_type: 'Interface',
383
+ // Zig: tagged and untagged unions are class-like containers, and so is
384
+ // the fieldless `opaque {}` (may own methods; labelled Struct, see
385
+ // ZIG_QUERIES). `struct_declaration` and `enum_declaration` are already
386
+ // present (Dart / generic).
387
+ union_declaration: 'Union',
388
+ opaque_declaration: 'Struct',
377
389
  };
378
390
  /**
379
391
  * Pre-order walk over a node and all its named descendants, invoking `cb` on
@@ -397,6 +409,24 @@ export function walkNamedTree(node, cb) {
397
409
  walkNamedTree(child, cb);
398
410
  }
399
411
  }
412
+ /**
413
+ * True when a node is, or contains, tree-sitter error recovery.
414
+ *
415
+ * After a syntax error the parser keeps going by guessing node boundaries, so
416
+ * the surviving tree stays WELL FORMED while describing text that was never
417
+ * written that way: an unterminated argument list can absorb the source of the
418
+ * next declaration into an `ERROR` child, and an assignment with no right-hand
419
+ * side gets a `MISSING` value node whose text is invented. A capture that reads
420
+ * such a subtree emits facts that look ordinary and are false, which is worse
421
+ * than emitting nothing — so callers that record source text verbatim should
422
+ * check this first and fail closed.
423
+ *
424
+ * `hasError` covers the subtree; `isMissing` is checked as well because a node
425
+ * inserted by recovery is the one case where the node itself carries the flag.
426
+ */
427
+ export function hasRecoveredSyntax(node) {
428
+ return node.hasError || node.isMissing;
429
+ }
400
430
  /** Return the first matching ancestor unless a boundary ancestor is reached first. */
401
431
  export function findAncestorBeforeBoundary(node, targetTypes, boundaryTypes) {
402
432
  let current = node.parent;
@@ -484,13 +514,16 @@ export function getLabelFromCaptures(captureMap, provider) {
484
514
  return null;
485
515
  const hasDefaultExportHocNameSeed = captureMap['definition.function'] !== undefined &&
486
516
  (captureMap['hoc'] !== undefined || captureMap['callee'] !== undefined);
487
- // Nameless `definition.class` passes through: a class extractor may
488
- // synthesize the name (Java anonymous class bodies → `Worker$N`, #2550).
489
- // Downstream stays safe — parse-worker skips any nameless definition the
490
- // extractor could not name (its `!nameNode && !extractedClassSymbol` gate).
517
+ // Nameless `definition.class` / `definition.struct` pass through: a class
518
+ // extractor may synthesize the name (Java anonymous class bodies →
519
+ // `Worker$N`, #2550; a file-level type named after its file — the
520
+ // extractor receives the file path for exactly this). Downstream stays
521
+ // safe — parse-worker skips any nameless definition the extractor could
522
+ // not name (its `!nameNode && !extractedClassSymbol` gate).
491
523
  if (!captureMap['name'] &&
492
524
  !captureMap['definition.constructor'] &&
493
525
  !captureMap['definition.class'] &&
526
+ !captureMap['definition.struct'] &&
494
527
  !hasDefaultExportHocNameSeed)
495
528
  return null;
496
529
  if (captureMap['definition.function']) {
@@ -691,6 +724,31 @@ const javaBinaryNameOfType = (node) => {
691
724
  const enclosingName = javaBinaryNameOfType(enclosing);
692
725
  return enclosingName === undefined ? undefined : `${enclosingName}$${simpleName}`;
693
726
  };
727
+ /**
728
+ * For a container node that is the direct `return` value of a function whose
729
+ * declared return type is the literal `type` (`fn List(comptime T: type) type
730
+ * { return struct {…}; }`), the function's `name` node; undefined otherwise.
731
+ * Language-agnostic by shape — today only tree-sitter-zig produces it.
732
+ */
733
+ function typeConstructorNameNode(container) {
734
+ const ret = container.parent;
735
+ if (ret?.type !== 'return_expression')
736
+ return undefined;
737
+ const stmt = ret.parent;
738
+ if (stmt?.type !== 'expression_statement')
739
+ return undefined;
740
+ const block = stmt.parent;
741
+ if (block?.type !== 'block')
742
+ return undefined;
743
+ const fn = block.parent;
744
+ if (fn?.type !== 'function_declaration')
745
+ return undefined;
746
+ if (fn.childForFieldName?.('body')?.id !== block.id)
747
+ return undefined;
748
+ if (fn.childForFieldName?.('type')?.text !== 'type')
749
+ return undefined;
750
+ return fn.childForFieldName?.('name') ?? undefined;
751
+ }
694
752
  /**
695
753
  * Authoritative Java local/anonymous type identity.
696
754
  *
@@ -756,7 +814,24 @@ export const findEnclosingClassInfo = (node, filePath, resolveEnclosingOwner,
756
814
  * class-container branch to compute `qualifiedClassId` from the SAME function
757
815
  * the node-id is built from, guaranteeing owner-id == node-id by construction.
758
816
  */
759
- getQualifiedOwnerName) => {
817
+ getQualifiedOwnerName,
818
+ /**
819
+ * Optional: the type the whole FILE declares (`LanguageProvider.resolveFileTypeOwner`).
820
+ * Consulted only when the walk reaches the tree root without meeting a
821
+ * container, so a member declared at file level can be owned by the file's
822
+ * own type (Zig file-structs). The name is what the definition phase names
823
+ * the class-like node, so owner id == node id by construction.
824
+ */
825
+ resolveFileTypeOwner,
826
+ /**
827
+ * Optional: the type a CONTAINER node declares
828
+ * (`LanguageProvider.resolveContainerTypeOwner`). Consulted for every
829
+ * `CLASS_CONTAINER_TYPES` node the walk meets, before the generic name-child
830
+ * derivation, for languages whose containers are named from context (a
831
+ * binding wrapper, an enclosing callable, an anonymous ordinal). Null falls
832
+ * through to the generic derivation.
833
+ */
834
+ resolveContainerTypeOwner) => {
760
835
  let current = node.parent;
761
836
  let iterations = 0;
762
837
  // Tracks container nodes already visited via the hook so a misbehaving hook
@@ -850,6 +925,18 @@ getQualifiedOwnerName) => {
850
925
  continue;
851
926
  }
852
927
  }
928
+ // A container the PROVIDER names from context (binding wrapper,
929
+ // enclosing callable, anonymous ordinal — Zig). The name is what the
930
+ // class-like node is minted under, so owner id == node id.
931
+ if (resolveContainerTypeOwner !== undefined) {
932
+ const containerOwner = resolveContainerTypeOwner(current, filePath);
933
+ if (containerOwner !== null) {
934
+ return {
935
+ classId: generateId(containerOwner.label, `${filePath}:${containerOwner.name}`),
936
+ className: containerOwner.name,
937
+ };
938
+ }
939
+ }
853
940
  // Rust impl_item: for `impl Trait for Struct {}`, pick the type after `for`
854
941
  // NOTE: This impl_item ownership logic is mirrored in
855
942
  // method-extractors/configs/rust.ts (extractOwnerName, metadata only).
@@ -926,7 +1013,27 @@ getQualifiedOwnerName) => {
926
1013
  current.children?.find((c) => c.type === 'type_identifier' ||
927
1014
  c.type === 'identifier' ||
928
1015
  c.type === 'name' ||
929
- c.type === 'constant');
1016
+ c.type === 'constant') ??
1017
+ // An ANONYMOUS container bound by the enclosing declaration —
1018
+ // `const Point = struct { … }` (tree-sitter-zig: struct/enum/union/
1019
+ // opaque nodes carry no name; the binding identifier is the first
1020
+ // named child of the parent `variable_declaration`). Same shape as the
1021
+ // Go `type_spec` branch above: the name lives one level up. Without it
1022
+ // the walk climbed past every Zig container and no member ever got a
1023
+ // HAS_METHOD / HAS_PROPERTY owner. The definition phase names the
1024
+ // container node from the same binding (`@name` on the wrapper), so
1025
+ // the owner id and the node id agree by construction.
1026
+ (current.parent?.type === 'variable_declaration'
1027
+ ? current.parent.namedChildren?.find((c) => c.type === 'identifier')
1028
+ : undefined) ??
1029
+ // An anonymous container RETURNED by a type-constructor function —
1030
+ // `pub fn List(comptime T: type) type { return struct { … }; }`
1031
+ // (Zig's only spelling of a generic type). The container's name is
1032
+ // the function's, which is what the definition phase uses too
1033
+ // (`@name` on the fn identifier, anchor on the container), so the
1034
+ // owner id and the node id agree by construction. Only the literal
1035
+ // `return <container>` of a fn returning `type` qualifies.
1036
+ typeConstructorNameNode(current);
930
1037
  if (nameNode) {
931
1038
  let label = CONTAINER_TYPE_TO_LABEL[current.type] || 'Class';
932
1039
  // Kotlin: class_declaration with an anonymous "interface" keyword child
@@ -976,6 +1083,17 @@ getQualifiedOwnerName) => {
976
1083
  };
977
1084
  }
978
1085
  }
1086
+ if (current.parent === null && resolveFileTypeOwner !== undefined) {
1087
+ // Tree root reached with no container on the way: ask the provider
1088
+ // whether the file itself is the owner.
1089
+ const fileOwner = resolveFileTypeOwner(current, filePath);
1090
+ if (fileOwner !== null) {
1091
+ return {
1092
+ classId: generateId(fileOwner.label, `${filePath}:${fileOwner.name}`),
1093
+ className: fileOwner.name,
1094
+ };
1095
+ }
1096
+ }
979
1097
  current = current.parent;
980
1098
  }
981
1099
  return null;
@@ -111,6 +111,15 @@ export interface CallableFlowCaptureOptions {
111
111
  readonly source: SyntaxNode;
112
112
  }[] | undefined;
113
113
  readonly extractFunctionParameters?: (node: SyntaxNode) => readonly SyntaxNode[] | undefined;
114
+ /**
115
+ * Provider-owned call-argument extraction, for grammars whose call node
116
+ * carries its arguments as DIRECT children with no argument-list wrapper
117
+ * (tree-sitter-zig's `call_expression`). Without a wrapper node the shared
118
+ * `arguments`/`parameterListNodeTypes` lookup finds nothing, so every
119
+ * `argument` fact is lost. Returning `undefined` falls back to the shared
120
+ * path (mirrors `extractFunctionParameters`).
121
+ */
122
+ readonly extractCallArguments?: (call: SyntaxNode) => readonly SyntaxNode[] | undefined;
114
123
  readonly extractCallCallee?: (node: SyntaxNode) => SyntaxNode | undefined;
115
124
  readonly isCallNode?: (node: SyntaxNode) => boolean;
116
125
  /**
@@ -165,6 +165,7 @@ function collectAssignments(nodes, options) {
165
165
  }
166
166
  function buildValueBindingIndex(nodes, assignments, functions, options) {
167
167
  const assignmentRegionIdsByName = new Map();
168
+ const memberStoreRegionIdsByName = new Map();
168
169
  const formalByOwner = new Map();
169
170
  const signatureByNameAndRegion = new Map();
170
171
  const add = (index, owner, name) => {
@@ -187,20 +188,28 @@ function buildValueBindingIndex(nodes, assignments, functions, options) {
187
188
  const terminal = terminalIdentifier(assignment.destination, options);
188
189
  if (terminal !== undefined)
189
190
  destinationNames.add(terminal.text);
190
- for (const name of destinationNames) {
191
- const region = nearestLexicalRegion(assignment.container, options);
192
- let regionIds = assignmentRegionIdsByName.get(name);
191
+ // A destination whose binding identifier and terminal identifier are two
192
+ // different nodes spans a member path (`o->run`, `self.slot.f`); a bare
193
+ // name or a declarator (`void (*fp)(int)`) resolves both to the same leaf.
194
+ const memberStoreName = terminal !== undefined && terminal.id !== destination?.node.id ? terminal.text : undefined;
195
+ const region = nearestLexicalRegion(assignment.container, options);
196
+ const functionOwner = options.functionScopedValueBindings === true
197
+ ? nearestFunctionOwner(assignment.container, options)
198
+ : undefined;
199
+ const record = (index, name) => {
200
+ let regionIds = index.get(name);
193
201
  if (regionIds === undefined) {
194
202
  regionIds = new Set();
195
- assignmentRegionIdsByName.set(name, regionIds);
203
+ index.set(name, regionIds);
196
204
  }
197
205
  regionIds.add(region.id);
198
- if (options.functionScopedValueBindings === true) {
199
- const functionOwner = nearestFunctionOwner(assignment.container, options);
200
- if (functionOwner !== undefined)
201
- regionIds.add(functionOwner.id);
202
- }
203
- }
206
+ if (functionOwner !== undefined)
207
+ regionIds.add(functionOwner.id);
208
+ };
209
+ for (const name of destinationNames)
210
+ record(assignmentRegionIdsByName, name);
211
+ if (memberStoreName !== undefined)
212
+ record(memberStoreRegionIdsByName, memberStoreName);
204
213
  }
205
214
  for (const fn of functions) {
206
215
  for (const parameter of fn.parameters) {
@@ -241,7 +250,12 @@ function buildValueBindingIndex(nodes, assignments, functions, options) {
241
250
  byRegion.set(functionOwner.id, signature);
242
251
  }
243
252
  }
244
- return { assignmentRegionIdsByName, formalByOwner, signatureByNameAndRegion };
253
+ return {
254
+ assignmentRegionIdsByName,
255
+ memberStoreRegionIdsByName,
256
+ formalByOwner,
257
+ signatureByNameAndRegion,
258
+ };
245
259
  }
246
260
  /** True when a pointer/parenthesized declarator sits between the declaration
247
261
  * and its binding identifier — the shape of a callable-typed variable, never
@@ -312,6 +326,30 @@ function isVisibleValueBinding(input, name, bindings, options) {
312
326
  // function call emitted no invoke fact at all (#2522 review, H1).
313
327
  return visibleCallableSignature(input, name, bindings, options) !== undefined;
314
328
  }
329
+ /**
330
+ * Member-call gate: the member's name-cell was written by a visible MEMBER
331
+ * store, or is a declared callable-typed binding (C struct field
332
+ * `void (*cb)(int);`, whose stores may live in other functions). Plain-name
333
+ * bindings and formals are deliberately NOT consulted — `x.f()` reads the
334
+ * member `f` of `x`, not a same-named local, and gating on the local minted an
335
+ * invoke through the wrong cell (a Zig `pub const release = deinit;` alias
336
+ * turned `self.slot.release()` into a `deinit → deinit` self-loop).
337
+ */
338
+ function isVisibleMemberStore(input, name, bindings, options) {
339
+ const regionIds = bindings.memberStoreRegionIdsByName.get(name);
340
+ if (regionIds !== undefined) {
341
+ const providerOwner = options.lexicalFunctionOwner?.(input);
342
+ if (providerOwner !== undefined && regionIds.has(providerOwner.id))
343
+ return true;
344
+ let node = input;
345
+ while (node !== null) {
346
+ if (regionIds.has(node.id))
347
+ return true;
348
+ node = node.parent;
349
+ }
350
+ }
351
+ return visibleCallableSignature(input, name, bindings, options) !== undefined;
352
+ }
315
353
  function visibleCallableSignature(input, name, bindings, options) {
316
354
  const byRegion = bindings.signatureByNameAndRegion.get(name);
317
355
  if (byRegion === undefined)
@@ -472,9 +510,15 @@ function emitCallFacts(call, knownCallableNames, valueBindings, options, out) {
472
510
  const member = directCallMemberParts(call, options) ?? memberParts(calleeNode, options);
473
511
  const callee = operandSyntax(calleeNode, options);
474
512
  const calleeIsValueBinding = callee !== undefined && isVisibleValueBinding(call, callee.name, valueBindings, options);
513
+ // A direct callee NAME exists only when the call spells its callee as a
514
+ // designator (`f(x)`, `ns.f(x)`). A receiver-less member (Zig's decl
515
+ // literal `.init(x)`, whose receiver is an inferred type) or a computed
516
+ // callee names nothing the solver may seed by simple name — doing so
517
+ // fanned each argument out to every same-named callable in the repo.
475
518
  const directCalleeName = member === undefined &&
476
519
  callee !== undefined &&
477
520
  callee.indirection === 0 &&
521
+ callee.directDesignator &&
478
522
  !calleeIsValueBinding
479
523
  ? callee.name
480
524
  : undefined;
@@ -551,7 +595,7 @@ function emitCallFacts(call, knownCallableNames, valueBindings, options, out) {
551
595
  // name-keyed field collapse matches the solver's store/load model.
552
596
  // ponytail: same-region joins only — cross-function vtable installs need
553
597
  // a field-sensitive cell model.
554
- if (isVisibleValueBinding(call, member.member.name, valueBindings, options)) {
598
+ if (isVisibleMemberStore(call, member.member.name, valueBindings, options)) {
555
599
  emitInvoke(callSite, member.member, 'indirect', args.length, out, options, member.receiver);
556
600
  }
557
601
  return;
@@ -605,6 +649,9 @@ function emitInvoke(call, callee, invocationKind, arity, out, options, receiver)
605
649
  }
606
650
  }
607
651
  function callArguments(call, options) {
652
+ const providerArguments = options.extractCallArguments?.(call);
653
+ if (providerArguments !== undefined)
654
+ return providerArguments;
608
655
  const list = call.childForFieldName('arguments') ??
609
656
  call.childForFieldName('argument') ??
610
657
  call.namedChildren.find((child) => child !== null && options.parameterListNodeTypes.has(child.type)) ??
@@ -645,9 +692,17 @@ function memberParts(input, options) {
645
692
  const receiverNode = node.childForFieldName('object') ??
646
693
  node.childForFieldName('argument') ??
647
694
  node.childForFieldName('receiver');
695
+ // `member` is the field name tree-sitter grammars use when the receiver
696
+ // field is `object` (Zig `field_expression`). It is only read once a
697
+ // receiver field matched: the other grammars that expose a `member` field
698
+ // (C/C++ `offsetof_expression`, JS `class_body`) carry no receiver field and
699
+ // stay unaffected. Without it every `x.f(arg)` in such a grammar collapsed
700
+ // to a DIRECT call named `f` and the flow solver fanned the argument out to
701
+ // every same-named callable.
648
702
  const memberNode = node.childForFieldName('property') ??
649
703
  node.childForFieldName('field') ??
650
- node.childForFieldName('method');
704
+ node.childForFieldName('method') ??
705
+ node.childForFieldName('member');
651
706
  if (receiverNode === null || memberNode === null)
652
707
  return undefined;
653
708
  const receiver = operandSyntax(receiverNode, options);
@@ -751,7 +806,13 @@ function wrappedExpression(node) {
751
806
  node.childForFieldName('value');
752
807
  if (field !== null && field.id !== node.id && node.namedChildCount === 1)
753
808
  return field;
754
- if (node.type.includes('parenthesized') ||
809
+ // `await` is a wrapper, not a callee: tree-sitter-typescript parses
810
+ // `await f<T>(x)` as `call_expression(function: await_expression(f), …)`,
811
+ // and `await_expression` carries its operand without a field name, so the
812
+ // field-based unwrap above misses it. Unwrapping keeps `f` a direct
813
+ // designator (`direct-callee-name`), as it is for the un-awaited spelling.
814
+ if (node.type.includes('await_expression') ||
815
+ node.type.includes('parenthesized') ||
755
816
  node.type.includes('reference_expression') ||
756
817
  node.type.includes('pointer_expression') ||
757
818
  node.type.includes('unary_expression') ||
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Test-file path classification — the single source of truth.
3
+ *
4
+ * WHY THIS MODULE EXISTS
5
+ *
6
+ * Two independent copies of this predicate existed and had drifted apart:
7
+ *
8
+ * - `core/ingestion/entry-point-scoring.ts` `isTestFile` — excludes test
9
+ * files from process entry-point detection.
10
+ * - `mcp/local/local-backend.ts` `isTestFilePath` — backs the
11
+ * `includeTests` flag on `impact` / `trace` / `context`.
12
+ *
13
+ * They answered "is this a test file?" differently, so the same path could be a
14
+ * test in one code path and not the other. The MCP copy recognized no C#, Java,
15
+ * or Swift test convention at all, meaning `includeTests: false` silently failed
16
+ * to filter them; the scoring copy missed `/conftest.` (it already matched
17
+ * `/test/`, so `/test/fixtures/` was never a scoring gap).
18
+ *
19
+ * The duplication was not gratuitous: `entry-point-scoring.ts` imports the
20
+ * language-provider registry, and #2802 deliberately cut that closure out of MCP
21
+ * server startup. Importing it back into `local-backend.ts` would reintroduce
22
+ * that cost. So the shared predicate lives here instead, with NO imports — pure
23
+ * string matching — and both callers delegate to it.
24
+ *
25
+ * Keep it dependency-free. Anything imported here lands in MCP startup.
26
+ */
27
+ /** Absent / empty paths are not test paths. */
28
+ export declare function isTestFilePath(filePath: string | null | undefined): boolean;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Test-file path classification — the single source of truth.
3
+ *
4
+ * WHY THIS MODULE EXISTS
5
+ *
6
+ * Two independent copies of this predicate existed and had drifted apart:
7
+ *
8
+ * - `core/ingestion/entry-point-scoring.ts` `isTestFile` — excludes test
9
+ * files from process entry-point detection.
10
+ * - `mcp/local/local-backend.ts` `isTestFilePath` — backs the
11
+ * `includeTests` flag on `impact` / `trace` / `context`.
12
+ *
13
+ * They answered "is this a test file?" differently, so the same path could be a
14
+ * test in one code path and not the other. The MCP copy recognized no C#, Java,
15
+ * or Swift test convention at all, meaning `includeTests: false` silently failed
16
+ * to filter them; the scoring copy missed `/conftest.` (it already matched
17
+ * `/test/`, so `/test/fixtures/` was never a scoring gap).
18
+ *
19
+ * The duplication was not gratuitous: `entry-point-scoring.ts` imports the
20
+ * language-provider registry, and #2802 deliberately cut that closure out of MCP
21
+ * server startup. Importing it back into `local-backend.ts` would reintroduce
22
+ * that cost. So the shared predicate lives here instead, with NO imports — pure
23
+ * string matching — and both callers delegate to it.
24
+ *
25
+ * Keep it dependency-free. Anything imported here lands in MCP startup.
26
+ */
27
+ /**
28
+ * Lowercase forward-slash path substrings. Directory needles include a leading
29
+ * slash so they match path components after the caller slash-prefixes relative
30
+ * paths. `/test/` already covers Maven `src/test` and `/test/fixtures/`;
31
+ * `/tests/` covers Laravel `tests/Feature` and `/tests/fixtures/`.
32
+ */
33
+ const TEST_PATH_SUBSTRINGS = [
34
+ '.test.',
35
+ '.spec.',
36
+ '__tests__/',
37
+ '__mocks__/',
38
+ '/test/',
39
+ '/tests/',
40
+ '/testing/',
41
+ '/spec/',
42
+ '/test_',
43
+ '/conftest.',
44
+ '/uitests/',
45
+ '.tests/',
46
+ '.test/',
47
+ '.integrationtests/',
48
+ '.unittests/',
49
+ '/testproject/',
50
+ ];
51
+ /** Case-insensitive suffixes that already include a delimiter (`_test.py`, not `test.py`). */
52
+ const TEST_PATH_DELIMITED_SUFFIXES = [
53
+ '_test.py',
54
+ '_test.go',
55
+ '_spec.rb',
56
+ '_test.rb',
57
+ ];
58
+ /**
59
+ * Case-sensitive `Test`/`Tests`/`Spec` suffixes. Lowercasing first would also
60
+ * match production names such as `Contest.swift` and `Latest.php`.
61
+ */
62
+ const TEST_PATH_CASED_SUFFIXES = [
63
+ 'Tests.swift',
64
+ 'Test.swift',
65
+ 'Tests.cs',
66
+ 'Test.cs',
67
+ 'Test.php',
68
+ 'Spec.php',
69
+ ];
70
+ /** Absent / empty paths are not test paths. */
71
+ export function isTestFilePath(filePath) {
72
+ if (!filePath)
73
+ return false;
74
+ const slashed = filePath.replace(/\\/g, '/');
75
+ const prefixed = slashed.startsWith('/') ? slashed : `/${slashed}`;
76
+ const lower = prefixed.toLowerCase();
77
+ if (TEST_PATH_SUBSTRINGS.some((needle) => lower.includes(needle)))
78
+ return true;
79
+ if (TEST_PATH_DELIMITED_SUFFIXES.some((suffix) => lower.endsWith(suffix)))
80
+ return true;
81
+ // Xcode `{Product}UITests` targets. Slash-anchored `/uitests/` does not match
82
+ // `MyAppUITests`; an unanchored `uitests/` substring also matches `fruitests`.
83
+ if (prefixed.split('/').some((seg) => seg.endsWith('UITests')))
84
+ return true;
85
+ const basename = prefixed.slice(prefixed.lastIndexOf('/') + 1);
86
+ return TEST_PATH_CASED_SUFFIXES.some((suffix) => basename.endsWith(suffix));
87
+ }
@@ -0,0 +1,2 @@
1
+ import type { VariableExtractionConfig } from '../../variable-types.js';
2
+ export declare const zigVariableConfig: VariableExtractionConfig;
@@ -0,0 +1,71 @@
1
+ import { SupportedLanguages } from '../../../../_shared/index.js';
2
+ import { hasZigPubKeyword } from '../../export-detection.js';
3
+ import { isZigKeywordDeclaration, isZigTypeShadowingBinding, } from '../../languages/zig/captures.js';
4
+ /**
5
+ * Zig variable extraction — enriches the Const / Variable nodes minted by
6
+ * ZIG_QUERIES' `@definition.const` / `@definition.variable` rules.
7
+ *
8
+ * tree-sitter-zig uses a single `variable_declaration` node for both `const`
9
+ * and `var` bindings — AND for statement assignments (`x = 5;`), which carry
10
+ * no keyword. The keyword is exposed as an unnamed token child
11
+ * (`type === 'const'` or `type === 'var'`).
12
+ *
13
+ * Excludes variable_declarations whose value is a struct/enum/union or an
14
+ * `@import(...)` builtin — those are handled by the class extractor / import
15
+ * pipeline, and a Variable record beside the Struct/Enum/Union node (or the
16
+ * import edge) would be a duplicate. `extractName` returns undefined for them,
17
+ * which is the generic extractor's skip signal (see `generic.ts`, and Python's
18
+ * broad `expression_statement` config for the same pattern).
19
+ */
20
+ const isVarKeyword = (node) => {
21
+ for (let i = 0; i < node.childCount; i++) {
22
+ const child = node.child(i);
23
+ if (child?.type === 'var')
24
+ return true;
25
+ }
26
+ return false;
27
+ };
28
+ export const zigVariableConfig = {
29
+ language: SupportedLanguages.Zig,
30
+ constNodeTypes: ['variable_declaration'],
31
+ staticNodeTypes: [],
32
+ variableNodeTypes: [],
33
+ extractName(node) {
34
+ if (isZigTypeShadowingBinding(node))
35
+ return undefined;
36
+ // Statement assignments share the node type and have no keyword — not a
37
+ // declaration (belt to the query's literal `"const"` / `"var"` brace).
38
+ if (!isZigKeywordDeclaration(node))
39
+ return undefined;
40
+ for (let i = 0; i < node.namedChildCount; i++) {
41
+ const child = node.namedChild(i);
42
+ if (child?.type === 'identifier')
43
+ return child.text;
44
+ }
45
+ return undefined;
46
+ },
47
+ extractType(node) {
48
+ // tree-sitter-zig 1.1.2 exposes the annotation as the `type:` field of
49
+ // variable_declaration (its only field; verified by AST dump: `const p:
50
+ // *Foo = …` → `pointer_type [type]`, `extern var f: T;` → `identifier
51
+ // [type]`). Reading the field covers every annotation shape (builtin,
52
+ // identifier, pointer/optional/slice/array/fn types) and, just as
53
+ // importantly, never mistakes an initializer for a type: `const f =
54
+ // target;` has no `type:` field, so it is untyped — the old positional
55
+ // fallback returned `target` as its type.
56
+ return node.childForFieldName('type')?.text?.trim();
57
+ },
58
+ extractVisibility(node) {
59
+ // `pub` only — `export var` is C linkage, private to other Zig files.
60
+ return hasZigPubKeyword(node) ? 'public' : 'private';
61
+ },
62
+ isConst(node) {
63
+ return !isVarKeyword(node);
64
+ },
65
+ isStatic() {
66
+ return false;
67
+ },
68
+ isMutable(node) {
69
+ return isVarKeyword(node);
70
+ },
71
+ };