codebase-onboarder 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/README.md +174 -46
  2. package/bin/build-if-source.js +23 -0
  3. package/cli/commands.d.ts +26 -0
  4. package/cli/commands.js +836 -811
  5. package/cli/commands.js.map +1 -0
  6. package/cli/explorer/advanced.d.ts +14 -0
  7. package/cli/explorer/advanced.js +321 -329
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +384 -313
  11. package/cli/explorer/app.js.map +1 -0
  12. package/cli/explorer/assistant.d.ts +9 -0
  13. package/cli/explorer/assistant.js +58 -0
  14. package/cli/explorer/assistant.js.map +1 -0
  15. package/cli/explorer/commands.d.ts +17 -0
  16. package/cli/explorer/commands.js +368 -302
  17. package/cli/explorer/commands.js.map +1 -0
  18. package/cli/explorer/featureViews.d.ts +124 -0
  19. package/cli/explorer/featureViews.js +179 -0
  20. package/cli/explorer/featureViews.js.map +1 -0
  21. package/cli/explorer/github.d.ts +21 -0
  22. package/cli/explorer/github.js +42 -44
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +90 -95
  26. package/cli/explorer/graphs.js.map +1 -0
  27. package/cli/explorer/picker.d.ts +22 -0
  28. package/cli/explorer/picker.js +150 -0
  29. package/cli/explorer/picker.js.map +1 -0
  30. package/cli/explorer/report.d.ts +85 -0
  31. package/cli/explorer/report.js +60 -0
  32. package/cli/explorer/report.js.map +1 -0
  33. package/cli/explorer/session.d.ts +449 -0
  34. package/cli/explorer/session.js +143 -144
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +465 -482
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +28 -44
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +214 -161
  44. package/cli/main.js.map +1 -0
  45. package/cli/prompt.d.ts +5 -0
  46. package/cli/prompt.js +84 -80
  47. package/cli/prompt.js.map +1 -0
  48. package/cli/scanOptions.d.ts +2 -0
  49. package/cli/scanOptions.js +11 -0
  50. package/cli/scanOptions.js.map +1 -0
  51. package/cli/ui.d.ts +33 -0
  52. package/cli/ui.js +35 -44
  53. package/cli/ui.js.map +1 -0
  54. package/cli/wizard.d.ts +187 -0
  55. package/cli/wizard.js +304 -284
  56. package/cli/wizard.js.map +1 -0
  57. package/package.json +15 -4
  58. package/public/app.d.ts +1 -0
  59. package/public/app.js +1057 -1009
  60. package/public/app.js.map +1 -0
  61. package/public/browser.d.ts +68 -0
  62. package/public/browser.js +2 -0
  63. package/public/browser.js.map +1 -0
  64. package/public/index.html +30 -13
  65. package/public/js/about.d.ts +6 -0
  66. package/public/js/about.js +152 -172
  67. package/public/js/about.js.map +1 -0
  68. package/public/js/aiDraft.d.ts +3 -0
  69. package/public/js/aiDraft.js +116 -124
  70. package/public/js/aiDraft.js.map +1 -0
  71. package/public/js/analysisPanel.d.ts +7 -0
  72. package/public/js/analysisPanel.js +166 -166
  73. package/public/js/analysisPanel.js.map +1 -0
  74. package/public/js/analysisReport.d.ts +38 -0
  75. package/public/js/analysisReport.js +105 -110
  76. package/public/js/analysisReport.js.map +1 -0
  77. package/public/js/api.d.ts +26 -0
  78. package/public/js/api.js +176 -167
  79. package/public/js/api.js.map +1 -0
  80. package/public/js/atlas.d.ts +6 -0
  81. package/public/js/atlas.js +50 -58
  82. package/public/js/atlas.js.map +1 -0
  83. package/public/js/blameView.d.ts +2 -0
  84. package/public/js/blameView.js +36 -37
  85. package/public/js/blameView.js.map +1 -0
  86. package/public/js/codeTab.d.ts +3 -0
  87. package/public/js/codeTab.js +175 -180
  88. package/public/js/codeTab.js.map +1 -0
  89. package/public/js/codeViewer.d.ts +5 -0
  90. package/public/js/codeViewer.js +162 -150
  91. package/public/js/codeViewer.js.map +1 -0
  92. package/public/js/components/FileChip.d.ts +9 -0
  93. package/public/js/components/FileChip.js +45 -49
  94. package/public/js/components/FileChip.js.map +1 -0
  95. package/public/js/components/MetricSparkline.d.ts +7 -0
  96. package/public/js/components/MetricSparkline.js +35 -44
  97. package/public/js/components/MetricSparkline.js.map +1 -0
  98. package/public/js/components/RiskBadge.d.ts +9 -0
  99. package/public/js/components/RiskBadge.js +55 -63
  100. package/public/js/components/RiskBadge.js.map +1 -0
  101. package/public/js/deepAnalysisView.d.ts +99 -0
  102. package/public/js/deepAnalysisView.js +282 -302
  103. package/public/js/deepAnalysisView.js.map +1 -0
  104. package/public/js/diagramPane.d.ts +8 -0
  105. package/public/js/diagramPane.js +133 -135
  106. package/public/js/diagramPane.js.map +1 -0
  107. package/public/js/diffView.d.ts +6 -0
  108. package/public/js/diffView.js +222 -209
  109. package/public/js/diffView.js.map +1 -0
  110. package/public/js/docsView.d.ts +2 -0
  111. package/public/js/docsView.js +441 -442
  112. package/public/js/docsView.js.map +1 -0
  113. package/public/js/dom.d.ts +189 -0
  114. package/public/js/dom.js +5 -0
  115. package/public/js/dom.js.map +1 -0
  116. package/public/js/fileSourceBrowser.d.ts +5 -0
  117. package/public/js/fileSourceBrowser.js +33 -41
  118. package/public/js/fileSourceBrowser.js.map +1 -0
  119. package/public/js/flameGraph.d.ts +5 -0
  120. package/public/js/flameGraph.js +62 -72
  121. package/public/js/flameGraph.js.map +1 -0
  122. package/public/js/forceGraph.d.ts +10 -0
  123. package/public/js/forceGraph.js +581 -556
  124. package/public/js/forceGraph.js.map +1 -0
  125. package/public/js/heatmap.d.ts +4 -0
  126. package/public/js/heatmap.js +142 -164
  127. package/public/js/heatmap.js.map +1 -0
  128. package/public/js/highlight.d.ts +2 -0
  129. package/public/js/highlight.js +116 -107
  130. package/public/js/highlight.js.map +1 -0
  131. package/public/js/html.d.ts +2 -0
  132. package/public/js/html.js +14 -44
  133. package/public/js/html.js.map +1 -0
  134. package/public/js/insightsView.d.ts +5 -0
  135. package/public/js/insightsView.js +93 -111
  136. package/public/js/insightsView.js.map +1 -0
  137. package/public/js/inspector.d.ts +37 -0
  138. package/public/js/inspector.js +416 -445
  139. package/public/js/inspector.js.map +1 -0
  140. package/public/js/llm.d.ts +113 -0
  141. package/public/js/llm.js +233 -272
  142. package/public/js/llm.js.map +1 -0
  143. package/public/js/mapView.d.ts +3 -0
  144. package/public/js/mapView.js +121 -120
  145. package/public/js/mapView.js.map +1 -0
  146. package/public/js/markdown.d.ts +3 -0
  147. package/public/js/markdown.js +84 -91
  148. package/public/js/markdown.js.map +1 -0
  149. package/public/js/mindmap.d.ts +32 -0
  150. package/public/js/mindmap.js +244 -259
  151. package/public/js/mindmap.js.map +1 -0
  152. package/public/js/mobilePanels.d.ts +5 -0
  153. package/public/js/mobilePanels.js +50 -0
  154. package/public/js/mobilePanels.js.map +1 -0
  155. package/public/js/repoFiles.d.ts +12 -0
  156. package/public/js/repoFiles.js +28 -27
  157. package/public/js/repoFiles.js.map +1 -0
  158. package/public/js/reviewView.d.ts +28 -0
  159. package/public/js/reviewView.js +256 -0
  160. package/public/js/reviewView.js.map +1 -0
  161. package/public/js/sbomView.d.ts +3 -0
  162. package/public/js/sbomView.js +59 -67
  163. package/public/js/sbomView.js.map +1 -0
  164. package/public/js/scanCache.d.ts +16 -0
  165. package/public/js/scanCache.js +67 -65
  166. package/public/js/scanCache.js.map +1 -0
  167. package/public/js/search.d.ts +7 -0
  168. package/public/js/search.js +868 -800
  169. package/public/js/search.js.map +1 -0
  170. package/public/js/searchLocal.d.ts +42 -0
  171. package/public/js/searchLocal.js +87 -0
  172. package/public/js/searchLocal.js.map +1 -0
  173. package/public/js/serverSettings.d.ts +5 -0
  174. package/public/js/serverSettings.js +153 -164
  175. package/public/js/serverSettings.js.map +1 -0
  176. package/public/js/state.d.ts +798 -0
  177. package/public/js/state.js +114 -122
  178. package/public/js/state.js.map +1 -0
  179. package/public/js/tour.d.ts +6 -0
  180. package/public/js/tour.js +5 -7
  181. package/public/js/tour.js.map +1 -0
  182. package/public/js/transitions.d.ts +2 -0
  183. package/public/js/transitions.js +9 -10
  184. package/public/js/transitions.js.map +1 -0
  185. package/public/js/tree.d.ts +12 -0
  186. package/public/js/tree.js +157 -154
  187. package/public/js/tree.js.map +1 -0
  188. package/public/js/workflowsView.d.ts +3 -0
  189. package/public/js/workflowsView.js +15 -22
  190. package/public/js/workflowsView.js.map +1 -0
  191. package/public/search.css +495 -0
  192. package/public/styles.css +163 -346
  193. package/public/workbench.css +166 -0
  194. package/server/apiAuth.d.ts +3 -0
  195. package/server/apiAuth.js +18 -20
  196. package/server/apiAuth.js.map +1 -0
  197. package/server/apiDiff.d.ts +2 -0
  198. package/server/apiDiff.js +20 -18
  199. package/server/apiDiff.js.map +1 -0
  200. package/server/apiDocs.d.ts +2 -0
  201. package/server/apiDocs.js +38 -40
  202. package/server/apiDocs.js.map +1 -0
  203. package/server/apiFile.d.ts +1 -0
  204. package/server/apiFile.js +14 -17
  205. package/server/apiFile.js.map +1 -0
  206. package/server/apiGitBlame.d.ts +2 -0
  207. package/server/apiGitBlame.js +50 -51
  208. package/server/apiGitBlame.js.map +1 -0
  209. package/server/apiMcp.d.ts +4 -0
  210. package/server/apiMcp.js +64 -66
  211. package/server/apiMcp.js.map +1 -0
  212. package/server/apiReview.d.ts +2 -0
  213. package/server/apiReview.js +45 -0
  214. package/server/apiReview.js.map +1 -0
  215. package/server/apiScan.d.ts +5 -0
  216. package/server/apiScan.js +90 -71
  217. package/server/apiScan.js.map +1 -0
  218. package/server/apiSearch.d.ts +33 -0
  219. package/server/apiSearch.js +184 -200
  220. package/server/apiSearch.js.map +1 -0
  221. package/server/apiSettings.d.ts +4 -0
  222. package/server/apiSettings.js +84 -85
  223. package/server/apiSettings.js.map +1 -0
  224. package/server/apiTools.d.ts +3 -0
  225. package/server/apiTools.js +55 -56
  226. package/server/apiTools.js.map +1 -0
  227. package/server/auth.d.ts +5 -0
  228. package/server/auth.js +54 -51
  229. package/server/auth.js.map +1 -0
  230. package/server/config.d.ts +42 -0
  231. package/server/config.js +189 -194
  232. package/server/config.js.map +1 -0
  233. package/server/daemon.d.ts +12 -0
  234. package/server/daemon.js +124 -114
  235. package/server/daemon.js.map +1 -0
  236. package/server/fileSourceNode.d.ts +2 -0
  237. package/server/fileSourceNode.js +34 -36
  238. package/server/fileSourceNode.js.map +1 -0
  239. package/server/gitClone.d.ts +9 -0
  240. package/server/gitClone.js +59 -61
  241. package/server/gitClone.js.map +1 -0
  242. package/server/gitDiff.d.ts +36 -0
  243. package/server/gitDiff.js +271 -169
  244. package/server/gitDiff.js.map +1 -0
  245. package/server/gitHistory.d.ts +12 -0
  246. package/server/gitHistory.js +80 -80
  247. package/server/gitHistory.js.map +1 -0
  248. package/server/gitRemote.d.ts +12 -0
  249. package/server/gitRemote.js +37 -38
  250. package/server/gitRemote.js.map +1 -0
  251. package/server/htmlText.d.ts +4 -0
  252. package/server/htmlText.js +16 -23
  253. package/server/htmlText.js.map +1 -0
  254. package/server/http.d.ts +5 -0
  255. package/server/http.js +27 -30
  256. package/server/http.js.map +1 -0
  257. package/server/httpGuards.d.ts +2 -0
  258. package/server/httpGuards.js +47 -43
  259. package/server/httpGuards.js.map +1 -0
  260. package/server/https.d.ts +34 -0
  261. package/server/https.js +121 -111
  262. package/server/https.js.map +1 -0
  263. package/server/index.d.ts +40 -0
  264. package/server/index.js +139 -147
  265. package/server/index.js.map +1 -0
  266. package/server/layout.d.ts +26 -0
  267. package/server/layout.js +59 -64
  268. package/server/layout.js.map +1 -0
  269. package/server/llmProxy.d.ts +3 -0
  270. package/server/llmProxy.js +137 -135
  271. package/server/llmProxy.js.map +1 -0
  272. package/server/logger.d.ts +38 -0
  273. package/server/logger.js +198 -211
  274. package/server/logger.js.map +1 -0
  275. package/server/mcp/analysis.d.ts +29 -0
  276. package/server/mcp/analysis.js +99 -120
  277. package/server/mcp/analysis.js.map +1 -0
  278. package/server/mcp/http.d.ts +9 -0
  279. package/server/mcp/http.js +128 -137
  280. package/server/mcp/http.js.map +1 -0
  281. package/server/mcp/runner.d.ts +68 -0
  282. package/server/mcp/runner.js +208 -218
  283. package/server/mcp/runner.js.map +1 -0
  284. package/server/mcp/server.d.ts +29 -0
  285. package/server/mcp/server.js +166 -179
  286. package/server/mcp/server.js.map +1 -0
  287. package/server/mcp/standalone.d.ts +1 -0
  288. package/server/mcp/standalone.js +8 -10
  289. package/server/mcp/standalone.js.map +1 -0
  290. package/server/mcp/tools.d.ts +2020 -0
  291. package/server/mcp/tools.js +523 -574
  292. package/server/mcp/tools.js.map +1 -0
  293. package/server/paths.d.ts +3 -0
  294. package/server/paths.js +17 -15
  295. package/server/paths.js.map +1 -0
  296. package/server/pidfile.d.ts +9 -0
  297. package/server/pidfile.js +43 -45
  298. package/server/pidfile.js.map +1 -0
  299. package/server/review.d.ts +5 -0
  300. package/server/review.js +35 -0
  301. package/server/review.js.map +1 -0
  302. package/server/router.d.ts +33 -0
  303. package/server/router.js +191 -197
  304. package/server/router.js.map +1 -0
  305. package/server/scanRequest.d.ts +3 -0
  306. package/server/scanRequest.js +36 -0
  307. package/server/scanRequest.js.map +1 -0
  308. package/server/searchIndex.d.ts +17 -0
  309. package/server/searchIndex.js +83 -80
  310. package/server/searchIndex.js.map +1 -0
  311. package/server/sessions.d.ts +14 -0
  312. package/server/sessions.js +62 -70
  313. package/server/sessions.js.map +1 -0
  314. package/server/startup.d.ts +118 -0
  315. package/server/startup.js +143 -148
  316. package/server/startup.js.map +1 -0
  317. package/server/static.d.ts +6 -0
  318. package/server/static.js +28 -31
  319. package/server/static.js.map +1 -0
  320. package/server/tools/install.d.ts +4 -0
  321. package/server/tools/install.js +176 -185
  322. package/server/tools/install.js.map +1 -0
  323. package/server/tools/parse.d.ts +8 -0
  324. package/server/tools/parse.js +112 -114
  325. package/server/tools/parse.js.map +1 -0
  326. package/server/tools/platform.d.ts +9 -0
  327. package/server/tools/platform.js +49 -47
  328. package/server/tools/platform.js.map +1 -0
  329. package/server/tools/registry.d.ts +137 -0
  330. package/server/tools/registry.js +173 -172
  331. package/server/tools/registry.js.map +1 -0
  332. package/server/tools/scan.d.ts +34 -0
  333. package/server/tools/scan.js +89 -98
  334. package/server/tools/scan.js.map +1 -0
  335. package/server/tools.d.ts +34 -0
  336. package/server/tools.js +94 -107
  337. package/server/tools.js.map +1 -0
  338. package/server/tunnel.d.ts +29 -0
  339. package/server/tunnel.js +61 -66
  340. package/server/tunnel.js.map +1 -0
  341. package/shared/analyzer/docs.d.ts +16 -0
  342. package/shared/analyzer/docs.js +99 -93
  343. package/shared/analyzer/docs.js.map +1 -0
  344. package/shared/analyzer/explainLocal.d.ts +4 -0
  345. package/shared/analyzer/explainLocal.js +122 -142
  346. package/shared/analyzer/explainLocal.js.map +1 -0
  347. package/shared/analyzer/github.d.ts +37 -0
  348. package/shared/analyzer/github.js +41 -43
  349. package/shared/analyzer/github.js.map +1 -0
  350. package/shared/analyzer/graph.d.ts +41 -0
  351. package/shared/analyzer/graph.js +393 -400
  352. package/shared/analyzer/graph.js.map +1 -0
  353. package/shared/analyzer/health.d.ts +33 -0
  354. package/shared/analyzer/health.js +197 -193
  355. package/shared/analyzer/health.js.map +1 -0
  356. package/shared/analyzer/history.d.ts +29 -0
  357. package/shared/analyzer/history.js +110 -111
  358. package/shared/analyzer/history.js.map +1 -0
  359. package/shared/analyzer/jsonConfig.d.ts +2 -0
  360. package/shared/analyzer/jsonConfig.js +61 -0
  361. package/shared/analyzer/jsonConfig.js.map +1 -0
  362. package/shared/analyzer/languages/csharp.d.ts +26 -0
  363. package/shared/analyzer/languages/csharp.js +83 -88
  364. package/shared/analyzer/languages/csharp.js.map +1 -0
  365. package/shared/analyzer/languages/generic.d.ts +23 -0
  366. package/shared/analyzer/languages/generic.js +94 -105
  367. package/shared/analyzer/languages/generic.js.map +1 -0
  368. package/shared/analyzer/languages/go.d.ts +24 -0
  369. package/shared/analyzer/languages/go.js +45 -54
  370. package/shared/analyzer/languages/go.js.map +1 -0
  371. package/shared/analyzer/languages/index.d.ts +6 -0
  372. package/shared/analyzer/languages/index.js +19 -20
  373. package/shared/analyzer/languages/index.js.map +1 -0
  374. package/shared/analyzer/languages/java.d.ts +20 -0
  375. package/shared/analyzer/languages/java.js +73 -78
  376. package/shared/analyzer/languages/java.js.map +1 -0
  377. package/shared/analyzer/languages/javascript.d.ts +12 -0
  378. package/shared/analyzer/languages/javascript.js +258 -209
  379. package/shared/analyzer/languages/javascript.js.map +1 -0
  380. package/shared/analyzer/languages/python.d.ts +23 -0
  381. package/shared/analyzer/languages/python.js +92 -100
  382. package/shared/analyzer/languages/python.js.map +1 -0
  383. package/shared/analyzer/languages/rust.d.ts +17 -0
  384. package/shared/analyzer/languages/rust.js +96 -98
  385. package/shared/analyzer/languages/rust.js.map +1 -0
  386. package/shared/analyzer/languages/typescript.d.ts +11 -0
  387. package/shared/analyzer/languages/typescript.js +117 -116
  388. package/shared/analyzer/languages/typescript.js.map +1 -0
  389. package/shared/analyzer/licenses.d.ts +18 -0
  390. package/shared/analyzer/licenses.js +130 -133
  391. package/shared/analyzer/licenses.js.map +1 -0
  392. package/shared/analyzer/metrics.d.ts +20 -0
  393. package/shared/analyzer/metrics.js +112 -104
  394. package/shared/analyzer/metrics.js.map +1 -0
  395. package/shared/analyzer/pathUtil.d.ts +10 -0
  396. package/shared/analyzer/pathUtil.js +29 -35
  397. package/shared/analyzer/pathUtil.js.map +1 -0
  398. package/shared/analyzer/patterns.d.ts +11 -0
  399. package/shared/analyzer/patterns.js +231 -253
  400. package/shared/analyzer/patterns.js.map +1 -0
  401. package/shared/analyzer/scan.d.ts +62 -0
  402. package/shared/analyzer/scan.js +451 -442
  403. package/shared/analyzer/scan.js.map +1 -0
  404. package/shared/analyzer/scanControl.d.ts +11 -0
  405. package/shared/analyzer/scanControl.js +62 -0
  406. package/shared/analyzer/scanControl.js.map +1 -0
  407. package/shared/analyzer/security.d.ts +18 -0
  408. package/shared/analyzer/security.js +159 -159
  409. package/shared/analyzer/security.js.map +1 -0
  410. package/shared/analyzer/services.d.ts +5 -0
  411. package/shared/analyzer/services.js +141 -138
  412. package/shared/analyzer/services.js.map +1 -0
  413. package/shared/analyzer/stack.d.ts +6 -0
  414. package/shared/analyzer/stack.js +134 -141
  415. package/shared/analyzer/stack.js.map +1 -0
  416. package/shared/analyzer/tour.d.ts +2 -0
  417. package/shared/analyzer/tour.js +45 -53
  418. package/shared/analyzer/tour.js.map +1 -0
  419. package/shared/analyzer/util.d.ts +8 -0
  420. package/shared/analyzer/util.js +130 -76
  421. package/shared/analyzer/util.js.map +1 -0
  422. package/shared/analyzer/workflows.d.ts +8 -0
  423. package/shared/analyzer/workflows.js +139 -134
  424. package/shared/analyzer/workflows.js.map +1 -0
  425. package/shared/contracts.d.ts +250 -0
  426. package/shared/contracts.js +2 -0
  427. package/shared/contracts.js.map +1 -0
  428. package/shared/diagram/aiFacts.d.ts +35 -0
  429. package/shared/diagram/aiFacts.js +102 -105
  430. package/shared/diagram/aiFacts.js.map +1 -0
  431. package/shared/diagram/aiMermaid.d.ts +5 -0
  432. package/shared/diagram/aiMermaid.js +46 -45
  433. package/shared/diagram/aiMermaid.js.map +1 -0
  434. package/shared/diagram/atlas.d.ts +16 -0
  435. package/shared/diagram/atlas.js +51 -60
  436. package/shared/diagram/atlas.js.map +1 -0
  437. package/shared/diagram/mermaid.d.ts +43 -0
  438. package/shared/diagram/mermaid.js +348 -370
  439. package/shared/diagram/mermaid.js.map +1 -0
  440. package/shared/review/contracts.d.ts +95 -0
  441. package/shared/review/contracts.js +2 -0
  442. package/shared/review/contracts.js.map +1 -0
  443. package/shared/review/review.d.ts +10 -0
  444. package/shared/review/review.js +184 -0
  445. package/shared/review/review.js.map +1 -0
  446. package/shared/search/query.d.ts +32 -0
  447. package/shared/search/query.js +395 -388
  448. package/shared/search/query.js.map +1 -0
@@ -22,192 +22,183 @@
22
22
  // held per-connection, so a session id would gate nothing that the localhost bind
23
23
  // does not already gate — and pretending to a security model this process does not
24
24
  // have would be worse than not claiming one.
25
-
26
25
  import http from 'node:http';
27
-
28
26
  import { handle, PROTOCOL_VERSION, SERVER_INFO } from './server.js';
29
27
  import { toolDefinitions } from './tools.js';
30
-
31
28
  export const HTTP_HOST = '127.0.0.1';
32
29
  export const DEFAULT_PORT = 8790;
33
30
  const MAX_BODY = 4 * 1024 * 1024; // a tools/call argument list, not a file upload
34
-
35
31
  // A POST without this in its Accept header is not an MCP client. The spec requires
36
32
  // clients to send both, and enforcing it is how a stray browser `fetch` to this
37
33
  // port is turned away at the door.
38
34
  function acceptsBoth(req) {
39
- const accept = String(req.headers.accept || '');
40
- return accept.includes('application/json') && accept.includes('text/event-stream');
35
+ const accept = String(req.headers.accept || '');
36
+ return accept.includes('application/json') && accept.includes('text/event-stream');
41
37
  }
42
-
43
38
  // The spec's DNS-rebinding defence: the Host header must name a loopback address
44
39
  // this server actually bound to. A rebinding attack sends `Host: evil.com` with
45
40
  // the DNS pointing at 127.0.0.1, so the name is the thing to check, not the
46
41
  // resolved address.
47
42
  function hostAllowed(hostHeader) {
48
- if (!hostHeader) return false;
49
- const host = String(hostHeader).replace(/:\d+$/, '');
50
- return host === '127.0.0.1' || host === 'localhost' || host === '[::1]' || host === '::1';
43
+ if (!hostHeader)
44
+ return false;
45
+ const host = String(hostHeader).replace(/:\d+$/, '');
46
+ return host === '127.0.0.1' || host === 'localhost' || host === '[::1]' || host === '::1';
51
47
  }
52
-
53
48
  // Origin, when present, must also be loopback. A request with no Origin at all is
54
49
  // a non-browser client — a harness, curl, a test — and those are the intended
55
50
  // callers, so their absence is not suspicious.
56
51
  function originAllowed(req) {
57
- const origin = req.headers.origin;
58
- if (!origin) return true;
59
- try {
60
- const { hostname } = new URL(String(origin));
61
- return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '[::1]';
62
- } catch {
63
- return false;
64
- }
52
+ const origin = req.headers.origin;
53
+ if (!origin)
54
+ return true;
55
+ try {
56
+ const { hostname } = new URL(String(origin));
57
+ return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '[::1]';
58
+ }
59
+ catch {
60
+ return false;
61
+ }
65
62
  }
66
-
67
63
  function guard(req, res) {
68
- if (!hostAllowed(req.headers.host)) {
69
- sendJSON(res, 421, { error: 'This endpoint is served on localhost only.' });
70
- return false;
71
- }
72
- if (!originAllowed(req)) {
73
- sendJSON(res, 403, { error: 'Cross-origin requests are not accepted.' });
74
- return false;
75
- }
76
- return true;
64
+ if (!hostAllowed(req.headers.host)) {
65
+ sendJSON(res, 421, { error: 'This endpoint is served on localhost only.' });
66
+ return false;
67
+ }
68
+ if (!originAllowed(req)) {
69
+ sendJSON(res, 403, { error: 'Cross-origin requests are not accepted.' });
70
+ return false;
71
+ }
72
+ return true;
77
73
  }
78
-
79
74
  function sendJSON(res, status, value, headers = {}) {
80
- const body = JSON.stringify(value);
81
- res.writeHead(status, {
82
- 'content-type': 'application/json',
83
- 'content-length': Buffer.byteLength(body),
84
- ...headers,
85
- });
86
- res.end(body);
75
+ const body = JSON.stringify(value);
76
+ res.writeHead(status, {
77
+ 'content-type': 'application/json',
78
+ 'content-length': Buffer.byteLength(body),
79
+ ...headers,
80
+ });
81
+ res.end(body);
87
82
  }
88
-
89
83
  // The 2025-06-18 spec lets a server answer a request with a plain JSON body when
90
84
  // it has nothing server-initiated to send. Sending both JSON and an event stream
91
85
  // would make a client that honours `application/json` wait forever for a stream
92
86
  // that never comes.
93
87
  function sendStreamable(res, message) {
94
- const body = JSON.stringify(message);
95
- res.writeHead(200, {
96
- 'content-type': 'application/json',
97
- 'content-length': Buffer.byteLength(body),
98
- });
99
- res.end(body);
88
+ const body = JSON.stringify(message);
89
+ res.writeHead(200, {
90
+ 'content-type': 'application/json',
91
+ 'content-length': Buffer.byteLength(body),
92
+ });
93
+ res.end(body);
100
94
  }
101
-
102
95
  function readBody(req) {
103
- return new Promise((resolve, reject) => {
104
- const chunks = [];
105
- let size = 0;
106
- req.on('data', (chunk) => {
107
- size += chunk.length;
108
- if (size > MAX_BODY) {
109
- reject(new Error('Request body too large.'));
110
- req.destroy();
111
- return;
112
- }
113
- chunks.push(chunk);
96
+ return new Promise((resolve, reject) => {
97
+ const chunks = [];
98
+ let size = 0;
99
+ req.on('data', (chunk) => {
100
+ size += chunk.length;
101
+ if (size > MAX_BODY) {
102
+ reject(new Error('Request body too large.'));
103
+ req.destroy();
104
+ return;
105
+ }
106
+ chunks.push(chunk);
107
+ });
108
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
109
+ req.on('error', reject);
114
110
  });
115
- req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
116
- req.on('error', reject);
117
- });
118
111
  }
119
-
120
112
  async function onPost(req, res) {
121
- if (!acceptsBoth(req)) {
122
- return sendJSON(res, 406, {
123
- error: 'An MCP client must Accept: application/json and text/event-stream.',
124
- });
125
- }
126
-
127
- let msg;
128
- try {
129
- msg = JSON.parse(await readBody(req));
130
- } catch (err) {
131
- return sendJSON(res, 400, {
132
- jsonrpc: '2.0', id: null,
133
- error: { code: -32700, message: `Could not parse the request: ${err.message}` },
134
- });
135
- }
136
-
137
- // A batch is legal JSON-RPC, and answering it in order keeps the client simple.
138
- // Notifications inside it produce no entries, which is correct: `handle` returns
139
- // undefined for them and they are filtered out here.
140
- if (Array.isArray(msg)) {
141
- const replies = [];
142
- for (const one of msg) {
143
- const reply = await handle(one);
144
- if (reply) replies.push(reply);
113
+ if (!acceptsBoth(req)) {
114
+ return sendJSON(res, 406, {
115
+ error: 'An MCP client must Accept: application/json and text/event-stream.',
116
+ });
145
117
  }
146
- if (!replies.length) {
147
- res.writeHead(202).end();
148
- return undefined;
118
+ let msg;
119
+ try {
120
+ msg = JSON.parse(String(await readBody(req)));
149
121
  }
150
- return sendStreamable(res, replies);
151
- }
152
-
153
- const reply = await handle(msg);
154
- // A lone notification: the spec says answer 202 with no body.
155
- if (!reply) {
156
- res.writeHead(202).end();
157
- return undefined;
158
- }
159
- return sendStreamable(res, reply);
122
+ catch (err) {
123
+ return sendJSON(res, 400, {
124
+ jsonrpc: '2.0', id: null,
125
+ error: { code: -32700, message: `Could not parse the request: ${err.message}` },
126
+ });
127
+ }
128
+ // A batch is legal JSON-RPC, and answering it in order keeps the client simple.
129
+ // Notifications inside it produce no entries, which is correct: `handle` returns
130
+ // undefined for them and they are filtered out here.
131
+ if (Array.isArray(msg)) {
132
+ const replies = [];
133
+ for (const one of msg) {
134
+ const reply = await handle(one);
135
+ if (reply)
136
+ replies.push(reply);
137
+ }
138
+ if (!replies.length) {
139
+ res.writeHead(202).end();
140
+ return undefined;
141
+ }
142
+ return sendStreamable(res, replies);
143
+ }
144
+ const reply = await handle(msg);
145
+ // A lone notification: the spec says answer 202 with no body.
146
+ if (!reply) {
147
+ res.writeHead(202).end();
148
+ return undefined;
149
+ }
150
+ return sendStreamable(res, reply);
160
151
  }
161
-
162
152
  function onGet(res) {
163
- // Without SSE there is no stream to open. 405 is the honest answer: this server
164
- // does not offer the GET half of the transport, and a client that wants
165
- // server-initiated messages should have used stdio.
166
- res.writeHead(405, { allow: 'POST', 'content-type': 'application/json' });
167
- res.end(JSON.stringify({
168
- error: 'This server does not offer server-initiated streams. Use the stdio transport, or POST to this endpoint.',
169
- }));
153
+ // Without SSE there is no stream to open. 405 is the honest answer: this server
154
+ // does not offer the GET half of the transport, and a client that wants
155
+ // server-initiated messages should have used stdio.
156
+ res.writeHead(405, { allow: 'POST', 'content-type': 'application/json' });
157
+ res.end(JSON.stringify({
158
+ error: 'This server does not offer server-initiated streams. Use the stdio transport, or POST to this endpoint.',
159
+ }));
170
160
  }
171
-
172
161
  export function handleMcpHttpRequest(req, res) {
173
- if (!guard(req, res)) return undefined;
174
- if (req.method === 'POST') return onPost(req, res);
175
- if (req.method === 'GET') return onGet(res);
176
- if (req.method === 'DELETE') {
177
- // No sessions exist, so there is nothing to delete. Saying so keeps a client
178
- // that cleans up politely from logging an error on the way out.
179
- res.writeHead(200, { 'content-type': 'application/json' });
180
- res.end(JSON.stringify({ ok: true }));
162
+ if (!guard(req, res))
163
+ return undefined;
164
+ if (req.method === 'POST')
165
+ return onPost(req, res);
166
+ if (req.method === 'GET')
167
+ return onGet(res);
168
+ if (req.method === 'DELETE') {
169
+ // No sessions exist, so there is nothing to delete. Saying so keeps a client
170
+ // that cleans up politely from logging an error on the way out.
171
+ res.writeHead(200, { 'content-type': 'application/json' });
172
+ res.end(JSON.stringify({ ok: true }));
173
+ return undefined;
174
+ }
175
+ res.writeHead(405, { allow: 'POST, GET, DELETE' }).end();
181
176
  return undefined;
182
- }
183
- res.writeHead(405, { allow: 'POST, GET, DELETE' }).end();
184
- return undefined;
185
177
  }
186
-
187
178
  /**
188
179
  * Start the Streamable HTTP transport. Returns `{ url, port, server, close }`, and
189
180
  * `port` is the port actually bound — which matters because the caller may have
190
181
  * asked for 0 and gets a free one back.
191
182
  */
192
183
  export function createHttpTransport({ port = DEFAULT_PORT, host = HTTP_HOST } = {}) {
193
- const server = http.createServer(handleMcpHttpRequest);
194
- // A long tool call is a scan of a large repository. The default 5s headers
195
- // timeout would cut the request off before the body finished arriving; the
196
- // request timeout covers the whole exchange and is generous on purpose, since
197
- // the person who asked for it is waiting for it.
198
- server.headersTimeout = 30_000;
199
- server.requestTimeout = 600_000;
200
-
201
- return new Promise((resolve, reject) => {
202
- server.once('error', reject);
203
- server.listen(port, host, () => {
204
- const actual = server.address().port;
205
- resolve({
206
- url: `http://${host}:${actual}/mcp`,
207
- port: actual,
208
- server,
209
- close: () => new Promise((done) => server.close(done)),
210
- });
184
+ const server = http.createServer(handleMcpHttpRequest);
185
+ // A long tool call is a scan of a large repository. The default 5s headers
186
+ // timeout would cut the request off before the body finished arriving; the
187
+ // request timeout covers the whole exchange and is generous on purpose, since
188
+ // the person who asked for it is waiting for it.
189
+ server.headersTimeout = 30_000;
190
+ server.requestTimeout = 600_000;
191
+ return new Promise((resolve, reject) => {
192
+ server.once('error', reject);
193
+ server.listen(port, host, () => {
194
+ const actual = server.address().port;
195
+ resolve({
196
+ url: `http://${host}:${actual}/mcp`,
197
+ port: actual,
198
+ server,
199
+ close: () => new Promise((done) => server.close(done)),
200
+ });
201
+ });
211
202
  });
212
- });
213
203
  }
204
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/server/mcp/http.ts"],"names":[],"mappings":"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","sourcesContent":["// The Streamable HTTP transport (MCP 2025-06-18), on one endpoint that answers\n// POST and GET.\n//\n// This exists because of the button. A stdio server is spawned *by* its client, so\n// a child this app started has nobody to talk to it — starting one from the UI\n// would launch a process no harness could ever reach. Over HTTP the server is a\n// server: the button starts it, a harness connects to it, and stopping it closes\n// the door for everyone. Both transports are offered because they suit different\n// clients, and the spec says clients should support stdio where possible.\n//\n// The security section of the spec is not optional here, and this server has no\n// authentication at all, so the three protections it names are all the protection\n// there is:\n// * Bind 127.0.0.1 only. Never 0.0.0.0 — this process will read any folder it\n// is asked to, and a LAN-reachable copy of that is not something to ship by\n// accident.\n// * Validate `Origin` on every request, so a page on another site cannot drive\n// it on the person's behalf.\n// * Validate `Host`, so a rebinding name cannot resolve here either.\n//\n// What is deliberately *not* implemented: OAuth and `Mcp-Session-Id`. Nothing is\n// held per-connection, so a session id would gate nothing that the localhost bind\n// does not already gate — and pretending to a security model this process does not\n// have would be worse than not claiming one.\n\nimport http from 'node:http';\n\nimport { handle, PROTOCOL_VERSION, SERVER_INFO } from './server.js';\nimport { toolDefinitions } from './tools.js';\n\nexport const HTTP_HOST = '127.0.0.1';\nexport const DEFAULT_PORT = 8790;\nconst MAX_BODY = 4 * 1024 * 1024; // a tools/call argument list, not a file upload\n\n// A POST without this in its Accept header is not an MCP client. The spec requires\n// clients to send both, and enforcing it is how a stray browser `fetch` to this\n// port is turned away at the door.\nfunction acceptsBoth(req) {\n const accept = String(req.headers.accept || '');\n return accept.includes('application/json') && accept.includes('text/event-stream');\n}\n\n// The spec's DNS-rebinding defence: the Host header must name a loopback address\n// this server actually bound to. A rebinding attack sends `Host: evil.com` with\n// the DNS pointing at 127.0.0.1, so the name is the thing to check, not the\n// resolved address.\nfunction hostAllowed(hostHeader) {\n if (!hostHeader) return false;\n const host = String(hostHeader).replace(/:\\d+$/, '');\n return host === '127.0.0.1' || host === 'localhost' || host === '[::1]' || host === '::1';\n}\n\n// Origin, when present, must also be loopback. A request with no Origin at all is\n// a non-browser client — a harness, curl, a test — and those are the intended\n// callers, so their absence is not suspicious.\nfunction originAllowed(req) {\n const origin = req.headers.origin;\n if (!origin) return true;\n try {\n const { hostname } = new URL(String(origin));\n return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '[::1]';\n } catch {\n return false;\n }\n}\n\nfunction guard(req, res) {\n if (!hostAllowed(req.headers.host)) {\n sendJSON(res, 421, { error: 'This endpoint is served on localhost only.' });\n return false;\n }\n if (!originAllowed(req)) {\n sendJSON(res, 403, { error: 'Cross-origin requests are not accepted.' });\n return false;\n }\n return true;\n}\n\nfunction sendJSON(res, status, value, headers: Record<string, any> = {}) {\n const body = JSON.stringify(value);\n res.writeHead(status, {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n ...headers,\n });\n res.end(body);\n}\n\n// The 2025-06-18 spec lets a server answer a request with a plain JSON body when\n// it has nothing server-initiated to send. Sending both JSON and an event stream\n// would make a client that honours `application/json` wait forever for a stream\n// that never comes.\nfunction sendStreamable(res, message) {\n const body = JSON.stringify(message);\n res.writeHead(200, {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n });\n res.end(body);\n}\n\nfunction readBody(req) {\n return new Promise((resolve, reject) => {\n const chunks = [];\n let size = 0;\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > MAX_BODY) {\n reject(new Error('Request body too large.'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n}\n\nasync function onPost(req, res) {\n if (!acceptsBoth(req)) {\n return sendJSON(res, 406, {\n error: 'An MCP client must Accept: application/json and text/event-stream.',\n });\n }\n\n let msg;\n try {\n msg = JSON.parse(String(await readBody(req)));\n } catch (err) {\n return sendJSON(res, 400, {\n jsonrpc: '2.0', id: null,\n error: { code: -32700, message: `Could not parse the request: ${err.message}` },\n });\n }\n\n // A batch is legal JSON-RPC, and answering it in order keeps the client simple.\n // Notifications inside it produce no entries, which is correct: `handle` returns\n // undefined for them and they are filtered out here.\n if (Array.isArray(msg)) {\n const replies = [];\n for (const one of msg) {\n const reply = await handle(one);\n if (reply) replies.push(reply);\n }\n if (!replies.length) {\n res.writeHead(202).end();\n return undefined;\n }\n return sendStreamable(res, replies);\n }\n\n const reply = await handle(msg);\n // A lone notification: the spec says answer 202 with no body.\n if (!reply) {\n res.writeHead(202).end();\n return undefined;\n }\n return sendStreamable(res, reply);\n}\n\nfunction onGet(res) {\n // Without SSE there is no stream to open. 405 is the honest answer: this server\n // does not offer the GET half of the transport, and a client that wants\n // server-initiated messages should have used stdio.\n res.writeHead(405, { allow: 'POST', 'content-type': 'application/json' });\n res.end(JSON.stringify({\n error: 'This server does not offer server-initiated streams. Use the stdio transport, or POST to this endpoint.',\n }));\n}\n\nexport function handleMcpHttpRequest(req, res) {\n if (!guard(req, res)) return undefined;\n if (req.method === 'POST') return onPost(req, res);\n if (req.method === 'GET') return onGet(res);\n if (req.method === 'DELETE') {\n // No sessions exist, so there is nothing to delete. Saying so keeps a client\n // that cleans up politely from logging an error on the way out.\n res.writeHead(200, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ ok: true }));\n return undefined;\n }\n res.writeHead(405, { allow: 'POST, GET, DELETE' }).end();\n return undefined;\n}\n\n/**\n * Start the Streamable HTTP transport. Returns `{ url, port, server, close }`, and\n * `port` is the port actually bound — which matters because the caller may have\n * asked for 0 and gets a free one back.\n */\nexport function createHttpTransport({ port = DEFAULT_PORT, host = HTTP_HOST }: Record<string, any> = {}) {\n const server = http.createServer(handleMcpHttpRequest);\n // A long tool call is a scan of a large repository. The default 5s headers\n // timeout would cut the request off before the body finished arriving; the\n // request timeout covers the whole exchange and is generous on purpose, since\n // the person who asked for it is waiting for it.\n server.headersTimeout = 30_000;\n server.requestTimeout = 600_000;\n\n return new Promise((resolve, reject) => {\n server.once('error', reject);\n server.listen(port, host, () => {\n const actual = (server.address() as import('node:net').AddressInfo).port;\n resolve({\n url: `http://${host}:${actual}/mcp`,\n port: actual,\n server,\n close: () => new Promise((done) => server.close(done)),\n });\n });\n });\n}\n"]}
@@ -0,0 +1,68 @@
1
+ export declare const REPO_ROOT: string;
2
+ export declare const ENTRY: string;
3
+ export declare function mcpCommand(): string;
4
+ export declare function mcpEntryPoint(): string;
5
+ export declare function mcpConfig(override: any): {
6
+ command: any;
7
+ args: any;
8
+ cwd: any;
9
+ };
10
+ export declare class McpRunner {
11
+ commandOverride: any;
12
+ child: any;
13
+ state: string;
14
+ startedAt: any;
15
+ lastError: string;
16
+ log: any[];
17
+ onLog: any;
18
+ get running(): boolean;
19
+ note(line: any): void;
20
+ constructor({ onLog, command, args, cwd }?: Record<string, any>);
21
+ start(): Promise<{
22
+ transport: string;
23
+ toolCount: number;
24
+ tools: string[];
25
+ cachedRepositories: any[];
26
+ lastRoot: any;
27
+ analyzers: Record<string, any>;
28
+ state: string;
29
+ running: boolean;
30
+ pid: any;
31
+ startedAt: any;
32
+ uptimeMs: number;
33
+ lastError: string;
34
+ log: any[];
35
+ }>;
36
+ handshake(exited: any): Promise<unknown>;
37
+ stop(): Promise<{
38
+ transport: string;
39
+ toolCount: number;
40
+ tools: string[];
41
+ cachedRepositories: any[];
42
+ lastRoot: any;
43
+ analyzers: Record<string, any>;
44
+ state: string;
45
+ running: boolean;
46
+ pid: any;
47
+ startedAt: any;
48
+ uptimeMs: number;
49
+ lastError: string;
50
+ log: any[];
51
+ }>;
52
+ status(): {
53
+ transport: string;
54
+ toolCount: number;
55
+ tools: string[];
56
+ cachedRepositories: any[];
57
+ lastRoot: any;
58
+ analyzers: Record<string, any>;
59
+ state: string;
60
+ running: boolean;
61
+ pid: any;
62
+ startedAt: any;
63
+ uptimeMs: number;
64
+ lastError: string;
65
+ log: any[];
66
+ };
67
+ }
68
+ export declare function createMcpRunner(opts: any): McpRunner;