codebase-onboarder 0.5.0 → 0.7.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 (448) hide show
  1. package/README.md +196 -47
  2. package/bin/build-if-source.js +23 -0
  3. package/cli/commands.d.ts +26 -0
  4. package/cli/commands.js +836 -811
  5. package/cli/commands.js.map +1 -0
  6. package/cli/explorer/advanced.d.ts +14 -0
  7. package/cli/explorer/advanced.js +449 -0
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +396 -229
  11. package/cli/explorer/app.js.map +1 -0
  12. package/cli/explorer/assistant.d.ts +9 -0
  13. package/cli/explorer/assistant.js +58 -0
  14. package/cli/explorer/assistant.js.map +1 -0
  15. package/cli/explorer/commands.d.ts +17 -0
  16. package/cli/explorer/commands.js +400 -162
  17. package/cli/explorer/commands.js.map +1 -0
  18. package/cli/explorer/featureViews.d.ts +124 -0
  19. package/cli/explorer/featureViews.js +179 -0
  20. package/cli/explorer/featureViews.js.map +1 -0
  21. package/cli/explorer/github.d.ts +21 -0
  22. package/cli/explorer/github.js +73 -0
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +173 -0
  26. package/cli/explorer/graphs.js.map +1 -0
  27. package/cli/explorer/picker.d.ts +22 -0
  28. package/cli/explorer/picker.js +150 -0
  29. package/cli/explorer/picker.js.map +1 -0
  30. package/cli/explorer/report.d.ts +85 -0
  31. package/cli/explorer/report.js +60 -0
  32. package/cli/explorer/report.js.map +1 -0
  33. package/cli/explorer/session.d.ts +449 -0
  34. package/cli/explorer/session.js +184 -95
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +496 -412
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +33 -0
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +235 -138
  44. package/cli/main.js.map +1 -0
  45. package/cli/prompt.d.ts +5 -0
  46. package/cli/prompt.js +84 -80
  47. package/cli/prompt.js.map +1 -0
  48. package/cli/scanOptions.d.ts +2 -0
  49. package/cli/scanOptions.js +11 -0
  50. package/cli/scanOptions.js.map +1 -0
  51. package/cli/ui.d.ts +33 -0
  52. package/cli/ui.js +55 -35
  53. package/cli/ui.js.map +1 -0
  54. package/cli/wizard.d.ts +187 -0
  55. package/cli/wizard.js +304 -284
  56. package/cli/wizard.js.map +1 -0
  57. package/package.json +15 -4
  58. package/public/app.d.ts +1 -0
  59. package/public/app.js +1057 -1009
  60. package/public/app.js.map +1 -0
  61. package/public/browser.d.ts +68 -0
  62. package/public/browser.js +2 -0
  63. package/public/browser.js.map +1 -0
  64. package/public/index.html +30 -13
  65. package/public/js/about.d.ts +6 -0
  66. package/public/js/about.js +165 -172
  67. package/public/js/about.js.map +1 -0
  68. package/public/js/aiDraft.d.ts +3 -0
  69. package/public/js/aiDraft.js +116 -124
  70. package/public/js/aiDraft.js.map +1 -0
  71. package/public/js/analysisPanel.d.ts +7 -0
  72. package/public/js/analysisPanel.js +166 -166
  73. package/public/js/analysisPanel.js.map +1 -0
  74. package/public/js/analysisReport.d.ts +38 -0
  75. package/public/js/analysisReport.js +105 -110
  76. package/public/js/analysisReport.js.map +1 -0
  77. package/public/js/api.d.ts +26 -0
  78. package/public/js/api.js +176 -167
  79. package/public/js/api.js.map +1 -0
  80. package/public/js/atlas.d.ts +6 -0
  81. package/public/js/atlas.js +50 -58
  82. package/public/js/atlas.js.map +1 -0
  83. package/public/js/blameView.d.ts +2 -0
  84. package/public/js/blameView.js +36 -37
  85. package/public/js/blameView.js.map +1 -0
  86. package/public/js/codeTab.d.ts +3 -0
  87. package/public/js/codeTab.js +175 -180
  88. package/public/js/codeTab.js.map +1 -0
  89. package/public/js/codeViewer.d.ts +5 -0
  90. package/public/js/codeViewer.js +162 -150
  91. package/public/js/codeViewer.js.map +1 -0
  92. package/public/js/components/FileChip.d.ts +9 -0
  93. package/public/js/components/FileChip.js +45 -49
  94. package/public/js/components/FileChip.js.map +1 -0
  95. package/public/js/components/MetricSparkline.d.ts +7 -0
  96. package/public/js/components/MetricSparkline.js +35 -44
  97. package/public/js/components/MetricSparkline.js.map +1 -0
  98. package/public/js/components/RiskBadge.d.ts +9 -0
  99. package/public/js/components/RiskBadge.js +55 -63
  100. package/public/js/components/RiskBadge.js.map +1 -0
  101. package/public/js/deepAnalysisView.d.ts +99 -0
  102. package/public/js/deepAnalysisView.js +282 -302
  103. package/public/js/deepAnalysisView.js.map +1 -0
  104. package/public/js/diagramPane.d.ts +8 -0
  105. package/public/js/diagramPane.js +133 -135
  106. package/public/js/diagramPane.js.map +1 -0
  107. package/public/js/diffView.d.ts +6 -0
  108. package/public/js/diffView.js +222 -209
  109. package/public/js/diffView.js.map +1 -0
  110. package/public/js/docsView.d.ts +2 -0
  111. package/public/js/docsView.js +441 -442
  112. package/public/js/docsView.js.map +1 -0
  113. package/public/js/dom.d.ts +189 -0
  114. package/public/js/dom.js +5 -0
  115. package/public/js/dom.js.map +1 -0
  116. package/public/js/fileSourceBrowser.d.ts +5 -0
  117. package/public/js/fileSourceBrowser.js +33 -41
  118. package/public/js/fileSourceBrowser.js.map +1 -0
  119. package/public/js/flameGraph.d.ts +5 -0
  120. package/public/js/flameGraph.js +62 -72
  121. package/public/js/flameGraph.js.map +1 -0
  122. package/public/js/forceGraph.d.ts +10 -0
  123. package/public/js/forceGraph.js +581 -556
  124. package/public/js/forceGraph.js.map +1 -0
  125. package/public/js/heatmap.d.ts +4 -0
  126. package/public/js/heatmap.js +142 -164
  127. package/public/js/heatmap.js.map +1 -0
  128. package/public/js/highlight.d.ts +2 -0
  129. package/public/js/highlight.js +116 -107
  130. package/public/js/highlight.js.map +1 -0
  131. package/public/js/html.d.ts +2 -0
  132. package/public/js/html.js +14 -44
  133. package/public/js/html.js.map +1 -0
  134. package/public/js/insightsView.d.ts +5 -0
  135. package/public/js/insightsView.js +93 -111
  136. package/public/js/insightsView.js.map +1 -0
  137. package/public/js/inspector.d.ts +37 -0
  138. package/public/js/inspector.js +416 -445
  139. package/public/js/inspector.js.map +1 -0
  140. package/public/js/llm.d.ts +113 -0
  141. package/public/js/llm.js +233 -272
  142. package/public/js/llm.js.map +1 -0
  143. package/public/js/mapView.d.ts +3 -0
  144. package/public/js/mapView.js +121 -120
  145. package/public/js/mapView.js.map +1 -0
  146. package/public/js/markdown.d.ts +3 -0
  147. package/public/js/markdown.js +84 -91
  148. package/public/js/markdown.js.map +1 -0
  149. package/public/js/mindmap.d.ts +32 -0
  150. package/public/js/mindmap.js +244 -259
  151. package/public/js/mindmap.js.map +1 -0
  152. package/public/js/mobilePanels.d.ts +5 -0
  153. package/public/js/mobilePanels.js +50 -0
  154. package/public/js/mobilePanels.js.map +1 -0
  155. package/public/js/repoFiles.d.ts +12 -0
  156. package/public/js/repoFiles.js +28 -27
  157. package/public/js/repoFiles.js.map +1 -0
  158. package/public/js/reviewView.d.ts +28 -0
  159. package/public/js/reviewView.js +256 -0
  160. package/public/js/reviewView.js.map +1 -0
  161. package/public/js/sbomView.d.ts +3 -0
  162. package/public/js/sbomView.js +59 -67
  163. package/public/js/sbomView.js.map +1 -0
  164. package/public/js/scanCache.d.ts +16 -0
  165. package/public/js/scanCache.js +67 -65
  166. package/public/js/scanCache.js.map +1 -0
  167. package/public/js/search.d.ts +7 -0
  168. package/public/js/search.js +868 -800
  169. package/public/js/search.js.map +1 -0
  170. package/public/js/searchLocal.d.ts +42 -0
  171. package/public/js/searchLocal.js +87 -0
  172. package/public/js/searchLocal.js.map +1 -0
  173. package/public/js/serverSettings.d.ts +5 -0
  174. package/public/js/serverSettings.js +153 -164
  175. package/public/js/serverSettings.js.map +1 -0
  176. package/public/js/state.d.ts +798 -0
  177. package/public/js/state.js +114 -122
  178. package/public/js/state.js.map +1 -0
  179. package/public/js/tour.d.ts +6 -0
  180. package/public/js/tour.js +5 -7
  181. package/public/js/tour.js.map +1 -0
  182. package/public/js/transitions.d.ts +2 -0
  183. package/public/js/transitions.js +9 -10
  184. package/public/js/transitions.js.map +1 -0
  185. package/public/js/tree.d.ts +12 -0
  186. package/public/js/tree.js +157 -154
  187. package/public/js/tree.js.map +1 -0
  188. package/public/js/workflowsView.d.ts +3 -0
  189. package/public/js/workflowsView.js +15 -22
  190. package/public/js/workflowsView.js.map +1 -0
  191. package/public/search.css +495 -0
  192. package/public/styles.css +163 -346
  193. package/public/workbench.css +166 -0
  194. package/server/apiAuth.d.ts +3 -0
  195. package/server/apiAuth.js +18 -20
  196. package/server/apiAuth.js.map +1 -0
  197. package/server/apiDiff.d.ts +2 -0
  198. package/server/apiDiff.js +20 -18
  199. package/server/apiDiff.js.map +1 -0
  200. package/server/apiDocs.d.ts +2 -0
  201. package/server/apiDocs.js +38 -40
  202. package/server/apiDocs.js.map +1 -0
  203. package/server/apiFile.d.ts +1 -0
  204. package/server/apiFile.js +14 -17
  205. package/server/apiFile.js.map +1 -0
  206. package/server/apiGitBlame.d.ts +2 -0
  207. package/server/apiGitBlame.js +50 -51
  208. package/server/apiGitBlame.js.map +1 -0
  209. package/server/apiMcp.d.ts +4 -0
  210. package/server/apiMcp.js +64 -66
  211. package/server/apiMcp.js.map +1 -0
  212. package/server/apiReview.d.ts +2 -0
  213. package/server/apiReview.js +45 -0
  214. package/server/apiReview.js.map +1 -0
  215. package/server/apiScan.d.ts +5 -0
  216. package/server/apiScan.js +90 -71
  217. package/server/apiScan.js.map +1 -0
  218. package/server/apiSearch.d.ts +33 -0
  219. package/server/apiSearch.js +184 -200
  220. package/server/apiSearch.js.map +1 -0
  221. package/server/apiSettings.d.ts +4 -0
  222. package/server/apiSettings.js +84 -85
  223. package/server/apiSettings.js.map +1 -0
  224. package/server/apiTools.d.ts +3 -0
  225. package/server/apiTools.js +55 -56
  226. package/server/apiTools.js.map +1 -0
  227. package/server/auth.d.ts +5 -0
  228. package/server/auth.js +54 -51
  229. package/server/auth.js.map +1 -0
  230. package/server/config.d.ts +42 -0
  231. package/server/config.js +189 -194
  232. package/server/config.js.map +1 -0
  233. package/server/daemon.d.ts +12 -0
  234. package/server/daemon.js +124 -114
  235. package/server/daemon.js.map +1 -0
  236. package/server/fileSourceNode.d.ts +2 -0
  237. package/server/fileSourceNode.js +34 -36
  238. package/server/fileSourceNode.js.map +1 -0
  239. package/server/gitClone.d.ts +9 -0
  240. package/server/gitClone.js +59 -61
  241. package/server/gitClone.js.map +1 -0
  242. package/server/gitDiff.d.ts +36 -0
  243. package/server/gitDiff.js +271 -169
  244. package/server/gitDiff.js.map +1 -0
  245. package/server/gitHistory.d.ts +12 -0
  246. package/server/gitHistory.js +80 -80
  247. package/server/gitHistory.js.map +1 -0
  248. package/server/gitRemote.d.ts +12 -0
  249. package/server/gitRemote.js +60 -0
  250. package/server/gitRemote.js.map +1 -0
  251. package/server/htmlText.d.ts +4 -0
  252. package/server/htmlText.js +16 -23
  253. package/server/htmlText.js.map +1 -0
  254. package/server/http.d.ts +5 -0
  255. package/server/http.js +27 -30
  256. package/server/http.js.map +1 -0
  257. package/server/httpGuards.d.ts +2 -0
  258. package/server/httpGuards.js +47 -43
  259. package/server/httpGuards.js.map +1 -0
  260. package/server/https.d.ts +34 -0
  261. package/server/https.js +121 -111
  262. package/server/https.js.map +1 -0
  263. package/server/index.d.ts +40 -0
  264. package/server/index.js +139 -147
  265. package/server/index.js.map +1 -0
  266. package/server/layout.d.ts +26 -0
  267. package/server/layout.js +59 -37
  268. package/server/layout.js.map +1 -0
  269. package/server/llmProxy.d.ts +3 -0
  270. package/server/llmProxy.js +137 -135
  271. package/server/llmProxy.js.map +1 -0
  272. package/server/logger.d.ts +38 -0
  273. package/server/logger.js +198 -211
  274. package/server/logger.js.map +1 -0
  275. package/server/mcp/analysis.d.ts +29 -0
  276. package/server/mcp/analysis.js +99 -120
  277. package/server/mcp/analysis.js.map +1 -0
  278. package/server/mcp/http.d.ts +9 -0
  279. package/server/mcp/http.js +128 -137
  280. package/server/mcp/http.js.map +1 -0
  281. package/server/mcp/runner.d.ts +68 -0
  282. package/server/mcp/runner.js +208 -218
  283. package/server/mcp/runner.js.map +1 -0
  284. package/server/mcp/server.d.ts +29 -0
  285. package/server/mcp/server.js +166 -179
  286. package/server/mcp/server.js.map +1 -0
  287. package/server/mcp/standalone.d.ts +1 -0
  288. package/server/mcp/standalone.js +8 -10
  289. package/server/mcp/standalone.js.map +1 -0
  290. package/server/mcp/tools.d.ts +2020 -0
  291. package/server/mcp/tools.js +523 -574
  292. package/server/mcp/tools.js.map +1 -0
  293. package/server/paths.d.ts +3 -0
  294. package/server/paths.js +17 -15
  295. package/server/paths.js.map +1 -0
  296. package/server/pidfile.d.ts +9 -0
  297. package/server/pidfile.js +43 -45
  298. package/server/pidfile.js.map +1 -0
  299. package/server/review.d.ts +5 -0
  300. package/server/review.js +35 -0
  301. package/server/review.js.map +1 -0
  302. package/server/router.d.ts +33 -0
  303. package/server/router.js +191 -197
  304. package/server/router.js.map +1 -0
  305. package/server/scanRequest.d.ts +3 -0
  306. package/server/scanRequest.js +36 -0
  307. package/server/scanRequest.js.map +1 -0
  308. package/server/searchIndex.d.ts +17 -0
  309. package/server/searchIndex.js +83 -80
  310. package/server/searchIndex.js.map +1 -0
  311. package/server/sessions.d.ts +14 -0
  312. package/server/sessions.js +62 -70
  313. package/server/sessions.js.map +1 -0
  314. package/server/startup.d.ts +118 -0
  315. package/server/startup.js +143 -148
  316. package/server/startup.js.map +1 -0
  317. package/server/static.d.ts +6 -0
  318. package/server/static.js +28 -31
  319. package/server/static.js.map +1 -0
  320. package/server/tools/install.d.ts +4 -0
  321. package/server/tools/install.js +176 -185
  322. package/server/tools/install.js.map +1 -0
  323. package/server/tools/parse.d.ts +8 -0
  324. package/server/tools/parse.js +112 -114
  325. package/server/tools/parse.js.map +1 -0
  326. package/server/tools/platform.d.ts +9 -0
  327. package/server/tools/platform.js +49 -47
  328. package/server/tools/platform.js.map +1 -0
  329. package/server/tools/registry.d.ts +137 -0
  330. package/server/tools/registry.js +173 -172
  331. package/server/tools/registry.js.map +1 -0
  332. package/server/tools/scan.d.ts +34 -0
  333. package/server/tools/scan.js +89 -98
  334. package/server/tools/scan.js.map +1 -0
  335. package/server/tools.d.ts +34 -0
  336. package/server/tools.js +94 -107
  337. package/server/tools.js.map +1 -0
  338. package/server/tunnel.d.ts +29 -0
  339. package/server/tunnel.js +61 -66
  340. package/server/tunnel.js.map +1 -0
  341. package/shared/analyzer/docs.d.ts +16 -0
  342. package/shared/analyzer/docs.js +99 -93
  343. package/shared/analyzer/docs.js.map +1 -0
  344. package/shared/analyzer/explainLocal.d.ts +4 -0
  345. package/shared/analyzer/explainLocal.js +122 -142
  346. package/shared/analyzer/explainLocal.js.map +1 -0
  347. package/shared/analyzer/github.d.ts +37 -0
  348. package/shared/analyzer/github.js +79 -0
  349. package/shared/analyzer/github.js.map +1 -0
  350. package/shared/analyzer/graph.d.ts +41 -0
  351. package/shared/analyzer/graph.js +393 -400
  352. package/shared/analyzer/graph.js.map +1 -0
  353. package/shared/analyzer/health.d.ts +33 -0
  354. package/shared/analyzer/health.js +197 -193
  355. package/shared/analyzer/health.js.map +1 -0
  356. package/shared/analyzer/history.d.ts +29 -0
  357. package/shared/analyzer/history.js +110 -111
  358. package/shared/analyzer/history.js.map +1 -0
  359. package/shared/analyzer/jsonConfig.d.ts +2 -0
  360. package/shared/analyzer/jsonConfig.js +61 -0
  361. package/shared/analyzer/jsonConfig.js.map +1 -0
  362. package/shared/analyzer/languages/csharp.d.ts +26 -0
  363. package/shared/analyzer/languages/csharp.js +83 -88
  364. package/shared/analyzer/languages/csharp.js.map +1 -0
  365. package/shared/analyzer/languages/generic.d.ts +23 -0
  366. package/shared/analyzer/languages/generic.js +94 -105
  367. package/shared/analyzer/languages/generic.js.map +1 -0
  368. package/shared/analyzer/languages/go.d.ts +24 -0
  369. package/shared/analyzer/languages/go.js +45 -54
  370. package/shared/analyzer/languages/go.js.map +1 -0
  371. package/shared/analyzer/languages/index.d.ts +6 -0
  372. package/shared/analyzer/languages/index.js +19 -20
  373. package/shared/analyzer/languages/index.js.map +1 -0
  374. package/shared/analyzer/languages/java.d.ts +20 -0
  375. package/shared/analyzer/languages/java.js +73 -78
  376. package/shared/analyzer/languages/java.js.map +1 -0
  377. package/shared/analyzer/languages/javascript.d.ts +12 -0
  378. package/shared/analyzer/languages/javascript.js +258 -209
  379. package/shared/analyzer/languages/javascript.js.map +1 -0
  380. package/shared/analyzer/languages/python.d.ts +23 -0
  381. package/shared/analyzer/languages/python.js +92 -100
  382. package/shared/analyzer/languages/python.js.map +1 -0
  383. package/shared/analyzer/languages/rust.d.ts +17 -0
  384. package/shared/analyzer/languages/rust.js +96 -98
  385. package/shared/analyzer/languages/rust.js.map +1 -0
  386. package/shared/analyzer/languages/typescript.d.ts +11 -0
  387. package/shared/analyzer/languages/typescript.js +117 -116
  388. package/shared/analyzer/languages/typescript.js.map +1 -0
  389. package/shared/analyzer/licenses.d.ts +18 -0
  390. package/shared/analyzer/licenses.js +130 -133
  391. package/shared/analyzer/licenses.js.map +1 -0
  392. package/shared/analyzer/metrics.d.ts +20 -0
  393. package/shared/analyzer/metrics.js +112 -104
  394. package/shared/analyzer/metrics.js.map +1 -0
  395. package/shared/analyzer/pathUtil.d.ts +10 -0
  396. package/shared/analyzer/pathUtil.js +29 -35
  397. package/shared/analyzer/pathUtil.js.map +1 -0
  398. package/shared/analyzer/patterns.d.ts +11 -0
  399. package/shared/analyzer/patterns.js +231 -253
  400. package/shared/analyzer/patterns.js.map +1 -0
  401. package/shared/analyzer/scan.d.ts +62 -0
  402. package/shared/analyzer/scan.js +451 -442
  403. package/shared/analyzer/scan.js.map +1 -0
  404. package/shared/analyzer/scanControl.d.ts +11 -0
  405. package/shared/analyzer/scanControl.js +62 -0
  406. package/shared/analyzer/scanControl.js.map +1 -0
  407. package/shared/analyzer/security.d.ts +18 -0
  408. package/shared/analyzer/security.js +159 -159
  409. package/shared/analyzer/security.js.map +1 -0
  410. package/shared/analyzer/services.d.ts +5 -0
  411. package/shared/analyzer/services.js +141 -138
  412. package/shared/analyzer/services.js.map +1 -0
  413. package/shared/analyzer/stack.d.ts +6 -0
  414. package/shared/analyzer/stack.js +134 -141
  415. package/shared/analyzer/stack.js.map +1 -0
  416. package/shared/analyzer/tour.d.ts +2 -0
  417. package/shared/analyzer/tour.js +45 -53
  418. package/shared/analyzer/tour.js.map +1 -0
  419. package/shared/analyzer/util.d.ts +8 -0
  420. package/shared/analyzer/util.js +130 -76
  421. package/shared/analyzer/util.js.map +1 -0
  422. package/shared/analyzer/workflows.d.ts +8 -0
  423. package/shared/analyzer/workflows.js +139 -134
  424. package/shared/analyzer/workflows.js.map +1 -0
  425. package/shared/contracts.d.ts +250 -0
  426. package/shared/contracts.js +2 -0
  427. package/shared/contracts.js.map +1 -0
  428. package/shared/diagram/aiFacts.d.ts +35 -0
  429. package/shared/diagram/aiFacts.js +102 -105
  430. package/shared/diagram/aiFacts.js.map +1 -0
  431. package/shared/diagram/aiMermaid.d.ts +5 -0
  432. package/shared/diagram/aiMermaid.js +46 -45
  433. package/shared/diagram/aiMermaid.js.map +1 -0
  434. package/shared/diagram/atlas.d.ts +16 -0
  435. package/shared/diagram/atlas.js +51 -60
  436. package/shared/diagram/atlas.js.map +1 -0
  437. package/shared/diagram/mermaid.d.ts +43 -0
  438. package/shared/diagram/mermaid.js +348 -370
  439. package/shared/diagram/mermaid.js.map +1 -0
  440. package/shared/review/contracts.d.ts +95 -0
  441. package/shared/review/contracts.js +2 -0
  442. package/shared/review/contracts.js.map +1 -0
  443. package/shared/review/review.d.ts +10 -0
  444. package/shared/review/review.js +184 -0
  445. package/shared/review/review.js.map +1 -0
  446. package/shared/search/query.d.ts +32 -0
  447. package/shared/search/query.js +395 -388
  448. package/shared/search/query.js.map +1 -0
@@ -23,58 +23,57 @@
23
23
  // both surfaces explain that instead of pretending.
24
24
  // * Findings merge into the same shape the built-in scanner uses, with
25
25
  // `source: 'builtin'|'external'` kept, so the attribution stays visible.
26
-
27
26
  import { escapeHtml } from './html.js';
28
27
  import { fetchToolsStatus, runAnalysisTools, streamToolInstall } from './api.js';
29
28
  import { state } from './state.js';
30
29
  import { engineRows, engineSummary } from './analysisReport.js';
31
30
  import { mergeFindingsIntoScan, summarizeSecurity } from '/shared/analyzer/security.js';
32
-
33
31
  // ---- the store -------------------------------------------------------------
34
-
35
32
  // Who wants to know when a run starts, finishes or fails. The inspector panel
36
33
  // and the Deep Analysis view both subscribe; neither polls.
37
34
  const listeners = new Set();
38
-
39
35
  export function subscribeAnalysis(listener) {
40
- listeners.add(listener);
41
- return () => listeners.delete(listener);
36
+ listeners.add(listener);
37
+ return () => listeners.delete(listener);
42
38
  }
43
-
44
39
  function notify() {
45
- for (const listener of listeners) listener();
40
+ for (const listener of listeners)
41
+ listener();
46
42
  }
47
-
48
43
  // Which engines are installed. Asked once per repo and cached on the session —
49
44
  // detection spawns `which`, and the answer does not change mid-scan.
50
45
  export async function ensureToolsStatus(force = false) {
51
- if (state.tools.running) return state.tools.status;
52
- if (state.tools.status && !force) return state.tools.status;
53
- if (state.tools.loading) return state.tools.status;
54
- state.tools.loading = true;
55
- notify();
56
- try {
57
- const status = await fetchToolsStatus();
58
- if (status) state.tools.status = status;
59
- } finally {
60
- state.tools.loading = false;
46
+ if (state.tools.running)
47
+ return state.tools.status;
48
+ if (state.tools.status && !force)
49
+ return state.tools.status;
50
+ if (state.tools.loading)
51
+ return state.tools.status;
52
+ state.tools.loading = true;
61
53
  notify();
62
- }
63
- return state.tools.status;
54
+ try {
55
+ const status = await fetchToolsStatus();
56
+ if (status)
57
+ state.tools.status = status;
58
+ }
59
+ finally {
60
+ state.tools.loading = false;
61
+ notify();
62
+ }
63
+ return state.tools.status;
64
64
  }
65
-
66
65
  // The per-engine option values the Configure panels hold, shaped for the API:
67
66
  // only engines that have a form contribute, and every run gets the full set —
68
67
  // the server picks out what its `tools`/`kinds` filter selected.
69
68
  function collectToolOptions() {
70
- const out = {};
71
- const status = state.tools.status || {};
72
- for (const id of Object.keys(status)) {
73
- if ((status[id].options || []).length) out[id] = state.tools.options[id] || {};
74
- }
75
- return out;
69
+ const out = {};
70
+ const status = state.tools.status || {};
71
+ for (const id of Object.keys(status)) {
72
+ if ((status[id].options || []).length)
73
+ out[id] = state.tools.options[id] || {};
74
+ }
75
+ return out;
76
76
  }
77
-
78
77
  // Run the engines. `kinds` narrows by purpose (security / dead-code), `tools`
79
78
  // to named engines — the view offers all three scopes.
80
79
  //
@@ -83,181 +82,182 @@ function collectToolOptions() {
83
82
  // (it dedups on path+line+rule), so re-running a subset after a full run adds
84
83
  // nothing twice.
85
84
  export async function runDeepAnalysis(options = {}) {
86
- if (state.tools.running) return null;
87
- if (!state.scanId) return null;
88
-
89
- state.tools.running = true;
90
- state.tools.error = null;
91
- notify();
92
-
93
- try {
94
- const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });
95
- state.tools.report = report;
96
- state.tools.findings = report.findings || [];
97
- state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);
98
- state.security = summarizeSecurity(state.scan);
99
- return report;
100
- } catch (err) {
101
- state.tools.error = err.message;
102
- return null;
103
- } finally {
104
- state.tools.running = false;
85
+ if (state.tools.running)
86
+ return null;
87
+ if (!state.scanId)
88
+ return null;
89
+ state.tools.running = true;
90
+ state.tools.error = null;
105
91
  notify();
106
- }
92
+ try {
93
+ const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });
94
+ state.tools.report = report;
95
+ state.tools.findings = report.findings || [];
96
+ state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);
97
+ state.security = summarizeSecurity(state.scan);
98
+ return report;
99
+ }
100
+ catch (err) {
101
+ state.tools.error = err.message;
102
+ return null;
103
+ }
104
+ finally {
105
+ state.tools.running = false;
106
+ notify();
107
+ }
107
108
  }
108
-
109
109
  // Install a missing engine without leaving the GUI. The server streams log
110
110
  // lines, which collect on `state.tools.install[id]` so both surfaces can show
111
111
  // a live console; on success the status is re-fetched (the install cleared
112
112
  // the server's detection cache) and the card flips from "not installed" to
113
113
  // "ready" without a restart.
114
114
  export async function installEngine(id) {
115
- const entry = state.tools.install[id];
116
- if (entry && entry.running) return null;
117
- state.tools.install[id] = { running: true, log: [], ok: null, error: null };
118
- notify();
119
-
120
- try {
121
- const done = await streamToolInstall(id, (event) => {
122
- const slot = state.tools.install[id];
123
- if (event.type === 'log') slot.log.push(event.line);
124
- if (slot.log.length > 400) slot.log.splice(0, slot.log.length - 400);
125
- notify();
126
- });
127
- const slot = state.tools.install[id];
128
- slot.running = false;
129
- slot.ok = !!done.ok;
130
- slot.error = done.ok ? null : (done.error || 'The install did not finish.');
131
- if (done.ok) await ensureToolsStatus(true);
132
- notify();
133
- return done;
134
- } catch (err) {
135
- state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };
115
+ const entry = state.tools.install[id];
116
+ if (entry && entry.running)
117
+ return null;
118
+ state.tools.install[id] = { running: true, log: [], ok: null, error: null };
136
119
  notify();
137
- return null;
138
- }
120
+ try {
121
+ const done = await streamToolInstall(id, (event) => {
122
+ const slot = state.tools.install[id];
123
+ if (event.type === 'log')
124
+ slot.log.push(event.line);
125
+ if (slot.log.length > 400)
126
+ slot.log.splice(0, slot.log.length - 400);
127
+ notify();
128
+ });
129
+ const slot = state.tools.install[id];
130
+ slot.running = false;
131
+ slot.ok = !!done.ok;
132
+ slot.error = done.ok ? null : (done.error || 'The install did not finish.');
133
+ if (done.ok)
134
+ await ensureToolsStatus(true);
135
+ notify();
136
+ return done;
137
+ }
138
+ catch (err) {
139
+ state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };
140
+ notify();
141
+ return null;
142
+ }
139
143
  }
140
-
141
144
  // A sentence for whoever pressed the button. Kept out of the store proper —
142
145
  // toasting is the caller's business, and the store has no hooks.
143
146
  export function runOutcomeMessage(report) {
144
- if (!report) return 'Deep analysis did not finish.';
145
- if (!report.ranCount) {
146
- return report.unavailable && report.unavailable.length
147
- ? 'No engine is installed — see the list for what to install.'
148
- : 'No engine managed to run.';
149
- }
150
- const n = (report.findings || []).length;
151
- return `${report.ranCount} engine${report.ranCount === 1 ? '' : 's'} ran — ${n} finding${n === 1 ? '' : 's'} merged.`;
147
+ if (!report)
148
+ return 'Deep analysis did not finish.';
149
+ if (!report.ranCount) {
150
+ return report.unavailable && report.unavailable.length
151
+ ? 'No engine is installed — see the list for what to install.'
152
+ : 'No engine managed to run.';
153
+ }
154
+ const n = (report.findings || []).length;
155
+ return `${report.ranCount} engine${report.ranCount === 1 ? '' : 's'} ran — ${n} finding${n === 1 ? '' : 's'} merged.`;
152
156
  }
153
-
154
157
  // ---- the inspector panel ---------------------------------------------------
155
-
156
158
  let host = null;
157
- let hooks = { onToast: () => {}, onOpenFile: () => {} };
158
-
159
+ let hooks = { onToast: (..._args) => { }, onOpenFile: (..._args) => { } };
159
160
  export function initAnalysisPanel(options) {
160
- host = options.host;
161
- hooks = { ...hooks, ...options };
162
-
163
- host.addEventListener('click', (event) => {
164
- const install = event.target.closest('[data-engine-install]');
165
- if (install) {
166
- installEngine(install.dataset.engineInstall).then((done) => {
167
- if (done && done.ok) hooks.onToast(`${install.dataset.engineInstall} installed — it is ready to run.`);
168
- else if (done && done.error) hooks.onToast(done.error);
169
- });
170
- return;
171
- }
172
- const run = event.target.closest('[data-run-tools]');
173
- if (run) {
174
- const scope = run.dataset.runTools;
175
- runTools(scope ? { tools: [scope] } : {});
176
- return;
177
- }
178
- const kind = event.target.closest('[data-run-kind]');
179
- if (kind) runTools({ kinds: [kind.dataset.runKind] });
180
- });
181
-
182
- subscribeAnalysis(() => paint());
161
+ host = options.host;
162
+ hooks = { ...hooks, ...options };
163
+ host.addEventListener('click', (event) => {
164
+ const install = event.target.closest('[data-engine-install]');
165
+ if (install) {
166
+ installEngine(install.dataset.engineInstall).then((done) => {
167
+ if (done && done.ok)
168
+ hooks.onToast(`${install.dataset.engineInstall} installed — it is ready to run.`);
169
+ else if (done && done.error)
170
+ hooks.onToast(done.error);
171
+ });
172
+ return;
173
+ }
174
+ const run = event.target.closest('[data-run-tools]');
175
+ if (run) {
176
+ const scope = run.dataset.runTools;
177
+ runTools(scope ? { tools: [scope] } : {});
178
+ return;
179
+ }
180
+ const kind = event.target.closest('[data-run-kind]');
181
+ if (kind)
182
+ runTools({ kinds: [kind.dataset.runKind] });
183
+ });
184
+ subscribeAnalysis(() => paint());
183
185
  }
184
-
185
186
  async function runTools(options) {
186
- const report = await runDeepAnalysis(options);
187
- hooks.onToast(runOutcomeMessage(report));
187
+ const report = await runDeepAnalysis(options);
188
+ hooks.onToast(runOutcomeMessage(report));
188
189
  }
189
-
190
190
  // Renders into the security view's inspector. Also the place the "not a
191
191
  // server-side scan" case is explained, since that is a property of the repo.
192
192
  export function renderAnalysisPanel() {
193
- if (!host) return;
194
- if (!state.scanId) {
195
- host.innerHTML = `<div class="tools-note">Deep analysis runs on a scanned folder or clone. A folder picked in the browser never leaves this tab, so there is nothing on the server for an external engine to read — the built-in scan is the whole story for this repo.</div>`;
196
- return;
197
- }
198
- if (!state.tools.status && !state.tools.loading) void ensureToolsStatus();
199
- paint();
193
+ if (!host)
194
+ return;
195
+ if (!state.scanId) {
196
+ host.innerHTML = `<div class="tools-note">Deep analysis runs on a scanned folder or clone. A folder picked in the browser never leaves this tab, so there is nothing on the server for an external engine to read — the built-in scan is the whole story for this repo.</div>`;
197
+ return;
198
+ }
199
+ if (!state.tools.status && !state.tools.loading)
200
+ void ensureToolsStatus();
201
+ paint();
200
202
  }
201
-
202
203
  // The panel is the summary; the Deep Analysis view is where you go to read the
203
204
  // whole report. So this stays tight: the engines, one button, and an outcome
204
205
  // line — no findings table here.
205
206
  function paint() {
206
- if (!host) return;
207
- const { status, report, running, loading, error } = state.tools;
208
- const rows = engineRows(status, report);
209
-
210
- const head = `<div class="tools-head">
207
+ if (!host)
208
+ return;
209
+ const { status, report, running, loading, error } = state.tools;
210
+ const rows = engineRows(status, report);
211
+ const head = `<div class="tools-head">
211
212
  <h4>Deep analysis <span class="tools-sub">external engines</span></h4>
212
213
  <button class="btn btn-ghost tools-run" data-run-tools ${running ? 'disabled' : ''}>
213
214
  ${running ? 'Running…' : 'Run deep analysis'}
214
215
  </button>
215
216
  </div>`;
216
-
217
- let body = '';
218
- if (error) body += `<div class="tools-err">${escapeHtml(error)}</div>`;
219
-
220
- if (!rows.length) {
221
- body += `<div class="tools-note">${loading ? 'Checking which engines are available…' : 'No engine table yet.'}</div>`;
222
- } else {
223
- body += '<ul class="tools-list">' + rows.map(engineCard).join('') + '</ul>';
224
- }
225
-
226
- const summary = engineSummary(report, rows);
227
- if (report || rows.length) {
228
- body += `<div class="tools-summary is-${escapeHtml(summary.tone)}">${escapeHtml(summary.text)}</div>`;
229
- }
230
-
231
- if (rows.some((r) => r.ran)) {
232
- body += '<div class="tools-more">Every finding, with links to the file and line, is in the <b>Deep Analysis</b> tab.</div>';
233
- }
234
-
235
- host.innerHTML = head + body;
217
+ let body = '';
218
+ if (error)
219
+ body += `<div class="tools-err">${escapeHtml(error)}</div>`;
220
+ if (!rows.length) {
221
+ body += `<div class="tools-note">${loading ? 'Checking which engines are available…' : 'No engine table yet.'}</div>`;
222
+ }
223
+ else {
224
+ body += '<ul class="tools-list">' + rows.map(engineCard).join('') + '</ul>';
225
+ }
226
+ const summary = engineSummary(report, rows);
227
+ if (report || rows.length) {
228
+ body += `<div class="tools-summary is-${escapeHtml(summary.tone)}">${escapeHtml(summary.text)}</div>`;
229
+ }
230
+ if (rows.some((r) => r.ran)) {
231
+ body += '<div class="tools-more">Every finding, with links to the file and line, is in the <b>Deep Analysis</b> tab.</div>';
232
+ }
233
+ host.innerHTML = head + body;
236
234
  }
237
-
238
235
  // One engine card. The badge is the whole story at a glance: did it run, what
239
236
  // did it find, and if it could not run, why not. A missing engine gets an
240
237
  // Install button — the person stays in the GUI, and the log lands in the Deep
241
238
  // Analysis view's console.
242
239
  function engineCard(engine) {
243
- const installing = state.tools.install[engine.id];
244
- let badge;
245
- if (installing && installing.running) badge = '<span class="tools-badge is-running">installing…</span>';
246
- else if (!engine.available) badge = '<span class="tools-badge is-missing">not installed</span>';
247
- else if (state.tools.running) badge = '<span class="tools-badge is-running">running…</span>';
248
- else if (engine.ran) badge = `<span class="tools-badge is-ran">${engine.findings} · ${engine.ms}ms</span>`;
249
- else if (engine.failed) badge = '<span class="tools-badge is-failed">failed</span>';
250
- else badge = `<span class="tools-badge is-ready">ready${engine.how ? ' · ' + escapeHtml(engine.how) : ''}</span>`;
251
-
252
- const note = !engine.available && engine.reason
253
- ? `<span class="tools-reason">${escapeHtml(engine.reason)}</span>`
254
- : (engine.failure ? `<span class="tools-reason">${escapeHtml(engine.failure)}</span>` : '');
255
-
256
- const installBtn = !engine.available && engine.installable
257
- ? `<button class="btn btn-ghost btn-sm" data-engine-install="${escapeHtml(engine.id)}" ${installing && installing.running ? 'disabled' : ''}>${installing && installing.running ? 'Installing…' : 'Install'}</button>`
258
- : '';
259
-
260
- return `<li class="tools-item${engine.available ? '' : ' is-missing'}">
240
+ const installing = state.tools.install[engine.id];
241
+ let badge;
242
+ if (installing && installing.running)
243
+ badge = '<span class="tools-badge is-running">installing…</span>';
244
+ else if (!engine.available)
245
+ badge = '<span class="tools-badge is-missing">not installed</span>';
246
+ else if (state.tools.running)
247
+ badge = '<span class="tools-badge is-running">running…</span>';
248
+ else if (engine.ran)
249
+ badge = `<span class="tools-badge is-ran">${engine.findings} · ${engine.ms}ms</span>`;
250
+ else if (engine.failed)
251
+ badge = '<span class="tools-badge is-failed">failed</span>';
252
+ else
253
+ badge = `<span class="tools-badge is-ready">ready${engine.how ? ' · ' + escapeHtml(engine.how) : ''}</span>`;
254
+ const note = !engine.available && engine.reason
255
+ ? `<span class="tools-reason">${escapeHtml(engine.reason)}</span>`
256
+ : (engine.failure ? `<span class="tools-reason">${escapeHtml(engine.failure)}</span>` : '');
257
+ const installBtn = !engine.available && engine.installable
258
+ ? `<button class="btn btn-ghost btn-sm" data-engine-install="${escapeHtml(engine.id)}" ${installing && installing.running ? 'disabled' : ''}>${installing && installing.running ? 'Installing…' : 'Install'}</button>`
259
+ : '';
260
+ return `<li class="tools-item${engine.available ? '' : ' is-missing'}">
261
261
  <div class="tools-item-main">
262
262
  <span class="tools-name">${escapeHtml(engine.label)}</span>
263
263
  ${badge}
@@ -267,4 +267,4 @@ function engineCard(engine) {
267
267
  ${note}
268
268
  </li>`;
269
269
  }
270
-
270
+ //# sourceMappingURL=analysisPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysisPanel.js","sourceRoot":"","sources":["../../src/public/js/analysisPanel.ts"],"names":[],"mappings":"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","sourcesContent":["// The deep-analysis store, and the panel the Security view draws from it.\n//\n// Onboarder's built-in scanner is a fast, zero-dependency first pass. This is\n// the second pass — it runs the real analyzers the machine has (Semgrep,\n// Gitleaks, Knip, Vulture, Depcheck) through the server, and merges what they\n// find into the scan so the security grade includes them.\n//\n// Two consumers now share one store: this file's panel in the Security view's\n// inspector, and the full Deep Analysis view\n// (`deepAnalysisView.js`). Putting the run in one place is what keeps them\n// from disagreeing — a run started from either surface lands in\n// `state.tools`, merges identically, and notifies both to repaint. The\n// alternative (each surface calling the API itself) is how you end up with two\n// buttons that produce two different grades.\n//\n// The contract, in three lines:\n//\n// * Nothing is required. Both surfaces render with zero engines installed and\n// say which to install — \"no deep analysis\" and \"no findings\" are never the\n// same sentence.\n// * Server-side scans only. A browser-picked folder never touches the disk\n// from the server's point of view, so there is no root to point a tool at;\n// both surfaces explain that instead of pretending.\n// * Findings merge into the same shape the built-in scanner uses, with\n// `source: 'builtin'|'external'` kept, so the attribution stays visible.\n\nimport { escapeHtml } from './html.js';\nimport { fetchToolsStatus, runAnalysisTools, streamToolInstall } from './api.js';\nimport { state } from './state.js';\nimport { engineRows, engineSummary } from './analysisReport.js';\nimport { mergeFindingsIntoScan, summarizeSecurity } from '/shared/analyzer/security.js';\n\n// ---- the store -------------------------------------------------------------\n\n// Who wants to know when a run starts, finishes or fails. The inspector panel\n// and the Deep Analysis view both subscribe; neither polls.\nconst listeners = new Set<() => void>();\n\nexport function subscribeAnalysis(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\n// Which engines are installed. Asked once per repo and cached on the session —\n// detection spawns `which`, and the answer does not change mid-scan.\nexport async function ensureToolsStatus(force = false) {\n if (state.tools.running) return state.tools.status;\n if (state.tools.status && !force) return state.tools.status;\n if (state.tools.loading) return state.tools.status;\n state.tools.loading = true;\n notify();\n try {\n const status = await fetchToolsStatus();\n if (status) state.tools.status = status;\n } finally {\n state.tools.loading = false;\n notify();\n }\n return state.tools.status;\n}\n\n// The per-engine option values the Configure panels hold, shaped for the API:\n// only engines that have a form contribute, and every run gets the full set —\n// the server picks out what its `tools`/`kinds` filter selected.\nfunction collectToolOptions() {\n const out: Record<string, any> = {};\n const status = state.tools.status || {};\n for (const id of Object.keys(status)) {\n if ((status[id].options || []).length) out[id] = state.tools.options[id] || {};\n }\n return out;\n}\n\n// Run the engines. `kinds` narrows by purpose (security / dead-code), `tools`\n// to named engines — the view offers all three scopes.\n//\n// The merge happens here rather than in either caller, so the grade can never\n// depend on which button was pressed. `mergeFindingsIntoScan` is idempotent\n// (it dedups on path+line+rule), so re-running a subset after a full run adds\n// nothing twice.\nexport async function runDeepAnalysis(options: Record<string, any> = {}) {\n if (state.tools.running) return null;\n if (!state.scanId) return null;\n\n state.tools.running = true;\n state.tools.error = null;\n notify();\n\n try {\n const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });\n state.tools.report = report;\n state.tools.findings = report.findings || [];\n state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);\n state.security = summarizeSecurity(state.scan);\n return report;\n } catch (err) {\n state.tools.error = err.message;\n return null;\n } finally {\n state.tools.running = false;\n notify();\n }\n}\n\n// Install a missing engine without leaving the GUI. The server streams log\n// lines, which collect on `state.tools.install[id]` so both surfaces can show\n// a live console; on success the status is re-fetched (the install cleared\n// the server's detection cache) and the card flips from \"not installed\" to\n// \"ready\" without a restart.\nexport async function installEngine(id) {\n const entry = state.tools.install[id];\n if (entry && entry.running) return null;\n state.tools.install[id] = { running: true, log: [], ok: null, error: null };\n notify();\n\n try {\n const done = await streamToolInstall(id, (event) => {\n const slot = state.tools.install[id];\n if (event.type === 'log') slot.log.push(event.line);\n if (slot.log.length > 400) slot.log.splice(0, slot.log.length - 400);\n notify();\n });\n const slot = state.tools.install[id];\n slot.running = false;\n slot.ok = !!done.ok;\n slot.error = done.ok ? null : (done.error || 'The install did not finish.');\n if (done.ok) await ensureToolsStatus(true);\n notify();\n return done;\n } catch (err) {\n state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };\n notify();\n return null;\n }\n}\n\n// A sentence for whoever pressed the button. Kept out of the store proper —\n// toasting is the caller's business, and the store has no hooks.\nexport function runOutcomeMessage(report) {\n if (!report) return 'Deep analysis did not finish.';\n if (!report.ranCount) {\n return report.unavailable && report.unavailable.length\n ? 'No engine is installed — see the list for what to install.'\n : 'No engine managed to run.';\n }\n const n = (report.findings || []).length;\n return `${report.ranCount} engine${report.ranCount === 1 ? '' : 's'} ran — ${n} finding${n === 1 ? '' : 's'} merged.`;\n}\n\n// ---- the inspector panel ---------------------------------------------------\n\nlet host = null;\nlet hooks = { onToast: (..._args: unknown[]) => {}, onOpenFile: (..._args: unknown[]) => {} };\n\nexport function initAnalysisPanel(options) {\n host = options.host;\n hooks = { ...hooks, ...options };\n\n host.addEventListener('click', (event) => {\n const install = event.target.closest('[data-engine-install]');\n if (install) {\n installEngine(install.dataset.engineInstall).then((done) => {\n if (done && done.ok) hooks.onToast(`${install.dataset.engineInstall} installed — it is ready to run.`);\n else if (done && done.error) hooks.onToast(done.error);\n });\n return;\n }\n const run = event.target.closest('[data-run-tools]');\n if (run) {\n const scope = run.dataset.runTools;\n runTools(scope ? { tools: [scope] } : {});\n return;\n }\n const kind = event.target.closest('[data-run-kind]');\n if (kind) runTools({ kinds: [kind.dataset.runKind] });\n });\n\n subscribeAnalysis(() => paint());\n}\n\nasync function runTools(options) {\n const report = await runDeepAnalysis(options);\n hooks.onToast(runOutcomeMessage(report));\n}\n\n// Renders into the security view's inspector. Also the place the \"not a\n// server-side scan\" case is explained, since that is a property of the repo.\nexport function renderAnalysisPanel() {\n if (!host) return;\n if (!state.scanId) {\n host.innerHTML = `<div class=\"tools-note\">Deep analysis runs on a scanned folder or clone. A folder picked in the browser never leaves this tab, so there is nothing on the server for an external engine to read — the built-in scan is the whole story for this repo.</div>`;\n return;\n }\n if (!state.tools.status && !state.tools.loading) void ensureToolsStatus();\n paint();\n}\n\n// The panel is the summary; the Deep Analysis view is where you go to read the\n// whole report. So this stays tight: the engines, one button, and an outcome\n// line — no findings table here.\nfunction paint() {\n if (!host) return;\n const { status, report, running, loading, error } = state.tools;\n const rows = engineRows(status, report);\n\n const head = `<div class=\"tools-head\">\n <h4>Deep analysis <span class=\"tools-sub\">external engines</span></h4>\n <button class=\"btn btn-ghost tools-run\" data-run-tools ${running ? 'disabled' : ''}>\n ${running ? 'Running…' : 'Run deep analysis'}\n </button>\n </div>`;\n\n let body = '';\n if (error) body += `<div class=\"tools-err\">${escapeHtml(error)}</div>`;\n\n if (!rows.length) {\n body += `<div class=\"tools-note\">${loading ? 'Checking which engines are available…' : 'No engine table yet.'}</div>`;\n } else {\n body += '<ul class=\"tools-list\">' + rows.map(engineCard).join('') + '</ul>';\n }\n\n const summary = engineSummary(report, rows);\n if (report || rows.length) {\n body += `<div class=\"tools-summary is-${escapeHtml(summary.tone)}\">${escapeHtml(summary.text)}</div>`;\n }\n\n if (rows.some((r) => r.ran)) {\n body += '<div class=\"tools-more\">Every finding, with links to the file and line, is in the <b>Deep Analysis</b> tab.</div>';\n }\n\n host.innerHTML = head + body;\n}\n\n// One engine card. The badge is the whole story at a glance: did it run, what\n// did it find, and if it could not run, why not. A missing engine gets an\n// Install button — the person stays in the GUI, and the log lands in the Deep\n// Analysis view's console.\nfunction engineCard(engine) {\n const installing = state.tools.install[engine.id];\n let badge;\n if (installing && installing.running) badge = '<span class=\"tools-badge is-running\">installing…</span>';\n else if (!engine.available) badge = '<span class=\"tools-badge is-missing\">not installed</span>';\n else if (state.tools.running) badge = '<span class=\"tools-badge is-running\">running…</span>';\n else if (engine.ran) badge = `<span class=\"tools-badge is-ran\">${engine.findings} · ${engine.ms}ms</span>`;\n else if (engine.failed) badge = '<span class=\"tools-badge is-failed\">failed</span>';\n else badge = `<span class=\"tools-badge is-ready\">ready${engine.how ? ' · ' + escapeHtml(engine.how) : ''}</span>`;\n\n const note = !engine.available && engine.reason\n ? `<span class=\"tools-reason\">${escapeHtml(engine.reason)}</span>`\n : (engine.failure ? `<span class=\"tools-reason\">${escapeHtml(engine.failure)}</span>` : '');\n\n const installBtn = !engine.available && engine.installable\n ? `<button class=\"btn btn-ghost btn-sm\" data-engine-install=\"${escapeHtml(engine.id)}\" ${installing && installing.running ? 'disabled' : ''}>${installing && installing.running ? 'Installing…' : 'Install'}</button>`\n : '';\n\n return `<li class=\"tools-item${engine.available ? '' : ' is-missing'}\">\n <div class=\"tools-item-main\">\n <span class=\"tools-name\">${escapeHtml(engine.label)}</span>\n ${badge}\n ${installBtn}\n <span class=\"tools-purpose\">${escapeHtml(engine.purpose)}</span>\n </div>\n ${note}\n </li>`;\n}\n\n"]}
@@ -0,0 +1,38 @@
1
+ export declare const SEV_ORDER: string[];
2
+ export declare function sevRank(severity: any): number;
3
+ export declare const BUILTIN_TOOL = "built-in";
4
+ export declare function findingsFromSecurity(security: any): any[];
5
+ export declare function tabulate(rows: any): {
6
+ total: any;
7
+ bySeverity: Record<string, any>;
8
+ byTool: Record<string, any>;
9
+ byCategory: Record<string, any>;
10
+ external: any;
11
+ builtin: number;
12
+ critical: any;
13
+ high: any;
14
+ medium: any;
15
+ low: any;
16
+ };
17
+ export declare function filterFindings(rows: any, { severity, tool, q }?: Record<string, any>): any;
18
+ export declare function engineRows(status: any, report: any): {
19
+ id: string;
20
+ label: any;
21
+ kind: any;
22
+ purpose: any;
23
+ available: boolean;
24
+ how: any;
25
+ reason: any;
26
+ options: any;
27
+ defaults: any;
28
+ installable: boolean;
29
+ ran: boolean;
30
+ failed: boolean;
31
+ findings: any;
32
+ ms: any;
33
+ failure: any;
34
+ }[];
35
+ export declare function engineSummary(report: any, rows: any): {
36
+ tone: string;
37
+ text: string;
38
+ };