minionsai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +89 -0
- package/bin/minions.mjs +19 -0
- package/dist/server/client/dist/assets/abap-BdImnpbu.js +1 -0
- package/dist/server/client/dist/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/server/client/dist/assets/ada-bCR0ucgS.js +1 -0
- package/dist/server/client/dist/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/server/client/dist/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/server/client/dist/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/server/client/dist/assets/apache-Pmp26Uib.js +1 -0
- package/dist/server/client/dist/assets/apex-D8_7TLub.js +1 -0
- package/dist/server/client/dist/assets/apl-dKokRX4l.js +1 -0
- package/dist/server/client/dist/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/server/client/dist/assets/ara-BRHolxvo.js +1 -0
- package/dist/server/client/dist/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/server/client/dist/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/server/client/dist/assets/astro-CbQHKStN.js +1 -0
- package/dist/server/client/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/server/client/dist/assets/awk-DMzUqQB5.js +1 -0
- package/dist/server/client/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/server/client/dist/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/server/client/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/server/client/dist/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/server/client/dist/assets/bat-BkioyH1T.js +1 -0
- package/dist/server/client/dist/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/server/client/dist/assets/berry-uYugtg8r.js +1 -0
- package/dist/server/client/dist/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/server/client/dist/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/server/client/dist/assets/bird2-DPOp833l.js +1 -0
- package/dist/server/client/dist/assets/blade-D4QpJJKB.js +1 -0
- package/dist/server/client/dist/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/server/client/dist/assets/c-BIGW1oBm.js +1 -0
- package/dist/server/client/dist/assets/c3-eo99z4R2.js +1 -0
- package/dist/server/client/dist/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/server/client/dist/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/server/client/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/server/client/dist/assets/clarity-D53aC0YG.js +1 -0
- package/dist/server/client/dist/assets/clojure-P80f7IUj.js +1 -0
- package/dist/server/client/dist/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/server/client/dist/assets/cobol-nwyudZeR.js +1 -0
- package/dist/server/client/dist/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/server/client/dist/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/server/client/dist/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/server/client/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/server/client/dist/assets/coq-DkFqJrB1.js +1 -0
- package/dist/server/client/dist/assets/cpp-CofmeUqb.js +1 -0
- package/dist/server/client/dist/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/server/client/dist/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/server/client/dist/assets/css-DPfMkruS.js +1 -0
- package/dist/server/client/dist/assets/csv-fuZLfV_i.js +1 -0
- package/dist/server/client/dist/assets/cue-D82EKSYY.js +1 -0
- package/dist/server/client/dist/assets/cypher-COkxafJQ.js +1 -0
- package/dist/server/client/dist/assets/d-85-TOEBH.js +1 -0
- package/dist/server/client/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/server/client/dist/assets/dart-CF10PKvl.js +1 -0
- package/dist/server/client/dist/assets/dax-CEL-wOlO.js +1 -0
- package/dist/server/client/dist/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/server/client/dist/assets/diff-D97Zzqfu.js +1 -0
- package/dist/server/client/dist/assets/docker-BcOcwvcX.js +1 -0
- package/dist/server/client/dist/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/server/client/dist/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/server/client/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/server/client/dist/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/server/client/dist/assets/edge-BkV0erSs.js +1 -0
- package/dist/server/client/dist/assets/elixir-CDX3lj18.js +1 -0
- package/dist/server/client/dist/assets/elm-DbKCFpqz.js +1 -0
- package/dist/server/client/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/server/client/dist/assets/erb-B12qg9BL.js +1 -0
- package/dist/server/client/dist/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/server/client/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/server/client/dist/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/server/client/dist/assets/fennel-BYunw83y.js +1 -0
- package/dist/server/client/dist/assets/fish-BvzEVeQv.js +1 -0
- package/dist/server/client/dist/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/server/client/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/server/client/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/server/client/dist/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/server/client/dist/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/server/client/dist/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/server/client/dist/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/server/client/dist/assets/genie-D0YGMca9.js +1 -0
- package/dist/server/client/dist/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/server/client/dist/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/server/client/dist/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/server/client/dist/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/server/client/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/server/client/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/server/client/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/server/client/dist/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/server/client/dist/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/server/client/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/server/client/dist/assets/gleam-BspZqrRM.js +1 -0
- package/dist/server/client/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/server/client/dist/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/server/client/dist/assets/glsl-DplSGwfg.js +1 -0
- package/dist/server/client/dist/assets/gn-n2N0HUVH.js +1 -0
- package/dist/server/client/dist/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/server/client/dist/assets/go-CxLEBnE3.js +1 -0
- package/dist/server/client/dist/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/server/client/dist/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/server/client/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/server/client/dist/assets/hack-CaT9iCJl.js +1 -0
- package/dist/server/client/dist/assets/haml-B8DHNrY2.js +1 -0
- package/dist/server/client/dist/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/server/client/dist/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/server/client/dist/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/server/client/dist/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/server/client/dist/assets/highlighted-body-TPN3WLV5-Dmyr2DoJ.js +1 -0
- package/dist/server/client/dist/assets/hjson-D5-asLiD.js +1 -0
- package/dist/server/client/dist/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/server/client/dist/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/server/client/dist/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/server/client/dist/assets/houston-DnULxvSX.js +1 -0
- package/dist/server/client/dist/assets/html-GMplVEZG.js +1 -0
- package/dist/server/client/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/server/client/dist/assets/http-jrhK8wxY.js +1 -0
- package/dist/server/client/dist/assets/hurl-irOxFIW8.js +1 -0
- package/dist/server/client/dist/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/server/client/dist/assets/hy-DFXneXwc.js +1 -0
- package/dist/server/client/dist/assets/imba-DGztddWO.js +1 -0
- package/dist/server/client/dist/assets/index-BB7507W7.css +1 -0
- package/dist/server/client/dist/assets/index-hLQDnL9J.js +694 -0
- package/dist/server/client/dist/assets/ini-BEwlwnbL.js +1 -0
- package/dist/server/client/dist/assets/java-CylS5w8V.js +1 -0
- package/dist/server/client/dist/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/server/client/dist/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/server/client/dist/assets/jison-wvAkD_A8.js +1 -0
- package/dist/server/client/dist/assets/json-Cp-IABpG.js +1 -0
- package/dist/server/client/dist/assets/json5-C9tS-k6U.js +1 -0
- package/dist/server/client/dist/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/server/client/dist/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/server/client/dist/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/server/client/dist/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/server/client/dist/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/server/client/dist/assets/julia-CxzCAyBv.js +1 -0
- package/dist/server/client/dist/assets/just-Cw27pwNe.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/server/client/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/server/client/dist/assets/kdl-DV7GczEv.js +1 -0
- package/dist/server/client/dist/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/server/client/dist/assets/kusto-DZf3V79B.js +1 -0
- package/dist/server/client/dist/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/server/client/dist/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/server/client/dist/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/server/client/dist/assets/less-B1dDrJ26.js +1 -0
- package/dist/server/client/dist/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/server/client/dist/assets/liquid-DYVedYrR.js +1 -0
- package/dist/server/client/dist/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/server/client/dist/assets/log-2UxHyX5q.js +1 -0
- package/dist/server/client/dist/assets/logo-BtOb2qkB.js +1 -0
- package/dist/server/client/dist/assets/lua-BaeVxFsk.js +1 -0
- package/dist/server/client/dist/assets/luau-C-HG3fhB.js +1 -0
- package/dist/server/client/dist/assets/make-CHLpvVh8.js +1 -0
- package/dist/server/client/dist/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/server/client/dist/assets/marko-CnJfTvn9.js +1 -0
- package/dist/server/client/dist/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/server/client/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/server/client/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/server/client/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/server/client/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/server/client/dist/assets/matlab-D7o27uSR.js +1 -0
- package/dist/server/client/dist/assets/mdc-BMNejdWA.js +1 -0
- package/dist/server/client/dist/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/server/client/dist/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/server/client/dist/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/server/client/dist/assets/min-light-CTRr51gU.js +1 -0
- package/dist/server/client/dist/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/server/client/dist/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/server/client/dist/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/server/client/dist/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/server/client/dist/assets/move-IF9eRakj.js +1 -0
- package/dist/server/client/dist/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/server/client/dist/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/server/client/dist/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/server/client/dist/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/server/client/dist/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/server/client/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/server/client/dist/assets/nim-CVrawwO9.js +1 -0
- package/dist/server/client/dist/assets/nix-CwoSXNpI.js +1 -0
- package/dist/server/client/dist/assets/nord-Ddv68eIx.js +1 -0
- package/dist/server/client/dist/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/server/client/dist/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/server/client/dist/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/server/client/dist/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/server/client/dist/assets/odin-BBf5iR-q.js +1 -0
- package/dist/server/client/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/server/client/dist/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/server/client/dist/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/server/client/dist/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/server/client/dist/assets/perl-C0TMdlhV.js +1 -0
- package/dist/server/client/dist/assets/php-Dhbhpdrm.js +1 -0
- package/dist/server/client/dist/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/server/client/dist/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/server/client/dist/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/server/client/dist/assets/po-BTJTHyun.js +1 -0
- package/dist/server/client/dist/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/server/client/dist/assets/polar-C0HS_06l.js +1 -0
- package/dist/server/client/dist/assets/postcss-CXtECtnM.js +1 -0
- package/dist/server/client/dist/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/server/client/dist/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/server/client/dist/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/server/client/dist/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/server/client/dist/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/server/client/dist/assets/pug-CGlum2m_.js +1 -0
- package/dist/server/client/dist/assets/puppet-BMWR74SV.js +1 -0
- package/dist/server/client/dist/assets/purescript-CklMAg4u.js +1 -0
- package/dist/server/client/dist/assets/python-B6aJPvgy.js +1 -0
- package/dist/server/client/dist/assets/qml-3beO22l8.js +1 -0
- package/dist/server/client/dist/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/server/client/dist/assets/qss-IeuSbFQv.js +1 -0
- package/dist/server/client/dist/assets/r-Dspwwk_N.js +1 -0
- package/dist/server/client/dist/assets/racket-BqYA7rlc.js +1 -0
- package/dist/server/client/dist/assets/raku-DXvB9xmW.js +1 -0
- package/dist/server/client/dist/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/server/client/dist/assets/red-bN70gL4F.js +1 -0
- package/dist/server/client/dist/assets/reg-C-SQnVFl.js +1 -0
- package/dist/server/client/dist/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/server/client/dist/assets/rel-C3B-1QV4.js +1 -0
- package/dist/server/client/dist/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/server/client/dist/assets/ron-D8l8udqQ.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/server/client/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/server/client/dist/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/server/client/dist/assets/rst-BrH8l1NY.js +1 -0
- package/dist/server/client/dist/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/server/client/dist/assets/rust-B1yitclQ.js +1 -0
- package/dist/server/client/dist/assets/sas-cz2c8ADy.js +1 -0
- package/dist/server/client/dist/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/server/client/dist/assets/scala-C151Ov-r.js +1 -0
- package/dist/server/client/dist/assets/scheme-C98Dy4si.js +1 -0
- package/dist/server/client/dist/assets/scss-OYdSNvt2.js +1 -0
- package/dist/server/client/dist/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/server/client/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/server/client/dist/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/server/client/dist/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/server/client/dist/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/server/client/dist/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/server/client/dist/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/server/client/dist/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/server/client/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/server/client/dist/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/server/client/dist/assets/solidity-rGO070M0.js +1 -0
- package/dist/server/client/dist/assets/soy-Brmx7dQM.js +1 -0
- package/dist/server/client/dist/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/server/client/dist/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/server/client/dist/assets/sql-BLtJtn59.js +1 -0
- package/dist/server/client/dist/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/server/client/dist/assets/stata-BH5u7GGu.js +1 -0
- package/dist/server/client/dist/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/server/client/dist/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/server/client/dist/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/server/client/dist/assets/swift-D82vCrfD.js +1 -0
- package/dist/server/client/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/server/client/dist/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/server/client/dist/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/server/client/dist/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/server/client/dist/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/server/client/dist/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/server/client/dist/assets/templ-P3uqSqPl.js +1 -0
- package/dist/server/client/dist/assets/terraform-BETggiCN.js +1 -0
- package/dist/server/client/dist/assets/tex-idrVyKtj.js +1 -0
- package/dist/server/client/dist/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/server/client/dist/assets/toml-vGWfd6FD.js +1 -0
- package/dist/server/client/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/server/client/dist/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/server/client/dist/assets/tsx-COt5Ahok.js +1 -0
- package/dist/server/client/dist/assets/turtle-BsS91CYL.js +1 -0
- package/dist/server/client/dist/assets/twig-DNn4PbVi.js +1 -0
- package/dist/server/client/dist/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/server/client/dist/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/server/client/dist/assets/typst-DHCkPAjA.js +1 -0
- package/dist/server/client/dist/assets/v-BcVCzyr7.js +1 -0
- package/dist/server/client/dist/assets/vala-CsfeWuGM.js +1 -0
- package/dist/server/client/dist/assets/vb-D17OF-Vu.js +1 -0
- package/dist/server/client/dist/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/server/client/dist/assets/vesper-DU1UobuO.js +1 -0
- package/dist/server/client/dist/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/server/client/dist/assets/viml-CJc9bBzg.js +1 -0
- package/dist/server/client/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/server/client/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/server/client/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/server/client/dist/assets/vue-DN_0RTcg.js +1 -0
- package/dist/server/client/dist/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/server/client/dist/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/server/client/dist/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/server/client/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/server/client/dist/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/server/client/dist/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/server/client/dist/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/server/client/dist/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/server/client/dist/assets/wit-5i3qLPDT.js +1 -0
- package/dist/server/client/dist/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/server/client/dist/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/server/client/dist/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/server/client/dist/assets/yaml-Buea-lGh.js +1 -0
- package/dist/server/client/dist/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/server/client/dist/assets/zig-VOosw3JB.js +1 -0
- package/dist/server/client/dist/favicon.ico +0 -0
- package/dist/server/client/dist/index.html +17 -0
- package/dist/server/client/dist/logo.png +0 -0
- package/dist/server/server/adapters/hermes-worker.d.ts +37 -0
- package/dist/server/server/adapters/hermes-worker.js +525 -0
- package/dist/server/server/adapters/types.d.ts +39 -0
- package/dist/server/server/adapters/types.js +1 -0
- package/dist/server/server/adapters/worker-protocol.d.ts +141 -0
- package/dist/server/server/adapters/worker-protocol.js +1 -0
- package/dist/server/server/agent-settings.d.ts +12 -0
- package/dist/server/server/agent-settings.js +56 -0
- package/dist/server/server/app.d.ts +5 -0
- package/dist/server/server/app.js +41 -0
- package/dist/server/server/db/index.d.ts +2 -0
- package/dist/server/server/db/index.js +14 -0
- package/dist/server/server/db/queries.d.ts +22 -0
- package/dist/server/server/db/queries.js +116 -0
- package/dist/server/server/db/schema.sql +16 -0
- package/dist/server/server/errors.d.ts +3 -0
- package/dist/server/server/errors.js +12 -0
- package/dist/server/server/events.d.ts +7 -0
- package/dist/server/server/events.js +50 -0
- package/dist/server/server/frontend.d.ts +4 -0
- package/dist/server/server/frontend.js +32 -0
- package/dist/server/server/index.d.ts +2 -0
- package/dist/server/server/index.js +63 -0
- package/dist/server/server/live-chat.d.ts +17 -0
- package/dist/server/server/live-chat.js +217 -0
- package/dist/server/server/paths.d.ts +7 -0
- package/dist/server/server/paths.js +39 -0
- package/dist/server/server/prompts/task-agent.d.ts +1 -0
- package/dist/server/server/prompts/task-agent.js +26 -0
- package/dist/server/server/routes/agent.d.ts +4 -0
- package/dist/server/server/routes/agent.js +94 -0
- package/dist/server/server/routes/chat.d.ts +1 -0
- package/dist/server/server/routes/chat.js +177 -0
- package/dist/server/server/routes/cron.d.ts +4 -0
- package/dist/server/server/routes/cron.js +109 -0
- package/dist/server/server/routes/files.d.ts +1 -0
- package/dist/server/server/routes/files.js +543 -0
- package/dist/server/server/routes/skills.d.ts +1 -0
- package/dist/server/server/routes/skills.js +13 -0
- package/dist/server/server/routes/tasks.d.ts +1 -0
- package/dist/server/server/routes/tasks.js +107 -0
- package/dist/server/server/skills/catalog.d.ts +21 -0
- package/dist/server/server/skills/catalog.js +160 -0
- package/dist/server/server/workers/hermes_cron.py +241 -0
- package/dist/server/server/workers/hermes_sessions.py +264 -0
- package/dist/server/server/workers/hermes_worker.py +1270 -0
- package/dist/server/server/workers/hermes_worker_utils.py +39 -0
- package/dist/server/shared/types.d.ts +211 -0
- package/dist/server/shared/types.js +2 -0
- package/package.json +74 -0
- package/skills/lead-generation/SKILL.md +41 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReasoningEffort, type Task } from '../shared/types.js';
|
|
2
|
+
import type { AgentRunSettings } from './adapters/types.js';
|
|
3
|
+
export interface AgentSettingsUpdate {
|
|
4
|
+
agent_model?: string | null;
|
|
5
|
+
reasoning_effort?: ReasoningEffort | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ParsedRunSettings {
|
|
8
|
+
taskFields: AgentSettingsUpdate;
|
|
9
|
+
hasFields: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function taskRunSettings(task: Task): AgentRunSettings;
|
|
12
|
+
export declare function parseRunSettingsBody(body: unknown): ParsedRunSettings;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { REASONING_EFFORTS } from '../shared/types.js';
|
|
2
|
+
import { isRecord } from './errors.js';
|
|
3
|
+
function hasOwn(record, key) {
|
|
4
|
+
return Object.prototype.hasOwnProperty.call(record, key);
|
|
5
|
+
}
|
|
6
|
+
function firstPresent(record, keys) {
|
|
7
|
+
for (const key of keys) {
|
|
8
|
+
if (hasOwn(record, key))
|
|
9
|
+
return record[key];
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
function normalizeModel(value) {
|
|
14
|
+
if (value === undefined)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (value === null)
|
|
17
|
+
return null;
|
|
18
|
+
if (typeof value !== 'string')
|
|
19
|
+
throw new Error('model must be a string or null');
|
|
20
|
+
const trimmed = value.trim();
|
|
21
|
+
return trimmed || null;
|
|
22
|
+
}
|
|
23
|
+
function normalizeReasoningEffort(value) {
|
|
24
|
+
if (value === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (value === null)
|
|
27
|
+
return null;
|
|
28
|
+
if (typeof value !== 'string' || !REASONING_EFFORTS.includes(value)) {
|
|
29
|
+
throw new Error(`reasoningEffort must be one of: ${REASONING_EFFORTS.join(', ')}`);
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
function parseSettingsFields(body) {
|
|
34
|
+
const record = isRecord(body) ? body : {};
|
|
35
|
+
const model = normalizeModel(firstPresent(record, ['agentModel', 'agent_model', 'model']));
|
|
36
|
+
const reasoningEffort = normalizeReasoningEffort(firstPresent(record, ['reasoningEffort', 'reasoning_effort']));
|
|
37
|
+
return {
|
|
38
|
+
...(model !== undefined ? { agent_model: model } : {}),
|
|
39
|
+
...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function taskRunSettings(task) {
|
|
43
|
+
return {
|
|
44
|
+
model: task.agent_model,
|
|
45
|
+
reasoningEffort: task.reasoning_effort,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function parseRunSettingsBody(body) {
|
|
49
|
+
const record = isRecord(body) ? body : {};
|
|
50
|
+
const source = hasOwn(record, 'settings') ? record.settings : record;
|
|
51
|
+
if (hasOwn(record, 'settings') && !isRecord(source)) {
|
|
52
|
+
throw new Error('settings must be an object');
|
|
53
|
+
}
|
|
54
|
+
const taskFields = parseSettingsFields(source);
|
|
55
|
+
return { taskFields, hasFields: Object.keys(taskFields).length > 0 };
|
|
56
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import { tasksRouter } from './routes/tasks.js';
|
|
4
|
+
import { chatRouter } from './routes/chat.js';
|
|
5
|
+
import { createAgentRouter, createTaskAgentSettingsRouter } from './routes/agent.js';
|
|
6
|
+
import { createCronRouter, createTaskCronRouter } from './routes/cron.js';
|
|
7
|
+
import { skillsRouter } from './routes/skills.js';
|
|
8
|
+
import { filesRouter } from './routes/files.js';
|
|
9
|
+
import { HermesWorkerAdapter } from './adapters/hermes-worker.js';
|
|
10
|
+
import { initSSE, addClient, sendEvent } from './events.js';
|
|
11
|
+
import { getRunStatuses } from './live-chat.js';
|
|
12
|
+
const app = express();
|
|
13
|
+
app.use(cors());
|
|
14
|
+
const adapter = new HermesWorkerAdapter();
|
|
15
|
+
app.get('/api/health', async (_req, res) => {
|
|
16
|
+
const hermes = await adapter.healthCheck();
|
|
17
|
+
res.json({ ok: true, hermes });
|
|
18
|
+
});
|
|
19
|
+
app.get('/api/events', (req, res) => {
|
|
20
|
+
initSSE(res);
|
|
21
|
+
addClient(res);
|
|
22
|
+
sendEvent(res, { type: 'task_runs_snapshot', runs: getRunStatuses() });
|
|
23
|
+
});
|
|
24
|
+
app.use('/api/files', express.json({ limit: '25mb' }), filesRouter);
|
|
25
|
+
app.use(express.json());
|
|
26
|
+
app.use('/api/tasks', tasksRouter);
|
|
27
|
+
app.use('/api/tasks', createTaskCronRouter(adapter));
|
|
28
|
+
app.use('/api/tasks', createTaskAgentSettingsRouter(adapter));
|
|
29
|
+
app.use('/api/tasks', chatRouter);
|
|
30
|
+
app.use('/api/agent', createAgentRouter(adapter));
|
|
31
|
+
app.use('/api/cron', createCronRouter(adapter));
|
|
32
|
+
app.use('/api/skills', skillsRouter);
|
|
33
|
+
app.use((error, _req, res, next) => {
|
|
34
|
+
if (!res.headersSent && error && typeof error === 'object' && error.type === 'entity.too.large') {
|
|
35
|
+
res.status(413).json({ error: 'Request body is too large', code: 'PAYLOAD_TOO_LARGE' });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
next(error);
|
|
39
|
+
});
|
|
40
|
+
export { adapter };
|
|
41
|
+
export default app;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { resolveMinionsDbPath, ensureMinionsStateDirs } from '../paths.js';
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
ensureMinionsStateDirs();
|
|
8
|
+
const dbPath = resolveMinionsDbPath();
|
|
9
|
+
const db = new Database(dbPath);
|
|
10
|
+
db.pragma('journal_mode = WAL');
|
|
11
|
+
db.pragma('foreign_keys = ON');
|
|
12
|
+
const schema = readFileSync(join(__dirname, 'schema.sql'), 'utf-8');
|
|
13
|
+
db.exec(schema);
|
|
14
|
+
export default db;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Task, type TaskStatus, type ReasoningEffort, type ContextUsage } from '../../shared/types.js';
|
|
2
|
+
export declare function getAllTasks(status?: TaskStatus): Task[];
|
|
3
|
+
export declare function getTask(id: string): Task | undefined;
|
|
4
|
+
export declare function insertTask(task: {
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string | null;
|
|
7
|
+
status: TaskStatus;
|
|
8
|
+
agent_model?: string | null;
|
|
9
|
+
reasoning_effort?: ReasoningEffort | null;
|
|
10
|
+
last_agent_response_at?: number | null;
|
|
11
|
+
}): Task;
|
|
12
|
+
type TaskUpdateFields = Pick<Task, 'title' | 'description' | 'status' | 'agent_model' | 'reasoning_effort' | 'last_agent_response_at' | 'last_context_used_tokens' | 'last_context_window_tokens'>;
|
|
13
|
+
export declare function updateTask(id: string, fields: Partial<TaskUpdateFields>): Task | undefined;
|
|
14
|
+
export declare function touchTask(id: string): void;
|
|
15
|
+
export declare function contextFromTask(task: Task): ContextUsage | null;
|
|
16
|
+
export declare function recordAgentResponse(taskId: string, at?: number, context?: ContextUsage | null): Task | undefined;
|
|
17
|
+
export declare function markTaskViewed(id: string): {
|
|
18
|
+
task: Task | undefined;
|
|
19
|
+
changed: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare function deleteTask(id: string): boolean;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
2
|
+
import db from './index.js';
|
|
3
|
+
const stmtAllTasks = db.prepare('SELECT * FROM tasks ORDER BY updated_at DESC');
|
|
4
|
+
const stmtTasksByStatus = db.prepare('SELECT * FROM tasks WHERE status = ? ORDER BY updated_at DESC');
|
|
5
|
+
const stmtGetTask = db.prepare('SELECT * FROM tasks WHERE id = ?');
|
|
6
|
+
const stmtInsertTask = db.prepare(`
|
|
7
|
+
INSERT INTO tasks (
|
|
8
|
+
id, title, description, status, agent_model, reasoning_effort,
|
|
9
|
+
created_at, updated_at, last_agent_response_at, last_viewed_at,
|
|
10
|
+
last_context_used_tokens, last_context_window_tokens
|
|
11
|
+
)
|
|
12
|
+
VALUES (
|
|
13
|
+
@id, @title, @description, @status, @agent_model, @reasoning_effort,
|
|
14
|
+
@created_at, @updated_at, @last_agent_response_at, @last_viewed_at,
|
|
15
|
+
@last_context_used_tokens, @last_context_window_tokens
|
|
16
|
+
)
|
|
17
|
+
`);
|
|
18
|
+
const stmtDeleteTask = db.prepare('DELETE FROM tasks WHERE id = ?');
|
|
19
|
+
const stmtTouchTask = db.prepare('UPDATE tasks SET updated_at = ? WHERE id = ?');
|
|
20
|
+
const stmtMarkTaskViewed = db.prepare(`
|
|
21
|
+
UPDATE tasks
|
|
22
|
+
SET last_viewed_at = last_agent_response_at
|
|
23
|
+
WHERE id = ?
|
|
24
|
+
AND last_agent_response_at IS NOT NULL
|
|
25
|
+
AND (last_viewed_at IS NULL OR last_viewed_at < last_agent_response_at)
|
|
26
|
+
`);
|
|
27
|
+
export function getAllTasks(status) {
|
|
28
|
+
return status ? stmtTasksByStatus.all(status) : stmtAllTasks.all();
|
|
29
|
+
}
|
|
30
|
+
export function getTask(id) {
|
|
31
|
+
return stmtGetTask.get(id);
|
|
32
|
+
}
|
|
33
|
+
export function insertTask(task) {
|
|
34
|
+
const id = uuid();
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
const row = {
|
|
37
|
+
id,
|
|
38
|
+
title: task.title,
|
|
39
|
+
description: task.description ?? null,
|
|
40
|
+
status: task.status,
|
|
41
|
+
agent_model: task.agent_model ?? null,
|
|
42
|
+
reasoning_effort: task.reasoning_effort ?? null,
|
|
43
|
+
created_at: now,
|
|
44
|
+
updated_at: now,
|
|
45
|
+
last_agent_response_at: task.last_agent_response_at ?? null,
|
|
46
|
+
last_viewed_at: null,
|
|
47
|
+
last_context_used_tokens: null,
|
|
48
|
+
last_context_window_tokens: null,
|
|
49
|
+
};
|
|
50
|
+
stmtInsertTask.run(row);
|
|
51
|
+
return row;
|
|
52
|
+
}
|
|
53
|
+
const ALLOWED_UPDATE_FIELDS = new Set([
|
|
54
|
+
'title',
|
|
55
|
+
'description',
|
|
56
|
+
'status',
|
|
57
|
+
'agent_model',
|
|
58
|
+
'reasoning_effort',
|
|
59
|
+
'last_agent_response_at',
|
|
60
|
+
'last_context_used_tokens',
|
|
61
|
+
'last_context_window_tokens',
|
|
62
|
+
]);
|
|
63
|
+
const updateStmtCache = new Map();
|
|
64
|
+
function getUpdateStmt(fieldKeys) {
|
|
65
|
+
const key = fieldKeys.join(',');
|
|
66
|
+
let stmt = updateStmtCache.get(key);
|
|
67
|
+
if (!stmt) {
|
|
68
|
+
const sets = fieldKeys.map(f => `${f} = @${f}`).join(', ');
|
|
69
|
+
stmt = db.prepare(`UPDATE tasks SET ${sets}, updated_at = @updated_at WHERE id = @id`);
|
|
70
|
+
updateStmtCache.set(key, stmt);
|
|
71
|
+
}
|
|
72
|
+
return stmt;
|
|
73
|
+
}
|
|
74
|
+
export function updateTask(id, fields) {
|
|
75
|
+
const fieldKeys = [];
|
|
76
|
+
const values = { id };
|
|
77
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
78
|
+
if (!ALLOWED_UPDATE_FIELDS.has(key))
|
|
79
|
+
continue;
|
|
80
|
+
fieldKeys.push(key);
|
|
81
|
+
values[key] = value ?? null;
|
|
82
|
+
}
|
|
83
|
+
if (fieldKeys.length === 0)
|
|
84
|
+
return getTask(id);
|
|
85
|
+
values.updated_at = Date.now();
|
|
86
|
+
getUpdateStmt(fieldKeys).run(values);
|
|
87
|
+
return getTask(id);
|
|
88
|
+
}
|
|
89
|
+
export function touchTask(id) {
|
|
90
|
+
stmtTouchTask.run(Date.now(), id);
|
|
91
|
+
}
|
|
92
|
+
export function contextFromTask(task) {
|
|
93
|
+
if (task.last_context_used_tokens == null || task.last_context_window_tokens == null)
|
|
94
|
+
return null;
|
|
95
|
+
return { used_tokens: task.last_context_used_tokens, window_tokens: task.last_context_window_tokens };
|
|
96
|
+
}
|
|
97
|
+
export function recordAgentResponse(taskId, at = Date.now(), context) {
|
|
98
|
+
return updateTask(taskId, {
|
|
99
|
+
last_agent_response_at: at,
|
|
100
|
+
...(context !== undefined ? {
|
|
101
|
+
last_context_used_tokens: context?.used_tokens ?? null,
|
|
102
|
+
last_context_window_tokens: context?.window_tokens ?? null,
|
|
103
|
+
} : {}),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export function markTaskViewed(id) {
|
|
107
|
+
const result = stmtMarkTaskViewed.run(id);
|
|
108
|
+
return {
|
|
109
|
+
task: getTask(id),
|
|
110
|
+
changed: result.changes > 0,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export function deleteTask(id) {
|
|
114
|
+
const result = stmtDeleteTask.run(id);
|
|
115
|
+
return result.changes > 0;
|
|
116
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
title TEXT NOT NULL,
|
|
4
|
+
description TEXT,
|
|
5
|
+
status TEXT NOT NULL DEFAULT 'in_progress',
|
|
6
|
+
agent_model TEXT,
|
|
7
|
+
reasoning_effort TEXT,
|
|
8
|
+
created_at INTEGER NOT NULL,
|
|
9
|
+
updated_at INTEGER NOT NULL,
|
|
10
|
+
last_agent_response_at INTEGER,
|
|
11
|
+
last_viewed_at INTEGER,
|
|
12
|
+
last_context_used_tokens INTEGER,
|
|
13
|
+
last_context_window_tokens INTEGER
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function toErrorMessage(error, fallback = 'Something went wrong') {
|
|
2
|
+
return error instanceof Error ? error.message : fallback;
|
|
3
|
+
}
|
|
4
|
+
export function isRecord(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function errorCode(error) {
|
|
8
|
+
if (!(error instanceof Error))
|
|
9
|
+
return undefined;
|
|
10
|
+
const code = error.code;
|
|
11
|
+
return typeof code === 'string' ? code : undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import type { BoardEvent } from '../shared/types.js';
|
|
3
|
+
export type { BoardEvent };
|
|
4
|
+
export declare function initSSE(res: Response): void;
|
|
5
|
+
export declare function addClient(res: Response): void;
|
|
6
|
+
export declare function sendEvent(res: Response, event: BoardEvent): void;
|
|
7
|
+
export declare function broadcast(event: BoardEvent): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const clients = new Set();
|
|
2
|
+
const KEEPALIVE_INTERVAL_MS = 30_000;
|
|
3
|
+
let keepaliveTimer = null;
|
|
4
|
+
function startKeepalive() {
|
|
5
|
+
if (keepaliveTimer)
|
|
6
|
+
return;
|
|
7
|
+
keepaliveTimer = setInterval(() => {
|
|
8
|
+
for (const client of clients) {
|
|
9
|
+
try {
|
|
10
|
+
client.write(':keepalive\n\n');
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
clients.delete(client);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (clients.size === 0) {
|
|
17
|
+
clearInterval(keepaliveTimer);
|
|
18
|
+
keepaliveTimer = null;
|
|
19
|
+
}
|
|
20
|
+
}, KEEPALIVE_INTERVAL_MS);
|
|
21
|
+
}
|
|
22
|
+
export function initSSE(res) {
|
|
23
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
24
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
25
|
+
res.setHeader('Connection', 'keep-alive');
|
|
26
|
+
res.flushHeaders();
|
|
27
|
+
}
|
|
28
|
+
export function addClient(res) {
|
|
29
|
+
clients.add(res);
|
|
30
|
+
res.on('close', () => clients.delete(res));
|
|
31
|
+
startKeepalive();
|
|
32
|
+
}
|
|
33
|
+
function writeEvent(res, event) {
|
|
34
|
+
const data = `data: ${JSON.stringify(event)}\n\n`;
|
|
35
|
+
try {
|
|
36
|
+
return res.write(data);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function sendEvent(res, event) {
|
|
43
|
+
writeEvent(res, event);
|
|
44
|
+
}
|
|
45
|
+
export function broadcast(event) {
|
|
46
|
+
for (const client of clients) {
|
|
47
|
+
if (!writeEvent(client, event))
|
|
48
|
+
clients.delete(client);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const CLIENT_DIR = path.resolve(__dirname, '..', 'client');
|
|
7
|
+
const CLIENT_DIST_DIR = path.join(CLIENT_DIR, 'dist');
|
|
8
|
+
const CLIENT_INDEX = path.join(CLIENT_DIST_DIR, 'index.html');
|
|
9
|
+
export async function mountFrontend(app, httpServer) {
|
|
10
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
11
|
+
const { createServer: createViteServer } = await import('vite');
|
|
12
|
+
const vite = await createViteServer({
|
|
13
|
+
configFile: path.join(CLIENT_DIR, 'vite.config.ts'),
|
|
14
|
+
root: CLIENT_DIR,
|
|
15
|
+
appType: 'spa',
|
|
16
|
+
server: {
|
|
17
|
+
middlewareMode: true,
|
|
18
|
+
hmr: { server: httpServer },
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
app.use(vite.middlewares);
|
|
22
|
+
return () => vite.close();
|
|
23
|
+
}
|
|
24
|
+
if (!existsSync(CLIENT_INDEX)) {
|
|
25
|
+
throw new Error(`Client build not found at ${CLIENT_INDEX}. Run npm run build first.`);
|
|
26
|
+
}
|
|
27
|
+
app.use(express.static(CLIENT_DIST_DIR));
|
|
28
|
+
app.get('*', (_req, res) => {
|
|
29
|
+
res.sendFile(CLIENT_INDEX);
|
|
30
|
+
});
|
|
31
|
+
return () => { };
|
|
32
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import './db/index.js';
|
|
3
|
+
import { once } from 'node:events';
|
|
4
|
+
import { createServer } from 'node:http';
|
|
5
|
+
import app, { adapter } from './app.js';
|
|
6
|
+
import { mountFrontend } from './frontend.js';
|
|
7
|
+
import { ensureBundledSkillsLinked } from './skills/catalog.js';
|
|
8
|
+
const PORT = parseInt(process.env.PORT || '6969', 10);
|
|
9
|
+
const httpServer = createServer(app);
|
|
10
|
+
let closeFrontend = () => { };
|
|
11
|
+
let shuttingDown = false;
|
|
12
|
+
async function main() {
|
|
13
|
+
ensureBundledSkillsLinked();
|
|
14
|
+
closeFrontend = await mountFrontend(app, httpServer);
|
|
15
|
+
await adapter.start();
|
|
16
|
+
httpServer.listen(PORT);
|
|
17
|
+
await once(httpServer, 'listening');
|
|
18
|
+
console.log(`Hermes Agent Mission Control running on http://localhost:${PORT}`);
|
|
19
|
+
}
|
|
20
|
+
function closeHttpServer() {
|
|
21
|
+
return new Promise((resolveClose, rejectClose) => {
|
|
22
|
+
if (!httpServer.listening) {
|
|
23
|
+
resolveClose();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
httpServer.close((error) => {
|
|
27
|
+
if (error)
|
|
28
|
+
rejectClose(error);
|
|
29
|
+
else
|
|
30
|
+
resolveClose();
|
|
31
|
+
});
|
|
32
|
+
httpServer.closeAllConnections();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async function shutdown(reason, exitCode = 0) {
|
|
36
|
+
if (shuttingDown) {
|
|
37
|
+
httpServer.closeAllConnections();
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
shuttingDown = true;
|
|
41
|
+
const forceExit = setTimeout(() => {
|
|
42
|
+
console.error(`Forced shutdown after ${reason}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}, 5000);
|
|
45
|
+
forceExit.unref();
|
|
46
|
+
const results = await Promise.allSettled([
|
|
47
|
+
closeHttpServer(),
|
|
48
|
+
closeFrontend(),
|
|
49
|
+
adapter.stop(),
|
|
50
|
+
]);
|
|
51
|
+
for (const result of results) {
|
|
52
|
+
if (result.status === 'rejected')
|
|
53
|
+
console.error(result.reason);
|
|
54
|
+
}
|
|
55
|
+
clearTimeout(forceExit);
|
|
56
|
+
process.exit(results.some((result) => result.status === 'rejected') ? 1 : exitCode);
|
|
57
|
+
}
|
|
58
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
59
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
60
|
+
main().catch((error) => {
|
|
61
|
+
console.error(error);
|
|
62
|
+
void shutdown('startup-error', 1);
|
|
63
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import type { LiveChatRun, TaskRunState } from '../shared/types.js';
|
|
3
|
+
import type { StreamEvent } from './adapters/types.js';
|
|
4
|
+
export type LiveChatEvent = StreamEvent | {
|
|
5
|
+
type: 'snapshot';
|
|
6
|
+
run: LiveChatRun;
|
|
7
|
+
};
|
|
8
|
+
export declare function startRun(taskId: string, sessionId: string, userContent: string): LiveChatRun;
|
|
9
|
+
export declare function applyEvent(taskId: string, event: StreamEvent): void;
|
|
10
|
+
export declare function getRun(taskId: string): LiveChatRun | undefined;
|
|
11
|
+
export declare function getRunContext(taskId: string): LiveChatRun['context'] | undefined;
|
|
12
|
+
export declare function getRunStatus(taskId: string): TaskRunState | undefined;
|
|
13
|
+
export declare function getRunStatuses(): TaskRunState[];
|
|
14
|
+
export declare function subscribe(taskId: string, res: Response): void;
|
|
15
|
+
export declare function sendSnapshot(res: Response, run: LiveChatRun): void;
|
|
16
|
+
export declare function broadcast(taskId: string, event: LiveChatEvent): void;
|
|
17
|
+
export declare function finishRun(taskId: string, ttlMs: number, runId: string): void;
|