@sanurb/ringi 0.2.0 → 0.3.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 (423) hide show
  1. package/dist/cli.mjs +2132 -0
  2. package/dist/cli.mjs.map +1 -0
  3. package/dist/mcp.mjs +1057 -0
  4. package/dist/mcp.mjs.map +1 -0
  5. package/dist/runtime.mjs +3116 -0
  6. package/dist/runtime.mjs.map +1 -0
  7. package/package.json +15 -14
  8. package/server/nitro.json +17 -0
  9. package/server/public/assets/ClientOnly-QdfAxyFs.js +1 -0
  10. package/server/public/assets/_reviewId-CmXHvWLn.js +1 -0
  11. package/server/public/assets/_reviewId-DdOpDx4U.js +1 -0
  12. package/server/public/assets/abap-B1dkBSPn.js +1 -0
  13. package/server/public/assets/action-bar-DLRNvLjj.js +45 -0
  14. package/server/public/assets/actionscript-3-BT4ibYlP.js +1 -0
  15. package/server/public/assets/ada-CD92zeps.js +1 -0
  16. package/server/public/assets/andromeeda-DqSmgxi0.js +1 -0
  17. package/server/public/assets/angular-html-BDC0PfKr.js +1 -0
  18. package/server/public/assets/angular-ts-B9yoQMtj.js +1 -0
  19. package/server/public/assets/apache-D5suuoa_.js +1 -0
  20. package/server/public/assets/apex-BL-m4VHy.js +1 -0
  21. package/server/public/assets/apl-CldhY0Pn.js +1 -0
  22. package/server/public/assets/applescript-CLiBqvKT.js +1 -0
  23. package/server/public/assets/ara-LdDF8cmv.js +1 -0
  24. package/server/public/assets/asciidoc-2DZ9hC2N.js +1 -0
  25. package/server/public/assets/asm-0ZPGRSUy.js +1 -0
  26. package/server/public/assets/astro-DR6labZJ.js +1 -0
  27. package/server/public/assets/aurora-x-Da7Zfvbg.js +1 -0
  28. package/server/public/assets/awk-Bn0gn_B_.js +1 -0
  29. package/server/public/assets/ayu-dark-bqYKoqpM.js +1 -0
  30. package/server/public/assets/ayu-light-C45jTIzZ.js +1 -0
  31. package/server/public/assets/ayu-mirage-BV_FCTQi.js +1 -0
  32. package/server/public/assets/ballerina-D2nw_w8Q.js +1 -0
  33. package/server/public/assets/bat-ByUBN5gS.js +1 -0
  34. package/server/public/assets/beancount-BTb2W6Mp.js +1 -0
  35. package/server/public/assets/berry-5SO2uITG.js +1 -0
  36. package/server/public/assets/bibtex-CDBTNfUI.js +1 -0
  37. package/server/public/assets/bicep-fgxG_4rP.js +1 -0
  38. package/server/public/assets/bird2-BCwzDhwX.js +1 -0
  39. package/server/public/assets/blade-BBTRu2-g.js +1 -0
  40. package/server/public/assets/bsl-CG-fq4sc.js +1 -0
  41. package/server/public/assets/c-CEvNj7xl.js +1 -0
  42. package/server/public/assets/c3-Dlaci63_.js +1 -0
  43. package/server/public/assets/cadence-DHbRuEmm.js +1 -0
  44. package/server/public/assets/cairo-Ds0kTeYT.js +1 -0
  45. package/server/public/assets/catppuccin-frappe-DrL1fUuH.js +1 -0
  46. package/server/public/assets/catppuccin-latte-C0REgVjl.js +1 -0
  47. package/server/public/assets/catppuccin-macchiato-ChQpylWO.js +1 -0
  48. package/server/public/assets/catppuccin-mocha-Dd0JU1T0.js +1 -0
  49. package/server/public/assets/clarity-DMoTOm4G.js +1 -0
  50. package/server/public/assets/clojure-DBhE3PpS.js +1 -0
  51. package/server/public/assets/cmake-DwMc40Or.js +1 -0
  52. package/server/public/assets/cobol-BdNJSMRt.js +1 -0
  53. package/server/public/assets/codeowners-1lVr8wqV.js +1 -0
  54. package/server/public/assets/codeql-DWflolvo.js +1 -0
  55. package/server/public/assets/coffee-RA4xA24H.js +1 -0
  56. package/server/public/assets/common-lisp-CrVQ5xT-.js +1 -0
  57. package/server/public/assets/compiler-runtime-DZXZ41-q.js +1 -0
  58. package/server/public/assets/coq-CjfoyYSh.js +1 -0
  59. package/server/public/assets/cpp-BoW7e2Ow.js +1 -0
  60. package/server/public/assets/createServerFn-DTk395iP.js +9 -0
  61. package/server/public/assets/crystal-CYKRo3F9.js +1 -0
  62. package/server/public/assets/csharp-C7bIWP5y.js +1 -0
  63. package/server/public/assets/css-Ck2tii2d.js +1 -0
  64. package/server/public/assets/csv-DsAkDVtA.js +1 -0
  65. package/server/public/assets/cue-BWmQgbOB.js +1 -0
  66. package/server/public/assets/cypher-D-jVC50Q.js +1 -0
  67. package/server/public/assets/d-CaviyOrm.js +1 -0
  68. package/server/public/assets/dark-plus-DIrnwZt9.js +1 -0
  69. package/server/public/assets/dart-CZEi7JgC.js +1 -0
  70. package/server/public/assets/dax-BK-8zffy.js +1 -0
  71. package/server/public/assets/desktop-D3cjbL4D.js +1 -0
  72. package/server/public/assets/diff-sHAzLvlp.js +1 -0
  73. package/server/public/assets/docker--xs2Ng3w.js +1 -0
  74. package/server/public/assets/dotenv-Cm4nwcJ7.js +1 -0
  75. package/server/public/assets/dracula-CAUSusef.js +1 -0
  76. package/server/public/assets/dracula-soft-cjNkMFza.js +1 -0
  77. package/server/public/assets/dream-maker-fjmWTFCO.js +1 -0
  78. package/server/public/assets/edge-DxycC9wl.js +1 -0
  79. package/server/public/assets/elixir-B-50Er3p.js +1 -0
  80. package/server/public/assets/elm-B4-ygIVo.js +1 -0
  81. package/server/public/assets/emacs-lisp-CJzqStIa.js +1 -0
  82. package/server/public/assets/erb-DJvYE1L1.js +1 -0
  83. package/server/public/assets/erlang-C-m_88FN.js +1 -0
  84. package/server/public/assets/everforest-dark-DBpaSMx1.js +1 -0
  85. package/server/public/assets/everforest-light-CiGrXwia.js +1 -0
  86. package/server/public/assets/fennel-DRaXF7k8.js +1 -0
  87. package/server/public/assets/file-tree-CI3Xwwid.js +1907 -0
  88. package/server/public/assets/fish-Bn-Yh3Jj.js +1 -0
  89. package/server/public/assets/fluent-DF5F8Ks_.js +1 -0
  90. package/server/public/assets/fortran-fixed-form-Cx1lv7HN.js +1 -0
  91. package/server/public/assets/fortran-free-form-hCQHRqew.js +1 -0
  92. package/server/public/assets/fsharp-DC5k9sy2.js +1 -0
  93. package/server/public/assets/gdresource-D0EsKdgH.js +1 -0
  94. package/server/public/assets/gdscript-_C9_Hi_w.js +1 -0
  95. package/server/public/assets/gdshader-BW7b1X1Y.js +1 -0
  96. package/server/public/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  97. package/server/public/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  98. package/server/public/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  99. package/server/public/assets/genie-Ch_6TCHd.js +1 -0
  100. package/server/public/assets/gherkin-CaNUsmTq.js +1 -0
  101. package/server/public/assets/git-commit-BcFsuO5E.js +1 -0
  102. package/server/public/assets/git-rebase-ChGA-z50.js +1 -0
  103. package/server/public/assets/github-dark-B9ygjgg6.js +1 -0
  104. package/server/public/assets/github-dark-default-Br2bgYSx.js +1 -0
  105. package/server/public/assets/github-dark-dimmed-CmtqpPJ-.js +1 -0
  106. package/server/public/assets/github-dark-high-contrast-fSfmrZcC.js +1 -0
  107. package/server/public/assets/github-light-BZjUqfZl.js +1 -0
  108. package/server/public/assets/github-light-default-lIytXXhR.js +1 -0
  109. package/server/public/assets/github-light-high-contrast-BRrjFb7n.js +1 -0
  110. package/server/public/assets/gleam-DALMDpNs.js +1 -0
  111. package/server/public/assets/glimmer-js-maLb6ysA.js +1 -0
  112. package/server/public/assets/glimmer-ts-DGNr-OBA.js +1 -0
  113. package/server/public/assets/glsl-CmplqyQ1.js +1 -0
  114. package/server/public/assets/gn-DGjqrYN9.js +1 -0
  115. package/server/public/assets/gnuplot-BYckvgQI.js +1 -0
  116. package/server/public/assets/go-JycvP538.js +1 -0
  117. package/server/public/assets/graphql-VhP7n4--.js +1 -0
  118. package/server/public/assets/groovy-D5qMRONT.js +1 -0
  119. package/server/public/assets/gruvbox-dark-hard-M1dj1e6V.js +1 -0
  120. package/server/public/assets/gruvbox-dark-medium-cqq_ncQu.js +1 -0
  121. package/server/public/assets/gruvbox-dark-soft-B4QwL2a9.js +1 -0
  122. package/server/public/assets/gruvbox-light-hard-DLayMKOQ.js +1 -0
  123. package/server/public/assets/gruvbox-light-medium-D52XgPKf.js +1 -0
  124. package/server/public/assets/gruvbox-light-soft-Dola3KdD.js +1 -0
  125. package/server/public/assets/hack-BVSQ2bxM.js +1 -0
  126. package/server/public/assets/haml-CwTtRHoj.js +1 -0
  127. package/server/public/assets/handlebars-CcO01SVo.js +1 -0
  128. package/server/public/assets/haskell-ys7wPPEd.js +1 -0
  129. package/server/public/assets/haxe-94kiChn7.js +1 -0
  130. package/server/public/assets/hcl-DmHt_-wq.js +1 -0
  131. package/server/public/assets/hjson-xMmoJ0Gx.js +1 -0
  132. package/server/public/assets/hlsl-b-Pskdze.js +1 -0
  133. package/server/public/assets/horizon-BKMqttiR.js +1 -0
  134. package/server/public/assets/horizon-bright-HNkBlnm5.js +1 -0
  135. package/server/public/assets/houston-BkBSBSOQ.js +1 -0
  136. package/server/public/assets/html-derivative-Cz-cKMi2.js +1 -0
  137. package/server/public/assets/html-zQbUS8Is.js +1 -0
  138. package/server/public/assets/http-CaGQ9BgA.js +1 -0
  139. package/server/public/assets/hurl-BBoki9bg.js +1 -0
  140. package/server/public/assets/hxml-iQTOTWpM.js +1 -0
  141. package/server/public/assets/hy-DKl1XhBq.js +1 -0
  142. package/server/public/assets/imba-DPxkOTAg.js +1 -0
  143. package/server/public/assets/ini-lkLGq_1x.js +1 -0
  144. package/server/public/assets/java-LAx6oszV.js +1 -0
  145. package/server/public/assets/javascript-COqx-gKX.js +1 -0
  146. package/server/public/assets/jinja-x-G_qSCP.js +1 -0
  147. package/server/public/assets/jison-7oSeVkKJ.js +1 -0
  148. package/server/public/assets/json-sTLOVXhc.js +1 -0
  149. package/server/public/assets/json5-Cy6ypJuJ.js +1 -0
  150. package/server/public/assets/jsonc-Cw2ugYAK.js +1 -0
  151. package/server/public/assets/jsonl-Dp5_qBVH.js +1 -0
  152. package/server/public/assets/jsonnet-BTbmg_-u.js +1 -0
  153. package/server/public/assets/jssm-CnT7nPea.js +1 -0
  154. package/server/public/assets/jsx-zXeIBQLI.js +1 -0
  155. package/server/public/assets/julia-E-6Xm9nd.js +1 -0
  156. package/server/public/assets/just-D9n74gZy.js +1 -0
  157. package/server/public/assets/kanagawa-dragon-CxsBnuhV.js +1 -0
  158. package/server/public/assets/kanagawa-lotus-vHdxDDOS.js +1 -0
  159. package/server/public/assets/kanagawa-wave-CIkfTKWk.js +1 -0
  160. package/server/public/assets/kdl-BwK60g80.js +1 -0
  161. package/server/public/assets/kotlin-Dbd9Vi-v.js +1 -0
  162. package/server/public/assets/kusto-BuTk9usc.js +1 -0
  163. package/server/public/assets/laserwave-C0wf_d3o.js +1 -0
  164. package/server/public/assets/latex-D0t4RtEU.js +1 -0
  165. package/server/public/assets/lean-CYAW8bRN.js +1 -0
  166. package/server/public/assets/less-D4uen21c.js +1 -0
  167. package/server/public/assets/light-plus-oqYyWKEE.js +1 -0
  168. package/server/public/assets/liquid-BzXN12F6.js +1 -0
  169. package/server/public/assets/llvm-Z1xJzteV.js +1 -0
  170. package/server/public/assets/log-BGUxlsk3.js +1 -0
  171. package/server/public/assets/logo-wVUhvQ1b.js +1 -0
  172. package/server/public/assets/lua-B0Cg8RP4.js +1 -0
  173. package/server/public/assets/luau-rPFZzCmq.js +1 -0
  174. package/server/public/assets/main-FvxVz-kD.js +15 -0
  175. package/server/public/assets/make-BmPf6m0P.js +1 -0
  176. package/server/public/assets/markdown-AseU6zcW.js +1 -0
  177. package/server/public/assets/marko-BlRPXWOe.js +1 -0
  178. package/server/public/assets/material-theme-6_W6rQhR.js +1 -0
  179. package/server/public/assets/material-theme-darker-VPEo3Sem.js +1 -0
  180. package/server/public/assets/material-theme-lighter-CUhzCcZ9.js +1 -0
  181. package/server/public/assets/material-theme-ocean-B2JdsaGb.js +1 -0
  182. package/server/public/assets/material-theme-palenight-DhY-sklA.js +1 -0
  183. package/server/public/assets/matlab-BOj_BDQv.js +1 -0
  184. package/server/public/assets/mdc-FiVDZSZ4.js +1 -0
  185. package/server/public/assets/mdx-Cm6cDkDI.js +1 -0
  186. package/server/public/assets/mermaid-DLO-R4hv.js +1 -0
  187. package/server/public/assets/min-dark-D34a_pX7.js +1 -0
  188. package/server/public/assets/min-light-Cdd4KORE.js +1 -0
  189. package/server/public/assets/mipsasm-DYpHF-GA.js +1 -0
  190. package/server/public/assets/mojo-DqYVFv_G.js +1 -0
  191. package/server/public/assets/monokai-CDR4sQ2n.js +1 -0
  192. package/server/public/assets/moonbit-DRKee9wk.js +1 -0
  193. package/server/public/assets/move-DbRk6Vn9.js +1 -0
  194. package/server/public/assets/narrat-IOfmaXfb.js +1 -0
  195. package/server/public/assets/new-DOyplRwM.js +1 -0
  196. package/server/public/assets/nextflow-D-Ec_bsY.js +1 -0
  197. package/server/public/assets/nextflow-groovy-EYl0c2BQ.js +1 -0
  198. package/server/public/assets/nginx-3JLAqmJa.js +1 -0
  199. package/server/public/assets/night-owl-light-Bedht9b4.js +1 -0
  200. package/server/public/assets/night-owl-yQJ3-I0I.js +1 -0
  201. package/server/public/assets/nim-DyjFVMzT.js +1 -0
  202. package/server/public/assets/nix-C2IovEl2.js +1 -0
  203. package/server/public/assets/nord-BjZ63GNL.js +1 -0
  204. package/server/public/assets/nushell-BflTrRB5.js +1 -0
  205. package/server/public/assets/objective-c-GRClK1S7.js +1 -0
  206. package/server/public/assets/objective-cpp-l3qYw-v5.js +1 -0
  207. package/server/public/assets/ocaml-BBDyhyMH.js +1 -0
  208. package/server/public/assets/odin-jCJ7Js99.js +1 -0
  209. package/server/public/assets/one-dark-pro-PIx2Diul.js +1 -0
  210. package/server/public/assets/one-light-BFMEz49S.js +1 -0
  211. package/server/public/assets/openscad-Drf0LgCX.js +1 -0
  212. package/server/public/assets/pascal-BT2XAUTl.js +1 -0
  213. package/server/public/assets/perl-Dr47G_2Q.js +1 -0
  214. package/server/public/assets/php-BhBDWTJe.js +1 -0
  215. package/server/public/assets/pierre-dark-CTXzTLfO.js +1 -0
  216. package/server/public/assets/pierre-light-C_5rlJRo.js +1 -0
  217. package/server/public/assets/pkl-ML-dWShO.js +1 -0
  218. package/server/public/assets/plastic-BFI-Z5Z2.js +1 -0
  219. package/server/public/assets/plsql-0vd5cLro.js +1 -0
  220. package/server/public/assets/po-CbZ_uqQA.js +1 -0
  221. package/server/public/assets/poimandres-Cayhd01L.js +1 -0
  222. package/server/public/assets/polar-C4hfV8Nc.js +1 -0
  223. package/server/public/assets/postcss-osFUbTLw.js +1 -0
  224. package/server/public/assets/powerquery-CTlGUQPj.js +1 -0
  225. package/server/public/assets/powershell-DyZsOmuq.js +1 -0
  226. package/server/public/assets/preload-helper-D7oT-Xwl.js +20 -0
  227. package/server/public/assets/prisma-SS92PO_I.js +1 -0
  228. package/server/public/assets/prolog-B1O1NNVC.js +1 -0
  229. package/server/public/assets/proto-BWu3eZTs.js +1 -0
  230. package/server/public/assets/pug-Dij_IK5w.js +1 -0
  231. package/server/public/assets/puppet-tvtRVdr6.js +1 -0
  232. package/server/public/assets/purescript-Dtbpb7D-.js +1 -0
  233. package/server/public/assets/python-Dlk0Acio.js +1 -0
  234. package/server/public/assets/qml-qUwk3nhh.js +1 -0
  235. package/server/public/assets/qmldir-B-iEOngH.js +1 -0
  236. package/server/public/assets/qss-Ba0p-aHw.js +1 -0
  237. package/server/public/assets/r-WmtNicKM.js +1 -0
  238. package/server/public/assets/racket-BXDsxf2U.js +1 -0
  239. package/server/public/assets/raku-Dw1WWFXK.js +1 -0
  240. package/server/public/assets/razor-DaqiVx3Q.js +1 -0
  241. package/server/public/assets/red-BC3Ds49b.js +1 -0
  242. package/server/public/assets/reg-DXFHGaM4.js +1 -0
  243. package/server/public/assets/regexp-CiSWN5Ne.js +1 -0
  244. package/server/public/assets/rel-Dc5_Ytx2.js +1 -0
  245. package/server/public/assets/reviews-CJvVXRLH.js +1 -0
  246. package/server/public/assets/reviews-CfbuF6ib.js +1 -0
  247. package/server/public/assets/riscv-ZgswiWij.js +1 -0
  248. package/server/public/assets/ron-YghabWAH.js +1 -0
  249. package/server/public/assets/rose-pine-ByWLnVr3.js +1 -0
  250. package/server/public/assets/rose-pine-dawn-DBmeySrz.js +1 -0
  251. package/server/public/assets/rose-pine-moon-B9J-N3nK.js +1 -0
  252. package/server/public/assets/rosmsg-DTKmAsVH.js +1 -0
  253. package/server/public/assets/routes-DNxq1Fba.js +1 -0
  254. package/server/public/assets/routes-Dp0ODZ55.js +2 -0
  255. package/server/public/assets/rst-CP6xOYlY.js +1 -0
  256. package/server/public/assets/ruby-BXYLc1CM.js +1 -0
  257. package/server/public/assets/rust-nfXwuE6F.js +1 -0
  258. package/server/public/assets/sas-CFdtZutF.js +1 -0
  259. package/server/public/assets/sass-CbRjkld3.js +1 -0
  260. package/server/public/assets/scala-BzD3eypx.js +1 -0
  261. package/server/public/assets/scheme-D4d1PV1y.js +1 -0
  262. package/server/public/assets/scss-D8KhdObH.js +1 -0
  263. package/server/public/assets/sdbl-Cf-Ydnvx.js +1 -0
  264. package/server/public/assets/shaderlab-DGohHMiF.js +1 -0
  265. package/server/public/assets/shellscript-BHdEbumI.js +1 -0
  266. package/server/public/assets/shellsession-Dh-bxrap.js +1 -0
  267. package/server/public/assets/slack-dark-MszIyPZ2.js +1 -0
  268. package/server/public/assets/slack-ochin-tQ3Q0gE9.js +1 -0
  269. package/server/public/assets/smalltalk-_uWoArwn.js +1 -0
  270. package/server/public/assets/snazzy-light-9sniMEk5.js +1 -0
  271. package/server/public/assets/solarized-dark-CdD0Hxzv.js +1 -0
  272. package/server/public/assets/solarized-light-C-nsEdqF.js +1 -0
  273. package/server/public/assets/solidity-D6uC-xwP.js +1 -0
  274. package/server/public/assets/soy-cDuODfbT.js +1 -0
  275. package/server/public/assets/sparql-BgU2QITA.js +1 -0
  276. package/server/public/assets/splunk-LQYHRu14.js +1 -0
  277. package/server/public/assets/sql-CKZpK620.js +1 -0
  278. package/server/public/assets/ssh-config-B7BUl8Rd.js +1 -0
  279. package/server/public/assets/stata-BLJTbKOO.js +1 -0
  280. package/server/public/assets/styles-UDowwF7S.css +2 -0
  281. package/server/public/assets/stylus-Byjxdx_q.js +1 -0
  282. package/server/public/assets/surrealql-C96KvYaj.js +1 -0
  283. package/server/public/assets/svelte-Qnbj2GWx.js +1 -0
  284. package/server/public/assets/swift-BexLlMrU.js +1 -0
  285. package/server/public/assets/synthwave-84-BxMBwQMS.js +1 -0
  286. package/server/public/assets/system-verilog-DVGwm0mw.js +1 -0
  287. package/server/public/assets/systemd-H2IT3-p5.js +1 -0
  288. package/server/public/assets/talonscript-mKZIGM8n.js +1 -0
  289. package/server/public/assets/tasl-B7he_Ugr.js +1 -0
  290. package/server/public/assets/tcl-5mT3RxHH.js +1 -0
  291. package/server/public/assets/templ-CQPDll3D.js +1 -0
  292. package/server/public/assets/terraform-BZP0GLsT.js +1 -0
  293. package/server/public/assets/test-D7JRfog1.js +1 -0
  294. package/server/public/assets/tex-97QNLoBJ.js +1 -0
  295. package/server/public/assets/tokyo-night-CTPVdZt9.js +1 -0
  296. package/server/public/assets/toml-CTFA98he.js +1 -0
  297. package/server/public/assets/ts-tags-B8zlXe2n.js +1 -0
  298. package/server/public/assets/tsv-BayJtYdY.js +1 -0
  299. package/server/public/assets/tsx-VqRU8NCz.js +1 -0
  300. package/server/public/assets/turtle-TVCBh_kY.js +1 -0
  301. package/server/public/assets/twig-FTTF8rVk.js +1 -0
  302. package/server/public/assets/typescript-CuX0hIVY.js +1 -0
  303. package/server/public/assets/typespec-BUvaJDLF.js +1 -0
  304. package/server/public/assets/typst-8NBaY7Ec.js +1 -0
  305. package/server/public/assets/useStore-M3H8PB1v.js +1 -0
  306. package/server/public/assets/utils-DElCu2hq.js +1 -0
  307. package/server/public/assets/v-VihyTigi.js +1 -0
  308. package/server/public/assets/vala-DyFAPyX6.js +1 -0
  309. package/server/public/assets/vb-Dg1Iqi4J.js +1 -0
  310. package/server/public/assets/verilog-D2Xc-vhD.js +1 -0
  311. package/server/public/assets/vesper-DJbtqYNr.js +1 -0
  312. package/server/public/assets/vhdl-CU3BVeE7.js +1 -0
  313. package/server/public/assets/viml-hG2shuOW.js +1 -0
  314. package/server/public/assets/vitesse-black-DbG2gsc0.js +1 -0
  315. package/server/public/assets/vitesse-dark-B6WV4xXH.js +1 -0
  316. package/server/public/assets/vitesse-light-DC1pdD02.js +1 -0
  317. package/server/public/assets/vue-DXwaEU0U.js +1 -0
  318. package/server/public/assets/vue-html-QD7AJ6JJ.js +1 -0
  319. package/server/public/assets/vue-vine-Bh2m1D2Z.js +1 -0
  320. package/server/public/assets/vyper-C1wojIuk.js +1 -0
  321. package/server/public/assets/wasm-C6Y0s02M.js +1 -0
  322. package/server/public/assets/wasm-qTvCOSHz.js +1 -0
  323. package/server/public/assets/wenyan-BG5vPQF0.js +1 -0
  324. package/server/public/assets/wgsl-DrVb-Cub.js +1 -0
  325. package/server/public/assets/wikitext-PRC4s8sH.js +1 -0
  326. package/server/public/assets/wit-ChW5qvg_.js +1 -0
  327. package/server/public/assets/wolfram-B8mKuZSQ.js +1 -0
  328. package/server/public/assets/xml-BK-rcb5a.js +1 -0
  329. package/server/public/assets/xsl-dt-d2R7p.js +1 -0
  330. package/server/public/assets/yaml-UiXU3hGj.js +1 -0
  331. package/server/public/assets/zenscript-C-jEPC9j.js +1 -0
  332. package/server/public/assets/zig-EbnRGjcz.js +1 -0
  333. package/server/public/favicon.ico +0 -0
  334. package/server/public/logo192.png +0 -0
  335. package/server/public/logo512.png +0 -0
  336. package/server/public/manifest.json +25 -0
  337. package/server/public/robots.txt +3 -0
  338. package/server/public/tanstack-circle-logo.png +0 -0
  339. package/server/public/tanstack-word-logo-white.svg +1 -0
  340. package/server/server/_chunks/ssr-renderer.mjs +15 -0
  341. package/server/server/_libs/@floating-ui/core+[...].mjs +698 -0
  342. package/server/server/_libs/@floating-ui/dom+[...].mjs +644 -0
  343. package/server/server/_libs/@floating-ui/react-dom+[...].mjs +839 -0
  344. package/server/server/_libs/@pierre/diffs+[...].mjs +18578 -0
  345. package/server/server/_libs/@radix-ui/react-arrow+[...].mjs +174 -0
  346. package/server/server/_libs/@radix-ui/react-collection+[...].mjs +162 -0
  347. package/server/server/_libs/@radix-ui/react-dialog+[...].mjs +1666 -0
  348. package/server/server/_libs/@radix-ui/react-popper+[...].mjs +289 -0
  349. package/server/server/_libs/@radix-ui/react-radio-group+[...].mjs +420 -0
  350. package/server/server/_libs/@radix-ui/react-select+[...].mjs +990 -0
  351. package/server/server/_libs/@tanstack/react-router+[...].mjs +14113 -0
  352. package/server/server/_libs/_.mjs +2 -0
  353. package/server/server/_libs/chokidar+readdirp.mjs +1599 -0
  354. package/server/server/_libs/class-variance-authority+clsx.mjs +69 -0
  355. package/server/server/_libs/effect+[...].mjs +34047 -0
  356. package/server/server/_libs/h3+rou3+srvx.mjs +1195 -0
  357. package/server/server/_libs/hookable.mjs +41 -0
  358. package/server/server/_libs/lucide-react.mjs +298 -0
  359. package/server/server/_libs/pierre__theme.mjs +2668 -0
  360. package/server/server/_libs/radix-ui__number.mjs +6 -0
  361. package/server/server/_libs/radix-ui__primitive.mjs +9 -0
  362. package/server/server/_libs/radix-ui__react-direction.mjs +11 -0
  363. package/server/server/_libs/shiki.mjs +16 -0
  364. package/server/server/_libs/shikijs__langs.mjs +1355 -0
  365. package/server/server/_libs/shikijs__themes.mjs +262 -0
  366. package/server/server/_libs/tailwind-merge.mjs +1962 -0
  367. package/server/server/_libs/tanstack__history.mjs +342 -0
  368. package/server/server/_libs/tanstack__router-core.mjs +6 -0
  369. package/server/server/_libs/ufo.mjs +64 -0
  370. package/server/server/_reviewId-AWnOGz5k.mjs +33 -0
  371. package/server/server/_reviewId-Com4yOlc.mjs +29 -0
  372. package/server/server/_reviewId-DAhmekJ2.mjs +277 -0
  373. package/server/server/_reviewId-p9mhYVwa.mjs +18 -0
  374. package/server/server/_runtime.mjs +35 -0
  375. package/server/server/_ssr/action-bar-C68xGnWW.mjs +592 -0
  376. package/server/server/_ssr/api-handler-CstW2n82.mjs +189 -0
  377. package/server/server/_ssr/client-runtime-BoPuAEoA.mjs +245 -0
  378. package/server/server/_ssr/createServerRpc--0mcGlWK.mjs +12 -0
  379. package/server/server/_ssr/createSsrRpc-AwdiLXmF.mjs +16 -0
  380. package/server/server/_ssr/domain-rpc-3Ds9DPr0.mjs +287 -0
  381. package/server/server/_ssr/file-tree-CQ5w2GHh.mjs +1951 -0
  382. package/server/server/_ssr/load-scoped-diff-NL2XAcdz.mjs +45 -0
  383. package/server/server/_ssr/new-BKl_G2Ks.mjs +37 -0
  384. package/server/server/_ssr/new-BREdMFAM.mjs +12 -0
  385. package/server/server/_ssr/new-DCz5eHkb.mjs +137 -0
  386. package/server/server/_ssr/reviews-BL5Nsgst.mjs +7 -0
  387. package/server/server/_ssr/reviews-BoaEgGKs.mjs +100 -0
  388. package/server/server/_ssr/reviews-C7_NIhY8.mjs +19 -0
  389. package/server/server/_ssr/reviews-Dd69YBDa.mjs +12 -0
  390. package/server/server/_ssr/router-DLxN8FOm.mjs +415 -0
  391. package/server/server/_ssr/routes-D25G8OuS.mjs +80 -0
  392. package/server/server/_ssr/routes-lz0AN75A.mjs +929 -0
  393. package/server/server/_ssr/runtime-D9IbnMlF.mjs +1401 -0
  394. package/server/server/_ssr/server-runtime-D99qpmma.mjs +12 -0
  395. package/server/server/_ssr/ssr.mjs +5318 -0
  396. package/server/server/_ssr/start-BIQfOZtj.mjs +4 -0
  397. package/server/server/_ssr/test-CQdMYlqa.mjs +6 -0
  398. package/server/server/_ssr/todo-m_uUvxca.mjs +88 -0
  399. package/server/server/_ssr/use-keyboard-shortcuts-D5b1Mxpq.mjs +25 -0
  400. package/server/server/_ssr/utils-BuOt9_LA.mjs +8 -0
  401. package/server/server/_tanstack-start-manifest_v-CnL10NRH.mjs +71 -0
  402. package/server/server/index.mjs +2615 -0
  403. package/server/server/node_modules/detect-libc/lib/detect-libc.js +313 -0
  404. package/server/server/node_modules/detect-libc/lib/elf.js +39 -0
  405. package/server/server/node_modules/detect-libc/lib/filesystem.js +51 -0
  406. package/server/server/node_modules/detect-libc/lib/process.js +24 -0
  407. package/server/server/node_modules/detect-libc/package.json +44 -0
  408. package/server/server/node_modules/msgpackr-extract/index.js +1 -0
  409. package/server/server/node_modules/msgpackr-extract/package.json +50 -0
  410. package/server/server/node_modules/node-gyp-build-optional-packages/index.js +6 -0
  411. package/server/server/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +236 -0
  412. package/server/server/node_modules/node-gyp-build-optional-packages/package.json +32 -0
  413. package/server/server/node_modules/tslib/modules/index.js +70 -0
  414. package/server/server/node_modules/tslib/modules/package.json +3 -0
  415. package/server/server/node_modules/tslib/package.json +47 -0
  416. package/server/server/node_modules/tslib/tslib.js +484 -0
  417. package/server/server/package.json +12 -0
  418. package/dist/chunk-KMYSGMD3.js +0 -3526
  419. package/dist/chunk-KMYSGMD3.js.map +0 -1
  420. package/dist/cli.js +0 -1839
  421. package/dist/cli.js.map +0 -1
  422. package/dist/mcp.js +0 -1228
  423. package/dist/mcp.js.map +0 -1
package/dist/mcp.mjs ADDED
@@ -0,0 +1,1057 @@
1
+ import { _ as ReviewSourceType, a as ReviewService, d as parseDiff, f as CommentService, h as ReviewId, i as TodoService, o as GitService, p as TodoId, r as ExportService, t as CoreLive, u as getDiffSummary } from "./runtime.mjs";
2
+ import { execFileSync } from "node:child_process";
3
+ import * as Schema from "effect/Schema";
4
+ import { ServiceMap } from "effect";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import * as ManagedRuntime from "effect/ManagedRuntime";
8
+ import * as ConfigProvider from "effect/ConfigProvider";
9
+ import { stdin, stdout } from "node:process";
10
+ import * as vm from "node:vm";
11
+ import * as Duration from "effect/Duration";
12
+ //#region src/mcp/config.ts
13
+ const DEFAULT_DB_PATH = ".ringi/reviews.db";
14
+ const DEFAULT_MAX_OUTPUT_BYTES = 100 * 1024;
15
+ const DEFAULT_TIMEOUT_MS = 3e4;
16
+ const MAX_TIMEOUT_MS = 12e4;
17
+ var McpConfig = class extends ServiceMap.Service()("McpConfig") {};
18
+ const McpConfigLive = (config) => Layer.succeed(McpConfig, McpConfig.of(config));
19
+ const resolveRepositoryRoot = (repoOverride) => {
20
+ return execFileSync("git", ["rev-parse", "--show-toplevel"], {
21
+ cwd: repoOverride ?? process.cwd(),
22
+ encoding: "utf8"
23
+ }).trim();
24
+ };
25
+ const resolveDbPath = (repoRoot, dbPathOverride) => dbPathOverride ?? `${repoRoot}/${DEFAULT_DB_PATH}`;
26
+ const parseNumberFlag = (flagValue, fallback, name) => {
27
+ if (flagValue === void 0) return fallback;
28
+ const parsed = Number.parseInt(flagValue, 10);
29
+ if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(`Invalid ${name}: expected a positive integer, received ${flagValue}`);
30
+ return parsed;
31
+ };
32
+ const resolveMcpConfig = (argv) => {
33
+ const args = [...argv];
34
+ const readonly = args.includes("--readonly");
35
+ const dbIndex = args.indexOf("--db-path");
36
+ const repoIndex = args.indexOf("--repo");
37
+ const timeoutIndex = args.indexOf("--timeout-ms");
38
+ const maxOutputIndex = args.indexOf("--max-output-bytes");
39
+ const repoRoot = resolveRepositoryRoot(repoIndex === -1 ? void 0 : args[repoIndex + 1]);
40
+ return {
41
+ cwd: process.cwd(),
42
+ dbPath: resolveDbPath(repoRoot, dbIndex === -1 ? void 0 : args[dbIndex + 1]),
43
+ defaultTimeoutMs: parseNumberFlag(timeoutIndex === -1 ? void 0 : args[timeoutIndex + 1], DEFAULT_TIMEOUT_MS, "timeout"),
44
+ maxOutputBytes: parseNumberFlag(maxOutputIndex === -1 ? void 0 : args[maxOutputIndex + 1], DEFAULT_MAX_OUTPUT_BYTES, "max output bytes"),
45
+ maxTimeoutMs: MAX_TIMEOUT_MS,
46
+ readonly,
47
+ repoRoot
48
+ };
49
+ };
50
+ //#endregion
51
+ //#region src/mcp/errors.ts
52
+ /**
53
+ * MCP execution domain errors.
54
+ *
55
+ * All errors that can occur during sandbox execution are modeled as typed,
56
+ * tagged errors for exhaustive handling via catchTag/catchTags.
57
+ */
58
+ /** Code validation failed (empty, too long, non-string). */
59
+ var InvalidCodeError = class extends Schema.TaggedErrorClass()("InvalidCodeError", { message: Schema.String }) {};
60
+ /** Timeout parameter is invalid (non-finite, zero, negative). */
61
+ var InvalidTimeoutError = class extends Schema.TaggedErrorClass()("InvalidTimeoutError", {
62
+ message: Schema.String,
63
+ received: Schema.Unknown
64
+ }) {};
65
+ /** Sandbox execution timed out. */
66
+ var ExecutionTimeoutError = class extends Schema.TaggedErrorClass()("ExecutionTimeoutError", {
67
+ message: Schema.String,
68
+ timeoutMs: Schema.Number
69
+ }) {};
70
+ /** Sandbox execution failed with an unrecoverable error. */
71
+ var SandboxExecutionError = class extends Schema.TaggedErrorClass()("SandboxExecutionError", {
72
+ error: Schema.Defect,
73
+ message: Schema.String
74
+ }) {};
75
+ //#endregion
76
+ //#region src/mcp/namespaces.ts
77
+ /**
78
+ * MCP sandbox namespace factories.
79
+ *
80
+ * Each factory creates a frozen namespace object suitable for injection into the
81
+ * vm.Context sandbox. Factories accept dependency-injected callbacks so they can
82
+ * be tested without an Effect runtime.
83
+ */
84
+ const PHASE_UNAVAILABLE_MESSAGE = "This capability is not available in the current server phase. Intelligence features require Phase 2.";
85
+ const createIntelligenceNamespace = () => Object.freeze({
86
+ getConfidence: (_reviewId) => Promise.reject(new Error(PHASE_UNAVAILABLE_MESSAGE)),
87
+ getImpacts: (_reviewId) => Promise.reject(new Error(PHASE_UNAVAILABLE_MESSAGE)),
88
+ getRelationships: (_reviewId) => Promise.reject(new Error(PHASE_UNAVAILABLE_MESSAGE)),
89
+ validate: (_options) => Promise.reject(new Error(PHASE_UNAVAILABLE_MESSAGE))
90
+ });
91
+ const createSessionNamespace = (deps) => Object.freeze({
92
+ context: async () => {
93
+ const repo = await deps.getRepositoryInfo();
94
+ return {
95
+ activeReviewId: await deps.getLatestReviewId(),
96
+ activeSnapshotId: null,
97
+ readonly: deps.readonly,
98
+ repository: repo,
99
+ serverMode: "stdio"
100
+ };
101
+ },
102
+ status: async () => ({
103
+ activeSubscriptions: 0,
104
+ currentPhase: "phase1",
105
+ ok: true,
106
+ readonly: deps.readonly
107
+ })
108
+ });
109
+ const buildPreview = (diffText, source) => {
110
+ const files = parseDiff(diffText);
111
+ const summary = getDiffSummary(files);
112
+ return {
113
+ files: files.map((f) => ({
114
+ additions: f.additions,
115
+ deletions: f.deletions,
116
+ path: f.newPath,
117
+ status: f.status
118
+ })),
119
+ source,
120
+ summary: {
121
+ totalAdditions: summary.totalAdditions,
122
+ totalDeletions: summary.totalDeletions,
123
+ totalFiles: summary.totalFiles
124
+ }
125
+ };
126
+ };
127
+ const createSourcesNamespace = (deps) => Object.freeze({
128
+ list: async () => {
129
+ const [stagedFiles, branches, commits] = await Promise.all([
130
+ deps.getStagedFiles(),
131
+ deps.getBranches(),
132
+ deps.getRecentCommits()
133
+ ]);
134
+ return {
135
+ branches: branches.map((b) => ({
136
+ current: b.current,
137
+ name: b.name
138
+ })),
139
+ recentCommits: commits.map((c) => ({
140
+ author: c.author,
141
+ date: c.date,
142
+ hash: c.hash,
143
+ message: c.message
144
+ })),
145
+ staged: { available: stagedFiles.length > 0 }
146
+ };
147
+ },
148
+ previewDiff: async (source) => {
149
+ let diffText;
150
+ switch (source.type) {
151
+ case "staged":
152
+ diffText = await deps.getStagedDiff();
153
+ break;
154
+ case "branch":
155
+ diffText = await deps.getBranchDiff(source.baseRef);
156
+ break;
157
+ case "commits":
158
+ diffText = await deps.getCommitDiff(source.commits);
159
+ break;
160
+ default: throw new Error(`Unsupported source type: ${source.type}`);
161
+ }
162
+ return buildPreview(diffText, source);
163
+ }
164
+ });
165
+ const createEventsNamespace = () => {
166
+ let subscriptionCounter = 0;
167
+ return Object.freeze({
168
+ listRecent: async (_filter) => [],
169
+ subscribe: async (filter) => {
170
+ subscriptionCounter += 1;
171
+ return {
172
+ eventTypes: filter?.eventTypes ?? [
173
+ "reviews.updated",
174
+ "comments.updated",
175
+ "todos.updated",
176
+ "files.changed"
177
+ ],
178
+ id: `sub_${subscriptionCounter}`,
179
+ reviewId: filter?.reviewId
180
+ };
181
+ }
182
+ });
183
+ };
184
+ //#endregion
185
+ //#region src/mcp/sandbox.ts
186
+ /**
187
+ * MCP sandbox global construction.
188
+ *
189
+ * Creates the six spec-compliant namespaces (`reviews`, `todos`, `sources`,
190
+ * `intelligence`, `events`, `session`) from injected dependencies.
191
+ *
192
+ * All domain interaction goes through the `call` callback so the sandbox module
193
+ * stays testable without an Effect runtime.
194
+ */
195
+ const parseId = (value, fieldName) => {
196
+ if (typeof value !== "string" || value.length === 0) throw new Error(`Invalid ${fieldName}: expected a non-empty string`);
197
+ return value;
198
+ };
199
+ /**
200
+ * Build the six frozen namespace objects for sandbox injection.
201
+ *
202
+ * The `call` callback wraps every domain operation with journal tracking and
203
+ * error handling. This keeps the sandbox module free of Effect imports.
204
+ */
205
+ const createSandboxGlobals = (deps) => {
206
+ const reviews = Object.freeze({
207
+ create: async (_input) => {
208
+ deps.requireWritable();
209
+ return deps.call("reviews.create", async () => {
210
+ throw new Error("reviews.create: not wired to runtime");
211
+ });
212
+ },
213
+ export: (_options) => deps.call("reviews.export", async () => {
214
+ throw new Error("reviews.export: not wired to runtime");
215
+ }),
216
+ get: (reviewIdValue) => {
217
+ parseId(reviewIdValue, "reviewId");
218
+ return deps.call("reviews.get", async () => {
219
+ throw new Error("reviews.get: not wired to runtime");
220
+ });
221
+ },
222
+ getComments: (reviewIdValue, _filePath) => {
223
+ parseId(reviewIdValue, "reviewId");
224
+ return deps.call("reviews.getComments", async () => {
225
+ throw new Error("reviews.getComments: not wired to runtime");
226
+ });
227
+ },
228
+ getDiff: (_query) => deps.call("reviews.getDiff", async () => {
229
+ throw new Error("reviews.getDiff: not wired to runtime");
230
+ }),
231
+ getFiles: (reviewIdValue) => {
232
+ parseId(reviewIdValue, "reviewId");
233
+ return deps.call("reviews.getFiles", async () => {
234
+ throw new Error("reviews.getFiles: not wired to runtime");
235
+ });
236
+ },
237
+ getStatus: (reviewIdValue) => {
238
+ parseId(reviewIdValue, "reviewId");
239
+ return deps.call("reviews.getStatus", async () => {
240
+ throw new Error("reviews.getStatus: not wired to runtime");
241
+ });
242
+ },
243
+ getSuggestions: (reviewIdValue) => {
244
+ parseId(reviewIdValue, "reviewId");
245
+ return deps.call("reviews.getSuggestions", async () => {
246
+ throw new Error("reviews.getSuggestions: not wired to runtime");
247
+ });
248
+ },
249
+ list: (_filters) => deps.call("reviews.list", async () => {
250
+ throw new Error("reviews.list: not wired to runtime");
251
+ })
252
+ });
253
+ const todos = Object.freeze({
254
+ add: async (_input) => {
255
+ deps.requireWritable();
256
+ return deps.call("todos.add", async () => {
257
+ throw new Error("todos.add: not wired to runtime");
258
+ });
259
+ },
260
+ clear: async (_reviewIdValue) => {
261
+ deps.requireWritable();
262
+ return deps.call("todos.clear", async () => {
263
+ throw new Error("todos.clear: not wired to runtime");
264
+ });
265
+ },
266
+ done: async (todoIdValue) => {
267
+ deps.requireWritable();
268
+ parseId(todoIdValue, "todoId");
269
+ return deps.call("todos.done", async () => {
270
+ throw new Error("todos.done: not wired to runtime");
271
+ });
272
+ },
273
+ list: (_filter) => deps.call("todos.list", async () => {
274
+ throw new Error("todos.list: not wired to runtime");
275
+ }),
276
+ move: async (todoIdValue, _positionValue) => {
277
+ deps.requireWritable();
278
+ parseId(todoIdValue, "todoId");
279
+ return deps.call("todos.move", async () => {
280
+ throw new Error("todos.move: not wired to runtime");
281
+ });
282
+ },
283
+ remove: async (todoIdValue) => {
284
+ deps.requireWritable();
285
+ parseId(todoIdValue, "todoId");
286
+ return deps.call("todos.remove", async () => {
287
+ throw new Error("todos.remove: not wired to runtime");
288
+ });
289
+ },
290
+ undone: async (todoIdValue) => {
291
+ deps.requireWritable();
292
+ parseId(todoIdValue, "todoId");
293
+ return deps.call("todos.undone", async () => {
294
+ throw new Error("todos.undone: not wired to runtime");
295
+ });
296
+ }
297
+ });
298
+ const sources = createSourcesNamespace({
299
+ getBranchDiff: deps.getBranchDiff,
300
+ getBranches: deps.getBranches,
301
+ getCommitDiff: deps.getCommitDiff,
302
+ getRecentCommits: deps.getRecentCommits,
303
+ getRepositoryInfo: deps.getRepositoryInfo,
304
+ getStagedDiff: deps.getStagedDiff,
305
+ getStagedFiles: deps.getStagedFiles
306
+ });
307
+ const intelligence = createIntelligenceNamespace();
308
+ return {
309
+ events: createEventsNamespace(),
310
+ intelligence,
311
+ reviews,
312
+ session: createSessionNamespace({
313
+ getLatestReviewId: deps.getLatestReviewId,
314
+ getRepositoryInfo: deps.getRepositoryInfo,
315
+ readonly: deps.readonly
316
+ }),
317
+ sources,
318
+ todos
319
+ };
320
+ };
321
+ //#endregion
322
+ //#region src/mcp/schemas.ts
323
+ /**
324
+ * MCP sandbox input schemas.
325
+ *
326
+ * Centralizes all validation for sandbox namespace inputs using Effect Schema.
327
+ * Replaces hand-written parse* helpers with declarative, composable schemas.
328
+ */
329
+ const NonEmptyString = Schema.String.pipe(Schema.check(Schema.isMinLength(1)));
330
+ const ReviewCreateFromSpec = Schema.Struct({ source: Schema.Struct({
331
+ baseRef: Schema.NullOr(Schema.String).pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => null)),
332
+ type: ReviewSourceType.pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => "staged"))
333
+ }) });
334
+ const ReviewCreateFromLegacy = Schema.Struct({
335
+ sourceRef: Schema.NullOr(Schema.String).pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => null)),
336
+ sourceType: ReviewSourceType.pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => "staged"))
337
+ });
338
+ /** Decode unknown input into a normalized ReviewCreateInput. */
339
+ const decodeReviewCreateInput = (input) => {
340
+ if (typeof input === "object" && input !== null && "source" in input) {
341
+ const parsed = Schema.decodeUnknownSync(ReviewCreateFromSpec)(input);
342
+ return {
343
+ sourceRef: parsed.source.baseRef ?? null,
344
+ sourceType: parsed.source.type ?? "staged"
345
+ };
346
+ }
347
+ const parsed = Schema.decodeUnknownSync(ReviewCreateFromLegacy)(input);
348
+ return {
349
+ sourceRef: parsed.sourceRef ?? null,
350
+ sourceType: parsed.sourceType ?? "staged"
351
+ };
352
+ };
353
+ const ReviewExportInput = Schema.Struct({ reviewId: ReviewId });
354
+ const ReviewDiffQuery = Schema.Struct({
355
+ filePath: NonEmptyString,
356
+ reviewId: ReviewId
357
+ });
358
+ const ReviewListFilters = Schema.Struct({
359
+ limit: Schema.Number.pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => 20)),
360
+ page: Schema.Number.pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => 1)),
361
+ pageSize: Schema.Number.pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => 20)),
362
+ sourceType: Schema.String.pipe(Schema.optionalKey),
363
+ status: Schema.String.pipe(Schema.optionalKey)
364
+ });
365
+ const TodoInputFromSpec = Schema.Struct({
366
+ reviewId: Schema.NullOr(ReviewId).pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => null)),
367
+ text: NonEmptyString
368
+ });
369
+ const TodoInputFromLegacy = Schema.Struct({
370
+ content: NonEmptyString,
371
+ reviewId: Schema.NullOr(ReviewId).pipe(Schema.optionalKey, Schema.withDecodingDefaultKey(() => null))
372
+ });
373
+ /** Decode unknown input into a normalized CreateTodoInput. */
374
+ const decodeCreateTodoInput = (input) => {
375
+ if (typeof input === "object" && input !== null && "text" in input) {
376
+ const parsed = Schema.decodeUnknownSync(TodoInputFromSpec)(input);
377
+ return {
378
+ content: parsed.text,
379
+ reviewId: parsed.reviewId ?? null
380
+ };
381
+ }
382
+ const parsed = Schema.decodeUnknownSync(TodoInputFromLegacy)(input);
383
+ return {
384
+ content: parsed.content,
385
+ reviewId: parsed.reviewId ?? null
386
+ };
387
+ };
388
+ const TodoListFilter = Schema.Struct({ reviewId: ReviewId.pipe(Schema.optionalKey) });
389
+ const TodoMoveInput = Schema.Struct({
390
+ position: Schema.Number,
391
+ todoId: TodoId
392
+ });
393
+ //#endregion
394
+ //#region src/mcp/execute.ts
395
+ const MAX_CODE_LENGTH = 5e4;
396
+ const MIN_PREVIEW_BYTES = 256;
397
+ const clampTimeout = (requestedTimeout, config) => {
398
+ if (requestedTimeout === void 0) return config.defaultTimeoutMs;
399
+ if (!Number.isFinite(requestedTimeout) || requestedTimeout <= 0) throw new Error(`Invalid timeout: expected a positive integer, received ${requestedTimeout}`);
400
+ return Math.min(Math.trunc(requestedTimeout), config.maxTimeoutMs);
401
+ };
402
+ const formatError$1 = (error) => error instanceof Error ? error.message : String(error);
403
+ const truncateUtf8 = (text, maxBytes) => {
404
+ const buffer = Buffer.from(text, "utf8");
405
+ if (buffer.byteLength <= maxBytes) return text;
406
+ return buffer.subarray(0, maxBytes).toString("utf8");
407
+ };
408
+ const summarizeForJournal = (value) => {
409
+ if (typeof value === "string") return value.length > 200 ? `${value.slice(0, 200)}…` : value;
410
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) return value;
411
+ if (Array.isArray(value)) return {
412
+ kind: "array",
413
+ length: value.length
414
+ };
415
+ if (typeof value === "object") return {
416
+ keys: Object.keys(value).slice(0, 10),
417
+ kind: "object"
418
+ };
419
+ return typeof value;
420
+ };
421
+ const finalizeOutput = (output, maxOutputBytes) => {
422
+ const serialized = JSON.stringify(output);
423
+ if (Buffer.byteLength(serialized, "utf8") <= maxOutputBytes) return output;
424
+ const previewBudget = Math.max(MIN_PREVIEW_BYTES, maxOutputBytes - Math.min(1024, Math.floor(maxOutputBytes / 4)));
425
+ return {
426
+ ...output,
427
+ result: {
428
+ note: "Result truncated to fit MCP output budget",
429
+ preview: truncateUtf8(JSON.stringify(output.result), previewBudget)
430
+ },
431
+ truncated: true
432
+ };
433
+ };
434
+ const ensureCode = (code) => {
435
+ if (typeof code !== "string") throw new TypeError("Invalid code: expected a string");
436
+ const trimmed = code.trim();
437
+ if (trimmed.length === 0) throw new Error("Invalid code: expected a non-empty string");
438
+ if (trimmed.length > MAX_CODE_LENGTH) throw new Error(`Invalid code: maximum length is ${MAX_CODE_LENGTH} characters`);
439
+ return trimmed;
440
+ };
441
+ /** Synchronous decode — throws on failure (for use inside Promise-returning sandbox callbacks). */
442
+ const decodeInputSync = (schema, input, operation) => {
443
+ try {
444
+ return Schema.decodeUnknownSync(schema)(input);
445
+ } catch (error) {
446
+ if (error instanceof Schema.SchemaError) throw new TypeError(`${operation}: ${String(error)}`, { cause: error });
447
+ throw error;
448
+ }
449
+ };
450
+ const validateCode = (code) => Effect.try({
451
+ catch: (e) => new InvalidCodeError({ message: formatError$1(e) }),
452
+ try: () => ensureCode(code)
453
+ });
454
+ const validateTimeout = (requested, config) => Effect.try({
455
+ catch: () => new InvalidTimeoutError({
456
+ message: `Invalid timeout: expected a positive integer, received ${requested}`,
457
+ received: requested
458
+ }),
459
+ try: () => clampTimeout(requested, config)
460
+ });
461
+ const writeSandboxLog = (level, args) => {
462
+ const line = args.map((arg) => {
463
+ if (typeof arg === "string") return arg;
464
+ try {
465
+ return JSON.stringify(arg);
466
+ } catch {
467
+ return String(arg);
468
+ }
469
+ }).join(" ");
470
+ process.stderr.write(`[ringi:mcp:${level}] ${line}\n`);
471
+ };
472
+ const createSandboxConsole = () => Object.freeze({
473
+ error: (...args) => writeSandboxLog("error", args),
474
+ info: (...args) => writeSandboxLog("info", args),
475
+ log: (...args) => writeSandboxLog("log", args),
476
+ warn: (...args) => writeSandboxLog("warn", args)
477
+ });
478
+ /**
479
+ * Runs user code in a VM sandbox with a single, deterministic timeout model:
480
+ *
481
+ * 1. `vm.Script.runInContext({ timeout })` — CPU-bound timeout for sync JS
482
+ * 2. `Effect.timeoutFail` — wall-clock timeout for the full async execution
483
+ *
484
+ * No `Promise.race` — timeout is handled by fiber interruption which properly
485
+ * cleans up resources. The vm timeout catches infinite sync loops while the
486
+ * Effect timeout catches slow async operations.
487
+ */
488
+ const runSandbox = (globals, code, timeoutMs) => {
489
+ return Effect.tryPromise({
490
+ catch: (error) => new SandboxExecutionError({
491
+ error,
492
+ message: formatError$1(error)
493
+ }),
494
+ try: () => {
495
+ const context = vm.createContext({
496
+ ...globals,
497
+ Buffer: void 0,
498
+ clearImmediate: void 0,
499
+ clearInterval: void 0,
500
+ clearTimeout: void 0,
501
+ console: createSandboxConsole(),
502
+ fetch: void 0,
503
+ process: void 0,
504
+ queueMicrotask,
505
+ require: void 0,
506
+ setImmediate: void 0,
507
+ setInterval: void 0,
508
+ setTimeout: void 0
509
+ });
510
+ const script = new vm.Script(`"use strict"; (async () => {\n${code}\n})()`, { filename: "ringi-mcp-execute.js" });
511
+ return Promise.resolve(script.runInContext(context, { timeout: timeoutMs }));
512
+ }
513
+ }).pipe(Effect.timeoutOrElse({
514
+ duration: Duration.millis(timeoutMs),
515
+ orElse: () => Effect.fail(new ExecutionTimeoutError({
516
+ message: `Execution timed out after ${timeoutMs}ms`,
517
+ timeoutMs
518
+ }))
519
+ }));
520
+ };
521
+ const createJournal = () => {
522
+ const entries = [];
523
+ const recordSuccess = (name, result) => {
524
+ entries.push({
525
+ name,
526
+ ok: true,
527
+ result: summarizeForJournal(result)
528
+ });
529
+ };
530
+ const recordFailure = (name, error) => {
531
+ entries.push({
532
+ error: formatError$1(error),
533
+ name,
534
+ ok: false
535
+ });
536
+ };
537
+ /**
538
+ * Runs a runtime Effect with journal tracking. Returns a Promise for sandbox use.
539
+ *
540
+ * The R parameter accepts any subset of McpRuntimeContext — the managed runtime
541
+ * provides all services, so any effect requiring a subset of them is safe to run.
542
+ */
543
+ const tracked = (runtime, name, effect) => runtime.runPromise(effect).then((result) => {
544
+ recordSuccess(name, result);
545
+ return result;
546
+ }, (error) => {
547
+ recordFailure(name, error);
548
+ throw error;
549
+ });
550
+ /** Promise-based call wrapper for non-Effect operations. */
551
+ const trackedAsync = async (name, fn) => {
552
+ try {
553
+ const result = await fn();
554
+ recordSuccess(name, result);
555
+ return result;
556
+ } catch (error) {
557
+ recordFailure(name, error);
558
+ throw error;
559
+ }
560
+ };
561
+ return {
562
+ entries,
563
+ recordFailure,
564
+ recordSuccess,
565
+ tracked,
566
+ trackedAsync
567
+ };
568
+ };
569
+ const buildSandboxGlobals = (runtime, config, journal) => {
570
+ const { tracked, trackedAsync } = journal;
571
+ const throwIfReadonly = () => {
572
+ if (config.readonly) throw new Error("Mutation rejected: MCP server is running in readonly mode");
573
+ };
574
+ const run = (name, effect) => tracked(runtime, name, effect);
575
+ const baseGlobals = createSandboxGlobals({
576
+ call: trackedAsync,
577
+ getBranchDiff: (branch) => run("git.getBranchDiff", Effect.gen(function* getBranchDiff() {
578
+ return yield* (yield* GitService).getBranchDiff(branch);
579
+ })),
580
+ getBranches: () => run("git.getBranches", Effect.gen(function* getBranches() {
581
+ return yield* (yield* GitService).getBranches;
582
+ })),
583
+ getCommitDiff: (shas) => run("git.getCommitDiff", Effect.gen(function* getCommitDiff() {
584
+ return yield* (yield* GitService).getCommitDiff(shas);
585
+ })),
586
+ getLatestReviewId: async () => {
587
+ return (await run("reviews.latestId", Effect.gen(function* result() {
588
+ return yield* (yield* ReviewService).list({
589
+ page: 1,
590
+ pageSize: 1,
591
+ repositoryPath: config.repoRoot
592
+ });
593
+ }))).reviews[0]?.id ?? null;
594
+ },
595
+ getRecentCommits: async () => {
596
+ return (await run("git.getCommits", Effect.gen(function* result() {
597
+ return yield* (yield* GitService).getCommits({
598
+ limit: 10,
599
+ offset: 0
600
+ });
601
+ }))).commits;
602
+ },
603
+ getRepositoryInfo: () => run("git.getRepositoryInfo", Effect.gen(function* getRepositoryInfo() {
604
+ return yield* (yield* GitService).getRepositoryInfo;
605
+ })),
606
+ getStagedDiff: () => run("git.getStagedDiff", Effect.gen(function* getStagedDiff() {
607
+ return yield* (yield* GitService).getStagedDiff;
608
+ })),
609
+ getStagedFiles: () => run("git.getStagedFiles", Effect.gen(function* getStagedFiles() {
610
+ return yield* (yield* GitService).getStagedFiles;
611
+ })),
612
+ readonly: config.readonly,
613
+ repoRoot: config.repoRoot,
614
+ requireWritable: throwIfReadonly
615
+ });
616
+ const reviews = Object.freeze({
617
+ create: async (inputValue) => {
618
+ throwIfReadonly();
619
+ const parsed = decodeReviewCreateInput(inputValue);
620
+ return run("reviews.create", Effect.gen(function* create() {
621
+ return yield* (yield* ReviewService).create(parsed);
622
+ }));
623
+ },
624
+ export: async (options) => {
625
+ const opts = decodeInputSync(ReviewExportInput, options, "reviews.export");
626
+ return {
627
+ markdown: await run("reviews.export", Effect.gen(function* markdown() {
628
+ return yield* (yield* ExportService).exportReview(opts.reviewId);
629
+ })),
630
+ reviewId: opts.reviewId
631
+ };
632
+ },
633
+ get: (reviewIdValue) => {
634
+ const reviewId = reviewIdValue;
635
+ return run("reviews.get", Effect.gen(function* get() {
636
+ return yield* (yield* ReviewService).getById(reviewId);
637
+ }));
638
+ },
639
+ getComments: (reviewIdValue, filePath) => {
640
+ const reviewId = reviewIdValue;
641
+ if (filePath !== null && filePath !== void 0 && typeof filePath !== "string") return Promise.reject(/* @__PURE__ */ new Error("Invalid filePath: expected a string"));
642
+ return run("reviews.getComments", Effect.gen(function* getComments() {
643
+ const svc = yield* CommentService;
644
+ return filePath ? yield* svc.getByFile(reviewId, filePath) : yield* svc.getByReview(reviewId);
645
+ }));
646
+ },
647
+ getDiff: async (query) => {
648
+ const q = decodeInputSync(ReviewDiffQuery, query, "reviews.getDiff");
649
+ const hunks = await run(`reviews.getDiff:${q.filePath}`, Effect.gen(function* hunks() {
650
+ return yield* (yield* ReviewService).getFileHunks(q.reviewId, q.filePath);
651
+ }));
652
+ return {
653
+ filePath: q.filePath,
654
+ hunks,
655
+ reviewId: q.reviewId
656
+ };
657
+ },
658
+ getFiles: async (reviewIdValue) => {
659
+ const reviewId = reviewIdValue;
660
+ return (await run("reviews.getFiles", Effect.gen(function* review() {
661
+ return yield* (yield* ReviewService).getById(reviewId);
662
+ }))).files;
663
+ },
664
+ getStatus: async (reviewIdValue) => {
665
+ const reviewId = reviewIdValue;
666
+ const [review, stats] = await Promise.all([run("reviews.getStatus.review", Effect.gen(function* () {
667
+ return yield* (yield* ReviewService).getById(reviewId);
668
+ })), run("reviews.getStatus.comments", Effect.gen(function* () {
669
+ return yield* (yield* CommentService).getStats(reviewId);
670
+ }))]);
671
+ return {
672
+ resolvedComments: stats.resolved,
673
+ reviewId,
674
+ status: review.status,
675
+ totalComments: stats.total,
676
+ unresolvedComments: stats.unresolved,
677
+ withSuggestions: 0
678
+ };
679
+ },
680
+ getSuggestions: async (reviewIdValue) => {
681
+ const reviewId = reviewIdValue;
682
+ return (await run("reviews.getSuggestions", Effect.gen(function* comments() {
683
+ return yield* (yield* CommentService).getByReview(reviewId);
684
+ }))).filter((c) => c.suggestion != null).map((c) => ({
685
+ commentId: c.id,
686
+ id: c.id,
687
+ originalCode: "",
688
+ suggestedCode: c.suggestion ?? ""
689
+ }));
690
+ },
691
+ list: async (filters) => {
692
+ const parsed = decodeInputSync(ReviewListFilters, filters ?? {}, "reviews.list");
693
+ return run("reviews.list", Effect.gen(function* list() {
694
+ return yield* (yield* ReviewService).list({
695
+ page: parsed.page,
696
+ pageSize: parsed.limit,
697
+ repositoryPath: config.repoRoot,
698
+ sourceType: parsed.sourceType,
699
+ status: parsed.status
700
+ });
701
+ }));
702
+ }
703
+ });
704
+ const todos = Object.freeze({
705
+ add: async (inputValue) => {
706
+ throwIfReadonly();
707
+ const parsed = decodeCreateTodoInput(inputValue);
708
+ return run("todos.add", Effect.gen(function* add() {
709
+ return yield* (yield* TodoService).create(parsed);
710
+ }));
711
+ },
712
+ clear: async (_reviewIdValue) => {
713
+ throwIfReadonly();
714
+ return run("todos.clear", Effect.gen(function* clear() {
715
+ return {
716
+ removed: (yield* (yield* TodoService).removeCompleted()).deleted,
717
+ success: true
718
+ };
719
+ }));
720
+ },
721
+ done: async (todoIdValue) => {
722
+ throwIfReadonly();
723
+ const todoId = todoIdValue;
724
+ return run("todos.done", Effect.gen(function* done() {
725
+ const svc = yield* TodoService;
726
+ const todo = yield* svc.getById(todoId);
727
+ if (todo.completed) return todo;
728
+ return yield* svc.toggle(todoId);
729
+ }));
730
+ },
731
+ list: async (filter) => {
732
+ const parsed = decodeInputSync(TodoListFilter, filter ?? {}, "todos.list");
733
+ return (await run("todos.list", Effect.gen(function* result() {
734
+ return yield* (yield* TodoService).list({ reviewId: parsed.reviewId });
735
+ }))).data;
736
+ },
737
+ move: async (todoIdValue, positionValue) => {
738
+ throwIfReadonly();
739
+ const parsed = decodeInputSync(TodoMoveInput, {
740
+ position: positionValue,
741
+ todoId: todoIdValue
742
+ }, "todos.move");
743
+ return run("todos.move", Effect.gen(function* move() {
744
+ return yield* (yield* TodoService).move(parsed.todoId, parsed.position);
745
+ }));
746
+ },
747
+ remove: async (todoIdValue) => {
748
+ throwIfReadonly();
749
+ const todoId = todoIdValue;
750
+ return run("todos.remove", Effect.gen(function* remove() {
751
+ return yield* (yield* TodoService).remove(todoId);
752
+ }));
753
+ },
754
+ undone: async (todoIdValue) => {
755
+ throwIfReadonly();
756
+ const todoId = todoIdValue;
757
+ return run("todos.undone", Effect.gen(function* undone() {
758
+ const svc = yield* TodoService;
759
+ const todo = yield* svc.getById(todoId);
760
+ if (!todo.completed) return todo;
761
+ return yield* svc.toggle(todoId);
762
+ }));
763
+ }
764
+ });
765
+ return {
766
+ events: baseGlobals.events,
767
+ intelligence: baseGlobals.intelligence,
768
+ reviews,
769
+ session: baseGlobals.session,
770
+ sources: baseGlobals.sources,
771
+ todos
772
+ };
773
+ };
774
+ /**
775
+ * Execute sandboxed user code against the Ringi core services.
776
+ *
777
+ * The execution pipeline is an Effect that:
778
+ * - Validates code and timeout via typed errors
779
+ * - Builds schema-validated sandbox namespaces
780
+ * - Runs the VM sandbox with a deterministic timeout model
781
+ * (vm.Script timeout for sync loops + Effect.timeoutFail for async wall-clock)
782
+ * - Propagates errors via typed tagged errors, never raw throws
783
+ *
784
+ * The managed runtime is passed explicitly — it provides the concrete service
785
+ * environment. Individual sandbox namespace methods use `runtime.runPromise`
786
+ * because they are called from user JS inside the vm sandbox (Promise boundary).
787
+ */
788
+ const executeCode = (runtime, config, input) => Effect.gen(function* executeCode() {
789
+ const timeoutMs = yield* validateTimeout(input.timeout, config);
790
+ const code = yield* validateCode(input.code);
791
+ const journal = createJournal();
792
+ return finalizeOutput(yield* runSandbox(buildSandboxGlobals(runtime, config, journal), code, timeoutMs).pipe(Effect.catchTags({
793
+ ExecutionTimeoutError: (e) => Effect.succeed({
794
+ error: e.message,
795
+ ok: false,
796
+ result: journal.entries.length === 0 ? null : { operations: journal.entries }
797
+ }),
798
+ SandboxExecutionError: (e) => Effect.succeed({
799
+ error: e.message,
800
+ ok: false,
801
+ result: journal.entries.length === 0 ? null : { operations: journal.entries }
802
+ })
803
+ }), Effect.map((result) => {
804
+ if (typeof result === "object" && result !== null && "ok" in result && result.ok === false) return result;
805
+ return {
806
+ ok: true,
807
+ result
808
+ };
809
+ })), config.maxOutputBytes);
810
+ });
811
+ /**
812
+ * Runs the Effect-based `executeCode` pipeline against the managed runtime.
813
+ * This is the ONLY place `runtime.runPromise` is called for the execution
814
+ * pipeline — the server boundary.
815
+ *
816
+ * Typed errors (InvalidCodeError, InvalidTimeoutError) are caught and
817
+ * formatted as ExecuteOutput instead of propagating as rejections.
818
+ */
819
+ const executeCodeToPromise = async (runtime, config, input) => {
820
+ const program = executeCode(runtime, config, input).pipe(Effect.catchTags({
821
+ InvalidCodeError: (e) => Effect.succeed({
822
+ error: e.message,
823
+ ok: false,
824
+ result: null
825
+ }),
826
+ InvalidTimeoutError: (e) => Effect.succeed({
827
+ error: e.message,
828
+ ok: false,
829
+ result: null
830
+ })
831
+ }));
832
+ try {
833
+ return await Effect.runPromise(program);
834
+ } catch (error) {
835
+ return finalizeOutput({
836
+ error: formatError$1(error),
837
+ ok: false,
838
+ result: null
839
+ }, config.maxOutputBytes);
840
+ }
841
+ };
842
+ //#endregion
843
+ //#region src/mcp/runtime.ts
844
+ const makeConfigLayer = (config) => ConfigProvider.layer(ConfigProvider.fromUnknown({
845
+ DB_PATH: config.dbPath,
846
+ REPOSITORY_PATH: config.repoRoot
847
+ }));
848
+ const makeMcpLayer = (config) => Layer.mergeAll(CoreLive, McpConfigLive(config)).pipe(Layer.provideMerge(makeConfigLayer(config)));
849
+ const createMcpRuntime = (config) => ManagedRuntime.make(makeMcpLayer(config));
850
+ //#endregion
851
+ //#region src/mcp/server.ts
852
+ const JSON_RPC_VERSION = "2.0";
853
+ const LATEST_PROTOCOL_VERSION = "2025-11-25";
854
+ const MCP_SERVER_NAME = "ringi";
855
+ const MCP_SERVER_VERSION = process.env.npm_package_version ?? "0.0.0-dev";
856
+ const EXECUTE_TOOL = {
857
+ description: "Run constrained JavaScript against Ringi review namespaces: review, todo, comment, diff, export, and session.",
858
+ inputSchema: {
859
+ additionalProperties: false,
860
+ properties: {
861
+ code: {
862
+ description: "JavaScript snippet to evaluate inside the Ringi MCP sandbox.",
863
+ type: "string"
864
+ },
865
+ timeout: {
866
+ description: "Optional timeout in milliseconds. Defaults to 30000 and clamps at 120000.",
867
+ type: "number"
868
+ }
869
+ },
870
+ required: ["code"],
871
+ type: "object"
872
+ },
873
+ name: "execute",
874
+ outputSchema: {
875
+ additionalProperties: false,
876
+ properties: {
877
+ error: { type: "string" },
878
+ ok: { type: "boolean" },
879
+ result: {},
880
+ truncated: { type: "boolean" }
881
+ },
882
+ required: ["ok", "result"],
883
+ type: "object"
884
+ }
885
+ };
886
+ const writeStderr = (message) => {
887
+ process.stderr.write(`[ringi:mcp] ${message}\n`);
888
+ };
889
+ const writeMessage = (message) => {
890
+ const body = JSON.stringify(message);
891
+ const payload = `Content-Length: ${Buffer.byteLength(body, "utf8")}\r\n\r\n${body}`;
892
+ stdout.write(payload);
893
+ };
894
+ const parseContentLength = (headerText) => {
895
+ const headerLine = headerText.split("\r\n").find((line) => line.toLowerCase().startsWith("content-length:"));
896
+ if (!headerLine) throw new Error("Missing Content-Length header");
897
+ const rawValue = headerLine.slice(headerLine.indexOf(":") + 1).trim();
898
+ const parsed = Number.parseInt(rawValue, 10);
899
+ if (!Number.isFinite(parsed) || parsed < 0) throw new Error(`Invalid Content-Length header: ${rawValue}`);
900
+ return parsed;
901
+ };
902
+ const formatError = (error) => {
903
+ if (error instanceof Error) return error.message;
904
+ return String(error);
905
+ };
906
+ const sendError = (id, code, message) => {
907
+ writeMessage({
908
+ error: {
909
+ code,
910
+ message
911
+ },
912
+ id,
913
+ jsonrpc: JSON_RPC_VERSION
914
+ });
915
+ };
916
+ const sendResult = (id, result) => {
917
+ writeMessage({
918
+ id,
919
+ jsonrpc: JSON_RPC_VERSION,
920
+ result
921
+ });
922
+ };
923
+ const createInitializeResult = () => ({
924
+ capabilities: { tools: { listChanged: false } },
925
+ protocolVersion: LATEST_PROTOCOL_VERSION,
926
+ serverInfo: {
927
+ description: "Local-first MCP codemode adapter over the Ringi core runtime.",
928
+ name: MCP_SERVER_NAME,
929
+ version: MCP_SERVER_VERSION
930
+ }
931
+ });
932
+ var StdioJsonRpcServer = class {
933
+ config = resolveMcpConfig(process.argv.slice(2));
934
+ runtime = createMcpRuntime(this.config);
935
+ buffer = Buffer.alloc(0);
936
+ initialized = false;
937
+ shuttingDown = false;
938
+ start() {
939
+ stdin.on("data", async (chunk) => {
940
+ this.buffer = Buffer.concat([this.buffer, chunk]);
941
+ try {
942
+ await this.drainBuffer();
943
+ } catch (error) {
944
+ writeStderr(`fatal buffer drain error: ${formatError(error)}`);
945
+ }
946
+ });
947
+ stdin.on("end", async () => {
948
+ await this.runtime.dispose();
949
+ });
950
+ process.on("SIGINT", async () => {
951
+ await this.close(0);
952
+ });
953
+ process.on("SIGTERM", async () => {
954
+ await this.close(0);
955
+ });
956
+ writeStderr(`server started readonly=${String(this.config.readonly)} repo=${this.config.repoRoot}`);
957
+ }
958
+ async close(code) {
959
+ await this.runtime.dispose();
960
+ process.exit(code);
961
+ }
962
+ async drainBuffer() {
963
+ while (true) {
964
+ const headerEnd = this.buffer.indexOf("\r\n\r\n");
965
+ if (headerEnd === -1) return;
966
+ const contentLength = parseContentLength(this.buffer.subarray(0, headerEnd).toString("utf8"));
967
+ const messageEnd = headerEnd + 4 + contentLength;
968
+ if (this.buffer.byteLength < messageEnd) return;
969
+ const payload = this.buffer.subarray(headerEnd + 4, messageEnd).toString("utf8");
970
+ this.buffer = this.buffer.subarray(messageEnd);
971
+ let message;
972
+ try {
973
+ message = JSON.parse(payload);
974
+ } catch (error) {
975
+ sendError(null, -32700, `Parse error: ${formatError(error)}`);
976
+ continue;
977
+ }
978
+ await this.handleMessage(message);
979
+ }
980
+ }
981
+ async handleMessage(message) {
982
+ if (typeof message.method !== "string") {
983
+ sendError(message.id ?? null, -32600, "Invalid JSON-RPC request");
984
+ return;
985
+ }
986
+ try {
987
+ if (await this.handleLifecycleMessage(message)) return;
988
+ this.assertInitialized();
989
+ if (message.method === "tools/list") {
990
+ sendResult(message.id ?? null, { tools: [EXECUTE_TOOL] });
991
+ return;
992
+ }
993
+ if (message.method === "tools/call") {
994
+ await this.handleToolCall(message.id ?? null, message.params);
995
+ return;
996
+ }
997
+ sendError(message.id ?? null, -32601, `Method not found: ${message.method}`);
998
+ } catch (error) {
999
+ sendError(message.id ?? null, -32603, formatError(error));
1000
+ }
1001
+ }
1002
+ async handleLifecycleMessage(message) {
1003
+ if (message.method === "initialize") {
1004
+ this.initialized = true;
1005
+ sendResult(message.id ?? null, createInitializeResult());
1006
+ return true;
1007
+ }
1008
+ if (message.method === "notifications/initialized") return true;
1009
+ if (message.method === "ping") {
1010
+ sendResult(message.id ?? null, {});
1011
+ return true;
1012
+ }
1013
+ if (message.method === "shutdown") {
1014
+ this.shuttingDown = true;
1015
+ sendResult(message.id ?? null, {});
1016
+ return true;
1017
+ }
1018
+ if (message.method === "exit") {
1019
+ await this.close(this.shuttingDown ? 0 : 1);
1020
+ return true;
1021
+ }
1022
+ return false;
1023
+ }
1024
+ assertInitialized() {
1025
+ if (!this.initialized) throw new Error("Server is not initialized");
1026
+ if (this.shuttingDown) throw new Error("Server is shutting down");
1027
+ }
1028
+ async handleToolCall(id, params) {
1029
+ if (!params || typeof params.name !== "string") {
1030
+ sendError(id, -32602, "Invalid tools/call params");
1031
+ return;
1032
+ }
1033
+ if (params.name !== EXECUTE_TOOL.name) {
1034
+ sendError(id, -32602, `Tool not found: ${String(params.name)}`);
1035
+ return;
1036
+ }
1037
+ const argumentsValue = params.arguments;
1038
+ if (typeof argumentsValue !== "object" || argumentsValue === null) {
1039
+ sendError(id, -32602, "Invalid tools/call arguments");
1040
+ return;
1041
+ }
1042
+ const executeResult = await executeCodeToPromise(this.runtime, this.config, argumentsValue);
1043
+ sendResult(id, {
1044
+ content: [{
1045
+ text: JSON.stringify(executeResult),
1046
+ type: "text"
1047
+ }],
1048
+ isError: !executeResult.ok,
1049
+ structuredContent: executeResult
1050
+ });
1051
+ }
1052
+ };
1053
+ new StdioJsonRpcServer().start();
1054
+ //#endregion
1055
+ export {};
1056
+
1057
+ //# sourceMappingURL=mcp.mjs.map