codebase-onboarder 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/README.md +284 -53
  2. package/bin/build-if-source.js +23 -0
  3. package/bin/onboarder.js +0 -0
  4. package/cli/agent/command.d.ts +71 -0
  5. package/cli/agent/command.js +177 -0
  6. package/cli/agent/command.js.map +1 -0
  7. package/cli/agent/config.d.ts +31 -0
  8. package/cli/agent/config.js +98 -0
  9. package/cli/agent/config.js.map +1 -0
  10. package/cli/agent/contracts.d.ts +77 -0
  11. package/cli/agent/contracts.js +2 -0
  12. package/cli/agent/contracts.js.map +1 -0
  13. package/cli/agent/files.d.ts +19 -0
  14. package/cli/agent/files.js +109 -0
  15. package/cli/agent/files.js.map +1 -0
  16. package/cli/agent/gitSource.d.ts +18 -0
  17. package/cli/agent/gitSource.js +69 -0
  18. package/cli/agent/gitSource.js.map +1 -0
  19. package/cli/agent/github.d.ts +21 -0
  20. package/cli/agent/github.js +94 -0
  21. package/cli/agent/github.js.map +1 -0
  22. package/cli/agent/mcp.d.ts +15 -0
  23. package/cli/agent/mcp.js +78 -0
  24. package/cli/agent/mcp.js.map +1 -0
  25. package/cli/agent/process.d.ts +18 -0
  26. package/cli/agent/process.js +118 -0
  27. package/cli/agent/process.js.map +1 -0
  28. package/cli/agent/protocol.d.ts +3 -0
  29. package/cli/agent/protocol.js +26 -0
  30. package/cli/agent/protocol.js.map +1 -0
  31. package/cli/agent/runner.d.ts +34 -0
  32. package/cli/agent/runner.js +152 -0
  33. package/cli/agent/runner.js.map +1 -0
  34. package/cli/agent/stdio.d.ts +1 -0
  35. package/cli/agent/stdio.js +62 -0
  36. package/cli/agent/stdio.js.map +1 -0
  37. package/cli/agent/tools.d.ts +7 -0
  38. package/cli/agent/tools.js +201 -0
  39. package/cli/agent/tools.js.map +1 -0
  40. package/cli/chat/app.d.ts +16 -0
  41. package/cli/chat/app.js +345 -0
  42. package/cli/chat/app.js.map +1 -0
  43. package/cli/chat/commands.d.ts +11 -0
  44. package/cli/chat/commands.js +120 -0
  45. package/cli/chat/commands.js.map +1 -0
  46. package/cli/chat/composer.d.ts +75 -0
  47. package/cli/chat/composer.js +467 -0
  48. package/cli/chat/composer.js.map +1 -0
  49. package/cli/chat/controller.d.ts +60 -0
  50. package/cli/chat/controller.js +393 -0
  51. package/cli/chat/controller.js.map +1 -0
  52. package/cli/chat/logo.d.ts +3 -0
  53. package/cli/chat/logo.js +14 -0
  54. package/cli/chat/logo.js.map +1 -0
  55. package/cli/chat/models.d.ts +18 -0
  56. package/cli/chat/models.js +88 -0
  57. package/cli/chat/models.js.map +1 -0
  58. package/cli/chat/profile.d.ts +5 -0
  59. package/cli/chat/profile.js +98 -0
  60. package/cli/chat/profile.js.map +1 -0
  61. package/cli/chat/render.d.ts +40 -0
  62. package/cli/chat/render.js +259 -0
  63. package/cli/chat/render.js.map +1 -0
  64. package/cli/chat/screen.d.ts +26 -0
  65. package/cli/chat/screen.js +117 -0
  66. package/cli/chat/screen.js.map +1 -0
  67. package/cli/chat/source.d.ts +29 -0
  68. package/cli/chat/source.js +116 -0
  69. package/cli/chat/source.js.map +1 -0
  70. package/cli/chat/store.d.ts +43 -0
  71. package/cli/chat/store.js +94 -0
  72. package/cli/chat/store.js.map +1 -0
  73. package/cli/chat/text.d.ts +4 -0
  74. package/cli/chat/text.js +27 -0
  75. package/cli/chat/text.js.map +1 -0
  76. package/cli/commands.d.ts +26 -0
  77. package/cli/commands.js +836 -811
  78. package/cli/commands.js.map +1 -0
  79. package/cli/explorer/advanced.d.ts +14 -0
  80. package/cli/explorer/advanced.js +321 -329
  81. package/cli/explorer/advanced.js.map +1 -0
  82. package/cli/explorer/app.d.ts +2 -0
  83. package/cli/explorer/app.js +404 -314
  84. package/cli/explorer/app.js.map +1 -0
  85. package/cli/explorer/assistant.d.ts +9 -0
  86. package/cli/explorer/assistant.js +58 -0
  87. package/cli/explorer/assistant.js.map +1 -0
  88. package/cli/explorer/commands.d.ts +17 -0
  89. package/cli/explorer/commands.js +373 -302
  90. package/cli/explorer/commands.js.map +1 -0
  91. package/cli/explorer/featureViews.d.ts +124 -0
  92. package/cli/explorer/featureViews.js +179 -0
  93. package/cli/explorer/featureViews.js.map +1 -0
  94. package/cli/explorer/github.d.ts +21 -0
  95. package/cli/explorer/github.js +42 -44
  96. package/cli/explorer/github.js.map +1 -0
  97. package/cli/explorer/graphs.d.ts +7 -0
  98. package/cli/explorer/graphs.js +90 -95
  99. package/cli/explorer/graphs.js.map +1 -0
  100. package/cli/explorer/picker.d.ts +22 -0
  101. package/cli/explorer/picker.js +150 -0
  102. package/cli/explorer/picker.js.map +1 -0
  103. package/cli/explorer/report.d.ts +85 -0
  104. package/cli/explorer/report.js +60 -0
  105. package/cli/explorer/report.js.map +1 -0
  106. package/cli/explorer/session.d.ts +449 -0
  107. package/cli/explorer/session.js +143 -144
  108. package/cli/explorer/session.js.map +1 -0
  109. package/cli/explorer/views.d.ts +19 -0
  110. package/cli/explorer/views.js +465 -482
  111. package/cli/explorer/views.js.map +1 -0
  112. package/cli/explorer/wrap.d.ts +1 -0
  113. package/cli/explorer/wrap.js +28 -44
  114. package/cli/explorer/wrap.js.map +1 -0
  115. package/cli/main.d.ts +1 -0
  116. package/cli/main.js +251 -164
  117. package/cli/main.js.map +1 -0
  118. package/cli/prompt.d.ts +5 -0
  119. package/cli/prompt.js +84 -80
  120. package/cli/prompt.js.map +1 -0
  121. package/cli/scanOptions.d.ts +2 -0
  122. package/cli/scanOptions.js +11 -0
  123. package/cli/scanOptions.js.map +1 -0
  124. package/cli/ui.d.ts +33 -0
  125. package/cli/ui.js +35 -44
  126. package/cli/ui.js.map +1 -0
  127. package/cli/wizard.d.ts +187 -0
  128. package/cli/wizard.js +304 -284
  129. package/cli/wizard.js.map +1 -0
  130. package/docs/HERMES_RESEARCH.md +51 -0
  131. package/package.json +16 -4
  132. package/public/app.d.ts +1 -0
  133. package/public/app.js +1133 -1011
  134. package/public/app.js.map +1 -0
  135. package/public/assets/onboarder-mark.svg +11 -0
  136. package/public/browser.d.ts +71 -0
  137. package/public/browser.js +2 -0
  138. package/public/browser.js.map +1 -0
  139. package/public/index.html +54 -20
  140. package/public/js/about.d.ts +6 -0
  141. package/public/js/about.js +152 -172
  142. package/public/js/about.js.map +1 -0
  143. package/public/js/aiDraft.d.ts +4 -0
  144. package/public/js/aiDraft.js +166 -125
  145. package/public/js/aiDraft.js.map +1 -0
  146. package/public/js/analysisPanel.d.ts +7 -0
  147. package/public/js/analysisPanel.js +166 -166
  148. package/public/js/analysisPanel.js.map +1 -0
  149. package/public/js/analysisReport.d.ts +38 -0
  150. package/public/js/analysisReport.js +105 -110
  151. package/public/js/analysisReport.js.map +1 -0
  152. package/public/js/api.d.ts +29 -0
  153. package/public/js/api.js +198 -166
  154. package/public/js/api.js.map +1 -0
  155. package/public/js/atlas.d.ts +6 -0
  156. package/public/js/atlas.js +50 -58
  157. package/public/js/atlas.js.map +1 -0
  158. package/public/js/blameView.d.ts +2 -0
  159. package/public/js/blameView.js +36 -37
  160. package/public/js/blameView.js.map +1 -0
  161. package/public/js/codeTab.d.ts +3 -0
  162. package/public/js/codeTab.js +175 -180
  163. package/public/js/codeTab.js.map +1 -0
  164. package/public/js/codeViewer.d.ts +5 -0
  165. package/public/js/codeViewer.js +162 -150
  166. package/public/js/codeViewer.js.map +1 -0
  167. package/public/js/components/FileChip.d.ts +9 -0
  168. package/public/js/components/FileChip.js +45 -49
  169. package/public/js/components/FileChip.js.map +1 -0
  170. package/public/js/components/MetricSparkline.d.ts +7 -0
  171. package/public/js/components/MetricSparkline.js +35 -44
  172. package/public/js/components/MetricSparkline.js.map +1 -0
  173. package/public/js/components/RiskBadge.d.ts +9 -0
  174. package/public/js/components/RiskBadge.js +55 -63
  175. package/public/js/components/RiskBadge.js.map +1 -0
  176. package/public/js/deepAnalysisView.d.ts +99 -0
  177. package/public/js/deepAnalysisView.js +282 -302
  178. package/public/js/deepAnalysisView.js.map +1 -0
  179. package/public/js/diagramPane.d.ts +9 -0
  180. package/public/js/diagramPane.js +138 -135
  181. package/public/js/diagramPane.js.map +1 -0
  182. package/public/js/diffView.d.ts +6 -0
  183. package/public/js/diffView.js +222 -209
  184. package/public/js/diffView.js.map +1 -0
  185. package/public/js/docsView.d.ts +2 -0
  186. package/public/js/docsView.js +441 -442
  187. package/public/js/docsView.js.map +1 -0
  188. package/public/js/dom.d.ts +197 -0
  189. package/public/js/dom.js +5 -0
  190. package/public/js/dom.js.map +1 -0
  191. package/public/js/fileSourceBrowser.d.ts +5 -0
  192. package/public/js/fileSourceBrowser.js +33 -41
  193. package/public/js/fileSourceBrowser.js.map +1 -0
  194. package/public/js/flameGraph.d.ts +5 -0
  195. package/public/js/flameGraph.js +62 -72
  196. package/public/js/flameGraph.js.map +1 -0
  197. package/public/js/forceGraph.d.ts +10 -0
  198. package/public/js/forceGraph.js +581 -556
  199. package/public/js/forceGraph.js.map +1 -0
  200. package/public/js/heatmap.d.ts +4 -0
  201. package/public/js/heatmap.js +142 -164
  202. package/public/js/heatmap.js.map +1 -0
  203. package/public/js/highlight.d.ts +2 -0
  204. package/public/js/highlight.js +116 -107
  205. package/public/js/highlight.js.map +1 -0
  206. package/public/js/html.d.ts +2 -0
  207. package/public/js/html.js +14 -44
  208. package/public/js/html.js.map +1 -0
  209. package/public/js/insightsView.d.ts +5 -0
  210. package/public/js/insightsView.js +93 -111
  211. package/public/js/insightsView.js.map +1 -0
  212. package/public/js/inspector.d.ts +37 -0
  213. package/public/js/inspector.js +416 -445
  214. package/public/js/inspector.js.map +1 -0
  215. package/public/js/llm.d.ts +115 -0
  216. package/public/js/llm.js +246 -278
  217. package/public/js/llm.js.map +1 -0
  218. package/public/js/mapView.d.ts +3 -0
  219. package/public/js/mapView.js +121 -120
  220. package/public/js/mapView.js.map +1 -0
  221. package/public/js/markdown.d.ts +3 -0
  222. package/public/js/markdown.js +84 -91
  223. package/public/js/markdown.js.map +1 -0
  224. package/public/js/mindmap.d.ts +32 -0
  225. package/public/js/mindmap.js +244 -259
  226. package/public/js/mindmap.js.map +1 -0
  227. package/public/js/mobilePanels.d.ts +5 -0
  228. package/public/js/mobilePanels.js +50 -0
  229. package/public/js/mobilePanels.js.map +1 -0
  230. package/public/js/repoFiles.d.ts +12 -0
  231. package/public/js/repoFiles.js +29 -28
  232. package/public/js/repoFiles.js.map +1 -0
  233. package/public/js/reviewView.d.ts +28 -0
  234. package/public/js/reviewView.js +256 -0
  235. package/public/js/reviewView.js.map +1 -0
  236. package/public/js/sbomView.d.ts +3 -0
  237. package/public/js/sbomView.js +59 -67
  238. package/public/js/sbomView.js.map +1 -0
  239. package/public/js/scanCache.d.ts +16 -0
  240. package/public/js/scanCache.js +67 -65
  241. package/public/js/scanCache.js.map +1 -0
  242. package/public/js/search.d.ts +7 -0
  243. package/public/js/search.js +868 -800
  244. package/public/js/search.js.map +1 -0
  245. package/public/js/searchLocal.d.ts +42 -0
  246. package/public/js/searchLocal.js +87 -0
  247. package/public/js/searchLocal.js.map +1 -0
  248. package/public/js/serverSettings.d.ts +5 -0
  249. package/public/js/serverSettings.js +153 -164
  250. package/public/js/serverSettings.js.map +1 -0
  251. package/public/js/state.d.ts +798 -0
  252. package/public/js/state.js +114 -122
  253. package/public/js/state.js.map +1 -0
  254. package/public/js/tour.d.ts +6 -0
  255. package/public/js/tour.js +5 -7
  256. package/public/js/tour.js.map +1 -0
  257. package/public/js/transitions.d.ts +2 -0
  258. package/public/js/transitions.js +9 -10
  259. package/public/js/transitions.js.map +1 -0
  260. package/public/js/tree.d.ts +12 -0
  261. package/public/js/tree.js +157 -154
  262. package/public/js/tree.js.map +1 -0
  263. package/public/js/workflowsView.d.ts +3 -0
  264. package/public/js/workflowsView.js +15 -22
  265. package/public/js/workflowsView.js.map +1 -0
  266. package/public/search.css +495 -0
  267. package/public/styles.css +188 -346
  268. package/public/workbench.css +166 -0
  269. package/server/apiAuth.d.ts +3 -0
  270. package/server/apiAuth.js +18 -20
  271. package/server/apiAuth.js.map +1 -0
  272. package/server/apiDiff.d.ts +2 -0
  273. package/server/apiDiff.js +20 -18
  274. package/server/apiDiff.js.map +1 -0
  275. package/server/apiDocs.d.ts +2 -0
  276. package/server/apiDocs.js +38 -40
  277. package/server/apiDocs.js.map +1 -0
  278. package/server/apiFile.d.ts +1 -0
  279. package/server/apiFile.js +14 -17
  280. package/server/apiFile.js.map +1 -0
  281. package/server/apiGitBlame.d.ts +2 -0
  282. package/server/apiGitBlame.js +50 -51
  283. package/server/apiGitBlame.js.map +1 -0
  284. package/server/apiMcp.d.ts +4 -0
  285. package/server/apiMcp.js +64 -66
  286. package/server/apiMcp.js.map +1 -0
  287. package/server/apiReview.d.ts +2 -0
  288. package/server/apiReview.js +45 -0
  289. package/server/apiReview.js.map +1 -0
  290. package/server/apiScan.d.ts +5 -0
  291. package/server/apiScan.js +90 -71
  292. package/server/apiScan.js.map +1 -0
  293. package/server/apiSearch.d.ts +33 -0
  294. package/server/apiSearch.js +184 -200
  295. package/server/apiSearch.js.map +1 -0
  296. package/server/apiSettings.d.ts +4 -0
  297. package/server/apiSettings.js +84 -85
  298. package/server/apiSettings.js.map +1 -0
  299. package/server/apiTools.d.ts +3 -0
  300. package/server/apiTools.js +55 -56
  301. package/server/apiTools.js.map +1 -0
  302. package/server/auth.d.ts +5 -0
  303. package/server/auth.js +54 -51
  304. package/server/auth.js.map +1 -0
  305. package/server/config.d.ts +42 -0
  306. package/server/config.js +189 -194
  307. package/server/config.js.map +1 -0
  308. package/server/daemon.d.ts +12 -0
  309. package/server/daemon.js +124 -114
  310. package/server/daemon.js.map +1 -0
  311. package/server/fileSourceNode.d.ts +2 -0
  312. package/server/fileSourceNode.js +34 -36
  313. package/server/fileSourceNode.js.map +1 -0
  314. package/server/gitClone.d.ts +9 -0
  315. package/server/gitClone.js +59 -61
  316. package/server/gitClone.js.map +1 -0
  317. package/server/gitDiff.d.ts +36 -0
  318. package/server/gitDiff.js +271 -169
  319. package/server/gitDiff.js.map +1 -0
  320. package/server/gitHistory.d.ts +12 -0
  321. package/server/gitHistory.js +80 -80
  322. package/server/gitHistory.js.map +1 -0
  323. package/server/gitRemote.d.ts +12 -0
  324. package/server/gitRemote.js +37 -38
  325. package/server/gitRemote.js.map +1 -0
  326. package/server/hermesChat.d.ts +13 -0
  327. package/server/hermesChat.js +145 -0
  328. package/server/hermesChat.js.map +1 -0
  329. package/server/htmlText.d.ts +4 -0
  330. package/server/htmlText.js +16 -23
  331. package/server/htmlText.js.map +1 -0
  332. package/server/http.d.ts +6 -0
  333. package/server/http.js +27 -34
  334. package/server/http.js.map +1 -0
  335. package/server/httpGuards.d.ts +2 -0
  336. package/server/httpGuards.js +47 -43
  337. package/server/httpGuards.js.map +1 -0
  338. package/server/https.d.ts +34 -0
  339. package/server/https.js +121 -111
  340. package/server/https.js.map +1 -0
  341. package/server/index.d.ts +40 -0
  342. package/server/index.js +139 -147
  343. package/server/index.js.map +1 -0
  344. package/server/layout.d.ts +26 -0
  345. package/server/layout.js +59 -64
  346. package/server/layout.js.map +1 -0
  347. package/server/llmProxy.d.ts +3 -0
  348. package/server/llmProxy.js +137 -135
  349. package/server/llmProxy.js.map +1 -0
  350. package/server/logger.d.ts +38 -0
  351. package/server/logger.js +198 -211
  352. package/server/logger.js.map +1 -0
  353. package/server/mcp/analysis.d.ts +29 -0
  354. package/server/mcp/analysis.js +99 -120
  355. package/server/mcp/analysis.js.map +1 -0
  356. package/server/mcp/http.d.ts +9 -0
  357. package/server/mcp/http.js +128 -137
  358. package/server/mcp/http.js.map +1 -0
  359. package/server/mcp/runner.d.ts +68 -0
  360. package/server/mcp/runner.js +208 -218
  361. package/server/mcp/runner.js.map +1 -0
  362. package/server/mcp/server.d.ts +29 -0
  363. package/server/mcp/server.js +167 -180
  364. package/server/mcp/server.js.map +1 -0
  365. package/server/mcp/standalone.d.ts +1 -0
  366. package/server/mcp/standalone.js +8 -10
  367. package/server/mcp/standalone.js.map +1 -0
  368. package/server/mcp/tools.d.ts +2020 -0
  369. package/server/mcp/tools.js +523 -574
  370. package/server/mcp/tools.js.map +1 -0
  371. package/server/paths.d.ts +3 -0
  372. package/server/paths.js +17 -15
  373. package/server/paths.js.map +1 -0
  374. package/server/pidfile.d.ts +9 -0
  375. package/server/pidfile.js +43 -45
  376. package/server/pidfile.js.map +1 -0
  377. package/server/review.d.ts +5 -0
  378. package/server/review.js +35 -0
  379. package/server/review.js.map +1 -0
  380. package/server/router.d.ts +33 -0
  381. package/server/router.js +195 -197
  382. package/server/router.js.map +1 -0
  383. package/server/scanRequest.d.ts +3 -0
  384. package/server/scanRequest.js +36 -0
  385. package/server/scanRequest.js.map +1 -0
  386. package/server/searchIndex.d.ts +17 -0
  387. package/server/searchIndex.js +83 -80
  388. package/server/searchIndex.js.map +1 -0
  389. package/server/sessions.d.ts +14 -0
  390. package/server/sessions.js +62 -70
  391. package/server/sessions.js.map +1 -0
  392. package/server/startup.d.ts +118 -0
  393. package/server/startup.js +143 -148
  394. package/server/startup.js.map +1 -0
  395. package/server/static.d.ts +6 -0
  396. package/server/static.js +28 -31
  397. package/server/static.js.map +1 -0
  398. package/server/tools/install.d.ts +4 -0
  399. package/server/tools/install.js +176 -185
  400. package/server/tools/install.js.map +1 -0
  401. package/server/tools/parse.d.ts +8 -0
  402. package/server/tools/parse.js +112 -114
  403. package/server/tools/parse.js.map +1 -0
  404. package/server/tools/platform.d.ts +9 -0
  405. package/server/tools/platform.js +49 -47
  406. package/server/tools/platform.js.map +1 -0
  407. package/server/tools/registry.d.ts +137 -0
  408. package/server/tools/registry.js +173 -172
  409. package/server/tools/registry.js.map +1 -0
  410. package/server/tools/scan.d.ts +34 -0
  411. package/server/tools/scan.js +89 -98
  412. package/server/tools/scan.js.map +1 -0
  413. package/server/tools.d.ts +34 -0
  414. package/server/tools.js +94 -107
  415. package/server/tools.js.map +1 -0
  416. package/server/tunnel.d.ts +29 -0
  417. package/server/tunnel.js +61 -66
  418. package/server/tunnel.js.map +1 -0
  419. package/shared/analyzer/docs.d.ts +16 -0
  420. package/shared/analyzer/docs.js +99 -93
  421. package/shared/analyzer/docs.js.map +1 -0
  422. package/shared/analyzer/explainLocal.d.ts +4 -0
  423. package/shared/analyzer/explainLocal.js +122 -142
  424. package/shared/analyzer/explainLocal.js.map +1 -0
  425. package/shared/analyzer/github.d.ts +37 -0
  426. package/shared/analyzer/github.js +41 -43
  427. package/shared/analyzer/github.js.map +1 -0
  428. package/shared/analyzer/graph.d.ts +41 -0
  429. package/shared/analyzer/graph.js +393 -400
  430. package/shared/analyzer/graph.js.map +1 -0
  431. package/shared/analyzer/health.d.ts +33 -0
  432. package/shared/analyzer/health.js +197 -193
  433. package/shared/analyzer/health.js.map +1 -0
  434. package/shared/analyzer/history.d.ts +29 -0
  435. package/shared/analyzer/history.js +110 -111
  436. package/shared/analyzer/history.js.map +1 -0
  437. package/shared/analyzer/jsonConfig.d.ts +2 -0
  438. package/shared/analyzer/jsonConfig.js +61 -0
  439. package/shared/analyzer/jsonConfig.js.map +1 -0
  440. package/shared/analyzer/languages/csharp.d.ts +26 -0
  441. package/shared/analyzer/languages/csharp.js +83 -88
  442. package/shared/analyzer/languages/csharp.js.map +1 -0
  443. package/shared/analyzer/languages/generic.d.ts +23 -0
  444. package/shared/analyzer/languages/generic.js +94 -105
  445. package/shared/analyzer/languages/generic.js.map +1 -0
  446. package/shared/analyzer/languages/go.d.ts +24 -0
  447. package/shared/analyzer/languages/go.js +45 -54
  448. package/shared/analyzer/languages/go.js.map +1 -0
  449. package/shared/analyzer/languages/index.d.ts +6 -0
  450. package/shared/analyzer/languages/index.js +19 -20
  451. package/shared/analyzer/languages/index.js.map +1 -0
  452. package/shared/analyzer/languages/java.d.ts +20 -0
  453. package/shared/analyzer/languages/java.js +73 -78
  454. package/shared/analyzer/languages/java.js.map +1 -0
  455. package/shared/analyzer/languages/javascript.d.ts +12 -0
  456. package/shared/analyzer/languages/javascript.js +258 -209
  457. package/shared/analyzer/languages/javascript.js.map +1 -0
  458. package/shared/analyzer/languages/python.d.ts +23 -0
  459. package/shared/analyzer/languages/python.js +92 -100
  460. package/shared/analyzer/languages/python.js.map +1 -0
  461. package/shared/analyzer/languages/rust.d.ts +17 -0
  462. package/shared/analyzer/languages/rust.js +96 -98
  463. package/shared/analyzer/languages/rust.js.map +1 -0
  464. package/shared/analyzer/languages/typescript.d.ts +11 -0
  465. package/shared/analyzer/languages/typescript.js +117 -116
  466. package/shared/analyzer/languages/typescript.js.map +1 -0
  467. package/shared/analyzer/licenses.d.ts +18 -0
  468. package/shared/analyzer/licenses.js +130 -133
  469. package/shared/analyzer/licenses.js.map +1 -0
  470. package/shared/analyzer/metrics.d.ts +20 -0
  471. package/shared/analyzer/metrics.js +112 -104
  472. package/shared/analyzer/metrics.js.map +1 -0
  473. package/shared/analyzer/pathUtil.d.ts +10 -0
  474. package/shared/analyzer/pathUtil.js +29 -35
  475. package/shared/analyzer/pathUtil.js.map +1 -0
  476. package/shared/analyzer/patterns.d.ts +11 -0
  477. package/shared/analyzer/patterns.js +231 -253
  478. package/shared/analyzer/patterns.js.map +1 -0
  479. package/shared/analyzer/scan.d.ts +62 -0
  480. package/shared/analyzer/scan.js +451 -442
  481. package/shared/analyzer/scan.js.map +1 -0
  482. package/shared/analyzer/scanControl.d.ts +11 -0
  483. package/shared/analyzer/scanControl.js +62 -0
  484. package/shared/analyzer/scanControl.js.map +1 -0
  485. package/shared/analyzer/security.d.ts +18 -0
  486. package/shared/analyzer/security.js +159 -159
  487. package/shared/analyzer/security.js.map +1 -0
  488. package/shared/analyzer/services.d.ts +5 -0
  489. package/shared/analyzer/services.js +141 -138
  490. package/shared/analyzer/services.js.map +1 -0
  491. package/shared/analyzer/stack.d.ts +6 -0
  492. package/shared/analyzer/stack.js +134 -141
  493. package/shared/analyzer/stack.js.map +1 -0
  494. package/shared/analyzer/tour.d.ts +2 -0
  495. package/shared/analyzer/tour.js +45 -53
  496. package/shared/analyzer/tour.js.map +1 -0
  497. package/shared/analyzer/util.d.ts +8 -0
  498. package/shared/analyzer/util.js +130 -76
  499. package/shared/analyzer/util.js.map +1 -0
  500. package/shared/analyzer/workflows.d.ts +8 -0
  501. package/shared/analyzer/workflows.js +139 -134
  502. package/shared/analyzer/workflows.js.map +1 -0
  503. package/shared/contracts.d.ts +250 -0
  504. package/shared/contracts.js +2 -0
  505. package/shared/contracts.js.map +1 -0
  506. package/shared/diagram/aiFacts.d.ts +35 -0
  507. package/shared/diagram/aiFacts.js +102 -105
  508. package/shared/diagram/aiFacts.js.map +1 -0
  509. package/shared/diagram/aiMermaid.d.ts +5 -0
  510. package/shared/diagram/aiMermaid.js +50 -46
  511. package/shared/diagram/aiMermaid.js.map +1 -0
  512. package/shared/diagram/atlas.d.ts +16 -0
  513. package/shared/diagram/atlas.js +51 -60
  514. package/shared/diagram/atlas.js.map +1 -0
  515. package/shared/diagram/mermaid.d.ts +43 -0
  516. package/shared/diagram/mermaid.js +348 -370
  517. package/shared/diagram/mermaid.js.map +1 -0
  518. package/shared/review/contracts.d.ts +95 -0
  519. package/shared/review/contracts.js +2 -0
  520. package/shared/review/contracts.js.map +1 -0
  521. package/shared/review/review.d.ts +10 -0
  522. package/shared/review/review.js +184 -0
  523. package/shared/review/review.js.map +1 -0
  524. package/shared/search/query.d.ts +32 -0
  525. package/shared/search/query.js +395 -388
  526. package/shared/search/query.js.map +1 -0
@@ -1,3 +1,4 @@
1
+ import { throwIfAborted } from '../../shared/analyzer/scanControl.js';
1
2
  // One repository, loaded into memory, the way the website loads it.
2
3
  //
3
4
  // This is the whole reason the terminal app can stand in for the site: it runs
@@ -9,10 +10,8 @@
9
10
  //
10
11
  // Everything below the loader is pure data plus a few lookups. The loader is
11
12
  // the only async part, and it is the only part that touches the filesystem.
12
-
13
13
  import { promises as fs } from 'node:fs';
14
14
  import path from 'node:path';
15
-
16
15
  import { nodeFileSource } from '../../server/fileSourceNode.js';
17
16
  import { buildSearchIndex } from '../../server/searchIndex.js';
18
17
  import { searchDocuments } from '../../server/apiSearch.js';
@@ -29,7 +28,6 @@ import { analyzeStack } from '../../shared/analyzer/stack.js';
29
28
  import { buildTourStops } from '../../shared/analyzer/tour.js';
30
29
  import { explainFile, explainFolder, explainOverview } from '../../shared/analyzer/explainLocal.js';
31
30
  import { languageLabel } from '../../shared/analyzer/languages/index.js';
32
-
33
31
  // Does this argument name a repository to fetch, rather than a folder on this
34
32
  // machine? The check is deliberately narrow: only the URL shapes git itself
35
33
  // accepts, so a folder that happens to be called `ssh://stuff` cannot exist on a
@@ -38,109 +36,111 @@ import { languageLabel } from '../../shared/analyzer/languages/index.js';
38
36
  // `github.com/src/server` because someone typed `cd src/server` would be a
39
37
  // genuinely bad failure. The shorthand, if it is wanted, has to be asked for.
40
38
  export function isGitUrl(target) {
41
- return /^(https?:\/\/|git@|ssh:\/\/)/.test(String(target || '').trim());
39
+ return /^(https?:\/\/|git@|ssh:\/\/)/.test(String(target || '').trim());
42
40
  }
43
-
44
41
  // Open a local folder or clone a remote one — the same three ways in the web
45
42
  // app's landing page offers, narrowed to the two that make sense for a command
46
43
  // line. A clone is left in place when the session ends; `closeRemote` removes it,
47
44
  // and the session calls that on `cd` and on exit, so nothing is orphaned in the
48
45
  // temp dir.
49
- export async function openRepoOrClone(target, { onProgress } = {}) {
50
- const raw = String(target || '').trim();
51
- if (!isGitUrl(raw)) return openRepo(raw, { onProgress });
52
-
53
- const url = assertGitUrl(raw);
54
- if (onProgress) onProgress({ phase: 'clone', url });
55
- const clone = await cloneRepo(url);
56
- try {
57
- const repo = await openRepo(clone.dir, { onProgress });
58
- // The repo's own name is what a person recognizes; the temp path is kept so
59
- // `about` can still print a path someone could go and look at.
60
- return {
61
- ...repo,
62
- name: repoNameFromUrl(url) || repo.name,
63
- gitUrl: url,
64
- tempId: path.basename(clone.dir),
65
- cloneDir: clone.dir,
66
- };
67
- } catch (err) {
68
- // A clone that was never loaded has no session to clean it up later, so it
69
- // has to go now or it is a temp directory nobody owns.
70
- await removeClone(clone.dir);
71
- throw err;
72
- }
46
+ export async function openRepoOrClone(target, options = {}) {
47
+ throwIfAborted(options.signal);
48
+ const onProgress = options.onProgress;
49
+ const raw = String(target || '').trim();
50
+ if (!isGitUrl(raw))
51
+ return openRepo(raw, options);
52
+ const url = assertGitUrl(raw);
53
+ if (onProgress)
54
+ onProgress({ phase: 'clone', url });
55
+ const clone = await cloneRepo(url);
56
+ try {
57
+ const repo = await openRepo(clone.dir, options);
58
+ // The repo's own name is what a person recognizes; the temp path is kept so
59
+ // `about` can still print a path someone could go and look at.
60
+ return {
61
+ ...repo,
62
+ name: repoNameFromUrl(url) || repo.name,
63
+ gitUrl: url,
64
+ tempId: path.basename(clone.dir),
65
+ cloneDir: clone.dir,
66
+ };
67
+ }
68
+ catch (err) {
69
+ // A clone that was never loaded has no session to clean it up later, so it
70
+ // has to go now or it is a temp directory nobody owns.
71
+ await removeClone(clone.dir);
72
+ throw err;
73
+ }
73
74
  }
74
-
75
75
  // The URL this repo should be asked about on GitHub, or null.
76
76
  //
77
77
  // A repo this session cloned knows its own URL. A repo someone was standing in
78
78
  // does not, and git does. Asking git here rather than in the `github` command
79
79
  // keeps the answer on the repo object, so every consumer gets it the same way.
80
80
  export async function remoteUrlFor(repo) {
81
- if (repo.gitUrl) return repo.gitUrl;
82
- if (repo.remoteChecked) return null;
83
- repo.remoteChecked = true;
84
- const found = await gitRemoteOrigin(repo.root);
85
- if (found.ok) repo.gitUrl = found.url;
86
- return repo.gitUrl || null;
81
+ if (repo.gitUrl)
82
+ return repo.gitUrl;
83
+ if (repo.remoteChecked)
84
+ return null;
85
+ repo.remoteChecked = true;
86
+ const found = await gitRemoteOrigin(repo.root);
87
+ if (found.ok)
88
+ repo.gitUrl = found.url;
89
+ return repo.gitUrl || null;
87
90
  }
88
-
89
91
  // Drop a temp clone, if this repo is one. Safe to call on a local repo: it
90
92
  // checks the shape of the directory rather than trusting a flag, so a bug
91
93
  // elsewhere cannot turn "clean up" into "delete the folder the user is in".
92
94
  export async function closeRemote(repo) {
93
- if (repo?.cloneDir) await removeClone(repo.cloneDir);
95
+ if (repo?.cloneDir)
96
+ await removeClone(repo.cloneDir);
94
97
  }
95
-
96
98
  // Scan a directory and return the loaded repo, or throw an Error whose message
97
99
  // is safe to print straight to the user. `target` may be `~`, a relative path,
98
100
  // or anything `expandHome` understands; it defaults to the current directory.
99
- export async function openRepo(target = '.', { onProgress } = {}) {
100
- const root = expandHome(String(target || '.'));
101
- const stat = await fs.stat(root).catch(() => null);
102
- if (!stat) throw new Error('No such folder: ' + root);
103
- if (!stat.isDirectory()) throw new Error('Not a folder: ' + root);
104
-
105
- const source = nodeFileSource(root);
106
- const scan = await scanRepo(source, { onProgress });
107
- const manifest = await detectManifest(source);
108
- const facts = computeFacts(scan, manifest);
109
- const searchIndex = await buildSearchIndex(source, scan.files.map((f) => f.path));
110
-
111
- // The layers projection is an input to patterns, not a parallel view of the
112
- // same thing — `detectPatterns` reads the layer depths to place a file in the
113
- // architecture. Compute once, share. The coupling matrix is the same kind of
114
- // thing: a projection of `facts.folderEdges` that both the site and the
115
- // terminal's heat grid read, so it is computed once here rather than per view.
116
- const layers = computeLayers(scan, facts);
117
-
118
- return {
119
- root,
120
- name: scan.name || path.basename(root),
121
- scan,
122
- facts,
123
- manifest,
124
- searchIndex,
125
- layers,
126
- coupling: couplingMatrix(scan, facts),
127
- health: analyzeHealth(scan, facts),
128
- patterns: detectPatterns(scan, facts, manifest, layers),
129
- security: summarizeSecurity(scan),
130
- stack: analyzeStack(manifest, scan.stats.languages || {}),
131
- tour: buildTourStops(scan, facts),
132
- languages: languageRows(scan),
133
- };
101
+ export async function openRepo(target = '.', options = {}) {
102
+ const root = expandHome(String(target || '.'));
103
+ const stat = await fs.stat(root).catch(() => null);
104
+ if (!stat)
105
+ throw new Error('No such folder: ' + root);
106
+ if (!stat.isDirectory())
107
+ throw new Error('Not a folder: ' + root);
108
+ const source = nodeFileSource(root);
109
+ const scan = await scanRepo(source, options);
110
+ const manifest = await detectManifest(source);
111
+ const facts = computeFacts(scan, manifest);
112
+ const searchIndex = await buildSearchIndex(source, scan.files.map((f) => f.path));
113
+ // The layers projection is an input to patterns, not a parallel view of the
114
+ // same thing — `detectPatterns` reads the layer depths to place a file in the
115
+ // architecture. Compute once, share. The coupling matrix is the same kind of
116
+ // thing: a projection of `facts.folderEdges` that both the site and the
117
+ // terminal's heat grid read, so it is computed once here rather than per view.
118
+ const layers = computeLayers(scan, facts);
119
+ const loaded = {
120
+ root,
121
+ name: scan.name || path.basename(root),
122
+ scan,
123
+ facts,
124
+ manifest,
125
+ searchIndex,
126
+ layers,
127
+ coupling: couplingMatrix(scan, facts),
128
+ health: analyzeHealth(scan, facts),
129
+ patterns: detectPatterns(scan, facts, manifest, layers),
130
+ security: summarizeSecurity(scan),
131
+ stack: analyzeStack(manifest, scan.stats.languages || {}),
132
+ tour: buildTourStops(scan, facts),
133
+ languages: languageRows(scan),
134
+ };
135
+ return loaded;
134
136
  }
135
-
136
137
  // LOC per language, biggest first, with the display label the site uses — so
137
138
  // `JavaScript` here and `JavaScript` there are the same string.
138
139
  function languageRows(scan) {
139
- return Object.entries(scan.stats.languages || {})
140
- .map(([id, loc]) => ({ id, loc, label: languageLabel(id) }))
141
- .sort((a, b) => b.loc - a.loc || a.label.localeCompare(b.label));
140
+ return Object.entries(scan.stats.languages || {})
141
+ .map(([id, loc]) => ({ id, loc, label: languageLabel(id) }))
142
+ .sort((a, b) => Number(b.loc) - Number(a.loc) || a.label.localeCompare(b.label));
142
143
  }
143
-
144
144
  // The one place a typed path becomes a real file. People type `logger.js`, not
145
145
  // `server/logger.js`, and a tool that says "no such file" for a file that is
146
146
  // right there is worse than no tool. So: exact, then folder, then suffix, then
@@ -148,104 +148,103 @@ function languageRows(scan) {
148
148
  // than guessed at — silently picking the wrong `index.js` is the failure mode
149
149
  // that makes people stop trusting a map.
150
150
  export function resolveTarget(repo, typed) {
151
- const raw = String(typed || '').trim().replace(/^\.\//, '');
152
- if (!raw) return { error: 'Name a file or folder.' };
153
-
154
- // `.` and `./` are the root, which is a real folder and a common thing to type
155
- // (`tree .`, `explain .`). Without this they fell through to the substring
156
- // match and offered eight unrelated files as "did you mean", which is worse
157
- // than useless — it is actively misleading. The root folder's path is `''`.
158
- if (raw === '.' || raw === './') return { folder: ROOT_FOLDER };
159
-
160
- const files = repo.scan.files;
161
- if (!repo.byPath) repo.byPath = new Map(files.map((f) => [f.path, f]));
162
- if (repo.byPath.has(raw)) return { file: repo.byPath.get(raw) };
163
-
164
- const folder = folderFor(repo, raw);
165
- if (folder) return { folder };
166
-
167
- const lower = raw.toLowerCase();
168
- const suffix = files.filter((f) => f.path.endsWith('/' + raw));
169
- if (suffix.length === 1) return { file: suffix[0] };
170
- if (suffix.length > 1) return { error: 'Which one?', candidates: suffix.map((f) => f.path) };
171
-
172
- const base = files.filter((f) => f.name.toLowerCase() === lower);
173
- if (base.length === 1) return { file: base[0] };
174
- if (base.length > 1) return { error: 'Which one?', candidates: base.map((f) => f.path) };
175
-
176
- const loose = files.filter((f) => f.path.toLowerCase().includes(lower));
177
- if (loose.length) {
178
- loose.sort((a, b) => a.path.length - b.path.length);
179
- return { error: 'No exact match. Did you mean:', candidates: loose.slice(0, 8).map((f) => f.path) };
180
- }
181
- return { error: 'Nothing in this repo matches "' + raw + '".' };
151
+ const raw = String(typed || '').trim().replace(/^\.\//, '');
152
+ if (!raw)
153
+ return { error: 'Name a file or folder.' };
154
+ // `.` and `./` are the root, which is a real folder and a common thing to type
155
+ // (`tree .`, `explain .`). Without this they fell through to the substring
156
+ // match and offered eight unrelated files as "did you mean", which is worse
157
+ // than useless — it is actively misleading. The root folder's path is `''`.
158
+ if (raw === '.' || raw === './')
159
+ return { folder: ROOT_FOLDER };
160
+ const files = repo.scan.files;
161
+ if (!repo.byPath)
162
+ repo.byPath = new Map(files.map((f) => [f.path, f]));
163
+ if (repo.byPath.has(raw))
164
+ return { file: repo.byPath.get(raw) };
165
+ const folder = folderFor(repo, raw);
166
+ if (folder)
167
+ return { folder };
168
+ const lower = raw.toLowerCase();
169
+ const suffix = files.filter((f) => f.path.endsWith('/' + raw));
170
+ if (suffix.length === 1)
171
+ return { file: suffix[0] };
172
+ if (suffix.length > 1)
173
+ return { error: 'Which one?', candidates: suffix.map((f) => f.path) };
174
+ const base = files.filter((f) => f.name.toLowerCase() === lower);
175
+ if (base.length === 1)
176
+ return { file: base[0] };
177
+ if (base.length > 1)
178
+ return { error: 'Which one?', candidates: base.map((f) => f.path) };
179
+ const loose = files.filter((f) => f.path.toLowerCase().includes(lower));
180
+ if (loose.length) {
181
+ loose.sort((a, b) => a.path.length - b.path.length);
182
+ return { error: 'No exact match. Did you mean:', candidates: loose.slice(0, 8).map((f) => f.path) };
183
+ }
184
+ return { error: 'Nothing in this repo matches "' + raw + '".' };
182
185
  }
183
-
184
186
  // The root folder is a real answer, not a sentinel: `tree .` and `explain .`
185
187
  // both need one, and it carries the same fields `resolveTarget` returns for any
186
188
  // other folder so the callers need no special case.
187
189
  const ROOT_FOLDER = Object.freeze({ name: '', path: '', loc: 0, comment: 0, blank: 0, size: 0, langs: {} });
188
-
189
190
  function folderFor(repo, typed) {
190
- const clean = typed.replace(/\/+$/, '');
191
- if (clean === '') return ROOT_FOLDER;
192
- const exact = repo.scan.folders.find((d) => d.path === clean);
193
- if (exact) return exact;
194
- const matches = repo.scan.folders.filter((d) => d.path.endsWith('/' + clean) || d.name === clean);
195
- return matches.length === 1 ? matches[0] : null;
191
+ const clean = typed.replace(/\/+$/, '');
192
+ if (clean === '')
193
+ return ROOT_FOLDER;
194
+ const exact = repo.scan.folders.find((d) => d.path === clean);
195
+ if (exact)
196
+ return exact;
197
+ const matches = repo.scan.folders.filter((d) => d.path.endsWith('/' + clean) || d.name === clean);
198
+ return matches.length === 1 ? matches[0] : null;
196
199
  }
197
-
198
200
  // Read a file through the same containment check the HTTP route uses. A tool
199
201
  // whose job is showing you one repository has no business reading any path on
200
202
  // the machine, and going through `resolveInside` means there is no second,
201
203
  // looser door to get there.
202
204
  export async function readRepoFile(repo, repoPath) {
203
- const abs = resolveInside(repo.root, repoPath);
204
- if (!abs) throw new Error('That path is outside the repository.');
205
- return fs.readFile(abs, 'utf8');
205
+ const abs = resolveInside(repo.root, repoPath);
206
+ if (!abs)
207
+ throw new Error('That path is outside the repository.');
208
+ return fs.readFile(abs, 'utf8');
206
209
  }
207
-
208
210
  // The website's search, verbatim: same TF-IDF ranking, same query language
209
211
  // (`ext:`, `path:`, `-exclude`, `"phrases"`, `/regex/`), same result shape. A
210
212
  // query that works in one surface works in the other, because it is the same
211
213
  // function.
212
214
  export function searchRepo(repo, query, { limit = 12 } = {}) {
213
- return searchDocuments(repo.searchIndex, query, { limit });
215
+ return searchDocuments(repo.searchIndex, query, { limit });
214
216
  }
215
-
216
217
  // A number a person typed, or nothing. `show f 1.5 2.5` used to print
217
218
  // `1.5–3 of 344`: `Number('1.5')` passed the `|| 1` fallback, the label
218
219
  // interpolated the fraction, and only `slice()` coerced it. A line range is
219
220
  // either a whole number of lines or it is a mistake, and a mistake gets a
220
221
  // message rather than a wrong heading.
221
222
  export function lineNumber(value, fallback) {
222
- if (value === undefined || value === null || value === '') return fallback;
223
- const n = Number(value);
224
- return Number.isInteger(n) && n > 0 ? n : null;
223
+ if (value === undefined || value === null || value === '')
224
+ return fallback;
225
+ const n = Number(value);
226
+ return Number.isInteger(n) && n > 0 ? n : null;
225
227
  }
226
-
227
228
  export function explainRepoFile(repo, file) {
228
- return explainFile(file.path, file, repo.facts);
229
+ return explainFile(file.path, file, repo.facts);
229
230
  }
230
-
231
231
  export function explainRepoFolder(repo, folder) {
232
- return explainFolder(folder.path, repo.scan, repo.facts);
232
+ return explainFolder(folder.path, repo.scan, repo.facts);
233
233
  }
234
-
235
234
  export function explainRepoOverview(repo) {
236
- return explainOverview(repo.scan, repo.facts, repo.manifest);
235
+ return explainOverview(repo.scan, repo.facts, repo.manifest);
237
236
  }
238
-
239
237
  // Short facts about a file, in the order `docs.js` states them, so the terminal
240
238
  // and the generated docs never describe the same file differently.
241
239
  export function fileFacts(repo, file) {
242
- return {
243
- role: roleOf(file.path, repo.facts),
244
- loc: file.loc || 0,
245
- complexity: file.complexity || 0,
246
- fanIn: repo.facts.fanIn[file.path] || 0,
247
- fanOut: repo.facts.fanOut[file.path] || 0,
248
- inCycle: (repo.facts.inCycle || []).includes(file.path),
249
- findings: (file.findings || []).length,
250
- };
240
+ return {
241
+ role: roleOf(file.path, repo.facts),
242
+ loc: file.loc || 0,
243
+ complexity: file.complexity || 0,
244
+ fanIn: repo.facts.fanIn[file.path] || 0,
245
+ fanOut: repo.facts.fanOut[file.path] || 0,
246
+ inCycle: (repo.facts.inCycle || []).includes(file.path),
247
+ findings: (file.findings || []).length,
248
+ };
251
249
  }
250
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/explorer/session.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ScanOptions } from '../../shared/contracts.js';\nimport { throwIfAborted } from '../../shared/analyzer/scanControl.js';\n// One repository, loaded into memory, the way the website loads it.\n//\n// This is the whole reason the terminal app can stand in for the site: it runs\n// the *same* modules in the *same* order as `server/apiScan.js` — FileSource →\n// scanRepo → detectManifest → computeFacts → buildSearchIndex — and then the\n// same projections the browser's views are projections of (health, layers,\n// patterns, security, stack, tour). Nothing here re-implements analysis, so the\n// two surfaces cannot drift into telling different stories about one repo.\n//\n// Everything below the loader is pure data plus a few lookups. The loader is\n// the only async part, and it is the only part that touches the filesystem.\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport { nodeFileSource } from '../../server/fileSourceNode.js';\nimport { buildSearchIndex } from '../../server/searchIndex.js';\nimport { searchDocuments } from '../../server/apiSearch.js';\nimport { expandHome, resolveInside } from '../../server/paths.js';\nimport { assertGitUrl, cloneRepo, removeClone, repoNameFromUrl } from '../../server/gitClone.js';\nimport { gitRemoteOrigin } from '../../server/gitRemote.js';\nimport { scanRepo } from '../../shared/analyzer/scan.js';\nimport { detectManifest } from '../../shared/analyzer/services.js';\nimport { computeFacts, roleOf } from '../../shared/analyzer/graph.js';\nimport { analyzeHealth } from '../../shared/analyzer/health.js';\nimport { computeLayers, detectPatterns, couplingMatrix } from '../../shared/analyzer/patterns.js';\nimport { summarizeSecurity } from '../../shared/analyzer/security.js';\nimport { analyzeStack } from '../../shared/analyzer/stack.js';\nimport { buildTourStops } from '../../shared/analyzer/tour.js';\nimport { explainFile, explainFolder, explainOverview } from '../../shared/analyzer/explainLocal.js';\nimport { languageLabel } from '../../shared/analyzer/languages/index.js';\n\n// Does this argument name a repository to fetch, rather than a folder on this\n// machine? The check is deliberately narrow: only the URL shapes git itself\n// accepts, so a folder that happens to be called `ssh://stuff` cannot exist on a\n// filesystem anyway, while `owner/repo` is NOT accepted — too many real folders\n// are named like that (`src/server`, `app/models`) and silently cloning\n// `github.com/src/server` because someone typed `cd src/server` would be a\n// genuinely bad failure. The shorthand, if it is wanted, has to be asked for.\nexport function isGitUrl(target) {\n return /^(https?:\\/\\/|git@|ssh:\\/\\/)/.test(String(target || '').trim());\n}\n\n// Open a local folder or clone a remote one — the same three ways in the web\n// app's landing page offers, narrowed to the two that make sense for a command\n// line. A clone is left in place when the session ends; `closeRemote` removes it,\n// and the session calls that on `cd` and on exit, so nothing is orphaned in the\n// temp dir.\nexport async function openRepoOrClone(target: string, options: ScanOptions = {}) {\n throwIfAborted(options.signal);\n const onProgress = options.onProgress;\n const raw = String(target || '').trim();\n if (!isGitUrl(raw)) return openRepo(raw, options);\n\n const url = assertGitUrl(raw);\n if (onProgress) onProgress({ phase: 'clone', url });\n const clone = await cloneRepo(url);\n try {\n const repo = await openRepo(clone.dir, options);\n // The repo's own name is what a person recognizes; the temp path is kept so\n // `about` can still print a path someone could go and look at.\n return {\n ...repo,\n name: repoNameFromUrl(url) || repo.name,\n gitUrl: url,\n tempId: path.basename(clone.dir),\n cloneDir: clone.dir,\n };\n } catch (err) {\n // A clone that was never loaded has no session to clean it up later, so it\n // has to go now or it is a temp directory nobody owns.\n await removeClone(clone.dir);\n throw err;\n }\n}\n\n// The URL this repo should be asked about on GitHub, or null.\n//\n// A repo this session cloned knows its own URL. A repo someone was standing in\n// does not, and git does. Asking git here rather than in the `github` command\n// keeps the answer on the repo object, so every consumer gets it the same way.\nexport async function remoteUrlFor(repo) {\n if (repo.gitUrl) return repo.gitUrl;\n if (repo.remoteChecked) return null;\n repo.remoteChecked = true;\n const found = await gitRemoteOrigin(repo.root);\n if (found.ok) repo.gitUrl = found.url;\n return repo.gitUrl || null;\n}\n\n// Drop a temp clone, if this repo is one. Safe to call on a local repo: it\n// checks the shape of the directory rather than trusting a flag, so a bug\n// elsewhere cannot turn \"clean up\" into \"delete the folder the user is in\".\nexport async function closeRemote(repo) {\n if (repo?.cloneDir) await removeClone(repo.cloneDir);\n}\n\n// Scan a directory and return the loaded repo, or throw an Error whose message\n// is safe to print straight to the user. `target` may be `~`, a relative path,\n// or anything `expandHome` understands; it defaults to the current directory.\nexport async function openRepo(target: string = '.', options: ScanOptions = {}) {\n const root = expandHome(String(target || '.'));\n const stat = await fs.stat(root).catch(() => null);\n if (!stat) throw new Error('No such folder: ' + root);\n if (!stat.isDirectory()) throw new Error('Not a folder: ' + root);\n\n const source = nodeFileSource(root);\n const scan = await scanRepo(source, options);\n const manifest = await detectManifest(source);\n const facts = computeFacts(scan, manifest);\n const searchIndex = await buildSearchIndex(source, scan.files.map((f) => f.path));\n\n // The layers projection is an input to patterns, not a parallel view of the\n // same thing — `detectPatterns` reads the layer depths to place a file in the\n // architecture. Compute once, share. The coupling matrix is the same kind of\n // thing: a projection of `facts.folderEdges` that both the site and the\n // terminal's heat grid read, so it is computed once here rather than per view.\n const layers = computeLayers(scan, facts);\n\n const loaded = {\n root,\n name: scan.name || path.basename(root),\n scan,\n facts,\n manifest,\n searchIndex,\n layers,\n coupling: couplingMatrix(scan, facts),\n health: analyzeHealth(scan, facts),\n patterns: detectPatterns(scan, facts, manifest, layers),\n security: summarizeSecurity(scan),\n stack: analyzeStack(manifest, scan.stats.languages || {}),\n tour: buildTourStops(scan, facts),\n languages: languageRows(scan),\n };\n return loaded as typeof loaded & { gitUrl?: string; cloneDir?: string; tempId?: string };\n}\n\n// LOC per language, biggest first, with the display label the site uses — so\n// `JavaScript` here and `JavaScript` there are the same string.\nfunction languageRows(scan) {\n return Object.entries(scan.stats.languages || {})\n .map(([id, loc]) => ({ id, loc, label: languageLabel(id) }))\n .sort((a, b) => Number(b.loc) - Number(a.loc) || a.label.localeCompare(b.label));\n}\n\n// The one place a typed path becomes a real file. People type `logger.js`, not\n// `server/logger.js`, and a tool that says \"no such file\" for a file that is\n// right there is worse than no tool. So: exact, then folder, then suffix, then\n// basename, then a substring. Ambiguity is reported with the candidates rather\n// than guessed at — silently picking the wrong `index.js` is the failure mode\n// that makes people stop trusting a map.\nexport function resolveTarget(repo, typed) {\n const raw = String(typed || '').trim().replace(/^\\.\\//, '');\n if (!raw) return { error: 'Name a file or folder.' };\n\n // `.` and `./` are the root, which is a real folder and a common thing to type\n // (`tree .`, `explain .`). Without this they fell through to the substring\n // match and offered eight unrelated files as \"did you mean\", which is worse\n // than useless — it is actively misleading. The root folder's path is `''`.\n if (raw === '.' || raw === './') return { folder: ROOT_FOLDER };\n\n const files = repo.scan.files;\n if (!repo.byPath) repo.byPath = new Map(files.map((f) => [f.path, f]));\n if (repo.byPath.has(raw)) return { file: repo.byPath.get(raw) };\n\n const folder = folderFor(repo, raw);\n if (folder) return { folder };\n\n const lower = raw.toLowerCase();\n const suffix = files.filter((f) => f.path.endsWith('/' + raw));\n if (suffix.length === 1) return { file: suffix[0] };\n if (suffix.length > 1) return { error: 'Which one?', candidates: suffix.map((f) => f.path) };\n\n const base = files.filter((f) => f.name.toLowerCase() === lower);\n if (base.length === 1) return { file: base[0] };\n if (base.length > 1) return { error: 'Which one?', candidates: base.map((f) => f.path) };\n\n const loose = files.filter((f) => f.path.toLowerCase().includes(lower));\n if (loose.length) {\n loose.sort((a, b) => a.path.length - b.path.length);\n return { error: 'No exact match. Did you mean:', candidates: loose.slice(0, 8).map((f) => f.path) };\n }\n return { error: 'Nothing in this repo matches \"' + raw + '\".' };\n}\n\n// The root folder is a real answer, not a sentinel: `tree .` and `explain .`\n// both need one, and it carries the same fields `resolveTarget` returns for any\n// other folder so the callers need no special case.\nconst ROOT_FOLDER = Object.freeze({ name: '', path: '', loc: 0, comment: 0, blank: 0, size: 0, langs: {} });\n\nfunction folderFor(repo, typed) {\n const clean = typed.replace(/\\/+$/, '');\n if (clean === '') return ROOT_FOLDER;\n const exact = repo.scan.folders.find((d) => d.path === clean);\n if (exact) return exact;\n const matches = repo.scan.folders.filter((d) => d.path.endsWith('/' + clean) || d.name === clean);\n return matches.length === 1 ? matches[0] : null;\n}\n\n// Read a file through the same containment check the HTTP route uses. A tool\n// whose job is showing you one repository has no business reading any path on\n// the machine, and going through `resolveInside` means there is no second,\n// looser door to get there.\nexport async function readRepoFile(repo, repoPath) {\n const abs = resolveInside(repo.root, repoPath);\n if (!abs) throw new Error('That path is outside the repository.');\n return fs.readFile(abs, 'utf8');\n}\n\n// The website's search, verbatim: same TF-IDF ranking, same query language\n// (`ext:`, `path:`, `-exclude`, `\"phrases\"`, `/regex/`), same result shape. A\n// query that works in one surface works in the other, because it is the same\n// function.\nexport function searchRepo(repo, query, { limit = 12 }: Record<string, any> = {}) {\n return searchDocuments(repo.searchIndex, query, { limit });\n}\n\n// A number a person typed, or nothing. `show f 1.5 2.5` used to print\n// `1.5–3 of 344`: `Number('1.5')` passed the `|| 1` fallback, the label\n// interpolated the fraction, and only `slice()` coerced it. A line range is\n// either a whole number of lines or it is a mistake, and a mistake gets a\n// message rather than a wrong heading.\nexport function lineNumber(value, fallback) {\n if (value === undefined || value === null || value === '') return fallback;\n const n = Number(value);\n return Number.isInteger(n) && n > 0 ? n : null;\n}\n\nexport function explainRepoFile(repo, file) {\n return explainFile(file.path, file, repo.facts);\n}\n\nexport function explainRepoFolder(repo, folder) {\n return explainFolder(folder.path, repo.scan, repo.facts);\n}\n\nexport function explainRepoOverview(repo) {\n return explainOverview(repo.scan, repo.facts, repo.manifest);\n}\n\n// Short facts about a file, in the order `docs.js` states them, so the terminal\n// and the generated docs never describe the same file differently.\nexport function fileFacts(repo, file) {\n return {\n role: roleOf(file.path, repo.facts),\n loc: file.loc || 0,\n complexity: file.complexity || 0,\n fanIn: repo.facts.fanIn[file.path] || 0,\n fanOut: repo.facts.fanOut[file.path] || 0,\n inCycle: (repo.facts.inCycle || []).includes(file.path),\n findings: (file.findings || []).length,\n };\n}\n"]}
@@ -0,0 +1,19 @@
1
+ export declare function overview(repo: any): string;
2
+ export declare function tree(repo: any, { sub, depth, limit }?: Record<string, any>): string;
3
+ export declare function find(repo: any, { query, limit }?: Record<string, any>): string;
4
+ export declare function show(repo: any, { target, from, count }?: Record<string, any>): Promise<string>;
5
+ export declare function targetError(found: any): string;
6
+ export declare function deps(repo: any, { target, limit }?: Record<string, any>): string;
7
+ export declare function explain(repo: any, { target }?: Record<string, any>): string;
8
+ export declare function tour(repo: any): string;
9
+ export declare function health(repo: any): string;
10
+ export declare function hubs(repo: any, { limit }?: Record<string, any>): string;
11
+ export declare function layers(repo: any, { limit }?: Record<string, any>): string;
12
+ export declare function patterns(repo: any): string;
13
+ export declare function stats(repo: any, { limit }?: Record<string, any>): string;
14
+ export declare function security(repo: any, { limit }?: Record<string, any>): string;
15
+ export declare function stack(repo: any, { limit }?: Record<string, any>): string;
16
+ export declare function entry(repo: any): string;
17
+ export declare function externals(repo: any): string;
18
+ export declare function about(repo: any, version?: string): string;
19
+ export declare function github(repo: any, result: any): string;