gitnexus 1.5.3 → 1.6.1

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 (304) hide show
  1. package/README.md +10 -0
  2. package/dist/_shared/graph/types.d.ts +1 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/language-detection.d.ts.map +1 -1
  7. package/dist/_shared/language-detection.js +2 -0
  8. package/dist/_shared/language-detection.js.map +1 -1
  9. package/dist/_shared/languages.d.ts +1 -0
  10. package/dist/_shared/languages.d.ts.map +1 -1
  11. package/dist/_shared/languages.js +1 -0
  12. package/dist/_shared/languages.js.map +1 -1
  13. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  14. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  15. package/dist/_shared/lbug/schema-constants.js +3 -1
  16. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  17. package/dist/_shared/mro-strategy.d.ts +19 -0
  18. package/dist/_shared/mro-strategy.d.ts.map +1 -0
  19. package/dist/_shared/mro-strategy.js +2 -0
  20. package/dist/_shared/mro-strategy.js.map +1 -0
  21. package/dist/cli/ai-context.d.ts +1 -0
  22. package/dist/cli/ai-context.js +28 -4
  23. package/dist/cli/analyze.d.ts +2 -0
  24. package/dist/cli/analyze.js +30 -4
  25. package/dist/cli/group.d.ts +2 -0
  26. package/dist/cli/group.js +233 -0
  27. package/dist/cli/index.js +3 -0
  28. package/dist/cli/serve.js +4 -1
  29. package/dist/cli/setup.js +34 -3
  30. package/dist/config/ignore-service.js +8 -3
  31. package/dist/core/augmentation/engine.js +1 -1
  32. package/dist/core/git-staleness.d.ts +13 -0
  33. package/dist/core/git-staleness.js +29 -0
  34. package/dist/core/group/bridge-db.d.ts +82 -0
  35. package/dist/core/group/bridge-db.js +460 -0
  36. package/dist/core/group/bridge-schema.d.ts +27 -0
  37. package/dist/core/group/bridge-schema.js +55 -0
  38. package/dist/core/group/config-parser.d.ts +3 -0
  39. package/dist/core/group/config-parser.js +83 -0
  40. package/dist/core/group/contract-extractor.d.ts +7 -0
  41. package/dist/core/group/contract-extractor.js +1 -0
  42. package/dist/core/group/extractors/fs-utils.d.ts +10 -0
  43. package/dist/core/group/extractors/fs-utils.js +24 -0
  44. package/dist/core/group/extractors/grpc-extractor.d.ts +25 -0
  45. package/dist/core/group/extractors/grpc-extractor.js +386 -0
  46. package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
  47. package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
  48. package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
  49. package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
  50. package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
  51. package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
  52. package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
  53. package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
  54. package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
  55. package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
  56. package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
  57. package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
  58. package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
  59. package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
  60. package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
  61. package/dist/core/group/extractors/http-patterns/go.js +215 -0
  62. package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
  63. package/dist/core/group/extractors/http-patterns/index.js +44 -0
  64. package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
  65. package/dist/core/group/extractors/http-patterns/java.js +253 -0
  66. package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
  67. package/dist/core/group/extractors/http-patterns/node.js +354 -0
  68. package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
  69. package/dist/core/group/extractors/http-patterns/php.js +70 -0
  70. package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
  71. package/dist/core/group/extractors/http-patterns/python.js +133 -0
  72. package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
  73. package/dist/core/group/extractors/http-patterns/types.js +1 -0
  74. package/dist/core/group/extractors/http-route-extractor.d.ts +21 -0
  75. package/dist/core/group/extractors/http-route-extractor.js +391 -0
  76. package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
  77. package/dist/core/group/extractors/manifest-extractor.js +235 -0
  78. package/dist/core/group/extractors/topic-extractor.d.ts +8 -0
  79. package/dist/core/group/extractors/topic-extractor.js +97 -0
  80. package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
  81. package/dist/core/group/extractors/topic-patterns/go.js +120 -0
  82. package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
  83. package/dist/core/group/extractors/topic-patterns/index.js +38 -0
  84. package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
  85. package/dist/core/group/extractors/topic-patterns/java.js +80 -0
  86. package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
  87. package/dist/core/group/extractors/topic-patterns/node.js +155 -0
  88. package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
  89. package/dist/core/group/extractors/topic-patterns/python.js +116 -0
  90. package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
  91. package/dist/core/group/extractors/topic-patterns/types.js +10 -0
  92. package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
  93. package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
  94. package/dist/core/group/matching.d.ts +13 -0
  95. package/dist/core/group/matching.js +198 -0
  96. package/dist/core/group/normalization.d.ts +3 -0
  97. package/dist/core/group/normalization.js +115 -0
  98. package/dist/core/group/service-boundary-detector.d.ts +8 -0
  99. package/dist/core/group/service-boundary-detector.js +155 -0
  100. package/dist/core/group/service.d.ts +46 -0
  101. package/dist/core/group/service.js +160 -0
  102. package/dist/core/group/storage.d.ts +9 -0
  103. package/dist/core/group/storage.js +91 -0
  104. package/dist/core/group/sync.d.ts +21 -0
  105. package/dist/core/group/sync.js +148 -0
  106. package/dist/core/group/types.d.ts +130 -0
  107. package/dist/core/group/types.js +1 -0
  108. package/dist/core/ingestion/binding-accumulator.d.ts +212 -0
  109. package/dist/core/ingestion/binding-accumulator.js +336 -0
  110. package/dist/core/ingestion/call-processor.d.ts +155 -24
  111. package/dist/core/ingestion/call-processor.js +1129 -247
  112. package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
  113. package/dist/core/ingestion/class-extractors/generic.js +135 -0
  114. package/dist/core/ingestion/class-types.d.ts +34 -0
  115. package/dist/core/ingestion/class-types.js +1 -0
  116. package/dist/core/ingestion/cobol-processor.d.ts +1 -1
  117. package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
  118. package/dist/core/ingestion/entry-point-scoring.js +1 -0
  119. package/dist/core/ingestion/field-types.d.ts +2 -2
  120. package/dist/core/ingestion/filesystem-walker.js +8 -0
  121. package/dist/core/ingestion/framework-detection.d.ts +1 -0
  122. package/dist/core/ingestion/framework-detection.js +1 -0
  123. package/dist/core/ingestion/heritage-processor.d.ts +8 -15
  124. package/dist/core/ingestion/heritage-processor.js +15 -28
  125. package/dist/core/ingestion/import-processor.d.ts +1 -11
  126. package/dist/core/ingestion/import-processor.js +1 -13
  127. package/dist/core/ingestion/import-resolvers/utils.js +1 -0
  128. package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
  129. package/dist/core/ingestion/import-resolvers/vue.js +9 -0
  130. package/dist/core/ingestion/language-config.js +1 -1
  131. package/dist/core/ingestion/language-provider.d.ts +14 -3
  132. package/dist/core/ingestion/languages/c-cpp.js +168 -1
  133. package/dist/core/ingestion/languages/csharp.js +20 -0
  134. package/dist/core/ingestion/languages/dart.js +26 -4
  135. package/dist/core/ingestion/languages/go.js +22 -0
  136. package/dist/core/ingestion/languages/index.d.ts +1 -0
  137. package/dist/core/ingestion/languages/index.js +2 -0
  138. package/dist/core/ingestion/languages/java.js +17 -0
  139. package/dist/core/ingestion/languages/kotlin.js +24 -1
  140. package/dist/core/ingestion/languages/php.js +23 -11
  141. package/dist/core/ingestion/languages/python.js +9 -0
  142. package/dist/core/ingestion/languages/ruby.js +43 -0
  143. package/dist/core/ingestion/languages/rust.js +38 -0
  144. package/dist/core/ingestion/languages/swift.js +31 -0
  145. package/dist/core/ingestion/languages/typescript.d.ts +1 -0
  146. package/dist/core/ingestion/languages/typescript.js +52 -3
  147. package/dist/core/ingestion/languages/vue.d.ts +13 -0
  148. package/dist/core/ingestion/languages/vue.js +81 -0
  149. package/dist/core/ingestion/markdown-processor.d.ts +1 -1
  150. package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
  151. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  152. package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
  153. package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
  154. package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
  155. package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
  156. package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
  157. package/dist/core/ingestion/method-extractors/configs/jvm.js +14 -4
  158. package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
  159. package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
  160. package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
  161. package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
  162. package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
  163. package/dist/core/ingestion/method-extractors/configs/ruby.js +286 -0
  164. package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
  165. package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
  166. package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
  167. package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
  168. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +85 -8
  169. package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
  170. package/dist/core/ingestion/method-extractors/generic.js +84 -17
  171. package/dist/core/ingestion/method-types.d.ts +29 -0
  172. package/dist/core/ingestion/model/field-registry.d.ts +18 -0
  173. package/dist/core/ingestion/model/field-registry.js +22 -0
  174. package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
  175. package/dist/core/ingestion/model/heritage-map.js +159 -0
  176. package/dist/core/ingestion/model/index.d.ts +20 -0
  177. package/dist/core/ingestion/model/index.js +41 -0
  178. package/dist/core/ingestion/model/method-registry.d.ts +62 -0
  179. package/dist/core/ingestion/model/method-registry.js +130 -0
  180. package/dist/core/ingestion/model/registration-table.d.ts +139 -0
  181. package/dist/core/ingestion/model/registration-table.js +224 -0
  182. package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
  183. package/dist/core/ingestion/model/resolution-context.js +337 -0
  184. package/dist/core/ingestion/model/resolve.d.ts +56 -0
  185. package/dist/core/ingestion/model/resolve.js +297 -0
  186. package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
  187. package/dist/core/ingestion/model/semantic-model.js +120 -0
  188. package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
  189. package/dist/core/ingestion/model/symbol-table.js +206 -0
  190. package/dist/core/ingestion/model/type-registry.d.ts +39 -0
  191. package/dist/core/ingestion/model/type-registry.js +62 -0
  192. package/dist/core/ingestion/mro-processor.d.ts +5 -4
  193. package/dist/core/ingestion/mro-processor.js +311 -107
  194. package/dist/core/ingestion/parsing-processor.d.ts +5 -4
  195. package/dist/core/ingestion/parsing-processor.js +224 -87
  196. package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
  197. package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
  198. package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
  199. package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
  200. package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
  201. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
  202. package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
  203. package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
  204. package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
  205. package/dist/core/ingestion/pipeline-phases/index.js +22 -0
  206. package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
  207. package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
  208. package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
  209. package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
  210. package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
  211. package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
  212. package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
  213. package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
  214. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
  215. package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
  216. package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
  217. package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
  218. package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
  219. package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
  220. package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
  221. package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
  222. package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
  223. package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
  224. package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
  225. package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
  226. package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
  227. package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
  228. package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
  229. package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
  230. package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
  231. package/dist/core/ingestion/pipeline-phases/types.js +37 -0
  232. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
  233. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
  234. package/dist/core/ingestion/pipeline.d.ts +18 -10
  235. package/dist/core/ingestion/pipeline.js +66 -1410
  236. package/dist/core/ingestion/process-processor.js +1 -1
  237. package/dist/core/ingestion/tree-sitter-queries.d.ts +5 -5
  238. package/dist/core/ingestion/tree-sitter-queries.js +90 -0
  239. package/dist/core/ingestion/type-env.d.ts +15 -2
  240. package/dist/core/ingestion/type-env.js +163 -102
  241. package/dist/core/ingestion/type-extractors/csharp.js +17 -0
  242. package/dist/core/ingestion/type-extractors/jvm.js +11 -0
  243. package/dist/core/ingestion/type-extractors/php.js +0 -55
  244. package/dist/core/ingestion/type-extractors/ruby.js +0 -32
  245. package/dist/core/ingestion/type-extractors/swift.js +13 -0
  246. package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
  247. package/dist/core/ingestion/type-extractors/typescript.js +66 -69
  248. package/dist/core/ingestion/utils/ast-helpers.d.ts +32 -44
  249. package/dist/core/ingestion/utils/ast-helpers.js +157 -573
  250. package/dist/core/ingestion/utils/env.d.ts +10 -0
  251. package/dist/core/ingestion/utils/env.js +10 -0
  252. package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
  253. package/dist/core/ingestion/utils/graph-sort.js +100 -0
  254. package/dist/core/ingestion/utils/method-props.d.ts +32 -0
  255. package/dist/core/ingestion/utils/method-props.js +147 -0
  256. package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
  257. package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
  258. package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
  259. package/dist/core/ingestion/workers/parse-worker.js +469 -200
  260. package/dist/core/lbug/lbug-adapter.d.ts +6 -0
  261. package/dist/core/lbug/lbug-adapter.js +134 -27
  262. package/dist/core/lbug/pool-adapter.d.ts +76 -0
  263. package/dist/core/lbug/pool-adapter.js +522 -0
  264. package/dist/core/run-analyze.d.ts +2 -0
  265. package/dist/core/run-analyze.js +1 -1
  266. package/dist/core/search/bm25-index.js +1 -1
  267. package/dist/core/tree-sitter/parser-loader.js +1 -0
  268. package/dist/core/wiki/graph-queries.js +1 -1
  269. package/dist/mcp/core/embedder.js +6 -5
  270. package/dist/mcp/core/lbug-adapter.d.ts +3 -63
  271. package/dist/mcp/core/lbug-adapter.js +3 -484
  272. package/dist/mcp/local/local-backend.d.ts +31 -2
  273. package/dist/mcp/local/local-backend.js +255 -46
  274. package/dist/mcp/resources.js +5 -4
  275. package/dist/mcp/staleness.d.ts +3 -13
  276. package/dist/mcp/staleness.js +2 -31
  277. package/dist/mcp/tools.js +80 -4
  278. package/dist/server/analyze-job.d.ts +2 -0
  279. package/dist/server/analyze-job.js +4 -0
  280. package/dist/server/api.d.ts +20 -1
  281. package/dist/server/api.js +306 -71
  282. package/dist/server/git-clone.d.ts +2 -1
  283. package/dist/server/git-clone.js +98 -5
  284. package/dist/storage/git.d.ts +13 -0
  285. package/dist/storage/git.js +25 -0
  286. package/dist/storage/repo-manager.js +1 -1
  287. package/package.json +9 -3
  288. package/scripts/patch-tree-sitter-swift.cjs +78 -0
  289. package/vendor/tree-sitter-proto/binding.gyp +30 -0
  290. package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
  291. package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
  292. package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
  293. package/vendor/tree-sitter-proto/package.json +18 -0
  294. package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
  295. package/vendor/tree-sitter-proto/src/parser.c +10149 -0
  296. package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
  297. package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
  298. package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
  299. package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
  300. package/dist/core/ingestion/named-binding-processor.js +0 -42
  301. package/dist/core/ingestion/resolution-context.d.ts +0 -58
  302. package/dist/core/ingestion/resolution-context.js +0 -135
  303. package/dist/core/ingestion/symbol-table.d.ts +0 -79
  304. package/dist/core/ingestion/symbol-table.js +0 -115
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Canonicalize an HTTP path for matching against Route.name in the graph.
3
+ * Mirrors core/ingestion/pipeline.ts ensureSlash semantics:
4
+ * - Ensures a leading slash.
5
+ * - Strips trailing slashes (except the root "/").
6
+ * - Normalizes consecutive slashes.
7
+ * - Does NOT lowercase (route matching is case-sensitive).
8
+ */
9
+ function normalizeRoutePath(raw) {
10
+ const trimmed = raw.trim();
11
+ if (!trimmed)
12
+ return '/';
13
+ const withLeading = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
14
+ const collapsed = withLeading.replace(/\/+/g, '/');
15
+ if (collapsed === '/')
16
+ return '/';
17
+ return collapsed.replace(/\/+$/, '');
18
+ }
19
+ /**
20
+ * Stable synthetic symbolUid for a manifest-declared contract whose target
21
+ * symbol could not be resolved against the per-repo graph (resolveSymbol
22
+ * returned null). Two reasons we don't leave the uid empty:
23
+ *
24
+ * 1. The bridge stores Contract nodes keyed in part by symbolUid; an empty
25
+ * uid means downstream Cypher queries that anchor on `provider.symbolUid`
26
+ * can't tell two different unresolved manifest contracts apart.
27
+ * 2. The cross-impact bridge query in cross-impact.ts joins local impact
28
+ * results to bridge contracts via `WHERE provider.symbolUid IN $localUids`.
29
+ * If the local impact engine produces a deterministic identifier for the
30
+ * unresolved target, it must agree with the value the bridge stored. A
31
+ * synthetic uid keyed off (repo, contractId) is the only thing both sides
32
+ * can derive without knowing about each other.
33
+ *
34
+ * Format: `manifest::<repo>::<contractId>`. Stable across syncs, scoped to a
35
+ * single repo within a group, and never collides with real indexer uids
36
+ * (which never start with `manifest::`).
37
+ */
38
+ export function manifestSymbolUid(repo, contractId) {
39
+ return `manifest::${repo}::${contractId}`;
40
+ }
41
+ export class ManifestExtractor {
42
+ async extractFromManifest(links, dbExecutors) {
43
+ const contracts = [];
44
+ const crossLinks = [];
45
+ for (const link of links) {
46
+ const contractId = this.buildContractId(link.type, link.contract);
47
+ const providerRepo = link.role === 'provider' ? link.from : link.to;
48
+ const consumerRepo = link.role === 'provider' ? link.to : link.from;
49
+ const providerSymbol = await this.resolveSymbol(providerRepo, link, dbExecutors);
50
+ const consumerSymbol = await this.resolveSymbol(consumerRepo, link, dbExecutors);
51
+ const providerRef = providerSymbol || { filePath: '', name: link.contract };
52
+ const consumerRef = consumerSymbol || { filePath: '', name: link.contract };
53
+ // When the resolver finds a real graph symbol we keep its uid, otherwise
54
+ // fall back to the deterministic synthetic uid (see manifestSymbolUid).
55
+ const providerUid = providerSymbol?.uid || manifestSymbolUid(providerRepo, contractId);
56
+ const consumerUid = consumerSymbol?.uid || manifestSymbolUid(consumerRepo, contractId);
57
+ contracts.push({
58
+ contractId,
59
+ type: link.type,
60
+ role: 'provider',
61
+ symbolUid: providerUid,
62
+ symbolRef: providerRef,
63
+ symbolName: link.contract,
64
+ confidence: 1.0,
65
+ meta: { source: 'manifest' },
66
+ repo: providerRepo,
67
+ });
68
+ contracts.push({
69
+ contractId,
70
+ type: link.type,
71
+ role: 'consumer',
72
+ symbolUid: consumerUid,
73
+ symbolRef: consumerRef,
74
+ symbolName: link.contract,
75
+ confidence: 1.0,
76
+ meta: { source: 'manifest' },
77
+ repo: consumerRepo,
78
+ });
79
+ crossLinks.push({
80
+ from: { repo: consumerRepo, symbolUid: consumerUid, symbolRef: consumerRef },
81
+ to: { repo: providerRepo, symbolUid: providerUid, symbolRef: providerRef },
82
+ type: link.type,
83
+ contractId,
84
+ matchType: 'manifest',
85
+ confidence: 1.0,
86
+ });
87
+ }
88
+ return { contracts, crossLinks };
89
+ }
90
+ async resolveSymbol(repoPathKey, link, dbExecutors) {
91
+ const executor = dbExecutors?.get(repoPathKey);
92
+ if (!executor)
93
+ return null;
94
+ // NOTE: All lookups use EXACT equality on the relevant name field and
95
+ // deterministic ORDER BY before LIMIT 1. Previous versions used CONTAINS
96
+ // for fuzzy matching (plus an unconditional ".proto" fallback for gRPC)
97
+ // which produced silent false positives: e.g. manifest "/orders" would
98
+ // match "/suborders", and a gRPC manifest entry in a repo with any
99
+ // .proto file would attach to a random proto symbol.
100
+ //
101
+ // If resolveSymbol returns null, the extractor falls back to a
102
+ // deterministic synthetic uid via `manifestSymbolUid(repo, contractId)`
103
+ // (see the function's docstring for why synthetic rather than empty).
104
+ // Cross-impact still works: the bridge query joins on the synthetic
105
+ // uid, and the local impact engine derives the same uid for the
106
+ // unresolved symbol — name-based hints are the additional safety net.
107
+ try {
108
+ let rows;
109
+ if (link.type === 'http') {
110
+ // Route.name is the canonicalized URL path (see
111
+ // core/ingestion/pipeline.ts ensureSlash + generateId('Route', ...)).
112
+ // Normalize the manifest contract the same way so a user-written
113
+ // "/api/orders" matches "api/orders" in the graph.
114
+ const normalized = normalizeRoutePath(link.contract);
115
+ rows = await executor(`MATCH (handler)-[r:CodeRelation {type: 'HANDLES_ROUTE'}]->(route:Route)
116
+ WHERE route.name = $normalized
117
+ RETURN handler.id AS uid, handler.name AS name, handler.filePath AS filePath
118
+ ORDER BY handler.filePath ASC
119
+ LIMIT 1`, { normalized });
120
+ }
121
+ else if (link.type === 'topic') {
122
+ // Topic names aren't a first-class NodeLabel in the graph —
123
+ // topics are referenced by function/method symbols (Kafka
124
+ // listeners, publishers). Restrict to symbol-like labels to
125
+ // avoid cross-matching Files/Variables/Imports that happen to
126
+ // share the topic name.
127
+ rows = await executor(`MATCH (n:Function|Method|Class|Interface) WHERE n.name = $contract
128
+ RETURN n.id AS uid, n.name AS name, n.filePath AS filePath
129
+ ORDER BY n.filePath ASC
130
+ LIMIT 1`, { contract: link.contract });
131
+ }
132
+ else if (link.type === 'grpc') {
133
+ // Contract is "Service/Method" or just "Service" (or package.Service
134
+ // variants). Prefer matching by method name when present, otherwise
135
+ // by service name. NO .proto path fallback — that's guaranteed to
136
+ // return a wrong symbol in any repo with more than one proto file.
137
+ // Label filters scope lookups: methods → Function|Method, services
138
+ // → Class|Interface (no label match = no silent wrong hits on
139
+ // File/Variable nodes that happen to share the name).
140
+ const parts = link.contract.split('/');
141
+ const serviceName = parts[0]?.trim() ?? '';
142
+ const methodName = parts[1]?.trim() ?? '';
143
+ if (methodName) {
144
+ rows = await executor(`MATCH (n:Function|Method) WHERE n.name = $methodName
145
+ RETURN n.id AS uid, n.name AS name, n.filePath AS filePath
146
+ ORDER BY n.filePath ASC
147
+ LIMIT 1`, { methodName });
148
+ }
149
+ else if (serviceName) {
150
+ rows = await executor(`MATCH (n:Class|Interface) WHERE n.name = $serviceName
151
+ RETURN n.id AS uid, n.name AS name, n.filePath AS filePath
152
+ ORDER BY n.filePath ASC
153
+ LIMIT 1`, { serviceName });
154
+ }
155
+ else {
156
+ rows = [];
157
+ }
158
+ }
159
+ else if (link.type === 'lib') {
160
+ // Only exact match on the symbol's name. Previous fallback to
161
+ // CONTAINS on n.filePath would promote "react" to "react-native"
162
+ // or "@types/react" — silent wrong attribution. Restrict to
163
+ // package-level labels so we don't return arbitrary symbols
164
+ // named after a library.
165
+ rows = await executor(`MATCH (n:Package|Module) WHERE n.name = $contract
166
+ RETURN n.id AS uid, n.name AS name, n.filePath AS filePath
167
+ ORDER BY n.filePath ASC
168
+ LIMIT 1`, { contract: link.contract });
169
+ }
170
+ else {
171
+ return null;
172
+ }
173
+ if (rows.length > 0) {
174
+ return {
175
+ filePath: rows[0].filePath,
176
+ name: rows[0].name,
177
+ uid: String(rows[0].uid ?? ''),
178
+ };
179
+ }
180
+ }
181
+ catch (err) {
182
+ // Log but don't throw: a broken graph query in one repo shouldn't
183
+ // fail the whole manifest extraction. Unresolved contracts still
184
+ // get a synthetic symbolUid below, so cross-impact can proceed.
185
+ const message = err instanceof Error ? err.message : String(err);
186
+ console.warn(`[manifest-extractor] resolveSymbol failed for ${link.type}:${link.contract} ` +
187
+ `in ${repoPathKey}: ${message}`);
188
+ }
189
+ return null;
190
+ }
191
+ /**
192
+ * Build a canonical contract id for a manifest link.
193
+ *
194
+ * HTTP is the only type with two valid forms:
195
+ * - Explicit method: `"GET::/api/orders"` → `"http::GET::/api/orders"`
196
+ * (matches exactly against `HttpRouteExtractor` provider/consumer
197
+ * contracts, which are also keyed by `http::<METHOD>::<path>`).
198
+ * - Method-agnostic: `"/api/orders"` → `"http::*::/api/orders"`
199
+ * — the `*` is a wildcard and is intended to match any concrete
200
+ * HTTP method on that path. Wildcard-aware matching is the
201
+ * responsibility of the sync / cross-impact layer (see #793);
202
+ * downstream code should treat `http::*::<path>` as matching
203
+ * every `http::<METHOD>::<path>` for the same path.
204
+ *
205
+ * Recommend the explicit-method form in group.yaml whenever the
206
+ * manifest author knows the method — it round-trips through exact
207
+ * equality matching without requiring wildcard logic downstream.
208
+ *
209
+ * NOTE on exhaustiveness: the switch covers every current
210
+ * `ContractType` variant and falls through to a `never` assertion so
211
+ * TypeScript fails the build if a new variant is added without a
212
+ * corresponding case.
213
+ */
214
+ buildContractId(type, contract) {
215
+ switch (type) {
216
+ case 'http': {
217
+ if (/^[A-Za-z]+::/.test(contract))
218
+ return `http::${contract}`;
219
+ return `http::*::${contract}`;
220
+ }
221
+ case 'grpc':
222
+ return `grpc::${contract}`;
223
+ case 'topic':
224
+ return `topic::${contract}`;
225
+ case 'lib':
226
+ return `lib::${contract}`;
227
+ case 'custom':
228
+ return `custom::${contract}`;
229
+ default: {
230
+ const _exhaustive = type;
231
+ throw new Error(`Unhandled ContractType: ${String(_exhaustive)}`);
232
+ }
233
+ }
234
+ }
235
+ }
@@ -0,0 +1,8 @@
1
+ import type { ContractExtractor, CypherExecutor } from '../contract-extractor.js';
2
+ import type { ExtractedContract, RepoHandle } from '../types.js';
3
+ export declare class TopicExtractor implements ContractExtractor {
4
+ type: "topic";
5
+ canExtract(_repo: RepoHandle): Promise<boolean>;
6
+ extract(_dbExecutor: CypherExecutor | null, repoPath: string, _repo: RepoHandle): Promise<ExtractedContract[]>;
7
+ private dedupe;
8
+ }
@@ -0,0 +1,97 @@
1
+ import { glob } from 'glob';
2
+ import Parser from 'tree-sitter';
3
+ import { readSafe } from './fs-utils.js';
4
+ import { scanFile, unquoteLiteral } from './tree-sitter-scanner.js';
5
+ import { TOPIC_SCAN_GLOB, getProviderForFile, } from './topic-patterns/index.js';
6
+ /**
7
+ * Language-agnostic orchestrator for topic (message broker) contract
8
+ * extraction. All grammar-specific knowledge lives in `topic-patterns/*`
9
+ * — this file must not import any tree-sitter grammar directly.
10
+ *
11
+ * Flow per file:
12
+ * 1. `getProviderForFile(rel)` → compiled plugin (or `undefined` if the
13
+ * file's extension isn't registered, in which case we skip it).
14
+ * 2. `scanFile(parser, provider, content)` → list of `{meta, valueText}`
15
+ * pairs, one per matched literal.
16
+ * 3. `unquoteLiteral(valueText)` → the raw topic string.
17
+ * 4. `makeContract(topic, meta, relPath)` → `ExtractedContract`.
18
+ *
19
+ * Adding a new language is a one-file edit in `topic-patterns/index.ts`.
20
+ */
21
+ function makeContract(topicName, meta, filePath) {
22
+ return {
23
+ contractId: `topic::${topicName}`,
24
+ type: 'topic',
25
+ role: meta.role,
26
+ symbolUid: '',
27
+ symbolRef: { filePath: filePath.replace(/\\/g, '/'), name: meta.symbolName },
28
+ symbolName: meta.symbolName,
29
+ confidence: meta.confidence,
30
+ meta: {
31
+ broker: meta.broker,
32
+ topicName,
33
+ extractionStrategy: 'tree_sitter',
34
+ },
35
+ };
36
+ }
37
+ export class TopicExtractor {
38
+ type = 'topic';
39
+ async canExtract(_repo) {
40
+ return true;
41
+ }
42
+ async extract(_dbExecutor, repoPath, _repo) {
43
+ const files = await glob(TOPIC_SCAN_GLOB, {
44
+ cwd: repoPath,
45
+ ignore: [
46
+ '**/node_modules/**',
47
+ '**/.git/**',
48
+ '**/vendor/**',
49
+ '**/dist/**',
50
+ '**/build/**',
51
+ // Language-level test file conventions. Go test files
52
+ // `*_test.go` live next to source; other languages either use
53
+ // separate test directories (Python's `tests/`, Java's
54
+ // `src/test/`) or are already covered by the dist/build ignores.
55
+ // Pushed to the glob level so the orchestrator stays
56
+ // language-agnostic.
57
+ '**/*_test.go',
58
+ ],
59
+ nodir: true,
60
+ });
61
+ // One parser reused across files; the scanner calls `setLanguage` per
62
+ // file based on which plugin the registry returns.
63
+ const parser = new Parser();
64
+ const out = [];
65
+ for (const rel of files) {
66
+ const provider = getProviderForFile(rel);
67
+ if (!provider)
68
+ continue;
69
+ const content = readSafe(repoPath, rel);
70
+ if (!content)
71
+ continue;
72
+ const matches = scanFile(parser, provider, content);
73
+ for (const match of matches) {
74
+ const valueNode = match.captures.value;
75
+ if (!valueNode)
76
+ continue;
77
+ const topicName = unquoteLiteral(valueNode.text);
78
+ if (!topicName)
79
+ continue;
80
+ out.push(makeContract(topicName, match.meta, rel));
81
+ }
82
+ }
83
+ return this.dedupe(out);
84
+ }
85
+ dedupe(items) {
86
+ const seen = new Set();
87
+ const out = [];
88
+ for (const c of items) {
89
+ const k = `${c.contractId}|${c.role}|${c.symbolRef.filePath}`;
90
+ if (seen.has(k))
91
+ continue;
92
+ seen.add(k);
93
+ out.push(c);
94
+ }
95
+ return out;
96
+ }
97
+ }
@@ -0,0 +1,2 @@
1
+ import type { TopicMeta } from './types.js';
2
+ export declare const GO_TOPIC_PROVIDER: import("../tree-sitter-scanner.js").CompiledPatterns<TopicMeta>;
@@ -0,0 +1,120 @@
1
+ import Go from 'tree-sitter-go';
2
+ import { compilePatterns } from '../tree-sitter-scanner.js';
3
+ /**
4
+ * Go topic extraction patterns.
5
+ *
6
+ * Detects Sarama, segmentio/kafka-go and nats.go producer/consumer APIs:
7
+ * - `X.ConsumePartition("topic", ...)`
8
+ * - `sarama.ProducerMessage{Topic: "xxx"}`
9
+ * - `kafka.Writer{Topic: "xxx"}` / `kafka.WriterConfig{Topic: ...}`
10
+ * - `kafka.Reader{Topic: "xxx"}` / `kafka.ReaderConfig{Topic: ...}`
11
+ * - `nc.Subscribe("topic", ...)` / `js.Subscribe("topic", ...)`
12
+ * - `nc.Publish("topic", ...)` / `js.Publish("topic", ...)`
13
+ *
14
+ * Every query MUST bind `@value` to the topic literal node.
15
+ */
16
+ const GO_TOPIC_SPEC = {
17
+ name: 'go-topic',
18
+ language: Go,
19
+ patterns: [
20
+ {
21
+ meta: {
22
+ role: 'consumer',
23
+ broker: 'kafka',
24
+ confidence: 0.7,
25
+ symbolName: 'ConsumePartition',
26
+ },
27
+ query: `
28
+ (call_expression
29
+ function: (selector_expression
30
+ field: (field_identifier) @method (#eq? @method "ConsumePartition"))
31
+ arguments: (argument_list . (interpreted_string_literal) @value))
32
+ `,
33
+ },
34
+ {
35
+ meta: {
36
+ role: 'provider',
37
+ broker: 'kafka',
38
+ confidence: 0.75,
39
+ symbolName: 'sarama.ProducerMessage',
40
+ },
41
+ query: `
42
+ (composite_literal
43
+ type: (qualified_type
44
+ package: (package_identifier) @pkg (#eq? @pkg "sarama")
45
+ name: (type_identifier) @ty (#eq? @ty "ProducerMessage"))
46
+ body: (literal_value
47
+ (keyed_element
48
+ (literal_element (identifier) @field (#eq? @field "Topic"))
49
+ (literal_element (interpreted_string_literal) @value))))
50
+ `,
51
+ },
52
+ {
53
+ meta: {
54
+ role: 'provider',
55
+ broker: 'kafka',
56
+ confidence: 0.75,
57
+ symbolName: 'kafka.Writer',
58
+ },
59
+ query: `
60
+ (composite_literal
61
+ type: (qualified_type
62
+ package: (package_identifier) @pkg (#eq? @pkg "kafka")
63
+ name: (type_identifier) @ty (#match? @ty "^(Writer|WriterConfig)$"))
64
+ body: (literal_value
65
+ (keyed_element
66
+ (literal_element (identifier) @field (#eq? @field "Topic"))
67
+ (literal_element (interpreted_string_literal) @value))))
68
+ `,
69
+ },
70
+ {
71
+ meta: {
72
+ role: 'consumer',
73
+ broker: 'kafka',
74
+ confidence: 0.75,
75
+ symbolName: 'kafka.Reader',
76
+ },
77
+ query: `
78
+ (composite_literal
79
+ type: (qualified_type
80
+ package: (package_identifier) @pkg (#eq? @pkg "kafka")
81
+ name: (type_identifier) @ty (#match? @ty "^(Reader|ReaderConfig)$"))
82
+ body: (literal_value
83
+ (keyed_element
84
+ (literal_element (identifier) @field (#eq? @field "Topic"))
85
+ (literal_element (interpreted_string_literal) @value))))
86
+ `,
87
+ },
88
+ {
89
+ meta: {
90
+ role: 'consumer',
91
+ broker: 'nats',
92
+ confidence: 0.8,
93
+ symbolName: 'nc.Subscribe',
94
+ },
95
+ query: `
96
+ (call_expression
97
+ function: (selector_expression
98
+ operand: (identifier) @obj (#match? @obj "^(nc|js)$")
99
+ field: (field_identifier) @method (#match? @method "^[Ss]ubscribe$"))
100
+ arguments: (argument_list . (interpreted_string_literal) @value))
101
+ `,
102
+ },
103
+ {
104
+ meta: {
105
+ role: 'provider',
106
+ broker: 'nats',
107
+ confidence: 0.8,
108
+ symbolName: 'nc.Publish',
109
+ },
110
+ query: `
111
+ (call_expression
112
+ function: (selector_expression
113
+ operand: (identifier) @obj (#match? @obj "^(nc|js)$")
114
+ field: (field_identifier) @method (#match? @method "^[Pp]ublish$"))
115
+ arguments: (argument_list . (interpreted_string_literal) @value))
116
+ `,
117
+ },
118
+ ],
119
+ };
120
+ export const GO_TOPIC_PROVIDER = compilePatterns(GO_TOPIC_SPEC);
@@ -0,0 +1,14 @@
1
+ import type { CompiledPatterns } from '../tree-sitter-scanner.js';
2
+ import type { TopicMeta } from './types.js';
3
+ export type { TopicMeta, Broker } from './types.js';
4
+ /**
5
+ * Glob pattern for files worth scanning. Kept here so adding a new
6
+ * language to the registry also widens the glob automatically via a
7
+ * single edit.
8
+ */
9
+ export declare const TOPIC_SCAN_GLOB = "**/*.{ts,tsx,js,jsx,java,go,py}";
10
+ /**
11
+ * Return the compiled provider registered for the given file's
12
+ * extension, or `undefined` if the extension is not registered.
13
+ */
14
+ export declare function getProviderForFile(rel: string): CompiledPatterns<TopicMeta> | undefined;
@@ -0,0 +1,38 @@
1
+ import * as path from 'node:path';
2
+ import { JAVA_TOPIC_PROVIDER } from './java.js';
3
+ import { GO_TOPIC_PROVIDER } from './go.js';
4
+ import { PYTHON_TOPIC_PROVIDER } from './python.js';
5
+ import { JAVASCRIPT_TOPIC_PROVIDER, TYPESCRIPT_TOPIC_PROVIDER, TSX_TOPIC_PROVIDER, } from './node.js';
6
+ /**
7
+ * File-extension → compiled-plugin registry for topic extraction. The
8
+ * top-level orchestrator (`topic-extractor.ts`) looks up the plugin for
9
+ * each file it visits and delegates the scanning to `tree-sitter-scanner`.
10
+ *
11
+ * Keys are lowercase extensions including the leading dot. To add a new
12
+ * language, drop a `topic-patterns/<lang>.ts` that exports a compiled
13
+ * provider, import it here and register the extension(s). No edits to
14
+ * `topic-extractor.ts` are required.
15
+ */
16
+ const REGISTRY = {
17
+ '.java': JAVA_TOPIC_PROVIDER,
18
+ '.go': GO_TOPIC_PROVIDER,
19
+ '.py': PYTHON_TOPIC_PROVIDER,
20
+ '.js': JAVASCRIPT_TOPIC_PROVIDER,
21
+ '.jsx': JAVASCRIPT_TOPIC_PROVIDER,
22
+ '.ts': TYPESCRIPT_TOPIC_PROVIDER,
23
+ '.tsx': TSX_TOPIC_PROVIDER,
24
+ };
25
+ /**
26
+ * Glob pattern for files worth scanning. Kept here so adding a new
27
+ * language to the registry also widens the glob automatically via a
28
+ * single edit.
29
+ */
30
+ export const TOPIC_SCAN_GLOB = '**/*.{ts,tsx,js,jsx,java,go,py}';
31
+ /**
32
+ * Return the compiled provider registered for the given file's
33
+ * extension, or `undefined` if the extension is not registered.
34
+ */
35
+ export function getProviderForFile(rel) {
36
+ const ext = path.extname(rel).toLowerCase();
37
+ return REGISTRY[ext];
38
+ }
@@ -0,0 +1,2 @@
1
+ import type { TopicMeta } from './types.js';
2
+ export declare const JAVA_TOPIC_PROVIDER: import("../tree-sitter-scanner.js").CompiledPatterns<TopicMeta>;
@@ -0,0 +1,80 @@
1
+ import Java from 'tree-sitter-java';
2
+ import { compilePatterns } from '../tree-sitter-scanner.js';
3
+ /**
4
+ * Java topic extraction patterns.
5
+ *
6
+ * Detects Kafka and RabbitMQ (Spring conventions) producer/consumer APIs:
7
+ * - `@KafkaListener(topics = "xxx")`
8
+ * - `@RabbitListener(queues = "xxx")`
9
+ * - `kafkaTemplate.send("xxx", ...)`
10
+ * - `rabbitTemplate.convertAndSend("xxx", ...)`
11
+ *
12
+ * Every query MUST bind `@value` to the topic literal node.
13
+ */
14
+ const JAVA_TOPIC_SPEC = {
15
+ name: 'java-topic',
16
+ language: Java,
17
+ patterns: [
18
+ {
19
+ meta: {
20
+ role: 'consumer',
21
+ broker: 'kafka',
22
+ confidence: 0.8,
23
+ symbolName: 'kafkaListener',
24
+ },
25
+ query: `
26
+ (annotation
27
+ name: (identifier) @name (#eq? @name "KafkaListener")
28
+ arguments: (annotation_argument_list
29
+ (element_value_pair
30
+ key: (identifier) @key (#eq? @key "topics")
31
+ value: (string_literal) @value)))
32
+ `,
33
+ },
34
+ {
35
+ meta: {
36
+ role: 'consumer',
37
+ broker: 'rabbitmq',
38
+ confidence: 0.8,
39
+ symbolName: 'rabbitListener',
40
+ },
41
+ query: `
42
+ (annotation
43
+ name: (identifier) @name (#eq? @name "RabbitListener")
44
+ arguments: (annotation_argument_list
45
+ (element_value_pair
46
+ key: (identifier) @key (#eq? @key "queues")
47
+ value: (string_literal) @value)))
48
+ `,
49
+ },
50
+ {
51
+ meta: {
52
+ role: 'provider',
53
+ broker: 'kafka',
54
+ confidence: 0.8,
55
+ symbolName: 'kafkaTemplate.send',
56
+ },
57
+ query: `
58
+ (method_invocation
59
+ object: (identifier) @obj (#eq? @obj "kafkaTemplate")
60
+ name: (identifier) @method (#eq? @method "send")
61
+ arguments: (argument_list . (string_literal) @value))
62
+ `,
63
+ },
64
+ {
65
+ meta: {
66
+ role: 'provider',
67
+ broker: 'rabbitmq',
68
+ confidence: 0.8,
69
+ symbolName: 'rabbitTemplate.convertAndSend',
70
+ },
71
+ query: `
72
+ (method_invocation
73
+ object: (identifier) @obj (#eq? @obj "rabbitTemplate")
74
+ name: (identifier) @method (#eq? @method "convertAndSend")
75
+ arguments: (argument_list . (string_literal) @value))
76
+ `,
77
+ },
78
+ ],
79
+ };
80
+ export const JAVA_TOPIC_PROVIDER = compilePatterns(JAVA_TOPIC_SPEC);
@@ -0,0 +1,4 @@
1
+ import type { TopicMeta } from './types.js';
2
+ export declare const JAVASCRIPT_TOPIC_PROVIDER: import("../tree-sitter-scanner.js").CompiledPatterns<TopicMeta>;
3
+ export declare const TYPESCRIPT_TOPIC_PROVIDER: import("../tree-sitter-scanner.js").CompiledPatterns<TopicMeta>;
4
+ export declare const TSX_TOPIC_PROVIDER: import("../tree-sitter-scanner.js").CompiledPatterns<TopicMeta>;