@optave/codegraph 3.7.0 → 3.8.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 (401) hide show
  1. package/README.md +28 -16
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +195 -30
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/metrics.d.ts +0 -3
  6. package/dist/ast-analysis/metrics.d.ts.map +1 -1
  7. package/dist/ast-analysis/metrics.js +30 -13
  8. package/dist/ast-analysis/metrics.js.map +1 -1
  9. package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
  10. package/dist/ast-analysis/rules/javascript.js +0 -1
  11. package/dist/ast-analysis/rules/javascript.js.map +1 -1
  12. package/dist/ast-analysis/shared.d.ts.map +1 -1
  13. package/dist/ast-analysis/shared.js +24 -19
  14. package/dist/ast-analysis/shared.js.map +1 -1
  15. package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
  16. package/dist/ast-analysis/visitor-utils.js +55 -39
  17. package/dist/ast-analysis/visitor-utils.js.map +1 -1
  18. package/dist/ast-analysis/visitor.d.ts.map +1 -1
  19. package/dist/ast-analysis/visitor.js +91 -70
  20. package/dist/ast-analysis/visitor.js.map +1 -1
  21. package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
  22. package/dist/ast-analysis/visitors/ast-store-visitor.js +52 -129
  23. package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
  24. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  25. package/dist/ast-analysis/visitors/complexity-visitor.js +32 -39
  26. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  27. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  28. package/dist/ast-analysis/visitors/dataflow-visitor.js +57 -38
  29. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  30. package/dist/cli/commands/ast.js +2 -2
  31. package/dist/cli/commands/ast.js.map +1 -1
  32. package/dist/cli/commands/watch.d.ts.map +1 -1
  33. package/dist/cli/commands/watch.js +16 -2
  34. package/dist/cli/commands/watch.js.map +1 -1
  35. package/dist/db/connection.d.ts.map +1 -1
  36. package/dist/db/connection.js +29 -26
  37. package/dist/db/connection.js.map +1 -1
  38. package/dist/db/query-builder.d.ts.map +1 -1
  39. package/dist/db/query-builder.js +16 -5
  40. package/dist/db/query-builder.js.map +1 -1
  41. package/dist/db/repository/base.d.ts +10 -0
  42. package/dist/db/repository/base.d.ts.map +1 -1
  43. package/dist/db/repository/base.js +17 -0
  44. package/dist/db/repository/base.js.map +1 -1
  45. package/dist/db/repository/native-repository.d.ts +6 -1
  46. package/dist/db/repository/native-repository.d.ts.map +1 -1
  47. package/dist/db/repository/native-repository.js +77 -1
  48. package/dist/db/repository/native-repository.js.map +1 -1
  49. package/dist/db/repository/nodes.d.ts.map +1 -1
  50. package/dist/db/repository/nodes.js +8 -4
  51. package/dist/db/repository/nodes.js.map +1 -1
  52. package/dist/db/repository/sqlite-repository.d.ts +3 -0
  53. package/dist/db/repository/sqlite-repository.d.ts.map +1 -1
  54. package/dist/db/repository/sqlite-repository.js +26 -0
  55. package/dist/db/repository/sqlite-repository.js.map +1 -1
  56. package/dist/domain/analysis/brief.d.ts.map +1 -1
  57. package/dist/domain/analysis/brief.js +13 -17
  58. package/dist/domain/analysis/brief.js.map +1 -1
  59. package/dist/domain/analysis/context.d.ts.map +1 -1
  60. package/dist/domain/analysis/context.js +14 -11
  61. package/dist/domain/analysis/context.js.map +1 -1
  62. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  63. package/dist/domain/analysis/dependencies.js +53 -52
  64. package/dist/domain/analysis/dependencies.js.map +1 -1
  65. package/dist/domain/analysis/fn-impact.d.ts +2 -7
  66. package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
  67. package/dist/domain/analysis/fn-impact.js +33 -31
  68. package/dist/domain/analysis/fn-impact.js.map +1 -1
  69. package/dist/domain/analysis/implementations.d.ts.map +1 -1
  70. package/dist/domain/analysis/implementations.js +11 -19
  71. package/dist/domain/analysis/implementations.js.map +1 -1
  72. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  73. package/dist/domain/analysis/module-map.js +55 -76
  74. package/dist/domain/analysis/module-map.js.map +1 -1
  75. package/dist/domain/analysis/query-helpers.d.ts +7 -0
  76. package/dist/domain/analysis/query-helpers.d.ts.map +1 -1
  77. package/dist/domain/analysis/query-helpers.js +15 -1
  78. package/dist/domain/analysis/query-helpers.js.map +1 -1
  79. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  80. package/dist/domain/graph/builder/pipeline.js +315 -43
  81. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  82. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  83. package/dist/domain/graph/builder/stages/build-edges.js +106 -1
  84. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  85. package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
  86. package/dist/domain/graph/builder/stages/collect-files.js +17 -5
  87. package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
  88. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  89. package/dist/domain/graph/builder/stages/detect-changes.js +99 -51
  90. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  91. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  92. package/dist/domain/graph/builder/stages/finalize.js +34 -7
  93. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  94. package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
  95. package/dist/domain/graph/builder/stages/insert-nodes.js +50 -26
  96. package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
  97. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  98. package/dist/domain/graph/builder/stages/resolve-imports.js +95 -84
  99. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  100. package/dist/domain/graph/cycles.d.ts +6 -0
  101. package/dist/domain/graph/cycles.d.ts.map +1 -1
  102. package/dist/domain/graph/cycles.js +114 -22
  103. package/dist/domain/graph/cycles.js.map +1 -1
  104. package/dist/domain/graph/resolve.js +1 -1
  105. package/dist/domain/graph/resolve.js.map +1 -1
  106. package/dist/domain/graph/watcher.d.ts +2 -0
  107. package/dist/domain/graph/watcher.d.ts.map +1 -1
  108. package/dist/domain/graph/watcher.js +170 -75
  109. package/dist/domain/graph/watcher.js.map +1 -1
  110. package/dist/domain/parser.d.ts +1 -6
  111. package/dist/domain/parser.d.ts.map +1 -1
  112. package/dist/domain/parser.js +101 -32
  113. package/dist/domain/parser.js.map +1 -1
  114. package/dist/domain/search/generator.js +1 -1
  115. package/dist/domain/search/generator.js.map +1 -1
  116. package/dist/domain/search/models.d.ts +4 -3
  117. package/dist/domain/search/models.d.ts.map +1 -1
  118. package/dist/domain/search/models.js +18 -5
  119. package/dist/domain/search/models.js.map +1 -1
  120. package/dist/domain/search/search/hybrid.d.ts.map +1 -1
  121. package/dist/domain/search/search/hybrid.js +29 -18
  122. package/dist/domain/search/search/hybrid.js.map +1 -1
  123. package/dist/extractors/clojure.d.ts +12 -0
  124. package/dist/extractors/clojure.d.ts.map +1 -0
  125. package/dist/extractors/clojure.js +245 -0
  126. package/dist/extractors/clojure.js.map +1 -0
  127. package/dist/extractors/cuda.d.ts +11 -0
  128. package/dist/extractors/cuda.d.ts.map +1 -0
  129. package/dist/extractors/cuda.js +302 -0
  130. package/dist/extractors/cuda.js.map +1 -0
  131. package/dist/extractors/erlang.d.ts +14 -0
  132. package/dist/extractors/erlang.d.ts.map +1 -0
  133. package/dist/extractors/erlang.js +239 -0
  134. package/dist/extractors/erlang.js.map +1 -0
  135. package/dist/extractors/fsharp.d.ts +13 -0
  136. package/dist/extractors/fsharp.d.ts.map +1 -0
  137. package/dist/extractors/fsharp.js +218 -0
  138. package/dist/extractors/fsharp.js.map +1 -0
  139. package/dist/extractors/gleam.d.ts +14 -0
  140. package/dist/extractors/gleam.d.ts.map +1 -0
  141. package/dist/extractors/gleam.js +229 -0
  142. package/dist/extractors/gleam.js.map +1 -0
  143. package/dist/extractors/go.js +36 -33
  144. package/dist/extractors/go.js.map +1 -1
  145. package/dist/extractors/groovy.d.ts +10 -0
  146. package/dist/extractors/groovy.d.ts.map +1 -0
  147. package/dist/extractors/groovy.js +304 -0
  148. package/dist/extractors/groovy.js.map +1 -0
  149. package/dist/extractors/helpers.d.ts.map +1 -1
  150. package/dist/extractors/helpers.js +40 -29
  151. package/dist/extractors/helpers.js.map +1 -1
  152. package/dist/extractors/index.d.ts +11 -0
  153. package/dist/extractors/index.d.ts.map +1 -1
  154. package/dist/extractors/index.js +11 -0
  155. package/dist/extractors/index.js.map +1 -1
  156. package/dist/extractors/java.js +58 -46
  157. package/dist/extractors/java.js.map +1 -1
  158. package/dist/extractors/javascript.js +46 -45
  159. package/dist/extractors/javascript.js.map +1 -1
  160. package/dist/extractors/julia.d.ts +16 -0
  161. package/dist/extractors/julia.d.ts.map +1 -0
  162. package/dist/extractors/julia.js +287 -0
  163. package/dist/extractors/julia.js.map +1 -0
  164. package/dist/extractors/kotlin.js +84 -78
  165. package/dist/extractors/kotlin.js.map +1 -1
  166. package/dist/extractors/objc.d.ts +9 -0
  167. package/dist/extractors/objc.d.ts.map +1 -0
  168. package/dist/extractors/objc.js +406 -0
  169. package/dist/extractors/objc.js.map +1 -0
  170. package/dist/extractors/ocaml.js +74 -0
  171. package/dist/extractors/ocaml.js.map +1 -1
  172. package/dist/extractors/python.js +29 -24
  173. package/dist/extractors/python.js.map +1 -1
  174. package/dist/extractors/r.d.ts +13 -0
  175. package/dist/extractors/r.d.ts.map +1 -0
  176. package/dist/extractors/r.js +251 -0
  177. package/dist/extractors/r.js.map +1 -0
  178. package/dist/extractors/rust.js +41 -32
  179. package/dist/extractors/rust.js.map +1 -1
  180. package/dist/extractors/solidity.d.ts +9 -0
  181. package/dist/extractors/solidity.d.ts.map +1 -0
  182. package/dist/extractors/solidity.js +365 -0
  183. package/dist/extractors/solidity.js.map +1 -0
  184. package/dist/extractors/swift.js +83 -81
  185. package/dist/extractors/swift.js.map +1 -1
  186. package/dist/extractors/verilog.d.ts +9 -0
  187. package/dist/extractors/verilog.d.ts.map +1 -0
  188. package/dist/extractors/verilog.js +286 -0
  189. package/dist/extractors/verilog.js.map +1 -0
  190. package/dist/extractors/zig.js +58 -60
  191. package/dist/extractors/zig.js.map +1 -1
  192. package/dist/features/ast.d.ts +16 -14
  193. package/dist/features/ast.d.ts.map +1 -1
  194. package/dist/features/ast.js +84 -83
  195. package/dist/features/ast.js.map +1 -1
  196. package/dist/features/audit.d.ts.map +1 -1
  197. package/dist/features/audit.js +8 -6
  198. package/dist/features/audit.js.map +1 -1
  199. package/dist/features/branch-compare.d.ts.map +1 -1
  200. package/dist/features/branch-compare.js +69 -72
  201. package/dist/features/branch-compare.js.map +1 -1
  202. package/dist/features/communities.d.ts.map +1 -1
  203. package/dist/features/communities.js +19 -7
  204. package/dist/features/communities.js.map +1 -1
  205. package/dist/features/complexity.d.ts.map +1 -1
  206. package/dist/features/complexity.js +120 -125
  207. package/dist/features/complexity.js.map +1 -1
  208. package/dist/features/dataflow.d.ts.map +1 -1
  209. package/dist/features/dataflow.js +136 -137
  210. package/dist/features/dataflow.js.map +1 -1
  211. package/dist/features/flow.d.ts.map +1 -1
  212. package/dist/features/flow.js +84 -79
  213. package/dist/features/flow.js.map +1 -1
  214. package/dist/features/structure-query.d.ts.map +1 -1
  215. package/dist/features/structure-query.js +69 -65
  216. package/dist/features/structure-query.js.map +1 -1
  217. package/dist/graph/algorithms/bfs.d.ts +2 -0
  218. package/dist/graph/algorithms/bfs.d.ts.map +1 -1
  219. package/dist/graph/algorithms/bfs.js +27 -0
  220. package/dist/graph/algorithms/bfs.js.map +1 -1
  221. package/dist/graph/algorithms/centrality.d.ts +2 -0
  222. package/dist/graph/algorithms/centrality.d.ts.map +1 -1
  223. package/dist/graph/algorithms/centrality.js +28 -0
  224. package/dist/graph/algorithms/centrality.js.map +1 -1
  225. package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
  226. package/dist/graph/algorithms/leiden/optimiser.js +70 -55
  227. package/dist/graph/algorithms/leiden/optimiser.js.map +1 -1
  228. package/dist/graph/algorithms/leiden/partition.d.ts.map +1 -1
  229. package/dist/graph/algorithms/leiden/partition.js +288 -266
  230. package/dist/graph/algorithms/leiden/partition.js.map +1 -1
  231. package/dist/graph/algorithms/louvain.d.ts +3 -4
  232. package/dist/graph/algorithms/louvain.d.ts.map +1 -1
  233. package/dist/graph/algorithms/louvain.js +29 -0
  234. package/dist/graph/algorithms/louvain.js.map +1 -1
  235. package/dist/graph/algorithms/shortest-path.d.ts +2 -0
  236. package/dist/graph/algorithms/shortest-path.d.ts.map +1 -1
  237. package/dist/graph/algorithms/shortest-path.js +18 -1
  238. package/dist/graph/algorithms/shortest-path.js.map +1 -1
  239. package/dist/graph/model.d.ts.map +1 -1
  240. package/dist/graph/model.js +5 -1
  241. package/dist/graph/model.js.map +1 -1
  242. package/dist/infrastructure/config.d.ts.map +1 -1
  243. package/dist/infrastructure/config.js +6 -4
  244. package/dist/infrastructure/config.js.map +1 -1
  245. package/dist/infrastructure/suppress.d.ts +25 -0
  246. package/dist/infrastructure/suppress.d.ts.map +1 -0
  247. package/dist/infrastructure/suppress.js +43 -0
  248. package/dist/infrastructure/suppress.js.map +1 -0
  249. package/dist/mcp/server.d.ts.map +1 -1
  250. package/dist/mcp/server.js +29 -24
  251. package/dist/mcp/server.js.map +1 -1
  252. package/dist/presentation/dataflow.d.ts.map +1 -1
  253. package/dist/presentation/dataflow.js +47 -38
  254. package/dist/presentation/dataflow.js.map +1 -1
  255. package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -1
  256. package/dist/presentation/diff-impact-mermaid.js +60 -51
  257. package/dist/presentation/diff-impact-mermaid.js.map +1 -1
  258. package/dist/presentation/queries-cli/exports.d.ts.map +1 -1
  259. package/dist/presentation/queries-cli/exports.js +20 -14
  260. package/dist/presentation/queries-cli/exports.js.map +1 -1
  261. package/dist/presentation/queries-cli/impact.d.ts.map +1 -1
  262. package/dist/presentation/queries-cli/impact.js +15 -13
  263. package/dist/presentation/queries-cli/impact.js.map +1 -1
  264. package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
  265. package/dist/presentation/queries-cli/inspect.js +101 -79
  266. package/dist/presentation/queries-cli/inspect.js.map +1 -1
  267. package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
  268. package/dist/presentation/queries-cli/overview.js +25 -16
  269. package/dist/presentation/queries-cli/overview.js.map +1 -1
  270. package/dist/presentation/queries-cli/path.js +26 -20
  271. package/dist/presentation/queries-cli/path.js.map +1 -1
  272. package/dist/presentation/result-formatter.d.ts +10 -0
  273. package/dist/presentation/result-formatter.d.ts.map +1 -1
  274. package/dist/presentation/result-formatter.js +16 -1
  275. package/dist/presentation/result-formatter.js.map +1 -1
  276. package/dist/presentation/viewer.d.ts.map +1 -1
  277. package/dist/presentation/viewer.js +18 -12
  278. package/dist/presentation/viewer.js.map +1 -1
  279. package/dist/shared/errors.d.ts +5 -0
  280. package/dist/shared/errors.d.ts.map +1 -1
  281. package/dist/shared/errors.js +5 -0
  282. package/dist/shared/errors.js.map +1 -1
  283. package/dist/shared/hierarchy.d.ts +8 -2
  284. package/dist/shared/hierarchy.d.ts.map +1 -1
  285. package/dist/shared/hierarchy.js +42 -1
  286. package/dist/shared/hierarchy.js.map +1 -1
  287. package/dist/shared/normalize.d.ts +6 -1
  288. package/dist/shared/normalize.d.ts.map +1 -1
  289. package/dist/shared/normalize.js +20 -12
  290. package/dist/shared/normalize.js.map +1 -1
  291. package/dist/shared/paginate.d.ts +0 -9
  292. package/dist/shared/paginate.d.ts.map +1 -1
  293. package/dist/shared/paginate.js +0 -15
  294. package/dist/shared/paginate.js.map +1 -1
  295. package/dist/types.d.ts +129 -3
  296. package/dist/types.d.ts.map +1 -1
  297. package/grammars/tree-sitter-clojure.wasm +0 -0
  298. package/grammars/tree-sitter-cuda.wasm +0 -0
  299. package/grammars/tree-sitter-erlang.wasm +0 -0
  300. package/grammars/tree-sitter-fsharp.wasm +0 -0
  301. package/grammars/tree-sitter-gleam.wasm +0 -0
  302. package/grammars/tree-sitter-groovy.wasm +0 -0
  303. package/grammars/tree-sitter-julia.wasm +0 -0
  304. package/grammars/tree-sitter-objc.wasm +0 -0
  305. package/grammars/tree-sitter-ocaml_interface.wasm +0 -0
  306. package/grammars/tree-sitter-r.wasm +0 -0
  307. package/grammars/tree-sitter-solidity.wasm +0 -0
  308. package/grammars/tree-sitter-verilog.wasm +0 -0
  309. package/package.json +18 -7
  310. package/src/ast-analysis/engine.ts +245 -42
  311. package/src/ast-analysis/metrics.ts +33 -11
  312. package/src/ast-analysis/rules/javascript.ts +0 -1
  313. package/src/ast-analysis/shared.ts +33 -24
  314. package/src/ast-analysis/visitor-utils.ts +52 -32
  315. package/src/ast-analysis/visitor.ts +132 -71
  316. package/src/ast-analysis/visitors/ast-store-visitor.ts +49 -119
  317. package/src/ast-analysis/visitors/complexity-visitor.ts +35 -40
  318. package/src/ast-analysis/visitors/dataflow-visitor.ts +87 -43
  319. package/src/cli/commands/ast.ts +2 -2
  320. package/src/cli/commands/watch.ts +16 -2
  321. package/src/db/connection.ts +29 -28
  322. package/src/db/query-builder.ts +15 -3
  323. package/src/db/repository/base.ts +20 -0
  324. package/src/db/repository/native-repository.ts +79 -1
  325. package/src/db/repository/nodes.ts +13 -8
  326. package/src/db/repository/sqlite-repository.ts +29 -0
  327. package/src/domain/analysis/brief.ts +15 -25
  328. package/src/domain/analysis/context.ts +17 -10
  329. package/src/domain/analysis/dependencies.ts +67 -76
  330. package/src/domain/analysis/fn-impact.ts +36 -43
  331. package/src/domain/analysis/implementations.ts +11 -17
  332. package/src/domain/analysis/module-map.ts +58 -92
  333. package/src/domain/analysis/query-helpers.ts +18 -1
  334. package/src/domain/graph/builder/pipeline.ts +366 -41
  335. package/src/domain/graph/builder/stages/build-edges.ts +162 -1
  336. package/src/domain/graph/builder/stages/collect-files.ts +18 -7
  337. package/src/domain/graph/builder/stages/detect-changes.ts +110 -56
  338. package/src/domain/graph/builder/stages/finalize.ts +41 -11
  339. package/src/domain/graph/builder/stages/insert-nodes.ts +75 -39
  340. package/src/domain/graph/builder/stages/resolve-imports.ts +122 -100
  341. package/src/domain/graph/cycles.ts +110 -23
  342. package/src/domain/graph/resolve.ts +1 -1
  343. package/src/domain/graph/watcher.ts +202 -96
  344. package/src/domain/parser.ts +122 -28
  345. package/src/domain/search/generator.ts +1 -1
  346. package/src/domain/search/models.ts +17 -4
  347. package/src/domain/search/search/hybrid.ts +69 -51
  348. package/src/extractors/clojure.ts +273 -0
  349. package/src/extractors/cuda.ts +316 -0
  350. package/src/extractors/erlang.ts +252 -0
  351. package/src/extractors/fsharp.ts +253 -0
  352. package/src/extractors/gleam.ts +246 -0
  353. package/src/extractors/go.ts +43 -33
  354. package/src/extractors/groovy.ts +332 -0
  355. package/src/extractors/helpers.ts +37 -23
  356. package/src/extractors/index.ts +11 -0
  357. package/src/extractors/java.ts +66 -47
  358. package/src/extractors/javascript.ts +45 -46
  359. package/src/extractors/julia.ts +318 -0
  360. package/src/extractors/kotlin.ts +84 -77
  361. package/src/extractors/objc.ts +431 -0
  362. package/src/extractors/ocaml.ts +78 -0
  363. package/src/extractors/python.ts +31 -25
  364. package/src/extractors/r.ts +253 -0
  365. package/src/extractors/rust.ts +37 -29
  366. package/src/extractors/solidity.ts +394 -0
  367. package/src/extractors/swift.ts +81 -80
  368. package/src/extractors/verilog.ts +315 -0
  369. package/src/extractors/zig.ts +58 -61
  370. package/src/features/ast.ts +131 -112
  371. package/src/features/audit.ts +8 -6
  372. package/src/features/branch-compare.ts +105 -79
  373. package/src/features/communities.ts +25 -10
  374. package/src/features/complexity.ts +171 -134
  375. package/src/features/dataflow.ts +165 -175
  376. package/src/features/flow.ts +129 -92
  377. package/src/features/structure-query.ts +79 -64
  378. package/src/graph/algorithms/bfs.ts +34 -0
  379. package/src/graph/algorithms/centrality.ts +30 -0
  380. package/src/graph/algorithms/leiden/optimiser.ts +99 -55
  381. package/src/graph/algorithms/leiden/partition.ts +359 -294
  382. package/src/graph/algorithms/louvain.ts +31 -4
  383. package/src/graph/algorithms/shortest-path.ts +20 -1
  384. package/src/graph/model.ts +6 -1
  385. package/src/infrastructure/config.ts +6 -4
  386. package/src/infrastructure/suppress.ts +47 -0
  387. package/src/mcp/server.ts +53 -37
  388. package/src/presentation/dataflow.ts +50 -44
  389. package/src/presentation/diff-impact-mermaid.ts +104 -62
  390. package/src/presentation/queries-cli/exports.ts +21 -13
  391. package/src/presentation/queries-cli/impact.ts +15 -13
  392. package/src/presentation/queries-cli/inspect.ts +100 -81
  393. package/src/presentation/queries-cli/overview.ts +26 -16
  394. package/src/presentation/queries-cli/path.ts +33 -25
  395. package/src/presentation/result-formatter.ts +19 -1
  396. package/src/presentation/viewer.ts +42 -14
  397. package/src/shared/errors.ts +6 -0
  398. package/src/shared/hierarchy.ts +50 -2
  399. package/src/shared/normalize.ts +31 -12
  400. package/src/shared/paginate.ts +0 -17
  401. package/src/types.ts +138 -3
@@ -0,0 +1,431 @@
1
+ import type {
2
+ Call,
3
+ ExtractorOutput,
4
+ SubDeclaration,
5
+ TreeSitterNode,
6
+ TreeSitterTree,
7
+ } from '../types.js';
8
+ import { findChild, nodeEndLine } from './helpers.js';
9
+
10
+ /**
11
+ * Extract symbols from Objective-C files.
12
+ *
13
+ * The tree-sitter-objc grammar extends C with @interface, @implementation,
14
+ * @protocol, method declarations, #import, and message expressions.
15
+ */
16
+ export function extractObjCSymbols(tree: TreeSitterTree, _filePath: string): ExtractorOutput {
17
+ const ctx: ExtractorOutput = {
18
+ definitions: [],
19
+ calls: [],
20
+ imports: [],
21
+ classes: [],
22
+ exports: [],
23
+ typeMap: new Map(),
24
+ };
25
+
26
+ walkObjCNode(tree.rootNode, ctx);
27
+ return ctx;
28
+ }
29
+
30
+ function walkObjCNode(node: TreeSitterNode, ctx: ExtractorOutput): void {
31
+ switch (node.type) {
32
+ case 'class_interface':
33
+ handleClassInterface(node, ctx);
34
+ break;
35
+ case 'class_implementation':
36
+ handleClassImplementation(node, ctx);
37
+ break;
38
+ case 'protocol_declaration':
39
+ handleProtocolDecl(node, ctx);
40
+ break;
41
+ case 'category_interface':
42
+ handleCategoryInterface(node, ctx);
43
+ break;
44
+ case 'category_implementation':
45
+ handleCategoryImplementation(node, ctx);
46
+ break;
47
+ case 'method_declaration':
48
+ case 'method_definition':
49
+ handleMethodDecl(node, ctx);
50
+ break;
51
+ case 'function_definition':
52
+ handleFunctionDef(node, ctx);
53
+ break;
54
+ case 'preproc_include':
55
+ case 'preproc_import':
56
+ handleImport(node, ctx);
57
+ break;
58
+ case 'import_declaration':
59
+ handleAtImport(node, ctx);
60
+ break;
61
+ case 'struct_specifier':
62
+ handleStructSpecifier(node, ctx);
63
+ break;
64
+ case 'enum_specifier':
65
+ handleEnumSpecifier(node, ctx);
66
+ break;
67
+ case 'type_definition':
68
+ handleTypedef(node, ctx);
69
+ break;
70
+ case 'call_expression':
71
+ handleCCallExpr(node, ctx);
72
+ break;
73
+ case 'message_expression':
74
+ handleMessageExpr(node, ctx);
75
+ break;
76
+ }
77
+
78
+ for (let i = 0; i < node.childCount; i++) {
79
+ const child = node.child(i);
80
+ if (child) walkObjCNode(child, ctx);
81
+ }
82
+ }
83
+
84
+ // ── ObjC class/protocol handlers ──────────────────────────────────────────
85
+
86
+ function handleClassInterface(node: TreeSitterNode, ctx: ExtractorOutput): void {
87
+ const nameNode = node.childForFieldName('name') || findObjCDeclName(node);
88
+ if (!nameNode) return;
89
+ const name = nameNode.text;
90
+
91
+ const members = collectClassMembers(node);
92
+ ctx.definitions.push({
93
+ name,
94
+ kind: 'class',
95
+ line: node.startPosition.row + 1,
96
+ endLine: nodeEndLine(node),
97
+ children: members.length > 0 ? members : undefined,
98
+ });
99
+
100
+ // Superclass
101
+ const superclass = node.childForFieldName('superclass');
102
+ if (superclass) {
103
+ ctx.classes.push({ name, extends: superclass.text, line: node.startPosition.row + 1 });
104
+ }
105
+
106
+ // Protocols
107
+ const protocols = findChild(node, 'protocol_qualifiers');
108
+ if (protocols) {
109
+ for (let i = 0; i < protocols.childCount; i++) {
110
+ const proto = protocols.child(i);
111
+ if (proto && proto.type === 'identifier') {
112
+ ctx.classes.push({ name, implements: proto.text, line: node.startPosition.row + 1 });
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ function handleClassImplementation(node: TreeSitterNode, ctx: ExtractorOutput): void {
119
+ const nameNode = node.childForFieldName('name') || findObjCDeclName(node);
120
+ if (!nameNode) return;
121
+
122
+ ctx.definitions.push({
123
+ name: nameNode.text,
124
+ kind: 'class',
125
+ line: node.startPosition.row + 1,
126
+ endLine: nodeEndLine(node),
127
+ });
128
+ }
129
+
130
+ function handleProtocolDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
131
+ const nameNode = node.childForFieldName('name') || findObjCDeclName(node);
132
+ if (!nameNode) return;
133
+
134
+ ctx.definitions.push({
135
+ name: nameNode.text,
136
+ kind: 'interface',
137
+ line: node.startPosition.row + 1,
138
+ endLine: nodeEndLine(node),
139
+ });
140
+ }
141
+
142
+ function handleCategoryInterface(node: TreeSitterNode, ctx: ExtractorOutput): void {
143
+ const nameNode = node.childForFieldName('name') || findObjCDeclName(node);
144
+ if (!nameNode) return;
145
+ const category = node.childForFieldName('category');
146
+ const catName = category ? `${nameNode.text}(${category.text})` : nameNode.text;
147
+
148
+ ctx.definitions.push({
149
+ name: catName,
150
+ kind: 'class',
151
+ line: node.startPosition.row + 1,
152
+ endLine: nodeEndLine(node),
153
+ });
154
+ }
155
+
156
+ function handleCategoryImplementation(node: TreeSitterNode, ctx: ExtractorOutput): void {
157
+ const nameNode = node.childForFieldName('name') || findObjCDeclName(node);
158
+ if (!nameNode) return;
159
+ const category = node.childForFieldName('category');
160
+ const catName = category ? `${nameNode.text}(${category.text})` : nameNode.text;
161
+
162
+ ctx.definitions.push({
163
+ name: catName,
164
+ kind: 'class',
165
+ line: node.startPosition.row + 1,
166
+ endLine: nodeEndLine(node),
167
+ });
168
+ }
169
+
170
+ // ── Method / function handlers ────────────────────────────────────────────
171
+
172
+ function handleMethodDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
173
+ const selector = buildSelector(node);
174
+ if (!selector) return;
175
+
176
+ const parentClass = findObjCParentClass(node);
177
+ const fullName = parentClass ? `${parentClass}.${selector}` : selector;
178
+
179
+ const params = extractMethodParams(node);
180
+ ctx.definitions.push({
181
+ name: fullName,
182
+ kind: 'method',
183
+ line: node.startPosition.row + 1,
184
+ endLine: nodeEndLine(node),
185
+ children: params.length > 0 ? params : undefined,
186
+ });
187
+ }
188
+
189
+ function handleFunctionDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
190
+ const declarator = node.childForFieldName('declarator');
191
+ if (!declarator) return;
192
+ const funcDeclarator =
193
+ declarator.type === 'function_declarator'
194
+ ? declarator
195
+ : findChild(declarator, 'function_declarator');
196
+ if (!funcDeclarator) return;
197
+ const nameNode = funcDeclarator.childForFieldName('declarator');
198
+ if (!nameNode) return;
199
+
200
+ const params = extractCParams(funcDeclarator.childForFieldName('parameters'));
201
+ ctx.definitions.push({
202
+ name: nameNode.text,
203
+ kind: 'function',
204
+ line: node.startPosition.row + 1,
205
+ endLine: nodeEndLine(node),
206
+ children: params.length > 0 ? params : undefined,
207
+ });
208
+ }
209
+
210
+ // ── Import handlers ───────────────────────────────────────────────────────
211
+
212
+ function handleImport(node: TreeSitterNode, ctx: ExtractorOutput): void {
213
+ const pathNode = node.childForFieldName('path');
214
+ if (!pathNode) return;
215
+ const raw = pathNode.text;
216
+ const source = raw.replace(/^["<]|[">]$/g, '');
217
+ const lastName = source.split('/').pop() ?? source;
218
+ ctx.imports.push({
219
+ source,
220
+ names: [lastName],
221
+ line: node.startPosition.row + 1,
222
+ cInclude: true,
223
+ });
224
+ }
225
+
226
+ function handleAtImport(node: TreeSitterNode, ctx: ExtractorOutput): void {
227
+ // @import Foundation;
228
+ const moduleNode = node.childForFieldName('module') || findChild(node, 'identifier');
229
+ if (moduleNode) {
230
+ ctx.imports.push({
231
+ source: moduleNode.text,
232
+ names: [moduleNode.text],
233
+ line: node.startPosition.row + 1,
234
+ });
235
+ }
236
+ }
237
+
238
+ // ── C-compatible type handlers ────────────────────────────────────────────
239
+
240
+ function handleStructSpecifier(node: TreeSitterNode, ctx: ExtractorOutput): void {
241
+ const nameNode = node.childForFieldName('name');
242
+ if (!nameNode) return;
243
+ ctx.definitions.push({
244
+ name: nameNode.text,
245
+ kind: 'struct',
246
+ line: node.startPosition.row + 1,
247
+ endLine: nodeEndLine(node),
248
+ });
249
+ }
250
+
251
+ function handleEnumSpecifier(node: TreeSitterNode, ctx: ExtractorOutput): void {
252
+ const nameNode = node.childForFieldName('name');
253
+ if (!nameNode) return;
254
+ ctx.definitions.push({
255
+ name: nameNode.text,
256
+ kind: 'enum',
257
+ line: node.startPosition.row + 1,
258
+ endLine: nodeEndLine(node),
259
+ });
260
+ }
261
+
262
+ function handleTypedef(node: TreeSitterNode, ctx: ExtractorOutput): void {
263
+ let name: string | undefined;
264
+ for (let i = node.childCount - 1; i >= 0; i--) {
265
+ const child = node.child(i);
266
+ if (
267
+ child &&
268
+ (child.type === 'type_identifier' ||
269
+ child.type === 'identifier' ||
270
+ child.type === 'primitive_type')
271
+ ) {
272
+ name = child.text;
273
+ break;
274
+ }
275
+ }
276
+ if (!name) return;
277
+ ctx.definitions.push({
278
+ name,
279
+ kind: 'type',
280
+ line: node.startPosition.row + 1,
281
+ endLine: nodeEndLine(node),
282
+ });
283
+ }
284
+
285
+ // ── Call handlers ─────────────────────────────────────────────────────────
286
+
287
+ function handleCCallExpr(node: TreeSitterNode, ctx: ExtractorOutput): void {
288
+ const funcNode = node.childForFieldName('function');
289
+ if (!funcNode) return;
290
+ const call: Call = { name: '', line: node.startPosition.row + 1 };
291
+ if (funcNode.type === 'field_expression') {
292
+ const field = funcNode.childForFieldName('field');
293
+ const argument = funcNode.childForFieldName('argument');
294
+ if (field) call.name = field.text;
295
+ if (argument) call.receiver = argument.text;
296
+ } else {
297
+ call.name = funcNode.text;
298
+ }
299
+ if (call.name) ctx.calls.push(call);
300
+ }
301
+
302
+ function handleMessageExpr(node: TreeSitterNode, ctx: ExtractorOutput): void {
303
+ // [receiver selector:arg ...]
304
+ const receiver = node.childForFieldName('receiver');
305
+ const selector = node.childForFieldName('selector');
306
+ if (!selector) return;
307
+
308
+ const call: Call = { name: selector.text, line: node.startPosition.row + 1 };
309
+ if (receiver) call.receiver = receiver.text;
310
+ ctx.calls.push(call);
311
+ }
312
+
313
+ // ── Helpers ───────────────────────────────────────────────────────────────
314
+
315
+ function buildSelector(methodNode: TreeSitterNode): string | null {
316
+ const selector = methodNode.childForFieldName('selector');
317
+ if (selector) return selector.text;
318
+
319
+ // Build selector from keyword children: initWith:name:
320
+ const parts: string[] = [];
321
+ for (let i = 0; i < methodNode.childCount; i++) {
322
+ const child = methodNode.child(i);
323
+ if (!child) continue;
324
+ if (child.type === 'keyword_selector') {
325
+ for (let j = 0; j < child.childCount; j++) {
326
+ const kw = child.child(j);
327
+ if (kw && kw.type === 'keyword_declarator') {
328
+ const kwName = kw.childForFieldName('keyword');
329
+ if (kwName) parts.push(kwName.text);
330
+ }
331
+ }
332
+ }
333
+ if (child.type === 'identifier' && i === 1) {
334
+ // Simple unary selector
335
+ return child.text;
336
+ }
337
+ }
338
+ return parts.length > 0 ? `${parts.join(':')}:` : null;
339
+ }
340
+
341
+ function findObjCParentClass(node: TreeSitterNode): string | null {
342
+ let current = node.parent;
343
+ while (current) {
344
+ if (
345
+ current.type === 'class_interface' ||
346
+ current.type === 'class_implementation' ||
347
+ current.type === 'protocol_declaration' ||
348
+ current.type === 'category_interface' ||
349
+ current.type === 'category_implementation'
350
+ ) {
351
+ const nameNode = current.childForFieldName('name') || findObjCDeclName(current);
352
+ return nameNode ? nameNode.text : null;
353
+ }
354
+ current = current.parent;
355
+ }
356
+ return null;
357
+ }
358
+
359
+ /**
360
+ * Find the declaration name for ObjC constructs where the grammar does not
361
+ * expose the class/protocol name as a named field. The identifier appears
362
+ * right after the `@interface` / `@implementation` / `@protocol` keyword.
363
+ */
364
+ function findObjCDeclName(node: TreeSitterNode): TreeSitterNode | null {
365
+ for (let i = 0; i < node.childCount; i++) {
366
+ const child = node.child(i);
367
+ if (child && child.type === 'identifier') return child;
368
+ }
369
+ return null;
370
+ }
371
+
372
+ function collectClassMembers(classNode: TreeSitterNode): SubDeclaration[] {
373
+ const members: SubDeclaration[] = [];
374
+ for (let i = 0; i < classNode.childCount; i++) {
375
+ const child = classNode.child(i);
376
+ if (!child) continue;
377
+ if (child.type === 'method_declaration' || child.type === 'method_definition') {
378
+ const sel = buildSelector(child);
379
+ if (sel) {
380
+ members.push({ name: sel, kind: 'method', line: child.startPosition.row + 1 });
381
+ }
382
+ }
383
+ if (child.type === 'property_declaration') {
384
+ const propName = child.childForFieldName('name');
385
+ if (propName) {
386
+ members.push({ name: propName.text, kind: 'property', line: child.startPosition.row + 1 });
387
+ }
388
+ }
389
+ }
390
+ return members;
391
+ }
392
+
393
+ function extractMethodParams(methodNode: TreeSitterNode): SubDeclaration[] {
394
+ const params: SubDeclaration[] = [];
395
+ for (let i = 0; i < methodNode.childCount; i++) {
396
+ const child = methodNode.child(i);
397
+ if (!child || child.type !== 'keyword_selector') continue;
398
+ for (let j = 0; j < child.childCount; j++) {
399
+ const kw = child.child(j);
400
+ if (kw && kw.type === 'keyword_declarator') {
401
+ const nameNode = kw.childForFieldName('name');
402
+ if (nameNode) {
403
+ params.push({
404
+ name: nameNode.text,
405
+ kind: 'parameter',
406
+ line: nameNode.startPosition.row + 1,
407
+ });
408
+ }
409
+ }
410
+ }
411
+ }
412
+ return params;
413
+ }
414
+
415
+ function extractCParams(paramListNode: TreeSitterNode | null): SubDeclaration[] {
416
+ const params: SubDeclaration[] = [];
417
+ if (!paramListNode) return params;
418
+ for (let i = 0; i < paramListNode.childCount; i++) {
419
+ const param = paramListNode.child(i);
420
+ if (!param || param.type !== 'parameter_declaration') continue;
421
+ const nameNode = param.childForFieldName('declarator');
422
+ if (nameNode) {
423
+ const name =
424
+ nameNode.type === 'identifier'
425
+ ? nameNode.text
426
+ : (findChild(nameNode, 'identifier')?.text ?? nameNode.text);
427
+ params.push({ name, kind: 'parameter', line: param.startPosition.row + 1 });
428
+ }
429
+ }
430
+ return params;
431
+ }
@@ -50,6 +50,19 @@ function walkOCamlNode(node: TreeSitterNode, ctx: ExtractorOutput): void {
50
50
  case 'application_expression':
51
51
  handleOCamlApplication(node, ctx);
52
52
  break;
53
+ // Shared node types present in both .ml and .mli files
54
+ case 'value_specification':
55
+ handleOCamlValueSpec(node, ctx);
56
+ break;
57
+ case 'external':
58
+ handleOCamlExternal(node, ctx);
59
+ break;
60
+ case 'module_type_definition':
61
+ handleOCamlModuleTypeDef(node, ctx);
62
+ break;
63
+ case 'exception_definition':
64
+ handleOCamlExceptionDef(node, ctx);
65
+ break;
53
66
  }
54
67
 
55
68
  for (let i = 0; i < node.childCount; i++) {
@@ -232,6 +245,71 @@ function handleOCamlOpen(node: TreeSitterNode, ctx: ExtractorOutput): void {
232
245
  });
233
246
  }
234
247
 
248
+ function hasDescendantType(node: TreeSitterNode, type: string): boolean {
249
+ if (node.type === type) return true;
250
+ for (let i = 0; i < node.childCount; i++) {
251
+ const child = node.child(i);
252
+ if (child && hasDescendantType(child, type)) return true;
253
+ }
254
+ return false;
255
+ }
256
+
257
+ function handleOCamlValueSpec(node: TreeSitterNode, ctx: ExtractorOutput): void {
258
+ const nameNode = findChild(node, 'value_name') || findChild(node, 'parenthesized_operator');
259
+ if (!nameNode) return;
260
+
261
+ // Check if the type contains `->` (function_type node)
262
+ const typeNode = node.childForFieldName('type');
263
+ const isFunction = typeNode ? hasDescendantType(typeNode, 'function_type') : false;
264
+
265
+ ctx.definitions.push({
266
+ name: nameNode.text,
267
+ kind: isFunction ? 'function' : 'variable',
268
+ line: node.startPosition.row + 1,
269
+ endLine: nodeEndLine(node),
270
+ });
271
+ }
272
+
273
+ function handleOCamlExternal(node: TreeSitterNode, ctx: ExtractorOutput): void {
274
+ const nameNode = findChild(node, 'value_name') || findChild(node, 'parenthesized_operator');
275
+ if (!nameNode) return;
276
+
277
+ ctx.definitions.push({
278
+ name: nameNode.text,
279
+ kind: 'function',
280
+ line: node.startPosition.row + 1,
281
+ endLine: nodeEndLine(node),
282
+ });
283
+ }
284
+
285
+ function handleOCamlModuleTypeDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
286
+ const nameNode = findChild(node, 'module_type_name');
287
+ if (!nameNode) return;
288
+
289
+ ctx.definitions.push({
290
+ name: nameNode.text,
291
+ kind: 'interface',
292
+ line: node.startPosition.row + 1,
293
+ endLine: nodeEndLine(node),
294
+ });
295
+ }
296
+
297
+ function handleOCamlExceptionDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
298
+ // Standard: `exception Foo of bar` — name is inside constructor_declaration
299
+ const ctorDecl = findChild(node, 'constructor_declaration');
300
+ const nameNode = ctorDecl
301
+ ? findChild(ctorDecl, 'constructor_name')
302
+ : findChild(node, 'constructor_name'); // fallback for `exception Foo = Bar` (alias)
303
+ if (!nameNode) return;
304
+
305
+ ctx.definitions.push({
306
+ name: nameNode.text,
307
+ kind: 'type',
308
+ line: node.startPosition.row + 1,
309
+ endLine: nodeEndLine(node),
310
+ });
311
+ }
312
+
235
313
  function handleOCamlApplication(node: TreeSitterNode, ctx: ExtractorOutput): void {
236
314
  // application_expression: first child is the function, rest are arguments
237
315
  const funcNode = node.child(0);
@@ -245,35 +245,41 @@ function extractPythonParameters(fnNode: TreeSitterNode): SubDeclaration[] {
245
245
  for (let i = 0; i < paramsNode.childCount; i++) {
246
246
  const child = paramsNode.child(i);
247
247
  if (!child) continue;
248
- const t = child.type;
249
- if (t === 'identifier') {
250
- params.push({ name: child.text, kind: 'parameter', line: child.startPosition.row + 1 });
251
- } else if (
252
- t === 'typed_parameter' ||
253
- t === 'default_parameter' ||
254
- t === 'typed_default_parameter'
255
- ) {
256
- const nameNode = child.childForFieldName('name') || child.child(0);
257
- if (nameNode && nameNode.type === 'identifier') {
258
- params.push({
259
- name: nameNode.text,
260
- kind: 'parameter',
261
- line: child.startPosition.row + 1,
262
- });
263
- }
264
- } else if (t === 'list_splat_pattern' || t === 'dictionary_splat_pattern') {
265
- for (let j = 0; j < child.childCount; j++) {
266
- const inner = child.child(j);
267
- if (inner && inner.type === 'identifier') {
268
- params.push({ name: inner.text, kind: 'parameter', line: child.startPosition.row + 1 });
269
- break;
270
- }
271
- }
272
- }
248
+ const param = extractSinglePyParam(child);
249
+ if (param) params.push(param);
273
250
  }
274
251
  return params;
275
252
  }
276
253
 
254
+ /** Extract a single parameter declaration from a parameter node. */
255
+ function extractSinglePyParam(child: TreeSitterNode): SubDeclaration | null {
256
+ const t = child.type;
257
+ if (t === 'identifier') {
258
+ return { name: child.text, kind: 'parameter', line: child.startPosition.row + 1 };
259
+ }
260
+ if (t === 'typed_parameter' || t === 'default_parameter' || t === 'typed_default_parameter') {
261
+ const nameNode = child.childForFieldName('name') || child.child(0);
262
+ if (nameNode && nameNode.type === 'identifier') {
263
+ return { name: nameNode.text, kind: 'parameter', line: child.startPosition.row + 1 };
264
+ }
265
+ }
266
+ if (t === 'list_splat_pattern' || t === 'dictionary_splat_pattern') {
267
+ return extractSplatParam(child);
268
+ }
269
+ return null;
270
+ }
271
+
272
+ /** Extract the identifier name from a *args or **kwargs splat pattern. */
273
+ function extractSplatParam(node: TreeSitterNode): SubDeclaration | null {
274
+ for (let j = 0; j < node.childCount; j++) {
275
+ const inner = node.child(j);
276
+ if (inner && inner.type === 'identifier') {
277
+ return { name: inner.text, kind: 'parameter', line: node.startPosition.row + 1 };
278
+ }
279
+ }
280
+ return null;
281
+ }
282
+
277
283
  /** Extract class-level assignment properties from expression statements. */
278
284
  function extractClassAssignment(
279
285
  child: TreeSitterNode,