codebase-onboarder 0.6.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 +174 -46
  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 +321 -329
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +384 -313
  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 +368 -302
  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 +42 -44
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +90 -95
  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 +143 -144
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +465 -482
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +28 -44
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +214 -161
  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 +35 -44
  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 +152 -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 +37 -38
  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 -64
  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 +41 -43
  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
@@ -13,234 +13,225 @@
13
13
  // makes one codebase serve all three platforms — a Mac with Homebrew, a
14
14
  // Windows box with winget, and a bare Linux server with nothing but curl all
15
15
  // get a working path, and the log says plainly which one was taken.
16
-
17
16
  import { spawn } from 'node:child_process';
18
17
  import fs from 'node:fs';
19
18
  import os from 'node:os';
20
19
  import path from 'node:path';
21
-
22
20
  import { findOnPath, onboarderBinDir, spawnArgv } from './platform.js';
23
21
  import { clearDetectionCache } from '../tools.js';
24
-
25
22
  // Gitleaks has no package-manager story on Linux, so the fallback is its
26
23
  // official release asset, fetched over TLS from GitHub and unpacked into
27
24
  // ~/.onboarder/bin — a directory `findOnPath` already checks. The version is
28
25
  // pinned on purpose: a moving "latest" URL is a supply-chain surprise.
29
26
  const GITLEAKS_VERSION = '8.24.3';
30
-
31
27
  function gitleaksAsset(platform, arch) {
32
- const osPart = { darwin: 'darwin', linux: 'linux', win32: 'windows' }[platform];
33
- const archPart = arch === 'arm64' ? 'arm64' : 'x64';
34
- const ext = platform === 'win32' ? 'zip' : 'tar.gz';
35
- return {
36
- url: `https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${osPart}_${archPart}.${ext}`,
37
- file: `gitleaks.${ext}`,
38
- binary: platform === 'win32' ? 'gitleaks.exe' : 'gitleaks',
39
- };
28
+ const osPart = { darwin: 'darwin', linux: 'linux', win32: 'windows' }[platform];
29
+ const archPart = arch === 'arm64' ? 'arm64' : 'x64';
30
+ const ext = platform === 'win32' ? 'zip' : 'tar.gz';
31
+ return {
32
+ url: `https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${osPart}_${archPart}.${ext}`,
33
+ file: `gitleaks.${ext}`,
34
+ binary: platform === 'win32' ? 'gitleaks.exe' : 'gitleaks',
35
+ };
40
36
  }
41
-
42
37
  // A plan step is `{ argv }`, built from a context so paths stay absolute.
43
38
  // `needs` is the launcher binary that must exist for the whole plan to run.
44
39
  const INSTALL_PLANS = {
45
- semgrep: [
46
- { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
47
- steps: (bin) => [[bin, ['install', 'semgrep']]] },
48
- { id: 'pipx', label: 'pipx', needs: 'pipx',
49
- steps: (bin) => [[bin, ['install', 'semgrep']]] },
50
- { id: 'uv', label: 'uv', needs: 'uv',
51
- steps: (bin) => [[bin, ['tool', 'install', 'semgrep']]] },
52
- { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],
53
- steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },
54
- { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],
55
- steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },
56
- ],
57
- vulture: [
58
- { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
59
- steps: (bin) => [[bin, ['install', 'vulture']]] },
60
- { id: 'pipx', label: 'pipx', needs: 'pipx',
61
- steps: (bin) => [[bin, ['install', 'vulture']]] },
62
- { id: 'uv', label: 'uv', needs: 'uv',
63
- steps: (bin) => [[bin, ['tool', 'install', 'vulture']]] },
64
- { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],
65
- steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },
66
- { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],
67
- steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },
68
- ],
69
- knip: [
70
- { id: 'npm', label: 'npm (global)', needs: 'npm',
71
- steps: (bin) => [[bin, ['install', '-g', 'knip']]] },
72
- ],
73
- depcheck: [
74
- { id: 'npm', label: 'npm (global)', needs: 'npm',
75
- steps: (bin) => [[bin, ['install', '-g', 'depcheck']]] },
76
- ],
77
- gitleaks: [
78
- { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
79
- steps: (bin) => [[bin, ['install', 'gitleaks']]] },
80
- { id: 'winget', label: 'winget', needs: 'winget', platforms: ['win32'],
81
- steps: (bin) => [[bin, ['install', '--id', 'Gitleaks.Gitleaks', '-e',
82
- '--accept-package-agreements', '--accept-source-agreements']]] },
83
- { id: 'download', label: 'GitHub release download', needs: 'curl',
84
- steps: (bin, ctx) => {
85
- const asset = gitleaksAsset(ctx.platform, ctx.arch);
86
- const archive = path.join(ctx.tmpDir, asset.file);
87
- return [
88
- [bin, ['-fSL', '-o', archive, asset.url]],
89
- // bsdtar ships with Windows 10+ and reads zip; GNU tar reads tar.gz.
90
- // One command shape serves both.
91
- ['tar', ['-xf', archive, '-C', ctx.binDir]],
92
- ];
93
- },
94
- after: (ctx) => {
95
- const asset = gitleaksAsset(ctx.platform, ctx.arch);
96
- const binPath = path.join(ctx.binDir, asset.binary);
97
- if (ctx.platform !== 'win32') fs.chmodSync(binPath, 0o755);
98
- return binPath;
99
- },
100
- },
101
- ],
40
+ semgrep: [
41
+ { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
42
+ steps: (bin) => [[bin, ['install', 'semgrep']]] },
43
+ { id: 'pipx', label: 'pipx', needs: 'pipx',
44
+ steps: (bin) => [[bin, ['install', 'semgrep']]] },
45
+ { id: 'uv', label: 'uv', needs: 'uv',
46
+ steps: (bin) => [[bin, ['tool', 'install', 'semgrep']]] },
47
+ { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],
48
+ steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },
49
+ { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],
50
+ steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },
51
+ ],
52
+ vulture: [
53
+ { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
54
+ steps: (bin) => [[bin, ['install', 'vulture']]] },
55
+ { id: 'pipx', label: 'pipx', needs: 'pipx',
56
+ steps: (bin) => [[bin, ['install', 'vulture']]] },
57
+ { id: 'uv', label: 'uv', needs: 'uv',
58
+ steps: (bin) => [[bin, ['tool', 'install', 'vulture']]] },
59
+ { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],
60
+ steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },
61
+ { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],
62
+ steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },
63
+ ],
64
+ knip: [
65
+ { id: 'npm', label: 'npm (global)', needs: 'npm',
66
+ steps: (bin) => [[bin, ['install', '-g', 'knip']]] },
67
+ ],
68
+ depcheck: [
69
+ { id: 'npm', label: 'npm (global)', needs: 'npm',
70
+ steps: (bin) => [[bin, ['install', '-g', 'depcheck']]] },
71
+ ],
72
+ gitleaks: [
73
+ { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],
74
+ steps: (bin) => [[bin, ['install', 'gitleaks']]] },
75
+ { id: 'winget', label: 'winget', needs: 'winget', platforms: ['win32'],
76
+ steps: (bin) => [[bin, ['install', '--id', 'Gitleaks.Gitleaks', '-e',
77
+ '--accept-package-agreements', '--accept-source-agreements']]] },
78
+ { id: 'download', label: 'GitHub release download', needs: 'curl',
79
+ steps: (bin, ctx) => {
80
+ const asset = gitleaksAsset(ctx.platform, ctx.arch);
81
+ const archive = path.join(ctx.tmpDir, asset.file);
82
+ return [
83
+ [bin, ['-fSL', '-o', archive, asset.url]],
84
+ // bsdtar ships with Windows 10+ and reads zip; GNU tar reads tar.gz.
85
+ // One command shape serves both.
86
+ ['tar', ['-xf', archive, '-C', ctx.binDir]],
87
+ ];
88
+ },
89
+ after: (ctx) => {
90
+ const asset = gitleaksAsset(ctx.platform, ctx.arch);
91
+ const binPath = path.join(ctx.binDir, asset.binary);
92
+ if (ctx.platform !== 'win32')
93
+ fs.chmodSync(binPath, 0o755);
94
+ return binPath;
95
+ },
96
+ },
97
+ ],
102
98
  };
103
99
  // The plans a tool can use on this platform, in preference order. Pure —
104
100
  // exported for the status endpoint and for tests.
105
101
  export function plansFor(toolId, platform = process.platform) {
106
- return (INSTALL_PLANS[toolId] || [])
107
- .filter((plan) => !plan.platforms || plan.platforms.includes(platform));
102
+ return (INSTALL_PLANS[toolId] || [])
103
+ .filter((plan) => !plan.platforms || plan.platforms.includes(platform));
108
104
  }
109
-
110
105
  // What the GUI's install dialog shows before the button is pressed: for each
111
106
  // plan, whether its launcher exists here. Injectable `find` keeps it testable.
112
107
  export function planAvailability(toolId, options = {}) {
113
- const platform = options.platform || process.platform;
114
- const find = options.find || ((bin) => findOnPath(bin));
115
- return plansFor(toolId, platform).map((plan) => ({
116
- id: plan.id,
117
- label: plan.label,
118
- needs: plan.needs,
119
- ready: !!find(plan.needs),
120
- }));
108
+ const platform = options.platform || process.platform;
109
+ const find = options.find || ((bin) => findOnPath(bin));
110
+ return plansFor(toolId, platform).map((plan) => ({
111
+ id: plan.id,
112
+ label: plan.label,
113
+ needs: plan.needs,
114
+ ready: !!find(plan.needs),
115
+ }));
121
116
  }
122
-
123
117
  // One install at a time per tool — two Install clicks must not run pip against
124
118
  // itself. Held here rather than in the handler so the rule survives a second
125
119
  // caller.
126
120
  const installing = new Set();
127
-
128
121
  export function isInstalling(toolId) {
129
- return installing.has(toolId);
122
+ return installing.has(toolId);
130
123
  }
131
-
132
124
  const STEP_TIMEOUT_MS = 10 * 60 * 1000; // pip on a slow link is still finite
133
-
134
125
  // Spawn one step, forwarding output line by line. Resolves with the exit
135
126
  // status; never rejects — a failed plan is data for the next plan, and the
136
127
  // whole log goes to the GUI either way.
137
128
  function runStep(command, args, onLog) {
138
- const { command: cmd, args: argv } = spawnArgv([command, ...args]);
139
- return new Promise((resolve) => {
140
- let child;
141
- try {
142
- child = spawn(cmd, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
143
- } catch (err) {
144
- onLog(`could not start ${cmd}: ${err.message}`);
145
- resolve(-1);
146
- return;
147
- }
148
- let pending = '';
149
- const feed = (chunk) => {
150
- pending += chunk.toString();
151
- const lines = pending.split(/\r?\n/);
152
- pending = lines.pop();
153
- for (const line of lines) if (line.trim()) onLog(line);
154
- };
155
- child.stdout.on('data', feed);
156
- child.stderr.on('data', feed);
157
- const timer = setTimeout(() => {
158
- child.kill('SIGKILL');
159
- onLog(`${cmd} took too long and was stopped.`);
160
- }, STEP_TIMEOUT_MS);
161
- child.on('error', (err) => {
162
- clearTimeout(timer);
163
- onLog(`could not run ${cmd}: ${err.message}`);
164
- resolve(-1);
165
- });
166
- child.on('close', (code) => {
167
- clearTimeout(timer);
168
- if (pending.trim()) onLog(pending);
169
- resolve(code ?? -1);
129
+ const { command: cmd, args: argv } = spawnArgv([command, ...args]);
130
+ return new Promise((resolve) => {
131
+ let child;
132
+ try {
133
+ child = spawn(cmd, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
134
+ }
135
+ catch (err) {
136
+ onLog(`could not start ${cmd}: ${err.message}`);
137
+ resolve(-1);
138
+ return;
139
+ }
140
+ let pending = '';
141
+ const feed = (chunk) => {
142
+ pending += chunk.toString();
143
+ const lines = pending.split(/\r?\n/);
144
+ pending = lines.pop();
145
+ for (const line of lines)
146
+ if (line.trim())
147
+ onLog(line);
148
+ };
149
+ child.stdout.on('data', feed);
150
+ child.stderr.on('data', feed);
151
+ const timer = setTimeout(() => {
152
+ child.kill('SIGKILL');
153
+ onLog(`${cmd} took too long and was stopped.`);
154
+ }, STEP_TIMEOUT_MS);
155
+ child.on('error', (err) => {
156
+ clearTimeout(timer);
157
+ onLog(`could not run ${cmd}: ${err.message}`);
158
+ resolve(-1);
159
+ });
160
+ child.on('close', (code) => {
161
+ clearTimeout(timer);
162
+ if (pending.trim())
163
+ onLog(pending);
164
+ resolve(code ?? -1);
165
+ });
170
166
  });
171
- });
172
167
  }
173
-
174
168
  // Install a tool, streaming progress through `onEvent({ type, ... })`:
175
169
  // { type: 'log', line } — one line of output from the installer
176
170
  // { type: 'plan', id, label } — which plan is being attempted
177
171
  // { type: 'done', ok, error?, method? }
178
172
  // Resolves with the same shape as the final `done` event.
179
- export async function installTool(toolId, onEvent = () => {}) {
180
- const log = (line) => onEvent({ type: 'log', line });
181
- const finish = (result) => { onEvent({ type: 'done', ...result }); return result; };
182
-
183
- const plans = plansFor(toolId);
184
- if (!plans.length) {
185
- return finish({ ok: false, error: `Onboarder does not know how to install "${toolId}".` });
186
- }
187
- if (installing.has(toolId)) {
188
- return finish({ ok: false, error: `${toolId} is already being installed.` });
189
- }
190
- installing.add(toolId);
191
-
192
- try {
193
- const ctx = {
194
- platform: process.platform,
195
- arch: process.arch,
196
- tmpDir: os.tmpdir(),
197
- binDir: onboarderBinDir(),
198
- };
199
-
200
- let attempted = 0;
201
- for (const plan of plans) {
202
- const launcher = findOnPath(plan.needs);
203
- if (!launcher) {
204
- log(`— skipping ${plan.label}: no ${plan.needs} on this machine.`);
205
- continue;
206
- }
207
- attempted += 1;
208
- onEvent({ type: 'plan', id: plan.id, label: plan.label });
209
- log(`Installing ${toolId} with ${plan.label}…`);
210
-
211
- if (plan.id === 'download') fs.mkdirSync(ctx.binDir, { recursive: true });
212
-
213
- let failed = false;
214
- for (const [command, args] of plan.steps(launcher, ctx)) {
215
- log(`$ ${command} ${args.join(' ')}`);
216
- const status = await runStep(command, args, log);
217
- if (status !== 0) {
218
- log(`✗ that step exited ${status}.`);
219
- failed = true;
220
- break;
173
+ export async function installTool(toolId, onEvent = (..._args) => { }) {
174
+ const log = (line) => onEvent({ type: 'log', line });
175
+ const finish = (result) => { onEvent({ type: 'done', ...result }); return result; };
176
+ const plans = plansFor(toolId);
177
+ if (!plans.length) {
178
+ return finish({ ok: false, error: `Onboarder does not know how to install "${toolId}".` });
179
+ }
180
+ if (installing.has(toolId)) {
181
+ return finish({ ok: false, error: `${toolId} is already being installed.` });
182
+ }
183
+ installing.add(toolId);
184
+ try {
185
+ const ctx = {
186
+ platform: process.platform,
187
+ arch: process.arch,
188
+ tmpDir: os.tmpdir(),
189
+ binDir: onboarderBinDir(),
190
+ };
191
+ let attempted = 0;
192
+ for (const plan of plans) {
193
+ const launcher = findOnPath(plan.needs);
194
+ if (!launcher) {
195
+ log(`— skipping ${plan.label}: no ${plan.needs} on this machine.`);
196
+ continue;
197
+ }
198
+ attempted += 1;
199
+ onEvent({ type: 'plan', id: plan.id, label: plan.label });
200
+ log(`Installing ${toolId} with ${plan.label}…`);
201
+ if (plan.id === 'download')
202
+ fs.mkdirSync(ctx.binDir, { recursive: true });
203
+ let failed = false;
204
+ for (const [command, args] of plan.steps(launcher, ctx)) {
205
+ log(`$ ${command} ${args.join(' ')}`);
206
+ const status = await runStep(command, args, log);
207
+ if (status !== 0) {
208
+ log(`✗ that step exited ${status}.`);
209
+ failed = true;
210
+ break;
211
+ }
212
+ }
213
+ if (failed)
214
+ continue;
215
+ try {
216
+ const binPath = plan.after ? plan.after(ctx) : null;
217
+ if (binPath)
218
+ log(`Installed to ${binPath}`);
219
+ }
220
+ catch (err) {
221
+ log(`✗ unpack failed: ${err.message}`);
222
+ continue;
223
+ }
224
+ clearDetectionCache();
225
+ log('✓ done. Re-checking the engine list…');
226
+ return finish({ ok: true, method: plan.label });
221
227
  }
222
- }
223
- if (failed) continue;
224
-
225
- try {
226
- const binPath = plan.after ? plan.after(ctx) : null;
227
- if (binPath) log(`Installed to ${binPath}`);
228
- } catch (err) {
229
- log(`✗ unpack failed: ${err.message}`);
230
- continue;
231
- }
232
-
233
- clearDetectionCache();
234
- log('✓ done. Re-checking the engine list…');
235
- return finish({ ok: true, method: plan.label });
228
+ const why = attempted
229
+ ? 'Every available installer failed — the log above says where.'
230
+ : 'No installer this machine has can install it. Try the manual command in the engine list.';
231
+ return finish({ ok: false, error: why });
232
+ }
233
+ finally {
234
+ installing.delete(toolId);
236
235
  }
237
-
238
- const why = attempted
239
- ? 'Every available installer failed — the log above says where.'
240
- : 'No installer this machine has can install it. Try the manual command in the engine list.';
241
- return finish({ ok: false, error: why });
242
- } finally {
243
- installing.delete(toolId);
244
- }
245
236
  }
246
-
237
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/server/tools/install.ts"],"names":[],"mappings":"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","sourcesContent":["// Installing an engine from the GUI.\n//\n// The engine's founding rule was \"detect, never install\" — the person\n// self-hosting decides what goes on the machine. This module relaxes *who\n// runs the command*, not *what runs*: the install plans below are fixed data,\n// one per tool per way of installing, and the GUI's Install button is the\n// person deciding. No plan takes user input; every step is an argument array\n// spawned without a shell, exactly like the analyzers themselves.\n//\n// Plans are ordered by preference and each names the launcher it needs\n// (`brew`, `pip`, `npm`, `winget`, `curl`, …). At install time the first plan\n// whose launcher is found on PATH runs; the rest are skipped. That is what\n// makes one codebase serve all three platforms — a Mac with Homebrew, a\n// Windows box with winget, and a bare Linux server with nothing but curl all\n// get a working path, and the log says plainly which one was taken.\n\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { findOnPath, onboarderBinDir, spawnArgv } from './platform.js';\nimport { clearDetectionCache } from '../tools.js';\n\n// Gitleaks has no package-manager story on Linux, so the fallback is its\n// official release asset, fetched over TLS from GitHub and unpacked into\n// ~/.onboarder/bin — a directory `findOnPath` already checks. The version is\n// pinned on purpose: a moving \"latest\" URL is a supply-chain surprise.\nconst GITLEAKS_VERSION = '8.24.3';\n\nfunction gitleaksAsset(platform, arch) {\n const osPart = { darwin: 'darwin', linux: 'linux', win32: 'windows' }[platform];\n const archPart = arch === 'arm64' ? 'arm64' : 'x64';\n const ext = platform === 'win32' ? 'zip' : 'tar.gz';\n return {\n url: `https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_${osPart}_${archPart}.${ext}`,\n file: `gitleaks.${ext}`,\n binary: platform === 'win32' ? 'gitleaks.exe' : 'gitleaks',\n };\n}\n\n// A plan step is `{ argv }`, built from a context so paths stay absolute.\n// `needs` is the launcher binary that must exist for the whole plan to run.\nconst INSTALL_PLANS = {\n semgrep: [\n { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],\n steps: (bin) => [[bin, ['install', 'semgrep']]] },\n { id: 'pipx', label: 'pipx', needs: 'pipx',\n steps: (bin) => [[bin, ['install', 'semgrep']]] },\n { id: 'uv', label: 'uv', needs: 'uv',\n steps: (bin) => [[bin, ['tool', 'install', 'semgrep']]] },\n { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],\n steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },\n { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],\n steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'semgrep']]] },\n ],\n vulture: [\n { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],\n steps: (bin) => [[bin, ['install', 'vulture']]] },\n { id: 'pipx', label: 'pipx', needs: 'pipx',\n steps: (bin) => [[bin, ['install', 'vulture']]] },\n { id: 'uv', label: 'uv', needs: 'uv',\n steps: (bin) => [[bin, ['tool', 'install', 'vulture']]] },\n { id: 'pip', label: 'pip (user site)', needs: 'python3', platforms: ['darwin', 'linux'],\n steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },\n { id: 'pip', label: 'pip (user site)', needs: 'python', platforms: ['win32'],\n steps: (bin) => [[bin, ['-m', 'pip', 'install', '--user', 'vulture']]] },\n ],\n knip: [\n { id: 'npm', label: 'npm (global)', needs: 'npm',\n steps: (bin) => [[bin, ['install', '-g', 'knip']]] },\n ],\n depcheck: [\n { id: 'npm', label: 'npm (global)', needs: 'npm',\n steps: (bin) => [[bin, ['install', '-g', 'depcheck']]] },\n ],\n gitleaks: [\n { id: 'brew', label: 'Homebrew', needs: 'brew', platforms: ['darwin'],\n steps: (bin) => [[bin, ['install', 'gitleaks']]] },\n { id: 'winget', label: 'winget', needs: 'winget', platforms: ['win32'],\n steps: (bin) => [[bin, ['install', '--id', 'Gitleaks.Gitleaks', '-e',\n '--accept-package-agreements', '--accept-source-agreements']]] },\n { id: 'download', label: 'GitHub release download', needs: 'curl',\n steps: (bin, ctx) => {\n const asset = gitleaksAsset(ctx.platform, ctx.arch);\n const archive = path.join(ctx.tmpDir, asset.file);\n return [\n [bin, ['-fSL', '-o', archive, asset.url]],\n // bsdtar ships with Windows 10+ and reads zip; GNU tar reads tar.gz.\n // One command shape serves both.\n ['tar', ['-xf', archive, '-C', ctx.binDir]],\n ];\n },\n after: (ctx) => {\n const asset = gitleaksAsset(ctx.platform, ctx.arch);\n const binPath = path.join(ctx.binDir, asset.binary);\n if (ctx.platform !== 'win32') fs.chmodSync(binPath, 0o755);\n return binPath;\n },\n },\n ],\n};\n// The plans a tool can use on this platform, in preference order. Pure —\n// exported for the status endpoint and for tests.\nexport function plansFor(toolId, platform = process.platform) {\n return (INSTALL_PLANS[toolId] || [])\n .filter((plan) => !plan.platforms || plan.platforms.includes(platform));\n}\n\n// What the GUI's install dialog shows before the button is pressed: for each\n// plan, whether its launcher exists here. Injectable `find` keeps it testable.\nexport function planAvailability(toolId, options: Record<string, any> = {}) {\n const platform = options.platform || process.platform;\n const find = options.find || ((bin) => findOnPath(bin));\n return plansFor(toolId, platform).map((plan) => ({\n id: plan.id,\n label: plan.label,\n needs: plan.needs,\n ready: !!find(plan.needs),\n }));\n}\n\n// One install at a time per tool — two Install clicks must not run pip against\n// itself. Held here rather than in the handler so the rule survives a second\n// caller.\nconst installing = new Set();\n\nexport function isInstalling(toolId) {\n return installing.has(toolId);\n}\n\nconst STEP_TIMEOUT_MS = 10 * 60 * 1000; // pip on a slow link is still finite\n\n// Spawn one step, forwarding output line by line. Resolves with the exit\n// status; never rejects — a failed plan is data for the next plan, and the\n// whole log goes to the GUI either way.\nfunction runStep(command, args, onLog) {\n const { command: cmd, args: argv } = spawnArgv([command, ...args]);\n return new Promise((resolve) => {\n let child;\n try {\n child = spawn(cmd, argv, { stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (err) {\n onLog(`could not start ${cmd}: ${err.message}`);\n resolve(-1);\n return;\n }\n let pending = '';\n const feed = (chunk) => {\n pending += chunk.toString();\n const lines = pending.split(/\\r?\\n/);\n pending = lines.pop();\n for (const line of lines) if (line.trim()) onLog(line);\n };\n child.stdout.on('data', feed);\n child.stderr.on('data', feed);\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n onLog(`${cmd} took too long and was stopped.`);\n }, STEP_TIMEOUT_MS);\n child.on('error', (err) => {\n clearTimeout(timer);\n onLog(`could not run ${cmd}: ${err.message}`);\n resolve(-1);\n });\n child.on('close', (code) => {\n clearTimeout(timer);\n if (pending.trim()) onLog(pending);\n resolve(code ?? -1);\n });\n });\n}\n\n// Install a tool, streaming progress through `onEvent({ type, ... })`:\n// { type: 'log', line } — one line of output from the installer\n// { type: 'plan', id, label } — which plan is being attempted\n// { type: 'done', ok, error?, method? }\n// Resolves with the same shape as the final `done` event.\nexport async function installTool(toolId, onEvent: (event: Record<string, unknown>) => void = (..._args: unknown[]) => {}) {\n const log = (line) => onEvent({ type: 'log', line });\n const finish = (result) => { onEvent({ type: 'done', ...result }); return result; };\n\n const plans = plansFor(toolId);\n if (!plans.length) {\n return finish({ ok: false, error: `Onboarder does not know how to install \"${toolId}\".` });\n }\n if (installing.has(toolId)) {\n return finish({ ok: false, error: `${toolId} is already being installed.` });\n }\n installing.add(toolId);\n\n try {\n const ctx = {\n platform: process.platform,\n arch: process.arch,\n tmpDir: os.tmpdir(),\n binDir: onboarderBinDir(),\n };\n\n let attempted = 0;\n for (const plan of plans) {\n const launcher = findOnPath(plan.needs);\n if (!launcher) {\n log(`— skipping ${plan.label}: no ${plan.needs} on this machine.`);\n continue;\n }\n attempted += 1;\n onEvent({ type: 'plan', id: plan.id, label: plan.label });\n log(`Installing ${toolId} with ${plan.label}…`);\n\n if (plan.id === 'download') fs.mkdirSync(ctx.binDir, { recursive: true });\n\n let failed = false;\n for (const [command, args] of plan.steps(launcher, ctx)) {\n log(`$ ${command} ${args.join(' ')}`);\n const status = await runStep(command, args, log);\n if (status !== 0) {\n log(`✗ that step exited ${status}.`);\n failed = true;\n break;\n }\n }\n if (failed) continue;\n\n try {\n const binPath = plan.after ? plan.after(ctx) : null;\n if (binPath) log(`Installed to ${binPath}`);\n } catch (err) {\n log(`✗ unpack failed: ${err.message}`);\n continue;\n }\n\n clearDetectionCache();\n log('✓ done. Re-checking the engine list…');\n return finish({ ok: true, method: plan.label });\n }\n\n const why = attempted\n ? 'Every available installer failed — the log above says where.'\n : 'No installer this machine has can install it. Try the manual command in the engine list.';\n return finish({ ok: false, error: why });\n } finally {\n installing.delete(toolId);\n }\n}\n\n"]}
@@ -0,0 +1,8 @@
1
+ export declare const SEVERITY_ORDER: string[];
2
+ export declare function normalizeSeverity(raw: any): "critical" | "high" | "info" | "low" | "medium";
3
+ export declare function parseSemgrep(json: any, rel: any): any[];
4
+ export declare function parseGitleaks(json: any, rel: any): any[];
5
+ export declare function parseKnip(json: any, rel: any): any[];
6
+ export declare function parseVulture(text: any, rel: any): any[];
7
+ export declare function parseDepcheck(json: any): any[];
8
+ export declare function mergeFindings(...lists: any[]): any[];