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
@@ -16,24 +16,20 @@
16
16
  // * A tool that throws is answered with a *result* carrying `isError: true`,
17
17
  // not a JSON-RPC error. That is what puts the message in front of the model
18
18
  // so it can correct itself; a protocol error just fails the turn.
19
-
20
19
  import { toolDefinitions, callTool, findTool } from './tools.js';
21
20
  import { ToolError } from './analysis.js';
22
-
23
21
  export const PROTOCOL_VERSION = '2025-06-18';
24
22
  export const SERVER_INFO = {
25
- name: 'onboarder',
26
- version: '1.0.0',
27
- title: 'Onboarder',
28
- instructions:
29
- 'Onboarder explains a codebase. Start with onboarder_scan on a repository path; '
30
- + 'it returns a written overview, the entry points, the most depended-upon files, and '
31
- + 'any dependency cycles. Then use onboarder_tour for a reading order, onboarder_search '
32
- + 'to find things by name, onboarder_explain_file for one file, and onboarder_read_file '
33
- + 'for raw source. Every tool also takes `path`; omit it to keep working on the last '
34
- + 'repository scanned. The repository is read, never written.',
23
+ name: 'onboarder',
24
+ version: '1.0.0',
25
+ title: 'Onboarder',
26
+ instructions: 'Onboarder explains a codebase. Start with onboarder_scan on a repository path; '
27
+ + 'it returns a written overview, the entry points, the most depended-upon files, and '
28
+ + 'any dependency cycles. Then use onboarder_tour for a reading order, onboarder_search '
29
+ + 'to find things by name, onboarder_explain_file for one file, and onboarder_read_file '
30
+ + 'for raw source. Every tool also takes `path`; omit it to keep working on the last '
31
+ + 'repository scanned. The repository is read, never written.',
35
32
  };
36
-
37
33
  // JSON-RPC error codes. Only the first two are protocol-level; the rest are
38
34
  // conventional in MCP and keep a misbehaving client from parsing a server bug as
39
35
  // a server bug it caused.
@@ -41,201 +37,192 @@ const PARSE_ERROR = -32700;
41
37
  const INVALID_REQUEST = -32600;
42
38
  const METHOD_NOT_FOUND = -32601;
43
39
  const INVALID_PARAMS = -32602;
44
-
45
40
  function result(id, value) {
46
- return { jsonrpc: '2.0', id, result: value };
41
+ return { jsonrpc: '2.0', id, result: value };
47
42
  }
48
-
49
43
  function failure(id, code, message, data) {
50
- const error = { code, message };
51
- if (data !== undefined) error.data = data;
52
- return { jsonrpc: '2.0', id, error };
44
+ const error = { code, message };
45
+ if (data !== undefined)
46
+ error.data = data;
47
+ return { jsonrpc: '2.0', id, error };
53
48
  }
54
-
55
49
  // A tool error and an internal error are different things. A `ToolError` is a
56
50
  // sentence the model can act on — "that path is outside the repo" — so it becomes
57
51
  // an isError result with that sentence intact. Anything else is a bug, and saying
58
52
  // so plainly beats pretending it was the caller's fault.
59
53
  async function callOne(name, args) {
60
- const tool = findTool(name);
61
- if (!tool) {
62
- return {
63
- isError: true,
64
- content: [{ type: 'text', text: `No tool called "${name}". Call tools/list to see what is available.` }],
65
- };
66
- }
67
- try {
68
- const value = await tool.run(args || {});
69
- // MCP content is a list of blocks. A tool that returns structured data sends
70
- // it as JSON text plus the native `structuredContent` field, which is what
71
- // typed clients read; the text block is what everything else falls back to.
72
- return {
73
- content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],
74
- structuredContent: value,
75
- isError: false,
76
- };
77
- } catch (err) {
78
- if (err instanceof ToolError) {
79
- return { isError: true, content: [{ type: 'text', text: err.message }] };
54
+ const tool = findTool(name);
55
+ if (!tool) {
56
+ return {
57
+ isError: true,
58
+ content: [{ type: 'text', text: `No tool called "${name}". Call tools/list to see what is available.` }],
59
+ };
60
+ }
61
+ try {
62
+ const value = await tool.run(args || {});
63
+ // MCP content is a list of blocks. A tool that returns structured data sends
64
+ // it as JSON text plus the native `structuredContent` field, which is what
65
+ // typed clients read; the text block is what everything else falls back to.
66
+ return {
67
+ content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],
68
+ structuredContent: value,
69
+ isError: false,
70
+ };
71
+ }
72
+ catch (err) {
73
+ if (err instanceof ToolError) {
74
+ return { isError: true, content: [{ type: 'text', text: err.message }] };
75
+ }
76
+ // Unexpected. Report the message, not the stack: the caller is a model on the
77
+ // other end of a pipe, and a stack trace is noise. The full error is on the
78
+ // child process's stderr, which is where a human debugging this will look.
79
+ console.error('[onboarder-mcp] tool failed:', err);
80
+ return {
81
+ isError: true,
82
+ content: [{ type: 'text', text: `The tool failed unexpectedly: ${err?.message || String(err)}` }],
83
+ };
80
84
  }
81
- // Unexpected. Report the message, not the stack: the caller is a model on the
82
- // other end of a pipe, and a stack trace is noise. The full error is on the
83
- // child process's stderr, which is where a human debugging this will look.
84
- console.error('[onboarder-mcp] tool failed:', err);
85
- return {
86
- isError: true,
87
- content: [{ type: 'text', text: `The tool failed unexpectedly: ${err?.message || String(err)}` }],
88
- };
89
- }
90
85
  }
91
-
92
86
  // The dispatcher is exported because the Streamable HTTP transport in `./http.js`
93
87
  // needs to answer the same messages without going through a line of stdio. The
94
88
  // protocol logic lives in exactly one place; a second transport must not become a
95
89
  // second implementation of `tools/list`.
96
90
  export { handle };
97
-
98
91
  async function handle(msg) {
99
- // A request must name a method and must declare the protocol version. Anything
100
- // else is not a request at all, and replying to it would invent an id to answer
101
- // under — so this returns nothing and the line is dropped.
102
- //
103
- // `null` rather than `undefined` is the contract with the loop below: both mean
104
- // "say nothing", but only one of them survives being awaited and compared.
105
- if (!msg || typeof msg !== 'object' || msg.jsonrpc !== '2.0' || typeof msg.method !== 'string') {
106
- return null;
107
- }
108
- const { method, id, params } = msg;
109
-
110
- // A notification has no id and expects no answer. Returning `null` is how the
111
- // loop knows to stay silent, which matters: replying to a notification is
112
- // itself a protocol violation.
113
- const isNotification = id === undefined || id === null;
114
-
115
- switch (method) {
116
- case 'initialize':
117
- return isNotification ? undefined : result(id, {
118
- protocolVersion: PROTOCOL_VERSION,
119
- capabilities: { tools: { listChanged: false } },
120
- serverInfo: SERVER_INFO,
121
- });
122
-
123
- // The client's post-handshake ping. Answering it is what tells the client the
124
- // handshake completed and the tool loop is live.
125
- case 'notifications/initialized':
126
- return null;
127
-
128
- case 'ping':
129
- return isNotification ? undefined : result(id, {});
130
-
131
- case 'tools/list':
132
- return isNotification ? undefined : result(id, { tools: toolDefinitions() });
133
-
134
- case 'tools/call':
135
- if (isNotification) return null;
136
- if (!params?.name || typeof params.name !== 'string') {
137
- return failure(id, INVALID_PARAMS, 'tools/call needs a tool name.');
138
- }
139
- return result(id, await callOne(params.name, params.arguments));
140
-
141
- // A client asking for resources or prompts is not an error — this server has
142
- // none, and saying so is more useful than METHOD_NOT_FOUND. A harness that
143
- // probes both at startup gets a clean answer instead of a warning.
144
- case 'resources/list':
145
- return result(id, { resources: [] });
146
-
147
- case 'prompts/list':
148
- return result(id, { prompts: [] });
149
-
150
- case 'resources/templates/list':
151
- return result(id, { resourceTemplates: [] });
152
-
153
- default:
154
- if (isNotification) return null;
155
- return failure(id, METHOD_NOT_FOUND, `No method called "${method}".`);
156
- }
92
+ // A request must name a method and must declare the protocol version. Anything
93
+ // else is not a request at all, and replying to it would invent an id to answer
94
+ // under — so this returns nothing and the line is dropped.
95
+ //
96
+ // `null` rather than `undefined` is the contract with the loop below: both mean
97
+ // "say nothing", but only one of them survives being awaited and compared.
98
+ if (!msg || typeof msg !== 'object' || msg.jsonrpc !== '2.0' || typeof msg.method !== 'string') {
99
+ return null;
100
+ }
101
+ const { method, id, params } = msg;
102
+ // A notification has no id and expects no answer. Returning `null` is how the
103
+ // loop knows to stay silent, which matters: replying to a notification is
104
+ // itself a protocol violation.
105
+ const isNotification = id === undefined || id === null;
106
+ switch (method) {
107
+ case 'initialize':
108
+ return isNotification ? undefined : result(id, {
109
+ protocolVersion: PROTOCOL_VERSION,
110
+ capabilities: { tools: { listChanged: false } },
111
+ serverInfo: SERVER_INFO,
112
+ });
113
+ // The client's post-handshake ping. Answering it is what tells the client the
114
+ // handshake completed and the tool loop is live.
115
+ case 'notifications/initialized':
116
+ return null;
117
+ case 'ping':
118
+ return isNotification ? undefined : result(id, {});
119
+ case 'tools/list':
120
+ return isNotification ? undefined : result(id, { tools: toolDefinitions() });
121
+ case 'tools/call':
122
+ if (isNotification)
123
+ return null;
124
+ if (!params?.name || typeof params.name !== 'string') {
125
+ return failure(id, INVALID_PARAMS, 'tools/call needs a tool name.');
126
+ }
127
+ return result(id, await callOne(params.name, params.arguments));
128
+ // A client asking for resources or prompts is not an error — this server has
129
+ // none, and saying so is more useful than METHOD_NOT_FOUND. A harness that
130
+ // probes both at startup gets a clean answer instead of a warning.
131
+ case 'resources/list':
132
+ return result(id, { resources: [] });
133
+ case 'prompts/list':
134
+ return result(id, { prompts: [] });
135
+ case 'resources/templates/list':
136
+ return result(id, { resourceTemplates: [] });
137
+ default:
138
+ if (isNotification)
139
+ return null;
140
+ return failure(id, METHOD_NOT_FOUND, `No method called "${method}".`);
141
+ }
157
142
  }
158
-
159
143
  // One line in, one line out. A message that will not parse gets a parse error
160
144
  // with `id: null`, which is what the spec requires — the client cannot know which
161
145
  // request the bad line belonged to.
162
146
  function parseLine(line) {
163
- try {
164
- const msg = JSON.parse(line);
165
- if (!msg || typeof msg !== 'object' || Array.isArray(msg)) {
166
- return { bad: failure(null, INVALID_REQUEST, 'A message must be a JSON-RPC object.') };
147
+ try {
148
+ const msg = JSON.parse(line);
149
+ if (!msg || typeof msg !== 'object' || Array.isArray(msg)) {
150
+ return { bad: failure(null, INVALID_REQUEST, 'A message must be a JSON-RPC object.') };
151
+ }
152
+ return { msg };
153
+ }
154
+ catch (err) {
155
+ return { bad: failure(null, PARSE_ERROR, `Could not parse the message: ${err.message}`) };
167
156
  }
168
- return { msg };
169
- } catch (err) {
170
- return { bad: failure(null, PARSE_ERROR, `Could not parse the message: ${err.message}`) };
171
- }
172
157
  }
173
-
174
158
  /**
175
159
  * Run the server until stdin closes. `input` and `output` are parameters so tests
176
160
  * can drive a whole session through in-memory streams.
177
161
  */
178
162
  export function serveMcp({ input = process.stdin, output = process.stdout } = {}) {
179
- let buffer = '';
180
- // Messages are handled strictly in order, but not awaited inline: a long scan
181
- // must not block the event loop from reading the next line, or a client that
182
- // pipelines would sit with a full buffer. The promise chain is what preserves
183
- // the ordering while letting reads continue.
184
- let chain = Promise.resolve();
185
- let closed = false;
186
-
187
- const send = (message) => {
188
- if (closed) return;
189
- output.write(JSON.stringify(message) + '\n');
190
- };
191
-
192
- const enqueue = (line) => {
193
- chain = chain.then(async () => {
194
- const { msg, bad } = parseLine(line);
195
- if (bad) { send(bad); return; }
196
- const response = await handle(msg);
197
- if (response) send(response);
198
- }).catch((err) => {
199
- // `handle` already turns tool failures into results. Reaching here means
200
- // something threw outside that, so the only honest move is to log it and
201
- // keep serving — a dead server helps nobody recover.
202
- console.error('[onboarder-mcp] dispatch failed:', err);
163
+ let buffer = '';
164
+ // Messages are handled strictly in order, but not awaited inline: a long scan
165
+ // must not block the event loop from reading the next line, or a client that
166
+ // pipelines would sit with a full buffer. The promise chain is what preserves
167
+ // the ordering while letting reads continue.
168
+ let chain = Promise.resolve();
169
+ let closed = false;
170
+ const send = (message) => {
171
+ if (closed)
172
+ return;
173
+ output.write(JSON.stringify(message) + '\n');
174
+ };
175
+ const enqueue = (line) => {
176
+ chain = chain.then(async () => {
177
+ const { msg, bad } = parseLine(line);
178
+ if (bad) {
179
+ send(bad);
180
+ return;
181
+ }
182
+ const response = await handle(msg);
183
+ if (response)
184
+ send(response);
185
+ }).catch((err) => {
186
+ // `handle` already turns tool failures into results. Reaching here means
187
+ // something threw outside that, so the only honest move is to log it and
188
+ // keep serving — a dead server helps nobody recover.
189
+ console.error('[onboarder-mcp] dispatch failed:', err);
190
+ });
191
+ };
192
+ input.setEncoding?.('utf8');
193
+ input.on('data', (chunk) => {
194
+ buffer += chunk;
195
+ let nl;
196
+ // A partial line at the end of a chunk stays in the buffer for the next one.
197
+ while ((nl = buffer.indexOf('\n')) !== -1) {
198
+ const line = buffer.slice(0, nl).trim();
199
+ buffer = buffer.slice(nl + 1);
200
+ if (line)
201
+ enqueue(line);
202
+ }
203
203
  });
204
- };
205
-
206
- input.setEncoding?.('utf8');
207
- input.on('data', (chunk) => {
208
- buffer += chunk;
209
- let nl;
210
- // A partial line at the end of a chunk stays in the buffer for the next one.
211
- while ((nl = buffer.indexOf('\n')) !== -1) {
212
- const line = buffer.slice(0, nl).trim();
213
- buffer = buffer.slice(nl + 1);
214
- if (line) enqueue(line);
215
- }
216
- });
217
-
218
- input.on('end', () => {
219
- // A last line without a trailing newline is still a message. Dropping it
220
- // would lose the final request of a session — which is often the only one.
221
- const line = buffer.trim();
222
- buffer = '';
223
- if (line) enqueue(line);
224
- // Let the queue finish before the process exits, so a reply written just
225
- // after stdin closed still reaches the client.
226
- chain.finally(() => {
227
- if (output === process.stdout) process.exitCode = 0;
204
+ input.on('end', () => {
205
+ // A last line without a trailing newline is still a message. Dropping it
206
+ // would lose the final request of a session — which is often the only one.
207
+ const line = buffer.trim();
208
+ buffer = '';
209
+ if (line)
210
+ enqueue(line);
211
+ // Let the queue finish before the process exits, so a reply written just
212
+ // after stdin closed still reaches the client.
213
+ chain.finally(() => {
214
+ if (output === process.stdout)
215
+ process.exitCode = 0;
216
+ });
217
+ });
218
+ input.on('error', (err) => {
219
+ console.error('[onboarder-mcp] stdin error:', err);
228
220
  });
229
- });
230
-
231
- input.on('error', (err) => {
232
- console.error('[onboarder-mcp] stdin error:', err);
233
- });
234
-
235
- return {
236
- stop() { closed = true; },
237
- // Awaiting the queue is how a test knows every reply has been written, and
238
- // how a shutdown can drain in-flight work instead of cutting it off.
239
- settled() { return chain; },
240
- };
221
+ return {
222
+ stop() { closed = true; },
223
+ // Awaiting the queue is how a test knows every reply has been written, and
224
+ // how a shutdown can drain in-flight work instead of cutting it off.
225
+ settled() { return chain; },
226
+ };
241
227
  }
228
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/mcp/server.ts"],"names":[],"mappings":"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","sourcesContent":["// The MCP server: JSON-RPC 2.0 over stdio, one JSON object per line.\n//\n// Why no SDK: the project has no dependencies, and `package.json` says so. MCP's\n// stdio transport is a framing convention (one line-delimited JSON-RPC message\n// per message, on the child's stdin/stdout), not a wire protocol with magic — so\n// implementing it directly is a few dozen lines and keeps the promise that this\n// repo installs with nothing. If the SDK ever becomes worth it, this file is the\n// only thing that changes; `tools.js` and `analysis.js` know nothing about JSON.\n//\n// The rules that matter for correctness:\n// * stdout belongs to the protocol. Anything else printed there corrupts the\n// stream, so the logger is redirected to stderr for the lifetime of the\n// child (see `runner.js`).\n// * Requests are answered in order. MCP clients pipeline, and answering a\n// `tools/call` out of order makes some clients discard the later result.\n// * A tool that throws is answered with a *result* carrying `isError: true`,\n// not a JSON-RPC error. That is what puts the message in front of the model\n// so it can correct itself; a protocol error just fails the turn.\n\nimport { toolDefinitions, callTool, findTool } from './tools.js';\nimport { ToolError } from './analysis.js';\n\nexport const PROTOCOL_VERSION = '2025-06-18';\nexport const SERVER_INFO = {\n name: 'onboarder',\n version: '1.0.0',\n title: 'Onboarder',\n instructions:\n 'Onboarder explains a codebase. Start with onboarder_scan on a repository path; '\n + 'it returns a written overview, the entry points, the most depended-upon files, and '\n + 'any dependency cycles. Then use onboarder_tour for a reading order, onboarder_search '\n + 'to find things by name, onboarder_explain_file for one file, and onboarder_read_file '\n + 'for raw source. Every tool also takes `path`; omit it to keep working on the last '\n + 'repository scanned. The repository is read, never written.',\n};\n\n// JSON-RPC error codes. Only the first two are protocol-level; the rest are\n// conventional in MCP and keep a misbehaving client from parsing a server bug as\n// a server bug it caused.\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INVALID_PARAMS = -32602;\n\nfunction result(id, value) {\n return { jsonrpc: '2.0', id, result: value };\n}\n\nfunction failure(id, code, message, data?: unknown) {\n const error: { code: number; message: string; data?: unknown } = { code, message };\n if (data !== undefined) error.data = data;\n return { jsonrpc: '2.0', id, error };\n}\n\n// A tool error and an internal error are different things. A `ToolError` is a\n// sentence the model can act on — \"that path is outside the repo\" — so it becomes\n// an isError result with that sentence intact. Anything else is a bug, and saying\n// so plainly beats pretending it was the caller's fault.\nasync function callOne(name, args) {\n const tool = findTool(name);\n if (!tool) {\n return {\n isError: true,\n content: [{ type: 'text', text: `No tool called \"${name}\". Call tools/list to see what is available.` }],\n };\n }\n try {\n const value = await tool.run(args || {});\n // MCP content is a list of blocks. A tool that returns structured data sends\n // it as JSON text plus the native `structuredContent` field, which is what\n // typed clients read; the text block is what everything else falls back to.\n return {\n content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],\n structuredContent: value,\n isError: false,\n };\n } catch (err) {\n if (err instanceof ToolError) {\n return { isError: true, content: [{ type: 'text', text: err.message }] };\n }\n // Unexpected. Report the message, not the stack: the caller is a model on the\n // other end of a pipe, and a stack trace is noise. The full error is on the\n // child process's stderr, which is where a human debugging this will look.\n console.error('[onboarder-mcp] tool failed:', err);\n return {\n isError: true,\n content: [{ type: 'text', text: `The tool failed unexpectedly: ${err?.message || String(err)}` }],\n };\n }\n}\n\n// The dispatcher is exported because the Streamable HTTP transport in `./http.js`\n// needs to answer the same messages without going through a line of stdio. The\n// protocol logic lives in exactly one place; a second transport must not become a\n// second implementation of `tools/list`.\nexport { handle };\n\nasync function handle(msg) {\n // A request must name a method and must declare the protocol version. Anything\n // else is not a request at all, and replying to it would invent an id to answer\n // under — so this returns nothing and the line is dropped.\n //\n // `null` rather than `undefined` is the contract with the loop below: both mean\n // \"say nothing\", but only one of them survives being awaited and compared.\n if (!msg || typeof msg !== 'object' || msg.jsonrpc !== '2.0' || typeof msg.method !== 'string') {\n return null;\n }\n const { method, id, params } = msg;\n\n // A notification has no id and expects no answer. Returning `null` is how the\n // loop knows to stay silent, which matters: replying to a notification is\n // itself a protocol violation.\n const isNotification = id === undefined || id === null;\n\n switch (method) {\n case 'initialize':\n return isNotification ? undefined : result(id, {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: { tools: { listChanged: false } },\n serverInfo: SERVER_INFO,\n });\n\n // The client's post-handshake ping. Answering it is what tells the client the\n // handshake completed and the tool loop is live.\n case 'notifications/initialized':\n return null;\n\n case 'ping':\n return isNotification ? undefined : result(id, {});\n\n case 'tools/list':\n return isNotification ? undefined : result(id, { tools: toolDefinitions() });\n\n case 'tools/call':\n if (isNotification) return null;\n if (!params?.name || typeof params.name !== 'string') {\n return failure(id, INVALID_PARAMS, 'tools/call needs a tool name.');\n }\n return result(id, await callOne(params.name, params.arguments));\n\n // A client asking for resources or prompts is not an error — this server has\n // none, and saying so is more useful than METHOD_NOT_FOUND. A harness that\n // probes both at startup gets a clean answer instead of a warning.\n case 'resources/list':\n return result(id, { resources: [] });\n\n case 'prompts/list':\n return result(id, { prompts: [] });\n\n case 'resources/templates/list':\n return result(id, { resourceTemplates: [] });\n\n default:\n if (isNotification) return null;\n return failure(id, METHOD_NOT_FOUND, `No method called \"${method}\".`);\n }\n}\n\n// One line in, one line out. A message that will not parse gets a parse error\n// with `id: null`, which is what the spec requires — the client cannot know which\n// request the bad line belonged to.\nfunction parseLine(line) {\n try {\n const msg = JSON.parse(line);\n if (!msg || typeof msg !== 'object' || Array.isArray(msg)) {\n return { bad: failure(null, INVALID_REQUEST, 'A message must be a JSON-RPC object.') };\n }\n return { msg };\n } catch (err) {\n return { bad: failure(null, PARSE_ERROR, `Could not parse the message: ${err.message}`) };\n }\n}\n\n/**\n * Run the server until stdin closes. `input` and `output` are parameters so tests\n * can drive a whole session through in-memory streams.\n */\nexport function serveMcp({ input = process.stdin, output = process.stdout }: Record<string, any> = {}) {\n let buffer = '';\n // Messages are handled strictly in order, but not awaited inline: a long scan\n // must not block the event loop from reading the next line, or a client that\n // pipelines would sit with a full buffer. The promise chain is what preserves\n // the ordering while letting reads continue.\n let chain = Promise.resolve();\n let closed = false;\n\n const send = (message) => {\n if (closed) return;\n output.write(JSON.stringify(message) + '\\n');\n };\n\n const enqueue = (line) => {\n chain = chain.then(async () => {\n const { msg, bad } = parseLine(line);\n if (bad) { send(bad); return; }\n const response = await handle(msg);\n if (response) send(response);\n }).catch((err) => {\n // `handle` already turns tool failures into results. Reaching here means\n // something threw outside that, so the only honest move is to log it and\n // keep serving — a dead server helps nobody recover.\n console.error('[onboarder-mcp] dispatch failed:', err);\n });\n };\n\n input.setEncoding?.('utf8');\n input.on('data', (chunk) => {\n buffer += chunk;\n let nl;\n // A partial line at the end of a chunk stays in the buffer for the next one.\n while ((nl = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, nl).trim();\n buffer = buffer.slice(nl + 1);\n if (line) enqueue(line);\n }\n });\n\n input.on('end', () => {\n // A last line without a trailing newline is still a message. Dropping it\n // would lose the final request of a session — which is often the only one.\n const line = buffer.trim();\n buffer = '';\n if (line) enqueue(line);\n // Let the queue finish before the process exits, so a reply written just\n // after stdin closed still reaches the client.\n chain.finally(() => {\n if (output === process.stdout) process.exitCode = 0;\n });\n });\n\n input.on('error', (err) => {\n console.error('[onboarder-mcp] stdin error:', err);\n });\n\n return {\n stop() { closed = true; },\n // Awaiting the queue is how a test knows every reply has been written, and\n // how a shutdown can drain in-flight work instead of cutting it off.\n settled() { return chain; },\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -11,9 +11,7 @@
11
11
  // would look like a server bug rather than a logging bug. Redirecting is better
12
12
  // than trusting: the guard costs one comparison per write and cannot be forgotten
13
13
  // by a future contributor three files deep.
14
-
15
14
  import { serveMcp, SERVER_INFO } from './server.js';
16
-
17
15
  // stdout is a shared pipe with two kinds of writer: the protocol, which must be
18
16
  // the only thing a client ever sees, and everything else — a stray `console.log`
19
17
  // in a shared analyzer, a logger — which would be read as a malformed frame and
@@ -25,18 +23,18 @@ import { serveMcp, SERVER_INFO } from './server.js';
25
23
  // on being the first thing to run.
26
24
  const realStdoutWrite = process.stdout.write.bind(process.stdout);
27
25
  const protocolStream = { write: (chunk) => realStdoutWrite(chunk) };
28
-
29
26
  process.stdout.write = function toStderr(chunk, encoding, callback) {
30
- process.stderr.write(chunk);
31
- if (typeof encoding === 'function') encoding();
32
- else if (typeof callback === 'function') callback();
33
- return true;
27
+ process.stderr.write(chunk);
28
+ if (typeof encoding === 'function')
29
+ encoding();
30
+ else if (typeof callback === 'function')
31
+ callback();
32
+ return true;
34
33
  };
35
-
36
34
  // Diagnostics are opt-in: a client reading stdout is reading a protocol stream
37
35
  // and nothing else, so anything else has to be asked for.
38
36
  if (process.env.ONBOARDER_MCP_LOG === '1') {
39
- console.error(`[onboarder-mcp] ${SERVER_INFO.name} ${SERVER_INFO.version} starting on stdio`);
37
+ console.error(`[onboarder-mcp] ${SERVER_INFO.name} ${SERVER_INFO.version} starting on stdio`);
40
38
  }
41
-
42
39
  serveMcp({ output: protocolStream });
40
+ //# sourceMappingURL=standalone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.js","sourceRoot":"","sources":["../../src/server/mcp/standalone.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,kFAAkF;AAClF,+EAA+E;AAC/E,6EAA6E;AAC7E,+CAA+C;AAC/C,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,6EAA6E;AAC7E,gFAAgF;AAChF,kFAAkF;AAClF,4CAA4C;AAE5C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpD,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,8CAA8C;AAC9C,EAAE;AACF,kFAAkF;AAClF,8EAA8E;AAC9E,kFAAkF;AAClF,mCAAmC;AACnC,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;AAEpE,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,SAAS,QAAQ,CAAC,KAA0B,EAAE,QAAmD,EAAE,QAAgC;IACxJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,QAAQ,EAAE,CAAC;SAC1C,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,QAAQ,EAAE,CAAC;IACpD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,+EAA+E;AAC/E,0DAA0D;AAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG,EAAE,CAAC;IAC1C,OAAO,CAAC,KAAK,CAAC,mBAAmB,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAChG,CAAC;AAED,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC","sourcesContent":["// The MCP server as its own process: `node server/mcp/standalone.js`.\n//\n// This is the command an agent harness is configured with. It is a separate entry\n// point rather than a flag on the web server because the two have incompatible\n// requirements for stdout — the web server logs to it, the MCP server speaks\n// JSON-RPC over it and must own it completely.\n//\n// It also guards stdout for the lifetime of the process. Anything that writes\n// there — a `console.log` from a shared analyzer, a logger the tools reach for —\n// would be read by the client as a malformed protocol frame, and the failure\n// would look like a server bug rather than a logging bug. Redirecting is better\n// than trusting: the guard costs one comparison per write and cannot be forgotten\n// by a future contributor three files deep.\n\nimport { serveMcp, SERVER_INFO } from './server.js';\n\n// stdout is a shared pipe with two kinds of writer: the protocol, which must be\n// the only thing a client ever sees, and everything else — a stray `console.log`\n// in a shared analyzer, a logger — which would be read as a malformed frame and\n// make the server look broken when it is not.\n//\n// Rather than hoping nothing else writes, this builds the protocol's writer first\n// and hands it to `serveMcp`, then points `process.stdout.write` at stderr. A\n// later `console.log` cannot corrupt the stream, and the protocol does not depend\n// on being the first thing to run.\nconst realStdoutWrite = process.stdout.write.bind(process.stdout);\nconst protocolStream = { write: (chunk) => realStdoutWrite(chunk) };\n\nprocess.stdout.write = function toStderr(chunk: string | Uint8Array, encoding?: BufferEncoding | ((err?: Error) => void), callback?: (err?: Error) => void) {\n process.stderr.write(chunk);\n if (typeof encoding === 'function') encoding();\n else if (typeof callback === 'function') callback();\n return true;\n};\n\n// Diagnostics are opt-in: a client reading stdout is reading a protocol stream\n// and nothing else, so anything else has to be asked for.\nif (process.env.ONBOARDER_MCP_LOG === '1') {\n console.error(`[onboarder-mcp] ${SERVER_INFO.name} ${SERVER_INFO.version} starting on stdio`);\n}\n\nserveMcp({ output: protocolStream });\n"]}