@monoes/monograph 1.2.0 → 1.2.2

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 (469) hide show
  1. package/.monomind/loops/mastermind-review-1782162423447.json +16 -0
  2. package/__tests__/mcp-tools/cypher.test.ts +10 -6
  3. package/__tests__/mcp-tools/detect-changes.test.ts +14 -11
  4. package/__tests__/pipeline/phases/wildcard-synthesis.test.ts +4 -4
  5. package/__tests__/search/embed-batch-config.test.ts +7 -7
  6. package/__tests__/search/hybrid-query.test.ts +3 -1
  7. package/__tests__/web/api.test.ts +1 -1
  8. package/dist/src/analysis/churn-cache.d.ts.map +1 -1
  9. package/dist/src/analysis/churn-cache.js +19 -6
  10. package/dist/src/analysis/churn-cache.js.map +1 -1
  11. package/dist/src/analysis/churn-trend.d.ts.map +1 -1
  12. package/dist/src/analysis/churn-trend.js +50 -6
  13. package/dist/src/analysis/churn-trend.js.map +1 -1
  14. package/dist/src/analysis/cluster-quality.d.ts +3 -0
  15. package/dist/src/analysis/cluster-quality.d.ts.map +1 -1
  16. package/dist/src/analysis/cluster-quality.js +18 -12
  17. package/dist/src/analysis/cluster-quality.js.map +1 -1
  18. package/dist/src/analysis/coverage-gaps.d.ts +3 -0
  19. package/dist/src/analysis/coverage-gaps.d.ts.map +1 -1
  20. package/dist/src/analysis/coverage-gaps.js +40 -1
  21. package/dist/src/analysis/coverage-gaps.js.map +1 -1
  22. package/dist/src/analysis/dep-classification.d.ts +2 -0
  23. package/dist/src/analysis/dep-classification.d.ts.map +1 -1
  24. package/dist/src/analysis/dep-classification.js +30 -0
  25. package/dist/src/analysis/dep-classification.js.map +1 -1
  26. package/dist/src/analysis/dependency-health.d.ts +4 -0
  27. package/dist/src/analysis/dependency-health.d.ts.map +1 -1
  28. package/dist/src/analysis/dependency-health.js +28 -0
  29. package/dist/src/analysis/dependency-health.js.map +1 -1
  30. package/dist/src/analysis/duplicate-exports.d.ts +9 -5
  31. package/dist/src/analysis/duplicate-exports.d.ts.map +1 -1
  32. package/dist/src/analysis/duplicate-exports.js +26 -2
  33. package/dist/src/analysis/duplicate-exports.js.map +1 -1
  34. package/dist/src/analysis/feature-flags.d.ts.map +1 -1
  35. package/dist/src/analysis/feature-flags.js +36 -17
  36. package/dist/src/analysis/feature-flags.js.map +1 -1
  37. package/dist/src/analysis/node-similarity.d.ts +19 -0
  38. package/dist/src/analysis/node-similarity.d.ts.map +1 -1
  39. package/dist/src/analysis/node-similarity.js +34 -3
  40. package/dist/src/analysis/node-similarity.js.map +1 -1
  41. package/dist/src/analysis/private-type-leaks.d.ts +4 -0
  42. package/dist/src/analysis/private-type-leaks.d.ts.map +1 -1
  43. package/dist/src/analysis/private-type-leaks.js +43 -2
  44. package/dist/src/analysis/private-type-leaks.js.map +1 -1
  45. package/dist/src/analysis/project-state.d.ts +2 -0
  46. package/dist/src/analysis/project-state.d.ts.map +1 -1
  47. package/dist/src/analysis/project-state.js +18 -7
  48. package/dist/src/analysis/project-state.js.map +1 -1
  49. package/dist/src/analysis/suppressions.d.ts.map +1 -1
  50. package/dist/src/analysis/suppressions.js +3 -1
  51. package/dist/src/analysis/suppressions.js.map +1 -1
  52. package/dist/src/analysis/trace.d.ts +5 -3
  53. package/dist/src/analysis/trace.d.ts.map +1 -1
  54. package/dist/src/analysis/trace.js +59 -53
  55. package/dist/src/analysis/trace.js.map +1 -1
  56. package/dist/src/analysis/unused-class-members.d.ts.map +1 -1
  57. package/dist/src/analysis/unused-class-members.js +7 -1
  58. package/dist/src/analysis/unused-class-members.js.map +1 -1
  59. package/dist/src/analysis/worker-pool.d.ts +3 -0
  60. package/dist/src/analysis/worker-pool.d.ts.map +1 -1
  61. package/dist/src/analysis/worker-pool.js +30 -8
  62. package/dist/src/analysis/worker-pool.js.map +1 -1
  63. package/dist/src/cli/augment.d.ts.map +1 -1
  64. package/dist/src/cli/augment.js +10 -3
  65. package/dist/src/cli/augment.js.map +1 -1
  66. package/dist/src/cli/skill-gen.js +3 -0
  67. package/dist/src/cli/skill-gen.js.map +1 -1
  68. package/dist/src/export/sarif.js +5 -5
  69. package/dist/src/export/sarif.js.map +1 -1
  70. package/dist/src/graph/analyzer.d.ts.map +1 -1
  71. package/dist/src/graph/analyzer.js +17 -2
  72. package/dist/src/graph/analyzer.js.map +1 -1
  73. package/dist/src/graph/author-analytics.d.ts +2 -0
  74. package/dist/src/graph/author-analytics.d.ts.map +1 -1
  75. package/dist/src/graph/author-analytics.js +39 -5
  76. package/dist/src/graph/author-analytics.js.map +1 -1
  77. package/dist/src/graph/baseline.d.ts +5 -0
  78. package/dist/src/graph/baseline.d.ts.map +1 -1
  79. package/dist/src/graph/baseline.js +65 -18
  80. package/dist/src/graph/baseline.js.map +1 -1
  81. package/dist/src/graph/clone-detector.d.ts.map +1 -1
  82. package/dist/src/graph/clone-detector.js +19 -33
  83. package/dist/src/graph/clone-detector.js.map +1 -1
  84. package/dist/src/graph/clone-families.d.ts +2 -0
  85. package/dist/src/graph/clone-families.d.ts.map +1 -1
  86. package/dist/src/graph/clone-families.js +38 -10
  87. package/dist/src/graph/clone-families.js.map +1 -1
  88. package/dist/src/graph/codeowners-extended.d.ts +17 -0
  89. package/dist/src/graph/codeowners-extended.d.ts.map +1 -1
  90. package/dist/src/graph/codeowners-extended.js +42 -0
  91. package/dist/src/graph/codeowners-extended.js.map +1 -1
  92. package/dist/src/graph/codeowners-gitlab.d.ts +21 -0
  93. package/dist/src/graph/codeowners-gitlab.d.ts.map +1 -1
  94. package/dist/src/graph/codeowners-gitlab.js +37 -0
  95. package/dist/src/graph/codeowners-gitlab.js.map +1 -1
  96. package/dist/src/graph/codeowners.d.ts +10 -0
  97. package/dist/src/graph/codeowners.d.ts.map +1 -1
  98. package/dist/src/graph/codeowners.js +24 -2
  99. package/dist/src/graph/codeowners.js.map +1 -1
  100. package/dist/src/graph/complexity.d.ts +10 -0
  101. package/dist/src/graph/complexity.d.ts.map +1 -1
  102. package/dist/src/graph/complexity.js +93 -43
  103. package/dist/src/graph/complexity.js.map +1 -1
  104. package/dist/src/graph/cross-reference-findings.d.ts.map +1 -1
  105. package/dist/src/graph/cross-reference-findings.js +19 -2
  106. package/dist/src/graph/cross-reference-findings.js.map +1 -1
  107. package/dist/src/graph/cross-reference.d.ts +4 -0
  108. package/dist/src/graph/cross-reference.d.ts.map +1 -1
  109. package/dist/src/graph/cross-reference.js +23 -0
  110. package/dist/src/graph/cross-reference.js.map +1 -1
  111. package/dist/src/graph/cycle-detection.d.ts +2 -0
  112. package/dist/src/graph/cycle-detection.d.ts.map +1 -1
  113. package/dist/src/graph/cycle-detection.js +26 -3
  114. package/dist/src/graph/cycle-detection.js.map +1 -1
  115. package/dist/src/graph/cycles.d.ts +11 -3
  116. package/dist/src/graph/cycles.d.ts.map +1 -1
  117. package/dist/src/graph/cycles.js +121 -83
  118. package/dist/src/graph/cycles.js.map +1 -1
  119. package/dist/src/graph/dead-code.d.ts +23 -0
  120. package/dist/src/graph/dead-code.d.ts.map +1 -1
  121. package/dist/src/graph/dead-code.js +53 -13
  122. package/dist/src/graph/dead-code.js.map +1 -1
  123. package/dist/src/graph/dependency-closure.d.ts.map +1 -1
  124. package/dist/src/graph/dependency-closure.js +20 -4
  125. package/dist/src/graph/dependency-closure.js.map +1 -1
  126. package/dist/src/graph/dfs.d.ts +14 -0
  127. package/dist/src/graph/dfs.d.ts.map +1 -1
  128. package/dist/src/graph/dfs.js +61 -0
  129. package/dist/src/graph/dfs.js.map +1 -1
  130. package/dist/src/graph/duplication-stats.d.ts.map +1 -1
  131. package/dist/src/graph/duplication-stats.js +19 -3
  132. package/dist/src/graph/duplication-stats.js.map +1 -1
  133. package/dist/src/graph/edge-filter.d.ts +2 -0
  134. package/dist/src/graph/edge-filter.d.ts.map +1 -1
  135. package/dist/src/graph/edge-filter.js +26 -12
  136. package/dist/src/graph/edge-filter.js.map +1 -1
  137. package/dist/src/graph/health-score.d.ts +8 -0
  138. package/dist/src/graph/health-score.d.ts.map +1 -1
  139. package/dist/src/graph/health-score.js +48 -17
  140. package/dist/src/graph/health-score.js.map +1 -1
  141. package/dist/src/graph/hotspots.d.ts +7 -0
  142. package/dist/src/graph/hotspots.d.ts.map +1 -1
  143. package/dist/src/graph/hotspots.js +50 -5
  144. package/dist/src/graph/hotspots.js.map +1 -1
  145. package/dist/src/graph/import-chain.d.ts +17 -1
  146. package/dist/src/graph/import-chain.d.ts.map +1 -1
  147. package/dist/src/graph/import-chain.js +68 -19
  148. package/dist/src/graph/import-chain.js.map +1 -1
  149. package/dist/src/graph/loader.d.ts.map +1 -1
  150. package/dist/src/graph/loader.js +9 -10
  151. package/dist/src/graph/loader.js.map +1 -1
  152. package/dist/src/graph/maintainability.d.ts +8 -0
  153. package/dist/src/graph/maintainability.d.ts.map +1 -1
  154. package/dist/src/graph/maintainability.js +65 -10
  155. package/dist/src/graph/maintainability.js.map +1 -1
  156. package/dist/src/graph/mirrored-dirs.d.ts +4 -0
  157. package/dist/src/graph/mirrored-dirs.d.ts.map +1 -1
  158. package/dist/src/graph/mirrored-dirs.js +48 -13
  159. package/dist/src/graph/mirrored-dirs.js.map +1 -1
  160. package/dist/src/graph/narrowing.d.ts +15 -0
  161. package/dist/src/graph/narrowing.d.ts.map +1 -1
  162. package/dist/src/graph/narrowing.js +33 -0
  163. package/dist/src/graph/narrowing.js.map +1 -1
  164. package/dist/src/graph/node-search.d.ts +3 -0
  165. package/dist/src/graph/node-search.d.ts.map +1 -1
  166. package/dist/src/graph/node-search.js +37 -4
  167. package/dist/src/graph/node-search.js.map +1 -1
  168. package/dist/src/graph/normalize-id.d.ts +4 -0
  169. package/dist/src/graph/normalize-id.d.ts.map +1 -1
  170. package/dist/src/graph/normalize-id.js +25 -2
  171. package/dist/src/graph/normalize-id.js.map +1 -1
  172. package/dist/src/graph/pagerank.d.ts +7 -0
  173. package/dist/src/graph/pagerank.d.ts.map +1 -1
  174. package/dist/src/graph/pagerank.js +49 -2
  175. package/dist/src/graph/pagerank.js.map +1 -1
  176. package/dist/src/graph/prune.d.ts +31 -0
  177. package/dist/src/graph/prune.d.ts.map +1 -1
  178. package/dist/src/graph/prune.js +65 -0
  179. package/dist/src/graph/prune.js.map +1 -1
  180. package/dist/src/graph/regex-search.d.ts +10 -2
  181. package/dist/src/graph/regex-search.d.ts.map +1 -1
  182. package/dist/src/graph/regex-search.js +33 -4
  183. package/dist/src/graph/regex-search.js.map +1 -1
  184. package/dist/src/graph/regression.d.ts +5 -0
  185. package/dist/src/graph/regression.d.ts.map +1 -1
  186. package/dist/src/graph/regression.js +45 -23
  187. package/dist/src/graph/regression.js.map +1 -1
  188. package/dist/src/graph/ripple-impact.d.ts +27 -0
  189. package/dist/src/graph/ripple-impact.d.ts.map +1 -1
  190. package/dist/src/graph/ripple-impact.js +55 -7
  191. package/dist/src/graph/ripple-impact.js.map +1 -1
  192. package/dist/src/graph/risk-profile.d.ts +7 -0
  193. package/dist/src/graph/risk-profile.d.ts.map +1 -1
  194. package/dist/src/graph/risk-profile.js +82 -48
  195. package/dist/src/graph/risk-profile.js.map +1 -1
  196. package/dist/src/graph/shingle-filter.d.ts.map +1 -1
  197. package/dist/src/graph/shingle-filter.js +25 -26
  198. package/dist/src/graph/shingle-filter.js.map +1 -1
  199. package/dist/src/graph/statistics.d.ts +19 -0
  200. package/dist/src/graph/statistics.d.ts.map +1 -1
  201. package/dist/src/graph/statistics.js +53 -40
  202. package/dist/src/graph/statistics.js.map +1 -1
  203. package/dist/src/graph/stats.d.ts +2 -0
  204. package/dist/src/graph/stats.d.ts.map +1 -1
  205. package/dist/src/graph/stats.js +54 -8
  206. package/dist/src/graph/stats.js.map +1 -1
  207. package/dist/src/graph/subgraph.d.ts +5 -0
  208. package/dist/src/graph/subgraph.d.ts.map +1 -1
  209. package/dist/src/graph/subgraph.js +73 -9
  210. package/dist/src/graph/subgraph.js.map +1 -1
  211. package/dist/src/graph/topo-sort.d.ts +15 -0
  212. package/dist/src/graph/topo-sort.d.ts.map +1 -1
  213. package/dist/src/graph/topo-sort.js +83 -10
  214. package/dist/src/graph/topo-sort.js.map +1 -1
  215. package/dist/src/graph/wcc.d.ts +29 -0
  216. package/dist/src/graph/wcc.d.ts.map +1 -1
  217. package/dist/src/graph/wcc.js +122 -39
  218. package/dist/src/graph/wcc.js.map +1 -1
  219. package/dist/src/index.js +1 -1
  220. package/dist/src/index.js.map +1 -1
  221. package/dist/src/mcp-tools/api-impact.d.ts.map +1 -1
  222. package/dist/src/mcp-tools/api-impact.js +13 -6
  223. package/dist/src/mcp-tools/api-impact.js.map +1 -1
  224. package/dist/src/mcp-tools/context.d.ts.map +1 -1
  225. package/dist/src/mcp-tools/context.js +19 -29
  226. package/dist/src/mcp-tools/context.js.map +1 -1
  227. package/dist/src/mcp-tools/cypher.d.ts +11 -0
  228. package/dist/src/mcp-tools/cypher.d.ts.map +1 -1
  229. package/dist/src/mcp-tools/cypher.js +13 -1
  230. package/dist/src/mcp-tools/cypher.js.map +1 -1
  231. package/dist/src/mcp-tools/detect-changes.d.ts.map +1 -1
  232. package/dist/src/mcp-tools/detect-changes.js +35 -20
  233. package/dist/src/mcp-tools/detect-changes.js.map +1 -1
  234. package/dist/src/mcp-tools/explain.d.ts.map +1 -1
  235. package/dist/src/mcp-tools/explain.js +4 -1
  236. package/dist/src/mcp-tools/explain.js.map +1 -1
  237. package/dist/src/mcp-tools/graph-query.d.ts +2 -0
  238. package/dist/src/mcp-tools/graph-query.d.ts.map +1 -1
  239. package/dist/src/mcp-tools/graph-query.js +20 -3
  240. package/dist/src/mcp-tools/graph-query.js.map +1 -1
  241. package/dist/src/mcp-tools/group-list.d.ts +1 -0
  242. package/dist/src/mcp-tools/group-list.d.ts.map +1 -1
  243. package/dist/src/mcp-tools/group-list.js +7 -9
  244. package/dist/src/mcp-tools/group-list.js.map +1 -1
  245. package/dist/src/mcp-tools/impact.d.ts.map +1 -1
  246. package/dist/src/mcp-tools/impact.js +20 -59
  247. package/dist/src/mcp-tools/impact.js.map +1 -1
  248. package/dist/src/mcp-tools/neighbors.d.ts.map +1 -1
  249. package/dist/src/mcp-tools/neighbors.js +24 -33
  250. package/dist/src/mcp-tools/neighbors.js.map +1 -1
  251. package/dist/src/mcp-tools/query.d.ts +2 -0
  252. package/dist/src/mcp-tools/query.d.ts.map +1 -1
  253. package/dist/src/mcp-tools/query.js +1 -0
  254. package/dist/src/mcp-tools/query.js.map +1 -1
  255. package/dist/src/mcp-tools/rename.d.ts.map +1 -1
  256. package/dist/src/mcp-tools/rename.js +12 -7
  257. package/dist/src/mcp-tools/rename.js.map +1 -1
  258. package/dist/src/mcp-tools/route-map.d.ts.map +1 -1
  259. package/dist/src/mcp-tools/route-map.js +19 -23
  260. package/dist/src/mcp-tools/route-map.js.map +1 -1
  261. package/dist/src/mcp-tools/shape-check.d.ts.map +1 -1
  262. package/dist/src/mcp-tools/shape-check.js +17 -13
  263. package/dist/src/mcp-tools/shape-check.js.map +1 -1
  264. package/dist/src/parsers/loader.js +6 -5
  265. package/dist/src/parsers/loader.js.map +1 -1
  266. package/dist/src/pipeline/cluster-only.d.ts.map +1 -1
  267. package/dist/src/pipeline/cluster-only.js +8 -4
  268. package/dist/src/pipeline/cluster-only.js.map +1 -1
  269. package/dist/src/pipeline/orchestrator.d.ts +2 -0
  270. package/dist/src/pipeline/orchestrator.d.ts.map +1 -1
  271. package/dist/src/pipeline/orchestrator.js +19 -0
  272. package/dist/src/pipeline/orchestrator.js.map +1 -1
  273. package/dist/src/pipeline/phases/boundary.d.ts +2 -0
  274. package/dist/src/pipeline/phases/boundary.d.ts.map +1 -1
  275. package/dist/src/pipeline/phases/boundary.js +31 -2
  276. package/dist/src/pipeline/phases/boundary.js.map +1 -1
  277. package/dist/src/pipeline/phases/communities.d.ts +14 -0
  278. package/dist/src/pipeline/phases/communities.d.ts.map +1 -1
  279. package/dist/src/pipeline/phases/communities.js +58 -5
  280. package/dist/src/pipeline/phases/communities.js.map +1 -1
  281. package/dist/src/pipeline/phases/contextual-proximity.d.ts.map +1 -1
  282. package/dist/src/pipeline/phases/contextual-proximity.js +21 -14
  283. package/dist/src/pipeline/phases/contextual-proximity.js.map +1 -1
  284. package/dist/src/pipeline/phases/cross-file.d.ts.map +1 -1
  285. package/dist/src/pipeline/phases/cross-file.js +35 -14
  286. package/dist/src/pipeline/phases/cross-file.js.map +1 -1
  287. package/dist/src/pipeline/phases/field-access.d.ts.map +1 -1
  288. package/dist/src/pipeline/phases/field-access.js +9 -4
  289. package/dist/src/pipeline/phases/field-access.js.map +1 -1
  290. package/dist/src/pipeline/phases/god-nodes.d.ts +4 -0
  291. package/dist/src/pipeline/phases/god-nodes.d.ts.map +1 -1
  292. package/dist/src/pipeline/phases/god-nodes.js +43 -9
  293. package/dist/src/pipeline/phases/god-nodes.js.map +1 -1
  294. package/dist/src/pipeline/phases/import-resolver.d.ts +11 -0
  295. package/dist/src/pipeline/phases/import-resolver.d.ts.map +1 -1
  296. package/dist/src/pipeline/phases/import-resolver.js +34 -7
  297. package/dist/src/pipeline/phases/import-resolver.js.map +1 -1
  298. package/dist/src/pipeline/phases/leiden.d.ts.map +1 -1
  299. package/dist/src/pipeline/phases/leiden.js +27 -19
  300. package/dist/src/pipeline/phases/leiden.js.map +1 -1
  301. package/dist/src/pipeline/phases/markdown.d.ts.map +1 -1
  302. package/dist/src/pipeline/phases/markdown.js +10 -5
  303. package/dist/src/pipeline/phases/markdown.js.map +1 -1
  304. package/dist/src/pipeline/phases/pdf-parse.d.ts.map +1 -1
  305. package/dist/src/pipeline/phases/pdf-parse.js +18 -3
  306. package/dist/src/pipeline/phases/pdf-parse.js.map +1 -1
  307. package/dist/src/pipeline/phases/processes.d.ts.map +1 -1
  308. package/dist/src/pipeline/phases/processes.js +26 -9
  309. package/dist/src/pipeline/phases/processes.js.map +1 -1
  310. package/dist/src/pipeline/phases/re-export-propagation.d.ts.map +1 -1
  311. package/dist/src/pipeline/phases/re-export-propagation.js +33 -14
  312. package/dist/src/pipeline/phases/re-export-propagation.js.map +1 -1
  313. package/dist/src/pipeline/phases/reachability.d.ts.map +1 -1
  314. package/dist/src/pipeline/phases/reachability.js +42 -26
  315. package/dist/src/pipeline/phases/reachability.js.map +1 -1
  316. package/dist/src/pipeline/phases/routes.d.ts.map +1 -1
  317. package/dist/src/pipeline/phases/routes.js +30 -21
  318. package/dist/src/pipeline/phases/routes.js.map +1 -1
  319. package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
  320. package/dist/src/pipeline/phases/scope-resolution.js +93 -63
  321. package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
  322. package/dist/src/pipeline/runner.d.ts +4 -0
  323. package/dist/src/pipeline/runner.d.ts.map +1 -1
  324. package/dist/src/pipeline/runner.js +30 -11
  325. package/dist/src/pipeline/runner.js.map +1 -1
  326. package/dist/src/query/cypher-parser.d.ts +20 -0
  327. package/dist/src/query/cypher-parser.d.ts.map +1 -1
  328. package/dist/src/query/cypher-parser.js +73 -0
  329. package/dist/src/query/cypher-parser.js.map +1 -1
  330. package/dist/src/search/embed-batch.d.ts.map +1 -1
  331. package/dist/src/search/embed-batch.js +4 -1
  332. package/dist/src/search/embed-batch.js.map +1 -1
  333. package/dist/src/search/hybrid-query.d.ts +4 -0
  334. package/dist/src/search/hybrid-query.d.ts.map +1 -1
  335. package/dist/src/search/hybrid-query.js +5 -1
  336. package/dist/src/search/hybrid-query.js.map +1 -1
  337. package/dist/src/staleness/git-staleness.js +3 -3
  338. package/dist/src/staleness/git-staleness.js.map +1 -1
  339. package/dist/src/storage/db.d.ts.map +1 -1
  340. package/dist/src/storage/db.js +12 -0
  341. package/dist/src/storage/db.js.map +1 -1
  342. package/dist/src/storage/edge-store.d.ts +2 -0
  343. package/dist/src/storage/edge-store.d.ts.map +1 -1
  344. package/dist/src/storage/edge-store.js +26 -1
  345. package/dist/src/storage/edge-store.js.map +1 -1
  346. package/dist/src/storage/embedding-store.d.ts +16 -0
  347. package/dist/src/storage/embedding-store.d.ts.map +1 -1
  348. package/dist/src/storage/embedding-store.js +26 -2
  349. package/dist/src/storage/embedding-store.js.map +1 -1
  350. package/dist/src/storage/file-cache.d.ts +5 -0
  351. package/dist/src/storage/file-cache.d.ts.map +1 -1
  352. package/dist/src/storage/file-cache.js +35 -9
  353. package/dist/src/storage/file-cache.js.map +1 -1
  354. package/dist/src/storage/fts-store.d.ts +4 -0
  355. package/dist/src/storage/fts-store.d.ts.map +1 -1
  356. package/dist/src/storage/fts-store.js +8 -3
  357. package/dist/src/storage/fts-store.js.map +1 -1
  358. package/dist/src/storage/node-store.d.ts +2 -0
  359. package/dist/src/storage/node-store.d.ts.map +1 -1
  360. package/dist/src/storage/node-store.js +28 -1
  361. package/dist/src/storage/node-store.js.map +1 -1
  362. package/dist/src/wiki/wiki-generator.d.ts.map +1 -1
  363. package/dist/src/wiki/wiki-generator.js +5 -1
  364. package/dist/src/wiki/wiki-generator.js.map +1 -1
  365. package/dist/tsconfig.tsbuildinfo +1 -1
  366. package/package.json +1 -1
  367. package/src/__tests__/pipeline/runner.parallel.test.ts +2 -2
  368. package/src/analysis/churn-cache.ts +18 -7
  369. package/src/analysis/churn-trend.ts +35 -6
  370. package/src/analysis/cluster-quality.ts +20 -11
  371. package/src/analysis/coverage-gaps.ts +44 -1
  372. package/src/analysis/dep-classification.ts +34 -0
  373. package/src/analysis/dependency-health.ts +25 -0
  374. package/src/analysis/duplicate-exports.ts +40 -4
  375. package/src/analysis/feature-flags.ts +37 -17
  376. package/src/analysis/node-similarity.ts +45 -4
  377. package/src/analysis/private-type-leaks.ts +49 -2
  378. package/src/analysis/project-state.ts +19 -9
  379. package/src/analysis/suppressions.ts +4 -1
  380. package/src/analysis/trace.ts +73 -54
  381. package/src/analysis/unused-class-members.ts +8 -1
  382. package/src/analysis/worker-pool.ts +40 -8
  383. package/src/cli/augment.ts +10 -3
  384. package/src/cli/skill-gen.ts +3 -0
  385. package/src/export/sarif.ts +5 -5
  386. package/src/graph/analyzer.ts +26 -2
  387. package/src/graph/author-analytics.ts +45 -5
  388. package/src/graph/baseline.ts +78 -24
  389. package/src/graph/clone-detector.ts +22 -36
  390. package/src/graph/clone-families.ts +34 -10
  391. package/src/graph/codeowners-extended.ts +54 -0
  392. package/src/graph/codeowners-gitlab.ts +46 -0
  393. package/src/graph/codeowners.ts +33 -2
  394. package/src/graph/complexity.ts +102 -47
  395. package/src/graph/cross-reference-findings.ts +23 -2
  396. package/src/graph/cross-reference.ts +26 -0
  397. package/src/graph/cycle-detection.ts +22 -3
  398. package/src/graph/cycles.ts +155 -96
  399. package/src/graph/dead-code.ts +76 -17
  400. package/src/graph/dependency-closure.ts +24 -7
  401. package/src/graph/dfs.ts +78 -0
  402. package/src/graph/duplication-stats.ts +17 -6
  403. package/src/graph/edge-filter.ts +26 -12
  404. package/src/graph/health-score.ts +47 -17
  405. package/src/graph/hotspots.ts +57 -8
  406. package/src/graph/import-chain.ts +89 -19
  407. package/src/graph/loader.ts +10 -7
  408. package/src/graph/maintainability.ts +72 -22
  409. package/src/graph/mirrored-dirs.ts +45 -14
  410. package/src/graph/narrowing.ts +44 -0
  411. package/src/graph/node-search.ts +50 -4
  412. package/src/graph/normalize-id.ts +26 -2
  413. package/src/graph/pagerank.ts +70 -2
  414. package/src/graph/prune.ts +76 -0
  415. package/src/graph/regex-search.ts +38 -4
  416. package/src/graph/regression.ts +48 -23
  417. package/src/graph/ripple-impact.ts +71 -11
  418. package/src/graph/risk-profile.ts +98 -53
  419. package/src/graph/shingle-filter.ts +33 -27
  420. package/src/graph/statistics.ts +73 -45
  421. package/src/graph/stats.ts +50 -16
  422. package/src/graph/subgraph.ts +97 -25
  423. package/src/graph/topo-sort.ts +101 -16
  424. package/src/graph/wcc.ts +146 -37
  425. package/src/index.ts +1 -1
  426. package/src/mcp-tools/api-impact.ts +13 -6
  427. package/src/mcp-tools/context.ts +31 -40
  428. package/src/mcp-tools/cypher.ts +14 -1
  429. package/src/mcp-tools/detect-changes.ts +38 -23
  430. package/src/mcp-tools/explain.ts +4 -1
  431. package/src/mcp-tools/graph-query.ts +24 -3
  432. package/src/mcp-tools/group-list.ts +9 -11
  433. package/src/mcp-tools/impact.ts +26 -66
  434. package/src/mcp-tools/neighbors.ts +34 -39
  435. package/src/mcp-tools/query.ts +3 -0
  436. package/src/mcp-tools/rename.ts +9 -8
  437. package/src/mcp-tools/route-map.ts +21 -23
  438. package/src/mcp-tools/shape-check.ts +18 -14
  439. package/src/parsers/loader.ts +5 -5
  440. package/src/pipeline/cluster-only.ts +8 -4
  441. package/src/pipeline/orchestrator.ts +22 -0
  442. package/src/pipeline/phases/boundary.ts +40 -2
  443. package/src/pipeline/phases/communities.ts +66 -5
  444. package/src/pipeline/phases/contextual-proximity.ts +15 -14
  445. package/src/pipeline/phases/cross-file.ts +35 -14
  446. package/src/pipeline/phases/field-access.ts +11 -4
  447. package/src/pipeline/phases/god-nodes.ts +47 -10
  448. package/src/pipeline/phases/import-resolver.ts +37 -5
  449. package/src/pipeline/phases/leiden.ts +25 -18
  450. package/src/pipeline/phases/markdown.ts +12 -7
  451. package/src/pipeline/phases/pdf-parse.ts +19 -2
  452. package/src/pipeline/phases/processes.ts +27 -15
  453. package/src/pipeline/phases/re-export-propagation.ts +40 -18
  454. package/src/pipeline/phases/reachability.ts +39 -24
  455. package/src/pipeline/phases/routes.ts +32 -21
  456. package/src/pipeline/phases/scope-resolution.ts +110 -71
  457. package/src/pipeline/runner.ts +28 -11
  458. package/src/query/cypher-parser.ts +83 -0
  459. package/src/search/embed-batch.ts +4 -1
  460. package/src/search/hybrid-query.ts +11 -1
  461. package/src/staleness/git-staleness.ts +3 -3
  462. package/src/storage/db.ts +11 -0
  463. package/src/storage/edge-store.ts +34 -1
  464. package/src/storage/embedding-store.ts +38 -6
  465. package/src/storage/file-cache.ts +35 -21
  466. package/src/storage/fts-store.ts +12 -3
  467. package/src/storage/node-store.ts +39 -1
  468. package/src/wiki/wiki-generator.ts +5 -1
  469. package/src/coverage/runtime.ts +0 -249
@@ -1,4 +1,8 @@
1
1
  import type { MonographDb } from '../storage/db.js';
2
+ /**
3
+ * Evict the cached graph for a given DB instance (call after writes).
4
+ */
5
+ export declare function invalidateGraphCache(db: MonographDb): void;
2
6
  /**
3
7
  * Graph density: ratio of actual edges to maximum possible directed edges.
4
8
  * For a directed graph with n nodes: max = n * (n - 1).
@@ -13,14 +17,29 @@ export declare function graphDensity(db: MonographDb): number;
13
17
  * We use the undirected approximation: treat edges as undirected, count triangles.
14
18
  */
15
19
  export declare function clusteringCoefficient(db: MonographDb): number;
20
+ export interface PathStats {
21
+ /** Average shortest path length across all reachable pairs (i ≠ j). */
22
+ averagePathLength: number;
23
+ /** Maximum shortest path length (diameter) across all reachable pairs. */
24
+ diameter: number;
25
+ }
26
+ /**
27
+ * Compute both average path length and graph diameter in a single BFS pass.
28
+ * Unreachable pairs are excluded from averagePathLength.
29
+ */
30
+ export declare function pathStats(db: MonographDb): PathStats;
16
31
  /**
17
32
  * Average shortest path length across all reachable node pairs (i, j) where i ≠ j.
18
33
  * Computed using BFS from each node. Unreachable pairs are excluded from the average.
34
+ *
35
+ * @deprecated Prefer `pathStats(db).averagePathLength` to share BFS with `graphDiameter`.
19
36
  */
20
37
  export declare function averagePathLength(db: MonographDb): number;
21
38
  /**
22
39
  * Graph diameter: the maximum shortest path length across all reachable node pairs.
23
40
  * Returns 0 for empty or single-node graphs.
41
+ *
42
+ * @deprecated Prefer `pathStats(db).diameter` to share BFS with `averagePathLength`.
24
43
  */
25
44
  export declare function graphDiameter(db: MonographDb): number;
26
45
  //# sourceMappingURL=statistics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../../../src/graph/statistics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWpD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAsC7D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CA4BzD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAyBrD"}
1
+ {"version":3,"file":"statistics.d.ts","sourceRoot":"","sources":["../../../src/graph/statistics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA0BpD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAG1D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWpD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAsC7D;AAMD,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,SAAS,CAuBpD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAErD"}
@@ -1,12 +1,36 @@
1
1
  import { bfsFromNode } from 'graphology-traversal/bfs.js';
2
2
  import { loadGraphFromDb } from './loader.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Module-level graph cache — avoids reloading the full graph on every call
5
+ // when multiple statistics functions are invoked in the same request cycle.
6
+ // TTL: 5 seconds; keyed by DB file path (better-sqlite3 exposes .name).
7
+ // ---------------------------------------------------------------------------
8
+ const GRAPH_CACHE_TTL_MS = 5_000;
9
+ const _graphCache = new Map();
10
+ function getGraph(db) {
11
+ const key = db.name ?? '__default__';
12
+ const now = Date.now();
13
+ const cached = _graphCache.get(key);
14
+ if (cached && now < cached.expiresAt)
15
+ return cached.graph;
16
+ const graph = loadGraphFromDb(db);
17
+ _graphCache.set(key, { graph, expiresAt: now + GRAPH_CACHE_TTL_MS });
18
+ return graph;
19
+ }
20
+ /**
21
+ * Evict the cached graph for a given DB instance (call after writes).
22
+ */
23
+ export function invalidateGraphCache(db) {
24
+ const key = db.name ?? '__default__';
25
+ _graphCache.delete(key);
26
+ }
3
27
  /**
4
28
  * Graph density: ratio of actual edges to maximum possible directed edges.
5
29
  * For a directed graph with n nodes: max = n * (n - 1).
6
30
  * Ignores self-loops.
7
31
  */
8
32
  export function graphDensity(db) {
9
- const graph = loadGraphFromDb(db);
33
+ const graph = getGraph(db);
10
34
  const n = graph.order;
11
35
  if (n < 2)
12
36
  return 0;
@@ -27,7 +51,7 @@ export function graphDensity(db) {
27
51
  * We use the undirected approximation: treat edges as undirected, count triangles.
28
52
  */
29
53
  export function clusteringCoefficient(db) {
30
- const graph = loadGraphFromDb(db);
54
+ const graph = getGraph(db);
31
55
  if (graph.order === 0)
32
56
  return 0;
33
57
  // Build undirected adjacency sets
@@ -63,59 +87,48 @@ export function clusteringCoefficient(db) {
63
87
  return totalCoeff / countWithNeighbors;
64
88
  }
65
89
  /**
66
- * Average shortest path length across all reachable node pairs (i, j) where i ≠ j.
67
- * Computed using BFS from each node. Unreachable pairs are excluded from the average.
90
+ * Compute both average path length and graph diameter in a single BFS pass.
91
+ * Unreachable pairs are excluded from averagePathLength.
68
92
  */
69
- export function averagePathLength(db) {
70
- const graph = loadGraphFromDb(db);
93
+ export function pathStats(db) {
94
+ const graph = getGraph(db);
71
95
  const nodes = graph.nodes();
72
96
  if (nodes.length < 2)
73
- return 0;
97
+ return { averagePathLength: 0, diameter: 0 };
74
98
  let totalLength = 0;
75
99
  let reachablePairs = 0;
100
+ let maxDist = 0;
76
101
  for (const source of nodes) {
77
- const distances = new Map();
78
- distances.set(source, 0);
79
102
  bfsFromNode(graph, source, (node, _attr, depth) => {
80
- if (node !== source) {
81
- distances.set(node, depth);
82
- }
83
- });
84
- for (const [target, dist] of distances) {
85
- if (target !== source && dist > 0) {
86
- totalLength += dist;
103
+ if (node !== source && depth > 0) {
104
+ totalLength += depth;
87
105
  reachablePairs++;
106
+ if (depth > maxDist)
107
+ maxDist = depth;
88
108
  }
89
- }
109
+ });
90
110
  }
91
- if (reachablePairs === 0)
92
- return 0;
93
- return totalLength / reachablePairs;
111
+ return {
112
+ averagePathLength: reachablePairs === 0 ? 0 : totalLength / reachablePairs,
113
+ diameter: maxDist,
114
+ };
115
+ }
116
+ /**
117
+ * Average shortest path length across all reachable node pairs (i, j) where i ≠ j.
118
+ * Computed using BFS from each node. Unreachable pairs are excluded from the average.
119
+ *
120
+ * @deprecated Prefer `pathStats(db).averagePathLength` to share BFS with `graphDiameter`.
121
+ */
122
+ export function averagePathLength(db) {
123
+ return pathStats(db).averagePathLength;
94
124
  }
95
125
  /**
96
126
  * Graph diameter: the maximum shortest path length across all reachable node pairs.
97
127
  * Returns 0 for empty or single-node graphs.
128
+ *
129
+ * @deprecated Prefer `pathStats(db).diameter` to share BFS with `averagePathLength`.
98
130
  */
99
131
  export function graphDiameter(db) {
100
- const graph = loadGraphFromDb(db);
101
- const nodes = graph.nodes();
102
- if (nodes.length < 2)
103
- return 0;
104
- let maxDist = 0;
105
- for (const source of nodes) {
106
- const distances = new Map();
107
- distances.set(source, 0);
108
- bfsFromNode(graph, source, (node, _attr, depth) => {
109
- if (node !== source) {
110
- distances.set(node, depth);
111
- }
112
- });
113
- for (const [target, dist] of distances) {
114
- if (target !== source && dist > maxDist) {
115
- maxDist = dist;
116
- }
117
- }
118
- }
119
- return maxDist;
132
+ return pathStats(db).diameter;
120
133
  }
121
134
  //# sourceMappingURL=statistics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"statistics.js","sourceRoot":"","sources":["../../../src/graph/statistics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"statistics.js","sourceRoot":"","sources":["../../../src/graph/statistics.ts"],"names":[],"mappings":"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"}
@@ -35,4 +35,6 @@ export declare function computeCouplingProfile(db: Database.Database): CouplingP
35
35
  * Quick stats summary (extends existing stats from monograph_stats MCP tool).
36
36
  */
37
37
  export declare function computeGraphStats(db: Database.Database): GraphStatsSummary;
38
+ /** Format a GraphStatsSummary as structured text for LLM consumption. */
39
+ export declare function formatGraphStats(s: GraphStatsSummary): string;
38
40
  //# sourceMappingURL=stats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/graph/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,eAAe,CAAC;CAClC;AA8BD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,eAAe,CAgC7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,iBAAiB,CAmB1E"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/graph/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAwB3C,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,eAAe,CAAC;CAClC;AA8BD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,eAAe,CA8B7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,iBAAiB,CAkB1E;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAY7D"}
@@ -1,3 +1,30 @@
1
+ // Per-DB prepared statement cache to avoid re-parsing SQL on repeated calls
2
+ const stmtCache = new WeakMap();
3
+ function stmt(db, sql) {
4
+ let dbCache = stmtCache.get(db);
5
+ if (!dbCache) {
6
+ dbCache = new Map();
7
+ stmtCache.set(db, dbCache);
8
+ }
9
+ let s = dbCache.get(sql);
10
+ if (!s) {
11
+ s = db.prepare(sql);
12
+ dbCache.set(sql, s);
13
+ }
14
+ return s;
15
+ }
16
+ /** Binary search: returns index of first element > value in a sorted ascending array. */
17
+ function upperBound(sorted, value) {
18
+ let lo = 0, hi = sorted.length;
19
+ while (lo < hi) {
20
+ const mid = (lo + hi) >>> 1;
21
+ if (sorted[mid] <= value)
22
+ lo = mid + 1;
23
+ else
24
+ hi = mid;
25
+ }
26
+ return lo;
27
+ }
1
28
  function percentile(sorted, p) {
2
29
  if (sorted.length === 0)
3
30
  return 0;
@@ -33,13 +60,17 @@ function buildRiskProfile(values) {
33
60
  * Compute full coupling profile from SQLite.
34
61
  */
35
62
  export function computeCouplingProfile(db) {
36
- const fanInRows = db.prepare('SELECT target_id, COUNT(*) as c FROM edges GROUP BY target_id').all();
37
- const fanOutRows = db.prepare('SELECT source_id, COUNT(*) as c FROM edges GROUP BY source_id').all();
38
- const totalFiles = db.prepare("SELECT COUNT(*) as n FROM nodes WHERE label = 'File'").get().n;
63
+ const fanInRows = stmt(db, 'SELECT target_id, COUNT(*) as c FROM edges GROUP BY target_id')
64
+ .all();
65
+ const fanOutRows = stmt(db, 'SELECT source_id, COUNT(*) as c FROM edges GROUP BY source_id')
66
+ .all();
67
+ const totalFiles = stmt(db, "SELECT COUNT(*) as n FROM nodes WHERE label = 'File'")
68
+ .get().n;
39
69
  const fanInValues = fanInRows.map(r => r.c).sort((a, b) => a - b);
40
70
  const fanOutValues = fanOutRows.map(r => r.c).sort((a, b) => a - b);
41
71
  const p95FanIn = percentile(fanInValues, 95);
42
- const couplingHighCount = fanInValues.filter(v => v > p95FanIn).length;
72
+ // Use binary search instead of O(N) filter to count elements above p95 threshold
73
+ const couplingHighCount = fanInValues.length - upperBound(fanInValues, p95FanIn);
43
74
  const couplingHighPct = fanInValues.length > 0
44
75
  ? Math.round((couplingHighCount / fanInValues.length) * 100)
45
76
  : 0;
@@ -58,10 +89,11 @@ export function computeCouplingProfile(db) {
58
89
  * Quick stats summary (extends existing stats from monograph_stats MCP tool).
59
90
  */
60
91
  export function computeGraphStats(db) {
61
- const nodeCount = db.prepare('SELECT COUNT(*) as n FROM nodes').get().n;
62
- const edgeCount = db.prepare('SELECT COUNT(*) as n FROM edges').get().n;
63
- const communityCount = db.prepare("SELECT COUNT(DISTINCT community_id) as n FROM nodes WHERE community_id IS NOT NULL").get().n;
64
- const fileCount = db.prepare("SELECT COUNT(*) as n FROM nodes WHERE label = 'File'").get().n;
92
+ const nodeCount = stmt(db, 'SELECT COUNT(*) as n FROM nodes').get().n;
93
+ const edgeCount = stmt(db, 'SELECT COUNT(*) as n FROM edges').get().n;
94
+ const communityCount = stmt(db, "SELECT COUNT(DISTINCT community_id) as n FROM nodes WHERE community_id IS NOT NULL").get().n;
95
+ const fileCount = stmt(db, "SELECT COUNT(*) as n FROM nodes WHERE label = 'File'")
96
+ .get().n;
65
97
  const couplingProfile = computeCouplingProfile(db);
66
98
  return {
67
99
  nodeCount,
@@ -71,4 +103,18 @@ export function computeGraphStats(db) {
71
103
  couplingProfile,
72
104
  };
73
105
  }
106
+ /** Format a GraphStatsSummary as structured text for LLM consumption. */
107
+ export function formatGraphStats(s) {
108
+ const cp = s.couplingProfile;
109
+ const lines = [
110
+ `Graph Stats`,
111
+ ` Nodes: ${s.nodeCount} Edges: ${s.edgeCount} Communities: ${s.communityCount} Files: ${s.fileCount}`,
112
+ `Coupling Profile (${cp.totalFiles} files)`,
113
+ ` Fan-in p50/p75/p90/p95: ${cp.p50FanIn}/${cp.p75FanIn}/${cp.p90FanIn}/${cp.p95FanIn}`,
114
+ ` High-coupling (>p95): ${cp.couplingHighPct}%`,
115
+ `Fan-in Risk: low=${cp.fanInProfile.low}(${cp.fanInProfile.lowPct}%) med=${cp.fanInProfile.medium}(${cp.fanInProfile.mediumPct}%) high=${cp.fanInProfile.high}(${cp.fanInProfile.highPct}%) crit=${cp.fanInProfile.critical}(${cp.fanInProfile.criticalPct}%)`,
116
+ `Fan-out Risk: low=${cp.fanOutProfile.low}(${cp.fanOutProfile.lowPct}%) med=${cp.fanOutProfile.medium}(${cp.fanOutProfile.mediumPct}%) high=${cp.fanOutProfile.high}(${cp.fanOutProfile.highPct}%) crit=${cp.fanOutProfile.critical}(${cp.fanOutProfile.criticalPct}%)`,
117
+ ];
118
+ return lines.join('\n');
119
+ }
74
120
  //# sourceMappingURL=stats.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/graph/stats.ts"],"names":[],"mappings":"AAkCA,SAAS,UAAU,CAAC,MAAgB,EAAE,CAAS;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IAC5B,IAAI,GAAG,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC;YAAE,GAAG,EAAE,CAAC;aACZ,IAAI,CAAC,IAAI,EAAE;YAAE,MAAM,EAAE,CAAC;aACtB,IAAI,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,CAAC;;YACpB,QAAQ,EAAE,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO;QACL,GAAG;QACH,MAAM;QACN,IAAI;QACJ,QAAQ;QACR,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC;QAChB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC;QACtB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC;QAClB,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAqB;IAC1D,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAC1B,+DAA+D,CAChE,CAAC,GAAG,EAAwC,CAAC;IAE9C,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,+DAA+D,CAChE,CAAC,GAAG,EAAwC,CAAC;IAE9C,MAAM,UAAU,GAAI,EAAE,CAAC,OAAO,CAC5B,sDAAsD,CACvD,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;IAE5B,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpE,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QAC5D,CAAC,CAAC,CAAC,CAAC;IAEN,OAAO;QACL,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,QAAQ;QACR,eAAe;QACf,YAAY,EAAE,gBAAgB,CAAC,WAAW,CAAC;QAC3C,aAAa,EAAE,gBAAgB,CAAC,YAAY,CAAC;QAC7C,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAqB;IACrD,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;IAC3F,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;IAC3F,MAAM,cAAc,GAAI,EAAE,CAAC,OAAO,CAChC,oFAAoF,CACrF,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;IAC5B,MAAM,SAAS,GAAI,EAAE,CAAC,OAAO,CAC3B,sDAAsD,CACvD,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;IAE5B,MAAM,eAAe,GAAG,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAEnD,OAAO;QACL,SAAS;QACT,SAAS;QACT,cAAc;QACd,SAAS;QACT,eAAe;KAChB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/graph/stats.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,9 @@ export interface InducedSubgraph {
5
5
  edges: MonographEdge[];
6
6
  }
7
7
  export declare function extractInducedSubgraph(db: MonographDb, nodeIds: string[]): InducedSubgraph;
8
+ /**
9
+ * Format an InducedSubgraph as structured text for LLM consumption.
10
+ * Groups nodes by file path and lists edges with relation + file:line hints.
11
+ */
12
+ export declare function formatInducedSubgraph(sg: InducedSubgraph): string;
8
13
  //# sourceMappingURL=subgraph.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subgraph.d.ts","sourceRoot":"","sources":["../../../src/graph/subgraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAiBD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,eAAe,CAkE1F"}
1
+ {"version":3,"file":"subgraph.d.ts","sourceRoot":"","sources":["../../../src/graph/subgraph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAwDD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,eAAe,CA6D1F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,eAAe,GAAG,MAAM,CA+BjE"}
@@ -12,26 +12,55 @@
12
12
  // SQLite SQLITE_MAX_VARIABLE_NUMBER limit (32766). Edge query binds nodeIds once
13
13
  // (source_id IN chunk), then filters target in-memory — full limit available per chunk.
14
14
  const SQLITE_VAR_LIMIT = 32766;
15
+ /** Cache of placeholder strings keyed by count: 1 → "?", 2 → "?,?", etc. */
16
+ const placeholderCache = new Map();
17
+ function placeholders(n) {
18
+ let ph = placeholderCache.get(n);
19
+ if (!ph) {
20
+ ph = Array(n).fill('?').join(',');
21
+ placeholderCache.set(n, ph);
22
+ }
23
+ return ph;
24
+ }
25
+ /**
26
+ * Prepared-statement caches per db instance — stored on the db object to avoid
27
+ * cross-db pollution while ensuring each unique chunk size is prepared at most once.
28
+ */
29
+ function getStmtCaches(db) {
30
+ const key = '__subgraphStmtCache__';
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ const dbAny = db;
33
+ if (!dbAny[key]) {
34
+ dbAny[key] = { nodes: new Map(), edges: new Map() };
35
+ }
36
+ return dbAny[key];
37
+ }
15
38
  export function extractInducedSubgraph(db, nodeIds) {
16
39
  if (nodeIds.length === 0)
17
40
  return { nodes: [], edges: [] };
18
- // Chunk helper to stay within SQLITE_MAX_VARIABLE_NUMBER
19
- function queryChunked(ids, chunkSize, query) {
41
+ const stmts = getStmtCaches(db);
42
+ // Chunk helper caches prepared statements by chunk size to avoid re-prepare per call.
43
+ function queryChunked(ids, chunkSize, stmtCache, sql) {
20
44
  const results = [];
21
45
  for (let i = 0; i < ids.length; i += chunkSize) {
22
46
  const chunk = ids.slice(i, i + chunkSize);
23
- const ph = chunk.map(() => '?').join(',');
24
- results.push(...query(ph, chunk));
47
+ const ph = placeholders(chunk.length);
48
+ let stmt = stmtCache.get(chunk.length);
49
+ if (!stmt) {
50
+ stmt = db.prepare(sql(ph));
51
+ stmtCache.set(chunk.length, stmt);
52
+ }
53
+ results.push(...stmt.all(...chunk));
25
54
  }
26
55
  return results;
27
56
  }
28
- const rawNodes = queryChunked(nodeIds, SQLITE_VAR_LIMIT, (ph, chunk) => db.prepare(`SELECT id, label, name, file_path, start_line, end_line, community_id, is_exported, language, properties
29
- FROM nodes WHERE id IN (${ph})`).all(...chunk));
57
+ const rawNodes = queryChunked(nodeIds, SQLITE_VAR_LIMIT, stmts.nodes, ph => `SELECT id, label, name, file_path, start_line, end_line, community_id, is_exported, language, properties FROM nodes WHERE id IN (${ph})`);
30
58
  // For edges: query by source_id chunks (1 bind per row), then filter target in-memory.
31
- // Querying by both source+target would miss cross-chunk edges and requires 2× bind slots.
32
59
  const nodeSet = new Set(nodeIds);
33
- const rawEdges = queryChunked(nodeIds, SQLITE_VAR_LIMIT, (ph, chunk) => db.prepare(`SELECT id, source_id, target_id, relation, confidence, confidence_score, reason, evidence
34
- FROM edges WHERE source_id IN (${ph})`).all(...chunk).filter(e => nodeSet.has(e.target_id)));
60
+ const allSourceEdges = queryChunked(nodeIds, SQLITE_VAR_LIMIT, stmts.edges,
61
+ // Drop unused 'evidence' column to reduce row data transfer
62
+ ph => `SELECT id, source_id, target_id, relation, confidence, confidence_score, reason FROM edges WHERE source_id IN (${ph})`);
63
+ const rawEdges = allSourceEdges.filter(e => nodeSet.has(e.target_id));
35
64
  const nodes = rawNodes.map(n => ({
36
65
  id: n.id,
37
66
  label: n.label,
@@ -56,4 +85,39 @@ export function extractInducedSubgraph(db, nodeIds) {
56
85
  }));
57
86
  return { nodes, edges };
58
87
  }
88
+ /**
89
+ * Format an InducedSubgraph as structured text for LLM consumption.
90
+ * Groups nodes by file path and lists edges with relation + file:line hints.
91
+ */
92
+ export function formatInducedSubgraph(sg) {
93
+ if (sg.nodes.length === 0)
94
+ return 'Subgraph is empty.';
95
+ const lines = [`Subgraph: ${sg.nodes.length} nodes, ${sg.edges.length} edges`];
96
+ // Group nodes by file
97
+ const byFile = new Map();
98
+ for (const n of sg.nodes) {
99
+ const file = n.filePath ?? '(unknown)';
100
+ let list = byFile.get(file);
101
+ if (!list) {
102
+ list = [];
103
+ byFile.set(file, list);
104
+ }
105
+ list.push(n);
106
+ }
107
+ lines.push('\nNodes:');
108
+ for (const [file, nodes] of byFile) {
109
+ lines.push(` ${file}`);
110
+ for (const n of nodes) {
111
+ const loc = n.startLine ? `:${n.startLine}` : '';
112
+ lines.push(` ${n.label} ${n.name}${loc}`);
113
+ }
114
+ }
115
+ if (sg.edges.length > 0) {
116
+ lines.push('\nEdges:');
117
+ for (const e of sg.edges) {
118
+ lines.push(` ${e.sourceId} --[${e.relation}]--> ${e.targetId}`);
119
+ }
120
+ }
121
+ return lines.join('\n');
122
+ }
59
123
  //# sourceMappingURL=subgraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subgraph.js","sourceRoot":"","sources":["../../../src/graph/subgraph.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,iFAAiF;AACjF,wFAAwF;AACxF,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B,MAAM,UAAU,sBAAsB,CAAC,EAAe,EAAE,OAAiB;IACvE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAE1D,yDAAyD;IACzD,SAAS,YAAY,CAAI,GAAa,EAAE,SAAiB,EAAE,KAA2C;QACpG,MAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC1C,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAYD,MAAM,QAAQ,GAAG,YAAY,CAAU,OAAO,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAC9E,EAAE,CAAC,OAAO,CACR;iCAC2B,EAAE,GAAG,CACjC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAc,CAC7B,CAAC;IAEF,uFAAuF;IACvF,0FAA0F;IAC1F,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,YAAY,CAAU,OAAO,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAC7E,EAAE,CAAC,OAAO,CACT;wCACkC,EAAE,GAAG,CACxC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CACpE,CAAC;IAEF,MAAM,KAAK,GAAoB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChD,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAA+B;QACxC,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE;QACvD,QAAQ,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS;QAClC,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,SAAS;QACpC,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;QAChC,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,SAAS;QACxC,UAAU,EAAE,CAAC,CAAC,WAAW,KAAK,CAAC;QAC/B,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS;QACjC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAA6B,CAAC,CAAC,CAAC,SAAS;KAC7F,CAAC,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAoB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChD,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,QAAQ,EAAE,CAAC,CAAC,SAAS;QACrB,QAAQ,EAAE,CAAC,CAAC,SAAS;QACrB,QAAQ,EAAE,CAAC,CAAC,QAAqC;QACjD,UAAU,EAAE,CAAC,CAAC,UAAyC;QACvD,eAAe,EAAE,CAAC,CAAC,gBAAgB;QACnC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;KAC9B,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"subgraph.js","sourceRoot":"","sources":["../../../src/graph/subgraph.ts"],"names":[],"mappings":"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"}
@@ -14,8 +14,23 @@ export interface TopoSortResult {
14
14
  * Files with no incoming edges on the reverse graph (i.e., no one imports them)
15
15
  * are leaves and appear in level 0.
16
16
  *
17
+ * The in-degree computation is pushed into SQL (GROUP BY aggregation) to avoid
18
+ * materialising the full edge table into JavaScript memory.
19
+ *
17
20
  * @param db - The MonographDb instance
18
21
  * @returns Object with `levels` (array of independent groups, leaf-first) and `cycleCount`.
19
22
  */
20
23
  export declare function topologicalLevelSort(db: MonographDb): TopoSortResult;
24
+ /**
25
+ * Format topological sort levels as structured text.
26
+ *
27
+ * Resolves node IDs to names and file paths so LLMs can navigate directly
28
+ * to the source. Cycle nodes (if any) are clearly labelled.
29
+ *
30
+ * @param db - The MonographDb instance (for name resolution)
31
+ * @param result - Result from topologicalLevelSort()
32
+ * @param maxLevels - Max levels to include in output (default: all)
33
+ * @returns Structured text suitable for injection into LLM context
34
+ */
35
+ export declare function formatTopoSort(db: MonographDb, result: TopoSortResult, maxLevels?: number): string;
21
36
  //# sourceMappingURL=topo-sort.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"topo-sort.d.ts","sourceRoot":"","sources":["../../../src/graph/topo-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B;;kFAE8E;IAC9E,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;IACnB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,GAAG,cAAc,CAgEpE"}
1
+ {"version":3,"file":"topo-sort.d.ts","sourceRoot":"","sources":["../../../src/graph/topo-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B;;kFAE8E;IAC9E,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;IACnB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,GAAG,cAAc,CAyEpE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,cAAc,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAoDR"}
@@ -5,30 +5,46 @@
5
5
  * Files with no incoming edges on the reverse graph (i.e., no one imports them)
6
6
  * are leaves and appear in level 0.
7
7
  *
8
+ * The in-degree computation is pushed into SQL (GROUP BY aggregation) to avoid
9
+ * materialising the full edge table into JavaScript memory.
10
+ *
8
11
  * @param db - The MonographDb instance
9
12
  * @returns Object with `levels` (array of independent groups, leaf-first) and `cycleCount`.
10
13
  */
11
14
  export function topologicalLevelSort(db) {
12
15
  const nodeRows = db.prepare('SELECT id FROM nodes').all();
13
- const edgeRows = db.prepare('SELECT source_id, target_id FROM edges').all();
14
16
  if (nodeRows.length === 0)
15
17
  return { levels: [], cycleCount: 0 };
16
18
  const nodes = nodeRows.map(r => r.id);
17
- // Build reverse graph: original edge src→tgt becomes tgt→src in reverse
18
- // In-degree in the reverse graph = number of nodes that tgt imports (out-degree in original)
19
- const reverseAdj = new Map();
19
+ // Compute in-degree (on the reverse graph) via SQL aggregation.
20
+ // In the original graph each edge src→tgt means "src imports tgt".
21
+ // In the reverse graph the edge becomes tgt→src, so src gains in-degree +1.
22
+ // We aggregate target_id counts grouped by source_id to get reverse-in-degree per node.
23
+ const inDegreeRows = db
24
+ .prepare(`SELECT source_id AS node_id, COUNT(*) AS cnt
25
+ FROM edges
26
+ WHERE source_id != target_id
27
+ GROUP BY source_id`)
28
+ .all();
20
29
  const inDegree = new Map();
21
- for (const n of nodes) {
22
- reverseAdj.set(n, []);
30
+ for (const n of nodes)
23
31
  inDegree.set(n, 0);
32
+ for (const { node_id, cnt } of inDegreeRows) {
33
+ if (inDegree.has(node_id))
34
+ inDegree.set(node_id, cnt);
24
35
  }
36
+ // Build reverse adjacency list — still needed for Kahn's BFS relaxation step.
37
+ // Fetch only what Kahn needs: target_id → [source_id, ...] (reverse direction).
38
+ const reverseAdj = new Map();
39
+ for (const n of nodes)
40
+ reverseAdj.set(n, []);
41
+ const edgeRows = db
42
+ .prepare('SELECT source_id, target_id FROM edges WHERE source_id != target_id')
43
+ .all();
25
44
  for (const { source_id: src, target_id: tgt } of edgeRows) {
26
- if (src === tgt)
27
- continue; // skip self-loops
28
45
  if (!reverseAdj.has(tgt) || !reverseAdj.has(src))
29
46
  continue;
30
47
  reverseAdj.get(tgt).push(src);
31
- inDegree.set(src, (inDegree.get(src) ?? 0) + 1);
32
48
  }
33
49
  // Kahn's BFS on the reverse graph
34
50
  const queue = [];
@@ -39,7 +55,6 @@ export function topologicalLevelSort(db) {
39
55
  const levels = [];
40
56
  const visited = new Set();
41
57
  while (queue.length > 0) {
42
- // All nodes currently at in-degree 0 form one level
43
58
  const level = [...queue];
44
59
  queue.length = 0;
45
60
  levels.push(level);
@@ -64,4 +79,62 @@ export function topologicalLevelSort(db) {
64
79
  }
65
80
  return { levels, cycleCount };
66
81
  }
82
+ // ---------------------------------------------------------------------------
83
+ // Structured text formatter for LLM consumption
84
+ // ---------------------------------------------------------------------------
85
+ /**
86
+ * Format topological sort levels as structured text.
87
+ *
88
+ * Resolves node IDs to names and file paths so LLMs can navigate directly
89
+ * to the source. Cycle nodes (if any) are clearly labelled.
90
+ *
91
+ * @param db - The MonographDb instance (for name resolution)
92
+ * @param result - Result from topologicalLevelSort()
93
+ * @param maxLevels - Max levels to include in output (default: all)
94
+ * @returns Structured text suitable for injection into LLM context
95
+ */
96
+ export function formatTopoSort(db, result, maxLevels) {
97
+ if (result.levels.length === 0) {
98
+ return 'Topological sort: no nodes found.';
99
+ }
100
+ // Batch-resolve all node IDs
101
+ const allIds = result.levels.flat();
102
+ const CHUNK = 200;
103
+ const nodeInfo = new Map();
104
+ for (let i = 0; i < allIds.length; i += CHUNK) {
105
+ const chunk = allIds.slice(i, i + CHUNK);
106
+ const ph = chunk.map(() => '?').join(',');
107
+ const rows = db
108
+ .prepare(`SELECT id, name, file_path FROM nodes WHERE id IN (${ph})`)
109
+ .all(...chunk);
110
+ for (const row of rows) {
111
+ nodeInfo.set(row.id, { name: row.name ?? row.id, filePath: row.file_path });
112
+ }
113
+ }
114
+ const isCycleLevelIdx = result.cycleCount > 0 && result.levels.length > 0
115
+ ? result.levels.length - 1
116
+ : -1;
117
+ const displayLevels = maxLevels !== undefined ? result.levels.slice(0, maxLevels) : result.levels;
118
+ const lines = [
119
+ `Topological sort: ${result.levels.length - (result.cycleCount > 0 ? 1 : 0)} level${result.levels.length === 1 ? '' : 's'}` +
120
+ (result.cycleCount > 0 ? `, ${result.cycleCount} node${result.cycleCount === 1 ? '' : 's'} in cycles` : ''),
121
+ '',
122
+ ];
123
+ for (let li = 0; li < displayLevels.length; li++) {
124
+ const level = displayLevels[li];
125
+ const label = li === isCycleLevelIdx ? 'Cycle nodes (unresolvable order)' : `Level ${li}`;
126
+ lines.push(`${label} (${level.length} node${level.length === 1 ? '' : 's'}):`);
127
+ for (const id of level) {
128
+ const info = nodeInfo.get(id);
129
+ const name = info?.name ?? id;
130
+ const fp = info?.filePath;
131
+ lines.push(` ${name}${fp ? ` — ${fp}` : ''}`);
132
+ }
133
+ lines.push('');
134
+ }
135
+ if (maxLevels !== undefined && result.levels.length > maxLevels) {
136
+ lines.push(`... (${result.levels.length - maxLevels} more level${result.levels.length - maxLevels === 1 ? '' : 's'} omitted)`);
137
+ }
138
+ return lines.join('\n').trimEnd();
139
+ }
67
140
  //# sourceMappingURL=topo-sort.js.map