codebase-onboarder 0.6.0 → 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 (526) hide show
  1. package/README.md +284 -53
  2. package/bin/build-if-source.js +23 -0
  3. package/bin/onboarder.js +0 -0
  4. package/cli/agent/command.d.ts +71 -0
  5. package/cli/agent/command.js +177 -0
  6. package/cli/agent/command.js.map +1 -0
  7. package/cli/agent/config.d.ts +31 -0
  8. package/cli/agent/config.js +98 -0
  9. package/cli/agent/config.js.map +1 -0
  10. package/cli/agent/contracts.d.ts +77 -0
  11. package/cli/agent/contracts.js +2 -0
  12. package/cli/agent/contracts.js.map +1 -0
  13. package/cli/agent/files.d.ts +19 -0
  14. package/cli/agent/files.js +109 -0
  15. package/cli/agent/files.js.map +1 -0
  16. package/cli/agent/gitSource.d.ts +18 -0
  17. package/cli/agent/gitSource.js +69 -0
  18. package/cli/agent/gitSource.js.map +1 -0
  19. package/cli/agent/github.d.ts +21 -0
  20. package/cli/agent/github.js +94 -0
  21. package/cli/agent/github.js.map +1 -0
  22. package/cli/agent/mcp.d.ts +15 -0
  23. package/cli/agent/mcp.js +78 -0
  24. package/cli/agent/mcp.js.map +1 -0
  25. package/cli/agent/process.d.ts +18 -0
  26. package/cli/agent/process.js +118 -0
  27. package/cli/agent/process.js.map +1 -0
  28. package/cli/agent/protocol.d.ts +3 -0
  29. package/cli/agent/protocol.js +26 -0
  30. package/cli/agent/protocol.js.map +1 -0
  31. package/cli/agent/runner.d.ts +34 -0
  32. package/cli/agent/runner.js +152 -0
  33. package/cli/agent/runner.js.map +1 -0
  34. package/cli/agent/stdio.d.ts +1 -0
  35. package/cli/agent/stdio.js +62 -0
  36. package/cli/agent/stdio.js.map +1 -0
  37. package/cli/agent/tools.d.ts +7 -0
  38. package/cli/agent/tools.js +201 -0
  39. package/cli/agent/tools.js.map +1 -0
  40. package/cli/chat/app.d.ts +16 -0
  41. package/cli/chat/app.js +345 -0
  42. package/cli/chat/app.js.map +1 -0
  43. package/cli/chat/commands.d.ts +11 -0
  44. package/cli/chat/commands.js +120 -0
  45. package/cli/chat/commands.js.map +1 -0
  46. package/cli/chat/composer.d.ts +75 -0
  47. package/cli/chat/composer.js +467 -0
  48. package/cli/chat/composer.js.map +1 -0
  49. package/cli/chat/controller.d.ts +60 -0
  50. package/cli/chat/controller.js +393 -0
  51. package/cli/chat/controller.js.map +1 -0
  52. package/cli/chat/logo.d.ts +3 -0
  53. package/cli/chat/logo.js +14 -0
  54. package/cli/chat/logo.js.map +1 -0
  55. package/cli/chat/models.d.ts +18 -0
  56. package/cli/chat/models.js +88 -0
  57. package/cli/chat/models.js.map +1 -0
  58. package/cli/chat/profile.d.ts +5 -0
  59. package/cli/chat/profile.js +98 -0
  60. package/cli/chat/profile.js.map +1 -0
  61. package/cli/chat/render.d.ts +40 -0
  62. package/cli/chat/render.js +259 -0
  63. package/cli/chat/render.js.map +1 -0
  64. package/cli/chat/screen.d.ts +26 -0
  65. package/cli/chat/screen.js +117 -0
  66. package/cli/chat/screen.js.map +1 -0
  67. package/cli/chat/source.d.ts +29 -0
  68. package/cli/chat/source.js +116 -0
  69. package/cli/chat/source.js.map +1 -0
  70. package/cli/chat/store.d.ts +43 -0
  71. package/cli/chat/store.js +94 -0
  72. package/cli/chat/store.js.map +1 -0
  73. package/cli/chat/text.d.ts +4 -0
  74. package/cli/chat/text.js +27 -0
  75. package/cli/chat/text.js.map +1 -0
  76. package/cli/commands.d.ts +26 -0
  77. package/cli/commands.js +836 -811
  78. package/cli/commands.js.map +1 -0
  79. package/cli/explorer/advanced.d.ts +14 -0
  80. package/cli/explorer/advanced.js +321 -329
  81. package/cli/explorer/advanced.js.map +1 -0
  82. package/cli/explorer/app.d.ts +2 -0
  83. package/cli/explorer/app.js +404 -314
  84. package/cli/explorer/app.js.map +1 -0
  85. package/cli/explorer/assistant.d.ts +9 -0
  86. package/cli/explorer/assistant.js +58 -0
  87. package/cli/explorer/assistant.js.map +1 -0
  88. package/cli/explorer/commands.d.ts +17 -0
  89. package/cli/explorer/commands.js +373 -302
  90. package/cli/explorer/commands.js.map +1 -0
  91. package/cli/explorer/featureViews.d.ts +124 -0
  92. package/cli/explorer/featureViews.js +179 -0
  93. package/cli/explorer/featureViews.js.map +1 -0
  94. package/cli/explorer/github.d.ts +21 -0
  95. package/cli/explorer/github.js +42 -44
  96. package/cli/explorer/github.js.map +1 -0
  97. package/cli/explorer/graphs.d.ts +7 -0
  98. package/cli/explorer/graphs.js +90 -95
  99. package/cli/explorer/graphs.js.map +1 -0
  100. package/cli/explorer/picker.d.ts +22 -0
  101. package/cli/explorer/picker.js +150 -0
  102. package/cli/explorer/picker.js.map +1 -0
  103. package/cli/explorer/report.d.ts +85 -0
  104. package/cli/explorer/report.js +60 -0
  105. package/cli/explorer/report.js.map +1 -0
  106. package/cli/explorer/session.d.ts +449 -0
  107. package/cli/explorer/session.js +143 -144
  108. package/cli/explorer/session.js.map +1 -0
  109. package/cli/explorer/views.d.ts +19 -0
  110. package/cli/explorer/views.js +465 -482
  111. package/cli/explorer/views.js.map +1 -0
  112. package/cli/explorer/wrap.d.ts +1 -0
  113. package/cli/explorer/wrap.js +28 -44
  114. package/cli/explorer/wrap.js.map +1 -0
  115. package/cli/main.d.ts +1 -0
  116. package/cli/main.js +251 -164
  117. package/cli/main.js.map +1 -0
  118. package/cli/prompt.d.ts +5 -0
  119. package/cli/prompt.js +84 -80
  120. package/cli/prompt.js.map +1 -0
  121. package/cli/scanOptions.d.ts +2 -0
  122. package/cli/scanOptions.js +11 -0
  123. package/cli/scanOptions.js.map +1 -0
  124. package/cli/ui.d.ts +33 -0
  125. package/cli/ui.js +35 -44
  126. package/cli/ui.js.map +1 -0
  127. package/cli/wizard.d.ts +187 -0
  128. package/cli/wizard.js +304 -284
  129. package/cli/wizard.js.map +1 -0
  130. package/docs/HERMES_RESEARCH.md +51 -0
  131. package/package.json +16 -4
  132. package/public/app.d.ts +1 -0
  133. package/public/app.js +1133 -1011
  134. package/public/app.js.map +1 -0
  135. package/public/assets/onboarder-mark.svg +11 -0
  136. package/public/browser.d.ts +71 -0
  137. package/public/browser.js +2 -0
  138. package/public/browser.js.map +1 -0
  139. package/public/index.html +54 -20
  140. package/public/js/about.d.ts +6 -0
  141. package/public/js/about.js +152 -172
  142. package/public/js/about.js.map +1 -0
  143. package/public/js/aiDraft.d.ts +4 -0
  144. package/public/js/aiDraft.js +166 -125
  145. package/public/js/aiDraft.js.map +1 -0
  146. package/public/js/analysisPanel.d.ts +7 -0
  147. package/public/js/analysisPanel.js +166 -166
  148. package/public/js/analysisPanel.js.map +1 -0
  149. package/public/js/analysisReport.d.ts +38 -0
  150. package/public/js/analysisReport.js +105 -110
  151. package/public/js/analysisReport.js.map +1 -0
  152. package/public/js/api.d.ts +29 -0
  153. package/public/js/api.js +198 -166
  154. package/public/js/api.js.map +1 -0
  155. package/public/js/atlas.d.ts +6 -0
  156. package/public/js/atlas.js +50 -58
  157. package/public/js/atlas.js.map +1 -0
  158. package/public/js/blameView.d.ts +2 -0
  159. package/public/js/blameView.js +36 -37
  160. package/public/js/blameView.js.map +1 -0
  161. package/public/js/codeTab.d.ts +3 -0
  162. package/public/js/codeTab.js +175 -180
  163. package/public/js/codeTab.js.map +1 -0
  164. package/public/js/codeViewer.d.ts +5 -0
  165. package/public/js/codeViewer.js +162 -150
  166. package/public/js/codeViewer.js.map +1 -0
  167. package/public/js/components/FileChip.d.ts +9 -0
  168. package/public/js/components/FileChip.js +45 -49
  169. package/public/js/components/FileChip.js.map +1 -0
  170. package/public/js/components/MetricSparkline.d.ts +7 -0
  171. package/public/js/components/MetricSparkline.js +35 -44
  172. package/public/js/components/MetricSparkline.js.map +1 -0
  173. package/public/js/components/RiskBadge.d.ts +9 -0
  174. package/public/js/components/RiskBadge.js +55 -63
  175. package/public/js/components/RiskBadge.js.map +1 -0
  176. package/public/js/deepAnalysisView.d.ts +99 -0
  177. package/public/js/deepAnalysisView.js +282 -302
  178. package/public/js/deepAnalysisView.js.map +1 -0
  179. package/public/js/diagramPane.d.ts +9 -0
  180. package/public/js/diagramPane.js +138 -135
  181. package/public/js/diagramPane.js.map +1 -0
  182. package/public/js/diffView.d.ts +6 -0
  183. package/public/js/diffView.js +222 -209
  184. package/public/js/diffView.js.map +1 -0
  185. package/public/js/docsView.d.ts +2 -0
  186. package/public/js/docsView.js +441 -442
  187. package/public/js/docsView.js.map +1 -0
  188. package/public/js/dom.d.ts +197 -0
  189. package/public/js/dom.js +5 -0
  190. package/public/js/dom.js.map +1 -0
  191. package/public/js/fileSourceBrowser.d.ts +5 -0
  192. package/public/js/fileSourceBrowser.js +33 -41
  193. package/public/js/fileSourceBrowser.js.map +1 -0
  194. package/public/js/flameGraph.d.ts +5 -0
  195. package/public/js/flameGraph.js +62 -72
  196. package/public/js/flameGraph.js.map +1 -0
  197. package/public/js/forceGraph.d.ts +10 -0
  198. package/public/js/forceGraph.js +581 -556
  199. package/public/js/forceGraph.js.map +1 -0
  200. package/public/js/heatmap.d.ts +4 -0
  201. package/public/js/heatmap.js +142 -164
  202. package/public/js/heatmap.js.map +1 -0
  203. package/public/js/highlight.d.ts +2 -0
  204. package/public/js/highlight.js +116 -107
  205. package/public/js/highlight.js.map +1 -0
  206. package/public/js/html.d.ts +2 -0
  207. package/public/js/html.js +14 -44
  208. package/public/js/html.js.map +1 -0
  209. package/public/js/insightsView.d.ts +5 -0
  210. package/public/js/insightsView.js +93 -111
  211. package/public/js/insightsView.js.map +1 -0
  212. package/public/js/inspector.d.ts +37 -0
  213. package/public/js/inspector.js +416 -445
  214. package/public/js/inspector.js.map +1 -0
  215. package/public/js/llm.d.ts +115 -0
  216. package/public/js/llm.js +246 -278
  217. package/public/js/llm.js.map +1 -0
  218. package/public/js/mapView.d.ts +3 -0
  219. package/public/js/mapView.js +121 -120
  220. package/public/js/mapView.js.map +1 -0
  221. package/public/js/markdown.d.ts +3 -0
  222. package/public/js/markdown.js +84 -91
  223. package/public/js/markdown.js.map +1 -0
  224. package/public/js/mindmap.d.ts +32 -0
  225. package/public/js/mindmap.js +244 -259
  226. package/public/js/mindmap.js.map +1 -0
  227. package/public/js/mobilePanels.d.ts +5 -0
  228. package/public/js/mobilePanels.js +50 -0
  229. package/public/js/mobilePanels.js.map +1 -0
  230. package/public/js/repoFiles.d.ts +12 -0
  231. package/public/js/repoFiles.js +29 -28
  232. package/public/js/repoFiles.js.map +1 -0
  233. package/public/js/reviewView.d.ts +28 -0
  234. package/public/js/reviewView.js +256 -0
  235. package/public/js/reviewView.js.map +1 -0
  236. package/public/js/sbomView.d.ts +3 -0
  237. package/public/js/sbomView.js +59 -67
  238. package/public/js/sbomView.js.map +1 -0
  239. package/public/js/scanCache.d.ts +16 -0
  240. package/public/js/scanCache.js +67 -65
  241. package/public/js/scanCache.js.map +1 -0
  242. package/public/js/search.d.ts +7 -0
  243. package/public/js/search.js +868 -800
  244. package/public/js/search.js.map +1 -0
  245. package/public/js/searchLocal.d.ts +42 -0
  246. package/public/js/searchLocal.js +87 -0
  247. package/public/js/searchLocal.js.map +1 -0
  248. package/public/js/serverSettings.d.ts +5 -0
  249. package/public/js/serverSettings.js +153 -164
  250. package/public/js/serverSettings.js.map +1 -0
  251. package/public/js/state.d.ts +798 -0
  252. package/public/js/state.js +114 -122
  253. package/public/js/state.js.map +1 -0
  254. package/public/js/tour.d.ts +6 -0
  255. package/public/js/tour.js +5 -7
  256. package/public/js/tour.js.map +1 -0
  257. package/public/js/transitions.d.ts +2 -0
  258. package/public/js/transitions.js +9 -10
  259. package/public/js/transitions.js.map +1 -0
  260. package/public/js/tree.d.ts +12 -0
  261. package/public/js/tree.js +157 -154
  262. package/public/js/tree.js.map +1 -0
  263. package/public/js/workflowsView.d.ts +3 -0
  264. package/public/js/workflowsView.js +15 -22
  265. package/public/js/workflowsView.js.map +1 -0
  266. package/public/search.css +495 -0
  267. package/public/styles.css +188 -346
  268. package/public/workbench.css +166 -0
  269. package/server/apiAuth.d.ts +3 -0
  270. package/server/apiAuth.js +18 -20
  271. package/server/apiAuth.js.map +1 -0
  272. package/server/apiDiff.d.ts +2 -0
  273. package/server/apiDiff.js +20 -18
  274. package/server/apiDiff.js.map +1 -0
  275. package/server/apiDocs.d.ts +2 -0
  276. package/server/apiDocs.js +38 -40
  277. package/server/apiDocs.js.map +1 -0
  278. package/server/apiFile.d.ts +1 -0
  279. package/server/apiFile.js +14 -17
  280. package/server/apiFile.js.map +1 -0
  281. package/server/apiGitBlame.d.ts +2 -0
  282. package/server/apiGitBlame.js +50 -51
  283. package/server/apiGitBlame.js.map +1 -0
  284. package/server/apiMcp.d.ts +4 -0
  285. package/server/apiMcp.js +64 -66
  286. package/server/apiMcp.js.map +1 -0
  287. package/server/apiReview.d.ts +2 -0
  288. package/server/apiReview.js +45 -0
  289. package/server/apiReview.js.map +1 -0
  290. package/server/apiScan.d.ts +5 -0
  291. package/server/apiScan.js +90 -71
  292. package/server/apiScan.js.map +1 -0
  293. package/server/apiSearch.d.ts +33 -0
  294. package/server/apiSearch.js +184 -200
  295. package/server/apiSearch.js.map +1 -0
  296. package/server/apiSettings.d.ts +4 -0
  297. package/server/apiSettings.js +84 -85
  298. package/server/apiSettings.js.map +1 -0
  299. package/server/apiTools.d.ts +3 -0
  300. package/server/apiTools.js +55 -56
  301. package/server/apiTools.js.map +1 -0
  302. package/server/auth.d.ts +5 -0
  303. package/server/auth.js +54 -51
  304. package/server/auth.js.map +1 -0
  305. package/server/config.d.ts +42 -0
  306. package/server/config.js +189 -194
  307. package/server/config.js.map +1 -0
  308. package/server/daemon.d.ts +12 -0
  309. package/server/daemon.js +124 -114
  310. package/server/daemon.js.map +1 -0
  311. package/server/fileSourceNode.d.ts +2 -0
  312. package/server/fileSourceNode.js +34 -36
  313. package/server/fileSourceNode.js.map +1 -0
  314. package/server/gitClone.d.ts +9 -0
  315. package/server/gitClone.js +59 -61
  316. package/server/gitClone.js.map +1 -0
  317. package/server/gitDiff.d.ts +36 -0
  318. package/server/gitDiff.js +271 -169
  319. package/server/gitDiff.js.map +1 -0
  320. package/server/gitHistory.d.ts +12 -0
  321. package/server/gitHistory.js +80 -80
  322. package/server/gitHistory.js.map +1 -0
  323. package/server/gitRemote.d.ts +12 -0
  324. package/server/gitRemote.js +37 -38
  325. package/server/gitRemote.js.map +1 -0
  326. package/server/hermesChat.d.ts +13 -0
  327. package/server/hermesChat.js +145 -0
  328. package/server/hermesChat.js.map +1 -0
  329. package/server/htmlText.d.ts +4 -0
  330. package/server/htmlText.js +16 -23
  331. package/server/htmlText.js.map +1 -0
  332. package/server/http.d.ts +6 -0
  333. package/server/http.js +27 -34
  334. package/server/http.js.map +1 -0
  335. package/server/httpGuards.d.ts +2 -0
  336. package/server/httpGuards.js +47 -43
  337. package/server/httpGuards.js.map +1 -0
  338. package/server/https.d.ts +34 -0
  339. package/server/https.js +121 -111
  340. package/server/https.js.map +1 -0
  341. package/server/index.d.ts +40 -0
  342. package/server/index.js +139 -147
  343. package/server/index.js.map +1 -0
  344. package/server/layout.d.ts +26 -0
  345. package/server/layout.js +59 -64
  346. package/server/layout.js.map +1 -0
  347. package/server/llmProxy.d.ts +3 -0
  348. package/server/llmProxy.js +137 -135
  349. package/server/llmProxy.js.map +1 -0
  350. package/server/logger.d.ts +38 -0
  351. package/server/logger.js +198 -211
  352. package/server/logger.js.map +1 -0
  353. package/server/mcp/analysis.d.ts +29 -0
  354. package/server/mcp/analysis.js +99 -120
  355. package/server/mcp/analysis.js.map +1 -0
  356. package/server/mcp/http.d.ts +9 -0
  357. package/server/mcp/http.js +128 -137
  358. package/server/mcp/http.js.map +1 -0
  359. package/server/mcp/runner.d.ts +68 -0
  360. package/server/mcp/runner.js +208 -218
  361. package/server/mcp/runner.js.map +1 -0
  362. package/server/mcp/server.d.ts +29 -0
  363. package/server/mcp/server.js +167 -180
  364. package/server/mcp/server.js.map +1 -0
  365. package/server/mcp/standalone.d.ts +1 -0
  366. package/server/mcp/standalone.js +8 -10
  367. package/server/mcp/standalone.js.map +1 -0
  368. package/server/mcp/tools.d.ts +2020 -0
  369. package/server/mcp/tools.js +523 -574
  370. package/server/mcp/tools.js.map +1 -0
  371. package/server/paths.d.ts +3 -0
  372. package/server/paths.js +17 -15
  373. package/server/paths.js.map +1 -0
  374. package/server/pidfile.d.ts +9 -0
  375. package/server/pidfile.js +43 -45
  376. package/server/pidfile.js.map +1 -0
  377. package/server/review.d.ts +5 -0
  378. package/server/review.js +35 -0
  379. package/server/review.js.map +1 -0
  380. package/server/router.d.ts +33 -0
  381. package/server/router.js +195 -197
  382. package/server/router.js.map +1 -0
  383. package/server/scanRequest.d.ts +3 -0
  384. package/server/scanRequest.js +36 -0
  385. package/server/scanRequest.js.map +1 -0
  386. package/server/searchIndex.d.ts +17 -0
  387. package/server/searchIndex.js +83 -80
  388. package/server/searchIndex.js.map +1 -0
  389. package/server/sessions.d.ts +14 -0
  390. package/server/sessions.js +62 -70
  391. package/server/sessions.js.map +1 -0
  392. package/server/startup.d.ts +118 -0
  393. package/server/startup.js +143 -148
  394. package/server/startup.js.map +1 -0
  395. package/server/static.d.ts +6 -0
  396. package/server/static.js +28 -31
  397. package/server/static.js.map +1 -0
  398. package/server/tools/install.d.ts +4 -0
  399. package/server/tools/install.js +176 -185
  400. package/server/tools/install.js.map +1 -0
  401. package/server/tools/parse.d.ts +8 -0
  402. package/server/tools/parse.js +112 -114
  403. package/server/tools/parse.js.map +1 -0
  404. package/server/tools/platform.d.ts +9 -0
  405. package/server/tools/platform.js +49 -47
  406. package/server/tools/platform.js.map +1 -0
  407. package/server/tools/registry.d.ts +137 -0
  408. package/server/tools/registry.js +173 -172
  409. package/server/tools/registry.js.map +1 -0
  410. package/server/tools/scan.d.ts +34 -0
  411. package/server/tools/scan.js +89 -98
  412. package/server/tools/scan.js.map +1 -0
  413. package/server/tools.d.ts +34 -0
  414. package/server/tools.js +94 -107
  415. package/server/tools.js.map +1 -0
  416. package/server/tunnel.d.ts +29 -0
  417. package/server/tunnel.js +61 -66
  418. package/server/tunnel.js.map +1 -0
  419. package/shared/analyzer/docs.d.ts +16 -0
  420. package/shared/analyzer/docs.js +99 -93
  421. package/shared/analyzer/docs.js.map +1 -0
  422. package/shared/analyzer/explainLocal.d.ts +4 -0
  423. package/shared/analyzer/explainLocal.js +122 -142
  424. package/shared/analyzer/explainLocal.js.map +1 -0
  425. package/shared/analyzer/github.d.ts +37 -0
  426. package/shared/analyzer/github.js +41 -43
  427. package/shared/analyzer/github.js.map +1 -0
  428. package/shared/analyzer/graph.d.ts +41 -0
  429. package/shared/analyzer/graph.js +393 -400
  430. package/shared/analyzer/graph.js.map +1 -0
  431. package/shared/analyzer/health.d.ts +33 -0
  432. package/shared/analyzer/health.js +197 -193
  433. package/shared/analyzer/health.js.map +1 -0
  434. package/shared/analyzer/history.d.ts +29 -0
  435. package/shared/analyzer/history.js +110 -111
  436. package/shared/analyzer/history.js.map +1 -0
  437. package/shared/analyzer/jsonConfig.d.ts +2 -0
  438. package/shared/analyzer/jsonConfig.js +61 -0
  439. package/shared/analyzer/jsonConfig.js.map +1 -0
  440. package/shared/analyzer/languages/csharp.d.ts +26 -0
  441. package/shared/analyzer/languages/csharp.js +83 -88
  442. package/shared/analyzer/languages/csharp.js.map +1 -0
  443. package/shared/analyzer/languages/generic.d.ts +23 -0
  444. package/shared/analyzer/languages/generic.js +94 -105
  445. package/shared/analyzer/languages/generic.js.map +1 -0
  446. package/shared/analyzer/languages/go.d.ts +24 -0
  447. package/shared/analyzer/languages/go.js +45 -54
  448. package/shared/analyzer/languages/go.js.map +1 -0
  449. package/shared/analyzer/languages/index.d.ts +6 -0
  450. package/shared/analyzer/languages/index.js +19 -20
  451. package/shared/analyzer/languages/index.js.map +1 -0
  452. package/shared/analyzer/languages/java.d.ts +20 -0
  453. package/shared/analyzer/languages/java.js +73 -78
  454. package/shared/analyzer/languages/java.js.map +1 -0
  455. package/shared/analyzer/languages/javascript.d.ts +12 -0
  456. package/shared/analyzer/languages/javascript.js +258 -209
  457. package/shared/analyzer/languages/javascript.js.map +1 -0
  458. package/shared/analyzer/languages/python.d.ts +23 -0
  459. package/shared/analyzer/languages/python.js +92 -100
  460. package/shared/analyzer/languages/python.js.map +1 -0
  461. package/shared/analyzer/languages/rust.d.ts +17 -0
  462. package/shared/analyzer/languages/rust.js +96 -98
  463. package/shared/analyzer/languages/rust.js.map +1 -0
  464. package/shared/analyzer/languages/typescript.d.ts +11 -0
  465. package/shared/analyzer/languages/typescript.js +117 -116
  466. package/shared/analyzer/languages/typescript.js.map +1 -0
  467. package/shared/analyzer/licenses.d.ts +18 -0
  468. package/shared/analyzer/licenses.js +130 -133
  469. package/shared/analyzer/licenses.js.map +1 -0
  470. package/shared/analyzer/metrics.d.ts +20 -0
  471. package/shared/analyzer/metrics.js +112 -104
  472. package/shared/analyzer/metrics.js.map +1 -0
  473. package/shared/analyzer/pathUtil.d.ts +10 -0
  474. package/shared/analyzer/pathUtil.js +29 -35
  475. package/shared/analyzer/pathUtil.js.map +1 -0
  476. package/shared/analyzer/patterns.d.ts +11 -0
  477. package/shared/analyzer/patterns.js +231 -253
  478. package/shared/analyzer/patterns.js.map +1 -0
  479. package/shared/analyzer/scan.d.ts +62 -0
  480. package/shared/analyzer/scan.js +451 -442
  481. package/shared/analyzer/scan.js.map +1 -0
  482. package/shared/analyzer/scanControl.d.ts +11 -0
  483. package/shared/analyzer/scanControl.js +62 -0
  484. package/shared/analyzer/scanControl.js.map +1 -0
  485. package/shared/analyzer/security.d.ts +18 -0
  486. package/shared/analyzer/security.js +159 -159
  487. package/shared/analyzer/security.js.map +1 -0
  488. package/shared/analyzer/services.d.ts +5 -0
  489. package/shared/analyzer/services.js +141 -138
  490. package/shared/analyzer/services.js.map +1 -0
  491. package/shared/analyzer/stack.d.ts +6 -0
  492. package/shared/analyzer/stack.js +134 -141
  493. package/shared/analyzer/stack.js.map +1 -0
  494. package/shared/analyzer/tour.d.ts +2 -0
  495. package/shared/analyzer/tour.js +45 -53
  496. package/shared/analyzer/tour.js.map +1 -0
  497. package/shared/analyzer/util.d.ts +8 -0
  498. package/shared/analyzer/util.js +130 -76
  499. package/shared/analyzer/util.js.map +1 -0
  500. package/shared/analyzer/workflows.d.ts +8 -0
  501. package/shared/analyzer/workflows.js +139 -134
  502. package/shared/analyzer/workflows.js.map +1 -0
  503. package/shared/contracts.d.ts +250 -0
  504. package/shared/contracts.js +2 -0
  505. package/shared/contracts.js.map +1 -0
  506. package/shared/diagram/aiFacts.d.ts +35 -0
  507. package/shared/diagram/aiFacts.js +102 -105
  508. package/shared/diagram/aiFacts.js.map +1 -0
  509. package/shared/diagram/aiMermaid.d.ts +5 -0
  510. package/shared/diagram/aiMermaid.js +50 -46
  511. package/shared/diagram/aiMermaid.js.map +1 -0
  512. package/shared/diagram/atlas.d.ts +16 -0
  513. package/shared/diagram/atlas.js +51 -60
  514. package/shared/diagram/atlas.js.map +1 -0
  515. package/shared/diagram/mermaid.d.ts +43 -0
  516. package/shared/diagram/mermaid.js +348 -370
  517. package/shared/diagram/mermaid.js.map +1 -0
  518. package/shared/review/contracts.d.ts +95 -0
  519. package/shared/review/contracts.js +2 -0
  520. package/shared/review/contracts.js.map +1 -0
  521. package/shared/review/review.d.ts +10 -0
  522. package/shared/review/review.js +184 -0
  523. package/shared/review/review.js.map +1 -0
  524. package/shared/search/query.d.ts +32 -0
  525. package/shared/search/query.js +395 -388
  526. package/shared/search/query.js.map +1 -0
@@ -1,272 +1,250 @@
1
1
  // Pattern reading: turns the raw import graph into observations about the
2
2
  // repo's shape — its depth layers, its load-bearing files, its smells.
3
3
  // Everything here is pure functions over scan + facts.
4
-
5
4
  // Assigns every reachable file a depth: the length of the longest import
6
5
  // chain from an entry point. Files no entry can reach land in `unreachable`.
7
6
  // Cycles are survived by capping how often a file may be relaxed.
8
7
  export function computeLayers(scan, facts) {
9
- let seeds = facts.entries.slice();
10
- if (!seeds.length) {
11
- // No recognized entry points — start from the tops of the import chains:
12
- // files that pull others in but are pulled in by nothing.
13
- seeds = scan.files
14
- .filter((f) => (facts.fanOut[f.path] || 0) > 0 && (facts.fanIn[f.path] || 0) === 0)
15
- .map((f) => f.path)
16
- .slice(0, 5);
17
- }
18
- if (!seeds.length) {
19
- // Last resort: the most depended-upon files.
20
- seeds = facts.hubs.slice(0, 3).map((h) => h.path);
21
- }
22
-
23
- const depth = new Map();
24
- const visits = new Map();
25
- const queue = [];
26
- for (const s of seeds) {
27
- depth.set(s, 0);
28
- queue.push(s);
29
- }
30
-
31
- while (queue.length) {
32
- const cur = queue.shift();
33
- const d = depth.get(cur);
34
- visits.set(cur, (visits.get(cur) || 0) + 1);
35
- if (visits.get(cur) > 4) continue; // circular chains give up here
36
- const next = d + 1;
37
- if (next > MAX_DEPTH) continue; // and nobody sinks past the basement
38
- for (const nxt of facts.importsOf[cur] || []) {
39
- if ((depth.get(nxt) ?? -1) < next) {
40
- depth.set(nxt, next);
41
- queue.push(nxt);
42
- }
8
+ let seeds = facts.entries.slice();
9
+ if (!seeds.length) {
10
+ // No recognized entry points — start from the tops of the import chains:
11
+ // files that pull others in but are pulled in by nothing.
12
+ seeds = scan.files
13
+ .filter((f) => (facts.fanOut[f.path] || 0) > 0 && (facts.fanIn[f.path] || 0) === 0)
14
+ .map((f) => f.path)
15
+ .slice(0, 5);
43
16
  }
44
- }
45
-
46
- // Depths can skip values (cycle members sink several floors at once), and
47
- // for..of over a sparse array hands holes to sort() — compact first.
48
- const sparse = [];
49
- for (const [path, d] of depth) {
50
- (sparse[d] ||= []).push(path);
51
- }
52
- const layers = sparse.filter(Boolean);
53
- for (const l of layers) l.sort((a, b) => a.localeCompare(b));
54
-
55
- const unreachable = scan.files
56
- .map((f) => f.path)
57
- .filter((p) => !depth.has(p))
58
- .sort();
59
-
60
- return { layers, unreachable, seeds };
17
+ if (!seeds.length) {
18
+ // Last resort: the most depended-upon files.
19
+ seeds = facts.hubs.slice(0, 3).map((h) => h.path);
20
+ }
21
+ const depth = new Map();
22
+ const visits = new Map();
23
+ const queue = [];
24
+ for (const s of seeds) {
25
+ depth.set(s, 0);
26
+ queue.push(s);
27
+ }
28
+ while (queue.length) {
29
+ const cur = queue.shift();
30
+ const d = depth.get(cur);
31
+ visits.set(cur, (visits.get(cur) || 0) + 1);
32
+ if (visits.get(cur) > 4)
33
+ continue; // circular chains give up here
34
+ const next = d + 1;
35
+ if (next > MAX_DEPTH)
36
+ continue; // and nobody sinks past the basement
37
+ for (const nxt of facts.importsOf[cur] || []) {
38
+ if ((depth.get(nxt) ?? -1) < next) {
39
+ depth.set(nxt, next);
40
+ queue.push(nxt);
41
+ }
42
+ }
43
+ }
44
+ // Depths can skip values (cycle members sink several floors at once), and
45
+ // for..of over a sparse array hands holes to sort() — compact first.
46
+ const sparse = [];
47
+ for (const [path, d] of depth) {
48
+ (sparse[d] ||= []).push(path);
49
+ }
50
+ const layers = sparse.filter(Boolean);
51
+ for (const l of layers)
52
+ l.sort((a, b) => a.localeCompare(b));
53
+ const unreachable = scan.files
54
+ .map((f) => f.path)
55
+ .filter((p) => !depth.has(p))
56
+ .sort();
57
+ return { layers, unreachable, seeds };
61
58
  }
62
-
63
59
  const MAX_DEPTH = 12;
64
-
65
60
  // Written observations, in the order a senior dev would mention them.
66
61
  // Each: { id, tone: 'good' | 'note' | 'warn', severity: 'info' | 'low' | 'medium' | 'high', paths: string[], title, detail }.
67
62
  export function detectPatterns(scan, facts, manifest, layersInfo) {
68
- const out = [];
69
- const topHub = facts.hubs[0];
70
-
71
- if (topHub && topHub.fanIn >= 5) {
72
- out.push({
73
- id: 'hub-and-spoke',
74
- tone: 'note',
75
- severity: 'info',
76
- paths: [topHub.path],
77
- title: 'Hub and spoke',
78
- detail: `\`${topHub.path}\` holds ${topHub.fanIn} dependents — this repo orbits a core. Learn that file and most of the rest makes sense.`,
79
- });
80
- }
81
-
82
- const god = scan.files
83
- .filter((f) => (facts.fanIn[f.path] || 0) + (facts.fanOut[f.path] || 0) >= 12)
84
- .sort((a, b) => ((facts.fanIn[b.path] || 0) + (facts.fanOut[b.path] || 0)) - ((facts.fanIn[a.path] || 0) + (facts.fanOut[a.path] || 0)));
85
-
86
- if (god.length) {
87
- out.push({
88
- id: 'god-files',
89
- tone: 'warn',
90
- severity: 'medium',
91
- paths: god.map((f) => f.path),
92
- title: god.length > 1 ? 'God files' : 'God file',
93
- detail: `${god.slice(0, 3).map((f) => `\`${f.path}\``).join(', ')} — heavily connected in both directions. Everyone's problem, nobody's owner. Touch gently.`,
94
- });
95
- }
96
-
97
- if (layersInfo && layersInfo.layers.length >= 3) {
98
- out.push({
99
- id: 'layered-shape',
100
- tone: 'good',
101
- severity: 'info',
102
- paths: [],
103
- title: 'A layered shape',
104
- detail: `The code reads in ${layersInfo.layers.length} strata from the door to the deepest leaf. That is an architecture someone can draw — always a good sign.`,
105
- });
106
- if (layersInfo.unreachable.length) {
107
- out.push({
108
- id: 'unreachable',
109
- tone: 'note',
110
- severity: 'info',
111
- paths: layersInfo.unreachable,
112
- title: 'Off the beaten path',
113
- detail: `${layersInfo.unreachable.length} files can't be reached from any entry point — utilities awaiting adoption, or furniture from an older layout.`,
114
- });
63
+ const out = [];
64
+ const topHub = facts.hubs[0];
65
+ if (topHub && topHub.fanIn >= 5) {
66
+ out.push({
67
+ id: 'hub-and-spoke',
68
+ tone: 'note',
69
+ severity: 'info',
70
+ paths: [topHub.path],
71
+ title: 'Hub and spoke',
72
+ detail: `\`${topHub.path}\` holds ${topHub.fanIn} dependents — this repo orbits a core. Learn that file and most of the rest makes sense.`,
73
+ });
74
+ }
75
+ const god = scan.files
76
+ .filter((f) => (facts.fanIn[f.path] || 0) + (facts.fanOut[f.path] || 0) >= 12)
77
+ .sort((a, b) => ((facts.fanIn[b.path] || 0) + (facts.fanOut[b.path] || 0)) - ((facts.fanIn[a.path] || 0) + (facts.fanOut[a.path] || 0)));
78
+ if (god.length) {
79
+ out.push({
80
+ id: 'god-files',
81
+ tone: 'warn',
82
+ severity: 'medium',
83
+ paths: god.map((f) => f.path),
84
+ title: god.length > 1 ? 'God files' : 'God file',
85
+ detail: `${god.slice(0, 3).map((f) => `\`${f.path}\``).join(', ')} — heavily connected in both directions. Everyone's problem, nobody's owner. Touch gently.`,
86
+ });
87
+ }
88
+ if (layersInfo && layersInfo.layers.length >= 3) {
89
+ out.push({
90
+ id: 'layered-shape',
91
+ tone: 'good',
92
+ severity: 'info',
93
+ paths: [],
94
+ title: 'A layered shape',
95
+ detail: `The code reads in ${layersInfo.layers.length} strata from the door to the deepest leaf. That is an architecture someone can draw — always a good sign.`,
96
+ });
97
+ if (layersInfo.unreachable.length) {
98
+ out.push({
99
+ id: 'unreachable',
100
+ tone: 'note',
101
+ severity: 'info',
102
+ paths: layersInfo.unreachable,
103
+ title: 'Off the beaten path',
104
+ detail: `${layersInfo.unreachable.length} files can't be reached from any entry point — utilities awaiting adoption, or furniture from an older layout.`,
105
+ });
106
+ }
107
+ }
108
+ if (facts.cycles.length) {
109
+ out.push({
110
+ id: 'cycles',
111
+ tone: 'warn',
112
+ severity: 'high',
113
+ paths: Array.from(new Set(facts.cycles.flat())),
114
+ title: 'Circular dependencies',
115
+ detail: `${facts.cycles.length} ${facts.cycles.length === 1 ? 'loop' : 'loops'} where files import each other; the biggest tangles ${facts.cycles[0].length} files. Untangle before a big refactor.`,
116
+ });
117
+ }
118
+ const barrels = scan.files.filter((f) => /^index\.[jt]sx?$/.test(f.name) &&
119
+ f.functions.length === 0 &&
120
+ (facts.fanIn[f.path] || 0) >= 2 &&
121
+ (facts.fanOut[f.path] || 0) >= 2);
122
+ if (barrels.length) {
123
+ out.push({
124
+ id: 'barrels',
125
+ tone: 'note',
126
+ severity: 'info',
127
+ paths: barrels.map((f) => f.path),
128
+ title: 'Barrel files',
129
+ detail: `${barrels.slice(0, 3).map((f) => `\`${f.path}\``).join(', ')} mostly re-export other modules. Convenient for imports, one extra hop when you're hunting a definition.`,
130
+ });
131
+ }
132
+ const testCount = scan.files.filter((f) => /(^|[._-])(test|spec|tests|__tests__)([._-]|\/|$)/i.test(f.path)).length;
133
+ if (testCount > 0) {
134
+ const pct = Math.round((testCount / Math.max(1, scan.stats.filesParsed)) * 100);
135
+ out.push({
136
+ id: 'test-shadow',
137
+ tone: 'good',
138
+ severity: 'info',
139
+ paths: [],
140
+ title: 'A test shadow',
141
+ detail: `${testCount} test ${testCount === 1 ? 'file' : 'files'} against ${scan.stats.filesParsed} code files (~${pct}%). Read tests to learn intended behavior, code to learn actual behavior.`,
142
+ });
143
+ }
144
+ else {
145
+ out.push({
146
+ id: 'no-tests',
147
+ tone: 'warn',
148
+ severity: 'medium',
149
+ paths: [],
150
+ title: 'No tests in sight',
151
+ detail: 'Nothing matches the usual test/spec naming. Onboarding risk: intended behavior lives only inside the code.',
152
+ });
115
153
  }
116
- }
117
-
118
- if (facts.cycles.length) {
119
- out.push({
120
- id: 'cycles',
121
- tone: 'warn',
122
- severity: 'high',
123
- paths: Array.from(new Set(facts.cycles.flat())),
124
- title: 'Circular dependencies',
125
- detail: `${facts.cycles.length} ${facts.cycles.length === 1 ? 'loop' : 'loops'} where files import each other; the biggest tangles ${facts.cycles[0].length} files. Untangle before a big refactor.`,
126
- });
127
- }
128
-
129
- const barrels = scan.files.filter(
130
- (f) =>
131
- /^index\.[jt]sx?$/.test(f.name) &&
132
- f.functions.length === 0 &&
133
- (facts.fanIn[f.path] || 0) >= 2 &&
134
- (facts.fanOut[f.path] || 0) >= 2
135
- );
136
- if (barrels.length) {
137
- out.push({
138
- id: 'barrels',
139
- tone: 'note',
140
- severity: 'info',
141
- paths: barrels.map((f) => f.path),
142
- title: 'Barrel files',
143
- detail: `${barrels.slice(0, 3).map((f) => `\`${f.path}\``).join(', ')} mostly re-export other modules. Convenient for imports, one extra hop when you're hunting a definition.`,
144
- });
145
- }
146
-
147
- const testCount = scan.files.filter((f) => /(^|[._-])(test|spec|tests|__tests__)([._-]|\/|$)/i.test(f.path)).length;
148
- if (testCount > 0) {
149
- const pct = Math.round((testCount / Math.max(1, scan.stats.filesParsed)) * 100);
150
- out.push({
151
- id: 'test-shadow',
152
- tone: 'good',
153
- severity: 'info',
154
- paths: [],
155
- title: 'A test shadow',
156
- detail: `${testCount} test ${testCount === 1 ? 'file' : 'files'} against ${scan.stats.filesParsed} code files (~${pct}%). Read tests to learn intended behavior, code to learn actual behavior.`,
157
- });
158
- } else {
159
- out.push({
160
- id: 'no-tests',
161
- tone: 'warn',
162
- severity: 'medium',
163
- paths: [],
164
- title: 'No tests in sight',
165
- detail: 'Nothing matches the usual test/spec naming. Onboarding risk: intended behavior lives only inside the code.',
166
- });
167
- }
168
-
169
- if (facts.untestedHubs?.length) {
170
- out.push({
171
- id: 'untested-hubs',
172
- tone: 'warn',
173
- severity: 'high',
174
- paths: facts.untestedHubs.map((h) => h.path),
175
- title: 'Untested hubs',
176
- detail: `${facts.untestedHubs.length} load-bearing ${facts.untestedHubs.length === 1 ? 'file is' : 'files are'} not reached by any test. Changing them has wide blast radius with no test safety net.`,
177
- });
178
- }
179
-
180
- if (facts.deadExports?.length) {
181
- const deadFiles = Array.from(new Set(facts.deadExports.map((d) => d.file)));
182
- out.push({
183
- id: 'dead-exports',
184
- tone: 'note',
185
- severity: 'low',
186
- paths: deadFiles,
187
- title: 'Unused exports',
188
- detail: `${facts.deadExports.length} exported ${facts.deadExports.length === 1 ? 'symbol is' : 'symbols are'} never imported anywhere in the project. Potential dead code or unexposed public API.`,
189
- });
190
- }
191
-
192
- if (facts.depsDrift?.undeclaredImported?.length) {
193
- out.push({
194
- id: 'undeclared-deps',
195
- tone: 'warn',
196
- severity: 'high',
197
- paths: [],
198
- title: 'Undeclared dependencies',
199
- detail: `Imported packages not listed in package manifest: ${facts.depsDrift.undeclaredImported.slice(0, 4).map((d) => `\`${d}\``).join(', ')}. Risk of build failure in CI/clean environments.`,
200
- });
201
- }
202
-
203
- if (facts.depsDrift?.unusedDeclared?.length) {
204
- out.push({
205
- id: 'unused-deps',
206
- tone: 'note',
207
- severity: 'low',
208
- paths: [],
209
- title: 'Unused dependencies',
210
- detail: `Declared dependencies not directly imported in source: ${facts.depsDrift.unusedDeclared.slice(0, 5).map((d) => `\`${d}\``).join(', ')}.`,
211
- });
212
- }
213
-
214
- if (facts.orphans.length) {
215
- out.push({
216
- id: 'orphans',
217
- tone: 'note',
218
- severity: 'info',
219
- paths: facts.orphans,
220
- title: 'Unclaimed territory',
221
- detail: `${facts.orphans.length} ${facts.orphans.length === 1 ? 'file is' : 'files are'} imported by nothing. Dead code, or doors the naming rules didn't recognize.`,
222
- });
223
- }
224
-
225
- const topExt = scan.externals[0];
226
- if (topExt && topExt.usedBy.length >= 3) {
227
- out.push({
228
- id: 'top-external',
229
- tone: 'note',
230
- severity: 'info',
231
- paths: topExt.usedBy,
232
- title: 'Heaviest outside anchor',
233
- detail: `\`${topExt.name}\` is pulled in by ${topExt.usedBy.length} files — the external dependency this repo would miss most.`,
234
- });
235
- }
236
-
237
- if (manifest?.services?.length) {
238
- out.push({
239
- id: 'services',
240
- tone: 'note',
241
- severity: 'info',
242
- paths: [],
243
- title: 'Runs as services',
244
- detail: `${manifest.services.length} ${manifest.services.length === 1 ? 'service' : 'services'} declared: ${manifest.services.map((s) => s.name).join(', ')}.`,
245
- });
246
- }
247
-
248
- return out;
154
+ if (facts.untestedHubs?.length) {
155
+ out.push({
156
+ id: 'untested-hubs',
157
+ tone: 'warn',
158
+ severity: 'high',
159
+ paths: facts.untestedHubs.map((h) => h.path),
160
+ title: 'Untested hubs',
161
+ detail: `${facts.untestedHubs.length} load-bearing ${facts.untestedHubs.length === 1 ? 'file is' : 'files are'} not reachable through test imports. Check whether tests exercise these files before changing them.`,
162
+ });
163
+ }
164
+ if (facts.deadExports?.length) {
165
+ const deadFiles = Array.from(new Set(facts.deadExports.map((d) => d.file)));
166
+ out.push({
167
+ id: 'dead-exports',
168
+ tone: 'note',
169
+ severity: 'low',
170
+ paths: deadFiles,
171
+ title: 'Unused exports',
172
+ detail: `${facts.deadExports.length} exported ${facts.deadExports.length === 1 ? 'symbol is' : 'symbols are'} never imported anywhere in the project. Potential dead code or unexposed public API.`,
173
+ });
174
+ }
175
+ if (facts.depsDrift?.undeclaredImported?.length) {
176
+ out.push({
177
+ id: 'undeclared-deps',
178
+ tone: 'warn',
179
+ severity: 'high',
180
+ paths: [],
181
+ title: 'Undeclared dependencies',
182
+ detail: `Imported packages not listed in package manifest: ${facts.depsDrift.undeclaredImported.slice(0, 4).map((d) => `\`${d}\``).join(', ')}. Risk of build failure in CI/clean environments.`,
183
+ });
184
+ }
185
+ if (facts.depsDrift?.unusedDeclared?.length) {
186
+ out.push({
187
+ id: 'unused-deps',
188
+ tone: 'note',
189
+ severity: 'low',
190
+ paths: [],
191
+ title: 'Unused dependencies',
192
+ detail: `Declared dependencies not directly imported in source: ${facts.depsDrift.unusedDeclared.slice(0, 5).map((d) => `\`${d}\``).join(', ')}.`,
193
+ });
194
+ }
195
+ if (facts.orphans.length) {
196
+ out.push({
197
+ id: 'orphans',
198
+ tone: 'note',
199
+ severity: 'info',
200
+ paths: facts.orphans,
201
+ title: 'Unclaimed territory',
202
+ detail: `${facts.orphans.length} ${facts.orphans.length === 1 ? 'file is' : 'files are'} imported by nothing. Dead code, or doors the naming rules didn't recognize.`,
203
+ });
204
+ }
205
+ const topExt = scan.externals[0];
206
+ if (topExt && topExt.usedBy.length >= 3) {
207
+ out.push({
208
+ id: 'top-external',
209
+ tone: 'note',
210
+ severity: 'info',
211
+ paths: topExt.usedBy,
212
+ title: 'Heaviest outside anchor',
213
+ detail: `\`${topExt.name}\` is pulled in by ${topExt.usedBy.length} files — the external dependency this repo would miss most.`,
214
+ });
215
+ }
216
+ if (manifest?.services?.length) {
217
+ out.push({
218
+ id: 'services',
219
+ tone: 'note',
220
+ severity: 'info',
221
+ paths: [],
222
+ title: 'Runs as services',
223
+ detail: `${manifest.services.length} ${manifest.services.length === 1 ? 'service' : 'services'} declared: ${manifest.services.map((s) => s.name).join(', ')}.`,
224
+ });
225
+ }
226
+ return out;
249
227
  }
250
-
251
228
  // Folder-to-folder traffic as a matrix for the heat grid. Folders are the
252
229
  // top-level ones, ordered by how much traffic they see in total.
253
230
  export function couplingMatrix(scan, facts, maxFolders = 8) {
254
- const traffic = new Map();
255
- for (const fe of facts.folderEdges) {
256
- traffic.set(fe.from, (traffic.get(fe.from) || 0) + fe.count);
257
- traffic.set(fe.to, (traffic.get(fe.to) || 0) + fe.count);
258
- }
259
- const folders = [...traffic.entries()]
260
- .sort((a, b) => b[1] - a[1])
261
- .slice(0, maxFolders)
262
- .map(([name]) => name);
263
-
264
- const counts = new Map();
265
- let max = 1;
266
- for (const fe of facts.folderEdges) {
267
- if (!folders.includes(fe.from) || !folders.includes(fe.to)) continue;
268
- counts.set(fe.from + '->' + fe.to, fe.count);
269
- max = Math.max(max, fe.count);
270
- }
271
- return { folders, counts, max };
231
+ const traffic = new Map();
232
+ for (const fe of facts.folderEdges) {
233
+ traffic.set(fe.from, (traffic.get(fe.from) || 0) + fe.count);
234
+ traffic.set(fe.to, (traffic.get(fe.to) || 0) + fe.count);
235
+ }
236
+ const folders = [...traffic.entries()]
237
+ .sort((a, b) => b[1] - a[1])
238
+ .slice(0, maxFolders)
239
+ .map(([name]) => name);
240
+ const counts = new Map();
241
+ let max = 1;
242
+ for (const fe of facts.folderEdges) {
243
+ if (!folders.includes(fe.from) || !folders.includes(fe.to))
244
+ continue;
245
+ counts.set(fe.from + '->' + fe.to, fe.count);
246
+ max = Math.max(max, fe.count);
247
+ }
248
+ return { folders, counts, max };
272
249
  }
250
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/shared/analyzer/patterns.ts"],"names":[],"mappings":"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","sourcesContent":["// Pattern reading: turns the raw import graph into observations about the\n// repo's shape — its depth layers, its load-bearing files, its smells.\n// Everything here is pure functions over scan + facts.\n\n// Assigns every reachable file a depth: the length of the longest import\n// chain from an entry point. Files no entry can reach land in `unreachable`.\n// Cycles are survived by capping how often a file may be relaxed.\nexport function computeLayers(scan, facts) {\n let seeds = facts.entries.slice();\n if (!seeds.length) {\n // No recognized entry points — start from the tops of the import chains:\n // files that pull others in but are pulled in by nothing.\n seeds = scan.files\n .filter((f) => (facts.fanOut[f.path] || 0) > 0 && (facts.fanIn[f.path] || 0) === 0)\n .map((f) => f.path)\n .slice(0, 5);\n }\n if (!seeds.length) {\n // Last resort: the most depended-upon files.\n seeds = facts.hubs.slice(0, 3).map((h) => h.path);\n }\n\n const depth = new Map();\n const visits = new Map();\n const queue = [];\n for (const s of seeds) {\n depth.set(s, 0);\n queue.push(s);\n }\n\n while (queue.length) {\n const cur = queue.shift();\n const d = depth.get(cur);\n visits.set(cur, (visits.get(cur) || 0) + 1);\n if (visits.get(cur) > 4) continue; // circular chains give up here\n const next = d + 1;\n if (next > MAX_DEPTH) continue; // and nobody sinks past the basement\n for (const nxt of facts.importsOf[cur] || []) {\n if ((depth.get(nxt) ?? -1) < next) {\n depth.set(nxt, next);\n queue.push(nxt);\n }\n }\n }\n\n // Depths can skip values (cycle members sink several floors at once), and\n // for..of over a sparse array hands holes to sort() — compact first.\n const sparse = [];\n for (const [path, d] of depth) {\n (sparse[d] ||= []).push(path);\n }\n const layers = sparse.filter(Boolean);\n for (const l of layers) l.sort((a, b) => a.localeCompare(b));\n\n const unreachable = scan.files\n .map((f) => f.path)\n .filter((p) => !depth.has(p))\n .sort();\n\n return { layers, unreachable, seeds };\n}\n\nconst MAX_DEPTH = 12;\n\n// Written observations, in the order a senior dev would mention them.\n// Each: { id, tone: 'good' | 'note' | 'warn', severity: 'info' | 'low' | 'medium' | 'high', paths: string[], title, detail }.\nexport function detectPatterns(scan, facts, manifest, layersInfo) {\n const out = [];\n const topHub = facts.hubs[0];\n\n if (topHub && topHub.fanIn >= 5) {\n out.push({\n id: 'hub-and-spoke',\n tone: 'note',\n severity: 'info',\n paths: [topHub.path],\n title: 'Hub and spoke',\n detail: `\\`${topHub.path}\\` holds ${topHub.fanIn} dependents — this repo orbits a core. Learn that file and most of the rest makes sense.`,\n });\n }\n\n const god = scan.files\n .filter((f) => (facts.fanIn[f.path] || 0) + (facts.fanOut[f.path] || 0) >= 12)\n .sort((a, b) => ((facts.fanIn[b.path] || 0) + (facts.fanOut[b.path] || 0)) - ((facts.fanIn[a.path] || 0) + (facts.fanOut[a.path] || 0)));\n\n if (god.length) {\n out.push({\n id: 'god-files',\n tone: 'warn',\n severity: 'medium',\n paths: god.map((f) => f.path),\n title: god.length > 1 ? 'God files' : 'God file',\n detail: `${god.slice(0, 3).map((f) => `\\`${f.path}\\``).join(', ')} — heavily connected in both directions. Everyone's problem, nobody's owner. Touch gently.`,\n });\n }\n\n if (layersInfo && layersInfo.layers.length >= 3) {\n out.push({\n id: 'layered-shape',\n tone: 'good',\n severity: 'info',\n paths: [],\n title: 'A layered shape',\n detail: `The code reads in ${layersInfo.layers.length} strata from the door to the deepest leaf. That is an architecture someone can draw — always a good sign.`,\n });\n if (layersInfo.unreachable.length) {\n out.push({\n id: 'unreachable',\n tone: 'note',\n severity: 'info',\n paths: layersInfo.unreachable,\n title: 'Off the beaten path',\n detail: `${layersInfo.unreachable.length} files can't be reached from any entry point — utilities awaiting adoption, or furniture from an older layout.`,\n });\n }\n }\n\n if (facts.cycles.length) {\n out.push({\n id: 'cycles',\n tone: 'warn',\n severity: 'high',\n paths: Array.from(new Set(facts.cycles.flat())),\n title: 'Circular dependencies',\n detail: `${facts.cycles.length} ${facts.cycles.length === 1 ? 'loop' : 'loops'} where files import each other; the biggest tangles ${facts.cycles[0].length} files. Untangle before a big refactor.`,\n });\n }\n\n const barrels = scan.files.filter(\n (f) =>\n /^index\\.[jt]sx?$/.test(f.name) &&\n f.functions.length === 0 &&\n (facts.fanIn[f.path] || 0) >= 2 &&\n (facts.fanOut[f.path] || 0) >= 2\n );\n if (barrels.length) {\n out.push({\n id: 'barrels',\n tone: 'note',\n severity: 'info',\n paths: barrels.map((f) => f.path),\n title: 'Barrel files',\n detail: `${barrels.slice(0, 3).map((f) => `\\`${f.path}\\``).join(', ')} mostly re-export other modules. Convenient for imports, one extra hop when you're hunting a definition.`,\n });\n }\n\n const testCount = scan.files.filter((f) => /(^|[._-])(test|spec|tests|__tests__)([._-]|\\/|$)/i.test(f.path)).length;\n if (testCount > 0) {\n const pct = Math.round((testCount / Math.max(1, scan.stats.filesParsed)) * 100);\n out.push({\n id: 'test-shadow',\n tone: 'good',\n severity: 'info',\n paths: [],\n title: 'A test shadow',\n detail: `${testCount} test ${testCount === 1 ? 'file' : 'files'} against ${scan.stats.filesParsed} code files (~${pct}%). Read tests to learn intended behavior, code to learn actual behavior.`,\n });\n } else {\n out.push({\n id: 'no-tests',\n tone: 'warn',\n severity: 'medium',\n paths: [],\n title: 'No tests in sight',\n detail: 'Nothing matches the usual test/spec naming. Onboarding risk: intended behavior lives only inside the code.',\n });\n }\n\n if (facts.untestedHubs?.length) {\n out.push({\n id: 'untested-hubs',\n tone: 'warn',\n severity: 'high',\n paths: facts.untestedHubs.map((h) => h.path),\n title: 'Untested hubs',\n detail: `${facts.untestedHubs.length} load-bearing ${facts.untestedHubs.length === 1 ? 'file is' : 'files are'} not reachable through test imports. Check whether tests exercise these files before changing them.`,\n });\n }\n\n if (facts.deadExports?.length) {\n const deadFiles = Array.from(new Set(facts.deadExports.map((d) => d.file)));\n out.push({\n id: 'dead-exports',\n tone: 'note',\n severity: 'low',\n paths: deadFiles,\n title: 'Unused exports',\n detail: `${facts.deadExports.length} exported ${facts.deadExports.length === 1 ? 'symbol is' : 'symbols are'} never imported anywhere in the project. Potential dead code or unexposed public API.`,\n });\n }\n\n if (facts.depsDrift?.undeclaredImported?.length) {\n out.push({\n id: 'undeclared-deps',\n tone: 'warn',\n severity: 'high',\n paths: [],\n title: 'Undeclared dependencies',\n detail: `Imported packages not listed in package manifest: ${facts.depsDrift.undeclaredImported.slice(0, 4).map((d) => `\\`${d}\\``).join(', ')}. Risk of build failure in CI/clean environments.`,\n });\n }\n\n if (facts.depsDrift?.unusedDeclared?.length) {\n out.push({\n id: 'unused-deps',\n tone: 'note',\n severity: 'low',\n paths: [],\n title: 'Unused dependencies',\n detail: `Declared dependencies not directly imported in source: ${facts.depsDrift.unusedDeclared.slice(0, 5).map((d) => `\\`${d}\\``).join(', ')}.`,\n });\n }\n\n if (facts.orphans.length) {\n out.push({\n id: 'orphans',\n tone: 'note',\n severity: 'info',\n paths: facts.orphans,\n title: 'Unclaimed territory',\n detail: `${facts.orphans.length} ${facts.orphans.length === 1 ? 'file is' : 'files are'} imported by nothing. Dead code, or doors the naming rules didn't recognize.`,\n });\n }\n\n const topExt = scan.externals[0];\n if (topExt && topExt.usedBy.length >= 3) {\n out.push({\n id: 'top-external',\n tone: 'note',\n severity: 'info',\n paths: topExt.usedBy,\n title: 'Heaviest outside anchor',\n detail: `\\`${topExt.name}\\` is pulled in by ${topExt.usedBy.length} files — the external dependency this repo would miss most.`,\n });\n }\n\n if (manifest?.services?.length) {\n out.push({\n id: 'services',\n tone: 'note',\n severity: 'info',\n paths: [],\n title: 'Runs as services',\n detail: `${manifest.services.length} ${manifest.services.length === 1 ? 'service' : 'services'} declared: ${manifest.services.map((s) => s.name).join(', ')}.`,\n });\n }\n\n return out;\n}\n\n// Folder-to-folder traffic as a matrix for the heat grid. Folders are the\n// top-level ones, ordered by how much traffic they see in total.\nexport function couplingMatrix(scan, facts, maxFolders = 8) {\n const traffic = new Map();\n for (const fe of facts.folderEdges) {\n traffic.set(fe.from, (traffic.get(fe.from) || 0) + fe.count);\n traffic.set(fe.to, (traffic.get(fe.to) || 0) + fe.count);\n }\n const folders = [...traffic.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, maxFolders)\n .map(([name]) => name);\n\n const counts = new Map();\n let max = 1;\n for (const fe of facts.folderEdges) {\n if (!folders.includes(fe.from) || !folders.includes(fe.to)) continue;\n counts.set(fe.from + '->' + fe.to, fe.count);\n max = Math.max(max, fe.count);\n }\n return { folders, counts, max };\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import type { FileSource, ScanOptions, ImportEdge, ScannedFile } from '../contracts.js';
2
+ export { DEFAULT_LIMITS } from './scanControl.js';
3
+ export declare function scanRepo(source: FileSource, options?: ScanOptions): Promise<{
4
+ root: string;
5
+ name: any;
6
+ scannedAt: string;
7
+ stats: {
8
+ filesTotal: number;
9
+ filesParsed: number;
10
+ skipped: number;
11
+ skips: {
12
+ ignored: number;
13
+ vendorDir: number;
14
+ notSource: number;
15
+ listFailed: number;
16
+ notCode: number;
17
+ readFailed: number;
18
+ tooLarge: number;
19
+ analyzeFailed: number;
20
+ };
21
+ truncated: any;
22
+ edgeCount: number;
23
+ imports: {
24
+ total: number;
25
+ internal: number;
26
+ external: number;
27
+ unresolved: number;
28
+ confidence: number;
29
+ worst: any[];
30
+ };
31
+ tookMs: number;
32
+ languages: Record<string, number>;
33
+ languageLoc: Record<string, number>;
34
+ };
35
+ allFiles: string[];
36
+ files: ScannedFile[];
37
+ edges: ImportEdge[];
38
+ externals: {
39
+ name: any;
40
+ usedBy: any[];
41
+ }[];
42
+ folders: {
43
+ path: string;
44
+ name: string;
45
+ depth: number;
46
+ fileCount: number;
47
+ loc: number;
48
+ comment: number;
49
+ blank: number;
50
+ size: number;
51
+ langs: Record<string, number>;
52
+ hasReadme: boolean;
53
+ docRatio: number;
54
+ }[];
55
+ workflows: any[];
56
+ sbom: any;
57
+ license: any;
58
+ licenseReport: any;
59
+ } & {
60
+ tempId?: string;
61
+ gitUrl?: string;
62
+ }>;