@optave/codegraph 3.4.0 → 3.4.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 (410) hide show
  1. package/README.md +7 -7
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +3 -9
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/shared.d.ts.map +1 -1
  6. package/dist/ast-analysis/shared.js +0 -1
  7. package/dist/ast-analysis/shared.js.map +1 -1
  8. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
  9. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
  10. package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
  11. package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
  12. package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
  13. package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
  14. package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
  15. package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
  16. package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
  17. package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
  18. package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
  19. package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
  20. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
  21. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
  22. package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
  23. package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
  24. package/dist/ast-analysis/visitors/cfg-visitor.d.ts +2 -2
  25. package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
  26. package/dist/ast-analysis/visitors/cfg-visitor.js +11 -445
  27. package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
  28. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  29. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  30. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  31. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  32. package/dist/cli/commands/batch.d.ts.map +1 -1
  33. package/dist/cli/commands/batch.js +4 -3
  34. package/dist/cli/commands/batch.js.map +1 -1
  35. package/dist/cli/commands/branch-compare.js +1 -1
  36. package/dist/cli/commands/branch-compare.js.map +1 -1
  37. package/dist/cli/commands/build.js +1 -1
  38. package/dist/cli/commands/build.js.map +1 -1
  39. package/dist/cli/commands/info.d.ts.map +1 -1
  40. package/dist/cli/commands/info.js +1 -2
  41. package/dist/cli/commands/info.js.map +1 -1
  42. package/dist/cli/commands/path.d.ts.map +1 -1
  43. package/dist/cli/commands/path.js +7 -2
  44. package/dist/cli/commands/path.js.map +1 -1
  45. package/dist/cli/commands/plot.d.ts.map +1 -1
  46. package/dist/cli/commands/plot.js +2 -2
  47. package/dist/cli/commands/plot.js.map +1 -1
  48. package/dist/cli/commands/watch.js +1 -1
  49. package/dist/cli/commands/watch.js.map +1 -1
  50. package/dist/cli/index.js +2 -2
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/cli/shared/open-graph.d.ts +2 -2
  53. package/dist/cli/shared/open-graph.d.ts.map +1 -1
  54. package/dist/cli/shared/open-graph.js.map +1 -1
  55. package/dist/cli/types.d.ts +1 -1
  56. package/dist/cli/types.d.ts.map +1 -1
  57. package/dist/cli.js +2 -3
  58. package/dist/cli.js.map +1 -1
  59. package/dist/db/connection.d.ts +17 -0
  60. package/dist/db/connection.d.ts.map +1 -1
  61. package/dist/db/connection.js +91 -2
  62. package/dist/db/connection.js.map +1 -1
  63. package/dist/db/index.d.ts +1 -1
  64. package/dist/db/index.d.ts.map +1 -1
  65. package/dist/db/index.js +1 -1
  66. package/dist/db/index.js.map +1 -1
  67. package/dist/db/migrations.d.ts.map +1 -1
  68. package/dist/db/migrations.js +7 -0
  69. package/dist/db/migrations.js.map +1 -1
  70. package/dist/domain/analysis/brief.d.ts.map +1 -1
  71. package/dist/domain/analysis/brief.js +1 -3
  72. package/dist/domain/analysis/brief.js.map +1 -1
  73. package/dist/domain/analysis/context.d.ts.map +1 -1
  74. package/dist/domain/analysis/context.js +2 -4
  75. package/dist/domain/analysis/context.js.map +1 -1
  76. package/dist/domain/analysis/dependencies.d.ts +49 -0
  77. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  78. package/dist/domain/analysis/dependencies.js +145 -0
  79. package/dist/domain/analysis/dependencies.js.map +1 -1
  80. package/dist/domain/analysis/diff-impact.d.ts +76 -0
  81. package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
  82. package/dist/domain/analysis/diff-impact.js +282 -0
  83. package/dist/domain/analysis/diff-impact.js.map +1 -0
  84. package/dist/domain/analysis/exports.d.ts.map +1 -1
  85. package/dist/domain/analysis/exports.js +0 -1
  86. package/dist/domain/analysis/exports.js.map +1 -1
  87. package/dist/domain/analysis/fn-impact.d.ts +66 -0
  88. package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
  89. package/dist/domain/analysis/fn-impact.js +189 -0
  90. package/dist/domain/analysis/fn-impact.js.map +1 -0
  91. package/dist/domain/analysis/impact.d.ts +8 -148
  92. package/dist/domain/analysis/impact.d.ts.map +1 -1
  93. package/dist/domain/analysis/impact.js +8 -568
  94. package/dist/domain/analysis/impact.js.map +1 -1
  95. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  96. package/dist/domain/analysis/module-map.js +1 -3
  97. package/dist/domain/analysis/module-map.js.map +1 -1
  98. package/dist/domain/graph/builder/context.d.ts +2 -3
  99. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  100. package/dist/domain/graph/builder/context.js.map +1 -1
  101. package/dist/domain/graph/builder/helpers.d.ts +4 -5
  102. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  103. package/dist/domain/graph/builder/helpers.js +1 -2
  104. package/dist/domain/graph/builder/helpers.js.map +1 -1
  105. package/dist/domain/graph/builder/incremental.d.ts +2 -3
  106. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  107. package/dist/domain/graph/builder/incremental.js.map +1 -1
  108. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  109. package/dist/domain/graph/builder/pipeline.js +6 -0
  110. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  111. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  112. package/dist/domain/graph/builder/stages/build-edges.js +12 -2
  113. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  114. package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
  115. package/dist/domain/graph/builder/stages/build-structure.js +155 -59
  116. package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
  117. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  118. package/dist/domain/graph/builder/stages/detect-changes.js +6 -6
  119. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  120. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  121. package/dist/domain/graph/builder/stages/finalize.js +85 -61
  122. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  123. package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
  124. package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
  125. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  126. package/dist/domain/graph/builder/stages/resolve-imports.js +58 -11
  127. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  128. package/dist/domain/graph/cycles.js +2 -2
  129. package/dist/domain/graph/cycles.js.map +1 -1
  130. package/dist/domain/graph/resolve.d.ts.map +1 -1
  131. package/dist/domain/graph/resolve.js +10 -8
  132. package/dist/domain/graph/resolve.js.map +1 -1
  133. package/dist/domain/graph/watcher.d.ts.map +1 -1
  134. package/dist/domain/graph/watcher.js +1 -3
  135. package/dist/domain/graph/watcher.js.map +1 -1
  136. package/dist/domain/parser.d.ts.map +1 -1
  137. package/dist/domain/parser.js +11 -12
  138. package/dist/domain/parser.js.map +1 -1
  139. package/dist/domain/queries.d.ts +3 -2
  140. package/dist/domain/queries.d.ts.map +1 -1
  141. package/dist/domain/queries.js +3 -2
  142. package/dist/domain/queries.js.map +1 -1
  143. package/dist/domain/search/generator.d.ts.map +1 -1
  144. package/dist/domain/search/generator.js.map +1 -1
  145. package/dist/extractors/csharp.js +2 -2
  146. package/dist/extractors/csharp.js.map +1 -1
  147. package/dist/extractors/go.js +2 -2
  148. package/dist/extractors/go.js.map +1 -1
  149. package/dist/extractors/helpers.d.ts +5 -0
  150. package/dist/extractors/helpers.d.ts.map +1 -1
  151. package/dist/extractors/helpers.js +5 -0
  152. package/dist/extractors/helpers.js.map +1 -1
  153. package/dist/extractors/javascript.js +58 -60
  154. package/dist/extractors/javascript.js.map +1 -1
  155. package/dist/extractors/php.js +2 -2
  156. package/dist/extractors/php.js.map +1 -1
  157. package/dist/extractors/python.js +2 -2
  158. package/dist/extractors/python.js.map +1 -1
  159. package/dist/extractors/rust.js +2 -2
  160. package/dist/extractors/rust.js.map +1 -1
  161. package/dist/features/audit.d.ts.map +1 -1
  162. package/dist/features/audit.js +1 -2
  163. package/dist/features/audit.js.map +1 -1
  164. package/dist/features/branch-compare.d.ts.map +1 -1
  165. package/dist/features/branch-compare.js +2 -3
  166. package/dist/features/branch-compare.js.map +1 -1
  167. package/dist/features/cfg.d.ts.map +1 -1
  168. package/dist/features/cfg.js +2 -4
  169. package/dist/features/cfg.js.map +1 -1
  170. package/dist/features/cochange.js +4 -4
  171. package/dist/features/cochange.js.map +1 -1
  172. package/dist/features/communities.js +4 -4
  173. package/dist/features/communities.js.map +1 -1
  174. package/dist/features/complexity-query.d.ts +37 -0
  175. package/dist/features/complexity-query.d.ts.map +1 -0
  176. package/dist/features/complexity-query.js +263 -0
  177. package/dist/features/complexity-query.js.map +1 -0
  178. package/dist/features/complexity.d.ts +2 -30
  179. package/dist/features/complexity.d.ts.map +1 -1
  180. package/dist/features/complexity.js +7 -261
  181. package/dist/features/complexity.js.map +1 -1
  182. package/dist/features/dataflow.d.ts.map +1 -1
  183. package/dist/features/dataflow.js +8 -24
  184. package/dist/features/dataflow.js.map +1 -1
  185. package/dist/features/export.d.ts +7 -8
  186. package/dist/features/export.d.ts.map +1 -1
  187. package/dist/features/export.js.map +1 -1
  188. package/dist/features/flow.d.ts.map +1 -1
  189. package/dist/features/flow.js.map +1 -1
  190. package/dist/features/graph-enrichment.d.ts.map +1 -1
  191. package/dist/features/graph-enrichment.js +1 -3
  192. package/dist/features/graph-enrichment.js.map +1 -1
  193. package/dist/features/manifesto.js +8 -8
  194. package/dist/features/manifesto.js.map +1 -1
  195. package/dist/features/snapshot.d.ts.map +1 -1
  196. package/dist/features/snapshot.js +0 -1
  197. package/dist/features/snapshot.js.map +1 -1
  198. package/dist/features/structure-query.d.ts +76 -0
  199. package/dist/features/structure-query.d.ts.map +1 -0
  200. package/dist/features/structure-query.js +245 -0
  201. package/dist/features/structure-query.js.map +1 -0
  202. package/dist/features/structure.d.ts +12 -67
  203. package/dist/features/structure.d.ts.map +1 -1
  204. package/dist/features/structure.js +188 -244
  205. package/dist/features/structure.js.map +1 -1
  206. package/dist/features/triage.js +2 -2
  207. package/dist/features/triage.js.map +1 -1
  208. package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
  209. package/dist/graph/algorithms/leiden/adapter.js +2 -9
  210. package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
  211. package/dist/graph/classifiers/roles.d.ts +5 -1
  212. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  213. package/dist/graph/classifiers/roles.js +20 -12
  214. package/dist/graph/classifiers/roles.js.map +1 -1
  215. package/dist/index.d.ts +1 -0
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js.map +1 -1
  218. package/dist/infrastructure/config.d.ts.map +1 -1
  219. package/dist/infrastructure/config.js +12 -11
  220. package/dist/infrastructure/config.js.map +1 -1
  221. package/dist/infrastructure/native.d.ts.map +1 -1
  222. package/dist/infrastructure/native.js +7 -3
  223. package/dist/infrastructure/native.js.map +1 -1
  224. package/dist/infrastructure/registry.d.ts.map +1 -1
  225. package/dist/infrastructure/registry.js +1 -1
  226. package/dist/infrastructure/registry.js.map +1 -1
  227. package/dist/infrastructure/update-check.js +3 -3
  228. package/dist/infrastructure/update-check.js.map +1 -1
  229. package/dist/mcp/server.d.ts.map +1 -1
  230. package/dist/mcp/server.js +2 -8
  231. package/dist/mcp/server.js.map +1 -1
  232. package/dist/mcp/tool-registry.d.ts.map +1 -1
  233. package/dist/mcp/tool-registry.js +9 -4
  234. package/dist/mcp/tool-registry.js.map +1 -1
  235. package/dist/mcp/tools/audit.js +1 -1
  236. package/dist/mcp/tools/audit.js.map +1 -1
  237. package/dist/mcp/tools/cfg.js +1 -1
  238. package/dist/mcp/tools/cfg.js.map +1 -1
  239. package/dist/mcp/tools/check.js +2 -2
  240. package/dist/mcp/tools/check.js.map +1 -1
  241. package/dist/mcp/tools/dataflow.js +2 -2
  242. package/dist/mcp/tools/dataflow.js.map +1 -1
  243. package/dist/mcp/tools/export-graph.js +1 -1
  244. package/dist/mcp/tools/export-graph.js.map +1 -1
  245. package/dist/mcp/tools/index.d.ts.map +1 -1
  246. package/dist/mcp/tools/index.js.map +1 -1
  247. package/dist/mcp/tools/path.d.ts +1 -0
  248. package/dist/mcp/tools/path.d.ts.map +1 -1
  249. package/dist/mcp/tools/path.js +9 -0
  250. package/dist/mcp/tools/path.js.map +1 -1
  251. package/dist/mcp/tools/query.js +1 -1
  252. package/dist/mcp/tools/query.js.map +1 -1
  253. package/dist/mcp/tools/semantic-search.js +1 -1
  254. package/dist/mcp/tools/semantic-search.js.map +1 -1
  255. package/dist/mcp/tools/sequence.js +1 -1
  256. package/dist/mcp/tools/sequence.js.map +1 -1
  257. package/dist/mcp/tools/symbol-children.js +1 -1
  258. package/dist/mcp/tools/symbol-children.js.map +1 -1
  259. package/dist/mcp/tools/triage.js +1 -1
  260. package/dist/mcp/tools/triage.js.map +1 -1
  261. package/dist/presentation/audit.d.ts.map +1 -1
  262. package/dist/presentation/audit.js +0 -1
  263. package/dist/presentation/audit.js.map +1 -1
  264. package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
  265. package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
  266. package/dist/presentation/diff-impact-mermaid.js +105 -0
  267. package/dist/presentation/diff-impact-mermaid.js.map +1 -0
  268. package/dist/presentation/flow.d.ts.map +1 -1
  269. package/dist/presentation/flow.js +0 -2
  270. package/dist/presentation/flow.js.map +1 -1
  271. package/dist/presentation/manifesto.d.ts.map +1 -1
  272. package/dist/presentation/manifesto.js +0 -1
  273. package/dist/presentation/manifesto.js.map +1 -1
  274. package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
  275. package/dist/presentation/queries-cli/inspect.js.map +1 -1
  276. package/dist/presentation/queries-cli/path.d.ts.map +1 -1
  277. package/dist/presentation/queries-cli/path.js +45 -1
  278. package/dist/presentation/queries-cli/path.js.map +1 -1
  279. package/dist/presentation/result-formatter.d.ts.map +1 -1
  280. package/dist/presentation/result-formatter.js +1 -3
  281. package/dist/presentation/result-formatter.js.map +1 -1
  282. package/dist/presentation/sequence.d.ts.map +1 -1
  283. package/dist/presentation/sequence.js +0 -1
  284. package/dist/presentation/sequence.js.map +1 -1
  285. package/dist/presentation/structure.d.ts.map +1 -1
  286. package/dist/presentation/structure.js.map +1 -1
  287. package/dist/presentation/triage.d.ts.map +1 -1
  288. package/dist/presentation/triage.js +0 -1
  289. package/dist/presentation/triage.js.map +1 -1
  290. package/dist/shared/constants.d.ts +9 -3
  291. package/dist/shared/constants.d.ts.map +1 -1
  292. package/dist/shared/constants.js +6 -3
  293. package/dist/shared/constants.js.map +1 -1
  294. package/dist/shared/errors.d.ts +2 -0
  295. package/dist/shared/errors.d.ts.map +1 -1
  296. package/dist/shared/errors.js +4 -0
  297. package/dist/shared/errors.js.map +1 -1
  298. package/dist/shared/version.d.ts +2 -0
  299. package/dist/shared/version.d.ts.map +1 -0
  300. package/dist/shared/version.js +5 -0
  301. package/dist/shared/version.js.map +1 -0
  302. package/dist/types.d.ts +2 -2
  303. package/dist/types.d.ts.map +1 -1
  304. package/package.json +8 -7
  305. package/src/ast-analysis/engine.ts +3 -9
  306. package/src/ast-analysis/shared.ts +0 -1
  307. package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
  308. package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
  309. package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
  310. package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
  311. package/src/ast-analysis/visitors/cfg-visitor.ts +34 -655
  312. package/src/ast-analysis/visitors/complexity-visitor.ts +0 -1
  313. package/src/ast-analysis/visitors/dataflow-visitor.ts +0 -1
  314. package/src/cli/commands/batch.ts +4 -3
  315. package/src/cli/commands/branch-compare.ts +1 -1
  316. package/src/cli/commands/build.ts +1 -1
  317. package/src/cli/commands/info.ts +1 -2
  318. package/src/cli/commands/path.ts +7 -2
  319. package/src/cli/commands/plot.ts +2 -2
  320. package/src/cli/commands/watch.ts +1 -1
  321. package/src/cli/index.ts +2 -2
  322. package/src/cli/shared/open-graph.ts +2 -2
  323. package/src/cli/types.ts +1 -1
  324. package/src/cli.ts +2 -3
  325. package/src/db/connection.ts +97 -13
  326. package/src/db/index.ts +2 -0
  327. package/src/db/migrations.ts +7 -0
  328. package/src/domain/analysis/brief.ts +0 -1
  329. package/src/domain/analysis/context.ts +2 -6
  330. package/src/domain/analysis/dependencies.ts +165 -0
  331. package/src/domain/analysis/diff-impact.ts +354 -0
  332. package/src/domain/analysis/exports.ts +0 -2
  333. package/src/domain/analysis/fn-impact.ts +241 -0
  334. package/src/domain/analysis/impact.ts +8 -718
  335. package/src/domain/analysis/module-map.ts +1 -5
  336. package/src/domain/graph/builder/context.ts +2 -2
  337. package/src/domain/graph/builder/helpers.ts +14 -11
  338. package/src/domain/graph/builder/incremental.ts +33 -28
  339. package/src/domain/graph/builder/pipeline.ts +8 -0
  340. package/src/domain/graph/builder/stages/build-edges.ts +17 -4
  341. package/src/domain/graph/builder/stages/build-structure.ts +205 -76
  342. package/src/domain/graph/builder/stages/detect-changes.ts +11 -12
  343. package/src/domain/graph/builder/stages/finalize.ts +100 -81
  344. package/src/domain/graph/builder/stages/insert-nodes.ts +12 -8
  345. package/src/domain/graph/builder/stages/resolve-imports.ts +75 -10
  346. package/src/domain/graph/cycles.ts +2 -2
  347. package/src/domain/graph/resolve.ts +14 -8
  348. package/src/domain/graph/watcher.ts +2 -4
  349. package/src/domain/parser.ts +11 -13
  350. package/src/domain/queries.ts +2 -2
  351. package/src/domain/search/generator.ts +3 -4
  352. package/src/extractors/csharp.ts +2 -2
  353. package/src/extractors/go.ts +2 -2
  354. package/src/extractors/helpers.ts +6 -0
  355. package/src/extractors/javascript.ts +58 -61
  356. package/src/extractors/php.ts +2 -2
  357. package/src/extractors/python.ts +2 -2
  358. package/src/extractors/rust.ts +2 -2
  359. package/src/features/audit.ts +1 -2
  360. package/src/features/branch-compare.ts +3 -9
  361. package/src/features/cfg.ts +2 -4
  362. package/src/features/cochange.ts +4 -4
  363. package/src/features/communities.ts +4 -4
  364. package/src/features/complexity-query.ts +370 -0
  365. package/src/features/complexity.ts +6 -365
  366. package/src/features/dataflow.ts +48 -70
  367. package/src/features/export.ts +12 -16
  368. package/src/features/flow.ts +0 -1
  369. package/src/features/graph-enrichment.ts +1 -3
  370. package/src/features/manifesto.ts +8 -8
  371. package/src/features/snapshot.ts +1 -2
  372. package/src/features/structure-query.ts +387 -0
  373. package/src/features/structure.ts +231 -376
  374. package/src/features/triage.ts +2 -2
  375. package/src/graph/algorithms/leiden/adapter.ts +2 -9
  376. package/src/graph/classifiers/roles.ts +22 -13
  377. package/src/index.ts +1 -0
  378. package/src/infrastructure/config.ts +12 -13
  379. package/src/infrastructure/native.ts +7 -3
  380. package/src/infrastructure/registry.ts +1 -1
  381. package/src/infrastructure/update-check.ts +3 -3
  382. package/src/mcp/server.ts +2 -10
  383. package/src/mcp/tool-registry.ts +11 -4
  384. package/src/mcp/tools/audit.ts +1 -1
  385. package/src/mcp/tools/cfg.ts +1 -1
  386. package/src/mcp/tools/check.ts +2 -2
  387. package/src/mcp/tools/dataflow.ts +2 -2
  388. package/src/mcp/tools/export-graph.ts +1 -1
  389. package/src/mcp/tools/index.ts +0 -1
  390. package/src/mcp/tools/path.ts +10 -0
  391. package/src/mcp/tools/query.ts +1 -1
  392. package/src/mcp/tools/semantic-search.ts +1 -1
  393. package/src/mcp/tools/sequence.ts +1 -1
  394. package/src/mcp/tools/symbol-children.ts +1 -1
  395. package/src/mcp/tools/triage.ts +1 -1
  396. package/src/presentation/audit.ts +0 -1
  397. package/src/presentation/diff-impact-mermaid.ts +127 -0
  398. package/src/presentation/flow.ts +0 -2
  399. package/src/presentation/manifesto.ts +0 -1
  400. package/src/presentation/queries-cli/inspect.ts +0 -1
  401. package/src/presentation/queries-cli/path.ts +71 -1
  402. package/src/presentation/result-formatter.ts +0 -1
  403. package/src/presentation/sequence.ts +0 -1
  404. package/src/presentation/structure.ts +0 -12
  405. package/src/presentation/triage.ts +0 -1
  406. package/src/shared/constants.ts +33 -19
  407. package/src/shared/errors.ts +5 -0
  408. package/src/shared/version.ts +10 -0
  409. package/src/types.ts +4 -10
  410. package/src/vendor.d.ts +0 -39
@@ -220,9 +220,9 @@ function evaluateFunctionRules(
220
220
  const value = row[def.metric] as number | null;
221
221
  if (value == null) continue;
222
222
  const meta = {
223
- name: row['name'] as string,
224
- file: row['file'] as string,
225
- line: row['line'] as number,
223
+ name: row.name as string,
224
+ file: row.file as string,
225
+ line: row.line as number,
226
226
  };
227
227
  const status = checkThreshold(def.name, rules[def.name]!, value, meta, violations);
228
228
  if (status !== 'pass') {
@@ -304,9 +304,9 @@ function evaluateFileRules(
304
304
  const value = row[def.metric] as number | null;
305
305
  if (value == null) continue;
306
306
  const meta = {
307
- name: row['name'] as string,
308
- file: row['file'] as string,
309
- line: row['line'] as number,
307
+ name: row.name as string,
308
+ file: row.file as string,
309
+ line: row.line as number,
310
310
  };
311
311
  const status = checkThreshold(def.name, rules[def.name]!, value, meta, violations);
312
312
  if (status !== 'pass') {
@@ -335,7 +335,7 @@ function evaluateGraphRules(
335
335
  violations: Violation[],
336
336
  ruleResults: RuleResult[],
337
337
  ): void {
338
- const thresholds = rules['noCycles']!;
338
+ const thresholds = rules.noCycles!;
339
339
  if (!isEnabled(thresholds)) {
340
340
  ruleResults.push({
341
341
  name: 'noCycles',
@@ -393,7 +393,7 @@ function evaluateBoundaryRules(
393
393
  violations: Violation[],
394
394
  ruleResults: RuleResult[],
395
395
  ): void {
396
- const thresholds = rules['boundaries']!;
396
+ const thresholds = rules.boundaries!;
397
397
  const boundaryConfig = config.manifesto?.boundaries;
398
398
 
399
399
  // Auto-enable at warn level when boundary config exists but threshold not set
@@ -47,8 +47,7 @@ export function snapshotSave(
47
47
 
48
48
  fs.mkdirSync(dir, { recursive: true });
49
49
 
50
- // biome-ignore lint/suspicious/noExplicitAny: better-sqlite3 default export typing
51
- const db = new (Database as any)(dbPath, { readonly: true });
50
+ const db = new Database(dbPath, { readonly: true });
52
51
  try {
53
52
  db.exec(`VACUUM INTO '${dest.replace(/'/g, "''")}'`);
54
53
  } finally {
@@ -0,0 +1,387 @@
1
+ /**
2
+ * Structure query functions — read-only DB queries for directory structure,
3
+ * hotspots, and module boundaries.
4
+ *
5
+ * Split from structure.ts to separate query-time concerns (DB reads, sorting,
6
+ * pagination) from build-time concerns (directory insertion, metrics computation,
7
+ * role classification).
8
+ */
9
+
10
+ import { openReadonlyOrFail, testFilterSQL } from '../db/index.js';
11
+ import { loadConfig } from '../infrastructure/config.js';
12
+ import { isTestFile } from '../infrastructure/test-filter.js';
13
+ import { normalizePath } from '../shared/constants.js';
14
+ import { paginateResult } from '../shared/paginate.js';
15
+ import type { CodegraphConfig } from '../types.js';
16
+
17
+ // ─── Query functions (read-only) ──────────────────────────────────────
18
+
19
+ interface DirRow {
20
+ id: number;
21
+ name: string;
22
+ file: string;
23
+ symbol_count: number | null;
24
+ fan_in: number | null;
25
+ fan_out: number | null;
26
+ cohesion: number | null;
27
+ file_count: number | null;
28
+ }
29
+
30
+ interface FileMetricRow {
31
+ name: string;
32
+ line_count: number | null;
33
+ symbol_count: number | null;
34
+ import_count: number | null;
35
+ export_count: number | null;
36
+ fan_in: number | null;
37
+ fan_out: number | null;
38
+ }
39
+
40
+ interface StructureDataOpts {
41
+ directory?: string;
42
+ depth?: number;
43
+ sort?: string;
44
+ noTests?: boolean;
45
+ full?: boolean;
46
+ fileLimit?: number;
47
+ limit?: number;
48
+ offset?: number;
49
+ }
50
+
51
+ interface DirectoryEntry {
52
+ directory: string;
53
+ fileCount: number;
54
+ symbolCount: number;
55
+ fanIn: number;
56
+ fanOut: number;
57
+ cohesion: number | null;
58
+ density: number;
59
+ files: {
60
+ file: string;
61
+ lineCount: number;
62
+ symbolCount: number;
63
+ importCount: number;
64
+ exportCount: number;
65
+ fanIn: number;
66
+ fanOut: number;
67
+ }[];
68
+ subdirectories: string[];
69
+ }
70
+
71
+ export function structureData(
72
+ customDbPath?: string,
73
+ opts: StructureDataOpts = {},
74
+ ): {
75
+ directories: DirectoryEntry[];
76
+ count: number;
77
+ suppressed?: number;
78
+ warning?: string;
79
+ } {
80
+ const db = openReadonlyOrFail(customDbPath);
81
+ try {
82
+ const rawDir = opts.directory || null;
83
+ const filterDir = rawDir && normalizePath(rawDir) !== '.' ? rawDir : null;
84
+ const maxDepth = opts.depth || null;
85
+ const sortBy = opts.sort || 'files';
86
+ const noTests = opts.noTests || false;
87
+ const full = opts.full || false;
88
+ const fileLimit = opts.fileLimit || 25;
89
+
90
+ // Get all directory nodes with their metrics
91
+ let dirs = db
92
+ .prepare(`
93
+ SELECT n.id, n.name, n.file, nm.symbol_count, nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
94
+ FROM nodes n
95
+ LEFT JOIN node_metrics nm ON n.id = nm.node_id
96
+ WHERE n.kind = 'directory'
97
+ `)
98
+ .all() as DirRow[];
99
+
100
+ if (filterDir) {
101
+ const norm = normalizePath(filterDir);
102
+ dirs = dirs.filter((d) => d.name === norm || d.name.startsWith(`${norm}/`));
103
+ }
104
+
105
+ if (maxDepth) {
106
+ const baseDepth = filterDir ? normalizePath(filterDir).split('/').length : 0;
107
+ dirs = dirs.filter((d) => {
108
+ const depth = d.name.split('/').length - baseDepth;
109
+ return depth <= maxDepth;
110
+ });
111
+ }
112
+
113
+ // Sort
114
+ const sortFn = getSortFn(sortBy);
115
+ dirs.sort(sortFn);
116
+
117
+ // Get file metrics for each directory
118
+ const result: DirectoryEntry[] = dirs.map((d) => {
119
+ let files = db
120
+ .prepare(`
121
+ SELECT n.name, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count, nm.fan_in, nm.fan_out
122
+ FROM edges e
123
+ JOIN nodes n ON e.target_id = n.id
124
+ LEFT JOIN node_metrics nm ON n.id = nm.node_id
125
+ WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'file'
126
+ `)
127
+ .all(d.id) as FileMetricRow[];
128
+ if (noTests) files = files.filter((f) => !isTestFile(f.name));
129
+
130
+ const subdirs = db
131
+ .prepare(`
132
+ SELECT n.name
133
+ FROM edges e
134
+ JOIN nodes n ON e.target_id = n.id
135
+ WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'directory'
136
+ `)
137
+ .all(d.id) as { name: string }[];
138
+
139
+ const fileCount = noTests ? files.length : d.file_count || 0;
140
+ return {
141
+ directory: d.name,
142
+ fileCount,
143
+ symbolCount: d.symbol_count || 0,
144
+ fanIn: d.fan_in || 0,
145
+ fanOut: d.fan_out || 0,
146
+ cohesion: d.cohesion,
147
+ density: fileCount > 0 ? (d.symbol_count || 0) / fileCount : 0,
148
+ files: files.map((f) => ({
149
+ file: f.name,
150
+ lineCount: f.line_count || 0,
151
+ symbolCount: f.symbol_count || 0,
152
+ importCount: f.import_count || 0,
153
+ exportCount: f.export_count || 0,
154
+ fanIn: f.fan_in || 0,
155
+ fanOut: f.fan_out || 0,
156
+ })),
157
+ subdirectories: subdirs.map((s) => s.name),
158
+ };
159
+ });
160
+
161
+ // Apply global file limit unless full mode
162
+ if (!full) {
163
+ const totalFiles = result.reduce((sum, d) => sum + d.files.length, 0);
164
+ if (totalFiles > fileLimit) {
165
+ let shown = 0;
166
+ for (const d of result) {
167
+ const remaining = fileLimit - shown;
168
+ if (remaining <= 0) {
169
+ d.files = [];
170
+ } else if (d.files.length > remaining) {
171
+ d.files = d.files.slice(0, remaining);
172
+ shown = fileLimit;
173
+ } else {
174
+ shown += d.files.length;
175
+ }
176
+ }
177
+ const suppressed = totalFiles - fileLimit;
178
+ return {
179
+ directories: result,
180
+ count: result.length,
181
+ suppressed,
182
+ warning: `${suppressed} files omitted (showing ${fileLimit}/${totalFiles}). Use --full to show all files, or narrow with --directory.`,
183
+ };
184
+ }
185
+ }
186
+
187
+ const base = { directories: result, count: result.length };
188
+ return paginateResult(base, 'directories', { limit: opts.limit, offset: opts.offset });
189
+ } finally {
190
+ db.close();
191
+ }
192
+ }
193
+
194
+ interface HotspotRow {
195
+ name: string;
196
+ kind: string;
197
+ line_count: number | null;
198
+ symbol_count: number | null;
199
+ import_count: number | null;
200
+ export_count: number | null;
201
+ fan_in: number | null;
202
+ fan_out: number | null;
203
+ cohesion: number | null;
204
+ file_count: number | null;
205
+ }
206
+
207
+ interface HotspotsDataOpts {
208
+ metric?: string;
209
+ level?: string;
210
+ limit?: number;
211
+ offset?: number;
212
+ noTests?: boolean;
213
+ }
214
+
215
+ export function hotspotsData(
216
+ customDbPath?: string,
217
+ opts: HotspotsDataOpts = {},
218
+ ): {
219
+ metric: string;
220
+ level: string;
221
+ limit: number;
222
+ hotspots: unknown[];
223
+ } {
224
+ const db = openReadonlyOrFail(customDbPath);
225
+ try {
226
+ const metric = opts.metric || 'fan-in';
227
+ const level = opts.level || 'file';
228
+ const limit = opts.limit || 10;
229
+ const noTests = opts.noTests || false;
230
+
231
+ const kind = level === 'directory' ? 'directory' : 'file';
232
+
233
+ const testFilter = testFilterSQL('n.name', noTests && kind === 'file');
234
+
235
+ const HOTSPOT_QUERIES: Record<string, { all(...params: unknown[]): HotspotRow[] }> = {
236
+ 'fan-in': db.prepare(`
237
+ SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
238
+ nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
239
+ FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
240
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.fan_in DESC NULLS LAST LIMIT ?`),
241
+ 'fan-out': db.prepare(`
242
+ SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
243
+ nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
244
+ FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
245
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.fan_out DESC NULLS LAST LIMIT ?`),
246
+ density: db.prepare(`
247
+ SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
248
+ nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
249
+ FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
250
+ WHERE n.kind = ? ${testFilter} ORDER BY nm.symbol_count DESC NULLS LAST LIMIT ?`),
251
+ coupling: db.prepare(`
252
+ SELECT n.name, n.kind, nm.line_count, nm.symbol_count, nm.import_count, nm.export_count,
253
+ nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
254
+ FROM nodes n JOIN node_metrics nm ON n.id = nm.node_id
255
+ WHERE n.kind = ? ${testFilter} ORDER BY (COALESCE(nm.fan_in, 0) + COALESCE(nm.fan_out, 0)) DESC NULLS LAST LIMIT ?`),
256
+ };
257
+
258
+ const stmt = HOTSPOT_QUERIES[metric] ?? HOTSPOT_QUERIES['fan-in'];
259
+ // stmt is always defined: metric is a valid key or the fallback is a concrete property
260
+ const rows = stmt!.all(kind, limit);
261
+
262
+ const hotspots = rows.map((r) => ({
263
+ name: r.name,
264
+ kind: r.kind,
265
+ lineCount: r.line_count,
266
+ symbolCount: r.symbol_count,
267
+ importCount: r.import_count,
268
+ exportCount: r.export_count,
269
+ fanIn: r.fan_in,
270
+ fanOut: r.fan_out,
271
+ cohesion: r.cohesion,
272
+ fileCount: r.file_count,
273
+ density:
274
+ (r.file_count ?? 0) > 0
275
+ ? (r.symbol_count || 0) / (r.file_count ?? 1)
276
+ : (r.line_count ?? 0) > 0
277
+ ? (r.symbol_count || 0) / (r.line_count ?? 1)
278
+ : 0,
279
+ coupling: (r.fan_in || 0) + (r.fan_out || 0),
280
+ }));
281
+
282
+ const base = { metric, level, limit, hotspots };
283
+ return paginateResult(base, 'hotspots', { limit: opts.limit, offset: opts.offset });
284
+ } finally {
285
+ db.close();
286
+ }
287
+ }
288
+
289
+ interface ModuleBoundariesOpts {
290
+ threshold?: number;
291
+ config?: CodegraphConfig;
292
+ }
293
+
294
+ export function moduleBoundariesData(
295
+ customDbPath?: string,
296
+ opts: ModuleBoundariesOpts = {},
297
+ ): {
298
+ threshold: number;
299
+ modules: {
300
+ directory: string;
301
+ cohesion: number | null;
302
+ fileCount: number;
303
+ symbolCount: number;
304
+ fanIn: number;
305
+ fanOut: number;
306
+ files: string[];
307
+ }[];
308
+ count: number;
309
+ } {
310
+ const db = openReadonlyOrFail(customDbPath);
311
+ try {
312
+ const config = opts.config || loadConfig();
313
+ const threshold =
314
+ opts.threshold ??
315
+ (config as unknown as { structure?: { cohesionThreshold?: number } }).structure
316
+ ?.cohesionThreshold ??
317
+ 0.3;
318
+
319
+ const dirs = db
320
+ .prepare(`
321
+ SELECT n.id, n.name, nm.symbol_count, nm.fan_in, nm.fan_out, nm.cohesion, nm.file_count
322
+ FROM nodes n
323
+ JOIN node_metrics nm ON n.id = nm.node_id
324
+ WHERE n.kind = 'directory' AND nm.cohesion IS NOT NULL AND nm.cohesion >= ?
325
+ ORDER BY nm.cohesion DESC
326
+ `)
327
+ .all(threshold) as {
328
+ id: number;
329
+ name: string;
330
+ symbol_count: number | null;
331
+ fan_in: number | null;
332
+ fan_out: number | null;
333
+ cohesion: number | null;
334
+ file_count: number | null;
335
+ }[];
336
+
337
+ const modules = dirs.map((d) => {
338
+ // Get files inside this directory
339
+ const files = (
340
+ db
341
+ .prepare(`
342
+ SELECT n.name FROM edges e
343
+ JOIN nodes n ON e.target_id = n.id
344
+ WHERE e.source_id = ? AND e.kind = 'contains' AND n.kind = 'file'
345
+ `)
346
+ .all(d.id) as { name: string }[]
347
+ ).map((f) => f.name);
348
+
349
+ return {
350
+ directory: d.name,
351
+ cohesion: d.cohesion,
352
+ fileCount: d.file_count || 0,
353
+ symbolCount: d.symbol_count || 0,
354
+ fanIn: d.fan_in || 0,
355
+ fanOut: d.fan_out || 0,
356
+ files,
357
+ };
358
+ });
359
+
360
+ return { threshold, modules, count: modules.length };
361
+ } finally {
362
+ db.close();
363
+ }
364
+ }
365
+
366
+ // ─── Helpers ──────────────────────────────────────────────────────────
367
+
368
+ function getSortFn(sortBy: string): (a: DirRow, b: DirRow) => number {
369
+ switch (sortBy) {
370
+ case 'cohesion':
371
+ return (a, b) => (b.cohesion ?? -1) - (a.cohesion ?? -1);
372
+ case 'fan-in':
373
+ return (a, b) => (b.fan_in || 0) - (a.fan_in || 0);
374
+ case 'fan-out':
375
+ return (a, b) => (b.fan_out || 0) - (a.fan_out || 0);
376
+ case 'density':
377
+ return (a, b) => {
378
+ const da = (a.file_count ?? 0) > 0 ? (a.symbol_count || 0) / (a.file_count ?? 1) : 0;
379
+ const db_ = (b.file_count ?? 0) > 0 ? (b.symbol_count || 0) / (b.file_count ?? 1) : 0;
380
+ return db_ - da;
381
+ };
382
+ case 'files':
383
+ return (a, b) => (b.file_count || 0) - (a.file_count || 0);
384
+ default:
385
+ return (a, b) => a.name.localeCompare(b.name);
386
+ }
387
+ }