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.
Files changed (361) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/bin/minions.mjs +19 -0
  4. package/dist/server/client/dist/assets/abap-BdImnpbu.js +1 -0
  5. package/dist/server/client/dist/assets/actionscript-3-CoDkCxhg.js +1 -0
  6. package/dist/server/client/dist/assets/ada-bCR0ucgS.js +1 -0
  7. package/dist/server/client/dist/assets/andromeeda-C4gqWexZ.js +1 -0
  8. package/dist/server/client/dist/assets/angular-html-CU67Zn6k.js +1 -0
  9. package/dist/server/client/dist/assets/angular-ts-BwZT4LLn.js +1 -0
  10. package/dist/server/client/dist/assets/apache-Pmp26Uib.js +1 -0
  11. package/dist/server/client/dist/assets/apex-D8_7TLub.js +1 -0
  12. package/dist/server/client/dist/assets/apl-dKokRX4l.js +1 -0
  13. package/dist/server/client/dist/assets/applescript-Co6uUVPk.js +1 -0
  14. package/dist/server/client/dist/assets/ara-BRHolxvo.js +1 -0
  15. package/dist/server/client/dist/assets/asciidoc-Ve4PFQV2.js +1 -0
  16. package/dist/server/client/dist/assets/asm-D_Q5rh1f.js +1 -0
  17. package/dist/server/client/dist/assets/astro-CbQHKStN.js +1 -0
  18. package/dist/server/client/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
  19. package/dist/server/client/dist/assets/awk-DMzUqQB5.js +1 -0
  20. package/dist/server/client/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
  21. package/dist/server/client/dist/assets/ayu-light-BA47KaF1.js +1 -0
  22. package/dist/server/client/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
  23. package/dist/server/client/dist/assets/ballerina-BFfxhgS-.js +1 -0
  24. package/dist/server/client/dist/assets/bat-BkioyH1T.js +1 -0
  25. package/dist/server/client/dist/assets/beancount-k_qm7-4y.js +1 -0
  26. package/dist/server/client/dist/assets/berry-uYugtg8r.js +1 -0
  27. package/dist/server/client/dist/assets/bibtex-CHM0blh-.js +1 -0
  28. package/dist/server/client/dist/assets/bicep-Bmn6On1c.js +1 -0
  29. package/dist/server/client/dist/assets/bird2-DPOp833l.js +1 -0
  30. package/dist/server/client/dist/assets/blade-D4QpJJKB.js +1 -0
  31. package/dist/server/client/dist/assets/bsl-BO_Y6i37.js +1 -0
  32. package/dist/server/client/dist/assets/c-BIGW1oBm.js +1 -0
  33. package/dist/server/client/dist/assets/c3-eo99z4R2.js +1 -0
  34. package/dist/server/client/dist/assets/cadence-Bv_4Rxtq.js +1 -0
  35. package/dist/server/client/dist/assets/cairo-KRGpt6FW.js +1 -0
  36. package/dist/server/client/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  37. package/dist/server/client/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  38. package/dist/server/client/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  39. package/dist/server/client/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  40. package/dist/server/client/dist/assets/clarity-D53aC0YG.js +1 -0
  41. package/dist/server/client/dist/assets/clojure-P80f7IUj.js +1 -0
  42. package/dist/server/client/dist/assets/cmake-D1j8_8rp.js +1 -0
  43. package/dist/server/client/dist/assets/cobol-nwyudZeR.js +1 -0
  44. package/dist/server/client/dist/assets/codeowners-Bp6g37R7.js +1 -0
  45. package/dist/server/client/dist/assets/codeql-DsOJ9woJ.js +1 -0
  46. package/dist/server/client/dist/assets/coffee-Ch7k5sss.js +1 -0
  47. package/dist/server/client/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
  48. package/dist/server/client/dist/assets/coq-DkFqJrB1.js +1 -0
  49. package/dist/server/client/dist/assets/cpp-CofmeUqb.js +1 -0
  50. package/dist/server/client/dist/assets/crystal-tKQVLTB8.js +1 -0
  51. package/dist/server/client/dist/assets/csharp-COcwbKMJ.js +1 -0
  52. package/dist/server/client/dist/assets/css-DPfMkruS.js +1 -0
  53. package/dist/server/client/dist/assets/csv-fuZLfV_i.js +1 -0
  54. package/dist/server/client/dist/assets/cue-D82EKSYY.js +1 -0
  55. package/dist/server/client/dist/assets/cypher-COkxafJQ.js +1 -0
  56. package/dist/server/client/dist/assets/d-85-TOEBH.js +1 -0
  57. package/dist/server/client/dist/assets/dark-plus-C3mMm8J8.js +1 -0
  58. package/dist/server/client/dist/assets/dart-CF10PKvl.js +1 -0
  59. package/dist/server/client/dist/assets/dax-CEL-wOlO.js +1 -0
  60. package/dist/server/client/dist/assets/desktop-BmXAJ9_W.js +1 -0
  61. package/dist/server/client/dist/assets/diff-D97Zzqfu.js +1 -0
  62. package/dist/server/client/dist/assets/docker-BcOcwvcX.js +1 -0
  63. package/dist/server/client/dist/assets/dotenv-Da5cRb03.js +1 -0
  64. package/dist/server/client/dist/assets/dracula-BzJJZx-M.js +1 -0
  65. package/dist/server/client/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
  66. package/dist/server/client/dist/assets/dream-maker-BtqSS_iP.js +1 -0
  67. package/dist/server/client/dist/assets/edge-BkV0erSs.js +1 -0
  68. package/dist/server/client/dist/assets/elixir-CDX3lj18.js +1 -0
  69. package/dist/server/client/dist/assets/elm-DbKCFpqz.js +1 -0
  70. package/dist/server/client/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
  71. package/dist/server/client/dist/assets/erb-B12qg9BL.js +1 -0
  72. package/dist/server/client/dist/assets/erlang-DsQrWhSR.js +1 -0
  73. package/dist/server/client/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
  74. package/dist/server/client/dist/assets/everforest-light-C8M2exoo.js +1 -0
  75. package/dist/server/client/dist/assets/fennel-BYunw83y.js +1 -0
  76. package/dist/server/client/dist/assets/fish-BvzEVeQv.js +1 -0
  77. package/dist/server/client/dist/assets/fluent-C4IJs8-o.js +1 -0
  78. package/dist/server/client/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  79. package/dist/server/client/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
  80. package/dist/server/client/dist/assets/fsharp-CXgrBDvD.js +1 -0
  81. package/dist/server/client/dist/assets/gdresource-BOOCDP_w.js +1 -0
  82. package/dist/server/client/dist/assets/gdscript-C5YyOfLZ.js +1 -0
  83. package/dist/server/client/dist/assets/gdshader-DkwncUOv.js +1 -0
  84. package/dist/server/client/dist/assets/genie-D0YGMca9.js +1 -0
  85. package/dist/server/client/dist/assets/gherkin-DyxjwDmM.js +1 -0
  86. package/dist/server/client/dist/assets/git-commit-F4YmCXRG.js +1 -0
  87. package/dist/server/client/dist/assets/git-rebase-r7XF79zn.js +1 -0
  88. package/dist/server/client/dist/assets/github-dark-DHJKELXO.js +1 -0
  89. package/dist/server/client/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
  90. package/dist/server/client/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  91. package/dist/server/client/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  92. package/dist/server/client/dist/assets/github-light-DAi9KRSo.js +1 -0
  93. package/dist/server/client/dist/assets/github-light-default-D7oLnXFd.js +1 -0
  94. package/dist/server/client/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  95. package/dist/server/client/dist/assets/gleam-BspZqrRM.js +1 -0
  96. package/dist/server/client/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
  97. package/dist/server/client/dist/assets/glimmer-ts-U6CK756n.js +1 -0
  98. package/dist/server/client/dist/assets/glsl-DplSGwfg.js +1 -0
  99. package/dist/server/client/dist/assets/gn-n2N0HUVH.js +1 -0
  100. package/dist/server/client/dist/assets/gnuplot-DdkO51Og.js +1 -0
  101. package/dist/server/client/dist/assets/go-CxLEBnE3.js +1 -0
  102. package/dist/server/client/dist/assets/graphql-ChdNCCLP.js +1 -0
  103. package/dist/server/client/dist/assets/groovy-gcz8RCvz.js +1 -0
  104. package/dist/server/client/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  105. package/dist/server/client/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  106. package/dist/server/client/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  107. package/dist/server/client/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  108. package/dist/server/client/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  109. package/dist/server/client/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  110. package/dist/server/client/dist/assets/hack-CaT9iCJl.js +1 -0
  111. package/dist/server/client/dist/assets/haml-B8DHNrY2.js +1 -0
  112. package/dist/server/client/dist/assets/handlebars-BL8al0AC.js +1 -0
  113. package/dist/server/client/dist/assets/haskell-Df6bDoY_.js +1 -0
  114. package/dist/server/client/dist/assets/haxe-CzTSHFRz.js +1 -0
  115. package/dist/server/client/dist/assets/hcl-BWvSN4gD.js +1 -0
  116. package/dist/server/client/dist/assets/highlighted-body-TPN3WLV5-Dmyr2DoJ.js +1 -0
  117. package/dist/server/client/dist/assets/hjson-D5-asLiD.js +1 -0
  118. package/dist/server/client/dist/assets/hlsl-D3lLCCz7.js +1 -0
  119. package/dist/server/client/dist/assets/horizon-BUw7H-hv.js +1 -0
  120. package/dist/server/client/dist/assets/horizon-bright-Cn-bp-IR.js +1 -0
  121. package/dist/server/client/dist/assets/houston-DnULxvSX.js +1 -0
  122. package/dist/server/client/dist/assets/html-GMplVEZG.js +1 -0
  123. package/dist/server/client/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
  124. package/dist/server/client/dist/assets/http-jrhK8wxY.js +1 -0
  125. package/dist/server/client/dist/assets/hurl-irOxFIW8.js +1 -0
  126. package/dist/server/client/dist/assets/hxml-Bvhsp5Yf.js +1 -0
  127. package/dist/server/client/dist/assets/hy-DFXneXwc.js +1 -0
  128. package/dist/server/client/dist/assets/imba-DGztddWO.js +1 -0
  129. package/dist/server/client/dist/assets/index-BB7507W7.css +1 -0
  130. package/dist/server/client/dist/assets/index-hLQDnL9J.js +694 -0
  131. package/dist/server/client/dist/assets/ini-BEwlwnbL.js +1 -0
  132. package/dist/server/client/dist/assets/java-CylS5w8V.js +1 -0
  133. package/dist/server/client/dist/assets/javascript-wDzz0qaB.js +1 -0
  134. package/dist/server/client/dist/assets/jinja-4LBKfQ-Z.js +1 -0
  135. package/dist/server/client/dist/assets/jison-wvAkD_A8.js +1 -0
  136. package/dist/server/client/dist/assets/json-Cp-IABpG.js +1 -0
  137. package/dist/server/client/dist/assets/json5-C9tS-k6U.js +1 -0
  138. package/dist/server/client/dist/assets/jsonc-Des-eS-w.js +1 -0
  139. package/dist/server/client/dist/assets/jsonl-DcaNXYhu.js +1 -0
  140. package/dist/server/client/dist/assets/jsonnet-DFQXde-d.js +1 -0
  141. package/dist/server/client/dist/assets/jssm-C2t-YnRu.js +1 -0
  142. package/dist/server/client/dist/assets/jsx-g9-lgVsj.js +1 -0
  143. package/dist/server/client/dist/assets/julia-CxzCAyBv.js +1 -0
  144. package/dist/server/client/dist/assets/just-Cw27pwNe.js +1 -0
  145. package/dist/server/client/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  146. package/dist/server/client/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  147. package/dist/server/client/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
  148. package/dist/server/client/dist/assets/kdl-DV7GczEv.js +1 -0
  149. package/dist/server/client/dist/assets/kotlin-BdnUsdx6.js +1 -0
  150. package/dist/server/client/dist/assets/kusto-DZf3V79B.js +1 -0
  151. package/dist/server/client/dist/assets/laserwave-DUszq2jm.js +1 -0
  152. package/dist/server/client/dist/assets/latex-CWtU0Tv5.js +1 -0
  153. package/dist/server/client/dist/assets/lean-BZvkOJ9d.js +1 -0
  154. package/dist/server/client/dist/assets/less-B1dDrJ26.js +1 -0
  155. package/dist/server/client/dist/assets/light-plus-B7mTdjB0.js +1 -0
  156. package/dist/server/client/dist/assets/liquid-DYVedYrR.js +1 -0
  157. package/dist/server/client/dist/assets/llvm-DjAJT7YJ.js +1 -0
  158. package/dist/server/client/dist/assets/log-2UxHyX5q.js +1 -0
  159. package/dist/server/client/dist/assets/logo-BtOb2qkB.js +1 -0
  160. package/dist/server/client/dist/assets/lua-BaeVxFsk.js +1 -0
  161. package/dist/server/client/dist/assets/luau-C-HG3fhB.js +1 -0
  162. package/dist/server/client/dist/assets/make-CHLpvVh8.js +1 -0
  163. package/dist/server/client/dist/assets/markdown-Cvjx9yec.js +1 -0
  164. package/dist/server/client/dist/assets/marko-CnJfTvn9.js +1 -0
  165. package/dist/server/client/dist/assets/material-theme-D5KoaKCx.js +1 -0
  166. package/dist/server/client/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
  167. package/dist/server/client/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  168. package/dist/server/client/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
  169. package/dist/server/client/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  170. package/dist/server/client/dist/assets/matlab-D7o27uSR.js +1 -0
  171. package/dist/server/client/dist/assets/mdc-BMNejdWA.js +1 -0
  172. package/dist/server/client/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  173. package/dist/server/client/dist/assets/mermaid-mWjccvbQ.js +1 -0
  174. package/dist/server/client/dist/assets/min-dark-CafNBF8u.js +1 -0
  175. package/dist/server/client/dist/assets/min-light-CTRr51gU.js +1 -0
  176. package/dist/server/client/dist/assets/mipsasm-CKIfxQSi.js +1 -0
  177. package/dist/server/client/dist/assets/mojo-rZm6bMo-.js +1 -0
  178. package/dist/server/client/dist/assets/monokai-D4h5O-jR.js +1 -0
  179. package/dist/server/client/dist/assets/moonbit-_H4v1dQx.js +1 -0
  180. package/dist/server/client/dist/assets/move-IF9eRakj.js +1 -0
  181. package/dist/server/client/dist/assets/narrat-DRg8JJMk.js +1 -0
  182. package/dist/server/client/dist/assets/nextflow-Zz6hmt5N.js +1 -0
  183. package/dist/server/client/dist/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  184. package/dist/server/client/dist/assets/nginx-BpAMiNFr.js +1 -0
  185. package/dist/server/client/dist/assets/night-owl-C39BiMTA.js +1 -0
  186. package/dist/server/client/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
  187. package/dist/server/client/dist/assets/nim-CVrawwO9.js +1 -0
  188. package/dist/server/client/dist/assets/nix-CwoSXNpI.js +1 -0
  189. package/dist/server/client/dist/assets/nord-Ddv68eIx.js +1 -0
  190. package/dist/server/client/dist/assets/nushell-Cz2AlsmD.js +1 -0
  191. package/dist/server/client/dist/assets/objective-c-DXmwc3jG.js +1 -0
  192. package/dist/server/client/dist/assets/objective-cpp-CLxacb5B.js +1 -0
  193. package/dist/server/client/dist/assets/ocaml-C0hk2d4L.js +1 -0
  194. package/dist/server/client/dist/assets/odin-BBf5iR-q.js +1 -0
  195. package/dist/server/client/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  196. package/dist/server/client/dist/assets/one-light-C3Wv6jpd.js +1 -0
  197. package/dist/server/client/dist/assets/openscad-C4EeE6gA.js +1 -0
  198. package/dist/server/client/dist/assets/pascal-D93ZcfNL.js +1 -0
  199. package/dist/server/client/dist/assets/perl-C0TMdlhV.js +1 -0
  200. package/dist/server/client/dist/assets/php-Dhbhpdrm.js +1 -0
  201. package/dist/server/client/dist/assets/pkl-u5AG7uiY.js +1 -0
  202. package/dist/server/client/dist/assets/plastic-3e1v2bzS.js +1 -0
  203. package/dist/server/client/dist/assets/plsql-ChMvpjG-.js +1 -0
  204. package/dist/server/client/dist/assets/po-BTJTHyun.js +1 -0
  205. package/dist/server/client/dist/assets/poimandres-CS3Unz2-.js +1 -0
  206. package/dist/server/client/dist/assets/polar-C0HS_06l.js +1 -0
  207. package/dist/server/client/dist/assets/postcss-CXtECtnM.js +1 -0
  208. package/dist/server/client/dist/assets/powerquery-CEu0bR-o.js +1 -0
  209. package/dist/server/client/dist/assets/powershell-Dpen1YoG.js +1 -0
  210. package/dist/server/client/dist/assets/prisma-Dd19v3D-.js +1 -0
  211. package/dist/server/client/dist/assets/prolog-CbFg5uaA.js +1 -0
  212. package/dist/server/client/dist/assets/proto-C7zT0LnQ.js +1 -0
  213. package/dist/server/client/dist/assets/pug-CGlum2m_.js +1 -0
  214. package/dist/server/client/dist/assets/puppet-BMWR74SV.js +1 -0
  215. package/dist/server/client/dist/assets/purescript-CklMAg4u.js +1 -0
  216. package/dist/server/client/dist/assets/python-B6aJPvgy.js +1 -0
  217. package/dist/server/client/dist/assets/qml-3beO22l8.js +1 -0
  218. package/dist/server/client/dist/assets/qmldir-C8lEn-DE.js +1 -0
  219. package/dist/server/client/dist/assets/qss-IeuSbFQv.js +1 -0
  220. package/dist/server/client/dist/assets/r-Dspwwk_N.js +1 -0
  221. package/dist/server/client/dist/assets/racket-BqYA7rlc.js +1 -0
  222. package/dist/server/client/dist/assets/raku-DXvB9xmW.js +1 -0
  223. package/dist/server/client/dist/assets/razor-Uh8Bk_45.js +1 -0
  224. package/dist/server/client/dist/assets/red-bN70gL4F.js +1 -0
  225. package/dist/server/client/dist/assets/reg-C-SQnVFl.js +1 -0
  226. package/dist/server/client/dist/assets/regexp-CDVJQ6XC.js +1 -0
  227. package/dist/server/client/dist/assets/rel-C3B-1QV4.js +1 -0
  228. package/dist/server/client/dist/assets/riscv-BM1_JUlF.js +1 -0
  229. package/dist/server/client/dist/assets/ron-D8l8udqQ.js +1 -0
  230. package/dist/server/client/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  231. package/dist/server/client/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  232. package/dist/server/client/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
  233. package/dist/server/client/dist/assets/rosmsg-BJDFO7_C.js +1 -0
  234. package/dist/server/client/dist/assets/rst-BrH8l1NY.js +1 -0
  235. package/dist/server/client/dist/assets/ruby-Dw2BHqvy.js +1 -0
  236. package/dist/server/client/dist/assets/rust-B1yitclQ.js +1 -0
  237. package/dist/server/client/dist/assets/sas-cz2c8ADy.js +1 -0
  238. package/dist/server/client/dist/assets/sass-Cj5Yp3dK.js +1 -0
  239. package/dist/server/client/dist/assets/scala-C151Ov-r.js +1 -0
  240. package/dist/server/client/dist/assets/scheme-C98Dy4si.js +1 -0
  241. package/dist/server/client/dist/assets/scss-OYdSNvt2.js +1 -0
  242. package/dist/server/client/dist/assets/sdbl-DVxCFoDh.js +1 -0
  243. package/dist/server/client/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
  244. package/dist/server/client/dist/assets/shellscript-Yzrsuije.js +1 -0
  245. package/dist/server/client/dist/assets/shellsession-BADoaaVG.js +1 -0
  246. package/dist/server/client/dist/assets/slack-dark-BthQWCQV.js +1 -0
  247. package/dist/server/client/dist/assets/slack-ochin-DqwNpetd.js +1 -0
  248. package/dist/server/client/dist/assets/smalltalk-BERRCDM3.js +1 -0
  249. package/dist/server/client/dist/assets/snazzy-light-Bw305WKR.js +1 -0
  250. package/dist/server/client/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
  251. package/dist/server/client/dist/assets/solarized-light-L9t79GZl.js +1 -0
  252. package/dist/server/client/dist/assets/solidity-rGO070M0.js +1 -0
  253. package/dist/server/client/dist/assets/soy-Brmx7dQM.js +1 -0
  254. package/dist/server/client/dist/assets/sparql-rVzFXLq3.js +1 -0
  255. package/dist/server/client/dist/assets/splunk-BtCnVYZw.js +1 -0
  256. package/dist/server/client/dist/assets/sql-BLtJtn59.js +1 -0
  257. package/dist/server/client/dist/assets/ssh-config-_ykCGR6B.js +1 -0
  258. package/dist/server/client/dist/assets/stata-BH5u7GGu.js +1 -0
  259. package/dist/server/client/dist/assets/stylus-BEDo0Tqx.js +1 -0
  260. package/dist/server/client/dist/assets/surrealql-Bq5Q-fJD.js +1 -0
  261. package/dist/server/client/dist/assets/svelte-C_ipcX3V.js +1 -0
  262. package/dist/server/client/dist/assets/swift-D82vCrfD.js +1 -0
  263. package/dist/server/client/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
  264. package/dist/server/client/dist/assets/system-verilog-CnnmHF94.js +1 -0
  265. package/dist/server/client/dist/assets/systemd-4A_iFExJ.js +1 -0
  266. package/dist/server/client/dist/assets/talonscript-CkByrt1z.js +1 -0
  267. package/dist/server/client/dist/assets/tasl-QIJgUcNo.js +1 -0
  268. package/dist/server/client/dist/assets/tcl-dwOrl1Do.js +1 -0
  269. package/dist/server/client/dist/assets/templ-P3uqSqPl.js +1 -0
  270. package/dist/server/client/dist/assets/terraform-BETggiCN.js +1 -0
  271. package/dist/server/client/dist/assets/tex-idrVyKtj.js +1 -0
  272. package/dist/server/client/dist/assets/tokyo-night-hegEt444.js +1 -0
  273. package/dist/server/client/dist/assets/toml-vGWfd6FD.js +1 -0
  274. package/dist/server/client/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
  275. package/dist/server/client/dist/assets/tsv-B_m7g4N7.js +1 -0
  276. package/dist/server/client/dist/assets/tsx-COt5Ahok.js +1 -0
  277. package/dist/server/client/dist/assets/turtle-BsS91CYL.js +1 -0
  278. package/dist/server/client/dist/assets/twig-DNn4PbVi.js +1 -0
  279. package/dist/server/client/dist/assets/typescript-BPQ3VLAy.js +1 -0
  280. package/dist/server/client/dist/assets/typespec-BGHnOYBU.js +1 -0
  281. package/dist/server/client/dist/assets/typst-DHCkPAjA.js +1 -0
  282. package/dist/server/client/dist/assets/v-BcVCzyr7.js +1 -0
  283. package/dist/server/client/dist/assets/vala-CsfeWuGM.js +1 -0
  284. package/dist/server/client/dist/assets/vb-D17OF-Vu.js +1 -0
  285. package/dist/server/client/dist/assets/verilog-BQ8w6xss.js +1 -0
  286. package/dist/server/client/dist/assets/vesper-DU1UobuO.js +1 -0
  287. package/dist/server/client/dist/assets/vhdl-CeAyd5Ju.js +1 -0
  288. package/dist/server/client/dist/assets/viml-CJc9bBzg.js +1 -0
  289. package/dist/server/client/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
  290. package/dist/server/client/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
  291. package/dist/server/client/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
  292. package/dist/server/client/dist/assets/vue-DN_0RTcg.js +1 -0
  293. package/dist/server/client/dist/assets/vue-html-AaS7Mt5G.js +1 -0
  294. package/dist/server/client/dist/assets/vue-vine-CQOfvN7w.js +1 -0
  295. package/dist/server/client/dist/assets/vyper-CDx5xZoG.js +1 -0
  296. package/dist/server/client/dist/assets/wasm-CG6Dc4jp.js +1 -0
  297. package/dist/server/client/dist/assets/wasm-MzD3tlZU.js +1 -0
  298. package/dist/server/client/dist/assets/wenyan-BV7otONQ.js +1 -0
  299. package/dist/server/client/dist/assets/wgsl-Dx-B1_4e.js +1 -0
  300. package/dist/server/client/dist/assets/wikitext-BhOHFoWU.js +1 -0
  301. package/dist/server/client/dist/assets/wit-5i3qLPDT.js +1 -0
  302. package/dist/server/client/dist/assets/wolfram-lXgVvXCa.js +1 -0
  303. package/dist/server/client/dist/assets/xml-sdJ4AIDG.js +1 -0
  304. package/dist/server/client/dist/assets/xsl-CtQFsRM5.js +1 -0
  305. package/dist/server/client/dist/assets/yaml-Buea-lGh.js +1 -0
  306. package/dist/server/client/dist/assets/zenscript-DVFEvuxE.js +1 -0
  307. package/dist/server/client/dist/assets/zig-VOosw3JB.js +1 -0
  308. package/dist/server/client/dist/favicon.ico +0 -0
  309. package/dist/server/client/dist/index.html +17 -0
  310. package/dist/server/client/dist/logo.png +0 -0
  311. package/dist/server/server/adapters/hermes-worker.d.ts +37 -0
  312. package/dist/server/server/adapters/hermes-worker.js +525 -0
  313. package/dist/server/server/adapters/types.d.ts +39 -0
  314. package/dist/server/server/adapters/types.js +1 -0
  315. package/dist/server/server/adapters/worker-protocol.d.ts +141 -0
  316. package/dist/server/server/adapters/worker-protocol.js +1 -0
  317. package/dist/server/server/agent-settings.d.ts +12 -0
  318. package/dist/server/server/agent-settings.js +56 -0
  319. package/dist/server/server/app.d.ts +5 -0
  320. package/dist/server/server/app.js +41 -0
  321. package/dist/server/server/db/index.d.ts +2 -0
  322. package/dist/server/server/db/index.js +14 -0
  323. package/dist/server/server/db/queries.d.ts +22 -0
  324. package/dist/server/server/db/queries.js +116 -0
  325. package/dist/server/server/db/schema.sql +16 -0
  326. package/dist/server/server/errors.d.ts +3 -0
  327. package/dist/server/server/errors.js +12 -0
  328. package/dist/server/server/events.d.ts +7 -0
  329. package/dist/server/server/events.js +50 -0
  330. package/dist/server/server/frontend.d.ts +4 -0
  331. package/dist/server/server/frontend.js +32 -0
  332. package/dist/server/server/index.d.ts +2 -0
  333. package/dist/server/server/index.js +63 -0
  334. package/dist/server/server/live-chat.d.ts +17 -0
  335. package/dist/server/server/live-chat.js +217 -0
  336. package/dist/server/server/paths.d.ts +7 -0
  337. package/dist/server/server/paths.js +39 -0
  338. package/dist/server/server/prompts/task-agent.d.ts +1 -0
  339. package/dist/server/server/prompts/task-agent.js +26 -0
  340. package/dist/server/server/routes/agent.d.ts +4 -0
  341. package/dist/server/server/routes/agent.js +94 -0
  342. package/dist/server/server/routes/chat.d.ts +1 -0
  343. package/dist/server/server/routes/chat.js +177 -0
  344. package/dist/server/server/routes/cron.d.ts +4 -0
  345. package/dist/server/server/routes/cron.js +109 -0
  346. package/dist/server/server/routes/files.d.ts +1 -0
  347. package/dist/server/server/routes/files.js +543 -0
  348. package/dist/server/server/routes/skills.d.ts +1 -0
  349. package/dist/server/server/routes/skills.js +13 -0
  350. package/dist/server/server/routes/tasks.d.ts +1 -0
  351. package/dist/server/server/routes/tasks.js +107 -0
  352. package/dist/server/server/skills/catalog.d.ts +21 -0
  353. package/dist/server/server/skills/catalog.js +160 -0
  354. package/dist/server/server/workers/hermes_cron.py +241 -0
  355. package/dist/server/server/workers/hermes_sessions.py +264 -0
  356. package/dist/server/server/workers/hermes_worker.py +1270 -0
  357. package/dist/server/server/workers/hermes_worker_utils.py +39 -0
  358. package/dist/server/shared/types.d.ts +211 -0
  359. package/dist/server/shared/types.js +2 -0
  360. package/package.json +74 -0
  361. package/skills/lead-generation/SKILL.md +41 -0
@@ -0,0 +1,109 @@
1
+ import { Router } from 'express';
2
+ import { getTask } from '../db/queries.js';
3
+ import { toErrorMessage } from '../errors.js';
4
+ function originTaskId(job) {
5
+ const origin = job.origin;
6
+ if (!origin || origin.platform !== 'minions')
7
+ return null;
8
+ return typeof origin.chat_id === 'string' && origin.chat_id.trim() ? origin.chat_id : null;
9
+ }
10
+ function attachLinkedTaskId(job) {
11
+ const taskId = originTaskId(job);
12
+ return { ...job, linkedTaskIds: taskId ? [taskId] : [] };
13
+ }
14
+ export function createCronRouter(adapter) {
15
+ const router = Router();
16
+ router.get('/jobs', async (req, res) => {
17
+ try {
18
+ const includeDisabled = req.query.includeDisabled === 'true';
19
+ const jobs = await adapter.listCronJobs(includeDisabled);
20
+ res.json({ jobs: jobs.map(attachLinkedTaskId) });
21
+ }
22
+ catch (error) {
23
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
24
+ }
25
+ });
26
+ router.get('/jobs/:jobId', async (req, res) => {
27
+ try {
28
+ const job = await adapter.getCronJob(req.params.jobId);
29
+ if (!job)
30
+ return res.status(404).json({ error: 'Cron job not found' });
31
+ res.json({ job: attachLinkedTaskId(job) });
32
+ }
33
+ catch (error) {
34
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
35
+ }
36
+ });
37
+ router.get('/jobs/:jobId/runs', async (req, res) => {
38
+ try {
39
+ const rawLimit = Array.isArray(req.query.limit) ? req.query.limit[0] : req.query.limit;
40
+ const limit = rawLimit ? Number.parseInt(String(rawLimit), 10) : 20;
41
+ const runs = await adapter.getCronRuns(req.params.jobId, Number.isFinite(limit) ? limit : 20);
42
+ res.json({ runs });
43
+ }
44
+ catch (error) {
45
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
46
+ }
47
+ });
48
+ router.get('/jobs/:jobId/runs/:runId/content', async (req, res) => {
49
+ try {
50
+ const content = await adapter.getCronRunContent(req.params.jobId, req.params.runId);
51
+ res.json({ content });
52
+ }
53
+ catch (error) {
54
+ const status = error.code === 'not_found' ? 404 : 503;
55
+ res.status(status).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
56
+ }
57
+ });
58
+ async function jobActionHandler(res, jobId, action) {
59
+ try {
60
+ const job = await action(jobId);
61
+ if (!job)
62
+ return res.status(404).json({ error: 'Cron job not found' });
63
+ res.json({ job: attachLinkedTaskId(job) });
64
+ }
65
+ catch (error) {
66
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
67
+ }
68
+ }
69
+ router.post('/jobs/:jobId/pause', (req, res) => {
70
+ const rawReason = req.body?.reason;
71
+ const reason = typeof rawReason === 'string' && rawReason.trim() ? rawReason.trim() : undefined;
72
+ jobActionHandler(res, req.params.jobId, (jobId) => adapter.pauseCronJob(jobId, reason));
73
+ });
74
+ router.post('/jobs/:jobId/resume', (req, res) => {
75
+ jobActionHandler(res, req.params.jobId, (jobId) => adapter.resumeCronJob(jobId));
76
+ });
77
+ router.post('/jobs/:jobId/run', (req, res) => {
78
+ jobActionHandler(res, req.params.jobId, (jobId) => adapter.runCronJob(jobId));
79
+ });
80
+ router.delete('/jobs/:jobId', async (req, res) => {
81
+ try {
82
+ const removed = await adapter.removeCronJob(req.params.jobId);
83
+ if (!removed)
84
+ return res.status(404).json({ error: 'Cron job not found' });
85
+ res.json({ ok: true });
86
+ }
87
+ catch (error) {
88
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
89
+ }
90
+ });
91
+ return router;
92
+ }
93
+ export function createTaskCronRouter(adapter) {
94
+ const router = Router();
95
+ router.get('/:id/cron-jobs', async (req, res) => {
96
+ const task = getTask(req.params.id);
97
+ if (!task)
98
+ return res.status(404).json({ error: 'Task not found' });
99
+ try {
100
+ const jobs = await adapter.listCronJobs(true);
101
+ const linkedJobs = jobs.filter((job) => originTaskId(job) === task.id);
102
+ res.json({ jobs: linkedJobs.map(attachLinkedTaskId) });
103
+ }
104
+ catch (error) {
105
+ res.status(503).json({ error: toErrorMessage(error, 'Hermes cron worker unavailable') });
106
+ }
107
+ });
108
+ return router;
109
+ }
@@ -0,0 +1 @@
1
+ export declare const filesRouter: import("express-serve-static-core").Router;
@@ -0,0 +1,543 @@
1
+ import { constants, mkdirSync } from 'node:fs';
2
+ import { access, copyFile, lstat, mkdir, open, readdir, readFile, rename, rm, rmdir, stat, unlink, writeFile, } from 'node:fs/promises';
3
+ import { homedir, tmpdir } from 'node:os';
4
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
5
+ import { randomUUID } from 'node:crypto';
6
+ import archiver from 'archiver';
7
+ import multer from 'multer';
8
+ import { Router } from 'express';
9
+ import { expandHomePrefix } from '../paths.js';
10
+ import { errorCode, isRecord } from '../errors.js';
11
+ const HOME = resolve(homedir());
12
+ const TEXT_SAMPLE_BYTES = 8192;
13
+ const MAX_TEXT_FILE_SIZE = 10 * 1024 * 1024;
14
+ const MAX_TEXT_FILE_SIZE_DISPLAY = '10 MiB';
15
+ const DEFAULT_FILE_BROWSER_PATH = '~/.minions/workspace';
16
+ const UPLOAD_TMP_DIR = join(tmpdir(), 'minions-uploads');
17
+ mkdirSync(UPLOAD_TMP_DIR, { recursive: true });
18
+ const uploadMiddleware = multer({
19
+ storage: multer.diskStorage({
20
+ destination: UPLOAD_TMP_DIR,
21
+ filename: (_req, file, callback) => {
22
+ callback(null, `${Date.now()}-${randomUUID()}-${basename(file.originalname)}`);
23
+ },
24
+ }),
25
+ }).array('files');
26
+ class FileRouteError extends Error {
27
+ status;
28
+ code;
29
+ constructor(status, message, code) {
30
+ super(message);
31
+ this.status = status;
32
+ this.code = code;
33
+ }
34
+ }
35
+ export const filesRouter = Router();
36
+ filesRouter.get('/list', async (req, res) => {
37
+ try {
38
+ const directoryPath = resolveUserPath(req.query.path, DEFAULT_FILE_BROWSER_PATH);
39
+ const directoryStats = await stat(directoryPath);
40
+ if (!directoryStats.isDirectory()) {
41
+ throw new FileRouteError(400, 'Path is not a directory', 'NOT_DIRECTORY');
42
+ }
43
+ const dirents = await readdir(directoryPath, { withFileTypes: true });
44
+ const entries = await Promise.all(dirents.map((dirent) => entryFromDirent(directoryPath, dirent)));
45
+ entries.sort(compareEntries);
46
+ const parentPath = dirname(directoryPath);
47
+ res.json({
48
+ path: directoryPath,
49
+ displayPath: displayPath(directoryPath),
50
+ parentPath: parentPath === directoryPath ? null : parentPath,
51
+ entries,
52
+ });
53
+ }
54
+ catch (error) {
55
+ sendFileError(res, error, 'Failed to list directory');
56
+ }
57
+ });
58
+ filesRouter.get('/read', async (req, res) => {
59
+ try {
60
+ const filePath = resolveRequiredPath(req.query.path);
61
+ const fileStats = await stat(filePath);
62
+ if (fileStats.isDirectory()) {
63
+ throw new FileRouteError(400, 'Cannot open a directory as text', 'IS_DIRECTORY');
64
+ }
65
+ if (!fileStats.isFile()) {
66
+ throw new FileRouteError(400, 'Path is not a regular text file', 'NOT_FILE');
67
+ }
68
+ if (fileStats.size > MAX_TEXT_FILE_SIZE) {
69
+ throw new FileRouteError(413, `File is too large to open as text. Maximum size is ${MAX_TEXT_FILE_SIZE_DISPLAY}.`, 'FILE_TOO_LARGE');
70
+ }
71
+ if (await looksBinary(filePath, fileStats.size)) {
72
+ throw new FileRouteError(415, 'Binary files cannot be opened as text', 'BINARY_FILE');
73
+ }
74
+ const content = await readFile(filePath, 'utf8');
75
+ res.json({
76
+ path: filePath,
77
+ displayPath: displayPath(filePath),
78
+ name: basename(filePath),
79
+ content,
80
+ size: fileStats.size,
81
+ modifiedAt: fileStats.mtimeMs,
82
+ encoding: 'utf8',
83
+ fileType: 'text',
84
+ });
85
+ }
86
+ catch (error) {
87
+ sendFileError(res, error, 'Failed to read file');
88
+ }
89
+ });
90
+ filesRouter.get('/download', async (req, res) => {
91
+ try {
92
+ const targetPath = resolveRequiredPath(req.query.path);
93
+ const targetStats = await stat(targetPath);
94
+ const targetName = basename(targetPath) || 'download';
95
+ if (targetStats.isDirectory()) {
96
+ res.attachment(`${targetName}.zip`);
97
+ res.type('application/zip');
98
+ const archive = archiver('zip', { zlib: { level: 6 } });
99
+ let handledArchiveError = false;
100
+ const handleArchiveError = (archiveError) => {
101
+ if (handledArchiveError)
102
+ return;
103
+ handledArchiveError = true;
104
+ sendStreamingFileError(res, archiveError, 'Failed to download folder');
105
+ };
106
+ archive.on('error', handleArchiveError);
107
+ archive.pipe(res);
108
+ archive.directory(targetPath, targetName);
109
+ archive.finalize().catch(handleArchiveError);
110
+ return;
111
+ }
112
+ if (!targetStats.isFile()) {
113
+ throw new FileRouteError(400, 'Path is not a downloadable file or folder', 'NOT_DOWNLOADABLE');
114
+ }
115
+ res.download(targetPath, targetName, (downloadError) => {
116
+ if (downloadError)
117
+ sendStreamingFileError(res, downloadError, 'Failed to download file');
118
+ });
119
+ }
120
+ catch (error) {
121
+ sendFileError(res, error, 'Failed to download file entry');
122
+ }
123
+ });
124
+ filesRouter.put('/write', async (req, res) => {
125
+ try {
126
+ const body = parseWriteRequest(req.body);
127
+ const filePath = resolveUserPath(body.path);
128
+ const currentStats = await stat(filePath);
129
+ if (currentStats.isDirectory()) {
130
+ throw new FileRouteError(400, 'Cannot write text to a directory', 'IS_DIRECTORY');
131
+ }
132
+ if (!currentStats.isFile()) {
133
+ throw new FileRouteError(400, 'Path is not a regular file', 'NOT_FILE');
134
+ }
135
+ if (typeof body.expectedModifiedAt === 'number'
136
+ && !body.overwrite
137
+ && Math.abs(currentStats.mtimeMs - body.expectedModifiedAt) > 1) {
138
+ throw new FileRouteError(409, 'File changed on disk', 'FILE_CHANGED');
139
+ }
140
+ await writeFile(filePath, body.content, 'utf8');
141
+ const nextStats = await stat(filePath);
142
+ res.json({
143
+ path: filePath,
144
+ displayPath: displayPath(filePath),
145
+ size: nextStats.size,
146
+ modifiedAt: nextStats.mtimeMs,
147
+ });
148
+ }
149
+ catch (error) {
150
+ sendFileError(res, error, 'Failed to write file');
151
+ }
152
+ });
153
+ filesRouter.post('/create', async (req, res) => {
154
+ try {
155
+ const body = parseCreateRequest(req.body);
156
+ const parentPath = resolveUserPath(body.parentPath);
157
+ const name = validateFileName(body.name);
158
+ const targetPath = join(parentPath, name);
159
+ if (body.type === 'directory') {
160
+ await mkdir(targetPath);
161
+ }
162
+ else {
163
+ await writeFile(targetPath, body.content ?? '', { encoding: 'utf8', flag: 'wx' });
164
+ }
165
+ res.status(201).json({ entry: await entryFromPath(targetPath) });
166
+ }
167
+ catch (error) {
168
+ sendFileError(res, error, 'Failed to create file entry');
169
+ }
170
+ });
171
+ filesRouter.post('/upload', (req, res) => {
172
+ uploadMiddleware(req, res, (error) => {
173
+ if (error) {
174
+ sendFileError(res, error, 'Failed to upload files');
175
+ return;
176
+ }
177
+ void handleUploadRequest(req, res);
178
+ });
179
+ });
180
+ filesRouter.patch('/rename', async (req, res) => {
181
+ try {
182
+ const body = parseRenameRequest(req.body);
183
+ const sourcePath = resolveUserPath(body.path);
184
+ const newName = validateFileName(body.newName);
185
+ const targetPath = join(dirname(sourcePath), newName);
186
+ if (await canAccess(targetPath, constants.F_OK)) {
187
+ throw new FileRouteError(409, 'Target already exists', 'EEXIST');
188
+ }
189
+ await rename(sourcePath, targetPath);
190
+ res.json({ entry: await entryFromPath(targetPath) });
191
+ }
192
+ catch (error) {
193
+ sendFileError(res, error, 'Failed to rename file entry');
194
+ }
195
+ });
196
+ filesRouter.delete('/', async (req, res) => {
197
+ try {
198
+ const body = parseDeleteRequest(req.body);
199
+ const targetPath = resolveUserPath(body.path);
200
+ const targetStats = await lstat(targetPath);
201
+ if (targetStats.isDirectory() && !targetStats.isSymbolicLink()) {
202
+ if (body.recursive) {
203
+ await rm(targetPath, { recursive: true, force: false });
204
+ }
205
+ else {
206
+ await rmdir(targetPath);
207
+ }
208
+ }
209
+ else {
210
+ await unlink(targetPath);
211
+ }
212
+ res.json({ ok: true });
213
+ }
214
+ catch (error) {
215
+ sendFileError(res, error, 'Failed to delete file entry');
216
+ }
217
+ });
218
+ async function handleUploadRequest(req, res) {
219
+ const uploadedFiles = Array.isArray(req.files) ? req.files : [];
220
+ try {
221
+ if (uploadedFiles.length === 0) {
222
+ throw new FileRouteError(400, 'At least one file is required', 'BAD_REQUEST');
223
+ }
224
+ const { targetPath, relativePaths } = parseUploadRequest(req.body, uploadedFiles.length);
225
+ const targetDirectory = resolveUserPath(targetPath);
226
+ const directoryStats = await stat(targetDirectory);
227
+ if (!directoryStats.isDirectory()) {
228
+ throw new FileRouteError(400, 'Upload target is not a directory', 'NOT_DIRECTORY');
229
+ }
230
+ const uploadedRootPaths = new Set();
231
+ for (const [index, file] of uploadedFiles.entries()) {
232
+ const segments = sanitizeUploadRelativePath(relativePaths[index] ?? file.originalname);
233
+ const destinationPath = join(targetDirectory, ...segments);
234
+ if (!isSameOrChildPath(targetDirectory, destinationPath)) {
235
+ throw new FileRouteError(400, 'Upload path cannot escape the target directory', 'BAD_REQUEST');
236
+ }
237
+ await assertWritableUploadTarget(destinationPath);
238
+ await mkdir(dirname(destinationPath), { recursive: true });
239
+ try {
240
+ await rename(file.path, destinationPath);
241
+ }
242
+ catch {
243
+ await copyFile(file.path, destinationPath);
244
+ }
245
+ uploadedRootPaths.add(join(targetDirectory, segments[0]));
246
+ }
247
+ const entries = await Promise.all([...uploadedRootPaths].sort((a, b) => a.localeCompare(b)).map((entryPath) => entryFromPath(entryPath)));
248
+ res.status(201).json({ uploaded: uploadedFiles.length, entries });
249
+ }
250
+ catch (error) {
251
+ sendFileError(res, error, 'Failed to upload files');
252
+ }
253
+ finally {
254
+ await Promise.all(uploadedFiles.map((file) => unlink(file.path).catch(() => undefined)));
255
+ }
256
+ }
257
+ function parseWriteRequest(value) {
258
+ if (!isRecord(value))
259
+ throw new FileRouteError(400, 'Request body is required', 'BAD_REQUEST');
260
+ if (typeof value.path !== 'string')
261
+ throw new FileRouteError(400, 'Path is required', 'BAD_REQUEST');
262
+ if (typeof value.content !== 'string')
263
+ throw new FileRouteError(400, 'Content is required', 'BAD_REQUEST');
264
+ assertTextContentSize(value.content);
265
+ return {
266
+ path: value.path,
267
+ content: value.content,
268
+ expectedModifiedAt: typeof value.expectedModifiedAt === 'number' ? value.expectedModifiedAt : undefined,
269
+ overwrite: value.overwrite === true,
270
+ };
271
+ }
272
+ function parseCreateRequest(value) {
273
+ if (!isRecord(value))
274
+ throw new FileRouteError(400, 'Request body is required', 'BAD_REQUEST');
275
+ if (typeof value.parentPath !== 'string')
276
+ throw new FileRouteError(400, 'Parent path is required', 'BAD_REQUEST');
277
+ if (typeof value.name !== 'string')
278
+ throw new FileRouteError(400, 'Name is required', 'BAD_REQUEST');
279
+ if (value.type !== 'file' && value.type !== 'directory') {
280
+ throw new FileRouteError(400, 'Type must be file or directory', 'BAD_REQUEST');
281
+ }
282
+ let content;
283
+ if (typeof value.content === 'string') {
284
+ assertTextContentSize(value.content);
285
+ content = value.content;
286
+ }
287
+ else if (value.content !== undefined) {
288
+ throw new FileRouteError(400, 'Content must be a string', 'BAD_REQUEST');
289
+ }
290
+ return {
291
+ parentPath: value.parentPath,
292
+ name: value.name,
293
+ type: value.type,
294
+ content,
295
+ };
296
+ }
297
+ function assertTextContentSize(content) {
298
+ if (Buffer.byteLength(content, 'utf8') <= MAX_TEXT_FILE_SIZE)
299
+ return;
300
+ throw new FileRouteError(413, `Text file content cannot exceed ${MAX_TEXT_FILE_SIZE_DISPLAY}.`, 'FILE_TOO_LARGE');
301
+ }
302
+ function parseUploadRequest(value, fileCount) {
303
+ if (!isRecord(value))
304
+ throw new FileRouteError(400, 'Request body is required', 'BAD_REQUEST');
305
+ if (typeof value.targetPath !== 'string') {
306
+ throw new FileRouteError(400, 'Upload target path is required', 'BAD_REQUEST');
307
+ }
308
+ const relativePaths = stringArrayFromField(value.relativePaths);
309
+ if (relativePaths.length > 0 && relativePaths.length !== fileCount) {
310
+ throw new FileRouteError(400, 'Upload path count must match file count', 'BAD_REQUEST');
311
+ }
312
+ return { targetPath: value.targetPath, relativePaths };
313
+ }
314
+ function parseRenameRequest(value) {
315
+ if (!isRecord(value))
316
+ throw new FileRouteError(400, 'Request body is required', 'BAD_REQUEST');
317
+ if (typeof value.path !== 'string')
318
+ throw new FileRouteError(400, 'Path is required', 'BAD_REQUEST');
319
+ if (typeof value.newName !== 'string')
320
+ throw new FileRouteError(400, 'New name is required', 'BAD_REQUEST');
321
+ return { path: value.path, newName: value.newName };
322
+ }
323
+ function parseDeleteRequest(value) {
324
+ if (!isRecord(value))
325
+ throw new FileRouteError(400, 'Request body is required', 'BAD_REQUEST');
326
+ if (typeof value.path !== 'string')
327
+ throw new FileRouteError(400, 'Path is required', 'BAD_REQUEST');
328
+ return { path: value.path, recursive: value.recursive === true };
329
+ }
330
+ function resolveRequiredPath(value) {
331
+ if (typeof value !== 'string' || value.length === 0) {
332
+ throw new FileRouteError(400, 'Path is required', 'BAD_REQUEST');
333
+ }
334
+ return resolveUserPath(value);
335
+ }
336
+ function resolveUserPath(value, fallback) {
337
+ if (typeof value !== 'string' || value.length === 0) {
338
+ if (fallback !== undefined)
339
+ return resolve(expandHomePrefix(fallback));
340
+ throw new FileRouteError(400, 'Path is required', 'BAD_REQUEST');
341
+ }
342
+ return resolve(expandHomePrefix(value));
343
+ }
344
+ function validateFileName(value) {
345
+ const name = value.trim();
346
+ if (!name)
347
+ throw new FileRouteError(400, 'Name is required', 'BAD_REQUEST');
348
+ if (name === '.' || name === '..' || name.includes('/') || name.includes('\\')) {
349
+ throw new FileRouteError(400, 'Name cannot include path separators', 'BAD_REQUEST');
350
+ }
351
+ return name;
352
+ }
353
+ function stringArrayFromField(value) {
354
+ if (value === undefined)
355
+ return [];
356
+ if (typeof value === 'string')
357
+ return [value];
358
+ if (Array.isArray(value) && value.every((item) => typeof item === 'string'))
359
+ return value;
360
+ throw new FileRouteError(400, 'Upload paths must be strings', 'BAD_REQUEST');
361
+ }
362
+ function sanitizeUploadRelativePath(value) {
363
+ const normalized = value.replaceAll('\\', '/');
364
+ if (!normalized || normalized.startsWith('/')) {
365
+ throw new FileRouteError(400, 'Upload path must be relative', 'BAD_REQUEST');
366
+ }
367
+ const segments = normalized.split('/');
368
+ if (segments.some((segment) => !segment || segment === '.' || segment === '..')) {
369
+ throw new FileRouteError(400, 'Upload path contains invalid segments', 'BAD_REQUEST');
370
+ }
371
+ return segments;
372
+ }
373
+ async function assertWritableUploadTarget(destinationPath) {
374
+ try {
375
+ const destinationStats = await lstat(destinationPath);
376
+ if (destinationStats.isDirectory()) {
377
+ throw new FileRouteError(409, 'A directory already exists at the upload target', 'EEXIST');
378
+ }
379
+ }
380
+ catch (error) {
381
+ if (error instanceof FileRouteError)
382
+ throw error;
383
+ if (errorCode(error) !== 'ENOENT')
384
+ throw error;
385
+ }
386
+ }
387
+ function isSameOrChildPath(parentPath, childPath) {
388
+ const childRelativePath = relative(parentPath, childPath);
389
+ return childRelativePath === '' || (!childRelativePath.startsWith('..') && !isAbsolute(childRelativePath));
390
+ }
391
+ async function entryFromDirent(parentPath, dirent) {
392
+ const entryPath = join(parentPath, dirent.name);
393
+ const type = fileEntryType(dirent);
394
+ return entryFromPath(entryPath, dirent.name, type, type !== 'symlink');
395
+ }
396
+ async function entryFromPath(entryPath, entryName = basename(entryPath), fallbackType = 'other', skipLstat = false) {
397
+ let linkStats = null;
398
+ let targetStats = null;
399
+ const unreachable = {
400
+ name: entryName,
401
+ path: entryPath,
402
+ displayPath: displayPath(entryPath),
403
+ type: fallbackType,
404
+ hidden: entryName.startsWith('.'),
405
+ size: null,
406
+ modifiedAt: null,
407
+ readable: false,
408
+ writable: false,
409
+ };
410
+ if (skipLstat) {
411
+ try {
412
+ targetStats = await stat(entryPath);
413
+ linkStats = targetStats;
414
+ }
415
+ catch {
416
+ return unreachable;
417
+ }
418
+ }
419
+ else {
420
+ try {
421
+ linkStats = await lstat(entryPath);
422
+ }
423
+ catch {
424
+ return unreachable;
425
+ }
426
+ try {
427
+ targetStats = await stat(entryPath);
428
+ }
429
+ catch {
430
+ targetStats = linkStats;
431
+ }
432
+ }
433
+ const type = skipLstat ? fallbackType : fileEntryType(linkStats);
434
+ const metadataStats = targetStats ?? linkStats;
435
+ const [readable, writable] = await Promise.all([
436
+ canAccess(entryPath, constants.R_OK),
437
+ canAccess(entryPath, constants.W_OK),
438
+ ]);
439
+ return {
440
+ name: entryName,
441
+ path: entryPath,
442
+ displayPath: displayPath(entryPath),
443
+ type,
444
+ hidden: entryName.startsWith('.'),
445
+ size: metadataStats.isDirectory() ? null : metadataStats.size,
446
+ modifiedAt: metadataStats.mtimeMs,
447
+ readable,
448
+ writable,
449
+ };
450
+ }
451
+ async function canAccess(targetPath, mode) {
452
+ try {
453
+ await access(targetPath, mode);
454
+ return true;
455
+ }
456
+ catch {
457
+ return false;
458
+ }
459
+ }
460
+ function displayPath(absolutePath) {
461
+ if (absolutePath === HOME)
462
+ return '~/';
463
+ const pathRelativeToHome = relative(HOME, absolutePath);
464
+ if (pathRelativeToHome && !pathRelativeToHome.startsWith('..') && !isAbsolute(pathRelativeToHome)) {
465
+ return `~/${pathRelativeToHome.split(sep).join('/')}`;
466
+ }
467
+ return absolutePath;
468
+ }
469
+ function fileEntryType(entry) {
470
+ if (entry.isSymbolicLink())
471
+ return 'symlink';
472
+ if (entry.isDirectory())
473
+ return 'directory';
474
+ if (entry.isFile())
475
+ return 'file';
476
+ return 'other';
477
+ }
478
+ const ENTRY_RANK = { directory: 0, file: 1, symlink: 2, other: 3 };
479
+ function compareEntries(a, b) {
480
+ const typeDifference = (ENTRY_RANK[a.type] ?? 3) - (ENTRY_RANK[b.type] ?? 3);
481
+ if (typeDifference !== 0)
482
+ return typeDifference;
483
+ return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
484
+ }
485
+ async function looksBinary(filePath, size) {
486
+ if (size === 0)
487
+ return false;
488
+ const sampleSize = Math.min(TEXT_SAMPLE_BYTES, size);
489
+ const buffer = Buffer.alloc(sampleSize);
490
+ const handle = await open(filePath, 'r');
491
+ try {
492
+ const { bytesRead } = await handle.read(buffer, 0, sampleSize, 0);
493
+ if (bytesRead === 0)
494
+ return false;
495
+ let controlBytes = 0;
496
+ for (let index = 0; index < bytesRead; index += 1) {
497
+ const byte = buffer[index];
498
+ if (byte === 0)
499
+ return true;
500
+ const isAllowedWhitespace = byte === 9 || byte === 10 || byte === 12 || byte === 13;
501
+ if ((byte < 32 && !isAllowedWhitespace) || byte === 127)
502
+ controlBytes += 1;
503
+ }
504
+ return controlBytes / bytesRead > 0.2;
505
+ }
506
+ finally {
507
+ await handle.close();
508
+ }
509
+ }
510
+ function sendFileError(res, error, fallback) {
511
+ if (error instanceof FileRouteError) {
512
+ res.status(error.status).json({ error: error.message, code: error.code });
513
+ return;
514
+ }
515
+ const code = errorCode(error);
516
+ const status = statusForNodeCode(code);
517
+ const message = error instanceof Error && error.message ? error.message : fallback;
518
+ res.status(status).json({ error: message, code });
519
+ }
520
+ function sendStreamingFileError(res, error, fallback) {
521
+ if (res.headersSent) {
522
+ res.destroy(error instanceof Error ? error : new Error(fallback));
523
+ return;
524
+ }
525
+ sendFileError(res, error, fallback);
526
+ }
527
+ function statusForNodeCode(code) {
528
+ switch (code) {
529
+ case 'ENOENT':
530
+ return 404;
531
+ case 'EACCES':
532
+ case 'EPERM':
533
+ return 403;
534
+ case 'ENOTDIR':
535
+ case 'EISDIR':
536
+ return 400;
537
+ case 'EEXIST':
538
+ case 'ENOTEMPTY':
539
+ return 409;
540
+ default:
541
+ return 500;
542
+ }
543
+ }
@@ -0,0 +1 @@
1
+ export declare const skillsRouter: import("express-serve-static-core").Router;
@@ -0,0 +1,13 @@
1
+ import { Router } from 'express';
2
+ import { getBundledSkillWithContent, listBundledSkills, toSkillMeta } from '../skills/catalog.js';
3
+ export const skillsRouter = Router();
4
+ skillsRouter.get('/', async (_req, res) => {
5
+ const skills = await listBundledSkills();
6
+ res.json({ skills: skills.map(toSkillMeta) });
7
+ });
8
+ skillsRouter.get('/:id/content', async (req, res) => {
9
+ const result = await getBundledSkillWithContent(req.params.id);
10
+ if (!result)
11
+ return res.status(404).json({ error: 'Skill not found' });
12
+ res.json({ skill: toSkillMeta(result.skill), content: result.content });
13
+ });
@@ -0,0 +1 @@
1
+ export declare const tasksRouter: import("express-serve-static-core").Router;