codebase-onboarder 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/README.md +284 -53
  2. package/bin/build-if-source.js +23 -0
  3. package/bin/onboarder.js +0 -0
  4. package/cli/agent/command.d.ts +71 -0
  5. package/cli/agent/command.js +177 -0
  6. package/cli/agent/command.js.map +1 -0
  7. package/cli/agent/config.d.ts +31 -0
  8. package/cli/agent/config.js +98 -0
  9. package/cli/agent/config.js.map +1 -0
  10. package/cli/agent/contracts.d.ts +77 -0
  11. package/cli/agent/contracts.js +2 -0
  12. package/cli/agent/contracts.js.map +1 -0
  13. package/cli/agent/files.d.ts +19 -0
  14. package/cli/agent/files.js +109 -0
  15. package/cli/agent/files.js.map +1 -0
  16. package/cli/agent/gitSource.d.ts +18 -0
  17. package/cli/agent/gitSource.js +69 -0
  18. package/cli/agent/gitSource.js.map +1 -0
  19. package/cli/agent/github.d.ts +21 -0
  20. package/cli/agent/github.js +94 -0
  21. package/cli/agent/github.js.map +1 -0
  22. package/cli/agent/mcp.d.ts +15 -0
  23. package/cli/agent/mcp.js +78 -0
  24. package/cli/agent/mcp.js.map +1 -0
  25. package/cli/agent/process.d.ts +18 -0
  26. package/cli/agent/process.js +118 -0
  27. package/cli/agent/process.js.map +1 -0
  28. package/cli/agent/protocol.d.ts +3 -0
  29. package/cli/agent/protocol.js +26 -0
  30. package/cli/agent/protocol.js.map +1 -0
  31. package/cli/agent/runner.d.ts +34 -0
  32. package/cli/agent/runner.js +152 -0
  33. package/cli/agent/runner.js.map +1 -0
  34. package/cli/agent/stdio.d.ts +1 -0
  35. package/cli/agent/stdio.js +62 -0
  36. package/cli/agent/stdio.js.map +1 -0
  37. package/cli/agent/tools.d.ts +7 -0
  38. package/cli/agent/tools.js +201 -0
  39. package/cli/agent/tools.js.map +1 -0
  40. package/cli/chat/app.d.ts +16 -0
  41. package/cli/chat/app.js +345 -0
  42. package/cli/chat/app.js.map +1 -0
  43. package/cli/chat/commands.d.ts +11 -0
  44. package/cli/chat/commands.js +120 -0
  45. package/cli/chat/commands.js.map +1 -0
  46. package/cli/chat/composer.d.ts +75 -0
  47. package/cli/chat/composer.js +467 -0
  48. package/cli/chat/composer.js.map +1 -0
  49. package/cli/chat/controller.d.ts +60 -0
  50. package/cli/chat/controller.js +393 -0
  51. package/cli/chat/controller.js.map +1 -0
  52. package/cli/chat/logo.d.ts +3 -0
  53. package/cli/chat/logo.js +14 -0
  54. package/cli/chat/logo.js.map +1 -0
  55. package/cli/chat/models.d.ts +18 -0
  56. package/cli/chat/models.js +88 -0
  57. package/cli/chat/models.js.map +1 -0
  58. package/cli/chat/profile.d.ts +5 -0
  59. package/cli/chat/profile.js +98 -0
  60. package/cli/chat/profile.js.map +1 -0
  61. package/cli/chat/render.d.ts +40 -0
  62. package/cli/chat/render.js +259 -0
  63. package/cli/chat/render.js.map +1 -0
  64. package/cli/chat/screen.d.ts +26 -0
  65. package/cli/chat/screen.js +117 -0
  66. package/cli/chat/screen.js.map +1 -0
  67. package/cli/chat/source.d.ts +29 -0
  68. package/cli/chat/source.js +116 -0
  69. package/cli/chat/source.js.map +1 -0
  70. package/cli/chat/store.d.ts +43 -0
  71. package/cli/chat/store.js +94 -0
  72. package/cli/chat/store.js.map +1 -0
  73. package/cli/chat/text.d.ts +4 -0
  74. package/cli/chat/text.js +27 -0
  75. package/cli/chat/text.js.map +1 -0
  76. package/cli/commands.d.ts +26 -0
  77. package/cli/commands.js +836 -811
  78. package/cli/commands.js.map +1 -0
  79. package/cli/explorer/advanced.d.ts +14 -0
  80. package/cli/explorer/advanced.js +321 -329
  81. package/cli/explorer/advanced.js.map +1 -0
  82. package/cli/explorer/app.d.ts +2 -0
  83. package/cli/explorer/app.js +404 -314
  84. package/cli/explorer/app.js.map +1 -0
  85. package/cli/explorer/assistant.d.ts +9 -0
  86. package/cli/explorer/assistant.js +58 -0
  87. package/cli/explorer/assistant.js.map +1 -0
  88. package/cli/explorer/commands.d.ts +17 -0
  89. package/cli/explorer/commands.js +373 -302
  90. package/cli/explorer/commands.js.map +1 -0
  91. package/cli/explorer/featureViews.d.ts +124 -0
  92. package/cli/explorer/featureViews.js +179 -0
  93. package/cli/explorer/featureViews.js.map +1 -0
  94. package/cli/explorer/github.d.ts +21 -0
  95. package/cli/explorer/github.js +42 -44
  96. package/cli/explorer/github.js.map +1 -0
  97. package/cli/explorer/graphs.d.ts +7 -0
  98. package/cli/explorer/graphs.js +90 -95
  99. package/cli/explorer/graphs.js.map +1 -0
  100. package/cli/explorer/picker.d.ts +22 -0
  101. package/cli/explorer/picker.js +150 -0
  102. package/cli/explorer/picker.js.map +1 -0
  103. package/cli/explorer/report.d.ts +85 -0
  104. package/cli/explorer/report.js +60 -0
  105. package/cli/explorer/report.js.map +1 -0
  106. package/cli/explorer/session.d.ts +449 -0
  107. package/cli/explorer/session.js +143 -144
  108. package/cli/explorer/session.js.map +1 -0
  109. package/cli/explorer/views.d.ts +19 -0
  110. package/cli/explorer/views.js +465 -482
  111. package/cli/explorer/views.js.map +1 -0
  112. package/cli/explorer/wrap.d.ts +1 -0
  113. package/cli/explorer/wrap.js +28 -44
  114. package/cli/explorer/wrap.js.map +1 -0
  115. package/cli/main.d.ts +1 -0
  116. package/cli/main.js +251 -164
  117. package/cli/main.js.map +1 -0
  118. package/cli/prompt.d.ts +5 -0
  119. package/cli/prompt.js +84 -80
  120. package/cli/prompt.js.map +1 -0
  121. package/cli/scanOptions.d.ts +2 -0
  122. package/cli/scanOptions.js +11 -0
  123. package/cli/scanOptions.js.map +1 -0
  124. package/cli/ui.d.ts +33 -0
  125. package/cli/ui.js +35 -44
  126. package/cli/ui.js.map +1 -0
  127. package/cli/wizard.d.ts +187 -0
  128. package/cli/wizard.js +304 -284
  129. package/cli/wizard.js.map +1 -0
  130. package/docs/HERMES_RESEARCH.md +51 -0
  131. package/package.json +16 -4
  132. package/public/app.d.ts +1 -0
  133. package/public/app.js +1133 -1011
  134. package/public/app.js.map +1 -0
  135. package/public/assets/onboarder-mark.svg +11 -0
  136. package/public/browser.d.ts +71 -0
  137. package/public/browser.js +2 -0
  138. package/public/browser.js.map +1 -0
  139. package/public/index.html +54 -20
  140. package/public/js/about.d.ts +6 -0
  141. package/public/js/about.js +152 -172
  142. package/public/js/about.js.map +1 -0
  143. package/public/js/aiDraft.d.ts +4 -0
  144. package/public/js/aiDraft.js +166 -125
  145. package/public/js/aiDraft.js.map +1 -0
  146. package/public/js/analysisPanel.d.ts +7 -0
  147. package/public/js/analysisPanel.js +166 -166
  148. package/public/js/analysisPanel.js.map +1 -0
  149. package/public/js/analysisReport.d.ts +38 -0
  150. package/public/js/analysisReport.js +105 -110
  151. package/public/js/analysisReport.js.map +1 -0
  152. package/public/js/api.d.ts +29 -0
  153. package/public/js/api.js +198 -166
  154. package/public/js/api.js.map +1 -0
  155. package/public/js/atlas.d.ts +6 -0
  156. package/public/js/atlas.js +50 -58
  157. package/public/js/atlas.js.map +1 -0
  158. package/public/js/blameView.d.ts +2 -0
  159. package/public/js/blameView.js +36 -37
  160. package/public/js/blameView.js.map +1 -0
  161. package/public/js/codeTab.d.ts +3 -0
  162. package/public/js/codeTab.js +175 -180
  163. package/public/js/codeTab.js.map +1 -0
  164. package/public/js/codeViewer.d.ts +5 -0
  165. package/public/js/codeViewer.js +162 -150
  166. package/public/js/codeViewer.js.map +1 -0
  167. package/public/js/components/FileChip.d.ts +9 -0
  168. package/public/js/components/FileChip.js +45 -49
  169. package/public/js/components/FileChip.js.map +1 -0
  170. package/public/js/components/MetricSparkline.d.ts +7 -0
  171. package/public/js/components/MetricSparkline.js +35 -44
  172. package/public/js/components/MetricSparkline.js.map +1 -0
  173. package/public/js/components/RiskBadge.d.ts +9 -0
  174. package/public/js/components/RiskBadge.js +55 -63
  175. package/public/js/components/RiskBadge.js.map +1 -0
  176. package/public/js/deepAnalysisView.d.ts +99 -0
  177. package/public/js/deepAnalysisView.js +282 -302
  178. package/public/js/deepAnalysisView.js.map +1 -0
  179. package/public/js/diagramPane.d.ts +9 -0
  180. package/public/js/diagramPane.js +138 -135
  181. package/public/js/diagramPane.js.map +1 -0
  182. package/public/js/diffView.d.ts +6 -0
  183. package/public/js/diffView.js +222 -209
  184. package/public/js/diffView.js.map +1 -0
  185. package/public/js/docsView.d.ts +2 -0
  186. package/public/js/docsView.js +441 -442
  187. package/public/js/docsView.js.map +1 -0
  188. package/public/js/dom.d.ts +197 -0
  189. package/public/js/dom.js +5 -0
  190. package/public/js/dom.js.map +1 -0
  191. package/public/js/fileSourceBrowser.d.ts +5 -0
  192. package/public/js/fileSourceBrowser.js +33 -41
  193. package/public/js/fileSourceBrowser.js.map +1 -0
  194. package/public/js/flameGraph.d.ts +5 -0
  195. package/public/js/flameGraph.js +62 -72
  196. package/public/js/flameGraph.js.map +1 -0
  197. package/public/js/forceGraph.d.ts +10 -0
  198. package/public/js/forceGraph.js +581 -556
  199. package/public/js/forceGraph.js.map +1 -0
  200. package/public/js/heatmap.d.ts +4 -0
  201. package/public/js/heatmap.js +142 -164
  202. package/public/js/heatmap.js.map +1 -0
  203. package/public/js/highlight.d.ts +2 -0
  204. package/public/js/highlight.js +116 -107
  205. package/public/js/highlight.js.map +1 -0
  206. package/public/js/html.d.ts +2 -0
  207. package/public/js/html.js +14 -44
  208. package/public/js/html.js.map +1 -0
  209. package/public/js/insightsView.d.ts +5 -0
  210. package/public/js/insightsView.js +93 -111
  211. package/public/js/insightsView.js.map +1 -0
  212. package/public/js/inspector.d.ts +37 -0
  213. package/public/js/inspector.js +416 -445
  214. package/public/js/inspector.js.map +1 -0
  215. package/public/js/llm.d.ts +115 -0
  216. package/public/js/llm.js +246 -278
  217. package/public/js/llm.js.map +1 -0
  218. package/public/js/mapView.d.ts +3 -0
  219. package/public/js/mapView.js +121 -120
  220. package/public/js/mapView.js.map +1 -0
  221. package/public/js/markdown.d.ts +3 -0
  222. package/public/js/markdown.js +84 -91
  223. package/public/js/markdown.js.map +1 -0
  224. package/public/js/mindmap.d.ts +32 -0
  225. package/public/js/mindmap.js +244 -259
  226. package/public/js/mindmap.js.map +1 -0
  227. package/public/js/mobilePanels.d.ts +5 -0
  228. package/public/js/mobilePanels.js +50 -0
  229. package/public/js/mobilePanels.js.map +1 -0
  230. package/public/js/repoFiles.d.ts +12 -0
  231. package/public/js/repoFiles.js +29 -28
  232. package/public/js/repoFiles.js.map +1 -0
  233. package/public/js/reviewView.d.ts +28 -0
  234. package/public/js/reviewView.js +256 -0
  235. package/public/js/reviewView.js.map +1 -0
  236. package/public/js/sbomView.d.ts +3 -0
  237. package/public/js/sbomView.js +59 -67
  238. package/public/js/sbomView.js.map +1 -0
  239. package/public/js/scanCache.d.ts +16 -0
  240. package/public/js/scanCache.js +67 -65
  241. package/public/js/scanCache.js.map +1 -0
  242. package/public/js/search.d.ts +7 -0
  243. package/public/js/search.js +868 -800
  244. package/public/js/search.js.map +1 -0
  245. package/public/js/searchLocal.d.ts +42 -0
  246. package/public/js/searchLocal.js +87 -0
  247. package/public/js/searchLocal.js.map +1 -0
  248. package/public/js/serverSettings.d.ts +5 -0
  249. package/public/js/serverSettings.js +153 -164
  250. package/public/js/serverSettings.js.map +1 -0
  251. package/public/js/state.d.ts +798 -0
  252. package/public/js/state.js +114 -122
  253. package/public/js/state.js.map +1 -0
  254. package/public/js/tour.d.ts +6 -0
  255. package/public/js/tour.js +5 -7
  256. package/public/js/tour.js.map +1 -0
  257. package/public/js/transitions.d.ts +2 -0
  258. package/public/js/transitions.js +9 -10
  259. package/public/js/transitions.js.map +1 -0
  260. package/public/js/tree.d.ts +12 -0
  261. package/public/js/tree.js +157 -154
  262. package/public/js/tree.js.map +1 -0
  263. package/public/js/workflowsView.d.ts +3 -0
  264. package/public/js/workflowsView.js +15 -22
  265. package/public/js/workflowsView.js.map +1 -0
  266. package/public/search.css +495 -0
  267. package/public/styles.css +188 -346
  268. package/public/workbench.css +166 -0
  269. package/server/apiAuth.d.ts +3 -0
  270. package/server/apiAuth.js +18 -20
  271. package/server/apiAuth.js.map +1 -0
  272. package/server/apiDiff.d.ts +2 -0
  273. package/server/apiDiff.js +20 -18
  274. package/server/apiDiff.js.map +1 -0
  275. package/server/apiDocs.d.ts +2 -0
  276. package/server/apiDocs.js +38 -40
  277. package/server/apiDocs.js.map +1 -0
  278. package/server/apiFile.d.ts +1 -0
  279. package/server/apiFile.js +14 -17
  280. package/server/apiFile.js.map +1 -0
  281. package/server/apiGitBlame.d.ts +2 -0
  282. package/server/apiGitBlame.js +50 -51
  283. package/server/apiGitBlame.js.map +1 -0
  284. package/server/apiMcp.d.ts +4 -0
  285. package/server/apiMcp.js +64 -66
  286. package/server/apiMcp.js.map +1 -0
  287. package/server/apiReview.d.ts +2 -0
  288. package/server/apiReview.js +45 -0
  289. package/server/apiReview.js.map +1 -0
  290. package/server/apiScan.d.ts +5 -0
  291. package/server/apiScan.js +90 -71
  292. package/server/apiScan.js.map +1 -0
  293. package/server/apiSearch.d.ts +33 -0
  294. package/server/apiSearch.js +184 -200
  295. package/server/apiSearch.js.map +1 -0
  296. package/server/apiSettings.d.ts +4 -0
  297. package/server/apiSettings.js +84 -85
  298. package/server/apiSettings.js.map +1 -0
  299. package/server/apiTools.d.ts +3 -0
  300. package/server/apiTools.js +55 -56
  301. package/server/apiTools.js.map +1 -0
  302. package/server/auth.d.ts +5 -0
  303. package/server/auth.js +54 -51
  304. package/server/auth.js.map +1 -0
  305. package/server/config.d.ts +42 -0
  306. package/server/config.js +189 -194
  307. package/server/config.js.map +1 -0
  308. package/server/daemon.d.ts +12 -0
  309. package/server/daemon.js +124 -114
  310. package/server/daemon.js.map +1 -0
  311. package/server/fileSourceNode.d.ts +2 -0
  312. package/server/fileSourceNode.js +34 -36
  313. package/server/fileSourceNode.js.map +1 -0
  314. package/server/gitClone.d.ts +9 -0
  315. package/server/gitClone.js +59 -61
  316. package/server/gitClone.js.map +1 -0
  317. package/server/gitDiff.d.ts +36 -0
  318. package/server/gitDiff.js +271 -169
  319. package/server/gitDiff.js.map +1 -0
  320. package/server/gitHistory.d.ts +12 -0
  321. package/server/gitHistory.js +80 -80
  322. package/server/gitHistory.js.map +1 -0
  323. package/server/gitRemote.d.ts +12 -0
  324. package/server/gitRemote.js +37 -38
  325. package/server/gitRemote.js.map +1 -0
  326. package/server/hermesChat.d.ts +13 -0
  327. package/server/hermesChat.js +145 -0
  328. package/server/hermesChat.js.map +1 -0
  329. package/server/htmlText.d.ts +4 -0
  330. package/server/htmlText.js +16 -23
  331. package/server/htmlText.js.map +1 -0
  332. package/server/http.d.ts +6 -0
  333. package/server/http.js +27 -34
  334. package/server/http.js.map +1 -0
  335. package/server/httpGuards.d.ts +2 -0
  336. package/server/httpGuards.js +47 -43
  337. package/server/httpGuards.js.map +1 -0
  338. package/server/https.d.ts +34 -0
  339. package/server/https.js +121 -111
  340. package/server/https.js.map +1 -0
  341. package/server/index.d.ts +40 -0
  342. package/server/index.js +139 -147
  343. package/server/index.js.map +1 -0
  344. package/server/layout.d.ts +26 -0
  345. package/server/layout.js +59 -64
  346. package/server/layout.js.map +1 -0
  347. package/server/llmProxy.d.ts +3 -0
  348. package/server/llmProxy.js +137 -135
  349. package/server/llmProxy.js.map +1 -0
  350. package/server/logger.d.ts +38 -0
  351. package/server/logger.js +198 -211
  352. package/server/logger.js.map +1 -0
  353. package/server/mcp/analysis.d.ts +29 -0
  354. package/server/mcp/analysis.js +99 -120
  355. package/server/mcp/analysis.js.map +1 -0
  356. package/server/mcp/http.d.ts +9 -0
  357. package/server/mcp/http.js +128 -137
  358. package/server/mcp/http.js.map +1 -0
  359. package/server/mcp/runner.d.ts +68 -0
  360. package/server/mcp/runner.js +208 -218
  361. package/server/mcp/runner.js.map +1 -0
  362. package/server/mcp/server.d.ts +29 -0
  363. package/server/mcp/server.js +167 -180
  364. package/server/mcp/server.js.map +1 -0
  365. package/server/mcp/standalone.d.ts +1 -0
  366. package/server/mcp/standalone.js +8 -10
  367. package/server/mcp/standalone.js.map +1 -0
  368. package/server/mcp/tools.d.ts +2020 -0
  369. package/server/mcp/tools.js +523 -574
  370. package/server/mcp/tools.js.map +1 -0
  371. package/server/paths.d.ts +3 -0
  372. package/server/paths.js +17 -15
  373. package/server/paths.js.map +1 -0
  374. package/server/pidfile.d.ts +9 -0
  375. package/server/pidfile.js +43 -45
  376. package/server/pidfile.js.map +1 -0
  377. package/server/review.d.ts +5 -0
  378. package/server/review.js +35 -0
  379. package/server/review.js.map +1 -0
  380. package/server/router.d.ts +33 -0
  381. package/server/router.js +195 -197
  382. package/server/router.js.map +1 -0
  383. package/server/scanRequest.d.ts +3 -0
  384. package/server/scanRequest.js +36 -0
  385. package/server/scanRequest.js.map +1 -0
  386. package/server/searchIndex.d.ts +17 -0
  387. package/server/searchIndex.js +83 -80
  388. package/server/searchIndex.js.map +1 -0
  389. package/server/sessions.d.ts +14 -0
  390. package/server/sessions.js +62 -70
  391. package/server/sessions.js.map +1 -0
  392. package/server/startup.d.ts +118 -0
  393. package/server/startup.js +143 -148
  394. package/server/startup.js.map +1 -0
  395. package/server/static.d.ts +6 -0
  396. package/server/static.js +28 -31
  397. package/server/static.js.map +1 -0
  398. package/server/tools/install.d.ts +4 -0
  399. package/server/tools/install.js +176 -185
  400. package/server/tools/install.js.map +1 -0
  401. package/server/tools/parse.d.ts +8 -0
  402. package/server/tools/parse.js +112 -114
  403. package/server/tools/parse.js.map +1 -0
  404. package/server/tools/platform.d.ts +9 -0
  405. package/server/tools/platform.js +49 -47
  406. package/server/tools/platform.js.map +1 -0
  407. package/server/tools/registry.d.ts +137 -0
  408. package/server/tools/registry.js +173 -172
  409. package/server/tools/registry.js.map +1 -0
  410. package/server/tools/scan.d.ts +34 -0
  411. package/server/tools/scan.js +89 -98
  412. package/server/tools/scan.js.map +1 -0
  413. package/server/tools.d.ts +34 -0
  414. package/server/tools.js +94 -107
  415. package/server/tools.js.map +1 -0
  416. package/server/tunnel.d.ts +29 -0
  417. package/server/tunnel.js +61 -66
  418. package/server/tunnel.js.map +1 -0
  419. package/shared/analyzer/docs.d.ts +16 -0
  420. package/shared/analyzer/docs.js +99 -93
  421. package/shared/analyzer/docs.js.map +1 -0
  422. package/shared/analyzer/explainLocal.d.ts +4 -0
  423. package/shared/analyzer/explainLocal.js +122 -142
  424. package/shared/analyzer/explainLocal.js.map +1 -0
  425. package/shared/analyzer/github.d.ts +37 -0
  426. package/shared/analyzer/github.js +41 -43
  427. package/shared/analyzer/github.js.map +1 -0
  428. package/shared/analyzer/graph.d.ts +41 -0
  429. package/shared/analyzer/graph.js +393 -400
  430. package/shared/analyzer/graph.js.map +1 -0
  431. package/shared/analyzer/health.d.ts +33 -0
  432. package/shared/analyzer/health.js +197 -193
  433. package/shared/analyzer/health.js.map +1 -0
  434. package/shared/analyzer/history.d.ts +29 -0
  435. package/shared/analyzer/history.js +110 -111
  436. package/shared/analyzer/history.js.map +1 -0
  437. package/shared/analyzer/jsonConfig.d.ts +2 -0
  438. package/shared/analyzer/jsonConfig.js +61 -0
  439. package/shared/analyzer/jsonConfig.js.map +1 -0
  440. package/shared/analyzer/languages/csharp.d.ts +26 -0
  441. package/shared/analyzer/languages/csharp.js +83 -88
  442. package/shared/analyzer/languages/csharp.js.map +1 -0
  443. package/shared/analyzer/languages/generic.d.ts +23 -0
  444. package/shared/analyzer/languages/generic.js +94 -105
  445. package/shared/analyzer/languages/generic.js.map +1 -0
  446. package/shared/analyzer/languages/go.d.ts +24 -0
  447. package/shared/analyzer/languages/go.js +45 -54
  448. package/shared/analyzer/languages/go.js.map +1 -0
  449. package/shared/analyzer/languages/index.d.ts +6 -0
  450. package/shared/analyzer/languages/index.js +19 -20
  451. package/shared/analyzer/languages/index.js.map +1 -0
  452. package/shared/analyzer/languages/java.d.ts +20 -0
  453. package/shared/analyzer/languages/java.js +73 -78
  454. package/shared/analyzer/languages/java.js.map +1 -0
  455. package/shared/analyzer/languages/javascript.d.ts +12 -0
  456. package/shared/analyzer/languages/javascript.js +258 -209
  457. package/shared/analyzer/languages/javascript.js.map +1 -0
  458. package/shared/analyzer/languages/python.d.ts +23 -0
  459. package/shared/analyzer/languages/python.js +92 -100
  460. package/shared/analyzer/languages/python.js.map +1 -0
  461. package/shared/analyzer/languages/rust.d.ts +17 -0
  462. package/shared/analyzer/languages/rust.js +96 -98
  463. package/shared/analyzer/languages/rust.js.map +1 -0
  464. package/shared/analyzer/languages/typescript.d.ts +11 -0
  465. package/shared/analyzer/languages/typescript.js +117 -116
  466. package/shared/analyzer/languages/typescript.js.map +1 -0
  467. package/shared/analyzer/licenses.d.ts +18 -0
  468. package/shared/analyzer/licenses.js +130 -133
  469. package/shared/analyzer/licenses.js.map +1 -0
  470. package/shared/analyzer/metrics.d.ts +20 -0
  471. package/shared/analyzer/metrics.js +112 -104
  472. package/shared/analyzer/metrics.js.map +1 -0
  473. package/shared/analyzer/pathUtil.d.ts +10 -0
  474. package/shared/analyzer/pathUtil.js +29 -35
  475. package/shared/analyzer/pathUtil.js.map +1 -0
  476. package/shared/analyzer/patterns.d.ts +11 -0
  477. package/shared/analyzer/patterns.js +231 -253
  478. package/shared/analyzer/patterns.js.map +1 -0
  479. package/shared/analyzer/scan.d.ts +62 -0
  480. package/shared/analyzer/scan.js +451 -442
  481. package/shared/analyzer/scan.js.map +1 -0
  482. package/shared/analyzer/scanControl.d.ts +11 -0
  483. package/shared/analyzer/scanControl.js +62 -0
  484. package/shared/analyzer/scanControl.js.map +1 -0
  485. package/shared/analyzer/security.d.ts +18 -0
  486. package/shared/analyzer/security.js +159 -159
  487. package/shared/analyzer/security.js.map +1 -0
  488. package/shared/analyzer/services.d.ts +5 -0
  489. package/shared/analyzer/services.js +141 -138
  490. package/shared/analyzer/services.js.map +1 -0
  491. package/shared/analyzer/stack.d.ts +6 -0
  492. package/shared/analyzer/stack.js +134 -141
  493. package/shared/analyzer/stack.js.map +1 -0
  494. package/shared/analyzer/tour.d.ts +2 -0
  495. package/shared/analyzer/tour.js +45 -53
  496. package/shared/analyzer/tour.js.map +1 -0
  497. package/shared/analyzer/util.d.ts +8 -0
  498. package/shared/analyzer/util.js +130 -76
  499. package/shared/analyzer/util.js.map +1 -0
  500. package/shared/analyzer/workflows.d.ts +8 -0
  501. package/shared/analyzer/workflows.js +139 -134
  502. package/shared/analyzer/workflows.js.map +1 -0
  503. package/shared/contracts.d.ts +250 -0
  504. package/shared/contracts.js +2 -0
  505. package/shared/contracts.js.map +1 -0
  506. package/shared/diagram/aiFacts.d.ts +35 -0
  507. package/shared/diagram/aiFacts.js +102 -105
  508. package/shared/diagram/aiFacts.js.map +1 -0
  509. package/shared/diagram/aiMermaid.d.ts +5 -0
  510. package/shared/diagram/aiMermaid.js +50 -46
  511. package/shared/diagram/aiMermaid.js.map +1 -0
  512. package/shared/diagram/atlas.d.ts +16 -0
  513. package/shared/diagram/atlas.js +51 -60
  514. package/shared/diagram/atlas.js.map +1 -0
  515. package/shared/diagram/mermaid.d.ts +43 -0
  516. package/shared/diagram/mermaid.js +348 -370
  517. package/shared/diagram/mermaid.js.map +1 -0
  518. package/shared/review/contracts.d.ts +95 -0
  519. package/shared/review/contracts.js +2 -0
  520. package/shared/review/contracts.js.map +1 -0
  521. package/shared/review/review.d.ts +10 -0
  522. package/shared/review/review.js +184 -0
  523. package/shared/review/review.js.map +1 -0
  524. package/shared/search/query.d.ts +32 -0
  525. package/shared/search/query.js +395 -388
  526. package/shared/search/query.js.map +1 -0
@@ -12,159 +12,157 @@
12
12
  // `severity` is one of the built-in five. `source` is 'builtin' or 'external'
13
13
  // and `tool` names which engine answered, so the UI can say "found by Semgrep"
14
14
  // rather than letting a finding appear from nowhere.
15
-
16
15
  export const SEVERITY_ORDER = ['info', 'low', 'medium', 'high', 'critical'];
17
-
18
16
  export function normalizeSeverity(raw) {
19
- const s = String(raw || '').toLowerCase();
20
- if (s === 'critical' || s === 'error') return s === 'error' ? 'high' : 'critical';
21
- if (s === 'high') return 'high';
22
- if (s === 'medium' || s === 'warning' || s === 'warn' || s === 'moderate') return 'medium';
23
- if (s === 'low' || s === 'note') return 'low';
24
- return 'info';
17
+ const s = String(raw || '').toLowerCase();
18
+ if (s === 'critical' || s === 'error')
19
+ return s === 'error' ? 'high' : 'critical';
20
+ if (s === 'high')
21
+ return 'high';
22
+ if (s === 'medium' || s === 'warning' || s === 'warn' || s === 'moderate')
23
+ return 'medium';
24
+ if (s === 'low' || s === 'note')
25
+ return 'low';
26
+ return 'info';
25
27
  }
26
-
27
28
  function clipExcerpt(text) {
28
- return String(text ?? '').replace(/\s+/g, ' ').trim().slice(0, 90);
29
+ return String(text ?? '').replace(/\s+/g, ' ').trim().slice(0, 90);
29
30
  }
30
-
31
31
  // ---- Semgrep / Opengrep ----------------------------------------------------
32
32
  // `semgrep --json` → { results: [ { check_id, path, start:{line}, extra:
33
33
  // { severity, message, lines, metadata:{category} } } ] }. Opengrep is the same
34
34
  // JSON. `rel` strips the scan root so paths match the repo-relative form the
35
35
  // rest of the app uses.
36
36
  export function parseSemgrep(json, rel) {
37
- const results = Array.isArray(json && json.results) ? json.results : [];
38
- const findings = [];
39
- for (const r of results) {
40
- const extra = r.extra || {};
41
- findings.push({
42
- rule: String(r.check_id || 'semgrep-rule'),
43
- severity: normalizeSeverity(extra.severity),
44
- category: (extra.metadata && extra.metadata.category) || 'security',
45
- message: clipExcerpt(extra.message || r.check_id),
46
- path: rel(r.path),
47
- line: r.start && r.start.line ? r.start.line : 1,
48
- excerpt: clipExcerpt(extra.lines),
49
- source: 'external',
50
- tool: 'semgrep',
51
- });
52
- }
53
- return findings;
37
+ const results = Array.isArray(json && json.results) ? json.results : [];
38
+ const findings = [];
39
+ for (const r of results) {
40
+ const extra = r.extra || {};
41
+ findings.push({
42
+ rule: String(r.check_id || 'semgrep-rule'),
43
+ severity: normalizeSeverity(extra.severity),
44
+ category: (extra.metadata && extra.metadata.category) || 'security',
45
+ message: clipExcerpt(extra.message || r.check_id),
46
+ path: rel(r.path),
47
+ line: r.start && r.start.line ? r.start.line : 1,
48
+ excerpt: clipExcerpt(extra.lines),
49
+ source: 'external',
50
+ tool: 'semgrep',
51
+ });
52
+ }
53
+ return findings;
54
54
  }
55
-
56
55
  // ---- Gitleaks ---------------------------------------------------------------
57
56
  // `gitleaks --report-format json` → an array of secrets: [ { RuleID,
58
57
  // Description, File, StartLine, Match, Secret } ]. The finding reports *that* a
59
58
  // secret exists, never the secret — `Secret` is read for nothing.
60
59
  export function parseGitleaks(json, rel) {
61
- const list = Array.isArray(json) ? json : [];
62
- const findings = [];
63
- for (const r of list) {
64
- findings.push({
65
- rule: 'secret:' + (r.RuleID || 'unknown'),
66
- severity: 'critical',
67
- category: 'secret',
68
- message: clipExcerpt(r.Description || 'A secret is committed to the source.'),
69
- path: rel(r.File),
70
- line: r.StartLine || 1,
71
- excerpt: 'committed credential (value redacted)',
72
- source: 'external',
73
- tool: 'gitleaks',
74
- });
75
- }
76
- return findings;
60
+ const list = Array.isArray(json) ? json : [];
61
+ const findings = [];
62
+ for (const r of list) {
63
+ findings.push({
64
+ rule: 'secret:' + (r.RuleID || 'unknown'),
65
+ severity: 'critical',
66
+ category: 'secret',
67
+ message: clipExcerpt(r.Description || 'A secret is committed to the source.'),
68
+ path: rel(r.File),
69
+ line: r.StartLine || 1,
70
+ excerpt: 'committed credential (value redacted)',
71
+ source: 'external',
72
+ tool: 'gitleaks',
73
+ });
74
+ }
75
+ return findings;
77
76
  }
78
-
79
77
  // ---- Knip -------------------------------------------------------------------
80
78
  // `knip --reporter json` groups dead code by kind: { files:[], dependencies:[],
81
79
  // unused:[{name,file,line}], ... }. Each becomes a finding so the dead-code
82
80
  // pass can be read in one list; the kind is the rule.
83
81
  export function parseKnip(json, rel) {
84
- const findings = [];
85
- const push = (rule, category, severity, path, line, message) => {
86
- findings.push({ rule, category, severity, message, path: rel(path), line: line || 1, excerpt: '', source: 'external', tool: 'knip' });
87
- };
88
-
89
- for (const file of (json && json.files) || []) {
90
- push('knip:unused-file', 'dead-file', 'medium', file, 1, 'This file is never imported anywhere.');
91
- }
92
- for (const dep of (json && json.dependencies) || []) {
93
- push('knip:unused-dependency', 'dead-dependency', 'low', dep, 1, `Dependency "${dep}" is declared but never imported.`);
94
- }
95
- for (const u of (json && json.unused) || []) {
96
- push('knip:unused-export', 'dead-export', 'low', u.file, u.line, `Export "${u.name}" is never used.`);
97
- }
98
- for (const u of (json && json.unresolved) || []) {
99
- push('knip:unresolved', 'dead-import', 'medium', u.file, u.line, `Import "${u.name}" does not resolve to anything.`);
100
- }
101
- return findings;
82
+ const findings = [];
83
+ const push = (rule, category, severity, path, line, message) => {
84
+ findings.push({ rule, category, severity, message, path: rel(path), line: line || 1, excerpt: '', source: 'external', tool: 'knip' });
85
+ };
86
+ for (const file of (json && json.files) || []) {
87
+ push('knip:unused-file', 'dead-file', 'medium', file, 1, 'This file is never imported anywhere.');
88
+ }
89
+ for (const dep of (json && json.dependencies) || []) {
90
+ push('knip:unused-dependency', 'dead-dependency', 'low', dep, 1, `Dependency "${dep}" is declared but never imported.`);
91
+ }
92
+ for (const u of (json && json.unused) || []) {
93
+ push('knip:unused-export', 'dead-export', 'low', u.file, u.line, `Export "${u.name}" is never used.`);
94
+ }
95
+ for (const u of (json && json.unresolved) || []) {
96
+ push('knip:unresolved', 'dead-import', 'medium', u.file, u.line, `Import "${u.name}" does not resolve to anything.`);
97
+ }
98
+ return findings;
102
99
  }
103
-
104
100
  // ---- Vulture ----------------------------------------------------------------
105
101
  // `vulture` prints lines like `src/util.py:42: unused function 'helper' (60%
106
102
  // confidence)`. There is no stable JSON, so we parse the text — which is why the
107
103
  // parser is a pure function over a string, and why the line shape is pinned by
108
104
  // a test rather than by reading the binary's source.
109
105
  const VULTURE_RE = /^(.+?):(\d+):\s+(.+?)\s+\((\d+)% confidence\)/;
110
-
111
106
  export function parseVulture(text, rel) {
112
- const findings = [];
113
- for (const line of String(text || '').split('\n')) {
114
- const m = line.match(VULTURE_RE);
115
- if (!m) continue;
116
- const confidence = Number(m[4]);
117
- if (confidence < 60) continue; // below vulture's own floor, it is guessing
118
- findings.push({
119
- rule: 'vulture:' + (m[3].split(' ')[0] || 'unused'),
120
- severity: confidence >= 90 ? 'medium' : 'low',
121
- category: 'dead-code',
122
- message: clipExcerpt(m[3]) + ` (${confidence}% confident)`,
123
- path: rel(m[1]),
124
- line: Number(m[2]) || 1,
125
- excerpt: '',
126
- source: 'external',
127
- tool: 'vulture',
128
- });
129
- }
130
- return findings;
107
+ const findings = [];
108
+ for (const line of String(text || '').split('\n')) {
109
+ const m = line.match(VULTURE_RE);
110
+ if (!m)
111
+ continue;
112
+ const confidence = Number(m[4]);
113
+ if (confidence < 60)
114
+ continue; // below vulture's own floor, it is guessing
115
+ findings.push({
116
+ rule: 'vulture:' + (m[3].split(' ')[0] || 'unused'),
117
+ severity: confidence >= 90 ? 'medium' : 'low',
118
+ category: 'dead-code',
119
+ message: clipExcerpt(m[3]) + ` (${confidence}% confident)`,
120
+ path: rel(m[1]),
121
+ line: Number(m[2]) || 1,
122
+ excerpt: '',
123
+ source: 'external',
124
+ tool: 'vulture',
125
+ });
126
+ }
127
+ return findings;
131
128
  }
132
-
133
129
  // ---- Depcheck ---------------------------------------------------------------
134
130
  // `depcheck --json` → { dependencies:[], devDependencies:[], missing:{} }.
135
131
  export function parseDepcheck(json) {
136
- const findings = [];
137
- const push = (name, dev) => findings.push({
138
- rule: 'depcheck:unused',
139
- severity: 'low',
140
- category: 'dead-dependency',
141
- message: `Package "${name}" is declared in package.json but never imported.`,
142
- path: 'package.json',
143
- line: 1,
144
- excerpt: '',
145
- source: 'external',
146
- tool: 'depcheck',
147
- dev,
148
- });
149
- for (const name of (json && json.dependencies) || []) push(name, false);
150
- for (const name of (json && json.devDependencies) || []) push(name, true);
151
- return findings;
132
+ const findings = [];
133
+ const push = (name, dev) => findings.push({
134
+ rule: 'depcheck:unused',
135
+ severity: 'low',
136
+ category: 'dead-dependency',
137
+ message: `Package "${name}" is declared in package.json but never imported.`,
138
+ path: 'package.json',
139
+ line: 1,
140
+ excerpt: '',
141
+ source: 'external',
142
+ tool: 'depcheck',
143
+ dev,
144
+ });
145
+ for (const name of (json && json.dependencies) || [])
146
+ push(name, false);
147
+ for (const name of (json && json.devDependencies) || [])
148
+ push(name, true);
149
+ return findings;
152
150
  }
153
-
154
151
  // Merge the external passes into one list, keeping the built-in scan's findings
155
152
  // untouched. Dedup on (path, line, rule): two engines that flag the same line
156
153
  // for the same reason are one problem, not two.
157
154
  export function mergeFindings(...lists) {
158
- const seen = new Set();
159
- const out = [];
160
- for (const list of lists) {
161
- for (const f of list || []) {
162
- const key = `${f.path}:${f.line}:${f.rule}`;
163
- if (seen.has(key)) continue;
164
- seen.add(key);
165
- out.push(f);
155
+ const seen = new Set();
156
+ const out = [];
157
+ for (const list of lists) {
158
+ for (const f of list || []) {
159
+ const key = `${f.path}:${f.line}:${f.rule}`;
160
+ if (seen.has(key))
161
+ continue;
162
+ seen.add(key);
163
+ out.push(f);
164
+ }
166
165
  }
167
- }
168
- return out;
166
+ return out;
169
167
  }
170
-
168
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/server/tools/parse.ts"],"names":[],"mappings":"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","sourcesContent":["// Parsing the dialects. Every analyzer speaks its own JSON (or SARIF); the UI\n// speaks one. This file is the translation layer, and it is pure — it takes a\n// string a tool printed and returns findings, so it can be tested in Node with\n// fixtures and needs no process, no filesystem, no PATH.\n//\n// The single target shape is the one the built-in scanner already emits\n// (`shared/analyzer/security.js`), so the existing security view needs no new\n// kind of row:\n//\n// { rule, severity, category, message, line, excerpt, source, tool }\n//\n// `severity` is one of the built-in five. `source` is 'builtin' or 'external'\n// and `tool` names which engine answered, so the UI can say \"found by Semgrep\"\n// rather than letting a finding appear from nowhere.\n\nexport const SEVERITY_ORDER = ['info', 'low', 'medium', 'high', 'critical'];\n\nexport function normalizeSeverity(raw) {\n const s = String(raw || '').toLowerCase();\n if (s === 'critical' || s === 'error') return s === 'error' ? 'high' : 'critical';\n if (s === 'high') return 'high';\n if (s === 'medium' || s === 'warning' || s === 'warn' || s === 'moderate') return 'medium';\n if (s === 'low' || s === 'note') return 'low';\n return 'info';\n}\n\nfunction clipExcerpt(text) {\n return String(text ?? '').replace(/\\s+/g, ' ').trim().slice(0, 90);\n}\n\n// ---- Semgrep / Opengrep ----------------------------------------------------\n// `semgrep --json` → { results: [ { check_id, path, start:{line}, extra:\n// { severity, message, lines, metadata:{category} } } ] }. Opengrep is the same\n// JSON. `rel` strips the scan root so paths match the repo-relative form the\n// rest of the app uses.\nexport function parseSemgrep(json, rel) {\n const results = Array.isArray(json && json.results) ? json.results : [];\n const findings = [];\n for (const r of results) {\n const extra = r.extra || {};\n findings.push({\n rule: String(r.check_id || 'semgrep-rule'),\n severity: normalizeSeverity(extra.severity),\n category: (extra.metadata && extra.metadata.category) || 'security',\n message: clipExcerpt(extra.message || r.check_id),\n path: rel(r.path),\n line: r.start && r.start.line ? r.start.line : 1,\n excerpt: clipExcerpt(extra.lines),\n source: 'external',\n tool: 'semgrep',\n });\n }\n return findings;\n}\n\n// ---- Gitleaks ---------------------------------------------------------------\n// `gitleaks --report-format json` → an array of secrets: [ { RuleID,\n// Description, File, StartLine, Match, Secret } ]. The finding reports *that* a\n// secret exists, never the secret — `Secret` is read for nothing.\nexport function parseGitleaks(json, rel) {\n const list = Array.isArray(json) ? json : [];\n const findings = [];\n for (const r of list) {\n findings.push({\n rule: 'secret:' + (r.RuleID || 'unknown'),\n severity: 'critical',\n category: 'secret',\n message: clipExcerpt(r.Description || 'A secret is committed to the source.'),\n path: rel(r.File),\n line: r.StartLine || 1,\n excerpt: 'committed credential (value redacted)',\n source: 'external',\n tool: 'gitleaks',\n });\n }\n return findings;\n}\n\n// ---- Knip -------------------------------------------------------------------\n// `knip --reporter json` groups dead code by kind: { files:[], dependencies:[],\n// unused:[{name,file,line}], ... }. Each becomes a finding so the dead-code\n// pass can be read in one list; the kind is the rule.\nexport function parseKnip(json, rel) {\n const findings = [];\n const push = (rule, category, severity, path, line, message) => {\n findings.push({ rule, category, severity, message, path: rel(path), line: line || 1, excerpt: '', source: 'external', tool: 'knip' });\n };\n\n for (const file of (json && json.files) || []) {\n push('knip:unused-file', 'dead-file', 'medium', file, 1, 'This file is never imported anywhere.');\n }\n for (const dep of (json && json.dependencies) || []) {\n push('knip:unused-dependency', 'dead-dependency', 'low', dep, 1, `Dependency \"${dep}\" is declared but never imported.`);\n }\n for (const u of (json && json.unused) || []) {\n push('knip:unused-export', 'dead-export', 'low', u.file, u.line, `Export \"${u.name}\" is never used.`);\n }\n for (const u of (json && json.unresolved) || []) {\n push('knip:unresolved', 'dead-import', 'medium', u.file, u.line, `Import \"${u.name}\" does not resolve to anything.`);\n }\n return findings;\n}\n\n// ---- Vulture ----------------------------------------------------------------\n// `vulture` prints lines like `src/util.py:42: unused function 'helper' (60%\n// confidence)`. There is no stable JSON, so we parse the text — which is why the\n// parser is a pure function over a string, and why the line shape is pinned by\n// a test rather than by reading the binary's source.\nconst VULTURE_RE = /^(.+?):(\\d+):\\s+(.+?)\\s+\\((\\d+)% confidence\\)/;\n\nexport function parseVulture(text, rel) {\n const findings = [];\n for (const line of String(text || '').split('\\n')) {\n const m = line.match(VULTURE_RE);\n if (!m) continue;\n const confidence = Number(m[4]);\n if (confidence < 60) continue; // below vulture's own floor, it is guessing\n findings.push({\n rule: 'vulture:' + (m[3].split(' ')[0] || 'unused'),\n severity: confidence >= 90 ? 'medium' : 'low',\n category: 'dead-code',\n message: clipExcerpt(m[3]) + ` (${confidence}% confident)`,\n path: rel(m[1]),\n line: Number(m[2]) || 1,\n excerpt: '',\n source: 'external',\n tool: 'vulture',\n });\n }\n return findings;\n}\n\n// ---- Depcheck ---------------------------------------------------------------\n// `depcheck --json` → { dependencies:[], devDependencies:[], missing:{} }.\nexport function parseDepcheck(json) {\n const findings = [];\n const push = (name, dev) => findings.push({\n rule: 'depcheck:unused',\n severity: 'low',\n category: 'dead-dependency',\n message: `Package \"${name}\" is declared in package.json but never imported.`,\n path: 'package.json',\n line: 1,\n excerpt: '',\n source: 'external',\n tool: 'depcheck',\n dev,\n });\n for (const name of (json && json.dependencies) || []) push(name, false);\n for (const name of (json && json.devDependencies) || []) push(name, true);\n return findings;\n}\n\n// Merge the external passes into one list, keeping the built-in scan's findings\n// untouched. Dedup on (path, line, rule): two engines that flag the same line\n// for the same reason are one problem, not two.\nexport function mergeFindings(...lists) {\n const seen = new Set();\n const out = [];\n for (const list of lists) {\n for (const f of list || []) {\n const key = `${f.path}:${f.line}:${f.rule}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(f);\n }\n }\n return out;\n}\n\n"]}
@@ -0,0 +1,9 @@
1
+ export declare function onboarderBinDir(home?: string): string;
2
+ export declare function candidateNames(cmd: any, platform?: NodeJS.Platform, pathext?: string): any[];
3
+ export declare function extraSearchDirs(platform?: NodeJS.Platform, home?: string): string[];
4
+ export declare function splitPath(pathValue: any, platform?: NodeJS.Platform): string[];
5
+ export declare function findOnPath(cmd: any, options?: Record<string, any>): string;
6
+ export declare function spawnArgv(argv: any, platform?: NodeJS.Platform): {
7
+ command: any;
8
+ args: any;
9
+ };
@@ -12,80 +12,82 @@
12
12
  // Silicon is the classic case — and the folder Onboarder's own installer
13
13
  // drops downloaded binaries into, so a tool installed from the GUI is found
14
14
  // on the next status check without a server restart.
15
-
16
15
  import fs from 'node:fs';
17
16
  import os from 'node:os';
18
17
  import path from 'node:path';
19
-
20
18
  // Where `install.js` puts binaries it downloads itself (gitleaks on Linux and
21
19
  // Windows). One fixed place, under the user's home, never the scanned repo.
22
20
  export function onboarderBinDir(home = os.homedir()) {
23
- return path.join(home, '.onboarder', 'bin');
21
+ return path.join(home, '.onboarder', 'bin');
24
22
  }
25
-
26
23
  // The names a command can go by on disk. Windows resolves `npm` to the first
27
24
  // of `npm.exe`, `npm.cmd`, … on PATHEXT; POSIX looks for the name as-is.
28
25
  export function candidateNames(cmd, platform = process.platform, pathext = '') {
29
- if (platform !== 'win32') return [cmd];
30
- const exts = (pathext || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM')
31
- .split(';').map((e) => e.trim()).filter(Boolean);
32
- const lower = cmd.toLowerCase();
33
- if (exts.some((e) => lower.endsWith(e.toLowerCase()))) return [cmd];
34
- return [cmd, ...exts.map((e) => cmd + e.toLowerCase())];
26
+ if (platform !== 'win32')
27
+ return [cmd];
28
+ const exts = (pathext || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM')
29
+ .split(';').map((e) => e.trim()).filter(Boolean);
30
+ const lower = cmd.toLowerCase();
31
+ if (exts.some((e) => lower.endsWith(e.toLowerCase())))
32
+ return [cmd];
33
+ return [cmd, ...exts.map((e) => cmd + e.toLowerCase())];
35
34
  }
36
-
37
35
  // Directories worth checking beyond PATH itself. The Homebrew pair matters on
38
36
  // a Mac launched from Spotlight rather than a shell; the Onboarder bin dir is
39
37
  // where the GUI installer puts self-downloaded tools.
40
38
  export function extraSearchDirs(platform = process.platform, home = os.homedir()) {
41
- const dirs = [onboarderBinDir(home)];
42
- if (platform === 'darwin') dirs.push('/opt/homebrew/bin', '/usr/local/bin');
43
- if (platform === 'linux') dirs.push('/usr/local/bin', path.join(home, '.local', 'bin'));
44
- if (platform === 'win32') {
45
- const local = process.env.LOCALAPPDATA;
46
- if (local) dirs.push(path.join(local, 'Programs', 'Gitleaks'));
47
- }
48
- return dirs;
39
+ const dirs = [onboarderBinDir(home)];
40
+ if (platform === 'darwin')
41
+ dirs.push('/opt/homebrew/bin', '/usr/local/bin');
42
+ if (platform === 'linux')
43
+ dirs.push('/usr/local/bin', path.join(home, '.local', 'bin'));
44
+ if (platform === 'win32') {
45
+ const local = process.env.LOCALAPPDATA;
46
+ if (local)
47
+ dirs.push(path.join(local, 'Programs', 'Gitleaks'));
48
+ }
49
+ return dirs;
49
50
  }
50
-
51
51
  // Split a PATH string the way the platform does. Exported for tests.
52
52
  export function splitPath(pathValue, platform = process.platform) {
53
- return String(pathValue || '')
54
- .split(platform === 'win32' ? ';' : ':')
55
- .map((d) => d.trim())
56
- .filter(Boolean);
53
+ return String(pathValue || '')
54
+ .split(platform === 'win32' ? ';' : ':')
55
+ .map((d) => d.trim())
56
+ .filter(Boolean);
57
57
  }
58
-
59
58
  // Find `cmd` on PATH (plus the extra dirs). Returns the absolute path, or
60
59
  // null. Pure apart from the `exists` probe, which defaults to the disk and is
61
60
  // injectable so the tests never touch a real filesystem layout.
62
61
  export function findOnPath(cmd, options = {}) {
63
- const platform = options.platform || process.platform;
64
- const envPath = options.envPath !== undefined ? options.envPath : process.env.PATH;
65
- const pathext = options.pathext !== undefined ? options.pathext : process.env.PATHEXT;
66
- const exists = options.exists || ((p) => fs.existsSync(p));
67
- const home = options.home || os.homedir();
68
-
69
- const dirs = [...splitPath(envPath, platform), ...extraSearchDirs(platform, home)];
70
- for (const dir of dirs) {
71
- for (const name of candidateNames(cmd, platform, pathext)) {
72
- const full = path.join(dir, name);
73
- try {
74
- if (exists(full)) return full;
75
- } catch {
76
- /* an unreadable dir is just not where the tool lives */
77
- }
62
+ const platform = options.platform || process.platform;
63
+ const envPath = options.envPath !== undefined ? options.envPath : process.env.PATH;
64
+ const pathext = options.pathext !== undefined ? options.pathext : process.env.PATHEXT;
65
+ const exists = options.exists || ((p) => fs.existsSync(p));
66
+ const home = options.home || os.homedir();
67
+ const dirs = [...splitPath(envPath, platform), ...extraSearchDirs(platform, home)];
68
+ for (const dir of dirs) {
69
+ for (const name of candidateNames(cmd, platform, pathext)) {
70
+ const full = path.join(dir, name);
71
+ try {
72
+ if (exists(full))
73
+ return full;
74
+ }
75
+ catch {
76
+ /* an unreadable dir is just not where the tool lives */
77
+ }
78
+ }
78
79
  }
79
- }
80
- return null;
80
+ return null;
81
81
  }
82
-
83
82
  // A `.cmd`/`.bat` shim cannot be spawned directly on Windows (Node refuses
84
83
  // with EINVAL): it needs cmd.exe. `spawnArgv` rewrites the argv for that case
85
84
  // and leaves everything else untouched, so callers keep passing plain arrays.
86
85
  export function spawnArgv(argv, platform = process.platform) {
87
- if (platform !== 'win32') return { command: argv[0], args: argv.slice(1) };
88
- if (!/\.(cmd|bat)$/i.test(argv[0] || '')) return { command: argv[0], args: argv.slice(1) };
89
- const quoted = argv.map((a) => `"${String(a).replace(/"/g, '\\"')}"`).join(' ');
90
- return { command: 'cmd.exe', args: ['/d', '/s', '/c', quoted] };
86
+ if (platform !== 'win32')
87
+ return { command: argv[0], args: argv.slice(1) };
88
+ if (!/\.(cmd|bat)$/i.test(argv[0] || ''))
89
+ return { command: argv[0], args: argv.slice(1) };
90
+ const quoted = argv.map((a) => `"${String(a).replace(/"/g, '\\"')}"`).join(' ');
91
+ return { command: 'cmd.exe', args: ['/d', '/s', '/c', quoted] };
91
92
  }
93
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/server/tools/platform.ts"],"names":[],"mappings":"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","sourcesContent":["// Cross-platform binary lookup.\n//\n// The engine used to ask the Unix `which` command where a tool lives. That is\n// the right answer on macOS and Linux and *no* answer on Windows, where the\n// command is `where` and an npm-installed tool is a `npm.cmd` shim, not an\n// ELF file. Doing the lookup by hand — split PATH, try the PATHEXT suffixes\n// on Windows — keeps one code path for all three platforms, keeps it testable\n// (`exists` is injectable), and removes a spawned process from detection.\n//\n// `findOnPath` also checks a couple of well-known directories that are on a\n// user's interactive PATH but often not on the server's — Homebrew on Apple\n// Silicon is the classic case — and the folder Onboarder's own installer\n// drops downloaded binaries into, so a tool installed from the GUI is found\n// on the next status check without a server restart.\n\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\n// Where `install.js` puts binaries it downloads itself (gitleaks on Linux and\n// Windows). One fixed place, under the user's home, never the scanned repo.\nexport function onboarderBinDir(home = os.homedir()) {\n return path.join(home, '.onboarder', 'bin');\n}\n\n// The names a command can go by on disk. Windows resolves `npm` to the first\n// of `npm.exe`, `npm.cmd`, … on PATHEXT; POSIX looks for the name as-is.\nexport function candidateNames(cmd, platform = process.platform, pathext = '') {\n if (platform !== 'win32') return [cmd];\n const exts = (pathext || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM')\n .split(';').map((e) => e.trim()).filter(Boolean);\n const lower = cmd.toLowerCase();\n if (exts.some((e) => lower.endsWith(e.toLowerCase()))) return [cmd];\n return [cmd, ...exts.map((e) => cmd + e.toLowerCase())];\n}\n\n// Directories worth checking beyond PATH itself. The Homebrew pair matters on\n// a Mac launched from Spotlight rather than a shell; the Onboarder bin dir is\n// where the GUI installer puts self-downloaded tools.\nexport function extraSearchDirs(platform = process.platform, home = os.homedir()) {\n const dirs = [onboarderBinDir(home)];\n if (platform === 'darwin') dirs.push('/opt/homebrew/bin', '/usr/local/bin');\n if (platform === 'linux') dirs.push('/usr/local/bin', path.join(home, '.local', 'bin'));\n if (platform === 'win32') {\n const local = process.env.LOCALAPPDATA;\n if (local) dirs.push(path.join(local, 'Programs', 'Gitleaks'));\n }\n return dirs;\n}\n\n// Split a PATH string the way the platform does. Exported for tests.\nexport function splitPath(pathValue, platform = process.platform) {\n return String(pathValue || '')\n .split(platform === 'win32' ? ';' : ':')\n .map((d) => d.trim())\n .filter(Boolean);\n}\n\n// Find `cmd` on PATH (plus the extra dirs). Returns the absolute path, or\n// null. Pure apart from the `exists` probe, which defaults to the disk and is\n// injectable so the tests never touch a real filesystem layout.\nexport function findOnPath(cmd, options: Record<string, any> = {}) {\n const platform = options.platform || process.platform;\n const envPath = options.envPath !== undefined ? options.envPath : process.env.PATH;\n const pathext = options.pathext !== undefined ? options.pathext : process.env.PATHEXT;\n const exists = options.exists || ((p) => fs.existsSync(p));\n const home = options.home || os.homedir();\n\n const dirs = [...splitPath(envPath, platform), ...extraSearchDirs(platform, home)];\n for (const dir of dirs) {\n for (const name of candidateNames(cmd, platform, pathext)) {\n const full = path.join(dir, name);\n try {\n if (exists(full)) return full;\n } catch {\n /* an unreadable dir is just not where the tool lives */\n }\n }\n }\n return null;\n}\n\n// A `.cmd`/`.bat` shim cannot be spawned directly on Windows (Node refuses\n// with EINVAL): it needs cmd.exe. `spawnArgv` rewrites the argv for that case\n// and leaves everything else untouched, so callers keep passing plain arrays.\nexport function spawnArgv(argv, platform = process.platform) {\n if (platform !== 'win32') return { command: argv[0], args: argv.slice(1) };\n if (!/\\.(cmd|bat)$/i.test(argv[0] || '')) return { command: argv[0], args: argv.slice(1) };\n const quoted = argv.map((a) => `\"${String(a).replace(/\"/g, '\\\\\"')}\"`).join(' ');\n return { command: 'cmd.exe', args: ['/d', '/s', '/c', quoted] };\n}\n"]}
@@ -0,0 +1,137 @@
1
+ export declare const TOOL_DEFS: ({
2
+ id: string;
3
+ label: string;
4
+ kind: string;
5
+ purpose: string;
6
+ commands: ({
7
+ kind: string;
8
+ bin: string;
9
+ pkg?: undefined;
10
+ } | {
11
+ kind: string;
12
+ pkg: string;
13
+ bin: string;
14
+ })[];
15
+ install: string[];
16
+ options: {
17
+ key: string;
18
+ label: string;
19
+ type: string;
20
+ values: string[];
21
+ default: string;
22
+ hint: string;
23
+ }[];
24
+ argv: (root: any, options?: Record<string, any>) => any[];
25
+ parse: (text: any, root: any) => any[];
26
+ usesReportFile?: undefined;
27
+ textOutput?: undefined;
28
+ cwd?: undefined;
29
+ } | {
30
+ id: string;
31
+ label: string;
32
+ kind: string;
33
+ purpose: string;
34
+ commands: {
35
+ kind: string;
36
+ bin: string;
37
+ }[];
38
+ install: string[];
39
+ options: {
40
+ key: string;
41
+ label: string;
42
+ type: string;
43
+ default: boolean;
44
+ hint: string;
45
+ }[];
46
+ usesReportFile: boolean;
47
+ argv: (root: any, options?: Record<string, any>, ctx?: Record<string, any>) => any[];
48
+ parse: (text: any, root: any) => any[];
49
+ textOutput?: undefined;
50
+ cwd?: undefined;
51
+ } | {
52
+ usesReportFile?: undefined;
53
+ id: string;
54
+ label: string;
55
+ kind: string;
56
+ purpose: string;
57
+ commands: ({
58
+ pkg?: undefined;
59
+ kind: string;
60
+ bin: string;
61
+ } | {
62
+ bin?: undefined;
63
+ kind: string;
64
+ pkg: string;
65
+ })[];
66
+ install: string[];
67
+ options: {
68
+ key: string;
69
+ label: string;
70
+ type: string;
71
+ values: string[];
72
+ default: any[];
73
+ hint: string;
74
+ }[];
75
+ argv: (root: any, options?: Record<string, any>) => any[];
76
+ parse: (text: any, root: any) => any[];
77
+ textOutput?: undefined;
78
+ cwd?: undefined;
79
+ } | {
80
+ usesReportFile?: undefined;
81
+ id: string;
82
+ label: string;
83
+ kind: string;
84
+ purpose: string;
85
+ commands: ({
86
+ pkg?: undefined;
87
+ kind: string;
88
+ bin: string;
89
+ } | {
90
+ kind: string;
91
+ pkg: string;
92
+ bin: string;
93
+ })[];
94
+ install: string[];
95
+ options: {
96
+ key: string;
97
+ label: string;
98
+ type: string;
99
+ min: number;
100
+ max: number;
101
+ default: number;
102
+ hint: string;
103
+ }[];
104
+ argv: (root: any, options?: Record<string, any>) => any[];
105
+ parse: (text: any, root: any) => any[];
106
+ textOutput: boolean;
107
+ cwd?: undefined;
108
+ } | {
109
+ usesReportFile?: undefined;
110
+ textOutput?: undefined;
111
+ id: string;
112
+ label: string;
113
+ kind: string;
114
+ purpose: string;
115
+ commands: ({
116
+ pkg?: undefined;
117
+ kind: string;
118
+ bin: string;
119
+ } | {
120
+ bin?: undefined;
121
+ kind: string;
122
+ pkg: string;
123
+ })[];
124
+ install: string[];
125
+ options: {
126
+ key: string;
127
+ label: string;
128
+ type: string;
129
+ default: boolean;
130
+ hint: string;
131
+ }[];
132
+ argv: (root: any, options?: Record<string, any>) => string[];
133
+ cwd: boolean;
134
+ parse: (text: any) => any[];
135
+ })[];
136
+ export declare function sanitizeOptions(def: any, raw: any): Record<string, any>;
137
+ export declare function defaultOptions(def: any): Record<string, any>;