@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,870 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { LlmFlags, SharedFlags } from '../_shared/index.js';
4
+ import { BaseLlmCommand } from '../llm/_shared/base-llm-command.js';
5
+ import { parseRow } from '../llm/_shared/csv-utils.js';
6
+ import { completeWithLogging, getErrorMessage } from '../llm/_shared/llm-utils.js';
7
+ import { areSameProcess, computeProcessGroups, getCrossProcessGroupPairs, getProcessDescription, getProcessGroupLabel, } from '../llm/_shared/process-utils.js';
8
+ export default class InteractionsGenerate extends BaseLlmCommand {
9
+ static description = 'Detect module interactions from call graph and generate semantics using LLM';
10
+ static examples = [
11
+ '<%= config.bin %> interactions generate',
12
+ '<%= config.bin %> interactions generate --dry-run',
13
+ '<%= config.bin %> interactions generate --force',
14
+ '<%= config.bin %> interactions generate -d index.db --verbose',
15
+ ];
16
+ static flags = {
17
+ database: SharedFlags.database,
18
+ json: SharedFlags.json,
19
+ ...LlmFlags,
20
+ 'batch-size': Flags.integer({
21
+ description: 'Module edges per LLM batch for semantic generation',
22
+ default: 10,
23
+ }),
24
+ 'min-relationship-coverage': Flags.integer({
25
+ description: 'Minimum % of cross-module relationships covered by interactions',
26
+ default: 90,
27
+ }),
28
+ 'max-gate-retries': Flags.integer({
29
+ description: 'Maximum retry attempts when coverage gate fails',
30
+ default: 2,
31
+ }),
32
+ };
33
+ async execute(ctx, flags) {
34
+ const { db, isJson, dryRun, verbose, model } = ctx;
35
+ const batchSize = flags['batch-size'];
36
+ const showLlmRequests = ctx.llmOptions.showLlmRequests;
37
+ const showLlmResponses = ctx.llmOptions.showLlmResponses;
38
+ // Check if interactions already exist
39
+ const existingCount = db.interactions.getCount();
40
+ if (!this.checkExistingAndClear(ctx, {
41
+ entityName: 'Interactions',
42
+ existingCount,
43
+ force: flags.force,
44
+ clearFn: () => db.interactions.clear(),
45
+ forceHint: 'Use --force to re-detect',
46
+ })) {
47
+ return;
48
+ }
49
+ this.logHeader(ctx, 'Interaction Detection');
50
+ // Get enriched module call graph
51
+ const enrichedEdges = db.callGraph.getEnrichedModuleCallGraph();
52
+ if (enrichedEdges.length === 0) {
53
+ if (isJson) {
54
+ this.log(JSON.stringify({ error: 'No module call graph edges found', hint: 'Run llm modules first' }));
55
+ }
56
+ else {
57
+ this.log(chalk.yellow('No module call graph edges found.'));
58
+ this.log(chalk.gray('Ensure modules are assigned first with `squint llm modules`'));
59
+ }
60
+ return;
61
+ }
62
+ // Count utility vs business edges
63
+ const utilityCount = enrichedEdges.filter((e) => e.edgePattern === 'utility').length;
64
+ const businessCount = enrichedEdges.filter((e) => e.edgePattern === 'business').length;
65
+ if (!isJson && verbose) {
66
+ this.log(chalk.gray(`Found ${enrichedEdges.length} module-to-module edges`));
67
+ this.log(chalk.gray(` Business logic: ${businessCount}, Utility: ${utilityCount}`));
68
+ }
69
+ // Generate semantics for each edge using LLM
70
+ const interactions = [];
71
+ for (let i = 0; i < enrichedEdges.length; i += batchSize) {
72
+ const batch = enrichedEdges.slice(i, i + batchSize);
73
+ try {
74
+ const batchIdx = Math.floor(i / batchSize);
75
+ const totalBatches = Math.ceil(enrichedEdges.length / batchSize);
76
+ const suggestions = await this.generateInteractionSemantics(batch, model, db, isJson, batchIdx + 1, totalBatches);
77
+ interactions.push(...suggestions);
78
+ if (!isJson && verbose) {
79
+ this.log(chalk.gray(` Batch ${Math.floor(i / batchSize) + 1}: Generated ${suggestions.length} interactions`));
80
+ }
81
+ }
82
+ catch (error) {
83
+ const message = getErrorMessage(error);
84
+ if (!isJson) {
85
+ this.log(chalk.yellow(` Batch ${Math.floor(i / batchSize) + 1} failed: ${message}`));
86
+ }
87
+ // Fall back to auto-generated semantics
88
+ for (const edge of batch) {
89
+ interactions.push(this.createDefaultInteraction(edge));
90
+ }
91
+ }
92
+ }
93
+ // Tag test-internal interactions: if either module is a test module, override pattern
94
+ const testModuleIds = db.modules.getTestModuleIds();
95
+ if (testModuleIds.size > 0) {
96
+ for (const interaction of interactions) {
97
+ if (testModuleIds.has(interaction.fromModuleId) || testModuleIds.has(interaction.toModuleId)) {
98
+ interaction.pattern = 'test-internal';
99
+ }
100
+ }
101
+ const testInternalCount = interactions.filter((i) => i.pattern === 'test-internal').length;
102
+ if (!isJson && verbose && testInternalCount > 0) {
103
+ this.log(chalk.gray(` Tagged ${testInternalCount} interactions as test-internal`));
104
+ }
105
+ }
106
+ // Persist interactions
107
+ if (!dryRun) {
108
+ for (const interaction of interactions) {
109
+ try {
110
+ db.interactions.upsert(interaction.fromModuleId, interaction.toModuleId, {
111
+ weight: interaction.weight,
112
+ pattern: interaction.pattern,
113
+ symbols: interaction.symbols,
114
+ semantic: interaction.semantic,
115
+ });
116
+ }
117
+ catch {
118
+ if (verbose && !isJson) {
119
+ this.log(chalk.yellow(` Skipping duplicate: ${interaction.fromModulePath} → ${interaction.toModulePath}`));
120
+ }
121
+ }
122
+ }
123
+ // Create inheritance-based interactions (extends/implements)
124
+ // These don't generate call edges but ARE significant architectural dependencies
125
+ const inheritanceResult = db.interactionAnalysis.syncInheritanceInteractions();
126
+ if (!isJson && verbose && inheritanceResult.created > 0) {
127
+ this.log(chalk.gray(` Inheritance edges: ${inheritanceResult.created}`));
128
+ }
129
+ }
130
+ // Step 2: Import-based interactions (deterministic — no LLM)
131
+ let importBasedCount = 0;
132
+ if (!dryRun) {
133
+ const importPairs = db.interactions.getImportOnlyModulePairs();
134
+ if (importPairs.length > 0) {
135
+ if (!isJson) {
136
+ this.log('');
137
+ this.log(chalk.bold('Step 2: Import-Based Interactions (Deterministic)'));
138
+ }
139
+ for (const pair of importPairs) {
140
+ const pattern = testModuleIds.has(pair.fromModuleId) || testModuleIds.has(pair.toModuleId) ? 'test-internal' : 'business';
141
+ try {
142
+ db.interactions.upsert(pair.fromModuleId, pair.toModuleId, {
143
+ weight: pair.weight,
144
+ pattern,
145
+ symbols: pair.symbols.length > 0 ? pair.symbols.slice(0, 20) : undefined,
146
+ semantic: pair.isTypeOnly
147
+ ? `Type/interface dependency (${pair.symbols.slice(0, 3).join(', ')}${pair.symbols.length > 3 ? '...' : ''})`
148
+ : `Imports ${pair.symbols.slice(0, 3).join(', ')}${pair.symbols.length > 3 ? ` (+${pair.symbols.length - 3} more)` : ''}`,
149
+ source: 'ast-import',
150
+ });
151
+ importBasedCount++;
152
+ }
153
+ catch {
154
+ // Skip if already exists
155
+ }
156
+ }
157
+ if (!isJson) {
158
+ this.log(chalk.green(` Added ${importBasedCount} import-based interactions`));
159
+ }
160
+ }
161
+ }
162
+ // Compute process groups for Steps 3 and 4
163
+ const processGroups = computeProcessGroups(db);
164
+ // Step 3: Infer cross-process (non-AST) interactions
165
+ if (!isJson) {
166
+ this.log('');
167
+ this.log(chalk.bold('Step 3: Inferring Cross-Process Connections (LLM Analysis)'));
168
+ if (verbose) {
169
+ this.log(chalk.gray(` Detected ${processGroups.groupCount} process group(s)`));
170
+ for (const [, mods] of processGroups.groupToModules) {
171
+ const label = getProcessGroupLabel(mods);
172
+ this.log(chalk.gray(` Group "${label}": ${mods.length} modules`));
173
+ }
174
+ }
175
+ }
176
+ // Get existing edges to avoid duplicates
177
+ const existingEdges = db.callGraph.getModuleCallGraph();
178
+ const logicalInteractions = await this.inferCrossProcessInteractions(db, processGroups, existingEdges, model, isJson, showLlmRequests, showLlmResponses);
179
+ let inferredCount = 0;
180
+ if (!dryRun && logicalInteractions.length > 0) {
181
+ for (const li of logicalInteractions) {
182
+ try {
183
+ // Derive symbols from target module's exported definitions
184
+ const toModuleWithMembers = db.modules.getWithMembers(li.toModuleId);
185
+ const symbols = toModuleWithMembers
186
+ ? toModuleWithMembers.members
187
+ .filter((m) => m.kind === 'function' || m.kind === 'class')
188
+ .slice(0, 10)
189
+ .map((m) => m.name)
190
+ : [];
191
+ db.interactions.upsert(li.fromModuleId, li.toModuleId, {
192
+ semantic: li.reason,
193
+ source: 'llm-inferred',
194
+ pattern: 'business',
195
+ symbols: symbols.length > 0 ? symbols : undefined,
196
+ weight: 1,
197
+ confidence: li.confidence,
198
+ });
199
+ inferredCount++;
200
+ }
201
+ catch {
202
+ // Skip duplicates (edge may already exist from AST detection)
203
+ if (verbose && !isJson) {
204
+ const modules = db.modules.getAll();
205
+ const fromMod = modules.find((m) => m.id === li.fromModuleId);
206
+ const toMod = modules.find((m) => m.id === li.toModuleId);
207
+ this.log(chalk.gray(` Skipping: ${fromMod?.fullPath} → ${toMod?.fullPath} (exists)`));
208
+ }
209
+ }
210
+ }
211
+ if (!isJson) {
212
+ this.log(chalk.green(` Added ${inferredCount} inferred interactions`));
213
+ }
214
+ // Post-hoc fan-in anomaly detection
215
+ const anomalies = db.interactionAnalysis.detectFanInAnomalies();
216
+ if (anomalies.length > 0) {
217
+ let totalRemoved = 0;
218
+ for (const anomaly of anomalies) {
219
+ const removed = db.interactions.removeInferredToModule(anomaly.moduleId);
220
+ totalRemoved += removed;
221
+ if (!isJson && verbose) {
222
+ this.log(chalk.yellow(` Fan-in anomaly: removed ${removed} inferred interactions targeting ${anomaly.modulePath} (llm-fan-in: ${anomaly.llmFanIn}, ast-fan-in: ${anomaly.astFanIn})`));
223
+ }
224
+ }
225
+ if (!isJson && totalRemoved > 0) {
226
+ this.log(chalk.yellow(` Fan-in cleanup: removed ${totalRemoved} hallucinated interactions from ${anomalies.length} anomalous target(s)`));
227
+ }
228
+ }
229
+ }
230
+ else if (!isJson) {
231
+ if (logicalInteractions.length === 0) {
232
+ this.log(chalk.gray(' No additional logical connections detected'));
233
+ }
234
+ else {
235
+ this.log(chalk.gray(` Would add ${logicalInteractions.length} inferred interactions (dry run)`));
236
+ }
237
+ }
238
+ // Step 4: Coverage validation - targeted inference for uncovered module pairs
239
+ if (!dryRun) {
240
+ const minRelCoverage = flags['min-relationship-coverage'];
241
+ const maxGateRetries = flags['max-gate-retries'];
242
+ const allModules = db.modules.getAll();
243
+ const moduleMap = new Map(allModules.map((m) => [m.id, m]));
244
+ for (let attempt = 0; attempt < maxGateRetries; attempt++) {
245
+ const coverageCheck = db.interactionAnalysis.getRelationshipCoverage();
246
+ const breakdown = db.interactionAnalysis.getRelationshipCoverageBreakdown();
247
+ if (coverageCheck.coveragePercent >= minRelCoverage || breakdown.noCallEdge === 0) {
248
+ break;
249
+ }
250
+ if (!isJson) {
251
+ if (attempt === 0) {
252
+ this.log('');
253
+ this.log(chalk.bold('Step 4: Coverage Validation (Targeted Inference)'));
254
+ }
255
+ this.log(chalk.gray(` Coverage: ${coverageCheck.coveragePercent.toFixed(1)}% (target: ${minRelCoverage}%), ${breakdown.noCallEdge} uncovered pairs`));
256
+ }
257
+ const uncoveredPairs = db.interactionAnalysis.getUncoveredModulePairs();
258
+ if (uncoveredPairs.length === 0)
259
+ break;
260
+ // Pre-filter: partition into auto-skip, auto-flip, and needs-llm
261
+ const needsLlm = [];
262
+ let autoSkipCount = 0;
263
+ for (const pair of uncoveredPairs) {
264
+ const fromMod = moduleMap.get(pair.fromModuleId);
265
+ const toMod = moduleMap.get(pair.toModuleId);
266
+ if (!fromMod || !toMod) {
267
+ autoSkipCount++;
268
+ continue;
269
+ }
270
+ // Cross-process pairs ALWAYS go to LLM (they communicate via runtime protocols)
271
+ if (!areSameProcess(pair.fromModuleId, pair.toModuleId, processGroups)) {
272
+ needsLlm.push(pair);
273
+ continue;
274
+ }
275
+ // Same-layer: check import paths
276
+ const hasForwardImports = db.interactions.hasModuleImportPath(pair.fromModuleId, pair.toModuleId);
277
+ if (hasForwardImports) {
278
+ // Has forward imports → send to LLM for confirmation
279
+ needsLlm.push(pair);
280
+ continue;
281
+ }
282
+ // No forward imports for same-layer pair
283
+ const hasReverseAst = db.interactionAnalysis.hasReverseInteraction(pair.fromModuleId, pair.toModuleId);
284
+ if (hasReverseAst) {
285
+ // Direction confusion: reverse AST interaction exists → auto-skip
286
+ if (verbose && !isJson) {
287
+ this.log(chalk.gray(` Auto-skip (reversed): ${pair.fromPath} → ${pair.toPath}`));
288
+ }
289
+ autoSkipCount++;
290
+ continue;
291
+ }
292
+ const hasReverseImports = db.interactions.hasModuleImportPath(pair.toModuleId, pair.fromModuleId);
293
+ if (hasReverseImports) {
294
+ // No forward, but reverse imports → direction confusion, auto-skip
295
+ if (verbose && !isJson) {
296
+ this.log(chalk.gray(` Auto-skip (reverse imports): ${pair.fromPath} → ${pair.toPath}`));
297
+ }
298
+ autoSkipCount++;
299
+ continue;
300
+ }
301
+ // No imports in either direction for same-layer → auto-skip
302
+ autoSkipCount++;
303
+ if (verbose && !isJson) {
304
+ this.log(chalk.gray(` Auto-skip (no imports): ${pair.fromPath} → ${pair.toPath}`));
305
+ }
306
+ }
307
+ if (!isJson && autoSkipCount > 0) {
308
+ this.log(chalk.gray(` Pre-filtered: ${autoSkipCount} pairs auto-skipped, ${needsLlm.length} sent to LLM`));
309
+ }
310
+ if (needsLlm.length === 0)
311
+ break;
312
+ const targetedResults = await this.inferTargetedInteractions(db, needsLlm, moduleMap, processGroups, model, isJson, showLlmRequests, showLlmResponses);
313
+ let targetedCount = 0;
314
+ for (const ti of targetedResults) {
315
+ try {
316
+ // Derive symbols from imports or relationship annotations
317
+ const importedSymbols = db.interactions.getModuleImportedSymbols(ti.fromModuleId, ti.toModuleId);
318
+ let symbols;
319
+ if (importedSymbols.length > 0) {
320
+ symbols = importedSymbols.map((s) => s.name);
321
+ }
322
+ else {
323
+ symbols = db.interactionAnalysis.getRelationshipSymbolsForPair(ti.fromModuleId, ti.toModuleId);
324
+ }
325
+ db.interactions.upsert(ti.fromModuleId, ti.toModuleId, {
326
+ semantic: ti.reason,
327
+ source: 'llm-inferred',
328
+ pattern: 'business',
329
+ symbols: symbols.length > 0 ? symbols : undefined,
330
+ weight: 1,
331
+ confidence: ti.confidence ?? 'medium',
332
+ });
333
+ targetedCount++;
334
+ }
335
+ catch {
336
+ // Skip duplicates
337
+ }
338
+ }
339
+ if (!isJson) {
340
+ this.log(chalk.green(` Pass ${attempt + 1}: Added ${targetedCount} targeted interactions`));
341
+ }
342
+ if (targetedCount === 0)
343
+ break;
344
+ }
345
+ }
346
+ // Get relationship coverage
347
+ const relCoverage = db.interactionAnalysis.getRelationshipCoverage();
348
+ // Output results
349
+ const result = {
350
+ totalEdges: enrichedEdges.length,
351
+ interactions: interactions.length,
352
+ importBasedInteractions: importBasedCount,
353
+ inferredInteractions: inferredCount,
354
+ businessCount,
355
+ utilityCount,
356
+ relationshipCoverage: relCoverage,
357
+ };
358
+ if (isJson) {
359
+ this.log(JSON.stringify(result, null, 2));
360
+ }
361
+ else {
362
+ this.log('');
363
+ this.log(chalk.bold('Results'));
364
+ this.log(`Total module edges: ${result.totalEdges}`);
365
+ this.log(`AST interactions created: ${result.interactions}`);
366
+ this.log(` Business: ${businessCount}`);
367
+ this.log(` Utility: ${utilityCount}`);
368
+ this.log(`Import-based interactions: ${result.importBasedInteractions}`);
369
+ this.log(`LLM-inferred interactions: ${result.inferredInteractions}`);
370
+ // Display relationship coverage
371
+ this.log('');
372
+ this.log(chalk.bold('Relationship → Interaction Coverage'));
373
+ this.log(` Total relationships: ${relCoverage.totalRelationships}`);
374
+ this.log(` Cross-module: ${relCoverage.crossModuleRelationships}`);
375
+ this.log(` Same-module (internal cohesion): ${relCoverage.sameModuleCount}`);
376
+ this.log(` Contributing to interactions: ${relCoverage.relationshipsContributingToInteractions}/${relCoverage.crossModuleRelationships} (${relCoverage.coveragePercent.toFixed(1)}%)`);
377
+ if (relCoverage.orphanedCount > 0) {
378
+ this.log(chalk.yellow(` Orphaned (missing module): ${relCoverage.orphanedCount}`));
379
+ }
380
+ if (dryRun) {
381
+ this.log('');
382
+ this.log(chalk.gray('(Dry run - no changes persisted)'));
383
+ }
384
+ }
385
+ }
386
+ /**
387
+ * Generate semantic descriptions for module edges using LLM.
388
+ */
389
+ async generateInteractionSemantics(edges, model, db, isJson, batchIdx, totalBatches) {
390
+ const systemPrompt = `You are a software architect analyzing module-level dependencies.
391
+
392
+ For each module-to-module interaction, provide a semantic description of what the interaction does.
393
+
394
+ Output format - respond with ONLY a CSV table:
395
+
396
+ \`\`\`csv
397
+ from_module,to_module,semantic
398
+ project.controllers,project.services.auth,"Controllers delegate authentication logic to the auth service for credential validation"
399
+ \`\`\`
400
+
401
+ Guidelines:
402
+ - Describe WHY the source module calls the target module
403
+ - For UTILITY patterns: use generic descriptions like "Uses logging utilities", "Accesses database layer"
404
+ - For BUSINESS patterns: be specific about the business action (e.g., "Processes customer orders", "Validates user credentials")
405
+ - Keep descriptions concise (under 80 chars)
406
+ - Focus on the business purpose, not implementation details`;
407
+ // Build module lookup for descriptions
408
+ const allModules = db.modules.getAll();
409
+ const moduleMap = new Map(allModules.map((m) => [m.id, m]));
410
+ // Build edge descriptions with symbol details and module context
411
+ const edgeDescriptions = edges
412
+ .map((e, i) => {
413
+ const symbolList = e.calledSymbols.map((s) => `${s.name} (${s.kind}, ${s.callCount} calls)`).join(', ');
414
+ const patternInfo = `[${e.edgePattern.toUpperCase()}]`;
415
+ const fromMod = moduleMap.get(e.fromModuleId);
416
+ const toMod = moduleMap.get(e.toModuleId);
417
+ const fromDesc = fromMod ? `${fromMod.name}${fromMod.description ? ` - ${fromMod.description}` : ''}` : '';
418
+ const toDesc = toMod ? `${toMod.name}${toMod.description ? ` - ${toMod.description}` : ''}` : '';
419
+ let desc = `${i + 1}. ${patternInfo} ${e.fromModulePath} → ${e.toModulePath} (${e.weight} calls)`;
420
+ if (fromDesc)
421
+ desc += `\n From: "${fromDesc}"`;
422
+ if (toDesc)
423
+ desc += `\n To: "${toDesc}"`;
424
+ desc += `\n Symbols: ${symbolList}`;
425
+ return desc;
426
+ })
427
+ .join('\n');
428
+ const userPrompt = `## Module Interactions to Describe (${edges.length})
429
+
430
+ ${edgeDescriptions}
431
+
432
+ Generate semantic descriptions for each interaction in CSV format.`;
433
+ const response = await completeWithLogging({
434
+ model,
435
+ systemPrompt,
436
+ userPrompt,
437
+ temperature: 0,
438
+ maxTokens: 4096,
439
+ command: this,
440
+ isJson,
441
+ iteration: { current: batchIdx, max: totalBatches },
442
+ });
443
+ return this.parseInteractionCSV(response, edges);
444
+ }
445
+ /**
446
+ * Parse LLM CSV response into interaction suggestions.
447
+ */
448
+ parseInteractionCSV(response, edges) {
449
+ const results = [];
450
+ // Find CSV block
451
+ const csvMatch = response.match(/```csv\n([\s\S]*?)\n```/) || response.match(/```\n([\s\S]*?)\n```/);
452
+ const csvContent = csvMatch ? csvMatch[1] : response;
453
+ const lines = csvContent.split('\n').filter((l) => l.trim() && !l.startsWith('from_module'));
454
+ for (const line of lines) {
455
+ const fields = parseRow(line);
456
+ if (!fields || fields.length < 3)
457
+ continue;
458
+ const [fromPath, toPath, semantic] = fields;
459
+ // Find matching edge
460
+ const edge = edges.find((e) => e.fromModulePath === fromPath && e.toModulePath === toPath) ||
461
+ edges.find((e) => e.fromModulePath.endsWith(fromPath) && e.toModulePath.endsWith(toPath));
462
+ if (edge) {
463
+ results.push({
464
+ fromModuleId: edge.fromModuleId,
465
+ toModuleId: edge.toModuleId,
466
+ fromModulePath: edge.fromModulePath,
467
+ toModulePath: edge.toModulePath,
468
+ semantic: semantic.trim().replace(/"/g, ''),
469
+ pattern: edge.edgePattern,
470
+ symbols: edge.calledSymbols.map((s) => s.name),
471
+ weight: edge.weight,
472
+ });
473
+ }
474
+ }
475
+ // Add defaults for any edges not covered
476
+ for (const edge of edges) {
477
+ if (!results.find((r) => r.fromModuleId === edge.fromModuleId && r.toModuleId === edge.toModuleId)) {
478
+ results.push(this.createDefaultInteraction(edge));
479
+ }
480
+ }
481
+ return results;
482
+ }
483
+ /**
484
+ * Create a default interaction from an edge when LLM fails.
485
+ */
486
+ createDefaultInteraction(edge) {
487
+ const fromLast = edge.fromModulePath.split('.').pop() ?? 'source';
488
+ const toLast = edge.toModulePath.split('.').pop() ?? 'target';
489
+ return {
490
+ fromModuleId: edge.fromModuleId,
491
+ toModuleId: edge.toModuleId,
492
+ fromModulePath: edge.fromModulePath,
493
+ toModulePath: edge.toModulePath,
494
+ semantic: `${fromLast} uses ${toLast}`,
495
+ pattern: edge.edgePattern,
496
+ symbols: edge.calledSymbols.map((s) => s.name),
497
+ weight: edge.weight,
498
+ };
499
+ }
500
+ // ============================================================
501
+ // Step 3: Cross-Process Interaction Inference
502
+ // ============================================================
503
+ /**
504
+ * Infer cross-process interactions between modules in different process groups.
505
+ * Uses import graph connectivity (union-find) to detect process boundaries,
506
+ * then asks LLM to identify runtime connections between separate processes.
507
+ */
508
+ async inferCrossProcessInteractions(db, processGroups, existingEdges, model, isJson, showLlmRequests, showLlmResponses) {
509
+ if (processGroups.groupCount < 2) {
510
+ this.log(chalk.gray(' Single process group — no cross-process inference needed'));
511
+ return [];
512
+ }
513
+ const modules = db.modules.getAll();
514
+ const modulesWithMembers = db.modules.getAllWithMembers();
515
+ // Build existing edge lookup to avoid duplicates
516
+ const existingPairs = new Set(existingEdges.map((e) => `${e.fromModuleId}->${e.toModuleId}`));
517
+ // Also include existing interactions (both AST and already-inferred)
518
+ const existingInteractions = db.interactions.getAll();
519
+ for (const interaction of existingInteractions) {
520
+ existingPairs.add(`${interaction.fromModuleId}->${interaction.toModuleId}`);
521
+ }
522
+ // Build members lookup for enriched prompt
523
+ const membersMap = new Map(modulesWithMembers.map((m) => [m.id, m]));
524
+ const allResults = [];
525
+ const crossProcessPairs = getCrossProcessGroupPairs(processGroups);
526
+ for (const [groupA, groupB] of crossProcessPairs) {
527
+ const labelA = getProcessGroupLabel(groupA);
528
+ const labelB = getProcessGroupLabel(groupB);
529
+ const systemPrompt = this.buildCrossProcessSystemPrompt();
530
+ const userPrompt = this.buildCrossProcessUserPrompt(groupA, groupB, labelA, labelB, existingEdges, modules, membersMap);
531
+ if (showLlmRequests) {
532
+ this.log(chalk.cyan('='.repeat(60)));
533
+ this.log(chalk.cyan(`LLM REQUEST - inferCrossProcessInteractions (${labelA} <-> ${labelB})`));
534
+ this.log(chalk.gray(systemPrompt));
535
+ this.log(chalk.gray(userPrompt));
536
+ }
537
+ const response = await completeWithLogging({
538
+ model,
539
+ systemPrompt,
540
+ userPrompt,
541
+ temperature: 0,
542
+ maxTokens: 8192,
543
+ command: this,
544
+ isJson,
545
+ });
546
+ if (showLlmResponses) {
547
+ this.log(chalk.green('='.repeat(60)));
548
+ this.log(chalk.green('LLM RESPONSE'));
549
+ this.log(chalk.gray(response));
550
+ }
551
+ const results = this.parseLogicalInteractionCSV(response, modules, existingPairs, processGroups, db);
552
+ allResults.push(...results);
553
+ }
554
+ return allResults;
555
+ }
556
+ /**
557
+ * Infer targeted interactions for specific uncovered module pairs.
558
+ * These are module pairs with symbol-level relationships but no detected interaction.
559
+ * Prompt is enriched with module descriptions, import evidence, and relationship details.
560
+ */
561
+ async inferTargetedInteractions(db, uncoveredPairs, moduleMap, processGroups, model, isJson, showLlmRequests, showLlmResponses) {
562
+ if (uncoveredPairs.length === 0)
563
+ return [];
564
+ const systemPrompt = `You are reviewing module pairs that have symbol-level relationships but no detected interaction.
565
+ For each pair, determine if a real runtime interaction exists and describe it.
566
+
567
+ ## Decision Rules (CRITICAL)
568
+ - If "Forward imports: NONE" AND "Process: same-process" → SKIP (no static dependency exists)
569
+ - If "Reverse AST interaction: YES" → SKIP (the relationship direction is reversed; the reverse is already detected)
570
+ - If "Forward imports: YES" → CONFIRM is likely valid
571
+ - If "Process: separate-process" → use module descriptions and relationship semantics to decide
572
+ - When in doubt about same-process pairs with no imports → SKIP (trust static analysis)
573
+
574
+ ## Output Format
575
+ \`\`\`csv
576
+ from_module_path,to_module_path,action,reason
577
+ project.backend.services.sales,project.backend.data.models.vehicle,CONFIRM,"Sales service updates vehicle availability status on sale completion"
578
+ project.shared.types,project.backend.models,SKIP,"Shared type definitions, no runtime interaction"
579
+ \`\`\`
580
+
581
+ For each pair:
582
+ - CONFIRM if a real interaction exists (provide a semantic description as reason)
583
+ - SKIP if it's an artifact (shared types, transitive dependency, test-only, or no static evidence)`;
584
+ // Build enriched pair descriptions
585
+ const pairDescriptions = uncoveredPairs
586
+ .map((p, i) => {
587
+ const fromMod = moduleMap.get(p.fromModuleId);
588
+ const toMod = moduleMap.get(p.toModuleId);
589
+ // Module descriptions
590
+ const fromDesc = fromMod ? `${fromMod.name}${fromMod.description ? ` - ${fromMod.description}` : ''}` : '';
591
+ const toDesc = toMod ? `${toMod.name}${toMod.description ? ` - ${toMod.description}` : ''}` : '';
592
+ // Process info
593
+ const processDesc = getProcessDescription(p.fromModuleId, p.toModuleId, processGroups);
594
+ // Import evidence
595
+ const hasForwardImports = db.interactions.hasModuleImportPath(p.fromModuleId, p.toModuleId);
596
+ const hasReverseImports = db.interactions.hasModuleImportPath(p.toModuleId, p.fromModuleId);
597
+ const forwardImportStr = hasForwardImports ? 'YES' : 'NONE';
598
+ const reverseImportStr = hasReverseImports ? 'YES' : 'NONE';
599
+ // Reverse AST interaction
600
+ const hasReverseAst = db.interactionAnalysis.hasReverseInteraction(p.fromModuleId, p.toModuleId);
601
+ // Relationship details
602
+ const relDetails = db.interactionAnalysis.getRelationshipDetailsForModulePair(p.fromModuleId, p.toModuleId);
603
+ let desc = `${i + 1}. ${p.fromPath} → ${p.toPath}`;
604
+ if (fromDesc)
605
+ desc += `\n From: "${fromDesc}"`;
606
+ if (toDesc)
607
+ desc += `\n To: "${toDesc}"`;
608
+ desc += `\n Process: ${processDesc}`;
609
+ desc += `\n Forward imports: ${forwardImportStr} | Reverse imports: ${reverseImportStr} | Reverse AST interaction: ${hasReverseAst ? 'YES' : 'NO'}`;
610
+ if (relDetails.length > 0) {
611
+ desc += `\n Relationship symbols (${relDetails.length}):`;
612
+ for (const rd of relDetails.slice(0, 5)) {
613
+ desc += `\n - ${rd.fromName} → ${rd.toName}: "${rd.semantic}"`;
614
+ }
615
+ if (relDetails.length > 5) {
616
+ desc += `\n (+${relDetails.length - 5} more)`;
617
+ }
618
+ }
619
+ return desc;
620
+ })
621
+ .join('\n');
622
+ const userPrompt = `## Module Pairs to Evaluate (${uncoveredPairs.length})
623
+
624
+ ${pairDescriptions}
625
+
626
+ Evaluate each pair and output CONFIRM or SKIP in CSV format.`;
627
+ if (showLlmRequests) {
628
+ this.log(chalk.cyan('='.repeat(60)));
629
+ this.log(chalk.cyan('LLM REQUEST - inferTargetedInteractions'));
630
+ this.log(chalk.gray(systemPrompt));
631
+ this.log(chalk.gray(userPrompt));
632
+ }
633
+ const response = await completeWithLogging({
634
+ model,
635
+ systemPrompt,
636
+ userPrompt,
637
+ temperature: 0,
638
+ maxTokens: 8192,
639
+ command: this,
640
+ isJson,
641
+ });
642
+ if (showLlmResponses) {
643
+ this.log(chalk.green('='.repeat(60)));
644
+ this.log(chalk.green('LLM RESPONSE'));
645
+ this.log(chalk.gray(response));
646
+ }
647
+ // Parse response
648
+ const results = [];
649
+ const csvMatch = response.match(/```csv\n([\s\S]*?)\n```/);
650
+ const csv = csvMatch ? csvMatch[1] : response;
651
+ const pairByPaths = new Map(uncoveredPairs.map((p) => [`${p.fromPath}|${p.toPath}`, p]));
652
+ const moduleByPath = new Map(Array.from(moduleMap.values()).map((m) => [m.fullPath, m]));
653
+ // Build existingInteractionPairs for gating
654
+ const existingInteractions = db.interactions.getAll();
655
+ const existingInteractionPairs = new Set(existingInteractions.map((i) => `${i.fromModuleId}->${i.toModuleId}`));
656
+ for (const line of csv.split('\n')) {
657
+ if (!line.trim() || line.startsWith('from_module'))
658
+ continue;
659
+ const fields = parseRow(line);
660
+ if (!fields || fields.length < 4)
661
+ continue;
662
+ const [fromPath, toPath, action, reason] = fields;
663
+ if (action.trim().toUpperCase() !== 'CONFIRM')
664
+ continue;
665
+ const pair = pairByPaths.get(`${fromPath.trim()}|${toPath.trim()}`);
666
+ if (!pair)
667
+ continue;
668
+ const fromModule = moduleByPath.get(pair.fromPath);
669
+ const toModule = moduleByPath.get(pair.toPath);
670
+ if (!fromModule || !toModule)
671
+ continue;
672
+ // Apply structural gating
673
+ const gate = this.gateInferredInteraction(fromModule, toModule, processGroups, existingInteractionPairs, db);
674
+ if (!gate.pass)
675
+ continue;
676
+ results.push({
677
+ fromModuleId: pair.fromModuleId,
678
+ toModuleId: pair.toModuleId,
679
+ reason: reason?.replace(/"/g, '').trim() ?? 'Targeted inference',
680
+ confidence: 'medium',
681
+ });
682
+ }
683
+ return results;
684
+ }
685
+ /**
686
+ * Build system prompt for cross-process inference.
687
+ */
688
+ buildCrossProcessSystemPrompt() {
689
+ return `You identify LOGICAL runtime connections between modules in separate processes.
690
+ These modules have NO import connectivity — they communicate via runtime protocols
691
+ (HTTP/REST, gRPC, WebSocket, IPC, message queues, CLI invocation, file I/O, etc.).
692
+
693
+ For each connection:
694
+ - Identify the SOURCE module (the one initiating the call/request)
695
+ - Identify the TARGET module (the one handling/receiving)
696
+ - Describe the communication mechanism and purpose
697
+
698
+ Use entity/name matching to pair modules:
699
+ - "useCustomers" (process A) likely calls "customerController" (process B)
700
+ - Match by entity name, action verbs, and module descriptions
701
+
702
+ Only report connections with medium or high confidence.
703
+
704
+ ## Output Format
705
+ \`\`\`csv
706
+ from_module_path,to_module_path,reason,confidence
707
+ project.frontend.hooks.useCustomers,project.backend.api.controllers,"Customer data hooks call customer API controllers via HTTP",high
708
+ \`\`\`
709
+
710
+ Confidence levels:
711
+ - high: Names/patterns strongly suggest connection
712
+ - medium: Context supports it but names don't match exactly
713
+ - Skip low confidence - only report likely connections
714
+
715
+ DO NOT report:
716
+ - Connections within the same process group (those are visible via static analysis)
717
+ - Utility modules (logging, config, etc.)
718
+ - Shared type definitions (no runtime interaction)
719
+
720
+ ## Architecture Constraints
721
+ - In client-server architectures, the CLIENT (frontend/app/sdk) initiates requests.
722
+ Backend modules do NOT push to specific frontend components.
723
+ - Dev-time modules (CLI scripts, seed scripts, migrations) have NO runtime callers.
724
+ Do NOT connect production modules to dev-time utilities.
725
+ - A realistic cross-process call surface has 3-8 callers per target, not dozens.
726
+ If you find yourself connecting most modules in one group to a single target, stop.`;
727
+ }
728
+ /**
729
+ * Build user prompt for cross-process inference between two process groups.
730
+ * Includes member names for entity pattern matching.
731
+ */
732
+ buildCrossProcessUserPrompt(groupA, groupB, labelA, labelB, existingEdges, allModules, membersMap) {
733
+ const parts = [];
734
+ const MAX_MEMBERS = 8;
735
+ const KIND_PRIORITY = { function: 0, class: 1, variable: 2 };
736
+ const formatMembers = (moduleId) => {
737
+ const modWithMembers = membersMap.get(moduleId);
738
+ if (!modWithMembers || modWithMembers.members.length === 0)
739
+ return '';
740
+ const sorted = [...modWithMembers.members].sort((a, b) => (KIND_PRIORITY[a.kind] ?? 3) - (KIND_PRIORITY[b.kind] ?? 3));
741
+ const shown = sorted.slice(0, MAX_MEMBERS);
742
+ const memberList = shown.map((m) => `${m.name} (${m.kind})`).join(', ');
743
+ const extra = sorted.length > MAX_MEMBERS ? ` (+${sorted.length - MAX_MEMBERS} more)` : '';
744
+ return `\n Members: ${memberList}${extra}`;
745
+ };
746
+ const groupAIds = new Set(groupA.map((m) => m.id));
747
+ const groupBIds = new Set(groupB.map((m) => m.id));
748
+ const BOUNDARY_PATTERNS = /\b(router|controller|handler|hook|client|endpoint|api|gateway|service|provider|adapter|facade|proxy|middleware)\b/i;
749
+ const detectBoundaryModules = (group) => {
750
+ return group.filter((m) => {
751
+ // Check module name/path
752
+ if (BOUNDARY_PATTERNS.test(m.fullPath) || BOUNDARY_PATTERNS.test(m.name))
753
+ return true;
754
+ // Check member names
755
+ const modWithMembers = membersMap.get(m.id);
756
+ if (modWithMembers) {
757
+ return modWithMembers.members.some((member) => BOUNDARY_PATTERNS.test(member.name));
758
+ }
759
+ return false;
760
+ });
761
+ };
762
+ const formatBoundaryHints = (boundaryModules, label) => {
763
+ if (boundaryModules.length === 0)
764
+ return [];
765
+ const hints = [];
766
+ hints.push(`\nLikely boundary modules in "${label}":`);
767
+ for (const m of boundaryModules.slice(0, 10)) {
768
+ hints.push(` * ${m.fullPath}`);
769
+ }
770
+ return hints;
771
+ };
772
+ parts.push(`## Process Group: "${labelA}" (${groupA.length} modules)`);
773
+ for (const m of groupA) {
774
+ parts.push(`- ${m.fullPath}: "${m.name}"${m.description ? ` - ${m.description}` : ''}${formatMembers(m.id)}`);
775
+ }
776
+ const boundaryA = detectBoundaryModules(groupA);
777
+ parts.push(...formatBoundaryHints(boundaryA, labelA));
778
+ parts.push('');
779
+ parts.push(`## Process Group: "${labelB}" (${groupB.length} modules)`);
780
+ for (const m of groupB) {
781
+ parts.push(`- ${m.fullPath}: "${m.name}"${m.description ? ` - ${m.description}` : ''}${formatMembers(m.id)}`);
782
+ }
783
+ const boundaryB = detectBoundaryModules(groupB);
784
+ parts.push(...formatBoundaryHints(boundaryB, labelB));
785
+ parts.push('');
786
+ parts.push('## Existing AST-Detected Cross-Process Connections (for reference)');
787
+ const crossProcessEdges = existingEdges.filter((e) => {
788
+ const fromInA = groupAIds.has(e.fromModuleId);
789
+ const fromInB = groupBIds.has(e.fromModuleId);
790
+ const toInA = groupAIds.has(e.toModuleId);
791
+ const toInB = groupBIds.has(e.toModuleId);
792
+ return (fromInA && toInB) || (fromInB && toInA);
793
+ });
794
+ if (crossProcessEdges.length === 0) {
795
+ parts.push('(None detected - this is why we need inference!)');
796
+ }
797
+ else {
798
+ for (const e of crossProcessEdges) {
799
+ const from = allModules.find((m) => m.id === e.fromModuleId);
800
+ const to = allModules.find((m) => m.id === e.toModuleId);
801
+ if (from && to) {
802
+ parts.push(`- ${from.fullPath} → ${to.fullPath}`);
803
+ }
804
+ }
805
+ }
806
+ parts.push('');
807
+ parts.push('Identify runtime connections between these two process groups.');
808
+ return parts.join('\n');
809
+ }
810
+ /**
811
+ * Structural gate for inferred interactions.
812
+ * Rejects duplicates, self-loops, and reverse-of-AST interactions.
813
+ */
814
+ gateInferredInteraction(fromModule, toModule, _processGroups, existingInteractionPairs, db) {
815
+ // Gate A — Duplicate
816
+ const pairKey = `${fromModule.id}->${toModule.id}`;
817
+ if (existingInteractionPairs.has(pairKey)) {
818
+ return { pass: false, reason: 'duplicate' };
819
+ }
820
+ // Gate B — Self-loop
821
+ if (fromModule.id === toModule.id) {
822
+ return { pass: false, reason: 'self-loop' };
823
+ }
824
+ // Gate C — Reverse-of-AST
825
+ const reverseInteraction = db.interactions.getByModules(toModule.id, fromModule.id);
826
+ if (reverseInteraction && (reverseInteraction.source === 'ast' || reverseInteraction.source === 'ast-import')) {
827
+ return { pass: false, reason: 'reverse-of-ast' };
828
+ }
829
+ return { pass: true };
830
+ }
831
+ /**
832
+ * Parse the LLM response CSV into inferred interactions.
833
+ */
834
+ parseLogicalInteractionCSV(response, modules, existingPairs, processGroups, db) {
835
+ const results = [];
836
+ const moduleByPath = new Map(modules.map((m) => [m.fullPath, m]));
837
+ const csvMatch = response.match(/```csv\n([\s\S]*?)\n```/);
838
+ const csv = csvMatch ? csvMatch[1] : response;
839
+ for (const line of csv.split('\n')) {
840
+ if (!line.trim() || line.startsWith('from_module'))
841
+ continue;
842
+ const fields = parseRow(line);
843
+ if (!fields || fields.length < 4)
844
+ continue;
845
+ const [fromPath, toPath, reason, confidenceStr] = fields;
846
+ const fromModule = moduleByPath.get(fromPath.trim());
847
+ const toModule = moduleByPath.get(toPath.trim());
848
+ if (!fromModule || !toModule)
849
+ continue;
850
+ const normalizedConfidence = confidenceStr.trim().toLowerCase();
851
+ if (normalizedConfidence === 'low')
852
+ continue;
853
+ // Apply structural gating
854
+ const gate = this.gateInferredInteraction(fromModule, toModule, processGroups, existingPairs, db);
855
+ if (!gate.pass)
856
+ continue;
857
+ const confidence = normalizedConfidence === 'high' ? 'high' : 'medium';
858
+ results.push({
859
+ fromModuleId: fromModule.id,
860
+ toModuleId: toModule.id,
861
+ reason: reason?.replace(/"/g, '').trim() ?? 'LLM inferred connection',
862
+ confidence,
863
+ });
864
+ // Mark as processed to avoid duplicates within this batch
865
+ existingPairs.add(`${fromModule.id}->${toModule.id}`);
866
+ }
867
+ return results;
868
+ }
869
+ }
870
+ //# sourceMappingURL=generate.js.map