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.
- package/LICENSE +202 -0
- package/README.md +14 -0
- package/cli.js +2 -0
- package/dist/app-icon.svg +29 -0
- package/dist/assets/abap-BdImnpbu.js +1 -0
- package/dist/assets/actionscript-3-B3316cI-.js +1 -0
- package/dist/assets/ada-bCR0ucgS.js +1 -0
- package/dist/assets/ahk-CsyLZFj1.js +1 -0
- package/dist/assets/ahk2-8Zs4aa1G.js +1 -0
- package/dist/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/assets/angular-html-DA-rfuFy.js +1 -0
- package/dist/assets/angular-ts-BrjP3tb8.js +1 -0
- package/dist/assets/apache-Pmp26Uib.js +1 -0
- package/dist/assets/apex-DhZFqWV2.js +1 -0
- package/dist/assets/apl-CORt7UWP.js +1 -0
- package/dist/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/assets/ara-BRHolxvo.js +1 -0
- package/dist/assets/asciidoc-CSVQ5wI8.js +1 -0
- package/dist/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/assets/astro-HNnZUWAn.js +1 -0
- package/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/assets/awk-DMzUqQB5.js +1 -0
- package/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/assets/bat-CickPsom.js +1 -0
- package/dist/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/assets/berry-uYugtg8r.js +1 -0
- package/dist/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/assets/bird2-Bx8U0n9b.js +1 -0
- package/dist/assets/blade-2xfisSek.js +1 -0
- package/dist/assets/bsl-DlhNcFeZ.js +1 -0
- package/dist/assets/c-BIGW1oBm.js +1 -0
- package/dist/assets/c3-Dp5svz6Z.js +1 -0
- package/dist/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/assets/catppuccin-frappe-CZL1YF0i.js +1 -0
- package/dist/assets/catppuccin-latte-DH-8KZSZ.js +1 -0
- package/dist/assets/catppuccin-macchiato-B7yYVSCf.js +1 -0
- package/dist/assets/catppuccin-mocha-Ct7hS0mc.js +1 -0
- package/dist/assets/chapel-DTp_pixX.js +1 -0
- package/dist/assets/clarity-Dn5IMItf.js +1 -0
- package/dist/assets/clojure-P80f7IUj.js +1 -0
- package/dist/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/assets/cobol-nBiQ_Alo.js +1 -0
- package/dist/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/assets/coq-C7JzOVbR.js +1 -0
- package/dist/assets/cpp-BMRokrvK.js +1 -0
- package/dist/assets/crystal-DGywbUpC.js +1 -0
- package/dist/assets/csharp-DSvCPggb.js +1 -0
- package/dist/assets/css-CLj8gQPS.js +1 -0
- package/dist/assets/csv-fuZLfV_i.js +1 -0
- package/dist/assets/cue-D82EKSYY.js +1 -0
- package/dist/assets/cypher-COkxafJQ.js +1 -0
- package/dist/assets/d-85-TOEBH.js +1 -0
- package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/assets/dart-bE4Kk8sk.js +1 -0
- package/dist/assets/dax-CEL-wOlO.js +1 -0
- package/dist/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/assets/diff-D97Zzqfu.js +1 -0
- package/dist/assets/docker-BcOcwvcX.js +1 -0
- package/dist/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/assets/edge-FbVlp4U3.js +1 -0
- package/dist/assets/elixir-CkH2-t6x.js +1 -0
- package/dist/assets/elm-DbKCFpqz.js +1 -0
- package/dist/assets/emacs-lisp-C_m_b--Z.js +1 -0
- package/dist/assets/erb-DXfck5VN.js +1 -0
- package/dist/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/assets/fennel-BYunw83y.js +1 -0
- package/dist/assets/fish-BvzEVeQv.js +1 -0
- package/dist/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/assets/gdresource-TyuKm33G.js +1 -0
- package/dist/assets/gdscript-DqcFQ5yU.js +1 -0
- package/dist/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/assets/genie-D0YGMca9.js +1 -0
- package/dist/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/assets/gleam-BspZqrRM.js +1 -0
- package/dist/assets/glimmer-js-ByusRIyA.js +1 -0
- package/dist/assets/glimmer-ts-BfAWNZQY.js +1 -0
- package/dist/assets/glsl-DplSGwfg.js +1 -0
- package/dist/assets/gn-n2N0HUVH.js +1 -0
- package/dist/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/assets/go-C27-OAKa.js +1 -0
- package/dist/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/assets/hack-BWmVpMyf.js +1 -0
- package/dist/assets/haml-D5jkg6IW.js +1 -0
- package/dist/assets/handlebars-BpdQsYii.js +1 -0
- package/dist/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/assets/haxe-CfZj7gIn.js +1 -0
- package/dist/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/assets/hjson-D5-asLiD.js +1 -0
- package/dist/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/assets/horizon-bright-CUuTKBJd.js +1 -0
- package/dist/assets/houston-DnULxvSX.js +1 -0
- package/dist/assets/html-derivative-DlHx6ybY.js +1 -0
- package/dist/assets/html-pp8916En.js +1 -0
- package/dist/assets/http-jrhK8wxY.js +1 -0
- package/dist/assets/hurl-irOxFIW8.js +1 -0
- package/dist/assets/hxml-2-FPmUDs.js +1 -0
- package/dist/assets/hy-DFXneXwc.js +1 -0
- package/dist/assets/imba-DGztddWO.js +1 -0
- package/dist/assets/index-B9rLIY81.js +263 -0
- package/dist/assets/index-CJBrtDbC.css +1 -0
- package/dist/assets/index-D-u0LYsV.js +153 -0
- package/dist/assets/ini-BEwlwnbL.js +1 -0
- package/dist/assets/java-CylS5w8V.js +1 -0
- package/dist/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/assets/jinja-f2NsQr07.js +1 -0
- package/dist/assets/jison-wvAkD_A8.js +1 -0
- package/dist/assets/json-Cp-IABpG.js +1 -0
- package/dist/assets/json5-C9tS-k6U.js +1 -0
- package/dist/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/assets/julia-5Bft2YPA.js +1 -0
- package/dist/assets/just-Cwhn7H3k.js +1 -0
- package/dist/assets/kanagawa-dragon-BuwD2xS4.js +1 -0
- package/dist/assets/kanagawa-lotus-C3DzagqV.js +1 -0
- package/dist/assets/kanagawa-wave-DFGoQZhC.js +1 -0
- package/dist/assets/kdl-DV7GczEv.js +1 -0
- package/dist/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/assets/kusto-wEQ09or8.js +1 -0
- package/dist/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/assets/latex-D5pSuvFb.js +1 -0
- package/dist/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/assets/less-B1dDrJ26.js +1 -0
- package/dist/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/assets/liquid-C0sCDyMI.js +1 -0
- package/dist/assets/llvm-BZoOZj88.js +1 -0
- package/dist/assets/log-2UxHyX5q.js +1 -0
- package/dist/assets/logo-BtOb2qkB.js +1 -0
- package/dist/assets/lua-BaeVxFsk.js +1 -0
- package/dist/assets/luau-BnpPk5vE.js +1 -0
- package/dist/assets/make-CHLpvVh8.js +1 -0
- package/dist/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/assets/marko-DjSrsDqO.js +1 -0
- package/dist/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/assets/matlab-D7o27uSR.js +1 -0
- package/dist/assets/mdc-D1_yUvq7.js +1 -0
- package/dist/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/assets/mermaid-CQcHuHx7.js +1 -0
- package/dist/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/assets/min-light-CTRr51gU.js +1 -0
- package/dist/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/assets/mojo-DJz3ZmWd.js +1 -0
- package/dist/assets/monokai-BRVnQi9A.js +1 -0
- package/dist/assets/moonbit-CHtswR0a.js +1 -0
- package/dist/assets/move-el3G9tDJ.js +1 -0
- package/dist/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/assets/nextflow-C-mBbutL.js +1 -0
- package/dist/assets/nextflow-groovy-vE_lwT2v.js +1 -0
- package/dist/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/assets/nim-BIad80T-.js +1 -0
- package/dist/assets/nix-CwoSXNpI.js +1 -0
- package/dist/assets/nord-Ddv68eIx.js +1 -0
- package/dist/assets/nsis-BlV79W_Q.js +1 -0
- package/dist/assets/nushell-D3jzshHO.js +1 -0
- package/dist/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/assets/odin-BBf5iR-q.js +1 -0
- package/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/assets/org-DM6o9KBp.js +1 -0
- package/dist/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/assets/perl-B9cMNwum.js +1 -0
- package/dist/assets/php-Csjmro_R.js +1 -0
- package/dist/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/assets/po-BTJTHyun.js +1 -0
- package/dist/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/assets/polar-C0HS_06l.js +1 -0
- package/dist/assets/postcss-CXtECtnM.js +1 -0
- package/dist/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/assets/powershell-BmBUJMz7.js +1 -0
- package/dist/assets/prisma-Vru482bI.js +1 -0
- package/dist/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/assets/pug-DKIMFp6K.js +1 -0
- package/dist/assets/puppet-BMWR74SV.js +1 -0
- package/dist/assets/purescript-CklMAg4u.js +1 -0
- package/dist/assets/python-B6aJPvgy.js +1 -0
- package/dist/assets/qml-3beO22l8.js +1 -0
- package/dist/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/assets/qss-IeuSbFQv.js +1 -0
- package/dist/assets/r-Cf5RLm7j.js +1 -0
- package/dist/assets/racket-BqYA7rlc.js +1 -0
- package/dist/assets/raku-DXvB9xmW.js +1 -0
- package/dist/assets/razor-BjBPvh-w.js +1 -0
- package/dist/assets/rbs-CpoqiR4B.js +1 -0
- package/dist/assets/red-hvxz__6c.js +1 -0
- package/dist/assets/reg-C-SQnVFl.js +1 -0
- package/dist/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/assets/rel-C3B-1QV4.js +1 -0
- package/dist/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/assets/ron-D8l8udqQ.js +1 -0
- package/dist/assets/rose-pine-5qJOZa0Y.js +1 -0
- package/dist/assets/rose-pine-dawn-zx0QlTCp.js +1 -0
- package/dist/assets/rose-pine-moon-C9pEdX9L.js +1 -0
- package/dist/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/assets/rst-bs7f0vWN.js +1 -0
- package/dist/assets/ruby-C0TQ7zu5.js +1 -0
- package/dist/assets/rust-B1yitclQ.js +1 -0
- package/dist/assets/sas-DEy46yEz.js +1 -0
- package/dist/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/assets/scala-CqE71os6.js +1 -0
- package/dist/assets/scheme-C98Dy4si.js +1 -0
- package/dist/assets/scss-D5BDwBP9.js +1 -0
- package/dist/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/assets/smalltalk-BOQMe2GC.js +1 -0
- package/dist/assets/smithy-cds9vsN8.js +1 -0
- package/dist/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/assets/solarized-dark-CpvCGNkr.js +1 -0
- package/dist/assets/solarized-light-Dlz6yCKv.js +1 -0
- package/dist/assets/solidity-DijEV5ha.js +1 -0
- package/dist/assets/soy-8wufbnw4.js +1 -0
- package/dist/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/assets/sql-CRqJ_cUM.js +1 -0
- package/dist/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/assets/stata-DI20mbqo.js +1 -0
- package/dist/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/assets/surrealql-Cjom0U5J.js +1 -0
- package/dist/assets/svelte-Cy7k_4gC.js +1 -0
- package/dist/assets/swift-C2oV4EkX.js +1 -0
- package/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/assets/system-verilog-0hqHdDBg.js +1 -0
- package/dist/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/assets/templ-DhtptRzy.js +1 -0
- package/dist/assets/terraform-BETggiCN.js +1 -0
- package/dist/assets/tex-D96PA37w.js +1 -0
- package/dist/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/assets/toml-vGWfd6FD.js +1 -0
- package/dist/assets/ts-tags-D351s5mN.js +1 -0
- package/dist/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/assets/tsx-COt5Ahok.js +1 -0
- package/dist/assets/turtle-BsS91CYL.js +1 -0
- package/dist/assets/twig-27uCiNez.js +1 -0
- package/dist/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/assets/typespec-CAFt9gP4.js +1 -0
- package/dist/assets/typst-BUadGCkm.js +1 -0
- package/dist/assets/v-BGw2Nkan.js +1 -0
- package/dist/assets/vala-CsfeWuGM.js +1 -0
- package/dist/assets/vb-Cu-pLBUe.js +1 -0
- package/dist/assets/verilog-nZwndyjY.js +1 -0
- package/dist/assets/vesper-DRje8inN.js +1 -0
- package/dist/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/assets/viml-CJc9bBzg.js +1 -0
- package/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/assets/vue-BqiEGhQt.js +1 -0
- package/dist/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/assets/vue-vine-BoDAl6tE.js +1 -0
- package/dist/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/assets/wit-5i3qLPDT.js +1 -0
- package/dist/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/assets/yaml-Buea-lGh.js +1 -0
- package/dist/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/assets/zig-VOosw3JB.js +1 -0
- package/dist/index.html +14 -0
- package/dist-server/companion/src/listener.js +187 -0
- package/dist-server/computer-proxy.js +1185 -0
- package/dist-server/connector-proxy.js +186 -0
- package/dist-server/container-mcp.js +15186 -0
- package/dist-server/drivers/agents-proxy.js +887 -0
- package/dist-server/drivers/browser-proxy.js +15037 -0
- package/dist-server/drivers/dweb-proxy.js +175 -0
- package/dist-server/drivers/phone-proxy.js +339 -0
- package/dist-server/drivers/pi-mcp-extension.ts +638 -0
- package/dist-server/index.js +64869 -0
- package/dist-server/local-computer.js +198 -0
- package/dist-server/mcp-server.js +1233 -0
- package/dist-server/openmausbot.js +3671 -0
- package/dist-server/pair-cli.js +3671 -0
- package/dist-server/permission-proxy.js +126 -0
- package/dist-server/prepare-cloudflared.js +253 -0
- package/dist-server/proxy-paths.js +29 -0
- package/dist-server/server/atomic.js +40 -0
- package/dist-server/server/attachments.js +471 -0
- package/dist-server/server/auto-approve.js +162 -0
- package/dist-server/server/auto-review.js +79 -0
- package/dist-server/server/avatar-image.js +144 -0
- package/dist-server/server/bot-cwd.js +29 -0
- package/dist-server/server/bot-directory.js +127 -0
- package/dist-server/server/bot-package.js +268 -0
- package/dist-server/server/bot-profile.js +76 -0
- package/dist-server/server/box-create-idempotency.js +463 -0
- package/dist-server/server/box.js +944 -0
- package/dist-server/server/brand.js +65 -0
- package/dist-server/server/browser-connection.js +187 -0
- package/dist-server/server/browser-lifecycle-cleanup.js +359 -0
- package/dist-server/server/calendar-calls.js +314 -0
- package/dist-server/server/channel-queue.js +70 -0
- package/dist-server/server/checkpoints.js +405 -0
- package/dist-server/server/chief-of-staff.js +49 -0
- package/dist-server/server/claude-update.js +70 -0
- package/dist-server/server/cli.js +524 -0
- package/dist-server/server/cloud-backend.js +30 -0
- package/dist-server/server/comms-visibility.js +109 -0
- package/dist-server/server/composio.js +945 -0
- package/dist-server/server/computer-control.js +149 -0
- package/dist-server/server/computer-observation.js +133 -0
- package/dist-server/server/computer-proxy.js +1061 -0
- package/dist-server/server/config.js +760 -0
- package/dist-server/server/connector-proxy.js +228 -0
- package/dist-server/server/container-computer.js +840 -0
- package/dist-server/server/container-mcp.js +27 -0
- package/dist-server/server/contracts.js +24 -0
- package/dist-server/server/control-client.js +100 -0
- package/dist-server/server/data-dir-lease.js +3 -0
- package/dist-server/server/decision-log.js +106 -0
- package/dist-server/server/delegations.js +628 -0
- package/dist-server/server/drivers/acp/core.js +904 -0
- package/dist-server/server/drivers/acp/cursor.js +365 -0
- package/dist-server/server/drivers/acp/custom.js +51 -0
- package/dist-server/server/drivers/acp/droid.js +225 -0
- package/dist-server/server/drivers/acp/gemini.js +95 -0
- package/dist-server/server/drivers/acp/grok.js +249 -0
- package/dist-server/server/drivers/acp/hermes.js +429 -0
- package/dist-server/server/drivers/acp/kimi.js +559 -0
- package/dist-server/server/drivers/acp/opencode-go.js +370 -0
- package/dist-server/server/drivers/acp/qwen.js +98 -0
- package/dist-server/server/drivers/agents-proxy.js +941 -0
- package/dist-server/server/drivers/antigravity-acp.js +507 -0
- package/dist-server/server/drivers/antigravity-release.js +65 -0
- package/dist-server/server/drivers/antigravity-runtime.js +395 -0
- package/dist-server/server/drivers/antigravity.js +144 -0
- package/dist-server/server/drivers/boxagent.js +245 -0
- package/dist-server/server/drivers/browser-proxy.js +520 -0
- package/dist-server/server/drivers/builtIn.js +36 -0
- package/dist-server/server/drivers/claude.js +1337 -0
- package/dist-server/server/drivers/codex-catalog.js +409 -0
- package/dist-server/server/drivers/codex.js +1116 -0
- package/dist-server/server/drivers/dweb-proxy.js +193 -0
- package/dist-server/server/drivers/grok.js +48 -0
- package/dist-server/server/drivers/grokagent.js +4 -0
- package/dist-server/server/drivers/local-inject.js +388 -0
- package/dist-server/server/drivers/minimax.js +108 -0
- package/dist-server/server/drivers/native.js +21 -0
- package/dist-server/server/drivers/openai-chat.js +240 -0
- package/dist-server/server/drivers/openai-compat.js +143 -0
- package/dist-server/server/drivers/phone-proxy.js +372 -0
- package/dist-server/server/drivers/pi.js +855 -0
- package/dist-server/server/drivers/retry.js +96 -0
- package/dist-server/server/enterprise.js +93 -0
- package/dist-server/server/env-path.js +329 -0
- package/dist-server/server/environment.js +105 -0
- package/dist-server/server/generated-image.js +39 -0
- package/dist-server/server/graceful-shutdown.js +24 -0
- package/dist-server/server/group-goal-run.js +124 -0
- package/dist-server/server/harness/bus.js +86 -0
- package/dist-server/server/harness/registry.js +217 -0
- package/dist-server/server/index.js +11634 -0
- package/dist-server/server/installed-playbooks.js +34 -0
- package/dist-server/server/local-computer.js +278 -0
- package/dist-server/server/local-routing.js +9 -0
- package/dist-server/server/local-vm-idle.js +44 -0
- package/dist-server/server/local-vm-inventory.js +34 -0
- package/dist-server/server/local-vm-lease.js +58 -0
- package/dist-server/server/mcp-bridge.js +251 -0
- package/dist-server/server/mcp-probe.js +153 -0
- package/dist-server/server/mcp-registry.js +130 -0
- package/dist-server/server/member-turn.js +6 -0
- package/dist-server/server/message-db.js +358 -0
- package/dist-server/server/message-file.js +439 -0
- package/dist-server/server/names.js +26 -0
- package/dist-server/server/notify.js +69 -0
- package/dist-server/server/openmaus-status-capsule.js +329 -0
- package/dist-server/server/openmausbot.js +6 -0
- package/dist-server/server/package-export.js +157 -0
- package/dist-server/server/pair-cli.js +7 -0
- package/dist-server/server/peer-approval-key.js +5 -0
- package/dist-server/server/peer-approval.js +182 -0
- package/dist-server/server/peer-provenance.js +44 -0
- package/dist-server/server/peer-roster.js +139 -0
- package/dist-server/server/permission-proxy.js +157 -0
- package/dist-server/server/phone-secret.js +358 -0
- package/dist-server/server/private-screen-capture.js +17 -0
- package/dist-server/server/procs.js +123 -0
- package/dist-server/server/project-scout.js +304 -0
- package/dist-server/server/proxy-paths.js +47 -0
- package/dist-server/server/redact.js +102 -0
- package/dist-server/server/remote-computer.js +170 -0
- package/dist-server/server/repeat-detector.js +48 -0
- package/dist-server/server/replies.js +38 -0
- package/dist-server/server/request-auth.js +327 -0
- package/dist-server/server/room-cwd.js +15 -0
- package/dist-server/server/room-post-budget.js +112 -0
- package/dist-server/server/room-turn-timeout.js +115 -0
- package/dist-server/server/routine-requests.js +871 -0
- package/dist-server/server/routines.js +1111 -0
- package/dist-server/server/schema.js +11 -0
- package/dist-server/server/screen-frame-gate.js +80 -0
- package/dist-server/server/section-context.js +85 -0
- package/dist-server/server/send-idempotency.js +53 -0
- package/dist-server/server/sessions.js +319 -0
- package/dist-server/server/skill-fetch.js +148 -0
- package/dist-server/server/skill-learn.js +61 -0
- package/dist-server/server/skill-library.js +116 -0
- package/dist-server/server/skills.js +1223 -0
- package/dist-server/server/steer-queue.js +114 -0
- package/dist-server/server/store.js +1217 -0
- package/dist-server/server/surface.js +107 -0
- package/dist-server/server/tailscale.js +103 -0
- package/dist-server/server/team-backup.js +183 -0
- package/dist-server/server/team-library.js +205 -0
- package/dist-server/server/team-manifest.js +224 -0
- package/dist-server/server/thread-events.js +226 -0
- package/dist-server/server/tts/elevenlabs.js +92 -0
- package/dist-server/server/tts/index.js +79 -0
- package/dist-server/server/tts/speech-text.js +195 -0
- package/dist-server/server/tts/system-voices.js +74 -0
- package/dist-server/server/tunnel.js +202 -0
- package/dist-server/server/turn-context.js +40 -0
- package/dist-server/server/turn-dispatch-guard.js +152 -0
- package/dist-server/server/turn-images.js +138 -0
- package/dist-server/server/turn-watchdog.js +65 -0
- package/dist-server/server/vps-computer.js +1099 -0
- package/dist-server/server/vps-container-mcp.js +31 -0
- package/dist-server/server/webhook-ingress.js +173 -0
- package/dist-server/server/webhooks.js +491 -0
- package/dist-server/server/workspace.js +178 -0
- package/dist-server/shared/approval-mode.js +39 -0
- package/dist-server/shared/bot-avatar.js +33 -0
- package/dist-server/shared/bot-profile.js +7 -0
- package/dist-server/shared/connector-availability.js +12 -0
- package/dist-server/shared/credential-request.js +82 -0
- package/dist-server/shared/group-goal-run.js +1 -0
- package/dist-server/shared/import-name.js +11 -0
- package/dist-server/shared/mascot-bodies.js +107 -0
- package/dist-server/shared/routine-request.js +10 -0
- package/dist-server/shared/routine-run.js +1 -0
- package/dist-server/shared/skill-request.js +16 -0
- package/dist-server/shared/team-backup.js +148 -0
- package/dist-server/src/lib/composer-attachments.js +676 -0
- package/dist-server/tunnel-guardian.js +390 -0
- package/dist-server/vps-container-mcp.js +15209 -0
- package/package.json +32 -0
- package/skills/create-verification-skill/SKILL.md +65 -0
- package/skills/create-verification-skill/manifest.json +13 -0
- package/skills/phone-harness/SKILL.md +26 -0
- package/skills/phone-harness/agents/openai.yaml +13 -0
- package/skills/phone-harness/manifest.json +17 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Build one idempotent shutdown callback for process signals. Cleanup jobs
|
|
2
|
+
* run together, but a wedged provider cannot keep the desktop child alive
|
|
3
|
+
* forever. The browser capability clear is one of these jobs, so a normal
|
|
4
|
+
* server stop does not leave a turn bearer usable until its absolute TTL. */
|
|
5
|
+
export function createGracefulShutdown({ cleanup, exit, timeoutMs = 6_000, }) {
|
|
6
|
+
let started = false;
|
|
7
|
+
return () => {
|
|
8
|
+
if (started)
|
|
9
|
+
return;
|
|
10
|
+
started = true;
|
|
11
|
+
let timer;
|
|
12
|
+
const deadline = new Promise((resolve) => {
|
|
13
|
+
timer = setTimeout(resolve, timeoutMs);
|
|
14
|
+
timer.unref?.();
|
|
15
|
+
});
|
|
16
|
+
const settled = Promise.allSettled(cleanup.map((job) => Promise.resolve().then(job)))
|
|
17
|
+
.then(() => undefined);
|
|
18
|
+
void Promise.race([settled, deadline]).finally(() => {
|
|
19
|
+
if (timer)
|
|
20
|
+
clearTimeout(timer);
|
|
21
|
+
exit(0);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Odd by design: coordinator/worker alternation must always leave the final
|
|
2
|
+
// bounded turn to the coordinator for an honest completion decision.
|
|
3
|
+
export const GROUP_GOAL_MAX_TURNS = 13;
|
|
4
|
+
export const GROUP_GOAL_CONTROL_OPEN = "<openmaus-goal>";
|
|
5
|
+
export const GROUP_GOAL_CONTROL_CLOSE = "</openmaus-goal>";
|
|
6
|
+
/** Turn-scoped events normally identify themselves. A coordinator completion
|
|
7
|
+
* can omit that field after its guard was already bound by turn.started; keep
|
|
8
|
+
* the bound identity so its public transcript message still settles cleanly. */
|
|
9
|
+
export function groupGoalCompletionTurnId(eventTurnId, boundTurnId) {
|
|
10
|
+
return eventTurnId ?? boundTurnId;
|
|
11
|
+
}
|
|
12
|
+
const bounded = (value, max) => typeof value === "string" ? value.trim().slice(0, max) : "";
|
|
13
|
+
function visibleCoordinatorText(text) {
|
|
14
|
+
let visible = text;
|
|
15
|
+
for (;;) {
|
|
16
|
+
const closeAt = visible.indexOf(GROUP_GOAL_CONTROL_CLOSE);
|
|
17
|
+
if (closeAt < 0)
|
|
18
|
+
break;
|
|
19
|
+
const openAt = visible.lastIndexOf(GROUP_GOAL_CONTROL_OPEN, closeAt);
|
|
20
|
+
if (openAt < 0) {
|
|
21
|
+
visible = `${visible.slice(0, closeAt)}${visible.slice(closeAt + GROUP_GOAL_CONTROL_CLOSE.length)}`;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
visible = `${visible.slice(0, openAt)}${visible.slice(closeAt + GROUP_GOAL_CONTROL_CLOSE.length)}`;
|
|
25
|
+
}
|
|
26
|
+
// A truncated final envelope is private protocol too. Keep the prose that
|
|
27
|
+
// preceded it, but never expose a half-written marker or JSON fragment.
|
|
28
|
+
const danglingOpen = visible.indexOf(GROUP_GOAL_CONTROL_OPEN);
|
|
29
|
+
if (danglingOpen >= 0)
|
|
30
|
+
visible = visible.slice(0, danglingOpen);
|
|
31
|
+
return visible.replaceAll(GROUP_GOAL_CONTROL_CLOSE, "").trim();
|
|
32
|
+
}
|
|
33
|
+
/** Keep the orchestration envelope out of the human transcript while still
|
|
34
|
+
* accepting ordinary prose before it. The last complete envelope wins: a
|
|
35
|
+
* quoted example earlier in the reply cannot accidentally steer the run. */
|
|
36
|
+
export function parseGroupGoalDecision(text) {
|
|
37
|
+
const closeAt = text.lastIndexOf(GROUP_GOAL_CONTROL_CLOSE);
|
|
38
|
+
const openAt = closeAt < 0 ? -1 : text.lastIndexOf(GROUP_GOAL_CONTROL_OPEN, closeAt);
|
|
39
|
+
if (openAt < 0 || closeAt < 0)
|
|
40
|
+
return { visibleText: visibleCoordinatorText(text), decision: null };
|
|
41
|
+
const visibleText = visibleCoordinatorText(text);
|
|
42
|
+
const payload = text.slice(openAt + GROUP_GOAL_CONTROL_OPEN.length, closeAt).trim();
|
|
43
|
+
try {
|
|
44
|
+
const raw = JSON.parse(payload);
|
|
45
|
+
const status = raw.status;
|
|
46
|
+
const detail = bounded(raw.detail, 500);
|
|
47
|
+
if (status === "continue") {
|
|
48
|
+
const next = bounded(raw.next, 100);
|
|
49
|
+
const instruction = bounded(raw.instruction, 2_000);
|
|
50
|
+
if (!next || !instruction)
|
|
51
|
+
return { visibleText, decision: null };
|
|
52
|
+
return {
|
|
53
|
+
visibleText,
|
|
54
|
+
decision: { status, next, instruction, ...(detail ? { detail } : {}) },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (status === "completed" || status === "needs-input" || status === "blocked") {
|
|
58
|
+
if (!detail)
|
|
59
|
+
return { visibleText, decision: null };
|
|
60
|
+
return { visibleText, decision: { status, detail } };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// A malformed control envelope is a safe pause, never permission to keep
|
|
65
|
+
// an autonomous loop running on a guess.
|
|
66
|
+
}
|
|
67
|
+
return { visibleText, decision: null };
|
|
68
|
+
}
|
|
69
|
+
/** Explicit room lead wins. Otherwise prefer an in-room Chief, then the
|
|
70
|
+
* first active member. A goal run never recruits somebody outside the room. */
|
|
71
|
+
export function selectGroupGoalCoordinator(members, responder) {
|
|
72
|
+
const active = members.filter((member) => !member.hidden);
|
|
73
|
+
if (responder.kind === "member") {
|
|
74
|
+
const explicit = active.find((member) => member.id === responder.botId);
|
|
75
|
+
if (explicit)
|
|
76
|
+
return explicit;
|
|
77
|
+
}
|
|
78
|
+
return active.find((member) => member.chiefOfStaff) ?? active[0] ?? null;
|
|
79
|
+
}
|
|
80
|
+
/** Resolve a model-selected teammate without letting fuzzy or duplicate
|
|
81
|
+
* names choose the wrong person. IDs always work; names work only if unique. */
|
|
82
|
+
export function resolveGroupGoalMember(reference, members) {
|
|
83
|
+
const wanted = reference.trim().replace(/^@/, "").toLocaleLowerCase();
|
|
84
|
+
if (!wanted)
|
|
85
|
+
return null;
|
|
86
|
+
const active = members.filter((member) => !member.hidden);
|
|
87
|
+
const idMatch = active.find((member) => member.id.toLocaleLowerCase() === wanted);
|
|
88
|
+
if (idMatch)
|
|
89
|
+
return idMatch;
|
|
90
|
+
const nameMatches = active.filter((member) => member.name.toLocaleLowerCase() === wanted);
|
|
91
|
+
return nameMatches.length === 1 ? nameMatches[0] : null;
|
|
92
|
+
}
|
|
93
|
+
export function groupGoalCoordinatorInstructions(args) {
|
|
94
|
+
const roster = args.members
|
|
95
|
+
.filter((member) => !member.hidden)
|
|
96
|
+
.map((member) => `${member.name} (${member.id})`)
|
|
97
|
+
.join(", ");
|
|
98
|
+
return [
|
|
99
|
+
"You are the lead coordinator for a bounded team goal run.",
|
|
100
|
+
`Goal: ${args.goal}`,
|
|
101
|
+
`Available room members: ${roster}.`,
|
|
102
|
+
`This is team turn ${args.turn} of ${args.maxTurns}; ${args.remainingTurns} turn(s) remain after this one.`,
|
|
103
|
+
...(args.note ? [`Harness note: ${args.note}`] : []),
|
|
104
|
+
"Use the conversation as the progress ledger. Decide whether the goal is genuinely complete, needs the human, is blocked, or needs one named teammate next.",
|
|
105
|
+
"Do not continue merely to generate discussion. Do not claim completion unless the requested deliverable or answer is present in the conversation.",
|
|
106
|
+
"Write a brief human-facing update or final answer, then end with exactly one private control envelope on its own line.",
|
|
107
|
+
`${GROUP_GOAL_CONTROL_OPEN}{"status":"continue","next":"Exact member id from the roster","instruction":"Concrete next assignment","detail":"Short progress note"}${GROUP_GOAL_CONTROL_CLOSE}`,
|
|
108
|
+
`Or use status "completed", "needs-input", or "blocked" with a non-empty "detail" and omit next/instruction.`,
|
|
109
|
+
"Never mention, quote, or explain the control envelope in your human-facing text.",
|
|
110
|
+
].join("\n");
|
|
111
|
+
}
|
|
112
|
+
export function groupGoalWorkerInstructions(args) {
|
|
113
|
+
return [
|
|
114
|
+
`You are a specialist contributing to a bounded team goal run led by ${args.coordinatorName}.`,
|
|
115
|
+
`Goal: ${args.goal}`,
|
|
116
|
+
`Your assignment: ${args.assignment}`,
|
|
117
|
+
`This is team turn ${args.turn} of ${args.maxTurns}.`,
|
|
118
|
+
"Do the assigned work now and put concrete results, evidence, or a clear blocker in your reply.",
|
|
119
|
+
`Address your result to ${args.coordinatorName}. Do not invent a new orchestration protocol or emit an openmaus-goal control envelope.`,
|
|
120
|
+
].join("\n");
|
|
121
|
+
}
|
|
122
|
+
export function groupGoalAssignmentKey(memberId, instruction) {
|
|
123
|
+
return `${memberId}:${instruction.trim().toLocaleLowerCase().replace(/\s+/g, " ")}`;
|
|
124
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Fan-in event bus — port of upstream's ProviderService fan-in +
|
|
2
|
+
// EventNdjsonLogger tee, minus Effect. Every adapter's event stream merges
|
|
3
|
+
// into one bus; each event is stamped with its providerInstanceId, teed to
|
|
4
|
+
// a per-thread canonical NDJSON log (the debugging trick both upstream and
|
|
5
|
+
// agentcal lean on), and delivered to subscribers (the SSE endpoint and
|
|
6
|
+
// the server-side message folder).
|
|
7
|
+
import { appendFileSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { EVENTS_DIR } from "../config.js";
|
|
10
|
+
import { redactSecrets } from "../redact.js";
|
|
11
|
+
import { newId } from "../contracts.js";
|
|
12
|
+
const INCOMPLETE_LOG_MESSAGE = "Canonical event history is incomplete: OpenMausBot could not write one or more events to disk. Live updates will continue.";
|
|
13
|
+
export class EventBus {
|
|
14
|
+
listeners = new Set();
|
|
15
|
+
unsubscribes = [];
|
|
16
|
+
pendingLogWarnings = new Map();
|
|
17
|
+
appendLog;
|
|
18
|
+
constructor(appendLog = appendFileSync) {
|
|
19
|
+
this.appendLog = appendLog;
|
|
20
|
+
}
|
|
21
|
+
attach(instances) {
|
|
22
|
+
for (const instance of instances) {
|
|
23
|
+
const unsub = instance.adapter.onEvent((event) => {
|
|
24
|
+
// hard invariant borrowed from correlateRuntimeEventWithInstance:
|
|
25
|
+
// an adapter may only emit events for its own driver kind
|
|
26
|
+
if (event.provider !== instance.driverKind) {
|
|
27
|
+
console.error(`bus: dropped cross-driver event from ${instance.instanceId}`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.publish({ ...event, providerInstanceId: instance.instanceId });
|
|
31
|
+
});
|
|
32
|
+
this.unsubscribes.push(unsub);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
publish(event) {
|
|
36
|
+
const pendingWarning = this.pendingLogWarnings.get(event.threadId);
|
|
37
|
+
const persistedEvents = pendingWarning ? [pendingWarning, redactSecrets(event)] : [redactSecrets(event)];
|
|
38
|
+
try {
|
|
39
|
+
// the canonical log is a file people paste into bug reports; scrub
|
|
40
|
+
// credential-shaped content (tool titles, request summaries, reply
|
|
41
|
+
// text) the same way the native tee does
|
|
42
|
+
this.appendLog(join(EVENTS_DIR, `${event.threadId}.ndjson`), persistedEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n", { mode: 0o600 });
|
|
43
|
+
if (pendingWarning)
|
|
44
|
+
this.pendingLogWarnings.delete(event.threadId);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// Never feed this warning back through publish(): that would retry the
|
|
48
|
+
// same failed write and recurse. Deliver it once for this outage, then
|
|
49
|
+
// persist the same marker before the first event written after recovery.
|
|
50
|
+
if (!pendingWarning) {
|
|
51
|
+
const warning = {
|
|
52
|
+
eventId: newId(),
|
|
53
|
+
provider: event.provider,
|
|
54
|
+
providerInstanceId: event.providerInstanceId,
|
|
55
|
+
threadId: event.threadId,
|
|
56
|
+
createdAt: new Date().toISOString(),
|
|
57
|
+
turnId: event.turnId,
|
|
58
|
+
type: "runtime.error",
|
|
59
|
+
message: INCOMPLETE_LOG_MESSAGE,
|
|
60
|
+
};
|
|
61
|
+
this.pendingLogWarnings.set(event.threadId, warning);
|
|
62
|
+
console.error("bus: canonical event log write failed", error);
|
|
63
|
+
this.deliver(warning);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.deliver(event);
|
|
67
|
+
}
|
|
68
|
+
deliver(event) {
|
|
69
|
+
for (const listener of [...this.listeners]) {
|
|
70
|
+
try {
|
|
71
|
+
listener(event);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
console.error("bus: listener threw", e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
subscribe(listener) {
|
|
79
|
+
this.listeners.add(listener);
|
|
80
|
+
return () => this.listeners.delete(listener);
|
|
81
|
+
}
|
|
82
|
+
detachAll() {
|
|
83
|
+
for (const unsub of this.unsubscribes.splice(0))
|
|
84
|
+
unsub();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// Provider instance registry — port of upstream's ProviderInstanceRegistryLive
|
|
2
|
+
// behavior, minus Effect: config map → live instances; unknown driver or
|
|
3
|
+
// config-decode failure becomes an UNAVAILABLE SHADOW SNAPSHOT instead of a
|
|
4
|
+
// startup failure (that behavior is what makes settings forward/backward
|
|
5
|
+
// compatible — do not remove it); dispose tears an instance down without
|
|
6
|
+
// touching its siblings.
|
|
7
|
+
import { findCliCandidates } from "../env-path.js";
|
|
8
|
+
/** The `cli` field off a driver's default config, when it has one — the
|
|
9
|
+
* placeholder an override input shows when nothing is set. */
|
|
10
|
+
function cliDefaultOf(driver) {
|
|
11
|
+
if (!driver)
|
|
12
|
+
return undefined;
|
|
13
|
+
try {
|
|
14
|
+
const cfg = driver.defaultConfig();
|
|
15
|
+
return typeof cfg?.cli === "string" ? cfg.cli : undefined;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Raw `config.cli` straight from disk — shadow snapshots can't decode, so
|
|
22
|
+
* this is the only faithful way to echo back what was configured. */
|
|
23
|
+
function cliOfRaw(raw) {
|
|
24
|
+
const cli = raw?.cli;
|
|
25
|
+
return typeof cli === "string" && cli ? cli : undefined;
|
|
26
|
+
}
|
|
27
|
+
export class ProviderRegistry {
|
|
28
|
+
byId = new Map();
|
|
29
|
+
/** decoded per-instance `cli` overrides, for describe() — drivers spawn
|
|
30
|
+
* from their own config; this map only reports what was configured */
|
|
31
|
+
cliByInstance = new Map();
|
|
32
|
+
driversByKind;
|
|
33
|
+
constructor(drivers) {
|
|
34
|
+
this.driversByKind = new Map(drivers.map((d) => [d.driverKind, d]));
|
|
35
|
+
}
|
|
36
|
+
async load(configs) {
|
|
37
|
+
for (const [instanceId, entry] of Object.entries(configs)) {
|
|
38
|
+
const driver = this.driversByKind.get(entry.driver);
|
|
39
|
+
if (!driver) {
|
|
40
|
+
this.byId.set(instanceId, {
|
|
41
|
+
instanceId,
|
|
42
|
+
shadow: {
|
|
43
|
+
instanceId,
|
|
44
|
+
driverKind: entry.driver,
|
|
45
|
+
displayName: entry.displayName,
|
|
46
|
+
cli: cliOfRaw(entry.config),
|
|
47
|
+
shadow: true,
|
|
48
|
+
reason: `unknown driver "${entry.driver}" — kept as configured, unavailable here`,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const config = entry.config === undefined ? driver.defaultConfig() : driver.decodeConfig(entry.config);
|
|
55
|
+
// Override detection is on the RAW config, never the decoded one:
|
|
56
|
+
// decodeConfig fills in the driver default ("claude", "codex", …),
|
|
57
|
+
// so reading `cli` there would flag every instance as overridden.
|
|
58
|
+
const rawCli = cliOfRaw(entry.config);
|
|
59
|
+
if (rawCli)
|
|
60
|
+
this.cliByInstance.set(instanceId, rawCli);
|
|
61
|
+
const live = await driver.create({
|
|
62
|
+
instanceId,
|
|
63
|
+
displayName: entry.displayName ?? driver.metadata.displayName,
|
|
64
|
+
environment: entry.environment ?? {},
|
|
65
|
+
enabled: entry.enabled ?? true,
|
|
66
|
+
config,
|
|
67
|
+
});
|
|
68
|
+
this.byId.set(instanceId, { instanceId, live });
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
this.byId.set(instanceId, {
|
|
72
|
+
instanceId,
|
|
73
|
+
shadow: {
|
|
74
|
+
instanceId,
|
|
75
|
+
driverKind: entry.driver,
|
|
76
|
+
displayName: entry.displayName ?? driver.metadata.displayName,
|
|
77
|
+
cli: cliOfRaw(entry.config),
|
|
78
|
+
shadow: true,
|
|
79
|
+
reason: e instanceof Error ? e.message : String(e),
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
get(instanceId) {
|
|
86
|
+
return this.byId.get(instanceId)?.live ?? null;
|
|
87
|
+
}
|
|
88
|
+
/** The configured executable for instance-scoped maintenance actions.
|
|
89
|
+
* This deliberately comes from the registry/config, never an HTTP body. */
|
|
90
|
+
cliTarget(instanceId) {
|
|
91
|
+
const entry = this.byId.get(instanceId);
|
|
92
|
+
if (!entry)
|
|
93
|
+
return null;
|
|
94
|
+
const driverKind = entry.shadow?.driverKind ?? entry.live.driverKind;
|
|
95
|
+
const driver = this.driversByKind.get(driverKind);
|
|
96
|
+
return {
|
|
97
|
+
driverKind,
|
|
98
|
+
cli: this.cliByInstance.get(instanceId) ?? entry.shadow?.cli ?? cliDefaultOf(driver) ?? null,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
entries() {
|
|
102
|
+
return [...this.byId.values()];
|
|
103
|
+
}
|
|
104
|
+
instances() {
|
|
105
|
+
return [...this.byId.values()].flatMap((e) => (e.live ? [e.live] : []));
|
|
106
|
+
}
|
|
107
|
+
async refreshModels(instanceId) {
|
|
108
|
+
const instance = this.get(instanceId);
|
|
109
|
+
if (!instance)
|
|
110
|
+
return false;
|
|
111
|
+
await instance.refreshModels?.();
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
async installRuntime(instanceId) {
|
|
115
|
+
const instance = this.get(instanceId);
|
|
116
|
+
if (!instance?.installRuntime)
|
|
117
|
+
return false;
|
|
118
|
+
await instance.installRuntime();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
async startAuthentication(instanceId) {
|
|
122
|
+
const instance = this.get(instanceId);
|
|
123
|
+
return instance?.startAuthentication ? instance.startAuthentication() : null;
|
|
124
|
+
}
|
|
125
|
+
async completeAuthentication(instanceId, flowId, callbackUrl) {
|
|
126
|
+
const instance = this.get(instanceId);
|
|
127
|
+
if (!instance?.completeAuthentication)
|
|
128
|
+
return false;
|
|
129
|
+
await instance.completeAuthentication(flowId, callbackUrl);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
async cancelAuthentication(instanceId) {
|
|
133
|
+
const instance = this.get(instanceId);
|
|
134
|
+
if (!instance?.cancelAuthentication)
|
|
135
|
+
return false;
|
|
136
|
+
await instance.cancelAuthentication();
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
/** instance snapshots for the model picker: id, driver, models, health */
|
|
140
|
+
async describe() {
|
|
141
|
+
// Multiple instances may share a driver. Scan each default binary once
|
|
142
|
+
// per response instead of repeating filesystem work for every row.
|
|
143
|
+
const candidatesByName = new Map();
|
|
144
|
+
const candidatesFor = (driver) => {
|
|
145
|
+
const name = cliDefaultOf(driver);
|
|
146
|
+
if (!name)
|
|
147
|
+
return [];
|
|
148
|
+
const cached = candidatesByName.get(name);
|
|
149
|
+
if (cached)
|
|
150
|
+
return cached;
|
|
151
|
+
const found = findCliCandidates(name);
|
|
152
|
+
candidatesByName.set(name, found);
|
|
153
|
+
return found;
|
|
154
|
+
};
|
|
155
|
+
return Promise.all(this.entries().map(async (entry) => {
|
|
156
|
+
const driver = this.driversByKind.get(entry.shadow?.driverKind ?? entry.live.driverKind);
|
|
157
|
+
if (entry.shadow) {
|
|
158
|
+
return {
|
|
159
|
+
instanceId: entry.instanceId,
|
|
160
|
+
driverKind: entry.shadow.driverKind,
|
|
161
|
+
displayName: entry.shadow.displayName ?? entry.shadow.driverKind,
|
|
162
|
+
snapshot: { state: "unavailable", reason: entry.shadow.reason },
|
|
163
|
+
models: { default: "", options: [] },
|
|
164
|
+
capabilities: { computerMcp: false, agentsMcp: false, localComputerMcp: false },
|
|
165
|
+
// an unknown driver has no driver record, hence no install path
|
|
166
|
+
access: driver?.metadata.access ?? "subscription",
|
|
167
|
+
install: driver?.install,
|
|
168
|
+
cli: entry.shadow.cli,
|
|
169
|
+
cliDefault: cliDefaultOf(driver),
|
|
170
|
+
// a shadow is exactly the "your CLI is broken, pick another"
|
|
171
|
+
// case where the detected-path dropdown matters most
|
|
172
|
+
cliCandidates: candidatesFor(driver),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const inst = entry.live;
|
|
176
|
+
let snapshot;
|
|
177
|
+
try {
|
|
178
|
+
snapshot = await inst.snapshot();
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
snapshot = { state: "unavailable", reason: e instanceof Error ? e.message : String(e) };
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
instanceId: inst.instanceId,
|
|
185
|
+
driverKind: inst.driverKind,
|
|
186
|
+
displayName: inst.displayName ?? inst.driverKind,
|
|
187
|
+
snapshot,
|
|
188
|
+
models: inst.models,
|
|
189
|
+
capabilities: {
|
|
190
|
+
computerMcp: inst.adapter.capabilities.computerMcp === true,
|
|
191
|
+
agentsMcp: inst.adapter.capabilities.agentsMcp === true,
|
|
192
|
+
composioMcp: inst.adapter.capabilities.composioMcp === true,
|
|
193
|
+
phoneMcp: inst.adapter.capabilities.phoneMcp === true,
|
|
194
|
+
browserMcp: inst.adapter.capabilities.browserMcp === true,
|
|
195
|
+
images: inst.adapter.capabilities.images === true,
|
|
196
|
+
effortLevels: inst.adapter.capabilities.effortLevels,
|
|
197
|
+
queueing: inst.adapter.capabilities.queueing === true,
|
|
198
|
+
localComputerMcp: inst.adapter.capabilities.localComputerMcp === true,
|
|
199
|
+
approvalReview: inst.reviewPermission !== undefined,
|
|
200
|
+
},
|
|
201
|
+
access: driver?.metadata.access ?? "subscription",
|
|
202
|
+
install: driver?.install,
|
|
203
|
+
cli: this.cliByInstance.get(inst.instanceId),
|
|
204
|
+
cliDefault: cliDefaultOf(driver),
|
|
205
|
+
// every copy of the driver's default binary on the augmented PATH —
|
|
206
|
+
// the dropdown's "detected" entries. Snapshotted per describe() so a
|
|
207
|
+
// newly installed CLI shows up on the next refresh.
|
|
208
|
+
cliCandidates: candidatesFor(driver),
|
|
209
|
+
};
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
async disposeAll() {
|
|
213
|
+
await Promise.allSettled(this.instances().map((i) => i.dispose()));
|
|
214
|
+
this.byId.clear();
|
|
215
|
+
this.cliByInstance.clear();
|
|
216
|
+
}
|
|
217
|
+
}
|