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,62 +1,55 @@
1
1
  // Turns scan results into Mermaid flowchart source. Kept separate from the
2
2
  // UI so the exact same diagrams can be produced in Node (tests, exports)
3
3
  // and in the browser.
4
-
5
4
  import { baseName, dirOf, topFolderOf } from '../analyzer/pathUtil.js';
6
5
  import { factIndex, scanIndex } from '../analyzer/graph.js';
7
-
8
6
  // ---- theming ---------------------------------------------------------------
9
7
  // Every diagram embeds its own init directive, so exported SVGs carry the
10
8
  // theme too. The app flips `currentTheme`; Node tests can do the same.
11
-
12
9
  let currentTheme = 'light';
13
-
14
10
  export function setDiagramTheme(theme) {
15
- currentTheme = theme === 'dark' ? 'dark' : 'light';
11
+ currentTheme = theme === 'dark' ? 'dark' : 'light';
16
12
  }
17
-
18
13
  export function getDiagramTheme() {
19
- return currentTheme;
14
+ return currentTheme;
20
15
  }
21
-
22
16
  const PALETTES = {
23
- light: {
24
- background: '#f7f4ed', node: '#fffdf7', border: '#3d3a33', text: '#2a2721',
25
- line: '#8a8577', cluster: '#efe9dc66', clusterBorder: '#8a8577',
26
- entry: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:2px,color:#1d3a2a',
27
- hub: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:2px,color:#5c3a10',
28
- cycle: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',
29
- ghost: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',
30
- self: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:3px,color:#1d3a2a',
31
- ext: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',
32
- blank: 'fill:transparent,stroke:transparent,color:transparent',
33
- note: 'fill:transparent,stroke:transparent,color:#8a8577',
34
- r0: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:1.5px,color:#1d3a2a',
35
- r1: 'fill:#fffdf7,stroke:#8a8577,stroke-width:1px,color:#2a2721',
36
- r2: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:1.5px,color:#5c3a10',
37
- r3: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',
38
- },
39
- dark: {
40
- background: '#211e19', node: '#2b2721', border: '#b8b0a0', text: '#ece7db',
41
- line: '#8a8577', cluster: '#2b272166', clusterBorder: '#6b6558',
42
- entry: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:2px,color:#cfe6d6',
43
- hub: 'fill:#463617,stroke:#d9a75f,stroke-width:2px,color:#f0d9ae',
44
- cycle: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',
45
- ghost: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',
46
- self: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:3px,color:#cfe6d6',
47
- ext: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',
48
- blank: 'fill:transparent,stroke:transparent,color:transparent',
49
- note: 'fill:transparent,stroke:transparent,color:#9b9484',
50
- r0: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:1.5px,color:#cfe6d6',
51
- r1: 'fill:#2b2721,stroke:#8a8577,stroke-width:1px,color:#ece7db',
52
- r2: 'fill:#463617,stroke:#d9a75f,stroke-width:1.5px,color:#f0d9ae',
53
- r3: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',
54
- },
17
+ light: {
18
+ background: '#f7f4ed', node: '#fffdf7', border: '#3d3a33', text: '#2a2721',
19
+ line: '#8a8577', cluster: '#efe9dc66', clusterBorder: '#8a8577',
20
+ entry: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:2px,color:#1d3a2a',
21
+ hub: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:2px,color:#5c3a10',
22
+ cycle: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',
23
+ ghost: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',
24
+ self: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:3px,color:#1d3a2a',
25
+ ext: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',
26
+ blank: 'fill:transparent,stroke:transparent,color:transparent',
27
+ note: 'fill:transparent,stroke:transparent,color:#8a8577',
28
+ r0: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:1.5px,color:#1d3a2a',
29
+ r1: 'fill:#fffdf7,stroke:#8a8577,stroke-width:1px,color:#2a2721',
30
+ r2: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:1.5px,color:#5c3a10',
31
+ r3: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',
32
+ },
33
+ dark: {
34
+ background: '#211e19', node: '#2b2721', border: '#b8b0a0', text: '#ece7db',
35
+ line: '#8a8577', cluster: '#2b272166', clusterBorder: '#6b6558',
36
+ entry: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:2px,color:#cfe6d6',
37
+ hub: 'fill:#463617,stroke:#d9a75f,stroke-width:2px,color:#f0d9ae',
38
+ cycle: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',
39
+ ghost: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',
40
+ self: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:3px,color:#cfe6d6',
41
+ ext: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',
42
+ blank: 'fill:transparent,stroke:transparent,color:transparent',
43
+ note: 'fill:transparent,stroke:transparent,color:#9b9484',
44
+ r0: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:1.5px,color:#cfe6d6',
45
+ r1: 'fill:#2b2721,stroke:#8a8577,stroke-width:1px,color:#ece7db',
46
+ r2: 'fill:#463617,stroke:#d9a75f,stroke-width:1.5px,color:#f0d9ae',
47
+ r3: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',
48
+ },
55
49
  };
56
-
57
50
  function themeBlock() {
58
- const p = PALETTES[currentTheme];
59
- return `%%{init: {
51
+ const p = PALETTES[currentTheme];
52
+ return `%%{init: {
60
53
  'theme': 'base',
61
54
  'themeVariables': {
62
55
  'background': '${p.background}',
@@ -75,352 +68,334 @@ function themeBlock() {
75
68
  'flowchart': { 'curve': 'basis', 'htmlLabels': false, 'nodeSpacing': 42, 'rankSpacing': 52 }
76
69
  }}%%`;
77
70
  }
78
-
79
71
  // AI-generated diagrams get our theme injected after the fact, so a model's
80
72
  // sketch is indistinguishable from the hand-drawn ones.
81
73
  export function diagramThemeBlock() {
82
- return themeBlock();
74
+ return themeBlock();
83
75
  }
84
-
85
76
  function classDefLines() {
86
- const p = PALETTES[currentTheme];
87
- return [
88
- ` classDef entry ${p.entry}`,
89
- ` classDef hub ${p.hub}`,
90
- ` classDef cycle ${p.cycle}`,
91
- ` classDef ghost ${p.ghost}`,
92
- ` classDef self ${p.self}`,
93
- ` classDef ext ${p.ext}`,
94
- ` classDef blank ${p.blank}`,
95
- ` classDef note ${p.note}`,
96
- ` classDef r0 ${p.r0}`,
97
- ` classDef r1 ${p.r1}`,
98
- ` classDef r2 ${p.r2}`,
99
- ` classDef r3 ${p.r3}`,
100
- ];
77
+ const p = PALETTES[currentTheme];
78
+ return [
79
+ ` classDef entry ${p.entry}`,
80
+ ` classDef hub ${p.hub}`,
81
+ ` classDef cycle ${p.cycle}`,
82
+ ` classDef ghost ${p.ghost}`,
83
+ ` classDef self ${p.self}`,
84
+ ` classDef ext ${p.ext}`,
85
+ ` classDef blank ${p.blank}`,
86
+ ` classDef note ${p.note}`,
87
+ ` classDef r0 ${p.r0}`,
88
+ ` classDef r1 ${p.r1}`,
89
+ ` classDef r2 ${p.r2}`,
90
+ ` classDef r3 ${p.r3}`,
91
+ ];
101
92
  }
102
-
103
93
  const MAX_LABEL = 34;
104
-
105
94
  export function overviewDiagram(scan, facts) {
106
- const lines = [themeBlock(), 'flowchart LR'];
107
-
108
- // Nodes: top-level folders, sized by parsed file count.
109
- const folderStats = new Map();
110
- for (const f of scan.files) {
111
- const top = topFolderOf(f.path);
112
- folderStats.set(top, (folderStats.get(top) || 0) + 1);
113
- }
114
- const entryFolders = new Set(facts.entries.map((p) => topFolderOf(p)));
115
-
116
- const ids = new Map();
117
- let n = 0;
118
- const sorted = [...folderStats.entries()].sort((a, b) => b[1] - a[1]);
119
- for (const [folder, count] of sorted) {
120
- const id = 'f' + n++;
121
- ids.set(folder, id);
122
- const isEntry = entryFolders.has(folder);
123
- const label = esc(folder === '(root)' ? '(repo root)' : folder + '/') + '\\n' + count + (count === 1 ? ' file' : ' files');
124
- if (isEntry) {
125
- lines.push(` ${id}(["${label}"]):::entry`);
126
- } else {
127
- lines.push(` ${id}["${label}"]`);
95
+ const lines = [themeBlock(), 'flowchart LR'];
96
+ // Nodes: top-level folders, sized by parsed file count.
97
+ const folderStats = new Map();
98
+ for (const f of scan.files) {
99
+ const top = topFolderOf(f.path);
100
+ folderStats.set(top, (folderStats.get(top) || 0) + 1);
101
+ }
102
+ const entryFolders = new Set(facts.entries.map((p) => topFolderOf(p)));
103
+ const ids = new Map();
104
+ let n = 0;
105
+ const sorted = [...folderStats.entries()].sort((a, b) => b[1] - a[1]);
106
+ for (const [folder, count] of sorted) {
107
+ const id = 'f' + n++;
108
+ ids.set(folder, id);
109
+ const isEntry = entryFolders.has(folder);
110
+ const label = esc(folder === '(root)' ? '(repo root)' : folder + '/') + '\\n' + count + (count === 1 ? ' file' : ' files');
111
+ if (isEntry) {
112
+ lines.push(` ${id}(["${label}"]):::entry`);
113
+ }
114
+ else {
115
+ lines.push(` ${id}["${label}"]`);
116
+ }
128
117
  }
129
- }
130
-
131
- for (const fe of facts.folderEdges) {
132
- const a = ids.get(fe.from);
133
- const b = ids.get(fe.to);
134
- if (a === undefined || b === undefined) continue;
135
- lines.push(` ${a} -->|${fe.count}| ${b}`);
136
- }
137
-
138
- lines.push(...classDefLines());
139
-
140
- const nodes = {};
141
- for (const [folder, id] of ids) {
142
- nodes[id] = { kind: 'folder', path: folder === '(root)' ? '' : folder };
143
- }
144
- return { source: lines.join('\n'), nodes };
118
+ for (const fe of facts.folderEdges) {
119
+ const a = ids.get(fe.from);
120
+ const b = ids.get(fe.to);
121
+ if (a === undefined || b === undefined)
122
+ continue;
123
+ lines.push(` ${a} -->|${fe.count}| ${b}`);
124
+ }
125
+ lines.push(...classDefLines());
126
+ const nodes = {};
127
+ for (const [folder, id] of ids) {
128
+ nodes[id] = { kind: 'folder', path: folder === '(root)' ? '' : folder };
129
+ }
130
+ return { source: lines.join('\n'), nodes };
145
131
  }
146
-
147
132
  export function folderDiagram(scan, facts, folder, opts = {}) {
148
- const include = opts.include || (() => true);
149
- const here = scanIndex(scan).filesIn(folder).filter((f) => include(f.path));
150
- if (!here.length) return emptyDiagram('Nothing matches the filter in this folder.');
151
-
152
- const lines = [themeBlock(), 'flowchart LR'];
153
- const localSet = new Set(here.map((f) => f.path));
154
- const ids = idMapFor(here.map((f) => f.path));
155
- const fx = factIndex(facts);
156
-
157
- for (const f of here) {
158
- const id = ids.get(f.path);
159
- const fin = facts.fanIn[f.path] || 0;
160
- const isEntry = fx.entries.has(f.path);
161
- const inCycle = fx.inCycle.has(f.path);
162
- const cls = isEntry ? ':::entry' : inCycle ? ':::cycle' : fin >= 5 ? ':::hub' : '';
163
- lines.push(` ${id}["${esc(shortName(f.name))}"]${cls}`);
164
- }
165
-
166
- // Edges between files in this folder; edges to elsewhere get ghost nodes.
167
- const ghosts = new Map(); // outside path -> id
168
- let g = 0;
169
- for (const e of scan.edges) {
170
- const fromIn = localSet.has(e.from);
171
- const toIn = localSet.has(e.to);
172
- if (fromIn && toIn) {
173
- lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
174
- } else if (fromIn && !toIn && include(e.to)) {
175
- const gid = ghostId(ghosts, e.to, () => 'g' + g++);
176
- lines.push(` ${ids.get(e.from)} -.-> ${gid}`);
177
- } else if (!fromIn && toIn && include(e.from)) {
178
- const gid = ghostId(ghosts, e.from, () => 'g' + g++);
179
- lines.push(` ${gid} -.-> ${ids.get(e.to)}`);
133
+ const include = opts.include || (() => true);
134
+ const here = scanIndex(scan).filesIn(folder).filter((f) => include(f.path));
135
+ if (!here.length)
136
+ return emptyDiagram('Nothing matches the filter in this folder.');
137
+ const lines = [themeBlock(), 'flowchart LR'];
138
+ const localSet = new Set(here.map((f) => f.path));
139
+ const ids = idMapFor(here.map((f) => f.path));
140
+ const fx = factIndex(facts);
141
+ for (const f of here) {
142
+ const id = ids.get(f.path);
143
+ const fin = facts.fanIn[f.path] || 0;
144
+ const isEntry = fx.entries.has(f.path);
145
+ const inCycle = fx.inCycle.has(f.path);
146
+ const cls = isEntry ? ':::entry' : inCycle ? ':::cycle' : fin >= 5 ? ':::hub' : '';
147
+ lines.push(` ${id}["${esc(shortName(f.name))}"]${cls}`);
148
+ }
149
+ // Edges between files in this folder; edges to elsewhere get ghost nodes.
150
+ const ghosts = new Map(); // outside path -> id
151
+ let g = 0;
152
+ for (const e of scan.edges) {
153
+ const fromIn = localSet.has(e.from);
154
+ const toIn = localSet.has(e.to);
155
+ if (fromIn && toIn) {
156
+ lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
157
+ }
158
+ else if (fromIn && !toIn && include(e.to)) {
159
+ const gid = ghostId(ghosts, e.to, () => 'g' + g++);
160
+ lines.push(` ${ids.get(e.from)} -.-> ${gid}`);
161
+ }
162
+ else if (!fromIn && toIn && include(e.from)) {
163
+ const gid = ghostId(ghosts, e.from, () => 'g' + g++);
164
+ lines.push(` ${gid} -.-> ${ids.get(e.to)}`);
165
+ }
180
166
  }
181
- }
182
- for (const [p, gid] of ghosts) {
183
- lines.push(` ${gid}["${esc(shortName(baseName(p)))}\\n${esc(dirOf(p) || '(root)')}"]:::ghost`);
184
- }
185
-
186
- lines.push(...classDefLines());
187
-
188
- const nodes = {};
189
- for (const [p, id] of ids) nodes[id] = { kind: 'file', path: p };
190
- for (const [p, id] of ghosts) nodes[id] = { kind: 'file', path: p };
191
- return { source: lines.join('\n'), nodes };
167
+ for (const [p, gid] of ghosts) {
168
+ lines.push(` ${gid}["${esc(shortName(baseName(p)))}\\n${esc(dirOf(p) || '(root)')}"]:::ghost`);
169
+ }
170
+ lines.push(...classDefLines());
171
+ const nodes = {};
172
+ for (const [p, id] of ids)
173
+ nodes[id] = { kind: 'file', path: p };
174
+ for (const [p, id] of ghosts)
175
+ nodes[id] = { kind: 'file', path: p };
176
+ return { source: lines.join('\n'), nodes };
192
177
  }
193
178
  export function fileDetailDiagram(scan, facts, path) {
194
- const file = scanIndex(scan).fileAt(path);
195
- if (!file) return emptyDiagram('File not found in the scan.');
196
-
197
- const lines = [themeBlock(), 'flowchart LR'];
198
- const importers = (facts.importers[path] || []).slice(0, 8);
199
- const imports = (facts.importsOf[path] || []).slice(0, 8);
200
- const ext = scan.externals.filter((x) => x.usedBy.includes(path)).slice(0, 5);
201
-
202
- lines.push(` subgraph up["imported by"]`);
203
- importers.forEach((p, i) => lines.push(` up${i}["${esc(shortName(baseName(p)))}"]`));
204
- if (!importers.length) lines.push(` upnone[" "]:::blank`);
205
- lines.push(' end');
206
-
207
- lines.push(` self["${esc(shortName(file.name))}"]:::self`);
208
-
209
- lines.push(` subgraph down["imports"]`);
210
- imports.forEach((p, i) => lines.push(` dn${i}["${esc(shortName(baseName(p)))}"]`));
211
- ext.forEach((x, i) => lines.push(` dx${i}["${esc(x.name)}"]:::ext`));
212
- if (!imports.length && !ext.length) lines.push(` dnnone[" "]:::blank`);
213
- lines.push(' end');
214
-
215
- importers.forEach((p, i) => lines.push(` up${i} --> self`));
216
- imports.forEach((p, i) => lines.push(` self --> dn${i}`));
217
- ext.forEach((x, i) => lines.push(` self -.-> dx${i}`));
218
-
219
- lines.push(...classDefLines());
220
-
221
- const nodes = { self: { kind: 'file', path } };
222
- importers.forEach((p, i) => (nodes['up' + i] = { kind: 'file', path: p }));
223
- imports.forEach((p, i) => (nodes['dn' + i] = { kind: 'file', path: p }));
224
- return { source: lines.join('\n'), nodes };
179
+ const file = scanIndex(scan).fileAt(path);
180
+ if (!file)
181
+ return emptyDiagram('File not found in the scan.');
182
+ const lines = [themeBlock(), 'flowchart LR'];
183
+ const importers = (facts.importers[path] || []).slice(0, 8);
184
+ const imports = (facts.importsOf[path] || []).slice(0, 8);
185
+ const ext = scan.externals.filter((x) => x.usedBy.includes(path)).slice(0, 5);
186
+ lines.push(` subgraph up["imported by"]`);
187
+ importers.forEach((p, i) => lines.push(` up${i}["${esc(shortName(baseName(p)))}"]`));
188
+ if (!importers.length)
189
+ lines.push(` upnone[" "]:::blank`);
190
+ lines.push(' end');
191
+ lines.push(` self["${esc(shortName(file.name))}"]:::self`);
192
+ lines.push(` subgraph down["imports"]`);
193
+ imports.forEach((p, i) => lines.push(` dn${i}["${esc(shortName(baseName(p)))}"]`));
194
+ ext.forEach((x, i) => lines.push(` dx${i}["${esc(x.name)}"]:::ext`));
195
+ if (!imports.length && !ext.length)
196
+ lines.push(` dnnone[" "]:::blank`);
197
+ lines.push(' end');
198
+ importers.forEach((p, i) => lines.push(` up${i} --> self`));
199
+ imports.forEach((p, i) => lines.push(` self --> dn${i}`));
200
+ ext.forEach((x, i) => lines.push(` self -.-> dx${i}`));
201
+ lines.push(...classDefLines());
202
+ const nodes = { self: { kind: 'file', path } };
203
+ importers.forEach((p, i) => (nodes['up' + i] = { kind: 'file', path: p }));
204
+ imports.forEach((p, i) => (nodes['dn' + i] = { kind: 'file', path: p }));
205
+ return { source: lines.join('\n'), nodes };
225
206
  }
226
-
227
207
  export function callsDiagram(file) {
228
- if (!file?.calls?.length) return emptyDiagram('No internal call links we can see.');
229
- const lines = [themeBlock(), 'flowchart LR'];
230
- const names = new Set();
231
- for (const c of file.calls) {
232
- names.add(c.from);
233
- names.add(c.to);
234
- }
235
- const ids = idMapFor([...names]);
236
- for (const name of names) {
237
- lines.push(` ${ids.get(name)}["${esc(name)}()"]`);
238
- }
239
- for (const c of file.calls) {
240
- lines.push(` ${ids.get(c.from)} --> ${ids.get(c.to)}`);
241
- }
242
- return { source: lines.join('\n'), nodes: {} };
208
+ if (!file?.calls?.length)
209
+ return emptyDiagram('No internal call links we can see.');
210
+ const lines = [themeBlock(), 'flowchart LR'];
211
+ const names = new Set();
212
+ for (const c of file.calls) {
213
+ names.add(c.from);
214
+ names.add(c.to);
215
+ }
216
+ const ids = idMapFor([...names]);
217
+ for (const name of names) {
218
+ lines.push(` ${ids.get(name)}["${esc(name)}()"]`);
219
+ }
220
+ for (const c of file.calls) {
221
+ lines.push(` ${ids.get(c.from)} --> ${ids.get(c.to)}`);
222
+ }
223
+ return { source: lines.join('\n'), nodes: {} };
243
224
  }
244
-
245
225
  export function servicesDiagram(scan, manifest) {
246
- if (!manifest?.services?.length) return emptyDiagram('No services detected.');
247
- const lines = [themeBlock(), 'flowchart LR'];
248
- manifest.services.forEach((s, i) => {
249
- const bits = [esc(s.name)];
250
- if (s.image) bits.push(esc(s.image));
251
- if (s.ports?.length) bits.push(esc(s.ports.join(', ')));
252
- if (s.command) bits.push(esc(shortName(s.command)));
253
- lines.push(` svc${i}(["${bits.join('\\n')}"])`);
254
- });
255
- // Link each service to the folder it builds from, when we can see one.
256
- manifest.services.forEach((s, i) => {
257
- if (!s.build) return;
258
- const dir = s.build.replace(/^\.\/?/, '').replace(/\/$/, '');
259
- if (!dir || scan.folders.some((f) => f.path === dir)) {
260
- lines.push(` svc${i} -.->|"${esc(dir || '.')}"| root${i}["${esc(dir || '(repo root)')}"]:::ghost`);
261
- }
262
- });
263
- lines.push(...classDefLines());
264
- return { source: lines.join('\n'), nodes: {} };
226
+ if (!manifest?.services?.length)
227
+ return emptyDiagram('No services detected.');
228
+ const lines = [themeBlock(), 'flowchart LR'];
229
+ manifest.services.forEach((s, i) => {
230
+ const bits = [esc(s.name)];
231
+ if (s.image)
232
+ bits.push(esc(s.image));
233
+ if (s.ports?.length)
234
+ bits.push(esc(s.ports.join(', ')));
235
+ if (s.command)
236
+ bits.push(esc(shortName(s.command)));
237
+ lines.push(` svc${i}(["${bits.join('\\n')}"])`);
238
+ });
239
+ // Link each service to the folder it builds from, when we can see one.
240
+ manifest.services.forEach((s, i) => {
241
+ if (!s.build)
242
+ return;
243
+ const dir = s.build.replace(/^\.\/?/, '').replace(/\/$/, '');
244
+ if (!dir || scan.folders.some((f) => f.path === dir)) {
245
+ lines.push(` svc${i} -.->|"${esc(dir || '.')}"| root${i}["${esc(dir || '(repo root)')}"]:::ghost`);
246
+ }
247
+ });
248
+ lines.push(...classDefLines());
249
+ return { source: lines.join('\n'), nodes: {} };
265
250
  }
266
-
267
251
  export function emptyDiagram(note) {
268
- const source = [themeBlock(), 'flowchart LR', ` empty["${esc(note)}"]:::note`, ...classDefLines()].join('\n');
269
- return { source, nodes: {} };
252
+ const source = [themeBlock(), 'flowchart LR', ` empty["${esc(note)}"]:::note`, ...classDefLines()].join('\n');
253
+ return { source, nodes: {} };
270
254
  }
271
-
272
255
  // The Patterns view: every file placed on its import depth — the longest
273
256
  // chain from an entry point — so the architecture's strata are visible at a
274
257
  // glance. Edges flow downward; anything horizontal or upward earns a look.
275
258
  export function layersDiagram(scan, facts, layersInfo, opts = {}) {
276
- const include = opts.include || (() => true);
277
- const { layers, unreachable } = layersInfo;
278
- const MAX_PER_LAYER = 10;
279
- const MAX_EDGES = 70;
280
-
281
- const lines = [themeBlock(), 'flowchart TD'];
282
- const ids = new Map();
283
- const nodes = {};
284
- let n = 0;
285
-
286
- const fx = factIndex(facts);
287
- const clsFor = (p) =>
288
- fx.entries.has(p) ? ':::entry'
289
- : fx.inCycle.has(p) ? ':::cycle'
290
- : (facts.fanIn[p] || 0) >= 5 ? ':::hub'
291
- : '';
292
-
293
- layers.forEach((files, i) => {
294
- const shown = files.filter(include);
295
- if (!shown.length) return;
296
- const label = i === 0 ? 'the way in' : 'depth ' + i;
297
- lines.push(` subgraph L${i}["${label}"]`);
298
- for (const p of shown.slice(0, MAX_PER_LAYER)) {
299
- const id = 'n' + n++;
300
- ids.set(p, id);
301
- nodes[id] = { kind: 'file', path: p };
302
- lines.push(` ${id}["${esc(shortName(baseName(p)))}"]${clsFor(p)}`);
303
- }
304
- if (shown.length > MAX_PER_LAYER) {
305
- lines.push(` moreL${i}["+ ${shown.length - MAX_PER_LAYER} more"]:::ghost`);
306
- }
307
- lines.push(' end');
308
- });
309
-
310
- const stray = unreachable.filter(include).slice(0, 6);
311
- if (stray.length) {
312
- lines.push(` subgraph LU["off the path"]`);
313
- for (const p of stray) {
314
- const id = 'n' + n++;
315
- ids.set(p, id);
316
- nodes[id] = { kind: 'file', path: p };
317
- lines.push(` ${id}["${esc(shortName(baseName(p)))}"]:::ghost`);
259
+ const include = opts.include || (() => true);
260
+ const { layers, unreachable } = layersInfo;
261
+ const MAX_PER_LAYER = 10;
262
+ const MAX_EDGES = 70;
263
+ const lines = [themeBlock(), 'flowchart TD'];
264
+ const ids = new Map();
265
+ const nodes = {};
266
+ let n = 0;
267
+ const fx = factIndex(facts);
268
+ const clsFor = (p) => fx.entries.has(p) ? ':::entry'
269
+ : fx.inCycle.has(p) ? ':::cycle'
270
+ : (facts.fanIn[p] || 0) >= 5 ? ':::hub'
271
+ : '';
272
+ layers.forEach((files, i) => {
273
+ const shown = files.filter(include);
274
+ if (!shown.length)
275
+ return;
276
+ const label = i === 0 ? 'the way in' : 'depth ' + i;
277
+ lines.push(` subgraph L${i}["${label}"]`);
278
+ for (const p of shown.slice(0, MAX_PER_LAYER)) {
279
+ const id = 'n' + n++;
280
+ ids.set(p, id);
281
+ nodes[id] = { kind: 'file', path: p };
282
+ lines.push(` ${id}["${esc(shortName(baseName(p)))}"]${clsFor(p)}`);
283
+ }
284
+ if (shown.length > MAX_PER_LAYER) {
285
+ lines.push(` moreL${i}["+ ${shown.length - MAX_PER_LAYER} more"]:::ghost`);
286
+ }
287
+ lines.push(' end');
288
+ });
289
+ const stray = unreachable.filter(include).slice(0, 6);
290
+ if (stray.length) {
291
+ lines.push(` subgraph LU["off the path"]`);
292
+ for (const p of stray) {
293
+ const id = 'n' + n++;
294
+ ids.set(p, id);
295
+ nodes[id] = { kind: 'file', path: p };
296
+ lines.push(` ${id}["${esc(shortName(baseName(p)))}"]:::ghost`);
297
+ }
298
+ if (unreachable.length > stray.length) {
299
+ lines.push(` moreLU["+ ${unreachable.length - stray.length} more"]:::ghost`);
300
+ }
301
+ lines.push(' end');
318
302
  }
319
- if (unreachable.length > stray.length) {
320
- lines.push(` moreLU["+ ${unreachable.length - stray.length} more"]:::ghost`);
303
+ let edgeCount = 0;
304
+ for (const e of scan.edges) {
305
+ if (edgeCount >= MAX_EDGES)
306
+ break;
307
+ if (!ids.has(e.from) || !ids.has(e.to))
308
+ continue;
309
+ lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
310
+ edgeCount++;
321
311
  }
322
- lines.push(' end');
323
- }
324
-
325
- let edgeCount = 0;
326
- for (const e of scan.edges) {
327
- if (edgeCount >= MAX_EDGES) break;
328
- if (!ids.has(e.from) || !ids.has(e.to)) continue;
329
- lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
330
- edgeCount++;
331
- }
332
-
333
- lines.push(...classDefLines());
334
- return { source: lines.join('\n'), nodes };
312
+ lines.push(...classDefLines());
313
+ return { source: lines.join('\n'), nodes };
335
314
  }
336
-
337
315
  // ---- helpers ---------------------------------------------------------------
338
-
339
316
  function idMapFor(paths) {
340
- const map = new Map();
341
- paths.forEach((p, i) => map.set(p, 'n' + i));
342
- return map;
317
+ const map = new Map();
318
+ paths.forEach((p, i) => map.set(p, 'n' + i));
319
+ return map;
343
320
  }
344
-
345
321
  function ghostId(ghosts, path, next) {
346
- if (!ghosts.has(path)) ghosts.set(path, next());
347
- return ghosts.get(path);
322
+ if (!ghosts.has(path))
323
+ ghosts.set(path, next());
324
+ return ghosts.get(path);
348
325
  }
349
-
350
326
  // Mermaid labels break on a handful of characters; keep them out.
351
327
  function esc(s) {
352
- return String(s)
353
- .replace(/["<>|{}[\]()]/g, '')
354
- .replace(/&/g, 'and')
355
- .slice(0, 80);
328
+ return String(s)
329
+ .replace(/["<>|{}[\]()]/g, '')
330
+ .replace(/&/g, 'and')
331
+ .slice(0, 80);
356
332
  }
357
-
358
333
  function shortName(name) {
359
- return name.length > MAX_LABEL ? name.slice(0, MAX_LABEL - 1) + '…' : name;
334
+ return name.length > MAX_LABEL ? name.slice(0, MAX_LABEL - 1) + '…' : name;
360
335
  }
361
-
362
336
  // The Health view: the riskiest files as a heat map, colored by risk band and
363
337
  // wired with their import arrows, so the dangerous neighborhood reads at a
364
338
  // glance. Nodes stay clickable into the deep-dive.
365
339
  export function healthDiagram(scan, facts, health, opts = {}) {
366
- const include = opts.include || (() => true);
367
- const MAX = 26;
368
- const top = health.perFile.filter((f) => include(f.path)).slice(0, MAX);
369
- const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
370
- const ids = new Map();
371
- const nodes = {};
372
- let n = 0;
373
- const band = (r) => (r >= 70 ? 'r3' : r >= 50 ? 'r2' : r >= 30 ? 'r1' : 'r0');
374
-
375
- for (const f of top) {
376
- const id = 'h' + n++;
377
- ids.set(f.path, id);
378
- nodes[id] = { kind: 'file', path: f.path };
379
- lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.risk}"]:::${band(f.risk)}`);
380
- }
381
-
382
- const set = new Set(top.map((f) => f.path));
383
- let drawn = 0;
384
- for (const e of scan.edges) {
385
- if (drawn >= 60) break;
386
-
387
- if (!set.has(e.from) || !set.has(e.to)) continue;
388
- lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
389
- drawn++;
390
- }
391
- if (!top.length) lines.push(' empty["Nothing stands out — this repo is in good shape."]:::note');
392
- return { source: lines.join('\n'), nodes };
340
+ const include = opts.include || (() => true);
341
+ const MAX = 26;
342
+ const top = health.perFile.filter((f) => include(f.path)).slice(0, MAX);
343
+ const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
344
+ const ids = new Map();
345
+ const nodes = {};
346
+ let n = 0;
347
+ const band = (r) => (r >= 70 ? 'r3' : r >= 50 ? 'r2' : r >= 30 ? 'r1' : 'r0');
348
+ for (const f of top) {
349
+ const id = 'h' + n++;
350
+ ids.set(f.path, id);
351
+ nodes[id] = { kind: 'file', path: f.path };
352
+ lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.risk}"]:::${band(f.risk)}`);
353
+ }
354
+ const set = new Set(top.map((f) => f.path));
355
+ let drawn = 0;
356
+ for (const e of scan.edges) {
357
+ if (drawn >= 60)
358
+ break;
359
+ if (!set.has(e.from) || !set.has(e.to))
360
+ continue;
361
+ lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
362
+ drawn++;
363
+ }
364
+ if (!top.length)
365
+ lines.push(' empty["Nothing stands out — this repo is in good shape."]:::note');
366
+ return { source: lines.join('\n'), nodes };
393
367
  }
394
-
395
368
  // The Security view: files carrying rule-engine findings, colored by their
396
369
  // worst severity (critical red → info green), wired with their import arrows.
397
370
  export function securityDiagram(scan, facts, security, opts = {}) {
398
- const include = opts.include || (() => true);
399
- const MAX = 26;
400
- const sevClass = { critical: 'r3', high: 'r2', medium: 'r1', low: 'r0', info: 'r0' };
401
- const top = security.files.filter((f) => include(f.path)).slice(0, MAX);
402
- const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
403
- const ids = new Map();
404
- const nodes = {};
405
- let n = 0;
406
- for (const f of top) {
407
- const id = 's' + n++;
408
- ids.set(f.path, id);
409
- nodes[id] = { kind: 'file', path: f.path };
410
- lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.count}"]:::${sevClass[f.worst]}`);
411
- }
412
- const set = new Set(top.map((f) => f.path));
413
- let drawn = 0;
414
- for (const e of scan.edges) {
415
- if (drawn >= 60) break;
416
- if (!set.has(e.from) || !set.has(e.to)) continue;
417
- lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
418
- drawn++;
419
- }
420
- if (!top.length) lines.push(' clean["No findings — the rule engine found nothing to flag."]:::r0');
421
- return { source: lines.join('\n'), nodes };
371
+ const include = opts.include || (() => true);
372
+ const MAX = 26;
373
+ const sevClass = { critical: 'r3', high: 'r2', medium: 'r1', low: 'r0', info: 'r0' };
374
+ const top = security.files.filter((f) => include(f.path)).slice(0, MAX);
375
+ const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
376
+ const ids = new Map();
377
+ const nodes = {};
378
+ let n = 0;
379
+ for (const f of top) {
380
+ const id = 's' + n++;
381
+ ids.set(f.path, id);
382
+ nodes[id] = { kind: 'file', path: f.path };
383
+ lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.count}"]:::${sevClass[f.worst]}`);
384
+ }
385
+ const set = new Set(top.map((f) => f.path));
386
+ let drawn = 0;
387
+ for (const e of scan.edges) {
388
+ if (drawn >= 60)
389
+ break;
390
+ if (!set.has(e.from) || !set.has(e.to))
391
+ continue;
392
+ lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
393
+ drawn++;
394
+ }
395
+ if (!top.length)
396
+ lines.push(' clean["No findings — the rule engine found nothing to flag."]:::r0');
397
+ return { source: lines.join('\n'), nodes };
422
398
  }
423
-
424
399
  // The History view: the hotspot cross-tab — complexity × churn — as a heat
425
400
  // map. A file high here is both hard to change and changed constantly, which
426
401
  // is where a newcomer's caution (and a maintainer's tests) belong. Import
@@ -428,32 +403,35 @@ export function securityDiagram(scan, facts, security, opts = {}) {
428
403
  // No history (browser pick, tarball, not a checkout) says why instead of
429
404
  // drawing an empty chart.
430
405
  export function historyDiagram(scan, facts, history, opts = {}) {
431
- if (!history?.available) {
432
- return emptyDiagram(history?.reason || 'No history available.');
433
- }
434
- const include = opts.include || (() => true);
435
- const MAX = 26;
436
- const band = (s) => (s >= 70 ? 'r3' : s >= 50 ? 'r2' : s >= 30 ? 'r1' : 'r0');
437
- const top = history.perFile.filter((f) => include(f.path)).slice(0, MAX);
438
- const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
439
- const ids = new Map();
440
- const nodes = {};
441
- let n = 0;
442
- for (const f of top) {
443
- const id = 't' + n++;
444
- ids.set(f.path, id);
445
- nodes[id] = { kind: 'file', path: f.path };
446
- lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.hotspot}"]:::${band(f.hotspot)}`);
447
- }
448
- const set = new Set(top.map((f) => f.path));
449
- let drawn = 0;
450
- for (const e of scan.edges) {
451
- if (drawn >= 60) break;
452
- if (!set.has(e.from) || !set.has(e.to)) continue;
453
- lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
454
- drawn++;
455
- }
456
- if (!top.length) lines.push(' quiet["No file in this repo has been touched in the recent window."]:::note');
457
- return { source: lines.join('\n'), nodes };
406
+ if (!history?.available) {
407
+ return emptyDiagram(history?.reason || 'No history available.');
408
+ }
409
+ const include = opts.include || (() => true);
410
+ const MAX = 26;
411
+ const band = (s) => (s >= 70 ? 'r3' : s >= 50 ? 'r2' : s >= 30 ? 'r1' : 'r0');
412
+ const top = history.perFile.filter((f) => include(f.path)).slice(0, MAX);
413
+ const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];
414
+ const ids = new Map();
415
+ const nodes = {};
416
+ let n = 0;
417
+ for (const f of top) {
418
+ const id = 't' + n++;
419
+ ids.set(f.path, id);
420
+ nodes[id] = { kind: 'file', path: f.path };
421
+ lines.push(` ${id}["${esc(shortName(baseName(f.path)))} · ${f.hotspot}"]:::${band(f.hotspot)}`);
422
+ }
423
+ const set = new Set(top.map((f) => f.path));
424
+ let drawn = 0;
425
+ for (const e of scan.edges) {
426
+ if (drawn >= 60)
427
+ break;
428
+ if (!set.has(e.from) || !set.has(e.to))
429
+ continue;
430
+ lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);
431
+ drawn++;
432
+ }
433
+ if (!top.length)
434
+ lines.push(' quiet["No file in this repo has been touched in the recent window."]:::note');
435
+ return { source: lines.join('\n'), nodes };
458
436
  }
459
-
437
+ //# sourceMappingURL=mermaid.js.map