openmausbot 0.1.55

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 (499) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +14 -0
  3. package/cli.js +2 -0
  4. package/dist/app-icon.svg +29 -0
  5. package/dist/assets/abap-BdImnpbu.js +1 -0
  6. package/dist/assets/actionscript-3-B3316cI-.js +1 -0
  7. package/dist/assets/ada-bCR0ucgS.js +1 -0
  8. package/dist/assets/ahk-CsyLZFj1.js +1 -0
  9. package/dist/assets/ahk2-8Zs4aa1G.js +1 -0
  10. package/dist/assets/andromeeda-C4gqWexZ.js +1 -0
  11. package/dist/assets/angular-html-DA-rfuFy.js +1 -0
  12. package/dist/assets/angular-ts-BrjP3tb8.js +1 -0
  13. package/dist/assets/apache-Pmp26Uib.js +1 -0
  14. package/dist/assets/apex-DhZFqWV2.js +1 -0
  15. package/dist/assets/apl-CORt7UWP.js +1 -0
  16. package/dist/assets/applescript-Co6uUVPk.js +1 -0
  17. package/dist/assets/ara-BRHolxvo.js +1 -0
  18. package/dist/assets/asciidoc-CSVQ5wI8.js +1 -0
  19. package/dist/assets/asm-D_Q5rh1f.js +1 -0
  20. package/dist/assets/astro-HNnZUWAn.js +1 -0
  21. package/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
  22. package/dist/assets/awk-DMzUqQB5.js +1 -0
  23. package/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
  24. package/dist/assets/ayu-light-BA47KaF1.js +1 -0
  25. package/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
  26. package/dist/assets/ballerina-BFfxhgS-.js +1 -0
  27. package/dist/assets/bat-CickPsom.js +1 -0
  28. package/dist/assets/beancount-k_qm7-4y.js +1 -0
  29. package/dist/assets/berry-uYugtg8r.js +1 -0
  30. package/dist/assets/bibtex-CHM0blh-.js +1 -0
  31. package/dist/assets/bicep-Bmn6On1c.js +1 -0
  32. package/dist/assets/bird2-Bx8U0n9b.js +1 -0
  33. package/dist/assets/blade-2xfisSek.js +1 -0
  34. package/dist/assets/bsl-DlhNcFeZ.js +1 -0
  35. package/dist/assets/c-BIGW1oBm.js +1 -0
  36. package/dist/assets/c3-Dp5svz6Z.js +1 -0
  37. package/dist/assets/cadence-Bv_4Rxtq.js +1 -0
  38. package/dist/assets/cairo-KRGpt6FW.js +1 -0
  39. package/dist/assets/catppuccin-frappe-CZL1YF0i.js +1 -0
  40. package/dist/assets/catppuccin-latte-DH-8KZSZ.js +1 -0
  41. package/dist/assets/catppuccin-macchiato-B7yYVSCf.js +1 -0
  42. package/dist/assets/catppuccin-mocha-Ct7hS0mc.js +1 -0
  43. package/dist/assets/chapel-DTp_pixX.js +1 -0
  44. package/dist/assets/clarity-Dn5IMItf.js +1 -0
  45. package/dist/assets/clojure-P80f7IUj.js +1 -0
  46. package/dist/assets/cmake-D1j8_8rp.js +1 -0
  47. package/dist/assets/cobol-nBiQ_Alo.js +1 -0
  48. package/dist/assets/codeowners-Bp6g37R7.js +1 -0
  49. package/dist/assets/codeql-DsOJ9woJ.js +1 -0
  50. package/dist/assets/coffee-Ch7k5sss.js +1 -0
  51. package/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
  52. package/dist/assets/coq-C7JzOVbR.js +1 -0
  53. package/dist/assets/cpp-BMRokrvK.js +1 -0
  54. package/dist/assets/crystal-DGywbUpC.js +1 -0
  55. package/dist/assets/csharp-DSvCPggb.js +1 -0
  56. package/dist/assets/css-CLj8gQPS.js +1 -0
  57. package/dist/assets/csv-fuZLfV_i.js +1 -0
  58. package/dist/assets/cue-D82EKSYY.js +1 -0
  59. package/dist/assets/cypher-COkxafJQ.js +1 -0
  60. package/dist/assets/d-85-TOEBH.js +1 -0
  61. package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
  62. package/dist/assets/dart-bE4Kk8sk.js +1 -0
  63. package/dist/assets/dax-CEL-wOlO.js +1 -0
  64. package/dist/assets/desktop-BmXAJ9_W.js +1 -0
  65. package/dist/assets/diff-D97Zzqfu.js +1 -0
  66. package/dist/assets/docker-BcOcwvcX.js +1 -0
  67. package/dist/assets/dotenv-Da5cRb03.js +1 -0
  68. package/dist/assets/dracula-BzJJZx-M.js +1 -0
  69. package/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
  70. package/dist/assets/dream-maker-BtqSS_iP.js +1 -0
  71. package/dist/assets/edge-FbVlp4U3.js +1 -0
  72. package/dist/assets/elixir-CkH2-t6x.js +1 -0
  73. package/dist/assets/elm-DbKCFpqz.js +1 -0
  74. package/dist/assets/emacs-lisp-C_m_b--Z.js +1 -0
  75. package/dist/assets/erb-DXfck5VN.js +1 -0
  76. package/dist/assets/erlang-DsQrWhSR.js +1 -0
  77. package/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
  78. package/dist/assets/everforest-light-C8M2exoo.js +1 -0
  79. package/dist/assets/fennel-BYunw83y.js +1 -0
  80. package/dist/assets/fish-BvzEVeQv.js +1 -0
  81. package/dist/assets/fluent-C4IJs8-o.js +1 -0
  82. package/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  83. package/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
  84. package/dist/assets/fsharp-CXgrBDvD.js +1 -0
  85. package/dist/assets/gdresource-TyuKm33G.js +1 -0
  86. package/dist/assets/gdscript-DqcFQ5yU.js +1 -0
  87. package/dist/assets/gdshader-DkwncUOv.js +1 -0
  88. package/dist/assets/genie-D0YGMca9.js +1 -0
  89. package/dist/assets/gherkin-DyxjwDmM.js +1 -0
  90. package/dist/assets/git-commit-F4YmCXRG.js +1 -0
  91. package/dist/assets/git-rebase-r7XF79zn.js +1 -0
  92. package/dist/assets/github-dark-DHJKELXO.js +1 -0
  93. package/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
  94. package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  95. package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  96. package/dist/assets/github-light-DAi9KRSo.js +1 -0
  97. package/dist/assets/github-light-default-D7oLnXFd.js +1 -0
  98. package/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  99. package/dist/assets/gleam-BspZqrRM.js +1 -0
  100. package/dist/assets/glimmer-js-ByusRIyA.js +1 -0
  101. package/dist/assets/glimmer-ts-BfAWNZQY.js +1 -0
  102. package/dist/assets/glsl-DplSGwfg.js +1 -0
  103. package/dist/assets/gn-n2N0HUVH.js +1 -0
  104. package/dist/assets/gnuplot-DdkO51Og.js +1 -0
  105. package/dist/assets/go-C27-OAKa.js +1 -0
  106. package/dist/assets/graphql-ChdNCCLP.js +1 -0
  107. package/dist/assets/groovy-gcz8RCvz.js +1 -0
  108. package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  109. package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  110. package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  111. package/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  112. package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  113. package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  114. package/dist/assets/hack-BWmVpMyf.js +1 -0
  115. package/dist/assets/haml-D5jkg6IW.js +1 -0
  116. package/dist/assets/handlebars-BpdQsYii.js +1 -0
  117. package/dist/assets/haskell-Df6bDoY_.js +1 -0
  118. package/dist/assets/haxe-CfZj7gIn.js +1 -0
  119. package/dist/assets/hcl-BWvSN4gD.js +1 -0
  120. package/dist/assets/hjson-D5-asLiD.js +1 -0
  121. package/dist/assets/hlsl-D3lLCCz7.js +1 -0
  122. package/dist/assets/horizon-BUw7H-hv.js +1 -0
  123. package/dist/assets/horizon-bright-CUuTKBJd.js +1 -0
  124. package/dist/assets/houston-DnULxvSX.js +1 -0
  125. package/dist/assets/html-derivative-DlHx6ybY.js +1 -0
  126. package/dist/assets/html-pp8916En.js +1 -0
  127. package/dist/assets/http-jrhK8wxY.js +1 -0
  128. package/dist/assets/hurl-irOxFIW8.js +1 -0
  129. package/dist/assets/hxml-2-FPmUDs.js +1 -0
  130. package/dist/assets/hy-DFXneXwc.js +1 -0
  131. package/dist/assets/imba-DGztddWO.js +1 -0
  132. package/dist/assets/index-B9rLIY81.js +263 -0
  133. package/dist/assets/index-CJBrtDbC.css +1 -0
  134. package/dist/assets/index-D-u0LYsV.js +153 -0
  135. package/dist/assets/ini-BEwlwnbL.js +1 -0
  136. package/dist/assets/java-CylS5w8V.js +1 -0
  137. package/dist/assets/javascript-wDzz0qaB.js +1 -0
  138. package/dist/assets/jinja-f2NsQr07.js +1 -0
  139. package/dist/assets/jison-wvAkD_A8.js +1 -0
  140. package/dist/assets/json-Cp-IABpG.js +1 -0
  141. package/dist/assets/json5-C9tS-k6U.js +1 -0
  142. package/dist/assets/jsonc-Des-eS-w.js +1 -0
  143. package/dist/assets/jsonl-DcaNXYhu.js +1 -0
  144. package/dist/assets/jsonnet-DFQXde-d.js +1 -0
  145. package/dist/assets/jssm-C2t-YnRu.js +1 -0
  146. package/dist/assets/jsx-g9-lgVsj.js +1 -0
  147. package/dist/assets/julia-5Bft2YPA.js +1 -0
  148. package/dist/assets/just-Cwhn7H3k.js +1 -0
  149. package/dist/assets/kanagawa-dragon-BuwD2xS4.js +1 -0
  150. package/dist/assets/kanagawa-lotus-C3DzagqV.js +1 -0
  151. package/dist/assets/kanagawa-wave-DFGoQZhC.js +1 -0
  152. package/dist/assets/kdl-DV7GczEv.js +1 -0
  153. package/dist/assets/kotlin-BdnUsdx6.js +1 -0
  154. package/dist/assets/kusto-wEQ09or8.js +1 -0
  155. package/dist/assets/laserwave-DUszq2jm.js +1 -0
  156. package/dist/assets/latex-D5pSuvFb.js +1 -0
  157. package/dist/assets/lean-BZvkOJ9d.js +1 -0
  158. package/dist/assets/less-B1dDrJ26.js +1 -0
  159. package/dist/assets/light-plus-B7mTdjB0.js +1 -0
  160. package/dist/assets/liquid-C0sCDyMI.js +1 -0
  161. package/dist/assets/llvm-BZoOZj88.js +1 -0
  162. package/dist/assets/log-2UxHyX5q.js +1 -0
  163. package/dist/assets/logo-BtOb2qkB.js +1 -0
  164. package/dist/assets/lua-BaeVxFsk.js +1 -0
  165. package/dist/assets/luau-BnpPk5vE.js +1 -0
  166. package/dist/assets/make-CHLpvVh8.js +1 -0
  167. package/dist/assets/markdown-Cvjx9yec.js +1 -0
  168. package/dist/assets/marko-DjSrsDqO.js +1 -0
  169. package/dist/assets/material-theme-D5KoaKCx.js +1 -0
  170. package/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
  171. package/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  172. package/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
  173. package/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  174. package/dist/assets/matlab-D7o27uSR.js +1 -0
  175. package/dist/assets/mdc-D1_yUvq7.js +1 -0
  176. package/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  177. package/dist/assets/mermaid-CQcHuHx7.js +1 -0
  178. package/dist/assets/min-dark-CafNBF8u.js +1 -0
  179. package/dist/assets/min-light-CTRr51gU.js +1 -0
  180. package/dist/assets/mipsasm-CKIfxQSi.js +1 -0
  181. package/dist/assets/mojo-DJz3ZmWd.js +1 -0
  182. package/dist/assets/monokai-BRVnQi9A.js +1 -0
  183. package/dist/assets/moonbit-CHtswR0a.js +1 -0
  184. package/dist/assets/move-el3G9tDJ.js +1 -0
  185. package/dist/assets/narrat-DRg8JJMk.js +1 -0
  186. package/dist/assets/nextflow-C-mBbutL.js +1 -0
  187. package/dist/assets/nextflow-groovy-vE_lwT2v.js +1 -0
  188. package/dist/assets/nginx-BpAMiNFr.js +1 -0
  189. package/dist/assets/night-owl-C39BiMTA.js +1 -0
  190. package/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
  191. package/dist/assets/nim-BIad80T-.js +1 -0
  192. package/dist/assets/nix-CwoSXNpI.js +1 -0
  193. package/dist/assets/nord-Ddv68eIx.js +1 -0
  194. package/dist/assets/nsis-BlV79W_Q.js +1 -0
  195. package/dist/assets/nushell-D3jzshHO.js +1 -0
  196. package/dist/assets/objective-c-DXmwc3jG.js +1 -0
  197. package/dist/assets/objective-cpp-CLxacb5B.js +1 -0
  198. package/dist/assets/ocaml-C0hk2d4L.js +1 -0
  199. package/dist/assets/odin-BBf5iR-q.js +1 -0
  200. package/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  201. package/dist/assets/one-light-C3Wv6jpd.js +1 -0
  202. package/dist/assets/openscad-C4EeE6gA.js +1 -0
  203. package/dist/assets/org-DM6o9KBp.js +1 -0
  204. package/dist/assets/pascal-D93ZcfNL.js +1 -0
  205. package/dist/assets/perl-B9cMNwum.js +1 -0
  206. package/dist/assets/php-Csjmro_R.js +1 -0
  207. package/dist/assets/pkl-u5AG7uiY.js +1 -0
  208. package/dist/assets/plastic-3e1v2bzS.js +1 -0
  209. package/dist/assets/plsql-ChMvpjG-.js +1 -0
  210. package/dist/assets/po-BTJTHyun.js +1 -0
  211. package/dist/assets/poimandres-CS3Unz2-.js +1 -0
  212. package/dist/assets/polar-C0HS_06l.js +1 -0
  213. package/dist/assets/postcss-CXtECtnM.js +1 -0
  214. package/dist/assets/powerquery-CEu0bR-o.js +1 -0
  215. package/dist/assets/powershell-BmBUJMz7.js +1 -0
  216. package/dist/assets/prisma-Vru482bI.js +1 -0
  217. package/dist/assets/prolog-CbFg5uaA.js +1 -0
  218. package/dist/assets/proto-C7zT0LnQ.js +1 -0
  219. package/dist/assets/pug-DKIMFp6K.js +1 -0
  220. package/dist/assets/puppet-BMWR74SV.js +1 -0
  221. package/dist/assets/purescript-CklMAg4u.js +1 -0
  222. package/dist/assets/python-B6aJPvgy.js +1 -0
  223. package/dist/assets/qml-3beO22l8.js +1 -0
  224. package/dist/assets/qmldir-C8lEn-DE.js +1 -0
  225. package/dist/assets/qss-IeuSbFQv.js +1 -0
  226. package/dist/assets/r-Cf5RLm7j.js +1 -0
  227. package/dist/assets/racket-BqYA7rlc.js +1 -0
  228. package/dist/assets/raku-DXvB9xmW.js +1 -0
  229. package/dist/assets/razor-BjBPvh-w.js +1 -0
  230. package/dist/assets/rbs-CpoqiR4B.js +1 -0
  231. package/dist/assets/red-hvxz__6c.js +1 -0
  232. package/dist/assets/reg-C-SQnVFl.js +1 -0
  233. package/dist/assets/regexp-CDVJQ6XC.js +1 -0
  234. package/dist/assets/rel-C3B-1QV4.js +1 -0
  235. package/dist/assets/riscv-BM1_JUlF.js +1 -0
  236. package/dist/assets/ron-D8l8udqQ.js +1 -0
  237. package/dist/assets/rose-pine-5qJOZa0Y.js +1 -0
  238. package/dist/assets/rose-pine-dawn-zx0QlTCp.js +1 -0
  239. package/dist/assets/rose-pine-moon-C9pEdX9L.js +1 -0
  240. package/dist/assets/rosmsg-BJDFO7_C.js +1 -0
  241. package/dist/assets/rst-bs7f0vWN.js +1 -0
  242. package/dist/assets/ruby-C0TQ7zu5.js +1 -0
  243. package/dist/assets/rust-B1yitclQ.js +1 -0
  244. package/dist/assets/sas-DEy46yEz.js +1 -0
  245. package/dist/assets/sass-Cj5Yp3dK.js +1 -0
  246. package/dist/assets/scala-CqE71os6.js +1 -0
  247. package/dist/assets/scheme-C98Dy4si.js +1 -0
  248. package/dist/assets/scss-D5BDwBP9.js +1 -0
  249. package/dist/assets/sdbl-DVxCFoDh.js +1 -0
  250. package/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
  251. package/dist/assets/shellscript-Yzrsuije.js +1 -0
  252. package/dist/assets/shellsession-BADoaaVG.js +1 -0
  253. package/dist/assets/slack-dark-BthQWCQV.js +1 -0
  254. package/dist/assets/slack-ochin-DqwNpetd.js +1 -0
  255. package/dist/assets/smalltalk-BOQMe2GC.js +1 -0
  256. package/dist/assets/smithy-cds9vsN8.js +1 -0
  257. package/dist/assets/snazzy-light-Bw305WKR.js +1 -0
  258. package/dist/assets/solarized-dark-CpvCGNkr.js +1 -0
  259. package/dist/assets/solarized-light-Dlz6yCKv.js +1 -0
  260. package/dist/assets/solidity-DijEV5ha.js +1 -0
  261. package/dist/assets/soy-8wufbnw4.js +1 -0
  262. package/dist/assets/sparql-rVzFXLq3.js +1 -0
  263. package/dist/assets/splunk-BtCnVYZw.js +1 -0
  264. package/dist/assets/sql-CRqJ_cUM.js +1 -0
  265. package/dist/assets/ssh-config-_ykCGR6B.js +1 -0
  266. package/dist/assets/stata-DI20mbqo.js +1 -0
  267. package/dist/assets/stylus-BEDo0Tqx.js +1 -0
  268. package/dist/assets/surrealql-Cjom0U5J.js +1 -0
  269. package/dist/assets/svelte-Cy7k_4gC.js +1 -0
  270. package/dist/assets/swift-C2oV4EkX.js +1 -0
  271. package/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
  272. package/dist/assets/system-verilog-0hqHdDBg.js +1 -0
  273. package/dist/assets/systemd-4A_iFExJ.js +1 -0
  274. package/dist/assets/talonscript-CkByrt1z.js +1 -0
  275. package/dist/assets/tasl-QIJgUcNo.js +1 -0
  276. package/dist/assets/tcl-dwOrl1Do.js +1 -0
  277. package/dist/assets/templ-DhtptRzy.js +1 -0
  278. package/dist/assets/terraform-BETggiCN.js +1 -0
  279. package/dist/assets/tex-D96PA37w.js +1 -0
  280. package/dist/assets/tokyo-night-hegEt444.js +1 -0
  281. package/dist/assets/toml-vGWfd6FD.js +1 -0
  282. package/dist/assets/ts-tags-D351s5mN.js +1 -0
  283. package/dist/assets/tsv-B_m7g4N7.js +1 -0
  284. package/dist/assets/tsx-COt5Ahok.js +1 -0
  285. package/dist/assets/turtle-BsS91CYL.js +1 -0
  286. package/dist/assets/twig-27uCiNez.js +1 -0
  287. package/dist/assets/typescript-BPQ3VLAy.js +1 -0
  288. package/dist/assets/typespec-CAFt9gP4.js +1 -0
  289. package/dist/assets/typst-BUadGCkm.js +1 -0
  290. package/dist/assets/v-BGw2Nkan.js +1 -0
  291. package/dist/assets/vala-CsfeWuGM.js +1 -0
  292. package/dist/assets/vb-Cu-pLBUe.js +1 -0
  293. package/dist/assets/verilog-nZwndyjY.js +1 -0
  294. package/dist/assets/vesper-DRje8inN.js +1 -0
  295. package/dist/assets/vhdl-CeAyd5Ju.js +1 -0
  296. package/dist/assets/viml-CJc9bBzg.js +1 -0
  297. package/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
  298. package/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
  299. package/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
  300. package/dist/assets/vue-BqiEGhQt.js +1 -0
  301. package/dist/assets/vue-html-AaS7Mt5G.js +1 -0
  302. package/dist/assets/vue-vine-BoDAl6tE.js +1 -0
  303. package/dist/assets/vyper-CDx5xZoG.js +1 -0
  304. package/dist/assets/wasm-CG6Dc4jp.js +1 -0
  305. package/dist/assets/wasm-MzD3tlZU.js +1 -0
  306. package/dist/assets/wenyan-BV7otONQ.js +1 -0
  307. package/dist/assets/wgsl-Dx-B1_4e.js +1 -0
  308. package/dist/assets/wikitext-BhOHFoWU.js +1 -0
  309. package/dist/assets/wit-5i3qLPDT.js +1 -0
  310. package/dist/assets/wolfram-lXgVvXCa.js +1 -0
  311. package/dist/assets/xml-sdJ4AIDG.js +1 -0
  312. package/dist/assets/xsl-CtQFsRM5.js +1 -0
  313. package/dist/assets/yaml-Buea-lGh.js +1 -0
  314. package/dist/assets/zenscript-DVFEvuxE.js +1 -0
  315. package/dist/assets/zig-VOosw3JB.js +1 -0
  316. package/dist/index.html +14 -0
  317. package/dist-server/companion/src/listener.js +187 -0
  318. package/dist-server/computer-proxy.js +1185 -0
  319. package/dist-server/connector-proxy.js +186 -0
  320. package/dist-server/container-mcp.js +15186 -0
  321. package/dist-server/drivers/agents-proxy.js +887 -0
  322. package/dist-server/drivers/browser-proxy.js +15037 -0
  323. package/dist-server/drivers/dweb-proxy.js +175 -0
  324. package/dist-server/drivers/phone-proxy.js +339 -0
  325. package/dist-server/drivers/pi-mcp-extension.ts +638 -0
  326. package/dist-server/index.js +64869 -0
  327. package/dist-server/local-computer.js +198 -0
  328. package/dist-server/mcp-server.js +1233 -0
  329. package/dist-server/openmausbot.js +3671 -0
  330. package/dist-server/pair-cli.js +3671 -0
  331. package/dist-server/permission-proxy.js +126 -0
  332. package/dist-server/prepare-cloudflared.js +253 -0
  333. package/dist-server/proxy-paths.js +29 -0
  334. package/dist-server/server/atomic.js +40 -0
  335. package/dist-server/server/attachments.js +471 -0
  336. package/dist-server/server/auto-approve.js +162 -0
  337. package/dist-server/server/auto-review.js +79 -0
  338. package/dist-server/server/avatar-image.js +144 -0
  339. package/dist-server/server/bot-cwd.js +29 -0
  340. package/dist-server/server/bot-directory.js +127 -0
  341. package/dist-server/server/bot-package.js +268 -0
  342. package/dist-server/server/bot-profile.js +76 -0
  343. package/dist-server/server/box-create-idempotency.js +463 -0
  344. package/dist-server/server/box.js +944 -0
  345. package/dist-server/server/brand.js +65 -0
  346. package/dist-server/server/browser-connection.js +187 -0
  347. package/dist-server/server/browser-lifecycle-cleanup.js +359 -0
  348. package/dist-server/server/calendar-calls.js +314 -0
  349. package/dist-server/server/channel-queue.js +70 -0
  350. package/dist-server/server/checkpoints.js +405 -0
  351. package/dist-server/server/chief-of-staff.js +49 -0
  352. package/dist-server/server/claude-update.js +70 -0
  353. package/dist-server/server/cli.js +524 -0
  354. package/dist-server/server/cloud-backend.js +30 -0
  355. package/dist-server/server/comms-visibility.js +109 -0
  356. package/dist-server/server/composio.js +945 -0
  357. package/dist-server/server/computer-control.js +149 -0
  358. package/dist-server/server/computer-observation.js +133 -0
  359. package/dist-server/server/computer-proxy.js +1061 -0
  360. package/dist-server/server/config.js +760 -0
  361. package/dist-server/server/connector-proxy.js +228 -0
  362. package/dist-server/server/container-computer.js +840 -0
  363. package/dist-server/server/container-mcp.js +27 -0
  364. package/dist-server/server/contracts.js +24 -0
  365. package/dist-server/server/control-client.js +100 -0
  366. package/dist-server/server/data-dir-lease.js +3 -0
  367. package/dist-server/server/decision-log.js +106 -0
  368. package/dist-server/server/delegations.js +628 -0
  369. package/dist-server/server/drivers/acp/core.js +904 -0
  370. package/dist-server/server/drivers/acp/cursor.js +365 -0
  371. package/dist-server/server/drivers/acp/custom.js +51 -0
  372. package/dist-server/server/drivers/acp/droid.js +225 -0
  373. package/dist-server/server/drivers/acp/gemini.js +95 -0
  374. package/dist-server/server/drivers/acp/grok.js +249 -0
  375. package/dist-server/server/drivers/acp/hermes.js +429 -0
  376. package/dist-server/server/drivers/acp/kimi.js +559 -0
  377. package/dist-server/server/drivers/acp/opencode-go.js +370 -0
  378. package/dist-server/server/drivers/acp/qwen.js +98 -0
  379. package/dist-server/server/drivers/agents-proxy.js +941 -0
  380. package/dist-server/server/drivers/antigravity-acp.js +507 -0
  381. package/dist-server/server/drivers/antigravity-release.js +65 -0
  382. package/dist-server/server/drivers/antigravity-runtime.js +395 -0
  383. package/dist-server/server/drivers/antigravity.js +144 -0
  384. package/dist-server/server/drivers/boxagent.js +245 -0
  385. package/dist-server/server/drivers/browser-proxy.js +520 -0
  386. package/dist-server/server/drivers/builtIn.js +36 -0
  387. package/dist-server/server/drivers/claude.js +1337 -0
  388. package/dist-server/server/drivers/codex-catalog.js +409 -0
  389. package/dist-server/server/drivers/codex.js +1116 -0
  390. package/dist-server/server/drivers/dweb-proxy.js +193 -0
  391. package/dist-server/server/drivers/grok.js +48 -0
  392. package/dist-server/server/drivers/grokagent.js +4 -0
  393. package/dist-server/server/drivers/local-inject.js +388 -0
  394. package/dist-server/server/drivers/minimax.js +108 -0
  395. package/dist-server/server/drivers/native.js +21 -0
  396. package/dist-server/server/drivers/openai-chat.js +240 -0
  397. package/dist-server/server/drivers/openai-compat.js +143 -0
  398. package/dist-server/server/drivers/phone-proxy.js +372 -0
  399. package/dist-server/server/drivers/pi.js +855 -0
  400. package/dist-server/server/drivers/retry.js +96 -0
  401. package/dist-server/server/enterprise.js +93 -0
  402. package/dist-server/server/env-path.js +329 -0
  403. package/dist-server/server/environment.js +105 -0
  404. package/dist-server/server/generated-image.js +39 -0
  405. package/dist-server/server/graceful-shutdown.js +24 -0
  406. package/dist-server/server/group-goal-run.js +124 -0
  407. package/dist-server/server/harness/bus.js +86 -0
  408. package/dist-server/server/harness/registry.js +217 -0
  409. package/dist-server/server/index.js +11634 -0
  410. package/dist-server/server/installed-playbooks.js +34 -0
  411. package/dist-server/server/local-computer.js +278 -0
  412. package/dist-server/server/local-routing.js +9 -0
  413. package/dist-server/server/local-vm-idle.js +44 -0
  414. package/dist-server/server/local-vm-inventory.js +34 -0
  415. package/dist-server/server/local-vm-lease.js +58 -0
  416. package/dist-server/server/mcp-bridge.js +251 -0
  417. package/dist-server/server/mcp-probe.js +153 -0
  418. package/dist-server/server/mcp-registry.js +130 -0
  419. package/dist-server/server/member-turn.js +6 -0
  420. package/dist-server/server/message-db.js +358 -0
  421. package/dist-server/server/message-file.js +439 -0
  422. package/dist-server/server/names.js +26 -0
  423. package/dist-server/server/notify.js +69 -0
  424. package/dist-server/server/openmaus-status-capsule.js +329 -0
  425. package/dist-server/server/openmausbot.js +6 -0
  426. package/dist-server/server/package-export.js +157 -0
  427. package/dist-server/server/pair-cli.js +7 -0
  428. package/dist-server/server/peer-approval-key.js +5 -0
  429. package/dist-server/server/peer-approval.js +182 -0
  430. package/dist-server/server/peer-provenance.js +44 -0
  431. package/dist-server/server/peer-roster.js +139 -0
  432. package/dist-server/server/permission-proxy.js +157 -0
  433. package/dist-server/server/phone-secret.js +358 -0
  434. package/dist-server/server/private-screen-capture.js +17 -0
  435. package/dist-server/server/procs.js +123 -0
  436. package/dist-server/server/project-scout.js +304 -0
  437. package/dist-server/server/proxy-paths.js +47 -0
  438. package/dist-server/server/redact.js +102 -0
  439. package/dist-server/server/remote-computer.js +170 -0
  440. package/dist-server/server/repeat-detector.js +48 -0
  441. package/dist-server/server/replies.js +38 -0
  442. package/dist-server/server/request-auth.js +327 -0
  443. package/dist-server/server/room-cwd.js +15 -0
  444. package/dist-server/server/room-post-budget.js +112 -0
  445. package/dist-server/server/room-turn-timeout.js +115 -0
  446. package/dist-server/server/routine-requests.js +871 -0
  447. package/dist-server/server/routines.js +1111 -0
  448. package/dist-server/server/schema.js +11 -0
  449. package/dist-server/server/screen-frame-gate.js +80 -0
  450. package/dist-server/server/section-context.js +85 -0
  451. package/dist-server/server/send-idempotency.js +53 -0
  452. package/dist-server/server/sessions.js +319 -0
  453. package/dist-server/server/skill-fetch.js +148 -0
  454. package/dist-server/server/skill-learn.js +61 -0
  455. package/dist-server/server/skill-library.js +116 -0
  456. package/dist-server/server/skills.js +1223 -0
  457. package/dist-server/server/steer-queue.js +114 -0
  458. package/dist-server/server/store.js +1217 -0
  459. package/dist-server/server/surface.js +107 -0
  460. package/dist-server/server/tailscale.js +103 -0
  461. package/dist-server/server/team-backup.js +183 -0
  462. package/dist-server/server/team-library.js +205 -0
  463. package/dist-server/server/team-manifest.js +224 -0
  464. package/dist-server/server/thread-events.js +226 -0
  465. package/dist-server/server/tts/elevenlabs.js +92 -0
  466. package/dist-server/server/tts/index.js +79 -0
  467. package/dist-server/server/tts/speech-text.js +195 -0
  468. package/dist-server/server/tts/system-voices.js +74 -0
  469. package/dist-server/server/tunnel.js +202 -0
  470. package/dist-server/server/turn-context.js +40 -0
  471. package/dist-server/server/turn-dispatch-guard.js +152 -0
  472. package/dist-server/server/turn-images.js +138 -0
  473. package/dist-server/server/turn-watchdog.js +65 -0
  474. package/dist-server/server/vps-computer.js +1099 -0
  475. package/dist-server/server/vps-container-mcp.js +31 -0
  476. package/dist-server/server/webhook-ingress.js +173 -0
  477. package/dist-server/server/webhooks.js +491 -0
  478. package/dist-server/server/workspace.js +178 -0
  479. package/dist-server/shared/approval-mode.js +39 -0
  480. package/dist-server/shared/bot-avatar.js +33 -0
  481. package/dist-server/shared/bot-profile.js +7 -0
  482. package/dist-server/shared/connector-availability.js +12 -0
  483. package/dist-server/shared/credential-request.js +82 -0
  484. package/dist-server/shared/group-goal-run.js +1 -0
  485. package/dist-server/shared/import-name.js +11 -0
  486. package/dist-server/shared/mascot-bodies.js +107 -0
  487. package/dist-server/shared/routine-request.js +10 -0
  488. package/dist-server/shared/routine-run.js +1 -0
  489. package/dist-server/shared/skill-request.js +16 -0
  490. package/dist-server/shared/team-backup.js +148 -0
  491. package/dist-server/src/lib/composer-attachments.js +676 -0
  492. package/dist-server/tunnel-guardian.js +390 -0
  493. package/dist-server/vps-container-mcp.js +15209 -0
  494. package/package.json +32 -0
  495. package/skills/create-verification-skill/SKILL.md +65 -0
  496. package/skills/create-verification-skill/manifest.json +13 -0
  497. package/skills/phone-harness/SKILL.md +26 -0
  498. package/skills/phone-harness/agents/openai.yaml +13 -0
  499. package/skills/phone-harness/manifest.json +17 -0
@@ -0,0 +1,251 @@
1
+ // The one transparent stdio bridge behind both MCP entry points
2
+ // (container-mcp.ts for the Local VM, vps-container-mcp.ts for the BYO VPS).
3
+ // It defines no tools and parses no MCP messages: bytes in, bytes out.
4
+ //
5
+ // The single exception to that transparency is the who-is-driving gate
6
+ // (opt-in via `gate`). While the person holds control of this computer in
7
+ // the app, a `tools/call` from the agent is answered with a refusal HERE,
8
+ // on the near side, and never forwarded — Cua Driver on the far side has
9
+ // no concept of a person holding the wheel, so the refusal cannot come
10
+ // from anywhere else. Everything that is not a tools/call still passes
11
+ // through untouched, and with no gate configured the bridge remains the
12
+ // byte-for-byte pipe described above.
13
+ //
14
+ // Two behaviors live here so neither entry point can drift:
15
+ // 1. Exit without truncation. `process.exit()` in a close/error handler
16
+ // discards whatever is still buffered on stdout — a final MCP result
17
+ // would be cut mid-frame. The bridge sets exitCode and unpipes instead,
18
+ // letting stdio drain before the process ends on its own.
19
+ // 2. A dead-transport watchdog (opt-in via `liveness`). docker's ssh
20
+ // connection helper accepts no ConnectTimeout/ServerAlive options, so a
21
+ // VPS dropping mid-turn leaves the exec silently wedged until the OS
22
+ // gives up — the harness sees a hung tool call, not an error.
23
+ import { spawn } from "node:child_process";
24
+ import { StringDecoder } from "node:string_decoder";
25
+ import { CONTROL_REFUSAL_PLAIN, createControlClient } from "./control-client.js";
26
+ import { augmentedPath } from "./env-path.js";
27
+ // 45s of TOTAL silence before the bridge even probes. An MCP session is
28
+ // legitimately quiet between tool calls and a slow screenshot can take tens
29
+ // of seconds, so silence alone never kills anything — it only triggers a
30
+ // liveness probe, and only a probe that FAILS ends the bridge. Any byte on
31
+ // stdin/stdout/stderr resets the window.
32
+ export const BRIDGE_INACTIVITY_MS = 45_000;
33
+ const PROBE_TIMEOUT_MS = 10_000;
34
+ /** Run the liveness command; alive means "exited 0 within the timeout". The
35
+ * probe is its own short-lived process, so it cannot inherit the wedged
36
+ * connection it is diagnosing. */
37
+ export function runLivenessProbe(probe, timeoutMs = PROBE_TIMEOUT_MS) {
38
+ return new Promise((resolve) => {
39
+ const child = spawn(probe.command, probe.args, {
40
+ shell: false,
41
+ env: { ...process.env, PATH: augmentedPath() },
42
+ stdio: ["ignore", "ignore", "ignore"],
43
+ });
44
+ const timer = setTimeout(() => {
45
+ child.kill("SIGKILL");
46
+ resolve(false);
47
+ }, timeoutMs);
48
+ timer.unref?.();
49
+ child.on("error", () => {
50
+ clearTimeout(timer);
51
+ resolve(false);
52
+ });
53
+ child.on("close", (code) => {
54
+ clearTimeout(timer);
55
+ resolve(code === 0);
56
+ });
57
+ });
58
+ }
59
+ /** Inactivity → probe → (only then) declare dead. Traffic arriving while a
60
+ * probe is in flight vetoes even a failed probe: bytes are better evidence
61
+ * of life than a health command racing a congested link. */
62
+ export function createInactivityWatchdog(options) {
63
+ let timer = null;
64
+ let stopped = false;
65
+ let probing = false;
66
+ let touchedWhileProbing = false;
67
+ const arm = () => {
68
+ if (stopped)
69
+ return;
70
+ timer = setTimeout(fire, options.inactivityMs);
71
+ timer.unref?.();
72
+ };
73
+ const settleProbe = (alive) => {
74
+ probing = false;
75
+ if (stopped)
76
+ return;
77
+ if (alive || touchedWhileProbing) {
78
+ arm();
79
+ return;
80
+ }
81
+ options.onDead();
82
+ };
83
+ const fire = () => {
84
+ probing = true;
85
+ touchedWhileProbing = false;
86
+ void options.probe().then(settleProbe, () => settleProbe(false));
87
+ };
88
+ arm();
89
+ return {
90
+ touch() {
91
+ if (stopped)
92
+ return;
93
+ if (probing) {
94
+ touchedWhileProbing = true;
95
+ return;
96
+ }
97
+ if (timer)
98
+ clearTimeout(timer);
99
+ arm();
100
+ },
101
+ stop() {
102
+ stopped = true;
103
+ if (timer)
104
+ clearTimeout(timer);
105
+ },
106
+ };
107
+ }
108
+ /** Collect a byte stream into complete newline-terminated lines. MCP's
109
+ * stdio transport is one JSON-RPC frame per line, so line boundaries are
110
+ * the only safe place to inspect — or inject — anything. */
111
+ export function createLineSplitter(onLine) {
112
+ let pending = "";
113
+ const decoder = new StringDecoder("utf8");
114
+ return {
115
+ push(chunk) {
116
+ pending += typeof chunk === "string" ? chunk : decoder.write(chunk);
117
+ let newline;
118
+ while ((newline = pending.indexOf("\n")) !== -1) {
119
+ const line = pending.slice(0, newline);
120
+ pending = pending.slice(newline + 1);
121
+ onLine(line);
122
+ }
123
+ },
124
+ flush() {
125
+ pending += decoder.end();
126
+ if (pending)
127
+ onLine(pending);
128
+ pending = "";
129
+ },
130
+ };
131
+ }
132
+ /** The gate itself, factored free of process wiring so a test can drive it
133
+ * with plain strings. Frames are handled on a serialized queue: the
134
+ * held-check is async, and answering frame N+1 before frame N would
135
+ * reorder the agent's protocol stream. Only a `tools/call` is ever
136
+ * refused; every other frame — handshakes, tools/list, notifications,
137
+ * lines that are not JSON — passes through untouched. */
138
+ export function createGateInterceptor(options) {
139
+ const refusalText = options.refusalText ?? CONTROL_REFUSAL_PLAIN;
140
+ let queue = Promise.resolve();
141
+ return (line) => {
142
+ queue = queue.then(async () => {
143
+ let frame = null;
144
+ try {
145
+ frame = JSON.parse(line);
146
+ }
147
+ catch {
148
+ // not a frame this gate understands — never stand between the
149
+ // agent and its driver on anything but a recognized tool call
150
+ }
151
+ if (!frame || frame.method !== "tools/call") {
152
+ options.forward(line);
153
+ return;
154
+ }
155
+ const held = await options.isHeld().catch(() => false);
156
+ if (!held) {
157
+ options.forward(line);
158
+ return;
159
+ }
160
+ options.refuse(JSON.stringify({
161
+ jsonrpc: "2.0",
162
+ id: frame.id ?? null,
163
+ result: { content: [{ type: "text", text: refusalText }], isError: true },
164
+ }));
165
+ });
166
+ };
167
+ }
168
+ export function runMcpBridge(options) {
169
+ const child = spawn(options.command, options.args, {
170
+ shell: false,
171
+ env: { ...process.env, PATH: augmentedPath() },
172
+ stdio: ["pipe", "pipe", "pipe"],
173
+ });
174
+ // docker may exit before it drains stdin; pipe() leaves this error unhandled.
175
+ child.stdin.on("error", () => { });
176
+ child.stderr.pipe(process.stderr);
177
+ let detach;
178
+ if (options.gate) {
179
+ const client = createControlClient({ url: options.gate.url, token: options.gate.token });
180
+ const inbound = createLineSplitter(createGateInterceptor({
181
+ isHeld: async () => (await client.state(true)).held,
182
+ forward: (line) => child.stdin.write(line + "\n"),
183
+ refuse: (line) => process.stdout.write(line + "\n"),
184
+ }));
185
+ const onStdin = (chunk) => inbound.push(chunk);
186
+ process.stdin.on("data", onStdin);
187
+ process.stdin.on("end", () => {
188
+ inbound.flush();
189
+ child.stdin.end();
190
+ });
191
+ // Injected refusals must never land inside one of the child's
192
+ // half-written frames, so the child's stdout is re-emitted at line
193
+ // granularity as well.
194
+ const outbound = createLineSplitter((line) => process.stdout.write(line + "\n"));
195
+ child.stdout.on("data", (chunk) => outbound.push(chunk));
196
+ child.stdout.on("end", () => outbound.flush());
197
+ detach = () => {
198
+ process.stdin.off("data", onStdin);
199
+ process.stdin.pause();
200
+ };
201
+ }
202
+ else {
203
+ process.stdin.pipe(child.stdin);
204
+ child.stdout.pipe(process.stdout);
205
+ detach = () => {
206
+ process.stdin.unpipe(child.stdin);
207
+ process.stdin.pause();
208
+ };
209
+ }
210
+ let watchdog = null;
211
+ if (options.liveness) {
212
+ const liveness = options.liveness;
213
+ watchdog = createInactivityWatchdog({
214
+ inactivityMs: BRIDGE_INACTIVITY_MS,
215
+ probe: () => runLivenessProbe(liveness),
216
+ onDead: () => {
217
+ process.stderr.write(`${options.label} transport went silent and stopped answering liveness probes; ending the bridge\n`);
218
+ process.exitCode = 1;
219
+ detach();
220
+ child.kill("SIGKILL");
221
+ // A docker wedged on a dead ssh connection may never deliver close.
222
+ // Nothing can be buffered on stdout after 45 quiet seconds, so this
223
+ // hard exit — unlike the close-handler one this file exists to avoid —
224
+ // cannot truncate anything.
225
+ const failsafe = setTimeout(() => process.exit(1), 2_000);
226
+ failsafe.unref?.();
227
+ },
228
+ });
229
+ const touch = () => watchdog?.touch();
230
+ process.stdin.on("data", touch);
231
+ child.stdout.on("data", touch);
232
+ child.stderr.on("data", touch);
233
+ }
234
+ child.on("error", (error) => {
235
+ process.stderr.write(`could not connect to ${options.label}: ${error.message}\n`);
236
+ process.exitCode = 1;
237
+ watchdog?.stop();
238
+ detach();
239
+ });
240
+ child.on("close", (code, signal) => {
241
+ if (signal)
242
+ process.stderr.write(`${options.label} connection ended with ${signal}\n`);
243
+ // Let stdout and stderr drain before the bridge exits.
244
+ process.exitCode = process.exitCode ?? code ?? 1;
245
+ watchdog?.stop();
246
+ detach();
247
+ });
248
+ for (const signal of ["SIGTERM", "SIGINT"]) {
249
+ process.on(signal, () => child.kill(signal));
250
+ }
251
+ }
@@ -0,0 +1,153 @@
1
+ import { augmentedPath } from "./env-path.js";
2
+ import { PROVIDER_CREDENTIAL_ENV, stripWorkspaceCredentialEnv, } from "./config.js";
3
+ import { createLineSplitter } from "./mcp-bridge.js";
4
+ import { killCliTree, spawnCli } from "./procs.js";
5
+ const MAX_STDOUT_BYTES = 1_048_576;
6
+ const MAX_TOOLS = 100;
7
+ const DEFAULT_TIMEOUT_MS = 8_000;
8
+ function probeEnvironment(server) {
9
+ const env = { ...process.env, PATH: augmentedPath() };
10
+ stripWorkspaceCredentialEnv(env);
11
+ for (const key of PROVIDER_CREDENTIAL_ENV)
12
+ delete env[key];
13
+ Object.assign(env, server.env);
14
+ return env;
15
+ }
16
+ function publicProbeError(kind) {
17
+ if (kind === "spawn")
18
+ return "Could not start this command. Check that it is installed and executable.";
19
+ if (kind === "timeout")
20
+ return "The server did not answer in time.";
21
+ if (kind === "closed")
22
+ return "The server stopped before the MCP handshake finished.";
23
+ if (kind === "cancelled")
24
+ return "Connection test was cancelled.";
25
+ return "The command did not return a valid MCP tools list.";
26
+ }
27
+ function redactConfiguredValues(value, env) {
28
+ let redacted = value;
29
+ for (const secret of Object.values(env)) {
30
+ if (secret)
31
+ redacted = redacted.split(secret).join("[redacted]");
32
+ }
33
+ return redacted;
34
+ }
35
+ /** Start one stdio server long enough to prove the MCP handshake and list its
36
+ * tools. It is always reaped, never inherits OpenMaus credentials, and never
37
+ * returns child stderr or environment values to the renderer. */
38
+ export function probeMcpServer(server, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
39
+ return new Promise((resolve) => {
40
+ if (signal?.aborted) {
41
+ resolve({ ok: false, error: publicProbeError("cancelled") });
42
+ return;
43
+ }
44
+ let child;
45
+ try {
46
+ child = spawnCli(server.command, server.args, {
47
+ cwd: process.cwd(),
48
+ env: probeEnvironment(server),
49
+ stdio: ["pipe", "pipe", "pipe"],
50
+ });
51
+ }
52
+ catch {
53
+ resolve({ ok: false, error: publicProbeError("spawn") });
54
+ return;
55
+ }
56
+ let settled = false;
57
+ let stdoutBytes = 0;
58
+ let initialized = false;
59
+ let timer;
60
+ const onAbort = () => finish({ ok: false, error: publicProbeError("cancelled") });
61
+ const finish = (result) => {
62
+ if (settled)
63
+ return;
64
+ settled = true;
65
+ if (timer)
66
+ clearTimeout(timer);
67
+ signal?.removeEventListener("abort", onAbort);
68
+ killCliTree(child);
69
+ resolve(result);
70
+ };
71
+ const write = (frame) => {
72
+ try {
73
+ child.stdin.write(`${JSON.stringify(frame)}\n`);
74
+ }
75
+ catch {
76
+ finish({ ok: false, error: publicProbeError("closed") });
77
+ }
78
+ };
79
+ const splitter = createLineSplitter((line) => {
80
+ if (settled || !line.trim())
81
+ return;
82
+ let frame;
83
+ try {
84
+ frame = JSON.parse(line);
85
+ }
86
+ catch {
87
+ return;
88
+ }
89
+ if (!frame || typeof frame !== "object")
90
+ return;
91
+ const value = frame;
92
+ if (value.id === 1 && value.result && !initialized) {
93
+ initialized = true;
94
+ write({ jsonrpc: "2.0", method: "notifications/initialized" });
95
+ write({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
96
+ return;
97
+ }
98
+ if (value.id !== 2)
99
+ return;
100
+ const result = value.result;
101
+ if (!Array.isArray(result?.tools)) {
102
+ finish({ ok: false, error: publicProbeError("protocol") });
103
+ return;
104
+ }
105
+ const tools = [];
106
+ for (const raw of result.tools.slice(0, MAX_TOOLS)) {
107
+ if (!raw || typeof raw !== "object")
108
+ continue;
109
+ const candidate = raw;
110
+ if (typeof candidate.name !== "string" || !candidate.name.trim())
111
+ continue;
112
+ tools.push({
113
+ name: redactConfiguredValues(candidate.name, server.env).slice(0, 200),
114
+ ...(typeof candidate.description === "string"
115
+ ? { description: redactConfiguredValues(candidate.description, server.env).slice(0, 500) }
116
+ : {}),
117
+ });
118
+ }
119
+ finish({ ok: true, tools });
120
+ });
121
+ timer = setTimeout(() => {
122
+ finish({ ok: false, error: publicProbeError("timeout") });
123
+ }, timeoutMs);
124
+ signal?.addEventListener("abort", onAbort, { once: true });
125
+ child.stdout.on("data", (chunk) => {
126
+ stdoutBytes += chunk.byteLength;
127
+ if (stdoutBytes > MAX_STDOUT_BYTES) {
128
+ finish({ ok: false, error: publicProbeError("protocol") });
129
+ return;
130
+ }
131
+ splitter.push(chunk);
132
+ });
133
+ // Drain without retaining it. Child stderr often contains secrets or
134
+ // arbitrary native logs and is not part of the MCP protocol.
135
+ child.stderr.resume();
136
+ child.once("error", () => finish({ ok: false, error: publicProbeError("spawn") }));
137
+ child.once("close", () => finish({ ok: false, error: publicProbeError("closed") }));
138
+ if (signal?.aborted) {
139
+ onAbort();
140
+ return;
141
+ }
142
+ write({
143
+ jsonrpc: "2.0",
144
+ id: 1,
145
+ method: "initialize",
146
+ params: {
147
+ protocolVersion: "2025-06-18",
148
+ capabilities: {},
149
+ clientInfo: { name: "OpenMausBot", version: "probe" },
150
+ },
151
+ });
152
+ });
153
+ }
@@ -0,0 +1,130 @@
1
+ import { z } from "zod";
2
+ export const MAX_MCP_SERVERS = 20;
3
+ const MAX_ARGS = 64;
4
+ const MAX_ENV = 64;
5
+ const MCP_NAME = /^[a-z][a-z0-9_-]{0,31}$/;
6
+ const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
7
+ /** Names used to route OpenMausBot's built-in MCP proxies and their ephemeral
8
+ * capabilities. Codex exposes MCP env names through one app-server process;
9
+ * a custom server must never request one of these names or it could redirect
10
+ * a built-in proxy or receive that proxy's bearer. */
11
+ export function isHarnessOwnedMcpEnvName(name) {
12
+ return name === "ELECTRON_RUN_AS_NODE" || name.startsWith("OMB_") || name.startsWith("OGB_");
13
+ }
14
+ function environmentNameError(name) {
15
+ if (!ENV_NAME.test(name))
16
+ return `Environment variable “${name}” is not valid.`;
17
+ if (isHarnessOwnedMcpEnvName(name)) {
18
+ return `Environment variable “${name}” is reserved by OpenMausBot.`;
19
+ }
20
+ return null;
21
+ }
22
+ const RESERVED_MCP_NAMES = new Set([
23
+ "ogb",
24
+ "computer",
25
+ "agents",
26
+ "composio",
27
+ "browser",
28
+ "phone",
29
+ "dweb",
30
+ "openmausbot_connectors",
31
+ "openmausbot_phone",
32
+ ]);
33
+ const storedEntrySchema = z.object({
34
+ command: z.string().trim().min(1).max(1_024),
35
+ args: z.array(z.string().max(4_096)).max(MAX_ARGS).optional(),
36
+ env: z.record(z.string(), z.string().max(16_384)).optional(),
37
+ enabled: z.boolean().optional(),
38
+ }).strict();
39
+ const mutationEntrySchema = storedEntrySchema.extend({
40
+ env: z.record(z.string(), z.union([z.string().max(16_384), z.literal(true)])).optional(),
41
+ });
42
+ export function mcpServerNameError(name) {
43
+ if (!MCP_NAME.test(name)) {
44
+ return "Use 1–32 lowercase letters, numbers, underscores, or hyphens, starting with a letter.";
45
+ }
46
+ if (RESERVED_MCP_NAMES.has(name))
47
+ return "That name is reserved by OpenMausBot.";
48
+ return null;
49
+ }
50
+ export function parseStoredMcpServer(name, raw) {
51
+ const nameError = mcpServerNameError(name);
52
+ if (nameError)
53
+ return { ok: false, error: nameError };
54
+ const parsed = storedEntrySchema.safeParse(raw);
55
+ if (!parsed.success) {
56
+ return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid MCP server." };
57
+ }
58
+ const env = parsed.data.env ?? {};
59
+ const invalidEnv = Object.keys(env).map(environmentNameError).find((error) => error !== null);
60
+ if (invalidEnv)
61
+ return { ok: false, error: invalidEnv };
62
+ if (Object.keys(env).length > MAX_ENV) {
63
+ return { ok: false, error: `Use at most ${MAX_ENV} environment variables.` };
64
+ }
65
+ return {
66
+ ok: true,
67
+ server: {
68
+ command: parsed.data.command,
69
+ args: parsed.data.args ?? [],
70
+ env,
71
+ enabled: parsed.data.enabled !== false,
72
+ },
73
+ };
74
+ }
75
+ /** Parse a renderer mutation. `true` is a write-only placeholder meaning
76
+ * “keep this already stored value”; it is never accepted for a new key. */
77
+ export function parseMcpServerMutation(name, raw, existing) {
78
+ const nameError = mcpServerNameError(name);
79
+ if (nameError)
80
+ return { ok: false, error: nameError };
81
+ const parsed = mutationEntrySchema.safeParse(raw);
82
+ if (!parsed.success) {
83
+ return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid MCP server." };
84
+ }
85
+ const incomingEnv = parsed.data.env ?? {};
86
+ const invalidEnv = Object.keys(incomingEnv).map(environmentNameError).find((error) => error !== null);
87
+ if (invalidEnv)
88
+ return { ok: false, error: invalidEnv };
89
+ if (Object.keys(incomingEnv).length > MAX_ENV) {
90
+ return { ok: false, error: `Use at most ${MAX_ENV} environment variables.` };
91
+ }
92
+ const env = {};
93
+ for (const [key, value] of Object.entries(incomingEnv)) {
94
+ if (value === true) {
95
+ const saved = existing?.env[key];
96
+ if (saved === undefined)
97
+ return { ok: false, error: `No saved value exists for ${key}.` };
98
+ env[key] = saved;
99
+ }
100
+ else {
101
+ env[key] = value;
102
+ }
103
+ }
104
+ return {
105
+ ok: true,
106
+ server: {
107
+ command: parsed.data.command,
108
+ args: parsed.data.args ?? [],
109
+ env,
110
+ // A newly added command is inert until the person has tested and
111
+ // explicitly enabled it. Existing file-authored entries keep today's
112
+ // enabled-by-default behavior through parseStoredMcpServer.
113
+ enabled: existing ? (parsed.data.enabled ?? existing.enabled) : false,
114
+ },
115
+ };
116
+ }
117
+ export function listMcpServers(raw) {
118
+ return Object.entries(raw ?? {}).flatMap(([name, value]) => {
119
+ const parsed = parseStoredMcpServer(name, value);
120
+ if (!parsed.ok)
121
+ return [];
122
+ return [{
123
+ name,
124
+ command: parsed.server.command,
125
+ args: parsed.server.args,
126
+ envKeys: Object.keys(parsed.server.env).sort(),
127
+ enabled: parsed.server.enabled,
128
+ }];
129
+ });
130
+ }
@@ -0,0 +1,6 @@
1
+ export function memberTurnSelection(selection) {
2
+ return {
3
+ model: selection.model,
4
+ ...(selection.effort ? { effort: selection.effort } : {}),
5
+ };
6
+ }