@zbigniewsobiecki/squint 1.0.0

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 (649) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1065 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.js +5 -0
  5. package/dist/commands/_shared/db-helper.d.ts +18 -0
  6. package/dist/commands/_shared/db-helper.d.ts.map +1 -0
  7. package/dist/commands/_shared/db-helper.js +72 -0
  8. package/dist/commands/_shared/db-helper.js.map +1 -0
  9. package/dist/commands/_shared/flags.d.ts +20 -0
  10. package/dist/commands/_shared/flags.d.ts.map +1 -0
  11. package/dist/commands/_shared/flags.js +38 -0
  12. package/dist/commands/_shared/flags.js.map +1 -0
  13. package/dist/commands/_shared/index.d.ts +6 -0
  14. package/dist/commands/_shared/index.d.ts.map +1 -0
  15. package/dist/commands/_shared/index.js +6 -0
  16. package/dist/commands/_shared/index.js.map +1 -0
  17. package/dist/commands/_shared/output.d.ts +22 -0
  18. package/dist/commands/_shared/output.d.ts.map +1 -0
  19. package/dist/commands/_shared/output.js +36 -0
  20. package/dist/commands/_shared/output.js.map +1 -0
  21. package/dist/commands/_shared/source-reader.d.ts +23 -0
  22. package/dist/commands/_shared/source-reader.d.ts.map +1 -0
  23. package/dist/commands/_shared/source-reader.js +45 -0
  24. package/dist/commands/_shared/source-reader.js.map +1 -0
  25. package/dist/commands/_shared/symbol-resolver.d.ts +35 -0
  26. package/dist/commands/_shared/symbol-resolver.d.ts.map +1 -0
  27. package/dist/commands/_shared/symbol-resolver.js +102 -0
  28. package/dist/commands/_shared/symbol-resolver.js.map +1 -0
  29. package/dist/commands/browse.d.ts +13 -0
  30. package/dist/commands/browse.d.ts.map +1 -0
  31. package/dist/commands/browse.js +106 -0
  32. package/dist/commands/browse.js.map +1 -0
  33. package/dist/commands/domains/create.d.ts +15 -0
  34. package/dist/commands/domains/create.d.ts.map +1 -0
  35. package/dist/commands/domains/create.js +34 -0
  36. package/dist/commands/domains/create.js.map +1 -0
  37. package/dist/commands/domains/delete.d.ts +14 -0
  38. package/dist/commands/domains/delete.d.ts.map +1 -0
  39. package/dist/commands/domains/delete.js +41 -0
  40. package/dist/commands/domains/delete.js.map +1 -0
  41. package/dist/commands/domains/index.d.ts +2 -0
  42. package/dist/commands/domains/index.d.ts.map +1 -0
  43. package/dist/commands/domains/index.js +2 -0
  44. package/dist/commands/domains/index.js.map +1 -0
  45. package/dist/commands/domains/list.d.ts +12 -0
  46. package/dist/commands/domains/list.d.ts.map +1 -0
  47. package/dist/commands/domains/list.js +67 -0
  48. package/dist/commands/domains/list.js.map +1 -0
  49. package/dist/commands/domains/merge.d.ts +14 -0
  50. package/dist/commands/domains/merge.d.ts.map +1 -0
  51. package/dist/commands/domains/merge.js +40 -0
  52. package/dist/commands/domains/merge.js.map +1 -0
  53. package/dist/commands/domains/rename.d.ts +14 -0
  54. package/dist/commands/domains/rename.d.ts.map +1 -0
  55. package/dist/commands/domains/rename.js +33 -0
  56. package/dist/commands/domains/rename.js.map +1 -0
  57. package/dist/commands/domains/show.d.ts +14 -0
  58. package/dist/commands/domains/show.d.ts.map +1 -0
  59. package/dist/commands/domains/show.js +47 -0
  60. package/dist/commands/domains/show.js.map +1 -0
  61. package/dist/commands/domains/sync.d.ts +11 -0
  62. package/dist/commands/domains/sync.d.ts.map +1 -0
  63. package/dist/commands/domains/sync.js +33 -0
  64. package/dist/commands/domains/sync.js.map +1 -0
  65. package/dist/commands/domains/update.d.ts +14 -0
  66. package/dist/commands/domains/update.d.ts.map +1 -0
  67. package/dist/commands/domains/update.js +28 -0
  68. package/dist/commands/domains/update.js.map +1 -0
  69. package/dist/commands/features/assign.d.ts +16 -0
  70. package/dist/commands/features/assign.d.ts.map +1 -0
  71. package/dist/commands/features/assign.js +51 -0
  72. package/dist/commands/features/assign.js.map +1 -0
  73. package/dist/commands/features/create.d.ts +15 -0
  74. package/dist/commands/features/create.d.ts.map +1 -0
  75. package/dist/commands/features/create.js +30 -0
  76. package/dist/commands/features/create.js.map +1 -0
  77. package/dist/commands/features/delete.d.ts +14 -0
  78. package/dist/commands/features/delete.d.ts.map +1 -0
  79. package/dist/commands/features/delete.js +37 -0
  80. package/dist/commands/features/delete.js.map +1 -0
  81. package/dist/commands/features/generate.d.ts +34 -0
  82. package/dist/commands/features/generate.d.ts.map +1 -0
  83. package/dist/commands/features/generate.js +178 -0
  84. package/dist/commands/features/generate.js.map +1 -0
  85. package/dist/commands/features/index.d.ts +2 -0
  86. package/dist/commands/features/index.d.ts.map +1 -0
  87. package/dist/commands/features/index.js +2 -0
  88. package/dist/commands/features/index.js.map +1 -0
  89. package/dist/commands/features/list.d.ts +11 -0
  90. package/dist/commands/features/list.d.ts.map +1 -0
  91. package/dist/commands/features/list.js +45 -0
  92. package/dist/commands/features/list.js.map +1 -0
  93. package/dist/commands/features/show.d.ts +15 -0
  94. package/dist/commands/features/show.d.ts.map +1 -0
  95. package/dist/commands/features/show.js +61 -0
  96. package/dist/commands/features/show.js.map +1 -0
  97. package/dist/commands/features/unassign.d.ts +16 -0
  98. package/dist/commands/features/unassign.d.ts.map +1 -0
  99. package/dist/commands/features/unassign.js +55 -0
  100. package/dist/commands/features/unassign.js.map +1 -0
  101. package/dist/commands/features/update.d.ts +16 -0
  102. package/dist/commands/features/update.d.ts.map +1 -0
  103. package/dist/commands/features/update.js +54 -0
  104. package/dist/commands/features/update.js.map +1 -0
  105. package/dist/commands/files/imported-by.d.ts +13 -0
  106. package/dist/commands/files/imported-by.d.ts.map +1 -0
  107. package/dist/commands/files/imported-by.js +40 -0
  108. package/dist/commands/files/imported-by.js.map +1 -0
  109. package/dist/commands/files/imports.d.ts +14 -0
  110. package/dist/commands/files/imports.d.ts.map +1 -0
  111. package/dist/commands/files/imports.js +48 -0
  112. package/dist/commands/files/imports.js.map +1 -0
  113. package/dist/commands/files/index.d.ts +2 -0
  114. package/dist/commands/files/index.d.ts.map +1 -0
  115. package/dist/commands/files/index.js +2 -0
  116. package/dist/commands/files/index.js.map +1 -0
  117. package/dist/commands/files/list.d.ts +11 -0
  118. package/dist/commands/files/list.d.ts.map +1 -0
  119. package/dist/commands/files/list.js +35 -0
  120. package/dist/commands/files/list.js.map +1 -0
  121. package/dist/commands/files/orphans.d.ts +12 -0
  122. package/dist/commands/files/orphans.d.ts.map +1 -0
  123. package/dist/commands/files/orphans.js +43 -0
  124. package/dist/commands/files/orphans.js.map +1 -0
  125. package/dist/commands/files/show.d.ts +14 -0
  126. package/dist/commands/files/show.d.ts.map +1 -0
  127. package/dist/commands/files/show.js +95 -0
  128. package/dist/commands/files/show.js.map +1 -0
  129. package/dist/commands/flows/add-step.d.ts +19 -0
  130. package/dist/commands/flows/add-step.d.ts.map +1 -0
  131. package/dist/commands/flows/add-step.js +46 -0
  132. package/dist/commands/flows/add-step.js.map +1 -0
  133. package/dist/commands/flows/create.d.ts +17 -0
  134. package/dist/commands/flows/create.d.ts.map +1 -0
  135. package/dist/commands/flows/create.js +39 -0
  136. package/dist/commands/flows/create.js.map +1 -0
  137. package/dist/commands/flows/delete.d.ts +14 -0
  138. package/dist/commands/flows/delete.d.ts.map +1 -0
  139. package/dist/commands/flows/delete.js +37 -0
  140. package/dist/commands/flows/delete.js.map +1 -0
  141. package/dist/commands/flows/generate.d.ts +50 -0
  142. package/dist/commands/flows/generate.d.ts.map +1 -0
  143. package/dist/commands/flows/generate.js +438 -0
  144. package/dist/commands/flows/generate.js.map +1 -0
  145. package/dist/commands/flows/index.d.ts +2 -0
  146. package/dist/commands/flows/index.d.ts.map +1 -0
  147. package/dist/commands/flows/index.js +2 -0
  148. package/dist/commands/flows/index.js.map +1 -0
  149. package/dist/commands/flows/list.d.ts +12 -0
  150. package/dist/commands/flows/list.d.ts.map +1 -0
  151. package/dist/commands/flows/list.js +98 -0
  152. package/dist/commands/flows/list.js.map +1 -0
  153. package/dist/commands/flows/remove-step.d.ts +18 -0
  154. package/dist/commands/flows/remove-step.d.ts.map +1 -0
  155. package/dist/commands/flows/remove-step.js +41 -0
  156. package/dist/commands/flows/remove-step.js.map +1 -0
  157. package/dist/commands/flows/show.d.ts +17 -0
  158. package/dist/commands/flows/show.d.ts.map +1 -0
  159. package/dist/commands/flows/show.js +136 -0
  160. package/dist/commands/flows/show.js.map +1 -0
  161. package/dist/commands/flows/trace.d.ts +22 -0
  162. package/dist/commands/flows/trace.d.ts.map +1 -0
  163. package/dist/commands/flows/trace.js +217 -0
  164. package/dist/commands/flows/trace.js.map +1 -0
  165. package/dist/commands/flows/update.d.ts +17 -0
  166. package/dist/commands/flows/update.d.ts.map +1 -0
  167. package/dist/commands/flows/update.js +60 -0
  168. package/dist/commands/flows/update.js.map +1 -0
  169. package/dist/commands/flows/verify.d.ts +21 -0
  170. package/dist/commands/flows/verify.d.ts.map +1 -0
  171. package/dist/commands/flows/verify.js +123 -0
  172. package/dist/commands/flows/verify.js.map +1 -0
  173. package/dist/commands/gaps.d.ts +14 -0
  174. package/dist/commands/gaps.d.ts.map +1 -0
  175. package/dist/commands/gaps.js +184 -0
  176. package/dist/commands/gaps.js.map +1 -0
  177. package/dist/commands/hierarchy/index.d.ts +20 -0
  178. package/dist/commands/hierarchy/index.d.ts.map +1 -0
  179. package/dist/commands/hierarchy/index.js +344 -0
  180. package/dist/commands/hierarchy/index.js.map +1 -0
  181. package/dist/commands/ingest.d.ts +23 -0
  182. package/dist/commands/ingest.d.ts.map +1 -0
  183. package/dist/commands/ingest.js +249 -0
  184. package/dist/commands/ingest.js.map +1 -0
  185. package/dist/commands/interactions/create.d.ts +16 -0
  186. package/dist/commands/interactions/create.d.ts.map +1 -0
  187. package/dist/commands/interactions/create.js +58 -0
  188. package/dist/commands/interactions/create.js.map +1 -0
  189. package/dist/commands/interactions/delete.d.ts +16 -0
  190. package/dist/commands/interactions/delete.d.ts.map +1 -0
  191. package/dist/commands/interactions/delete.js +28 -0
  192. package/dist/commands/interactions/delete.js.map +1 -0
  193. package/dist/commands/interactions/generate.d.ts +62 -0
  194. package/dist/commands/interactions/generate.d.ts.map +1 -0
  195. package/dist/commands/interactions/generate.js +870 -0
  196. package/dist/commands/interactions/generate.js.map +1 -0
  197. package/dist/commands/interactions/index.d.ts +2 -0
  198. package/dist/commands/interactions/index.d.ts.map +1 -0
  199. package/dist/commands/interactions/index.js +2 -0
  200. package/dist/commands/interactions/index.js.map +1 -0
  201. package/dist/commands/interactions/list.d.ts +15 -0
  202. package/dist/commands/interactions/list.d.ts.map +1 -0
  203. package/dist/commands/interactions/list.js +127 -0
  204. package/dist/commands/interactions/list.js.map +1 -0
  205. package/dist/commands/interactions/show.d.ts +17 -0
  206. package/dist/commands/interactions/show.d.ts.map +1 -0
  207. package/dist/commands/interactions/show.js +80 -0
  208. package/dist/commands/interactions/show.js.map +1 -0
  209. package/dist/commands/interactions/update.d.ts +20 -0
  210. package/dist/commands/interactions/update.d.ts.map +1 -0
  211. package/dist/commands/interactions/update.js +57 -0
  212. package/dist/commands/interactions/update.js.map +1 -0
  213. package/dist/commands/interactions/validate.d.ts +12 -0
  214. package/dist/commands/interactions/validate.d.ts.map +1 -0
  215. package/dist/commands/interactions/validate.js +94 -0
  216. package/dist/commands/interactions/validate.js.map +1 -0
  217. package/dist/commands/interactions/verify.d.ts +18 -0
  218. package/dist/commands/interactions/verify.d.ts.map +1 -0
  219. package/dist/commands/interactions/verify.js +127 -0
  220. package/dist/commands/interactions/verify.js.map +1 -0
  221. package/dist/commands/llm/_shared/base-llm-command.d.ts +44 -0
  222. package/dist/commands/llm/_shared/base-llm-command.d.ts.map +1 -0
  223. package/dist/commands/llm/_shared/base-llm-command.js +73 -0
  224. package/dist/commands/llm/_shared/base-llm-command.js.map +1 -0
  225. package/dist/commands/llm/_shared/coverage.d.ts +61 -0
  226. package/dist/commands/llm/_shared/coverage.d.ts.map +1 -0
  227. package/dist/commands/llm/_shared/coverage.js +161 -0
  228. package/dist/commands/llm/_shared/coverage.js.map +1 -0
  229. package/dist/commands/llm/_shared/csv-utils.d.ts +65 -0
  230. package/dist/commands/llm/_shared/csv-utils.d.ts.map +1 -0
  231. package/dist/commands/llm/_shared/csv-utils.js +231 -0
  232. package/dist/commands/llm/_shared/csv-utils.js.map +1 -0
  233. package/dist/commands/llm/_shared/csv.d.ts +44 -0
  234. package/dist/commands/llm/_shared/csv.d.ts.map +1 -0
  235. package/dist/commands/llm/_shared/csv.js +76 -0
  236. package/dist/commands/llm/_shared/csv.js.map +1 -0
  237. package/dist/commands/llm/_shared/entity-utils.d.ts +11 -0
  238. package/dist/commands/llm/_shared/entity-utils.d.ts.map +1 -0
  239. package/dist/commands/llm/_shared/entity-utils.js +87 -0
  240. package/dist/commands/llm/_shared/entity-utils.js.map +1 -0
  241. package/dist/commands/llm/_shared/flow-csv.d.ts +74 -0
  242. package/dist/commands/llm/_shared/flow-csv.d.ts.map +1 -0
  243. package/dist/commands/llm/_shared/flow-csv.js +198 -0
  244. package/dist/commands/llm/_shared/flow-csv.js.map +1 -0
  245. package/dist/commands/llm/_shared/flow-prompts.d.ts +61 -0
  246. package/dist/commands/llm/_shared/flow-prompts.d.ts.map +1 -0
  247. package/dist/commands/llm/_shared/flow-prompts.js +281 -0
  248. package/dist/commands/llm/_shared/flow-prompts.js.map +1 -0
  249. package/dist/commands/llm/_shared/flow-validation.d.ts +69 -0
  250. package/dist/commands/llm/_shared/flow-validation.d.ts.map +1 -0
  251. package/dist/commands/llm/_shared/flow-validation.js +176 -0
  252. package/dist/commands/llm/_shared/flow-validation.js.map +1 -0
  253. package/dist/commands/llm/_shared/llm-utils.d.ts +88 -0
  254. package/dist/commands/llm/_shared/llm-utils.d.ts.map +1 -0
  255. package/dist/commands/llm/_shared/llm-utils.js +256 -0
  256. package/dist/commands/llm/_shared/llm-utils.js.map +1 -0
  257. package/dist/commands/llm/_shared/module-csv.d.ts +76 -0
  258. package/dist/commands/llm/_shared/module-csv.d.ts.map +1 -0
  259. package/dist/commands/llm/_shared/module-csv.js +196 -0
  260. package/dist/commands/llm/_shared/module-csv.js.map +1 -0
  261. package/dist/commands/llm/_shared/module-prompts.d.ts +107 -0
  262. package/dist/commands/llm/_shared/module-prompts.d.ts.map +1 -0
  263. package/dist/commands/llm/_shared/module-prompts.js +395 -0
  264. package/dist/commands/llm/_shared/module-prompts.js.map +1 -0
  265. package/dist/commands/llm/_shared/process-utils.d.ts +52 -0
  266. package/dist/commands/llm/_shared/process-utils.d.ts.map +1 -0
  267. package/dist/commands/llm/_shared/process-utils.js +214 -0
  268. package/dist/commands/llm/_shared/process-utils.js.map +1 -0
  269. package/dist/commands/llm/_shared/prompts.d.ts +132 -0
  270. package/dist/commands/llm/_shared/prompts.d.ts.map +1 -0
  271. package/dist/commands/llm/_shared/prompts.js +391 -0
  272. package/dist/commands/llm/_shared/prompts.js.map +1 -0
  273. package/dist/commands/llm/_shared/pure-check.d.ts +10 -0
  274. package/dist/commands/llm/_shared/pure-check.d.ts.map +1 -0
  275. package/dist/commands/llm/_shared/pure-check.js +449 -0
  276. package/dist/commands/llm/_shared/pure-check.js.map +1 -0
  277. package/dist/commands/llm/_shared/verify/content-verifier.d.ts +40 -0
  278. package/dist/commands/llm/_shared/verify/content-verifier.d.ts.map +1 -0
  279. package/dist/commands/llm/_shared/verify/content-verifier.js +247 -0
  280. package/dist/commands/llm/_shared/verify/content-verifier.js.map +1 -0
  281. package/dist/commands/llm/_shared/verify/coverage-checker.d.ts +34 -0
  282. package/dist/commands/llm/_shared/verify/coverage-checker.d.ts.map +1 -0
  283. package/dist/commands/llm/_shared/verify/coverage-checker.js +1096 -0
  284. package/dist/commands/llm/_shared/verify/coverage-checker.js.map +1 -0
  285. package/dist/commands/llm/_shared/verify/verify-prompts.d.ts +30 -0
  286. package/dist/commands/llm/_shared/verify/verify-prompts.d.ts.map +1 -0
  287. package/dist/commands/llm/_shared/verify/verify-prompts.js +118 -0
  288. package/dist/commands/llm/_shared/verify/verify-prompts.js.map +1 -0
  289. package/dist/commands/llm/_shared/verify/verify-types.d.ts +47 -0
  290. package/dist/commands/llm/_shared/verify/verify-types.d.ts.map +1 -0
  291. package/dist/commands/llm/_shared/verify/verify-types.js +2 -0
  292. package/dist/commands/llm/_shared/verify/verify-types.js.map +1 -0
  293. package/dist/commands/llm/annotate.d.ts +7 -0
  294. package/dist/commands/llm/annotate.d.ts.map +1 -0
  295. package/dist/commands/llm/annotate.js +11 -0
  296. package/dist/commands/llm/annotate.js.map +1 -0
  297. package/dist/commands/llm/features/feature-grouper.d.ts +31 -0
  298. package/dist/commands/llm/features/feature-grouper.d.ts.map +1 -0
  299. package/dist/commands/llm/features/feature-grouper.js +223 -0
  300. package/dist/commands/llm/features/feature-grouper.js.map +1 -0
  301. package/dist/commands/llm/features/index.d.ts +6 -0
  302. package/dist/commands/llm/features/index.d.ts.map +1 -0
  303. package/dist/commands/llm/features/index.js +6 -0
  304. package/dist/commands/llm/features/index.js.map +1 -0
  305. package/dist/commands/llm/features/types.d.ts +10 -0
  306. package/dist/commands/llm/features/types.d.ts.map +1 -0
  307. package/dist/commands/llm/features/types.js +5 -0
  308. package/dist/commands/llm/features/types.js.map +1 -0
  309. package/dist/commands/llm/features.d.ts +7 -0
  310. package/dist/commands/llm/features.d.ts.map +1 -0
  311. package/dist/commands/llm/features.js +11 -0
  312. package/dist/commands/llm/features.js.map +1 -0
  313. package/dist/commands/llm/flows/atomic-flow-builder.d.ts +51 -0
  314. package/dist/commands/llm/flows/atomic-flow-builder.d.ts.map +1 -0
  315. package/dist/commands/llm/flows/atomic-flow-builder.js +247 -0
  316. package/dist/commands/llm/flows/atomic-flow-builder.js.map +1 -0
  317. package/dist/commands/llm/flows/dedup.d.ts +18 -0
  318. package/dist/commands/llm/flows/dedup.d.ts.map +1 -0
  319. package/dist/commands/llm/flows/dedup.js +76 -0
  320. package/dist/commands/llm/flows/dedup.js.map +1 -0
  321. package/dist/commands/llm/flows/entry-point-detector.d.ts +41 -0
  322. package/dist/commands/llm/flows/entry-point-detector.d.ts.map +1 -0
  323. package/dist/commands/llm/flows/entry-point-detector.js +388 -0
  324. package/dist/commands/llm/flows/entry-point-detector.js.map +1 -0
  325. package/dist/commands/llm/flows/flow-enhancer.d.ts +21 -0
  326. package/dist/commands/llm/flows/flow-enhancer.d.ts.map +1 -0
  327. package/dist/commands/llm/flows/flow-enhancer.js +166 -0
  328. package/dist/commands/llm/flows/flow-enhancer.js.map +1 -0
  329. package/dist/commands/llm/flows/flow-tracer.d.ts +50 -0
  330. package/dist/commands/llm/flows/flow-tracer.d.ts.map +1 -0
  331. package/dist/commands/llm/flows/flow-tracer.js +271 -0
  332. package/dist/commands/llm/flows/flow-tracer.js.map +1 -0
  333. package/dist/commands/llm/flows/flow-validator.d.ts +31 -0
  334. package/dist/commands/llm/flows/flow-validator.d.ts.map +1 -0
  335. package/dist/commands/llm/flows/flow-validator.js +262 -0
  336. package/dist/commands/llm/flows/flow-validator.js.map +1 -0
  337. package/dist/commands/llm/flows/gap-flow-generator.d.ts +13 -0
  338. package/dist/commands/llm/flows/gap-flow-generator.d.ts.map +1 -0
  339. package/dist/commands/llm/flows/gap-flow-generator.js +48 -0
  340. package/dist/commands/llm/flows/gap-flow-generator.js.map +1 -0
  341. package/dist/commands/llm/flows/index.d.ts +12 -0
  342. package/dist/commands/llm/flows/index.d.ts.map +1 -0
  343. package/dist/commands/llm/flows/index.js +12 -0
  344. package/dist/commands/llm/flows/index.js.map +1 -0
  345. package/dist/commands/llm/flows/types.d.ts +87 -0
  346. package/dist/commands/llm/flows/types.d.ts.map +1 -0
  347. package/dist/commands/llm/flows/types.js +5 -0
  348. package/dist/commands/llm/flows/types.js.map +1 -0
  349. package/dist/commands/llm/flows.d.ts +7 -0
  350. package/dist/commands/llm/flows.d.ts.map +1 -0
  351. package/dist/commands/llm/flows.js +11 -0
  352. package/dist/commands/llm/flows.js.map +1 -0
  353. package/dist/commands/llm/interactions.d.ts +7 -0
  354. package/dist/commands/llm/interactions.d.ts.map +1 -0
  355. package/dist/commands/llm/interactions.js +11 -0
  356. package/dist/commands/llm/interactions.js.map +1 -0
  357. package/dist/commands/llm/modules.d.ts +7 -0
  358. package/dist/commands/llm/modules.d.ts.map +1 -0
  359. package/dist/commands/llm/modules.js +11 -0
  360. package/dist/commands/llm/modules.js.map +1 -0
  361. package/dist/commands/llm/relationships.d.ts +7 -0
  362. package/dist/commands/llm/relationships.d.ts.map +1 -0
  363. package/dist/commands/llm/relationships.js +11 -0
  364. package/dist/commands/llm/relationships.js.map +1 -0
  365. package/dist/commands/modules/assign.d.ts +14 -0
  366. package/dist/commands/modules/assign.d.ts.map +1 -0
  367. package/dist/commands/modules/assign.js +54 -0
  368. package/dist/commands/modules/assign.js.map +1 -0
  369. package/dist/commands/modules/create.d.ts +16 -0
  370. package/dist/commands/modules/create.d.ts.map +1 -0
  371. package/dist/commands/modules/create.js +37 -0
  372. package/dist/commands/modules/create.js.map +1 -0
  373. package/dist/commands/modules/delete.d.ts +14 -0
  374. package/dist/commands/modules/delete.d.ts.map +1 -0
  375. package/dist/commands/modules/delete.js +54 -0
  376. package/dist/commands/modules/delete.js.map +1 -0
  377. package/dist/commands/modules/generate.d.ts +84 -0
  378. package/dist/commands/modules/generate.d.ts.map +1 -0
  379. package/dist/commands/modules/generate.js +1234 -0
  380. package/dist/commands/modules/generate.js.map +1 -0
  381. package/dist/commands/modules/index.d.ts +2 -0
  382. package/dist/commands/modules/index.d.ts.map +1 -0
  383. package/dist/commands/modules/index.js +2 -0
  384. package/dist/commands/modules/index.js.map +1 -0
  385. package/dist/commands/modules/list.d.ts +13 -0
  386. package/dist/commands/modules/list.d.ts.map +1 -0
  387. package/dist/commands/modules/list.js +92 -0
  388. package/dist/commands/modules/list.js.map +1 -0
  389. package/dist/commands/modules/prune.d.ts +10 -0
  390. package/dist/commands/modules/prune.d.ts.map +1 -0
  391. package/dist/commands/modules/prune.js +23 -0
  392. package/dist/commands/modules/prune.js.map +1 -0
  393. package/dist/commands/modules/show.d.ts +15 -0
  394. package/dist/commands/modules/show.d.ts.map +1 -0
  395. package/dist/commands/modules/show.js +95 -0
  396. package/dist/commands/modules/show.js.map +1 -0
  397. package/dist/commands/modules/unassign.d.ts +13 -0
  398. package/dist/commands/modules/unassign.d.ts.map +1 -0
  399. package/dist/commands/modules/unassign.js +49 -0
  400. package/dist/commands/modules/unassign.js.map +1 -0
  401. package/dist/commands/modules/update.d.ts +15 -0
  402. package/dist/commands/modules/update.d.ts.map +1 -0
  403. package/dist/commands/modules/update.js +50 -0
  404. package/dist/commands/modules/update.js.map +1 -0
  405. package/dist/commands/modules/verify.d.ts +18 -0
  406. package/dist/commands/modules/verify.d.ts.map +1 -0
  407. package/dist/commands/modules/verify.js +114 -0
  408. package/dist/commands/modules/verify.js.map +1 -0
  409. package/dist/commands/overview.d.ts +12 -0
  410. package/dist/commands/overview.d.ts.map +1 -0
  411. package/dist/commands/overview.js +219 -0
  412. package/dist/commands/overview.js.map +1 -0
  413. package/dist/commands/parse.d.ts +30 -0
  414. package/dist/commands/parse.d.ts.map +1 -0
  415. package/dist/commands/parse.js +211 -0
  416. package/dist/commands/parse.js.map +1 -0
  417. package/dist/commands/process-groups/index.d.ts +2 -0
  418. package/dist/commands/process-groups/index.d.ts.map +1 -0
  419. package/dist/commands/process-groups/index.js +2 -0
  420. package/dist/commands/process-groups/index.js.map +1 -0
  421. package/dist/commands/process-groups/list.d.ts +11 -0
  422. package/dist/commands/process-groups/list.d.ts.map +1 -0
  423. package/dist/commands/process-groups/list.js +98 -0
  424. package/dist/commands/process-groups/list.js.map +1 -0
  425. package/dist/commands/relationships/annotate.d.ts +27 -0
  426. package/dist/commands/relationships/annotate.d.ts.map +1 -0
  427. package/dist/commands/relationships/annotate.js +453 -0
  428. package/dist/commands/relationships/annotate.js.map +1 -0
  429. package/dist/commands/relationships/index.d.ts +2 -0
  430. package/dist/commands/relationships/index.d.ts.map +1 -0
  431. package/dist/commands/relationships/index.js +2 -0
  432. package/dist/commands/relationships/index.js.map +1 -0
  433. package/dist/commands/relationships/list.d.ts +18 -0
  434. package/dist/commands/relationships/list.d.ts.map +1 -0
  435. package/dist/commands/relationships/list.js +147 -0
  436. package/dist/commands/relationships/list.js.map +1 -0
  437. package/dist/commands/relationships/next.d.ts +17 -0
  438. package/dist/commands/relationships/next.d.ts.map +1 -0
  439. package/dist/commands/relationships/next.js +178 -0
  440. package/dist/commands/relationships/next.js.map +1 -0
  441. package/dist/commands/relationships/set.d.ts +19 -0
  442. package/dist/commands/relationships/set.d.ts.map +1 -0
  443. package/dist/commands/relationships/set.js +65 -0
  444. package/dist/commands/relationships/set.js.map +1 -0
  445. package/dist/commands/relationships/show.d.ts +13 -0
  446. package/dist/commands/relationships/show.d.ts.map +1 -0
  447. package/dist/commands/relationships/show.js +59 -0
  448. package/dist/commands/relationships/show.js.map +1 -0
  449. package/dist/commands/relationships/unset.d.ts +16 -0
  450. package/dist/commands/relationships/unset.d.ts.map +1 -0
  451. package/dist/commands/relationships/unset.js +62 -0
  452. package/dist/commands/relationships/unset.js.map +1 -0
  453. package/dist/commands/relationships/verify.d.ts +24 -0
  454. package/dist/commands/relationships/verify.d.ts.map +1 -0
  455. package/dist/commands/relationships/verify.js +328 -0
  456. package/dist/commands/relationships/verify.js.map +1 -0
  457. package/dist/commands/stats.d.ts +11 -0
  458. package/dist/commands/stats.d.ts.map +1 -0
  459. package/dist/commands/stats.js +207 -0
  460. package/dist/commands/stats.js.map +1 -0
  461. package/dist/commands/symbols/annotate.d.ts +32 -0
  462. package/dist/commands/symbols/annotate.d.ts.map +1 -0
  463. package/dist/commands/symbols/annotate.js +862 -0
  464. package/dist/commands/symbols/annotate.js.map +1 -0
  465. package/dist/commands/symbols/deps.d.ts +18 -0
  466. package/dist/commands/symbols/deps.d.ts.map +1 -0
  467. package/dist/commands/symbols/deps.js +104 -0
  468. package/dist/commands/symbols/deps.js.map +1 -0
  469. package/dist/commands/symbols/index.d.ts +2 -0
  470. package/dist/commands/symbols/index.d.ts.map +1 -0
  471. package/dist/commands/symbols/index.js +2 -0
  472. package/dist/commands/symbols/index.js.map +1 -0
  473. package/dist/commands/symbols/list.d.ts +17 -0
  474. package/dist/commands/symbols/list.d.ts.map +1 -0
  475. package/dist/commands/symbols/list.js +136 -0
  476. package/dist/commands/symbols/list.js.map +1 -0
  477. package/dist/commands/symbols/next.d.ts +15 -0
  478. package/dist/commands/symbols/next.d.ts.map +1 -0
  479. package/dist/commands/symbols/next.js +147 -0
  480. package/dist/commands/symbols/next.js.map +1 -0
  481. package/dist/commands/symbols/prereqs.d.ts +18 -0
  482. package/dist/commands/symbols/prereqs.d.ts.map +1 -0
  483. package/dist/commands/symbols/prereqs.js +107 -0
  484. package/dist/commands/symbols/prereqs.js.map +1 -0
  485. package/dist/commands/symbols/ready.d.ts +17 -0
  486. package/dist/commands/symbols/ready.d.ts.map +1 -0
  487. package/dist/commands/symbols/ready.js +126 -0
  488. package/dist/commands/symbols/ready.js.map +1 -0
  489. package/dist/commands/symbols/set.d.ts +27 -0
  490. package/dist/commands/symbols/set.d.ts.map +1 -0
  491. package/dist/commands/symbols/set.js +241 -0
  492. package/dist/commands/symbols/set.js.map +1 -0
  493. package/dist/commands/symbols/show.d.ts +19 -0
  494. package/dist/commands/symbols/show.d.ts.map +1 -0
  495. package/dist/commands/symbols/show.js +182 -0
  496. package/dist/commands/symbols/show.js.map +1 -0
  497. package/dist/commands/symbols/understood.d.ts +15 -0
  498. package/dist/commands/symbols/understood.d.ts.map +1 -0
  499. package/dist/commands/symbols/understood.js +101 -0
  500. package/dist/commands/symbols/understood.js.map +1 -0
  501. package/dist/commands/symbols/unset.d.ts +16 -0
  502. package/dist/commands/symbols/unset.d.ts.map +1 -0
  503. package/dist/commands/symbols/unset.js +48 -0
  504. package/dist/commands/symbols/unset.js.map +1 -0
  505. package/dist/commands/symbols/verify.d.ts +25 -0
  506. package/dist/commands/symbols/verify.d.ts.map +1 -0
  507. package/dist/commands/symbols/verify.js +360 -0
  508. package/dist/commands/symbols/verify.js.map +1 -0
  509. package/dist/db/connection.d.ts +14 -0
  510. package/dist/db/connection.d.ts.map +1 -0
  511. package/dist/db/connection.js +37 -0
  512. package/dist/db/connection.js.map +1 -0
  513. package/dist/db/database-facade.d.ts +125 -0
  514. package/dist/db/database-facade.d.ts.map +1 -0
  515. package/dist/db/database-facade.js +347 -0
  516. package/dist/db/database-facade.js.map +1 -0
  517. package/dist/db/database.d.ts +9 -0
  518. package/dist/db/database.d.ts.map +1 -0
  519. package/dist/db/database.js +11 -0
  520. package/dist/db/database.js.map +1 -0
  521. package/dist/db/index.d.ts +7 -0
  522. package/dist/db/index.d.ts.map +1 -0
  523. package/dist/db/index.js +11 -0
  524. package/dist/db/index.js.map +1 -0
  525. package/dist/db/repositories/_shared/call-graph-query.d.ts +10 -0
  526. package/dist/db/repositories/_shared/call-graph-query.d.ts.map +1 -0
  527. package/dist/db/repositories/_shared/call-graph-query.js +59 -0
  528. package/dist/db/repositories/_shared/call-graph-query.js.map +1 -0
  529. package/dist/db/repositories/call-graph-service.d.ts +28 -0
  530. package/dist/db/repositories/call-graph-service.d.ts.map +1 -0
  531. package/dist/db/repositories/call-graph-service.js +223 -0
  532. package/dist/db/repositories/call-graph-service.js.map +1 -0
  533. package/dist/db/repositories/definition-repository.d.ts +99 -0
  534. package/dist/db/repositories/definition-repository.d.ts.map +1 -0
  535. package/dist/db/repositories/definition-repository.js +317 -0
  536. package/dist/db/repositories/definition-repository.js.map +1 -0
  537. package/dist/db/repositories/dependency-repository.d.ts +78 -0
  538. package/dist/db/repositories/dependency-repository.d.ts.map +1 -0
  539. package/dist/db/repositories/dependency-repository.js +446 -0
  540. package/dist/db/repositories/dependency-repository.js.map +1 -0
  541. package/dist/db/repositories/domain-repository.d.ts +97 -0
  542. package/dist/db/repositories/domain-repository.d.ts.map +1 -0
  543. package/dist/db/repositories/domain-repository.js +261 -0
  544. package/dist/db/repositories/domain-repository.js.map +1 -0
  545. package/dist/db/repositories/feature-repository.d.ts +64 -0
  546. package/dist/db/repositories/feature-repository.d.ts.map +1 -0
  547. package/dist/db/repositories/feature-repository.js +189 -0
  548. package/dist/db/repositories/feature-repository.js.map +1 -0
  549. package/dist/db/repositories/file-repository.d.ts +67 -0
  550. package/dist/db/repositories/file-repository.d.ts.map +1 -0
  551. package/dist/db/repositories/file-repository.js +179 -0
  552. package/dist/db/repositories/file-repository.js.map +1 -0
  553. package/dist/db/repositories/flow-repository.d.ts +172 -0
  554. package/dist/db/repositories/flow-repository.d.ts.map +1 -0
  555. package/dist/db/repositories/flow-repository.js +599 -0
  556. package/dist/db/repositories/flow-repository.js.map +1 -0
  557. package/dist/db/repositories/graph-repository.d.ts +93 -0
  558. package/dist/db/repositories/graph-repository.d.ts.map +1 -0
  559. package/dist/db/repositories/graph-repository.js +413 -0
  560. package/dist/db/repositories/graph-repository.js.map +1 -0
  561. package/dist/db/repositories/index.d.ts +20 -0
  562. package/dist/db/repositories/index.d.ts.map +1 -0
  563. package/dist/db/repositories/index.js +15 -0
  564. package/dist/db/repositories/index.js.map +1 -0
  565. package/dist/db/repositories/interaction-analysis.d.ts +78 -0
  566. package/dist/db/repositories/interaction-analysis.d.ts.map +1 -0
  567. package/dist/db/repositories/interaction-analysis.js +340 -0
  568. package/dist/db/repositories/interaction-analysis.js.map +1 -0
  569. package/dist/db/repositories/interaction-repository.d.ts +145 -0
  570. package/dist/db/repositories/interaction-repository.d.ts.map +1 -0
  571. package/dist/db/repositories/interaction-repository.js +395 -0
  572. package/dist/db/repositories/interaction-repository.js.map +1 -0
  573. package/dist/db/repositories/metadata-repository.d.ts +110 -0
  574. package/dist/db/repositories/metadata-repository.d.ts.map +1 -0
  575. package/dist/db/repositories/metadata-repository.js +294 -0
  576. package/dist/db/repositories/metadata-repository.js.map +1 -0
  577. package/dist/db/repositories/module-repository.d.ts +162 -0
  578. package/dist/db/repositories/module-repository.d.ts.map +1 -0
  579. package/dist/db/repositories/module-repository.js +519 -0
  580. package/dist/db/repositories/module-repository.js.map +1 -0
  581. package/dist/db/repositories/relationship-repository.d.ts +98 -0
  582. package/dist/db/repositories/relationship-repository.d.ts.map +1 -0
  583. package/dist/db/repositories/relationship-repository.js +421 -0
  584. package/dist/db/repositories/relationship-repository.js.map +1 -0
  585. package/dist/db/schema-manager.d.ts +31 -0
  586. package/dist/db/schema-manager.d.ts.map +1 -0
  587. package/dist/db/schema-manager.js +398 -0
  588. package/dist/db/schema-manager.js.map +1 -0
  589. package/dist/db/schema.d.ts +404 -0
  590. package/dist/db/schema.d.ts.map +1 -0
  591. package/dist/db/schema.js +234 -0
  592. package/dist/db/schema.js.map +1 -0
  593. package/dist/db/utils/tree-builder.d.ts +25 -0
  594. package/dist/db/utils/tree-builder.d.ts.map +1 -0
  595. package/dist/db/utils/tree-builder.js +38 -0
  596. package/dist/db/utils/tree-builder.js.map +1 -0
  597. package/dist/index.d.ts +2 -0
  598. package/dist/index.d.ts.map +1 -0
  599. package/dist/index.js +2 -0
  600. package/dist/index.js.map +1 -0
  601. package/dist/parser/ast-parser.d.ts +23 -0
  602. package/dist/parser/ast-parser.d.ts.map +1 -0
  603. package/dist/parser/ast-parser.js +65 -0
  604. package/dist/parser/ast-parser.js.map +1 -0
  605. package/dist/parser/definition-extractor.d.ts +29 -0
  606. package/dist/parser/definition-extractor.d.ts.map +1 -0
  607. package/dist/parser/definition-extractor.js +379 -0
  608. package/dist/parser/definition-extractor.js.map +1 -0
  609. package/dist/parser/reference-extractor.d.ts +72 -0
  610. package/dist/parser/reference-extractor.d.ts.map +1 -0
  611. package/dist/parser/reference-extractor.js +759 -0
  612. package/dist/parser/reference-extractor.js.map +1 -0
  613. package/dist/utils/file-scanner.d.ts +6 -0
  614. package/dist/utils/file-scanner.d.ts.map +1 -0
  615. package/dist/utils/file-scanner.js +33 -0
  616. package/dist/utils/file-scanner.js.map +1 -0
  617. package/dist/web/api-transforms.d.ts +4 -0
  618. package/dist/web/api-transforms.d.ts.map +1 -0
  619. package/dist/web/api-transforms.js +4 -0
  620. package/dist/web/api-transforms.js.map +1 -0
  621. package/dist/web/server.d.ts +16 -0
  622. package/dist/web/server.d.ts.map +1 -0
  623. package/dist/web/server.js +229 -0
  624. package/dist/web/server.js.map +1 -0
  625. package/dist/web/server.test.d.ts +2 -0
  626. package/dist/web/server.test.d.ts.map +1 -0
  627. package/dist/web/server.test.js +505 -0
  628. package/dist/web/server.test.js.map +1 -0
  629. package/dist/web/transforms/flow-transforms.d.ts +117 -0
  630. package/dist/web/transforms/flow-transforms.d.ts.map +1 -0
  631. package/dist/web/transforms/flow-transforms.js +202 -0
  632. package/dist/web/transforms/flow-transforms.js.map +1 -0
  633. package/dist/web/transforms/index.d.ts +4 -0
  634. package/dist/web/transforms/index.d.ts.map +1 -0
  635. package/dist/web/transforms/index.js +4 -0
  636. package/dist/web/transforms/index.js.map +1 -0
  637. package/dist/web/transforms/module-transforms.d.ts +42 -0
  638. package/dist/web/transforms/module-transforms.d.ts.map +1 -0
  639. package/dist/web/transforms/module-transforms.js +64 -0
  640. package/dist/web/transforms/module-transforms.js.map +1 -0
  641. package/dist/web/transforms/symbol-transforms.d.ts +31 -0
  642. package/dist/web/transforms/symbol-transforms.d.ts.map +1 -0
  643. package/dist/web/transforms/symbol-transforms.js +95 -0
  644. package/dist/web/transforms/symbol-transforms.js.map +1 -0
  645. package/package.json +96 -0
  646. package/ui/dist/assets/index-DP3dRMlh.js +268 -0
  647. package/ui/dist/assets/index-DP3dRMlh.js.map +1 -0
  648. package/ui/dist/assets/index-Db204Xn1.css +1 -0
  649. package/ui/dist/index.html +67 -0
@@ -0,0 +1,1096 @@
1
+ /**
2
+ * Phase 1: Deterministic coverage and structural checks (no LLM required).
3
+ */
4
+ import fs from 'node:fs';
5
+ import { isTestFile } from '../module-prompts.js';
6
+ import { detectImpurePatterns } from '../pure-check.js';
7
+ /**
8
+ * Read source lines from a file synchronously (for use in non-async verification).
9
+ */
10
+ function readSourceSync(filePath, startLine, endLine) {
11
+ try {
12
+ const content = fs.readFileSync(filePath, 'utf-8');
13
+ const lines = content.split('\n');
14
+ return lines.slice(startLine - 1, endLine).join('\n');
15
+ }
16
+ catch {
17
+ return '';
18
+ }
19
+ }
20
+ /**
21
+ * Check annotation coverage for the given aspects.
22
+ * Reports missing annotations as issues.
23
+ */
24
+ export function checkAnnotationCoverage(db, aspects) {
25
+ const issues = [];
26
+ let missingCount = 0;
27
+ const totalDefinitions = db.definitions.getCount();
28
+ let annotatedDefinitions = totalDefinitions;
29
+ for (const aspect of aspects) {
30
+ const missingIds = db.metadata.getDefinitionsWithout(aspect);
31
+ if (missingIds.length > 0) {
32
+ annotatedDefinitions = Math.min(annotatedDefinitions, totalDefinitions - missingIds.length);
33
+ missingCount += missingIds.length;
34
+ // Report first 50 missing as individual issues
35
+ for (const defId of missingIds.slice(0, 50)) {
36
+ const def = db.definitions.getById(defId);
37
+ if (def) {
38
+ issues.push({
39
+ definitionId: defId,
40
+ definitionName: def.name,
41
+ filePath: def.filePath,
42
+ line: def.line,
43
+ severity: 'error',
44
+ category: 'missing-annotation',
45
+ message: `Missing '${aspect}' annotation`,
46
+ });
47
+ }
48
+ }
49
+ if (missingIds.length > 50) {
50
+ issues.push({
51
+ severity: 'info',
52
+ category: 'missing-annotation',
53
+ message: `... and ${missingIds.length - 50} more definitions missing '${aspect}'`,
54
+ });
55
+ }
56
+ }
57
+ }
58
+ // Check for suspicious pure:true annotations
59
+ if (aspects.includes('pure')) {
60
+ const pureIssues = checkPureAnnotations(db);
61
+ issues.push(...pureIssues);
62
+ }
63
+ // Check for inconsistent domain tags across same-named definitions
64
+ if (aspects.includes('domain')) {
65
+ const domainIssues = checkDomainConsistency(db);
66
+ issues.push(...domainIssues);
67
+ }
68
+ // Get relationship counts
69
+ let totalRelationships = 0;
70
+ let annotatedRelationships = 0;
71
+ try {
72
+ annotatedRelationships = db.relationships.getCount();
73
+ const unannotated = db.relationships.getUnannotatedCount();
74
+ totalRelationships = annotatedRelationships + unannotated;
75
+ }
76
+ catch {
77
+ // Table doesn't exist
78
+ }
79
+ const passed = missingCount === 0;
80
+ return {
81
+ passed,
82
+ issues,
83
+ stats: {
84
+ totalDefinitions,
85
+ annotatedDefinitions: totalDefinitions - missingCount,
86
+ totalRelationships,
87
+ annotatedRelationships,
88
+ missingCount,
89
+ structuralIssueCount: 0,
90
+ },
91
+ };
92
+ }
93
+ /**
94
+ * Check for inconsistent domain tags across definitions with the same name and kind.
95
+ */
96
+ function checkDomainConsistency(db) {
97
+ const issues = [];
98
+ const allDefs = db.definitions.getAll();
99
+ // Group definitions by (name, kind)
100
+ const groups = new Map();
101
+ for (const def of allDefs) {
102
+ const key = `${def.name}::${def.kind}`;
103
+ if (!groups.has(key))
104
+ groups.set(key, []);
105
+ groups.get(key).push({ id: def.id, name: def.name, kind: def.kind, line: def.line });
106
+ }
107
+ for (const [, defs] of groups) {
108
+ if (defs.length < 2)
109
+ continue;
110
+ // Get domain metadata for each definition
111
+ const domainVariants = new Map(); // normalized domain string → def IDs
112
+ for (const def of defs) {
113
+ const domainValue = db.metadata.getValue(def.id, 'domain');
114
+ if (!domainValue)
115
+ continue;
116
+ try {
117
+ const parsed = JSON.parse(domainValue);
118
+ const normalized = JSON.stringify([...parsed].sort());
119
+ if (!domainVariants.has(normalized))
120
+ domainVariants.set(normalized, []);
121
+ domainVariants.get(normalized).push(def.id);
122
+ }
123
+ catch {
124
+ // Skip unparseable domain values
125
+ }
126
+ }
127
+ // If there are multiple distinct domain variants, flag inconsistency
128
+ if (domainVariants.size > 1) {
129
+ for (const def of defs) {
130
+ const domainValue = db.metadata.getValue(def.id, 'domain');
131
+ if (!domainValue)
132
+ continue;
133
+ const fullDef = db.definitions.getById(def.id);
134
+ issues.push({
135
+ definitionId: def.id,
136
+ definitionName: def.name,
137
+ filePath: fullDef?.filePath,
138
+ line: def.line,
139
+ severity: 'warning',
140
+ category: 'inconsistent-domain',
141
+ message: `'${def.name}' (${def.kind}) has domain ${domainValue} — other definitions with same name have different domains`,
142
+ fixData: { action: 'harmonize-domain' },
143
+ });
144
+ }
145
+ }
146
+ }
147
+ return issues;
148
+ }
149
+ /**
150
+ * Check for suspicious pure:true annotations using deterministic pattern detection.
151
+ */
152
+ function checkPureAnnotations(db) {
153
+ const issues = [];
154
+ // Get all definitions that have pure = "true"
155
+ const pureTrueIds = db.metadata.getDefinitionsWith('pure');
156
+ for (const defId of pureTrueIds) {
157
+ const pureValue = db.metadata.getValue(defId, 'pure');
158
+ if (pureValue !== 'true')
159
+ continue;
160
+ const def = db.definitions.getById(defId);
161
+ if (!def)
162
+ continue;
163
+ // Skip types that are inherently pure
164
+ if (def.kind === 'interface' || def.kind === 'type' || def.kind === 'enum')
165
+ continue;
166
+ try {
167
+ const source = readSourceSync(db.resolveFilePath(def.filePath), def.line, def.endLine);
168
+ if (!source)
169
+ continue;
170
+ const impureReasons = detectImpurePatterns(source);
171
+ if (impureReasons.length > 0) {
172
+ issues.push({
173
+ definitionId: def.id,
174
+ definitionName: def.name,
175
+ filePath: def.filePath,
176
+ line: def.line,
177
+ severity: 'warning',
178
+ category: 'suspect-pure',
179
+ message: `'${def.name}' marked pure but source contains: ${impureReasons[0]}`,
180
+ suggestion: 'Consider changing pure to "false"',
181
+ fixData: { action: 'set-pure-false' },
182
+ });
183
+ }
184
+ }
185
+ catch {
186
+ // File not readable — skip
187
+ }
188
+ // Gate 2: transitive impurity — check if any dependency has pure:false
189
+ if (issues.every((i) => i.definitionId !== defId || i.category !== 'suspect-pure')) {
190
+ try {
191
+ const deps = db.dependencies.getWithMetadata(defId, 'pure');
192
+ for (const dep of deps) {
193
+ const depPure = db.metadata.getValue(dep.id, 'pure');
194
+ if (depPure === 'false') {
195
+ issues.push({
196
+ definitionId: def.id,
197
+ definitionName: def.name,
198
+ filePath: def.filePath,
199
+ line: def.line,
200
+ severity: 'warning',
201
+ category: 'suspect-pure',
202
+ message: `'${def.name}' marked pure but depends on impure '${dep.name}'`,
203
+ suggestion: 'Consider changing pure to "false"',
204
+ fixData: { action: 'set-pure-false' },
205
+ });
206
+ break;
207
+ }
208
+ }
209
+ }
210
+ catch {
211
+ // Ignore errors
212
+ }
213
+ }
214
+ }
215
+ return issues;
216
+ }
217
+ /**
218
+ * Check relationship coverage and structural issues.
219
+ */
220
+ export function checkRelationshipCoverage(db) {
221
+ const issues = [];
222
+ let structuralIssueCount = 0;
223
+ // Count unannotated relationships
224
+ let annotatedRelationships = 0;
225
+ let unannotatedCount = 0;
226
+ try {
227
+ annotatedRelationships = db.relationships.getCount();
228
+ unannotatedCount = db.relationships.getUnannotatedCount();
229
+ }
230
+ catch {
231
+ // Table doesn't exist
232
+ }
233
+ const totalRelationships = annotatedRelationships + unannotatedCount;
234
+ if (unannotatedCount > 0) {
235
+ const unannotated = db.relationships.getUnannotated({ limit: 50 });
236
+ for (const rel of unannotated) {
237
+ issues.push({
238
+ definitionId: rel.fromDefinitionId,
239
+ definitionName: rel.fromName,
240
+ severity: 'error',
241
+ category: 'missing-relationship',
242
+ message: `Missing: ${rel.fromName} → ${rel.toName}`,
243
+ fixData: { action: 'annotate-missing-relationship', targetDefinitionId: rel.toDefinitionId },
244
+ });
245
+ }
246
+ if (unannotatedCount > 50) {
247
+ issues.push({
248
+ severity: 'error',
249
+ category: 'missing-relationship',
250
+ message: `... and ${unannotatedCount - 50} more missing relationships`,
251
+ });
252
+ }
253
+ structuralIssueCount += unannotatedCount;
254
+ }
255
+ // Check for PENDING_LLM_ANNOTATION relationships
256
+ try {
257
+ const allRels = db.relationships.getAll({ limit: 100000 });
258
+ const pendingRels = allRels.filter((r) => r.semantic === 'PENDING_LLM_ANNOTATION');
259
+ for (const rel of pendingRels) {
260
+ issues.push({
261
+ definitionId: rel.fromDefinitionId,
262
+ definitionName: rel.fromName,
263
+ severity: 'error',
264
+ category: 'pending-annotation',
265
+ message: `${rel.fromName} → ${rel.toName} (${rel.relationshipType}) has placeholder PENDING_LLM_ANNOTATION`,
266
+ fixData: { action: 'reannotate-relationship', targetDefinitionId: rel.toDefinitionId },
267
+ });
268
+ structuralIssueCount++;
269
+ }
270
+ }
271
+ catch {
272
+ // Table doesn't exist
273
+ }
274
+ // Duplicate target detection: extends/implements where same (from_id, type) links to multiple to_ids with same name
275
+ try {
276
+ const allRels = db.relationships.getAll({ limit: 100000 });
277
+ const byFromAndType = new Map();
278
+ for (const rel of allRels) {
279
+ if (rel.relationshipType === 'extends' || rel.relationshipType === 'implements') {
280
+ const key = `${rel.fromDefinitionId}:${rel.relationshipType}`;
281
+ if (!byFromAndType.has(key))
282
+ byFromAndType.set(key, []);
283
+ byFromAndType.get(key).push({ toId: rel.toDefinitionId, toName: rel.toName });
284
+ }
285
+ }
286
+ for (const [key, targets] of byFromAndType) {
287
+ // Check if multiple targets share the same name (cartesian product error)
288
+ const nameGroups = new Map();
289
+ for (const t of targets) {
290
+ if (!nameGroups.has(t.toName))
291
+ nameGroups.set(t.toName, []);
292
+ nameGroups.get(t.toName).push(t.toId);
293
+ }
294
+ for (const [name, ids] of nameGroups) {
295
+ if (ids.length > 1) {
296
+ const [fromIdStr, relType] = key.split(':');
297
+ issues.push({
298
+ severity: 'error',
299
+ category: 'duplicate-target',
300
+ message: `Definition #${fromIdStr} has ${ids.length} '${relType}' relationships to different definitions named '${name}' (IDs: ${ids.join(', ')})`,
301
+ suggestion: 'This is likely a cartesian product error — only one target should exist',
302
+ });
303
+ structuralIssueCount++;
304
+ }
305
+ }
306
+ }
307
+ }
308
+ catch {
309
+ // Table doesn't exist
310
+ }
311
+ // Relationship type mismatch detection
312
+ try {
313
+ const typeMismatchIssues = checkRelationshipTypeMismatches(db);
314
+ issues.push(...typeMismatchIssues);
315
+ structuralIssueCount += typeMismatchIssues.length;
316
+ }
317
+ catch {
318
+ // Ignore errors
319
+ }
320
+ // Stale file detection
321
+ try {
322
+ const allFiles = db.files.getAll();
323
+ for (const file of allFiles) {
324
+ try {
325
+ fs.accessSync(db.resolveFilePath(file.path));
326
+ }
327
+ catch {
328
+ issues.push({
329
+ filePath: file.path,
330
+ severity: 'warning',
331
+ category: 'stale-file',
332
+ message: `File no longer exists on disk: ${file.path}`,
333
+ suggestion: 'Use --fix to remove stale file entries',
334
+ });
335
+ structuralIssueCount++;
336
+ }
337
+ }
338
+ }
339
+ catch {
340
+ // Files table doesn't exist
341
+ }
342
+ // Missing extends: definitions where extends_name is set but no extends relationship exists
343
+ try {
344
+ const BUILTIN_BASE_CLASSES = new Set([
345
+ 'Error',
346
+ 'TypeError',
347
+ 'RangeError',
348
+ 'SyntaxError',
349
+ 'ReferenceError',
350
+ 'URIError',
351
+ 'EvalError',
352
+ 'AggregateError',
353
+ 'Array',
354
+ 'Map',
355
+ 'Set',
356
+ 'WeakMap',
357
+ 'WeakSet',
358
+ 'RegExp',
359
+ 'Promise',
360
+ 'Proxy',
361
+ 'Event',
362
+ 'EventTarget',
363
+ 'CustomEvent',
364
+ 'HTMLElement',
365
+ 'HTMLDivElement',
366
+ 'HTMLInputElement',
367
+ 'ReadableStream',
368
+ 'WritableStream',
369
+ 'TransformStream',
370
+ 'EventEmitter',
371
+ ]);
372
+ const allDefs = db.definitions.getAll();
373
+ for (const def of allDefs) {
374
+ if (!def.extendsName)
375
+ continue;
376
+ // Skip built-in base classes that have no definition in the DB
377
+ if (BUILTIN_BASE_CLASSES.has(def.extendsName))
378
+ continue;
379
+ const relsFrom = db.relationships.getFrom(def.id);
380
+ const hasExtendsRel = relsFrom.some((r) => r.relationshipType === 'extends');
381
+ if (!hasExtendsRel) {
382
+ const fullDef = db.definitions.getById(def.id);
383
+ issues.push({
384
+ definitionId: def.id,
385
+ definitionName: def.name,
386
+ filePath: fullDef?.filePath,
387
+ line: def.line,
388
+ severity: 'warning',
389
+ category: 'missing-extends',
390
+ message: `Definition '${def.name}' has extends_name='${def.extendsName}' but no 'extends' relationship annotation`,
391
+ suggestion: 'The target class may not be indexed, or the extends clause uses unsupported syntax',
392
+ });
393
+ structuralIssueCount++;
394
+ }
395
+ }
396
+ }
397
+ catch {
398
+ // Ignore errors
399
+ }
400
+ // Missing implements: definitions where implements_names is set but no implements relationship exists
401
+ try {
402
+ const BUILTIN_INTERFACES = new Set([
403
+ 'Iterable',
404
+ 'Iterator',
405
+ 'AsyncIterable',
406
+ 'AsyncIterator',
407
+ 'PromiseLike',
408
+ 'ArrayLike',
409
+ 'Disposable',
410
+ 'AsyncDisposable',
411
+ ]);
412
+ const allDefs2 = db.definitions.getAll();
413
+ for (const def of allDefs2) {
414
+ const fullDef = db.definitions.getById(def.id);
415
+ if (!fullDef?.implementsNames || fullDef.implementsNames.length === 0)
416
+ continue;
417
+ const relsFrom = db.relationships.getFrom(def.id);
418
+ const implementsRels = new Set(relsFrom.filter((r) => r.relationshipType === 'implements').map((r) => r.toName));
419
+ for (const ifaceName of fullDef.implementsNames) {
420
+ if (BUILTIN_INTERFACES.has(ifaceName))
421
+ continue;
422
+ if (implementsRels.has(ifaceName))
423
+ continue;
424
+ issues.push({
425
+ definitionId: def.id,
426
+ definitionName: def.name,
427
+ filePath: fullDef.filePath,
428
+ line: def.line,
429
+ severity: 'warning',
430
+ category: 'missing-implements',
431
+ message: `Definition '${def.name}' implements '${ifaceName}' but no 'implements' relationship annotation exists`,
432
+ suggestion: 'The target interface may not be indexed, or the implements clause uses unsupported syntax',
433
+ });
434
+ structuralIssueCount++;
435
+ }
436
+ }
437
+ }
438
+ catch {
439
+ // Ignore errors
440
+ }
441
+ const totalDefinitions = db.definitions.getCount();
442
+ const passed = unannotatedCount === 0 && structuralIssueCount === 0;
443
+ return {
444
+ passed,
445
+ issues,
446
+ stats: {
447
+ totalDefinitions,
448
+ annotatedDefinitions: totalDefinitions,
449
+ totalRelationships,
450
+ annotatedRelationships,
451
+ missingCount: unannotatedCount,
452
+ structuralIssueCount,
453
+ },
454
+ };
455
+ }
456
+ /**
457
+ * Detect relationship type mismatches: relationships marked as 'uses' that should be 'extends' or 'implements'.
458
+ *
459
+ * Tier 1 — Column-based: checks definitions with extends_name/implements_names/extends_interfaces
460
+ * against relationship_annotations marked as 'uses' targeting those same definitions.
461
+ * Tier 2 — Source-code regex: for definitions with inheritance columns, checks source code
462
+ * for extends/implements keywords targeting relationship targets.
463
+ */
464
+ function checkRelationshipTypeMismatches(db) {
465
+ const issues = [];
466
+ const allDefs = db.definitions.getAll();
467
+ for (const def of allDefs) {
468
+ // Get full definition details (includes implementsNames, extendsInterfaces)
469
+ const fullDef = db.definitions.getById(def.id);
470
+ if (!fullDef)
471
+ continue;
472
+ // Collect all inheritance target names
473
+ const extendsNames = new Set();
474
+ const implementsNames = new Set();
475
+ if (fullDef.extendsName) {
476
+ extendsNames.add(fullDef.extendsName);
477
+ }
478
+ if (fullDef.extendsInterfaces) {
479
+ for (const name of fullDef.extendsInterfaces) {
480
+ extendsNames.add(name);
481
+ }
482
+ }
483
+ if (fullDef.implementsNames) {
484
+ for (const name of fullDef.implementsNames) {
485
+ implementsNames.add(name);
486
+ }
487
+ }
488
+ // Skip if no inheritance
489
+ if (extendsNames.size === 0 && implementsNames.size === 0)
490
+ continue;
491
+ // Get all relationships from this definition
492
+ const relsFrom = db.relationships.getFrom(def.id);
493
+ for (const rel of relsFrom) {
494
+ if (rel.relationshipType !== 'uses')
495
+ continue;
496
+ // Tier 1: check if target name matches a known inheritance target
497
+ let expectedType = null;
498
+ if (extendsNames.has(rel.toName)) {
499
+ expectedType = 'extends';
500
+ }
501
+ else if (implementsNames.has(rel.toName)) {
502
+ expectedType = 'implements';
503
+ }
504
+ if (expectedType) {
505
+ issues.push({
506
+ definitionId: def.id,
507
+ definitionName: def.name,
508
+ filePath: fullDef.filePath,
509
+ line: def.line,
510
+ severity: 'warning',
511
+ category: 'wrong-relationship-type',
512
+ message: `'${def.name}' → '${rel.toName}' is type 'uses' but should be '${expectedType}' (based on definition columns)`,
513
+ suggestion: `Use --fix to change relationship type to '${expectedType}'`,
514
+ fixData: {
515
+ action: 'change-relationship-type',
516
+ targetDefinitionId: rel.toDefinitionId,
517
+ expectedType,
518
+ },
519
+ });
520
+ }
521
+ }
522
+ }
523
+ return issues;
524
+ }
525
+ /**
526
+ * Check flow quality: structural integrity and coverage of generated flows.
527
+ */
528
+ export function checkFlowQuality(db) {
529
+ const issues = [];
530
+ let structuralIssueCount = 0;
531
+ const allFlows = db.flows.getAll();
532
+ const allModulesWithMembers = db.modules.getAllWithMembers();
533
+ const moduleMap = new Map(allModulesWithMembers.map((m) => [m.id, m]));
534
+ // Check 1 — orphan-entry-point: Flow references a module with no callable definitions
535
+ const callableKinds = new Set(['function', 'class', 'const', 'variable', 'method']);
536
+ for (const flow of allFlows) {
537
+ if (!flow.entryPointModuleId)
538
+ continue;
539
+ const mod = moduleMap.get(flow.entryPointModuleId);
540
+ if (!mod)
541
+ continue;
542
+ const hasCallable = mod.members.some((m) => callableKinds.has(m.kind));
543
+ if (!hasCallable) {
544
+ issues.push({
545
+ severity: 'error',
546
+ category: 'orphan-entry-point',
547
+ message: `Flow '${flow.name}' (id=${flow.id}) references module '${mod.fullPath}' which has no callable definitions (all members are type-only)`,
548
+ suggestion: 'Use --fix to remove this flow',
549
+ fixData: { action: 'remove-flow', targetDefinitionId: flow.id },
550
+ });
551
+ structuralIssueCount++;
552
+ }
553
+ }
554
+ // Check 2 — empty-flow: Flow has 0 steps
555
+ for (const flow of allFlows) {
556
+ const steps = db.flows.getSteps(flow.id);
557
+ if (steps.length === 0) {
558
+ issues.push({
559
+ severity: 'warning',
560
+ category: 'empty-flow',
561
+ message: `Flow '${flow.name}' (id=${flow.id}) has 0 interaction steps`,
562
+ suggestion: 'Use --fix to remove empty flows',
563
+ fixData: { action: 'remove-flow', targetDefinitionId: flow.id },
564
+ });
565
+ }
566
+ }
567
+ // Check 3 — dangling-interaction: Flow step references a non-existent interaction
568
+ for (const flow of allFlows) {
569
+ const steps = db.flows.getSteps(flow.id);
570
+ for (const step of steps) {
571
+ const interaction = db.interactions.getById(step.interactionId);
572
+ if (!interaction) {
573
+ issues.push({
574
+ severity: 'error',
575
+ category: 'dangling-interaction',
576
+ message: `Flow '${flow.name}' (id=${flow.id}) step ${step.stepOrder} references non-existent interaction ${step.interactionId}`,
577
+ });
578
+ structuralIssueCount++;
579
+ }
580
+ }
581
+ }
582
+ // Check 4 — duplicate-slug: Multiple flows share the same slug
583
+ const slugCounts = new Map();
584
+ for (const flow of allFlows) {
585
+ const ids = slugCounts.get(flow.slug) ?? [];
586
+ ids.push(flow.id);
587
+ slugCounts.set(flow.slug, ids);
588
+ }
589
+ for (const [slug, ids] of slugCounts) {
590
+ if (ids.length > 1) {
591
+ issues.push({
592
+ severity: 'warning',
593
+ category: 'duplicate-slug',
594
+ message: `Slug '${slug}' is shared by ${ids.length} flows (IDs: ${ids.join(', ')})`,
595
+ });
596
+ }
597
+ }
598
+ // Check 5 — uncovered-interactions: Interactions not covered by any flow (informational)
599
+ const coveredInteractionIds = new Set();
600
+ for (const flow of allFlows) {
601
+ const steps = db.flows.getSteps(flow.id);
602
+ for (const step of steps) {
603
+ coveredInteractionIds.add(step.interactionId);
604
+ }
605
+ }
606
+ const allInteractions = db.interactions.getAll();
607
+ const relevantInteractions = allInteractions.filter((i) => i.pattern !== 'test-internal');
608
+ const uncovered = relevantInteractions.filter((i) => !coveredInteractionIds.has(i.id));
609
+ if (uncovered.length > 0) {
610
+ issues.push({
611
+ severity: 'info',
612
+ category: 'uncovered-interactions',
613
+ message: `${uncovered.length}/${relevantInteractions.length} relevant interactions are not covered by any flow`,
614
+ });
615
+ for (const i of uncovered.slice(0, 20)) {
616
+ issues.push({
617
+ severity: 'info',
618
+ category: 'uncovered-interactions',
619
+ message: ` ${i.fromModulePath} → ${i.toModulePath}${i.semantic ? `: ${i.semantic}` : ''}`,
620
+ });
621
+ }
622
+ if (uncovered.length > 20) {
623
+ issues.push({
624
+ severity: 'info',
625
+ category: 'uncovered-interactions',
626
+ message: ` ... and ${uncovered.length - 20} more`,
627
+ });
628
+ }
629
+ }
630
+ // Check 6 — broken-chain: consecutive steps where toModuleId doesn't connect to next step
631
+ for (const flow of allFlows) {
632
+ const steps = db.flows.getSteps(flow.id);
633
+ if (steps.length < 2)
634
+ continue;
635
+ for (let i = 0; i < steps.length - 1; i++) {
636
+ const currentInteraction = db.interactions.getById(steps[i].interactionId);
637
+ const nextInteraction = db.interactions.getById(steps[i + 1].interactionId);
638
+ if (!currentInteraction || !nextInteraction)
639
+ continue; // Skip nulls (caught by dangling-interaction)
640
+ const currentTo = currentInteraction.toModuleId;
641
+ const nextFrom = nextInteraction.fromModuleId;
642
+ const nextTo = nextInteraction.toModuleId;
643
+ if (currentTo !== nextFrom && currentTo !== nextTo) {
644
+ issues.push({
645
+ severity: 'warning',
646
+ category: 'broken-chain',
647
+ message: `Flow '${flow.name}' (id=${flow.id}) has broken chain at step ${steps[i].stepOrder}→${steps[i + 1].stepOrder}: module #${currentTo} doesn't connect to next step`,
648
+ });
649
+ }
650
+ }
651
+ }
652
+ // Check 7 — entry-mismatch: entry point module != first step's from module
653
+ for (const flow of allFlows) {
654
+ if (!flow.entryPointModuleId)
655
+ continue;
656
+ const steps = db.flows.getSteps(flow.id);
657
+ if (steps.length === 0)
658
+ continue;
659
+ const firstInteraction = db.interactions.getById(steps[0].interactionId);
660
+ if (!firstInteraction)
661
+ continue;
662
+ if (flow.entryPointModuleId !== firstInteraction.fromModuleId) {
663
+ issues.push({
664
+ severity: 'warning',
665
+ category: 'entry-mismatch',
666
+ message: `Flow '${flow.name}' (id=${flow.id}) entry module #${flow.entryPointModuleId} doesn't match first step's from module #${firstInteraction.fromModuleId}`,
667
+ });
668
+ }
669
+ }
670
+ // Check 8 — entry-not-in-module: entry point definition not a member of entry module
671
+ for (const flow of allFlows) {
672
+ if (!flow.entryPointId || !flow.entryPointModuleId)
673
+ continue;
674
+ const mod = moduleMap.get(flow.entryPointModuleId);
675
+ if (!mod)
676
+ continue;
677
+ const isMember = mod.members.some((m) => m.definitionId === flow.entryPointId);
678
+ if (!isMember) {
679
+ issues.push({
680
+ severity: 'error',
681
+ category: 'entry-not-in-module',
682
+ message: `Flow '${flow.name}' (id=${flow.id}) entry point definition #${flow.entryPointId} is not a member of entry module #${flow.entryPointModuleId}`,
683
+ fixData: { action: 'null-entry-point', flowId: flow.id },
684
+ });
685
+ structuralIssueCount++;
686
+ }
687
+ }
688
+ const passed = structuralIssueCount === 0;
689
+ return {
690
+ passed,
691
+ issues,
692
+ stats: {
693
+ totalDefinitions: allFlows.length,
694
+ annotatedDefinitions: allFlows.length - structuralIssueCount,
695
+ totalRelationships: relevantInteractions.length,
696
+ annotatedRelationships: coveredInteractionIds.size,
697
+ missingCount: uncovered.length,
698
+ structuralIssueCount,
699
+ },
700
+ };
701
+ }
702
+ /**
703
+ * Check module assignment quality: test symbols in production modules,
704
+ * non-exported test symbols in shared modules.
705
+ */
706
+ export function checkModuleAssignments(db) {
707
+ const issues = [];
708
+ let structuralIssueCount = 0;
709
+ const modules = db.modules.getAll();
710
+ if (modules.length === 0) {
711
+ return {
712
+ passed: true,
713
+ issues: [],
714
+ stats: {
715
+ totalDefinitions: db.definitions.getCount(),
716
+ annotatedDefinitions: 0,
717
+ totalRelationships: 0,
718
+ annotatedRelationships: 0,
719
+ missingCount: 0,
720
+ structuralIssueCount: 0,
721
+ },
722
+ };
723
+ }
724
+ const testModuleIds = db.modules.getTestModuleIds();
725
+ // Check 1: test-in-production — test file symbols assigned to non-test modules
726
+ const allModulesWithMembers = db.modules.getAllWithMembers();
727
+ for (const mod of allModulesWithMembers) {
728
+ if (testModuleIds.has(mod.id))
729
+ continue; // production module check only
730
+ for (const member of mod.members) {
731
+ if (isTestFile(member.filePath)) {
732
+ issues.push({
733
+ definitionId: member.definitionId,
734
+ definitionName: member.name,
735
+ filePath: member.filePath,
736
+ line: member.line,
737
+ severity: 'warning',
738
+ category: 'test-in-production',
739
+ message: `Test symbol '${member.name}' from test file assigned to production module '${mod.fullPath}'`,
740
+ suggestion: 'Move to a test module (project.testing.*)',
741
+ fixData: { action: 'move-to-test-module' },
742
+ });
743
+ structuralIssueCount++;
744
+ }
745
+ }
746
+ }
747
+ // Check 2: non-exported test symbol in shared module
748
+ // Flag non-exported symbols from test files assigned to modules that have
749
+ // members from multiple different files (i.e. shared/infrastructure modules)
750
+ for (const mod of allModulesWithMembers) {
751
+ // Count distinct files in this module
752
+ const distinctFiles = new Set(mod.members.map((m) => m.filePath));
753
+ if (distinctFiles.size <= 1)
754
+ continue; // single-file module is fine
755
+ for (const member of mod.members) {
756
+ if (isTestFile(member.filePath) && !member.isExported) {
757
+ issues.push({
758
+ definitionId: member.definitionId,
759
+ definitionName: member.name,
760
+ filePath: member.filePath,
761
+ line: member.line,
762
+ severity: 'info',
763
+ category: 'non-exported-in-shared',
764
+ message: `Non-exported test symbol '${member.name}' in shared module '${mod.fullPath}' (${distinctFiles.size} files)`,
765
+ suggestion: 'File-local test symbols should not be in shared modules — assign to a general test module',
766
+ });
767
+ }
768
+ }
769
+ }
770
+ // Check 3: unassigned-definition — definitions not assigned to any module (informational)
771
+ try {
772
+ const unassigned = db.modules.getUnassigned();
773
+ if (unassigned.length > 0) {
774
+ issues.push({
775
+ severity: 'info',
776
+ category: 'unassigned-definition',
777
+ message: `${unassigned.length} definitions are not assigned to any module`,
778
+ });
779
+ for (const sym of unassigned.slice(0, 20)) {
780
+ issues.push({
781
+ definitionId: sym.id,
782
+ definitionName: sym.name,
783
+ filePath: sym.filePath,
784
+ line: sym.line,
785
+ severity: 'info',
786
+ category: 'unassigned-definition',
787
+ message: ` ${sym.name} (${sym.kind}) in ${sym.filePath}:${sym.line}`,
788
+ });
789
+ }
790
+ if (unassigned.length > 20) {
791
+ issues.push({
792
+ severity: 'info',
793
+ category: 'unassigned-definition',
794
+ message: ` ... and ${unassigned.length - 20} more`,
795
+ });
796
+ }
797
+ }
798
+ }
799
+ catch {
800
+ // Ignore errors
801
+ }
802
+ const totalDefinitions = db.definitions.getCount();
803
+ const passed = structuralIssueCount === 0;
804
+ return {
805
+ passed,
806
+ issues,
807
+ stats: {
808
+ totalDefinitions,
809
+ annotatedDefinitions: totalDefinitions,
810
+ totalRelationships: 0,
811
+ annotatedRelationships: 0,
812
+ missingCount: 0,
813
+ structuralIssueCount,
814
+ },
815
+ };
816
+ }
817
+ /**
818
+ * Check referential integrity: detect ghost rows referencing deleted entities.
819
+ */
820
+ export function checkReferentialIntegrity(db) {
821
+ const issues = [];
822
+ let structuralIssueCount = 0;
823
+ const ghosts = db.findGhostRows();
824
+ for (const g of ghosts.ghostRelationships) {
825
+ issues.push({
826
+ severity: 'error',
827
+ category: 'ghost-relationship',
828
+ message: `Relationship annotation #${g.id} references a deleted definition`,
829
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.id },
830
+ });
831
+ structuralIssueCount++;
832
+ }
833
+ for (const g of ghosts.ghostMembers) {
834
+ issues.push({
835
+ severity: 'error',
836
+ category: 'ghost-member',
837
+ message: `Module member for definition #${g.definitionId} references a deleted definition or module`,
838
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.definitionId },
839
+ });
840
+ structuralIssueCount++;
841
+ }
842
+ for (const g of ghosts.ghostEntryPoints) {
843
+ issues.push({
844
+ severity: 'error',
845
+ category: 'ghost-entry-point',
846
+ message: `Flow #${g.id} references a deleted entry point definition`,
847
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.id },
848
+ });
849
+ structuralIssueCount++;
850
+ }
851
+ for (const g of ghosts.ghostEntryModules) {
852
+ issues.push({
853
+ severity: 'error',
854
+ category: 'ghost-entry-module',
855
+ message: `Flow #${g.id} references a deleted entry point module`,
856
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.id },
857
+ });
858
+ structuralIssueCount++;
859
+ }
860
+ for (const g of ghosts.ghostInteractions) {
861
+ issues.push({
862
+ severity: 'error',
863
+ category: 'ghost-interaction',
864
+ message: `Interaction #${g.id} references a deleted module`,
865
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.id },
866
+ });
867
+ structuralIssueCount++;
868
+ }
869
+ for (const g of ghosts.ghostSubflows) {
870
+ issues.push({
871
+ severity: 'error',
872
+ category: 'ghost-subflow',
873
+ message: `Subflow step (rowid=${g.rowid}) references a deleted flow`,
874
+ fixData: { action: 'remove-ghost', ghostTable: g.table, ghostRowId: g.rowid },
875
+ });
876
+ structuralIssueCount++;
877
+ }
878
+ const passed = structuralIssueCount === 0;
879
+ return {
880
+ passed,
881
+ issues,
882
+ stats: {
883
+ totalDefinitions: 0,
884
+ annotatedDefinitions: 0,
885
+ totalRelationships: 0,
886
+ annotatedRelationships: 0,
887
+ missingCount: 0,
888
+ structuralIssueCount,
889
+ },
890
+ };
891
+ }
892
+ /**
893
+ * Check interaction quality: self-loops, missing import paths, symbol mismatches,
894
+ * false bidirectionals, and ungrounded inferred interactions.
895
+ */
896
+ export function checkInteractionQuality(db, processGroups) {
897
+ const issues = [];
898
+ let structuralIssueCount = 0;
899
+ const allInteractions = db.interactions.getAll();
900
+ if (allInteractions.length === 0) {
901
+ return {
902
+ passed: true,
903
+ issues: [],
904
+ stats: {
905
+ totalDefinitions: 0,
906
+ annotatedDefinitions: 0,
907
+ totalRelationships: 0,
908
+ annotatedRelationships: 0,
909
+ missingCount: 0,
910
+ structuralIssueCount: 0,
911
+ },
912
+ };
913
+ }
914
+ // Build call graph edge set for O(1) lookups
915
+ const callGraphEdges = new Set();
916
+ try {
917
+ const moduleCallGraph = db.callGraph.getModuleCallGraph();
918
+ for (const edge of moduleCallGraph) {
919
+ callGraphEdges.add(`${edge.fromModuleId}->${edge.toModuleId}`);
920
+ }
921
+ }
922
+ catch {
923
+ // Call graph may not be available
924
+ }
925
+ // Build module members lookup for symbol mismatch checks
926
+ const allModulesWithMembers = db.modules.getAllWithMembers();
927
+ const moduleMemberNames = new Map();
928
+ for (const mod of allModulesWithMembers) {
929
+ moduleMemberNames.set(mod.id, new Set(mod.members.map((m) => m.name)));
930
+ }
931
+ // Helper to check if two modules are cross-process
932
+ const isCrossProcess = (fromId, toId) => {
933
+ if (!processGroups)
934
+ return false;
935
+ const fromGroup = processGroups.moduleToGroup.get(fromId);
936
+ const toGroup = processGroups.moduleToGroup.get(toId);
937
+ if (fromGroup === undefined || toGroup === undefined)
938
+ return false;
939
+ return fromGroup !== toGroup;
940
+ };
941
+ // Build AST edge flow map for direction-implausible check (Check 8)
942
+ // Map: "groupA->groupB" → count of AST edges from groupA to groupB
943
+ const astFlowCounts = new Map();
944
+ if (processGroups) {
945
+ for (const interaction of allInteractions) {
946
+ if (interaction.source !== 'ast' && interaction.source !== 'ast-import')
947
+ continue;
948
+ const fromGroup = processGroups.moduleToGroup.get(interaction.fromModuleId);
949
+ const toGroup = processGroups.moduleToGroup.get(interaction.toModuleId);
950
+ if (fromGroup === undefined || toGroup === undefined)
951
+ continue;
952
+ if (fromGroup === toGroup)
953
+ continue;
954
+ const key = `${fromGroup}->${toGroup}`;
955
+ astFlowCounts.set(key, (astFlowCounts.get(key) ?? 0) + 1);
956
+ }
957
+ }
958
+ for (const interaction of allInteractions) {
959
+ // Check 1: self-loop-interaction
960
+ if (interaction.fromModuleId === interaction.toModuleId) {
961
+ issues.push({
962
+ severity: 'error',
963
+ category: 'self-loop-interaction',
964
+ message: `Interaction #${interaction.id} is a self-loop: ${interaction.fromModulePath} → ${interaction.toModulePath}`,
965
+ fixData: { action: 'remove-interaction', interactionId: interaction.id },
966
+ });
967
+ structuralIssueCount++;
968
+ continue; // Skip other checks for self-loops
969
+ }
970
+ // Check 2: no-import-path (for AST/import-based interactions)
971
+ if (interaction.source === 'ast' || interaction.source === 'ast-import') {
972
+ try {
973
+ const hasImport = db.interactions.hasModuleImportPath(interaction.fromModuleId, interaction.toModuleId);
974
+ if (!hasImport) {
975
+ issues.push({
976
+ severity: 'warning',
977
+ category: 'no-import-path',
978
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${interaction.toModulePath}) has source '${interaction.source}' but no import path exists`,
979
+ });
980
+ }
981
+ }
982
+ catch {
983
+ // Skip if query fails
984
+ }
985
+ }
986
+ // Check 3: interaction-symbol-mismatch
987
+ if (interaction.symbols) {
988
+ try {
989
+ const symbolNames = typeof interaction.symbols === 'string' ? JSON.parse(interaction.symbols) : interaction.symbols;
990
+ const targetMembers = moduleMemberNames.get(interaction.toModuleId);
991
+ if (targetMembers && symbolNames.length > 0) {
992
+ const mismatched = symbolNames.filter((s) => !targetMembers.has(s));
993
+ if (mismatched.length > 0 && mismatched.length === symbolNames.length) {
994
+ issues.push({
995
+ severity: 'warning',
996
+ category: 'interaction-symbol-mismatch',
997
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${interaction.toModulePath}): all ${symbolNames.length} symbols not found in target module`,
998
+ fixData: { action: 'rebuild-symbols', interactionId: interaction.id },
999
+ });
1000
+ }
1001
+ }
1002
+ }
1003
+ catch {
1004
+ // JSON parse error — skip
1005
+ }
1006
+ }
1007
+ // Check 4: false-bidirectional
1008
+ if (interaction.direction === 'bi') {
1009
+ const reverseKey = `${interaction.toModuleId}->${interaction.fromModuleId}`;
1010
+ if (!callGraphEdges.has(reverseKey)) {
1011
+ issues.push({
1012
+ severity: 'warning',
1013
+ category: 'false-bidirectional',
1014
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${interaction.toModulePath}) is 'bi' but no reverse call graph edge exists`,
1015
+ fixData: { action: 'set-direction-uni', interactionId: interaction.id },
1016
+ });
1017
+ }
1018
+ }
1019
+ // Check 5: ungrounded-inferred (process-aware)
1020
+ if (interaction.source === 'llm-inferred') {
1021
+ // Skip check for cross-process interactions — they're expected to have no static evidence
1022
+ if (!isCrossProcess(interaction.fromModuleId, interaction.toModuleId)) {
1023
+ const forwardKey = `${interaction.fromModuleId}->${interaction.toModuleId}`;
1024
+ const hasCallEdge = callGraphEdges.has(forwardKey);
1025
+ let hasImport = false;
1026
+ try {
1027
+ hasImport = db.interactions.hasModuleImportPath(interaction.fromModuleId, interaction.toModuleId);
1028
+ }
1029
+ catch {
1030
+ // Skip
1031
+ }
1032
+ if (!hasCallEdge && !hasImport) {
1033
+ issues.push({
1034
+ severity: 'warning',
1035
+ category: 'ungrounded-inferred',
1036
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${interaction.toModulePath}) is 'llm-inferred' with no import path and no call graph edge`,
1037
+ fixData: { action: 'remove-interaction', interactionId: interaction.id },
1038
+ });
1039
+ }
1040
+ }
1041
+ }
1042
+ // Check 8: direction-implausible (for llm-inferred cross-process interactions)
1043
+ if (interaction.source === 'llm-inferred' && processGroups) {
1044
+ const fromGroup = processGroups.moduleToGroup.get(interaction.fromModuleId);
1045
+ const toGroup = processGroups.moduleToGroup.get(interaction.toModuleId);
1046
+ if (fromGroup !== undefined && toGroup !== undefined && fromGroup !== toGroup) {
1047
+ const forwardKey = `${fromGroup}->${toGroup}`;
1048
+ const reverseKey = `${toGroup}->${fromGroup}`;
1049
+ const forwardCount = astFlowCounts.get(forwardKey) ?? 0;
1050
+ const reverseCount = astFlowCounts.get(reverseKey) ?? 0;
1051
+ // Flag if AST edges only flow in the reverse direction
1052
+ if (forwardCount === 0 && reverseCount > 0) {
1053
+ issues.push({
1054
+ severity: 'warning',
1055
+ category: 'direction-implausible',
1056
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${interaction.toModulePath}) goes against AST edge flow (${reverseCount} AST edges flow in reverse, 0 forward)`,
1057
+ fixData: { action: 'remove-interaction', interactionId: interaction.id },
1058
+ });
1059
+ }
1060
+ }
1061
+ }
1062
+ }
1063
+ // Check 6: fan-in-anomaly
1064
+ try {
1065
+ const anomalies = db.interactionAnalysis.detectFanInAnomalies();
1066
+ for (const anomaly of anomalies) {
1067
+ // Get all llm-inferred interactions targeting this module
1068
+ const inferredToModule = allInteractions.filter((i) => i.toModuleId === anomaly.moduleId && i.source === 'llm-inferred');
1069
+ for (const interaction of inferredToModule) {
1070
+ issues.push({
1071
+ severity: 'warning',
1072
+ category: 'fan-in-anomaly',
1073
+ message: `Interaction #${interaction.id} (${interaction.fromModulePath} → ${anomaly.modulePath}) targets a fan-in anomaly (${anomaly.llmFanIn} LLM inbound, ${anomaly.astFanIn} AST inbound)`,
1074
+ fixData: { action: 'remove-inferred-to-module', targetModuleId: anomaly.moduleId },
1075
+ });
1076
+ }
1077
+ }
1078
+ }
1079
+ catch {
1080
+ // Skip if analysis fails
1081
+ }
1082
+ const passed = structuralIssueCount === 0;
1083
+ return {
1084
+ passed,
1085
+ issues,
1086
+ stats: {
1087
+ totalDefinitions: allInteractions.length,
1088
+ annotatedDefinitions: allInteractions.length - structuralIssueCount,
1089
+ totalRelationships: 0,
1090
+ annotatedRelationships: 0,
1091
+ missingCount: 0,
1092
+ structuralIssueCount,
1093
+ },
1094
+ };
1095
+ }
1096
+ //# sourceMappingURL=coverage-checker.js.map