codebase-onboarder 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/README.md +196 -47
  2. package/bin/build-if-source.js +23 -0
  3. package/cli/commands.d.ts +26 -0
  4. package/cli/commands.js +836 -811
  5. package/cli/commands.js.map +1 -0
  6. package/cli/explorer/advanced.d.ts +14 -0
  7. package/cli/explorer/advanced.js +449 -0
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +396 -229
  11. package/cli/explorer/app.js.map +1 -0
  12. package/cli/explorer/assistant.d.ts +9 -0
  13. package/cli/explorer/assistant.js +58 -0
  14. package/cli/explorer/assistant.js.map +1 -0
  15. package/cli/explorer/commands.d.ts +17 -0
  16. package/cli/explorer/commands.js +400 -162
  17. package/cli/explorer/commands.js.map +1 -0
  18. package/cli/explorer/featureViews.d.ts +124 -0
  19. package/cli/explorer/featureViews.js +179 -0
  20. package/cli/explorer/featureViews.js.map +1 -0
  21. package/cli/explorer/github.d.ts +21 -0
  22. package/cli/explorer/github.js +73 -0
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +173 -0
  26. package/cli/explorer/graphs.js.map +1 -0
  27. package/cli/explorer/picker.d.ts +22 -0
  28. package/cli/explorer/picker.js +150 -0
  29. package/cli/explorer/picker.js.map +1 -0
  30. package/cli/explorer/report.d.ts +85 -0
  31. package/cli/explorer/report.js +60 -0
  32. package/cli/explorer/report.js.map +1 -0
  33. package/cli/explorer/session.d.ts +449 -0
  34. package/cli/explorer/session.js +184 -95
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +496 -412
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +33 -0
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +235 -138
  44. package/cli/main.js.map +1 -0
  45. package/cli/prompt.d.ts +5 -0
  46. package/cli/prompt.js +84 -80
  47. package/cli/prompt.js.map +1 -0
  48. package/cli/scanOptions.d.ts +2 -0
  49. package/cli/scanOptions.js +11 -0
  50. package/cli/scanOptions.js.map +1 -0
  51. package/cli/ui.d.ts +33 -0
  52. package/cli/ui.js +55 -35
  53. package/cli/ui.js.map +1 -0
  54. package/cli/wizard.d.ts +187 -0
  55. package/cli/wizard.js +304 -284
  56. package/cli/wizard.js.map +1 -0
  57. package/package.json +15 -4
  58. package/public/app.d.ts +1 -0
  59. package/public/app.js +1057 -1009
  60. package/public/app.js.map +1 -0
  61. package/public/browser.d.ts +68 -0
  62. package/public/browser.js +2 -0
  63. package/public/browser.js.map +1 -0
  64. package/public/index.html +30 -13
  65. package/public/js/about.d.ts +6 -0
  66. package/public/js/about.js +165 -172
  67. package/public/js/about.js.map +1 -0
  68. package/public/js/aiDraft.d.ts +3 -0
  69. package/public/js/aiDraft.js +116 -124
  70. package/public/js/aiDraft.js.map +1 -0
  71. package/public/js/analysisPanel.d.ts +7 -0
  72. package/public/js/analysisPanel.js +166 -166
  73. package/public/js/analysisPanel.js.map +1 -0
  74. package/public/js/analysisReport.d.ts +38 -0
  75. package/public/js/analysisReport.js +105 -110
  76. package/public/js/analysisReport.js.map +1 -0
  77. package/public/js/api.d.ts +26 -0
  78. package/public/js/api.js +176 -167
  79. package/public/js/api.js.map +1 -0
  80. package/public/js/atlas.d.ts +6 -0
  81. package/public/js/atlas.js +50 -58
  82. package/public/js/atlas.js.map +1 -0
  83. package/public/js/blameView.d.ts +2 -0
  84. package/public/js/blameView.js +36 -37
  85. package/public/js/blameView.js.map +1 -0
  86. package/public/js/codeTab.d.ts +3 -0
  87. package/public/js/codeTab.js +175 -180
  88. package/public/js/codeTab.js.map +1 -0
  89. package/public/js/codeViewer.d.ts +5 -0
  90. package/public/js/codeViewer.js +162 -150
  91. package/public/js/codeViewer.js.map +1 -0
  92. package/public/js/components/FileChip.d.ts +9 -0
  93. package/public/js/components/FileChip.js +45 -49
  94. package/public/js/components/FileChip.js.map +1 -0
  95. package/public/js/components/MetricSparkline.d.ts +7 -0
  96. package/public/js/components/MetricSparkline.js +35 -44
  97. package/public/js/components/MetricSparkline.js.map +1 -0
  98. package/public/js/components/RiskBadge.d.ts +9 -0
  99. package/public/js/components/RiskBadge.js +55 -63
  100. package/public/js/components/RiskBadge.js.map +1 -0
  101. package/public/js/deepAnalysisView.d.ts +99 -0
  102. package/public/js/deepAnalysisView.js +282 -302
  103. package/public/js/deepAnalysisView.js.map +1 -0
  104. package/public/js/diagramPane.d.ts +8 -0
  105. package/public/js/diagramPane.js +133 -135
  106. package/public/js/diagramPane.js.map +1 -0
  107. package/public/js/diffView.d.ts +6 -0
  108. package/public/js/diffView.js +222 -209
  109. package/public/js/diffView.js.map +1 -0
  110. package/public/js/docsView.d.ts +2 -0
  111. package/public/js/docsView.js +441 -442
  112. package/public/js/docsView.js.map +1 -0
  113. package/public/js/dom.d.ts +189 -0
  114. package/public/js/dom.js +5 -0
  115. package/public/js/dom.js.map +1 -0
  116. package/public/js/fileSourceBrowser.d.ts +5 -0
  117. package/public/js/fileSourceBrowser.js +33 -41
  118. package/public/js/fileSourceBrowser.js.map +1 -0
  119. package/public/js/flameGraph.d.ts +5 -0
  120. package/public/js/flameGraph.js +62 -72
  121. package/public/js/flameGraph.js.map +1 -0
  122. package/public/js/forceGraph.d.ts +10 -0
  123. package/public/js/forceGraph.js +581 -556
  124. package/public/js/forceGraph.js.map +1 -0
  125. package/public/js/heatmap.d.ts +4 -0
  126. package/public/js/heatmap.js +142 -164
  127. package/public/js/heatmap.js.map +1 -0
  128. package/public/js/highlight.d.ts +2 -0
  129. package/public/js/highlight.js +116 -107
  130. package/public/js/highlight.js.map +1 -0
  131. package/public/js/html.d.ts +2 -0
  132. package/public/js/html.js +14 -44
  133. package/public/js/html.js.map +1 -0
  134. package/public/js/insightsView.d.ts +5 -0
  135. package/public/js/insightsView.js +93 -111
  136. package/public/js/insightsView.js.map +1 -0
  137. package/public/js/inspector.d.ts +37 -0
  138. package/public/js/inspector.js +416 -445
  139. package/public/js/inspector.js.map +1 -0
  140. package/public/js/llm.d.ts +113 -0
  141. package/public/js/llm.js +233 -272
  142. package/public/js/llm.js.map +1 -0
  143. package/public/js/mapView.d.ts +3 -0
  144. package/public/js/mapView.js +121 -120
  145. package/public/js/mapView.js.map +1 -0
  146. package/public/js/markdown.d.ts +3 -0
  147. package/public/js/markdown.js +84 -91
  148. package/public/js/markdown.js.map +1 -0
  149. package/public/js/mindmap.d.ts +32 -0
  150. package/public/js/mindmap.js +244 -259
  151. package/public/js/mindmap.js.map +1 -0
  152. package/public/js/mobilePanels.d.ts +5 -0
  153. package/public/js/mobilePanels.js +50 -0
  154. package/public/js/mobilePanels.js.map +1 -0
  155. package/public/js/repoFiles.d.ts +12 -0
  156. package/public/js/repoFiles.js +28 -27
  157. package/public/js/repoFiles.js.map +1 -0
  158. package/public/js/reviewView.d.ts +28 -0
  159. package/public/js/reviewView.js +256 -0
  160. package/public/js/reviewView.js.map +1 -0
  161. package/public/js/sbomView.d.ts +3 -0
  162. package/public/js/sbomView.js +59 -67
  163. package/public/js/sbomView.js.map +1 -0
  164. package/public/js/scanCache.d.ts +16 -0
  165. package/public/js/scanCache.js +67 -65
  166. package/public/js/scanCache.js.map +1 -0
  167. package/public/js/search.d.ts +7 -0
  168. package/public/js/search.js +868 -800
  169. package/public/js/search.js.map +1 -0
  170. package/public/js/searchLocal.d.ts +42 -0
  171. package/public/js/searchLocal.js +87 -0
  172. package/public/js/searchLocal.js.map +1 -0
  173. package/public/js/serverSettings.d.ts +5 -0
  174. package/public/js/serverSettings.js +153 -164
  175. package/public/js/serverSettings.js.map +1 -0
  176. package/public/js/state.d.ts +798 -0
  177. package/public/js/state.js +114 -122
  178. package/public/js/state.js.map +1 -0
  179. package/public/js/tour.d.ts +6 -0
  180. package/public/js/tour.js +5 -7
  181. package/public/js/tour.js.map +1 -0
  182. package/public/js/transitions.d.ts +2 -0
  183. package/public/js/transitions.js +9 -10
  184. package/public/js/transitions.js.map +1 -0
  185. package/public/js/tree.d.ts +12 -0
  186. package/public/js/tree.js +157 -154
  187. package/public/js/tree.js.map +1 -0
  188. package/public/js/workflowsView.d.ts +3 -0
  189. package/public/js/workflowsView.js +15 -22
  190. package/public/js/workflowsView.js.map +1 -0
  191. package/public/search.css +495 -0
  192. package/public/styles.css +163 -346
  193. package/public/workbench.css +166 -0
  194. package/server/apiAuth.d.ts +3 -0
  195. package/server/apiAuth.js +18 -20
  196. package/server/apiAuth.js.map +1 -0
  197. package/server/apiDiff.d.ts +2 -0
  198. package/server/apiDiff.js +20 -18
  199. package/server/apiDiff.js.map +1 -0
  200. package/server/apiDocs.d.ts +2 -0
  201. package/server/apiDocs.js +38 -40
  202. package/server/apiDocs.js.map +1 -0
  203. package/server/apiFile.d.ts +1 -0
  204. package/server/apiFile.js +14 -17
  205. package/server/apiFile.js.map +1 -0
  206. package/server/apiGitBlame.d.ts +2 -0
  207. package/server/apiGitBlame.js +50 -51
  208. package/server/apiGitBlame.js.map +1 -0
  209. package/server/apiMcp.d.ts +4 -0
  210. package/server/apiMcp.js +64 -66
  211. package/server/apiMcp.js.map +1 -0
  212. package/server/apiReview.d.ts +2 -0
  213. package/server/apiReview.js +45 -0
  214. package/server/apiReview.js.map +1 -0
  215. package/server/apiScan.d.ts +5 -0
  216. package/server/apiScan.js +90 -71
  217. package/server/apiScan.js.map +1 -0
  218. package/server/apiSearch.d.ts +33 -0
  219. package/server/apiSearch.js +184 -200
  220. package/server/apiSearch.js.map +1 -0
  221. package/server/apiSettings.d.ts +4 -0
  222. package/server/apiSettings.js +84 -85
  223. package/server/apiSettings.js.map +1 -0
  224. package/server/apiTools.d.ts +3 -0
  225. package/server/apiTools.js +55 -56
  226. package/server/apiTools.js.map +1 -0
  227. package/server/auth.d.ts +5 -0
  228. package/server/auth.js +54 -51
  229. package/server/auth.js.map +1 -0
  230. package/server/config.d.ts +42 -0
  231. package/server/config.js +189 -194
  232. package/server/config.js.map +1 -0
  233. package/server/daemon.d.ts +12 -0
  234. package/server/daemon.js +124 -114
  235. package/server/daemon.js.map +1 -0
  236. package/server/fileSourceNode.d.ts +2 -0
  237. package/server/fileSourceNode.js +34 -36
  238. package/server/fileSourceNode.js.map +1 -0
  239. package/server/gitClone.d.ts +9 -0
  240. package/server/gitClone.js +59 -61
  241. package/server/gitClone.js.map +1 -0
  242. package/server/gitDiff.d.ts +36 -0
  243. package/server/gitDiff.js +271 -169
  244. package/server/gitDiff.js.map +1 -0
  245. package/server/gitHistory.d.ts +12 -0
  246. package/server/gitHistory.js +80 -80
  247. package/server/gitHistory.js.map +1 -0
  248. package/server/gitRemote.d.ts +12 -0
  249. package/server/gitRemote.js +60 -0
  250. package/server/gitRemote.js.map +1 -0
  251. package/server/htmlText.d.ts +4 -0
  252. package/server/htmlText.js +16 -23
  253. package/server/htmlText.js.map +1 -0
  254. package/server/http.d.ts +5 -0
  255. package/server/http.js +27 -30
  256. package/server/http.js.map +1 -0
  257. package/server/httpGuards.d.ts +2 -0
  258. package/server/httpGuards.js +47 -43
  259. package/server/httpGuards.js.map +1 -0
  260. package/server/https.d.ts +34 -0
  261. package/server/https.js +121 -111
  262. package/server/https.js.map +1 -0
  263. package/server/index.d.ts +40 -0
  264. package/server/index.js +139 -147
  265. package/server/index.js.map +1 -0
  266. package/server/layout.d.ts +26 -0
  267. package/server/layout.js +59 -37
  268. package/server/layout.js.map +1 -0
  269. package/server/llmProxy.d.ts +3 -0
  270. package/server/llmProxy.js +137 -135
  271. package/server/llmProxy.js.map +1 -0
  272. package/server/logger.d.ts +38 -0
  273. package/server/logger.js +198 -211
  274. package/server/logger.js.map +1 -0
  275. package/server/mcp/analysis.d.ts +29 -0
  276. package/server/mcp/analysis.js +99 -120
  277. package/server/mcp/analysis.js.map +1 -0
  278. package/server/mcp/http.d.ts +9 -0
  279. package/server/mcp/http.js +128 -137
  280. package/server/mcp/http.js.map +1 -0
  281. package/server/mcp/runner.d.ts +68 -0
  282. package/server/mcp/runner.js +208 -218
  283. package/server/mcp/runner.js.map +1 -0
  284. package/server/mcp/server.d.ts +29 -0
  285. package/server/mcp/server.js +166 -179
  286. package/server/mcp/server.js.map +1 -0
  287. package/server/mcp/standalone.d.ts +1 -0
  288. package/server/mcp/standalone.js +8 -10
  289. package/server/mcp/standalone.js.map +1 -0
  290. package/server/mcp/tools.d.ts +2020 -0
  291. package/server/mcp/tools.js +523 -574
  292. package/server/mcp/tools.js.map +1 -0
  293. package/server/paths.d.ts +3 -0
  294. package/server/paths.js +17 -15
  295. package/server/paths.js.map +1 -0
  296. package/server/pidfile.d.ts +9 -0
  297. package/server/pidfile.js +43 -45
  298. package/server/pidfile.js.map +1 -0
  299. package/server/review.d.ts +5 -0
  300. package/server/review.js +35 -0
  301. package/server/review.js.map +1 -0
  302. package/server/router.d.ts +33 -0
  303. package/server/router.js +191 -197
  304. package/server/router.js.map +1 -0
  305. package/server/scanRequest.d.ts +3 -0
  306. package/server/scanRequest.js +36 -0
  307. package/server/scanRequest.js.map +1 -0
  308. package/server/searchIndex.d.ts +17 -0
  309. package/server/searchIndex.js +83 -80
  310. package/server/searchIndex.js.map +1 -0
  311. package/server/sessions.d.ts +14 -0
  312. package/server/sessions.js +62 -70
  313. package/server/sessions.js.map +1 -0
  314. package/server/startup.d.ts +118 -0
  315. package/server/startup.js +143 -148
  316. package/server/startup.js.map +1 -0
  317. package/server/static.d.ts +6 -0
  318. package/server/static.js +28 -31
  319. package/server/static.js.map +1 -0
  320. package/server/tools/install.d.ts +4 -0
  321. package/server/tools/install.js +176 -185
  322. package/server/tools/install.js.map +1 -0
  323. package/server/tools/parse.d.ts +8 -0
  324. package/server/tools/parse.js +112 -114
  325. package/server/tools/parse.js.map +1 -0
  326. package/server/tools/platform.d.ts +9 -0
  327. package/server/tools/platform.js +49 -47
  328. package/server/tools/platform.js.map +1 -0
  329. package/server/tools/registry.d.ts +137 -0
  330. package/server/tools/registry.js +173 -172
  331. package/server/tools/registry.js.map +1 -0
  332. package/server/tools/scan.d.ts +34 -0
  333. package/server/tools/scan.js +89 -98
  334. package/server/tools/scan.js.map +1 -0
  335. package/server/tools.d.ts +34 -0
  336. package/server/tools.js +94 -107
  337. package/server/tools.js.map +1 -0
  338. package/server/tunnel.d.ts +29 -0
  339. package/server/tunnel.js +61 -66
  340. package/server/tunnel.js.map +1 -0
  341. package/shared/analyzer/docs.d.ts +16 -0
  342. package/shared/analyzer/docs.js +99 -93
  343. package/shared/analyzer/docs.js.map +1 -0
  344. package/shared/analyzer/explainLocal.d.ts +4 -0
  345. package/shared/analyzer/explainLocal.js +122 -142
  346. package/shared/analyzer/explainLocal.js.map +1 -0
  347. package/shared/analyzer/github.d.ts +37 -0
  348. package/shared/analyzer/github.js +79 -0
  349. package/shared/analyzer/github.js.map +1 -0
  350. package/shared/analyzer/graph.d.ts +41 -0
  351. package/shared/analyzer/graph.js +393 -400
  352. package/shared/analyzer/graph.js.map +1 -0
  353. package/shared/analyzer/health.d.ts +33 -0
  354. package/shared/analyzer/health.js +197 -193
  355. package/shared/analyzer/health.js.map +1 -0
  356. package/shared/analyzer/history.d.ts +29 -0
  357. package/shared/analyzer/history.js +110 -111
  358. package/shared/analyzer/history.js.map +1 -0
  359. package/shared/analyzer/jsonConfig.d.ts +2 -0
  360. package/shared/analyzer/jsonConfig.js +61 -0
  361. package/shared/analyzer/jsonConfig.js.map +1 -0
  362. package/shared/analyzer/languages/csharp.d.ts +26 -0
  363. package/shared/analyzer/languages/csharp.js +83 -88
  364. package/shared/analyzer/languages/csharp.js.map +1 -0
  365. package/shared/analyzer/languages/generic.d.ts +23 -0
  366. package/shared/analyzer/languages/generic.js +94 -105
  367. package/shared/analyzer/languages/generic.js.map +1 -0
  368. package/shared/analyzer/languages/go.d.ts +24 -0
  369. package/shared/analyzer/languages/go.js +45 -54
  370. package/shared/analyzer/languages/go.js.map +1 -0
  371. package/shared/analyzer/languages/index.d.ts +6 -0
  372. package/shared/analyzer/languages/index.js +19 -20
  373. package/shared/analyzer/languages/index.js.map +1 -0
  374. package/shared/analyzer/languages/java.d.ts +20 -0
  375. package/shared/analyzer/languages/java.js +73 -78
  376. package/shared/analyzer/languages/java.js.map +1 -0
  377. package/shared/analyzer/languages/javascript.d.ts +12 -0
  378. package/shared/analyzer/languages/javascript.js +258 -209
  379. package/shared/analyzer/languages/javascript.js.map +1 -0
  380. package/shared/analyzer/languages/python.d.ts +23 -0
  381. package/shared/analyzer/languages/python.js +92 -100
  382. package/shared/analyzer/languages/python.js.map +1 -0
  383. package/shared/analyzer/languages/rust.d.ts +17 -0
  384. package/shared/analyzer/languages/rust.js +96 -98
  385. package/shared/analyzer/languages/rust.js.map +1 -0
  386. package/shared/analyzer/languages/typescript.d.ts +11 -0
  387. package/shared/analyzer/languages/typescript.js +117 -116
  388. package/shared/analyzer/languages/typescript.js.map +1 -0
  389. package/shared/analyzer/licenses.d.ts +18 -0
  390. package/shared/analyzer/licenses.js +130 -133
  391. package/shared/analyzer/licenses.js.map +1 -0
  392. package/shared/analyzer/metrics.d.ts +20 -0
  393. package/shared/analyzer/metrics.js +112 -104
  394. package/shared/analyzer/metrics.js.map +1 -0
  395. package/shared/analyzer/pathUtil.d.ts +10 -0
  396. package/shared/analyzer/pathUtil.js +29 -35
  397. package/shared/analyzer/pathUtil.js.map +1 -0
  398. package/shared/analyzer/patterns.d.ts +11 -0
  399. package/shared/analyzer/patterns.js +231 -253
  400. package/shared/analyzer/patterns.js.map +1 -0
  401. package/shared/analyzer/scan.d.ts +62 -0
  402. package/shared/analyzer/scan.js +451 -442
  403. package/shared/analyzer/scan.js.map +1 -0
  404. package/shared/analyzer/scanControl.d.ts +11 -0
  405. package/shared/analyzer/scanControl.js +62 -0
  406. package/shared/analyzer/scanControl.js.map +1 -0
  407. package/shared/analyzer/security.d.ts +18 -0
  408. package/shared/analyzer/security.js +159 -159
  409. package/shared/analyzer/security.js.map +1 -0
  410. package/shared/analyzer/services.d.ts +5 -0
  411. package/shared/analyzer/services.js +141 -138
  412. package/shared/analyzer/services.js.map +1 -0
  413. package/shared/analyzer/stack.d.ts +6 -0
  414. package/shared/analyzer/stack.js +134 -141
  415. package/shared/analyzer/stack.js.map +1 -0
  416. package/shared/analyzer/tour.d.ts +2 -0
  417. package/shared/analyzer/tour.js +45 -53
  418. package/shared/analyzer/tour.js.map +1 -0
  419. package/shared/analyzer/util.d.ts +8 -0
  420. package/shared/analyzer/util.js +130 -76
  421. package/shared/analyzer/util.js.map +1 -0
  422. package/shared/analyzer/workflows.d.ts +8 -0
  423. package/shared/analyzer/workflows.js +139 -134
  424. package/shared/analyzer/workflows.js.map +1 -0
  425. package/shared/contracts.d.ts +250 -0
  426. package/shared/contracts.js +2 -0
  427. package/shared/contracts.js.map +1 -0
  428. package/shared/diagram/aiFacts.d.ts +35 -0
  429. package/shared/diagram/aiFacts.js +102 -105
  430. package/shared/diagram/aiFacts.js.map +1 -0
  431. package/shared/diagram/aiMermaid.d.ts +5 -0
  432. package/shared/diagram/aiMermaid.js +46 -45
  433. package/shared/diagram/aiMermaid.js.map +1 -0
  434. package/shared/diagram/atlas.d.ts +16 -0
  435. package/shared/diagram/atlas.js +51 -60
  436. package/shared/diagram/atlas.js.map +1 -0
  437. package/shared/diagram/mermaid.d.ts +43 -0
  438. package/shared/diagram/mermaid.js +348 -370
  439. package/shared/diagram/mermaid.js.map +1 -0
  440. package/shared/review/contracts.d.ts +95 -0
  441. package/shared/review/contracts.js +2 -0
  442. package/shared/review/contracts.js.map +1 -0
  443. package/shared/review/review.d.ts +10 -0
  444. package/shared/review/review.js +184 -0
  445. package/shared/review/review.js.map +1 -0
  446. package/shared/search/query.d.ts +32 -0
  447. package/shared/search/query.js +395 -388
  448. package/shared/search/query.js.map +1 -0
@@ -9,10 +9,8 @@
9
9
  //
10
10
  // It reuses the same `shared/` analyzers the browser runs, rather than a second
11
11
  // implementation: a number in an MCP response is the same number the UI shows.
12
-
13
12
  import { promises as fs } from 'node:fs';
14
13
  import path from 'node:path';
15
-
16
14
  import { scanRepo } from '../../shared/analyzer/scan.js';
17
15
  import { computeFacts, scanIndex } from '../../shared/analyzer/graph.js';
18
16
  import { detectManifest } from '../../shared/analyzer/services.js';
@@ -29,180 +27,161 @@ import { nodeFileSource } from '../fileSourceNode.js';
29
27
  import { gitLog, parseGitLog } from '../gitHistory.js';
30
28
  import { analyzeHistory, unavailableHistory } from '../../shared/analyzer/history.js';
31
29
  import { expandHome, resolveInside } from '../paths.js';
32
-
33
30
  // How many repositories stay warm. One is the common case — a client points at a
34
31
  // repo and works in it — but an agent comparing two projects should not pay for a
35
32
  // rescan when it alternates between them. Each entry holds a parsed file list, so
36
33
  // the cap is about memory, not count.
37
34
  const MAX_CACHED = 4;
38
-
39
35
  const cache = new Map();
40
-
41
36
  // Root path -> the finished analysis. Resolving the path first means `/Users/x/~
42
37
  // repo` and `/Users/x/repo` are one entry, not two that evict each other.
43
38
  export function cachedAnalysis(root) {
44
- return cache.get(path.resolve(root)) || null;
39
+ return cache.get(path.resolve(root)) || null;
45
40
  }
46
-
47
41
  export function cachedRoots() {
48
- return [...cache.keys()];
42
+ return [...cache.keys()];
49
43
  }
50
-
51
44
  export function clearAnalysisCache() {
52
- cache.clear();
45
+ cache.clear();
53
46
  }
54
-
55
47
  // A tool error is a message the agent can act on, not a stack trace. The protocol
56
48
  // layer turns these into `isError` results so the model sees the sentence and can
57
49
  // correct itself, rather than the call failing opaquely.
58
50
  export class ToolError extends Error {
59
- constructor(message) {
60
- super(message);
61
- this.name = 'ToolError';
62
- }
51
+ name;
52
+ constructor(message) {
53
+ super(message);
54
+ this.name = 'ToolError';
55
+ }
63
56
  }
64
-
65
57
  function buildPatterns(scan, facts, manifest) {
66
- const layersInfo = computeLayers(scan, facts);
67
- return {
68
- layersInfo,
69
- findings: detectPatterns(scan, facts, manifest, layersInfo),
70
- coupling: couplingMatrix(scan, facts),
71
- };
58
+ const layersInfo = computeLayers(scan, facts);
59
+ return {
60
+ layersInfo,
61
+ findings: detectPatterns(scan, facts, manifest, layersInfo),
62
+ coupling: couplingMatrix(scan, facts),
63
+ };
72
64
  }
73
-
74
65
  async function collectHistory(root, scan) {
75
- try {
76
- const log = await gitLog(root);
77
- if (!log.ok) return unavailableHistory(log.reason);
78
- return analyzeHistory(scan, parseGitLog(log.text), { totalCommits: log.totalCommits });
79
- } catch {
80
- return unavailableHistory('The history could not be read — the scan itself is unaffected.');
81
- }
66
+ try {
67
+ const log = await gitLog(root);
68
+ if (!log.ok)
69
+ return unavailableHistory(log.reason);
70
+ return analyzeHistory(scan, parseGitLog(log.text), { totalCommits: log.totalCommits });
71
+ }
72
+ catch {
73
+ return unavailableHistory('The history could not be read — the scan itself is unaffected.');
74
+ }
82
75
  }
83
-
84
76
  // The entry point. `force` is how `onboarder_rescan` differs from every other
85
77
  // tool: the same call twice returns the same answer until it is asked not to.
86
78
  export async function analyzeRepository(rootInput, { force = false } = {}) {
87
- const trimmed = String(rootInput || '').trim();
88
- if (!trimmed) throw new ToolError('A repository path is required.');
89
-
90
- const root = expandHome(trimmed);
91
- if (!force) {
92
- const hit = cache.get(root);
93
- if (hit) {
94
- // Re-insert so the eviction below drops a genuinely cold repo rather than
95
- // whichever one happened to be scanned first.
96
- cache.delete(root);
97
- cache.set(root, hit);
98
- return hit;
79
+ const trimmed = String(rootInput || '').trim();
80
+ if (!trimmed)
81
+ throw new ToolError('A repository path is required.');
82
+ const root = expandHome(trimmed);
83
+ if (!force) {
84
+ const hit = cache.get(root);
85
+ if (hit) {
86
+ // Re-insert so the eviction below drops a genuinely cold repo rather than
87
+ // whichever one happened to be scanned first.
88
+ cache.delete(root);
89
+ cache.set(root, hit);
90
+ return hit;
91
+ }
92
+ }
93
+ const stat = await fs.stat(root).catch(() => null);
94
+ if (!stat?.isDirectory()) {
95
+ throw new ToolError(`No folder at ${root}. Check the path and try again.`);
99
96
  }
100
- }
101
-
102
- const stat = await fs.stat(root).catch(() => null);
103
- if (!stat?.isDirectory()) {
104
- throw new ToolError(`No folder at ${root}. Check the path and try again.`);
105
- }
106
-
107
- const source = nodeFileSource(root);
108
- const scan = await scanRepo(source);
109
- const manifest = await detectManifest(source);
110
- const facts = computeFacts(scan, manifest);
111
-
112
- // Built here rather than on first search for the same reason the HTTP route
113
- // builds it at scan time: a search that reads every file is a search whose cost
114
- // depends on what was asked, and an agent asks repeatedly.
115
- const searchIndexData = await buildSearchIndex(source, scan.files.map((f) => f.path));
116
-
117
- const analysis = {
118
- root,
119
- scannedAt: Date.now(),
120
- scan,
121
- facts,
122
- manifest,
123
- stack: analyzeStack(manifest, scan.stats.languages),
124
- patterns: buildPatterns(scan, facts, manifest),
125
- health: analyzeHealth(scan, facts),
126
- security: summarizeSecurity(scan),
127
- history: await collectHistory(root, scan),
128
- searchIndex: searchIndexData,
129
- // The prose the overview panel shows, computed here so an agent gets the same
130
- // onboarding summary a person reads rather than a pile of raw arrays.
131
- overview: explainOverview(scan, facts, manifest),
132
- caveats: scanCaveats(scan),
133
- };
134
-
135
- cache.set(root, analysis);
136
- // Map preserves insertion order, so the first key is the least recently used.
137
- while (cache.size > MAX_CACHED) cache.delete(cache.keys().next().value);
138
- return analysis;
97
+ const source = nodeFileSource(root);
98
+ const scan = await scanRepo(source);
99
+ const manifest = await detectManifest(source);
100
+ const facts = computeFacts(scan, manifest);
101
+ // Built here rather than on first search for the same reason the HTTP route
102
+ // builds it at scan time: a search that reads every file is a search whose cost
103
+ // depends on what was asked, and an agent asks repeatedly.
104
+ const searchIndexData = await buildSearchIndex(source, scan.files.map((f) => f.path));
105
+ const analysis = {
106
+ root,
107
+ scannedAt: Date.now(),
108
+ scan,
109
+ facts,
110
+ manifest,
111
+ stack: analyzeStack(manifest, scan.stats.languages),
112
+ patterns: buildPatterns(scan, facts, manifest),
113
+ health: analyzeHealth(scan, facts),
114
+ security: summarizeSecurity(scan),
115
+ history: await collectHistory(root, scan),
116
+ searchIndex: searchIndexData,
117
+ // The prose the overview panel shows, computed here so an agent gets the same
118
+ // onboarding summary a person reads rather than a pile of raw arrays.
119
+ overview: explainOverview(scan, facts, manifest),
120
+ caveats: scanCaveats(scan),
121
+ };
122
+ cache.set(root, analysis);
123
+ // Map preserves insertion order, so the first key is the least recently used.
124
+ while (cache.size > MAX_CACHED)
125
+ cache.delete(cache.keys().next().value);
126
+ return analysis;
139
127
  }
140
-
141
-
142
128
  // Files anywhere under a folder, parsed or not. `scanIndex().filesIn` is an exact
143
129
  // directory lookup over the *parsed* files, which is the right thing for a diagram
144
130
  // of one directory and the wrong thing for "what is in this folder" — an agent
145
131
  // asking about `public` wants the stylesheet and the icons too.
146
132
  export function filesUnder(analysis, folder) {
147
- const prefix = folder ? String(folder).replace(/\/+$/, '') + '/' : '';
148
- return analysis.scan.allFiles.filter((p) => p.startsWith(prefix));
133
+ const prefix = folder ? String(folder).replace(/\/+$/, '') + '/' : '';
134
+ return analysis.scan.allFiles.filter((p) => p.startsWith(prefix));
149
135
  }
150
-
151
136
  // The files under a folder that the parser understood, as file objects. The same
152
137
  // containment rule, so the two cannot disagree about what a folder holds.
153
138
  export function parsedFilesUnder(analysis, folder) {
154
- const paths = new Set(filesUnder(analysis, folder));
155
- return analysis.scan.files.filter((f) => paths.has(f.path));
139
+ const paths = new Set(filesUnder(analysis, folder));
140
+ return analysis.scan.files.filter((f) => paths.has(f.path));
156
141
  }
157
-
158
142
  // Resolves a repository-relative path to an absolute one, refusing anything that
159
143
  // lands outside the root. This is the same check `/api/file` makes, and it is the
160
144
  // only thing standing between an agent and the rest of the disk: an MCP client is
161
145
  // another program on this machine, not a browser tab, so the cross-origin guards
162
146
  // do not apply here. Containment is the boundary, not the scan.
163
147
  export function resolveIn(analysis, relPath) {
164
- if (typeof relPath !== 'string' || !relPath.trim()) {
165
- throw new ToolError('A file path is required.');
166
- }
167
- const abs = resolveInside(analysis.root, relPath.trim());
168
- if (!abs) throw new ToolError(`${relPath} is outside ${analysis.root}.`);
169
- return { abs, rel: path.relative(analysis.root, abs).split(path.sep).join('/') };
148
+ if (typeof relPath !== 'string' || !relPath.trim()) {
149
+ throw new ToolError('A file path is required.');
150
+ }
151
+ const abs = resolveInside(analysis.root, relPath.trim());
152
+ if (!abs)
153
+ throw new ToolError(`${relPath} is outside ${analysis.root}.`);
154
+ return { abs, rel: path.relative(analysis.root, abs).split(path.sep).join('/') };
170
155
  }
171
-
172
156
  // The same, but also insists the parser looked at the file. The analysis tools
173
157
  // (`explain_file`, `explain_folder`) need a parsed file because every field they
174
158
  // return came from parsing it; saying "package.json is not a file in the scanned
175
159
  // repository" for a JSON manifest would be technically true and practically
176
160
  // useless, so those tools check this and `read_file` does not.
177
161
  export function fileIn(analysis, relPath) {
178
- const { abs, rel } = resolveIn(analysis, relPath);
179
- const file = scanIndex(analysis.scan).fileAt(rel);
180
- if (!file) {
181
- throw new ToolError(`${rel} is not a source file in the scan. Use onboarder_read_file to read it as text.`);
182
- }
183
- return { abs, rel, file };
162
+ const { abs, rel } = resolveIn(analysis, relPath);
163
+ const file = scanIndex(analysis.scan).fileAt(rel);
164
+ if (!file) {
165
+ throw new ToolError(`${rel} is not a source file in the scan. Use onboarder_read_file to read it as text.`);
166
+ }
167
+ return { abs, rel, file };
184
168
  }
185
-
186
169
  export async function readFileText(analysis, relPath) {
187
- const { abs, rel } = resolveIn(analysis, relPath);
188
- const stat = await fs.stat(abs).catch(() => null);
189
- if (!stat?.isFile()) throw new ToolError(`${rel} could not be read.`);
190
- // Matches the HTTP route's ceiling. A tool that returns a 200 MB file has not
191
- // answered the question, it has exhausted the context window.
192
- if (stat.size > 200 * 1024) {
193
- throw new ToolError(`${rel} is ${Math.round(stat.size / 1024)} KB — too large to return whole.`);
194
- }
195
- return { path: rel, text: await fs.readFile(abs, 'utf8') };
170
+ const { abs, rel } = resolveIn(analysis, relPath);
171
+ const stat = await fs.stat(abs).catch(() => null);
172
+ if (!stat?.isFile())
173
+ throw new ToolError(`${rel} could not be read.`);
174
+ // Matches the HTTP route's ceiling. A tool that returns a 200 MB file has not
175
+ // answered the question, it has exhausted the context window.
176
+ if (stat.size > 200 * 1024) {
177
+ throw new ToolError(`${rel} is ${Math.round(stat.size / 1024)} KB — too large to return whole.`);
178
+ }
179
+ return { path: rel, text: await fs.readFile(abs, 'utf8') };
196
180
  }
197
-
198
181
  // Re-exported so tools build their payloads from the same helpers the views do,
199
182
  // rather than re-deriving "which files are in this folder" a third time.
200
183
  //
201
184
  // `importsOf`/`importers` are the plain-object maps `computeFacts` returns, not
202
185
  // methods on the scan index — the index only answers questions about files.
203
- export {
204
- scanIndex, dirOf, baseName,
205
- explainFile, explainFolder,
206
- docFileRow, fileFactsLine, fileStaticDoc, folderStaticDoc,
207
- searchDocuments,
208
- };
186
+ export { scanIndex, dirOf, baseName, explainFile, explainFolder, docFileRow, fileFactsLine, fileStaticDoc, folderStaticDoc, searchDocuments, };
187
+ //# sourceMappingURL=analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../../src/server/mcp/analysis.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,kFAAkF;AAClF,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,kFAAkF;AAClF,iFAAiF;AACjF,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAE/E,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACjH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC1G,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAExD,iFAAiF;AACjF,kFAAkF;AAClF,kFAAkF;AAClF,sCAAsC;AACtC,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;AAExB,iFAAiF;AACjF,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,IAAI;IACjC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED,kFAAkF;AAClF,kFAAkF;AAClF,yDAAyD;AACzD,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,IAAI,CAAS;IAEb,YAAY,OAAO;QACjB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ;IAC1C,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO;QACL,UAAU;QACV,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC;QAC3D,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAI,EAAE,IAAI;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,OAAO,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kBAAkB,CAAC,gEAAgE,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAS,EAAE,EAAE,KAAK,GAAG,KAAK,EAAE,GAAwB,EAAE;IAC5F,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;IAEpE,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,GAAG,EAAE,CAAC;YACR,0EAA0E;YAC1E,8CAA8C;YAC9C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,SAAS,CAAC,gBAAgB,IAAI,iCAAiC,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE3C,4EAA4E;IAC5E,gFAAgF;IAChF,2DAA2D;IAC3D,MAAM,eAAe,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtF,MAAM,QAAQ,GAAG;QACf,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI;QACJ,KAAK;QACL,QAAQ;QACR,KAAK,EAAE,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;QACnD,QAAQ,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC9C,MAAM,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC;QAClC,QAAQ,EAAE,iBAAiB,CAAC,IAAI,CAAC;QACjC,OAAO,EAAE,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC;QACzC,WAAW,EAAE,eAAe;QAC5B,8EAA8E;QAC9E,sEAAsE;QACtE,QAAQ,EAAE,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC;QAChD,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC;KAC3B,CAAC;IAEF,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1B,8EAA8E;IAC9E,OAAO,KAAK,CAAC,IAAI,GAAG,UAAU;QAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IACxE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAGD,kFAAkF;AAClF,mFAAmF;AACnF,+EAA+E;AAC/E,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,QAAQ,EAAE,MAAM;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,iFAAiF;AACjF,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB,CAAC,QAAQ,EAAE,MAAM;IAC/C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,iFAAiF;AACjF,kFAAkF;AAClF,kFAAkF;AAClF,iFAAiF;AACjF,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,QAAQ,EAAE,OAAO;IACzC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACnD,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,eAAe,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IACzE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACnF,CAAC;AAED,+EAA+E;AAC/E,iFAAiF;AACjF,iFAAiF;AACjF,4EAA4E;AAC5E,+DAA+D;AAC/D,MAAM,UAAU,MAAM,CAAC,QAAQ,EAAE,OAAO;IACtC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,SAAS,CAAC,GAAG,GAAG,gFAAgF,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAQ,EAAE,OAAO;IAClD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,GAAG,qBAAqB,CAAC,CAAC;IACtE,8EAA8E;IAC9E,8DAA8D;IAC9D,IAAI,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,GAAG,GAAG,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,gFAAgF;AAChF,yEAAyE;AACzE,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,OAAO,EACL,SAAS,EAAE,KAAK,EAAE,QAAQ,EAC1B,WAAW,EAAE,aAAa,EAC1B,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EACzD,eAAe,GAChB,CAAC","sourcesContent":["// The analysis every MCP tool reads from, computed once per repository.\n//\n// The HTTP app already knows this shape: `apiScan.js` returns `scan`, `facts` and\n// `manifest`, and each view derives the rest on demand. An MCP client has no\n// session to hold a scan id in and no view to trigger those derivations, so this\n// module does the whole derivation up front, once, and hands the result to every\n// tool. The tools are then pure projections — a tool cannot disagree with another\n// about what the repository looks like, because there is only one answer cached.\n//\n// It reuses the same `shared/` analyzers the browser runs, rather than a second\n// implementation: a number in an MCP response is the same number the UI shows.\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport { scanRepo } from '../../shared/analyzer/scan.js';\nimport { computeFacts, scanIndex } from '../../shared/analyzer/graph.js';\nimport { detectManifest } from '../../shared/analyzer/services.js';\nimport { analyzeStack } from '../../shared/analyzer/stack.js';\nimport { computeLayers, detectPatterns, couplingMatrix } from '../../shared/analyzer/patterns.js';\nimport { analyzeHealth } from '../../shared/analyzer/health.js';\nimport { summarizeSecurity } from '../../shared/analyzer/security.js';\nimport { explainOverview, explainFile, explainFolder, scanCaveats } from '../../shared/analyzer/explainLocal.js';\nimport { docFileRow, fileFactsLine, fileStaticDoc, folderStaticDoc } from '../../shared/analyzer/docs.js';\nimport { baseName, dirOf } from '../../shared/analyzer/pathUtil.js';\nimport { buildSearchIndex } from '../searchIndex.js';\nimport { searchDocuments } from '../apiSearch.js';\nimport { nodeFileSource } from '../fileSourceNode.js';\nimport { gitLog, parseGitLog } from '../gitHistory.js';\nimport { analyzeHistory, unavailableHistory } from '../../shared/analyzer/history.js';\nimport { expandHome, resolveInside } from '../paths.js';\n\n// How many repositories stay warm. One is the common case — a client points at a\n// repo and works in it — but an agent comparing two projects should not pay for a\n// rescan when it alternates between them. Each entry holds a parsed file list, so\n// the cap is about memory, not count.\nconst MAX_CACHED = 4;\n\nconst cache = new Map();\n\n// Root path -> the finished analysis. Resolving the path first means `/Users/x/~\n// repo` and `/Users/x/repo` are one entry, not two that evict each other.\nexport function cachedAnalysis(root) {\n return cache.get(path.resolve(root)) || null;\n}\n\nexport function cachedRoots() {\n return [...cache.keys()];\n}\n\nexport function clearAnalysisCache() {\n cache.clear();\n}\n\n// A tool error is a message the agent can act on, not a stack trace. The protocol\n// layer turns these into `isError` results so the model sees the sentence and can\n// correct itself, rather than the call failing opaquely.\nexport class ToolError extends Error {\n name: string;\n\n constructor(message) {\n super(message);\n this.name = 'ToolError';\n }\n}\n\nfunction buildPatterns(scan, facts, manifest) {\n const layersInfo = computeLayers(scan, facts);\n return {\n layersInfo,\n findings: detectPatterns(scan, facts, manifest, layersInfo),\n coupling: couplingMatrix(scan, facts),\n };\n}\n\nasync function collectHistory(root, scan) {\n try {\n const log = await gitLog(root);\n if (!log.ok) return unavailableHistory(log.reason);\n return analyzeHistory(scan, parseGitLog(log.text), { totalCommits: log.totalCommits });\n } catch {\n return unavailableHistory('The history could not be read — the scan itself is unaffected.');\n }\n}\n\n// The entry point. `force` is how `onboarder_rescan` differs from every other\n// tool: the same call twice returns the same answer until it is asked not to.\nexport async function analyzeRepository(rootInput, { force = false }: Record<string, any> = {}) {\n const trimmed = String(rootInput || '').trim();\n if (!trimmed) throw new ToolError('A repository path is required.');\n\n const root = expandHome(trimmed);\n if (!force) {\n const hit = cache.get(root);\n if (hit) {\n // Re-insert so the eviction below drops a genuinely cold repo rather than\n // whichever one happened to be scanned first.\n cache.delete(root);\n cache.set(root, hit);\n return hit;\n }\n }\n\n const stat = await fs.stat(root).catch(() => null);\n if (!stat?.isDirectory()) {\n throw new ToolError(`No folder at ${root}. Check the path and try again.`);\n }\n\n const source = nodeFileSource(root);\n const scan = await scanRepo(source);\n const manifest = await detectManifest(source);\n const facts = computeFacts(scan, manifest);\n\n // Built here rather than on first search for the same reason the HTTP route\n // builds it at scan time: a search that reads every file is a search whose cost\n // depends on what was asked, and an agent asks repeatedly.\n const searchIndexData = await buildSearchIndex(source, scan.files.map((f) => f.path));\n\n const analysis = {\n root,\n scannedAt: Date.now(),\n scan,\n facts,\n manifest,\n stack: analyzeStack(manifest, scan.stats.languages),\n patterns: buildPatterns(scan, facts, manifest),\n health: analyzeHealth(scan, facts),\n security: summarizeSecurity(scan),\n history: await collectHistory(root, scan),\n searchIndex: searchIndexData,\n // The prose the overview panel shows, computed here so an agent gets the same\n // onboarding summary a person reads rather than a pile of raw arrays.\n overview: explainOverview(scan, facts, manifest),\n caveats: scanCaveats(scan),\n };\n\n cache.set(root, analysis);\n // Map preserves insertion order, so the first key is the least recently used.\n while (cache.size > MAX_CACHED) cache.delete(cache.keys().next().value);\n return analysis;\n}\n\n\n// Files anywhere under a folder, parsed or not. `scanIndex().filesIn` is an exact\n// directory lookup over the *parsed* files, which is the right thing for a diagram\n// of one directory and the wrong thing for \"what is in this folder\" — an agent\n// asking about `public` wants the stylesheet and the icons too.\nexport function filesUnder(analysis, folder) {\n const prefix = folder ? String(folder).replace(/\\/+$/, '') + '/' : '';\n return analysis.scan.allFiles.filter((p) => p.startsWith(prefix));\n}\n\n// The files under a folder that the parser understood, as file objects. The same\n// containment rule, so the two cannot disagree about what a folder holds.\nexport function parsedFilesUnder(analysis, folder) {\n const paths = new Set(filesUnder(analysis, folder));\n return analysis.scan.files.filter((f) => paths.has(f.path));\n}\n\n// Resolves a repository-relative path to an absolute one, refusing anything that\n// lands outside the root. This is the same check `/api/file` makes, and it is the\n// only thing standing between an agent and the rest of the disk: an MCP client is\n// another program on this machine, not a browser tab, so the cross-origin guards\n// do not apply here. Containment is the boundary, not the scan.\nexport function resolveIn(analysis, relPath) {\n if (typeof relPath !== 'string' || !relPath.trim()) {\n throw new ToolError('A file path is required.');\n }\n const abs = resolveInside(analysis.root, relPath.trim());\n if (!abs) throw new ToolError(`${relPath} is outside ${analysis.root}.`);\n return { abs, rel: path.relative(analysis.root, abs).split(path.sep).join('/') };\n}\n\n// The same, but also insists the parser looked at the file. The analysis tools\n// (`explain_file`, `explain_folder`) need a parsed file because every field they\n// return came from parsing it; saying \"package.json is not a file in the scanned\n// repository\" for a JSON manifest would be technically true and practically\n// useless, so those tools check this and `read_file` does not.\nexport function fileIn(analysis, relPath) {\n const { abs, rel } = resolveIn(analysis, relPath);\n const file = scanIndex(analysis.scan).fileAt(rel);\n if (!file) {\n throw new ToolError(`${rel} is not a source file in the scan. Use onboarder_read_file to read it as text.`);\n }\n return { abs, rel, file };\n}\n\nexport async function readFileText(analysis, relPath) {\n const { abs, rel } = resolveIn(analysis, relPath);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat?.isFile()) throw new ToolError(`${rel} could not be read.`);\n // Matches the HTTP route's ceiling. A tool that returns a 200 MB file has not\n // answered the question, it has exhausted the context window.\n if (stat.size > 200 * 1024) {\n throw new ToolError(`${rel} is ${Math.round(stat.size / 1024)} KB — too large to return whole.`);\n }\n return { path: rel, text: await fs.readFile(abs, 'utf8') };\n}\n\n// Re-exported so tools build their payloads from the same helpers the views do,\n// rather than re-deriving \"which files are in this folder\" a third time.\n//\n// `importsOf`/`importers` are the plain-object maps `computeFacts` returns, not\n// methods on the scan index — the index only answers questions about files.\nexport {\n scanIndex, dirOf, baseName,\n explainFile, explainFolder,\n docFileRow, fileFactsLine, fileStaticDoc, folderStaticDoc,\n searchDocuments,\n};\n"]}
@@ -0,0 +1,9 @@
1
+ export declare const HTTP_HOST = "127.0.0.1";
2
+ export declare const DEFAULT_PORT = 8790;
3
+ export declare function handleMcpHttpRequest(req: any, res: any): void | Promise<void>;
4
+ /**
5
+ * Start the Streamable HTTP transport. Returns `{ url, port, server, close }`, and
6
+ * `port` is the port actually bound — which matters because the caller may have
7
+ * asked for 0 and gets a free one back.
8
+ */
9
+ export declare function createHttpTransport({ port, host }?: Record<string, any>): Promise<unknown>;