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
@@ -9,297 +9,363 @@
9
9
  // `run(ctx, args)` returns a string to print, or a marker the app layer acts on
10
10
  // (`EXIT`, `CLEAR`). `args` is an array of already-parsed words, so quoting is
11
11
  // handled once, in the tokenizer, and every command sees the same shape.
12
-
13
12
  import * as V from './views.js';
14
13
  import * as A from './advanced.js';
15
- import { lineNumber } from './session.js';
14
+ import { lineNumber, resolveTarget, fileFacts } from './session.js';
16
15
  import { bold, cyan, dim, ok, fit, termWidth } from '../ui.js';
17
16
  import { wrapText } from './wrap.js';
17
+ import { formatSbom, formatWorkflows, formatAtlas, formatInspector } from './featureViews.js';
18
18
  import { execFile } from 'node:child_process';
19
19
  import { promisify } from 'node:util';
20
-
21
20
  const run = promisify(execFile);
22
-
23
21
  export const EXIT = Symbol('exit');
24
22
  export const CLEAR = Symbol('clear');
25
-
26
23
  export const COMMANDS = [
27
- {
28
- name: 'help', aliases: ['?'], group: 'basics',
29
- usage: 'help [command]', summary: 'This list, or everything about one command.',
30
- // The topic is forwarded. `help find` used to ignore its argument and print
31
- // the whole list, which reads as the command not working.
32
- run: (ctx, args) => ctx.help(args.join(' ')),
33
- },
34
- {
35
- name: 'map', aliases: ['overview', 'home'], group: 'basics',
36
- usage: 'map', summary: 'What this repo is, and where to start.',
37
- run: (ctx) => V.overview(ctx.repo),
38
- },
39
- {
40
- name: 'tour', aliases: ['start', 'onboarding'], group: 'basics',
41
- usage: 'tour', summary: 'The reading order a new teammate should follow.',
42
- run: (ctx) => V.tour(ctx.repo),
43
- },
44
- {
45
- name: 'explain', aliases: ['why', 'what'], group: 'basics',
46
- usage: 'explain [file|folder]', summary: 'This repo, or one file/folder, in prose. No AI key needed.',
47
- run: (ctx, args) => V.explain(ctx.repo, { target: args.join(' ') }),
48
- },
49
- {
50
- name: 'tree', aliases: ['ls', 'files'], group: 'navigate',
51
- usage: 'tree [folder] [depth]', summary: 'The file tree, with entries and hubs marked.',
52
- run: (ctx, args) => {
53
- // A lone number is the depth, not a folder called "2". `tree 3` is what
54
- // everyone types when they want to see more; making them spell
55
- // `tree . 3` would be pedantry in a tool built to be forgiving. `.` is the
56
- // root, so it must not be taken as a folder name either.
57
- const onlyDepth = args.length === 1 && /^\d+$/.test(args[0]);
58
- const sub = onlyDepth ? '' : (args[0] || '');
59
- return V.tree(ctx.repo, {
60
- sub: sub === '.' ? '' : sub,
61
- depth: onlyDepth ? Number(args[0]) : (Number(args[1]) || 2),
62
- });
63
- },
64
- },
65
- {
66
- name: 'find', aliases: ['search', 'grep'], group: 'navigate',
67
- usage: 'find <query>', summary: 'Search. Supports ext:js, -exclude, "phrases", /regex/.',
68
- run: (ctx, args) => V.find(ctx.repo, { query: args.join(' ') }),
69
- },
70
- {
71
- name: 'show', aliases: ['open', 'cat', 'read'], group: 'navigate',
72
- usage: 'show <file> [from] [count]', summary: 'Read a file. Name it loosely: `show logger.js` works.',
73
- run: (ctx, args) => V.show(ctx.repo, {
74
- target: args[0] || '',
75
- from: lineNumber(args[1], 0),
76
- count: lineNumber(args[2], 0),
77
- }),
78
- },
79
- {
80
- name: 'deps', aliases: ['connections'], group: 'navigate',
81
- usage: 'deps <file>', summary: 'What a file imports, and what imports it.',
82
- run: (ctx, args) => V.deps(ctx.repo, { target: args.join(' ') }),
83
- },
84
- {
85
- name: 'health', aliases: ['grade'], group: 'analyze',
86
- usage: 'health', summary: 'Health grade, riskiest files, debt.',
87
- run: (ctx) => V.health(ctx.repo),
88
- },
89
- {
90
- name: 'hubs', aliases: ['core'], group: 'analyze',
91
- usage: 'hubs', summary: 'The most depended-on files.',
92
- run: (ctx) => V.hubs(ctx.repo),
93
- },
94
- {
95
- name: 'layers', aliases: ['depth'], group: 'analyze',
96
- usage: 'layers', summary: 'Import depth, shallowest first.',
97
- run: (ctx) => V.layers(ctx.repo),
98
- },
99
- {
100
- name: 'patterns', aliases: ['architecture'], group: 'analyze',
101
- usage: 'patterns', summary: 'What the architecture looks like, in prose.',
102
- run: (ctx) => V.patterns(ctx.repo),
103
- },
104
- {
105
- name: 'stats', aliases: ['numbers'], group: 'analyze',
106
- usage: 'stats', summary: 'Languages, biggest folders and files, complexity.',
107
- run: (ctx) => V.stats(ctx.repo),
108
- },
109
- {
110
- name: 'security', aliases: ['audit'], group: 'analyze',
111
- usage: 'security', summary: 'Heuristic findings from the built-in rules.',
112
- run: (ctx) => V.security(ctx.repo),
113
- },
114
- {
115
- name: 'stack', aliases: ['packages'], group: 'analyze',
116
- usage: 'stack', summary: 'Declared dependencies and frameworks.',
117
- run: (ctx) => V.stack(ctx.repo),
118
- },
119
- {
120
- name: 'entry', aliases: ['entries'], group: 'analyze',
121
- usage: 'entry', summary: 'Recognized entry points and how far they reach.',
122
- run: (ctx) => V.entry(ctx.repo),
123
- },
124
- {
125
- name: 'externals', aliases: ['drift'], group: 'analyze',
126
- usage: 'externals', summary: 'External packages, plus dependency drift.',
127
- run: (ctx) => V.externals(ctx.repo),
128
- },
129
- {
130
- name: 'graph', aliases: ['tree-graph'], group: 'navigate',
131
- usage: 'graph <file> [depth]', summary: 'The dependency tree around a file, as arrows.',
132
- run: (ctx, args) => A.graph(ctx.repo, { target: args[0] || '', depth: Number(args[1]) || 2 }),
133
- },
134
- {
135
- name: 'blast', aliases: ['impact', 'radius'], group: 'navigate',
136
- usage: 'blast <file>', summary: 'What breaks if this file breaks, transitively.',
137
- run: (ctx, args) => A.blast(ctx.repo, { target: args.join(' ') }),
138
- },
139
- {
140
- name: 'symbols', aliases: ['outline', 'functions'], group: 'navigate',
141
- usage: 'symbols <file>', summary: 'Functions, classes and exports in a file.',
142
- run: (ctx, args) => A.symbols(ctx.repo, { target: args.join(' ') }),
143
- },
144
- {
145
- name: 'docs', aliases: ['document'], group: 'analyze',
146
- usage: 'docs [file|folder] | docs --write', summary: 'Prose docs for a file, or write ONBOARDER.md.',
147
- run: async (ctx, args) => {
148
- // `--write` is the one command here that touches the filesystem. It is
149
- // opt-in, explicit, and prints where it wrote — a map tool should never
150
- // leave a file behind just because someone asked what the docs say.
151
- if (args[0] === '--write') {
152
- const abs = await A.writeDocs(ctx.repo, args[1] || 'ONBOARDER.md');
153
- return ' ' + ok('Wrote ') + cyan(abs);
154
- }
155
- return A.docs(ctx.repo, { target: args.filter((a) => a !== '--write').join(' ') });
156
- },
157
- },
158
- {
159
- name: 'log', aliases: ['history', 'commits'], group: 'git',
160
- usage: 'log [count]', summary: 'Recent commits, and who wrote them.',
161
- run: (ctx, args) => A.log(ctx.repo, { limit: Number(args[0]) || 15 }),
162
- },
163
- {
164
- name: 'hotspots', aliases: ['churn'], group: 'git',
165
- usage: 'hotspots [count]', summary: 'Files that are both complex and frequently changed.',
166
- run: (ctx, args) => A.hotspots(ctx.repo, { limit: Number(args[0]) || 12 }),
167
- },
168
- {
169
- name: 'blame', aliases: ['authors'], group: 'git',
170
- usage: 'blame <file>', summary: 'Who wrote each line of a file.',
171
- run: (ctx, args) => A.blame(ctx.repo, { target: args.join(' ') }),
172
- },
173
- {
174
- name: 'coupling', aliases: ['matrix', 'heatmap'], group: 'analyze',
175
- usage: 'coupling', summary: 'Folder-to-folder import traffic, as a heat grid.',
176
- run: (ctx) => A.coupling(ctx.repo),
177
- },
178
- {
179
- name: 'clusters', aliases: ['communities', 'modules'], group: 'analyze',
180
- usage: 'clusters', summary: 'Groups of files that import each other more than the rest.',
181
- run: (ctx) => A.clusters(ctx.repo),
182
- },
183
- {
184
- name: 'diagram', aliases: ['mermaid'], group: 'analyze',
185
- usage: 'diagram [file]', summary: 'Mermaid source for the repo, or one file.',
186
- run: (ctx, args) => A.diagram(ctx.repo, { target: args.join(' ') }),
187
- },
188
- {
189
- name: 'layers-diagram', aliases: [], group: 'analyze',
190
- usage: 'layers-diagram', summary: 'Mermaid source for the layer stack.',
191
- run: (ctx) => A.layerDiagram(ctx.repo),
192
- },
193
- {
194
- name: 'risks', aliases: ['problems', 'smells'], group: 'analyze',
195
- usage: 'risks', summary: 'Cycles, orphans, dead exports, drift — in one list.',
196
- run: (ctx) => A.risks(ctx.repo),
197
- },
198
- {
199
- name: 'about', aliases: ['version'], group: 'session',
200
- usage: 'about', summary: 'Version, repo path, and what is indexed.',
201
- run: (ctx) => V.about(ctx.repo, ctx.version),
202
- },
203
- {
204
- name: 'rescan', aliases: ['reload'], group: 'session',
205
- usage: 'rescan', summary: 'Re-read the repo from disk.',
206
- run: (ctx) => ctx.rescan(),
207
- },
208
- {
209
- name: 'github', aliases: ['remote', 'repo'], group: 'session',
210
- usage: 'github', summary: "What GitHub says about this repo — stars, issues, license.",
211
- run: (ctx) => ctx.github(),
212
- },
213
- {
214
- name: 'cd', aliases: ['open-repo', 'use'], group: 'session',
215
- usage: 'cd <folder|url>', summary: 'Load another repository, or clone one by URL.',
216
- run: (ctx, args) => ctx.loadRepo(args.join(' ')),
217
- },
218
- {
219
- name: 'web', aliases: ['site', 'serve'], group: 'session',
220
- usage: 'web', summary: 'Start the web UI and print its URL.',
221
- run: (ctx) => ctx.web(),
222
- },
223
- {
224
- name: 'clear', aliases: ['cls'], group: 'session',
225
- usage: 'clear', summary: 'Clear the screen.',
226
- run: () => CLEAR,
227
- },
228
- {
229
- name: 'exit', aliases: ['quit', 'q'], group: 'session',
230
- usage: 'exit', summary: 'Leave. Ctrl-D does the same.',
231
- run: () => EXIT,
232
- },
24
+ {
25
+ name: 'agent', aliases: [], group: 'basics',
26
+ usage: 'agent <workflow> --task "..."', summary: 'Hermes: repository Q&A, review, triage, implementation, and GitHub tasks.',
27
+ run: (ctx, args) => ctx.agent(args),
28
+ },
29
+ {
30
+ name: 'help', aliases: ['?'], group: 'basics',
31
+ usage: 'help [command]', summary: 'This list, or everything about one command.',
32
+ // The topic is forwarded. `help find` used to ignore its argument and print
33
+ // the whole list, which reads as the command not working.
34
+ run: (ctx, args) => ctx.help(args.join(' ')),
35
+ },
36
+ {
37
+ name: 'map', aliases: ['overview', 'home'], group: 'basics',
38
+ usage: 'map', summary: 'What this repo is, and where to start.',
39
+ run: (ctx) => V.overview(ctx.repo),
40
+ },
41
+ {
42
+ name: 'tour', aliases: ['start', 'onboarding'], group: 'basics',
43
+ usage: 'tour', summary: 'The reading order a new teammate should follow.',
44
+ run: (ctx) => V.tour(ctx.repo),
45
+ },
46
+ {
47
+ name: 'explain', aliases: ['why', 'what'], group: 'basics',
48
+ usage: 'explain [file|folder]', summary: 'This repo, or one file/folder, in prose. No AI key needed.',
49
+ run: (ctx, args) => V.explain(ctx.repo, { target: args.join(' ') }),
50
+ },
51
+ {
52
+ name: 'tree', aliases: ['ls', 'files'], group: 'navigate',
53
+ usage: 'tree [folder] [depth]', summary: 'The file tree, with entries and hubs marked.',
54
+ run: (ctx, args) => {
55
+ // A lone number is the depth, not a folder called "2". `tree 3` is what
56
+ // everyone types when they want to see more; making them spell
57
+ // `tree . 3` would be pedantry in a tool built to be forgiving. `.` is the
58
+ // root, so it must not be taken as a folder name either.
59
+ const onlyDepth = args.length === 1 && /^\d+$/.test(args[0]);
60
+ const sub = onlyDepth ? '' : (args[0] || '');
61
+ return V.tree(ctx.repo, {
62
+ sub: sub === '.' ? '' : sub,
63
+ depth: onlyDepth ? Number(args[0]) : (Number(args[1]) || 2),
64
+ });
65
+ },
66
+ },
67
+ {
68
+ name: 'find', aliases: ['search', 'grep'], group: 'navigate',
69
+ usage: 'find <query>', summary: 'Search. Supports ext:js, -exclude, "phrases", /regex/.',
70
+ run: (ctx, args) => V.find(ctx.repo, { query: args.join(' ') }),
71
+ },
72
+ {
73
+ name: 'show', aliases: ['open', 'cat', 'read', 'code'], group: 'navigate',
74
+ usage: 'show <file> [from] [count]', summary: 'Read a file. Name it loosely: `show logger.js` works.',
75
+ run: (ctx, args) => V.show(ctx.repo, {
76
+ target: args[0] || '',
77
+ from: lineNumber(args[1], 0),
78
+ count: lineNumber(args[2], 0),
79
+ }),
80
+ },
81
+ {
82
+ name: 'deps', aliases: ['connections'], group: 'navigate',
83
+ usage: 'deps <file>', summary: 'What a file imports, and what imports it.',
84
+ run: (ctx, args) => V.deps(ctx.repo, { target: args.join(' ') }),
85
+ },
86
+ {
87
+ name: 'inspect', aliases: ['detail'], group: 'navigate',
88
+ usage: 'inspect <file>', summary: 'One file’s role, links, exports, and findings.',
89
+ run: (ctx, args) => {
90
+ const target = args.join(' ');
91
+ if (!target)
92
+ return ' Name a file: inspect path/to/file.js';
93
+ const found = resolveTarget(ctx.repo, target);
94
+ if (found.error)
95
+ return V.explain(ctx.repo, { target });
96
+ if (found.folder)
97
+ return V.explain(ctx.repo, { target });
98
+ const file = found.file;
99
+ return formatInspector({
100
+ path: file.path,
101
+ role: fileFacts(ctx.repo, file).role,
102
+ loc: file.loc || 0,
103
+ complexity: file.complexity || 0,
104
+ risk: ctx.repo.health.perFile.find((item) => item.path === file.path)?.risk || 0,
105
+ imports: ctx.repo.facts.importsOf[file.path] || [],
106
+ importers: ctx.repo.facts.importers[file.path] || [],
107
+ exports: file.exports || [],
108
+ findings: file.findings || [],
109
+ });
110
+ },
111
+ },
112
+ {
113
+ name: 'health', aliases: ['grade'], group: 'analyze',
114
+ usage: 'health', summary: 'Health grade, riskiest files, debt.',
115
+ run: (ctx) => V.health(ctx.repo),
116
+ },
117
+ {
118
+ name: 'hubs', aliases: ['core'], group: 'analyze',
119
+ usage: 'hubs', summary: 'The most depended-on files.',
120
+ run: (ctx) => V.hubs(ctx.repo),
121
+ },
122
+ {
123
+ name: 'layers', aliases: ['depth'], group: 'analyze',
124
+ usage: 'layers', summary: 'Import depth, shallowest first.',
125
+ run: (ctx) => V.layers(ctx.repo),
126
+ },
127
+ {
128
+ name: 'patterns', aliases: ['architecture'], group: 'analyze',
129
+ usage: 'patterns', summary: 'What the architecture looks like, in prose.',
130
+ run: (ctx) => V.patterns(ctx.repo),
131
+ },
132
+ {
133
+ name: 'stats', aliases: ['numbers'], group: 'analyze',
134
+ usage: 'stats', summary: 'Languages, biggest folders and files, complexity.',
135
+ run: (ctx) => V.stats(ctx.repo),
136
+ },
137
+ {
138
+ name: 'security', aliases: ['audit'], group: 'analyze',
139
+ usage: 'security', summary: 'Heuristic findings from the built-in rules.',
140
+ run: (ctx) => V.security(ctx.repo),
141
+ },
142
+ {
143
+ name: 'stack', aliases: ['packages', 'services'], group: 'analyze',
144
+ usage: 'stack', summary: 'Declared dependencies and frameworks.',
145
+ run: (ctx) => V.stack(ctx.repo),
146
+ },
147
+ {
148
+ name: 'entry', aliases: ['entries'], group: 'analyze',
149
+ usage: 'entry', summary: 'Recognized entry points and how far they reach.',
150
+ run: (ctx) => V.entry(ctx.repo),
151
+ },
152
+ {
153
+ name: 'externals', aliases: ['drift'], group: 'analyze',
154
+ usage: 'externals', summary: 'External packages, plus dependency drift.',
155
+ run: (ctx) => V.externals(ctx.repo),
156
+ },
157
+ {
158
+ name: 'graph', aliases: ['tree-graph'], group: 'navigate',
159
+ usage: 'graph <file> [depth]', summary: 'The dependency tree around a file, as arrows.',
160
+ run: (ctx, args) => A.graph(ctx.repo, { target: args[0] || '', depth: Number(args[1]) || 2 }),
161
+ },
162
+ {
163
+ name: 'blast', aliases: ['impact', 'radius'], group: 'navigate',
164
+ usage: 'blast <file>', summary: 'What breaks if this file breaks, transitively.',
165
+ run: (ctx, args) => A.blast(ctx.repo, { target: args.join(' ') }),
166
+ },
167
+ {
168
+ name: 'symbols', aliases: ['outline', 'functions'], group: 'navigate',
169
+ usage: 'symbols <file>', summary: 'Functions, classes and exports in a file.',
170
+ run: (ctx, args) => A.symbols(ctx.repo, { target: args.join(' ') }),
171
+ },
172
+ {
173
+ name: 'docs', aliases: ['document'], group: 'analyze',
174
+ usage: 'docs [file|folder] | docs --write', summary: 'Prose docs for a file, or write ONBOARDER.md.',
175
+ run: async (ctx, args) => {
176
+ // `--write` is the one command here that touches the filesystem. It is
177
+ // opt-in, explicit, and prints where it wrote — a map tool should never
178
+ // leave a file behind just because someone asked what the docs say.
179
+ if (args[0] === '--write') {
180
+ const abs = await A.writeDocs(ctx.repo, args[1] || 'ONBOARDER.md');
181
+ return ' ' + ok('Wrote ') + cyan(abs);
182
+ }
183
+ return A.docs(ctx.repo, { target: args.filter((a) => a !== '--write').join(' ') });
184
+ },
185
+ },
186
+ {
187
+ name: 'log', aliases: ['history', 'commits'], group: 'git',
188
+ usage: 'log [count]', summary: 'Recent commits, and who wrote them.',
189
+ run: (ctx, args) => A.log(ctx.repo, { limit: Number(args[0]) || 15 }),
190
+ },
191
+ {
192
+ name: 'hotspots', aliases: ['churn'], group: 'git',
193
+ usage: 'hotspots [count]', summary: 'Files that are both complex and frequently changed.',
194
+ run: (ctx, args) => A.hotspots(ctx.repo, { limit: Number(args[0]) || 12 }),
195
+ },
196
+ {
197
+ name: 'blame', aliases: ['authors'], group: 'git',
198
+ usage: 'blame <file>', summary: 'Who wrote each line of a file.',
199
+ run: (ctx, args) => A.blame(ctx.repo, { target: args.join(' ') }),
200
+ },
201
+ {
202
+ name: 'coupling', aliases: ['matrix', 'heatmap'], group: 'analyze',
203
+ usage: 'coupling', summary: 'Folder-to-folder import traffic, as a heat grid.',
204
+ run: (ctx) => A.coupling(ctx.repo),
205
+ },
206
+ {
207
+ name: 'clusters', aliases: ['communities', 'modules'], group: 'analyze',
208
+ usage: 'clusters', summary: 'Groups of files that import each other more than the rest.',
209
+ run: (ctx) => A.clusters(ctx.repo),
210
+ },
211
+ {
212
+ name: 'diagram', aliases: ['mermaid'], group: 'analyze',
213
+ usage: 'diagram [file]', summary: 'Mermaid source for the repo, or one file.',
214
+ run: (ctx, args) => A.diagram(ctx.repo, { target: args.join(' ') }),
215
+ },
216
+ {
217
+ name: 'layers-diagram', aliases: [], group: 'analyze',
218
+ usage: 'layers-diagram', summary: 'Mermaid source for the layer stack.',
219
+ run: (ctx) => A.layerDiagram(ctx.repo),
220
+ },
221
+ {
222
+ name: 'risks', aliases: ['problems', 'smells', 'insights'], group: 'analyze',
223
+ usage: 'risks', summary: 'Cycles, orphans, dead exports, drift — in one list.',
224
+ run: (ctx) => A.risks(ctx.repo),
225
+ },
226
+ {
227
+ name: 'workflows', aliases: ['ci', 'pipelines'], group: 'analyze',
228
+ usage: 'workflows', summary: 'GitHub Actions triggers, jobs, and steps.',
229
+ run: (ctx) => formatWorkflows(ctx.repo.scan.workflows || []),
230
+ },
231
+ {
232
+ name: 'atlas', aliases: ['diagrams'], group: 'analyze',
233
+ usage: 'atlas', summary: 'An index of useful repository and file diagrams.',
234
+ run: (ctx) => formatAtlas(ctx.repo.facts.entries, ctx.repo.facts.hubs, ctx.repo.scan.folders),
235
+ },
236
+ {
237
+ name: 'sbom', aliases: ['licenses', 'inventory'], group: 'analyze',
238
+ usage: 'sbom [filter]', summary: 'Declared dependencies and inferred license inventory.',
239
+ run: (ctx, args) => formatSbom(ctx.repo.scan.licenseReport, args.join(' ')),
240
+ },
241
+ {
242
+ name: 'diff', aliases: ['changes'], group: 'git',
243
+ usage: 'diff [base] [head] [file]', summary: 'Git changes, patch, and dependent-file impact.',
244
+ run: (ctx, args) => ctx.diff(args[0] || 'HEAD', args[1] || '', args[2] || ''),
245
+ },
246
+ {
247
+ name: 'engines', aliases: ['analyzers'], group: 'analyze',
248
+ usage: 'engines', summary: 'Show available external analyzers and how to install them.',
249
+ run: (ctx) => ctx.engines(),
250
+ },
251
+ {
252
+ name: 'deep', aliases: ['deep-analysis'], group: 'analyze',
253
+ usage: 'deep <engine|all>', summary: 'Run an optional analyzer and show its findings.',
254
+ run: (ctx, args) => args[0] ? ctx.deep(args[0]) : ctx.engines(),
255
+ },
256
+ {
257
+ name: 'ask', aliases: ['ai'], group: 'basics',
258
+ usage: 'ask <question>', summary: 'Ask an optional OpenAI-compatible model about this repo.',
259
+ run: (ctx, args) => ctx.ask(args.join(' ')),
260
+ },
261
+ {
262
+ name: 'about', aliases: ['version'], group: 'session',
263
+ usage: 'about', summary: 'Version, repo path, and what is indexed.',
264
+ run: (ctx) => V.about(ctx.repo, ctx.version),
265
+ },
266
+ {
267
+ name: 'rescan', aliases: ['reload'], group: 'session',
268
+ usage: 'rescan', summary: 'Re-read the repo from disk.',
269
+ run: (ctx) => ctx.rescan(),
270
+ },
271
+ {
272
+ name: 'github', aliases: ['remote', 'repo'], group: 'session',
273
+ usage: 'github', summary: "What GitHub says about this repo — stars, issues, license.",
274
+ run: (ctx) => ctx.github(),
275
+ },
276
+ {
277
+ name: 'cd', aliases: ['open-repo', 'use'], group: 'session',
278
+ usage: 'cd [folder|url]', summary: 'Choose a folder, or load one by path or Git URL.',
279
+ run: (ctx, args) => args.length ? ctx.loadRepo(args.join(' ')) : ctx.selectSource(),
280
+ },
281
+ {
282
+ name: 'pick', aliases: ['browse'], group: 'session',
283
+ usage: 'pick', summary: 'Browse device folders or paste a Git URL.',
284
+ run: (ctx) => ctx.selectSource(),
285
+ },
286
+ {
287
+ name: 'web', aliases: ['site', 'serve'], group: 'session',
288
+ usage: 'web', summary: 'Start the web UI and print its URL.',
289
+ run: (ctx) => ctx.web(),
290
+ },
291
+ {
292
+ name: 'clear', aliases: ['cls'], group: 'session',
293
+ usage: 'clear', summary: 'Clear the screen.',
294
+ run: () => CLEAR,
295
+ },
296
+ {
297
+ name: 'exit', aliases: ['quit', 'q'], group: 'session',
298
+ usage: 'exit', summary: 'Leave. Ctrl-D does the same.',
299
+ run: () => EXIT,
300
+ },
233
301
  ];
234
-
235
302
  // One lookup for every spelling a person might type, built once at import.
236
303
  const BY_NAME = new Map();
237
304
  for (const cmd of COMMANDS) {
238
- BY_NAME.set(cmd.name, cmd);
239
- for (const a of cmd.aliases) BY_NAME.set(a, cmd);
305
+ BY_NAME.set(cmd.name, cmd);
306
+ for (const a of cmd.aliases)
307
+ BY_NAME.set(a, cmd);
240
308
  }
241
-
242
309
  export function lookup(word) {
243
- return BY_NAME.get(String(word || '').toLowerCase());
310
+ return BY_NAME.get(String(word || '').toLowerCase());
244
311
  }
245
-
246
312
  // Every canonical name, for "did you mean" matching. Aliases are deliberately
247
313
  // excluded: suggesting `open` when someone typed `sho` is less useful than
248
314
  // suggesting `show`, which is the word they were reaching for.
249
315
  export function commandNames() {
250
- return COMMANDS.map((c) => c.name);
316
+ return COMMANDS.map((c) => c.name);
251
317
  }
252
-
253
318
  // `help <command>` answers about one command; bare `help` lists them, grouped so
254
319
  // the shape of the tool is visible rather than alphabetical. Every row is
255
320
  // fitted, because a long summary on a narrow terminal used to wrap into the
256
321
  // next row and make the list unreadable.
257
322
  export function helpText(ctx, topic = '') {
258
- const w = termWidth();
259
- if (topic) {
260
- const cmd = lookup(topic);
261
- if (!cmd) return fit(` No command called "${topic}". Try \`help\`.`, Math.max(10, w - 2));
262
- const also = cmd.aliases.length ? ` (also: ${cmd.aliases.join(', ')})` : '';
263
- return [
264
- fit(' ' + cmd.usage + also, Math.max(10, w - 2)),
265
- wrapText(cmd.summary, ' '),
266
- ].join('\n');
267
- }
268
- const groups = new Map();
269
- for (const cmd of COMMANDS) {
270
- if (!groups.has(cmd.group)) groups.set(cmd.group, []);
271
- groups.get(cmd.group).push(cmd);
272
- }
273
- // Two cells of indent, two of gap, and the summary gets whatever is left. The
274
- // usage column shrinks with the terminal rather than pushing the text off it.
275
- const longest = Math.max(...COMMANDS.map((c) => c.usage.length));
276
- const usageRoom = Math.max(8, Math.min(longest, Math.floor(w * 0.4)));
277
- const out = [];
278
- for (const [group, list] of groups) {
279
- out.push(fit(' ' + group.toUpperCase(), Math.max(10, w - 2)));
280
- for (const c of list) {
281
- const left = ' ' + fit(c.usage, usageRoom);
282
- const room = w - left.length - 2;
283
- out.push(room > 8 ? left + ' ' + fit(c.summary, room, { tail: false }) : left);
323
+ const w = termWidth();
324
+ if (topic) {
325
+ const cmd = lookup(topic);
326
+ if (!cmd)
327
+ return fit(` No command called "${topic}". Try \`help\`.`, Math.max(10, w - 2));
328
+ const also = cmd.aliases.length ? ` (also: ${cmd.aliases.join(', ')})` : '';
329
+ return [
330
+ fit(' ' + cmd.usage + also, Math.max(10, w - 2)),
331
+ wrapText(cmd.summary, ' '),
332
+ ].join('\n');
284
333
  }
285
- }
286
- out.push('');
287
- out.push(fit(' ' + (ctx?.repo ? ctx.repo.name : 'onboarder')
288
- + ' · Ctrl-D or `exit` to leave · Ctrl-C twice to quit', Math.max(10, w - 2)));
289
- return out.join('\n');
334
+ const groups = new Map();
335
+ for (const cmd of COMMANDS) {
336
+ if (!groups.has(cmd.group))
337
+ groups.set(cmd.group, []);
338
+ groups.get(cmd.group).push(cmd);
339
+ }
340
+ // Two cells of indent, two of gap, and the summary gets whatever is left. The
341
+ // usage column shrinks with the terminal rather than pushing the text off it.
342
+ const longest = Math.max(...COMMANDS.map((c) => c.usage.length));
343
+ const usageRoom = Math.max(8, Math.min(longest, Math.floor(w * 0.4)));
344
+ const out = [];
345
+ for (const [group, list] of groups) {
346
+ out.push(fit(' ' + group.toUpperCase(), Math.max(10, w - 2)));
347
+ for (const c of list) {
348
+ const left = ' ' + fit(c.usage, usageRoom);
349
+ const room = w - left.length - 2;
350
+ out.push(room > 8 ? left + ' ' + fit(c.summary, room, { tail: false }) : left);
351
+ }
352
+ }
353
+ out.push('');
354
+ out.push(fit(' ' + (ctx?.repo ? ctx.repo.name : 'onboarder')
355
+ + ' · Ctrl-D or `exit` to leave · Ctrl-C twice to quit', Math.max(10, w - 2)));
356
+ return out.join('\n');
290
357
  }
291
-
292
358
  // Split a typed line into words, honoring quotes so `find "exact phrase"` and
293
359
  // `show "my file.js"` arrive as one argument each. Done once, here, so no
294
360
  // command has to re-implement it.
295
361
  export function tokenize(line) {
296
- const out = [];
297
- const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
298
- let m;
299
- while ((m = re.exec(String(line || '')))) out.push(m[1] ?? m[2] ?? m[3]);
300
- return out;
362
+ const out = [];
363
+ const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
364
+ let m;
365
+ while ((m = re.exec(String(line || ''))))
366
+ out.push(m[1] ?? m[2] ?? m[3]);
367
+ return out;
301
368
  }
302
-
303
369
  // Tab completion, because a REPL where you retype `shared/analyzer/graph.js` one
304
370
  // letter at a time is not a REPL, it is a punishment.
305
371
  //
@@ -314,56 +380,61 @@ export function tokenize(line) {
314
380
  // one thing. It is deliberately the *only* way out to a shell, so the set of
315
381
  // things that can happen in a session stays legible.
316
382
  function completer(repo) {
317
- return function complete(line) {
318
- const trailingSpace = /\s$/.test(line);
319
- const parts = line.split(/\s+/);
320
- // Completing a command (no space yet, or trailing space after one word).
321
- if (parts.length <= 1 || (parts.length === 2 && trailingSpace)) {
322
- const hits = [...BY_NAME.keys()].filter((n) => n.startsWith(parts[0] || '')).sort();
323
- return [hits.length ? hits : parts, parts[0] || ''];
324
- }
325
- // Completing a path argument against the loaded repo. Matches at any depth,
326
- // not just from the root: `show rend` should find `src/render.js`, which is
327
- // the case the resolver's forgiving path lookup already handles — the
328
- // completer has to agree with it or Tab contradicts what the command does.
329
- const frag = parts[parts.length - 1] || '';
330
- const slash = frag.lastIndexOf('/');
331
- const dir = slash === -1 ? '' : frag.slice(0, slash + 1);
332
- const base = slash === -1 ? frag : frag.slice(slash + 1);
333
- const seen = new Set();
334
- const hits = [];
335
- for (const f of repo.scan.allFiles || repo.scan.files) {
336
- if (dir && !f.startsWith(dir)) continue;
337
- // With no directory typed, match the *last* segment so `rend` finds
338
- // `src/render.js`; with one typed, match the segment being completed.
339
- const name = dir ? f.slice(dir.length) : f.slice(f.lastIndexOf('/') + 1);
340
- if (!name.startsWith(base)) continue;
341
- if (seen.has(name)) continue;
342
- seen.add(name);
343
- hits.push(name);
344
- if (hits.length >= 200) break;
345
- }
346
- return [hits.length ? hits : [frag], frag];
347
- };
383
+ return function complete(line) {
384
+ const trailingSpace = /\s$/.test(line);
385
+ const parts = line.split(/\s+/);
386
+ // Completing a command (no space yet, or trailing space after one word).
387
+ if (parts.length <= 1 || (parts.length === 2 && trailingSpace)) {
388
+ const hits = [...BY_NAME.keys()].filter((n) => n.startsWith(parts[0] || '')).sort();
389
+ return [hits.length ? hits : parts, parts[0] || ''];
390
+ }
391
+ // Completing a path argument against the loaded repo. Matches at any depth,
392
+ // not just from the root: `show rend` should find `src/render.js`, which is
393
+ // the case the resolver's forgiving path lookup already handles — the
394
+ // completer has to agree with it or Tab contradicts what the command does.
395
+ const frag = parts[parts.length - 1] || '';
396
+ const slash = frag.lastIndexOf('/');
397
+ const dir = slash === -1 ? '' : frag.slice(0, slash + 1);
398
+ const base = slash === -1 ? frag : frag.slice(slash + 1);
399
+ const seen = new Set();
400
+ const hits = [];
401
+ for (const f of repo.scan.allFiles || repo.scan.files) {
402
+ if (dir && !f.startsWith(dir))
403
+ continue;
404
+ // With no directory typed, match the *last* segment so `rend` finds
405
+ // `src/render.js`; with one typed, match the segment being completed.
406
+ const name = dir ? f.slice(dir.length) : f.slice(f.lastIndexOf('/') + 1);
407
+ if (!name.startsWith(base))
408
+ continue;
409
+ if (seen.has(name))
410
+ continue;
411
+ seen.add(name);
412
+ hits.push(name);
413
+ if (hits.length >= 200)
414
+ break;
415
+ }
416
+ return [hits.length ? hits : [frag], frag];
417
+ };
348
418
  }
349
-
350
419
  // Run a shell command and capture its output. A non-zero exit is not a crash —
351
420
  // `grep` that finds nothing is a normal answer — so the code is reported, not
352
421
  // thrown. There is no `shell: true`: the whole line is the argument vector, so
353
422
  // nothing in a filename can be interpreted as a second command.
354
423
  async function shellEscape(line, cwd) {
355
- const parts = tokenize(line);
356
- if (!parts.length) return null;
357
- try {
358
- const { stdout, stderr } = await run(parts[0], parts.slice(1), { cwd, maxBuffer: 8 * 1024 * 1024 });
359
- const out = String(stdout || '').trimEnd();
360
- const err = String(stderr || '').trimEnd();
361
- return [out, err].filter(Boolean).join('\n') || dim(' (no output)');
362
- } catch (e) {
363
- const code = e.code ?? e.status;
364
- const err = String(e.stderr || '').trimEnd() || String(e.message || '').trimEnd();
365
- return dim(' exit ' + (code ?? '?') + (err ? '\n ' + err : ''));
366
- }
424
+ const parts = tokenize(line);
425
+ if (!parts.length)
426
+ return null;
427
+ try {
428
+ const { stdout, stderr } = await run(parts[0], parts.slice(1), { cwd, maxBuffer: 8 * 1024 * 1024 });
429
+ const out = String(stdout || '').trimEnd();
430
+ const err = String(stderr || '').trimEnd();
431
+ return [out, err].filter(Boolean).join('\n') || dim(' (no output)');
432
+ }
433
+ catch (e) {
434
+ const code = e.code ?? e.status;
435
+ const err = String(e.stderr || '').trimEnd() || String(e.message || '').trimEnd();
436
+ return dim(' exit ' + (code ?? '?') + (err ? '\n ' + err : ''));
437
+ }
367
438
  }
368
-
369
439
  export { completer, shellEscape };
440
+ //# sourceMappingURL=commands.js.map