anycodex 0.0.3 → 0.0.5

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 (324) hide show
  1. package/dist/bin.js +21 -9
  2. package/package.json +3 -62
  3. package/src/bin.ts +663 -0
  4. package/tsconfig.json +8 -0
  5. package/tsup.config.ts +12 -0
  6. package/dist/app/assets/abap-BdImnpbu.js +0 -1
  7. package/dist/app/assets/actionscript-3-CoDkCxhg.js +0 -1
  8. package/dist/app/assets/ada-bCR0ucgS.js +0 -1
  9. package/dist/app/assets/andromeeda-C4gqWexZ.js +0 -1
  10. package/dist/app/assets/angular-html-DA-rfuFy.js +0 -1
  11. package/dist/app/assets/angular-ts-BrjP3tb8.js +0 -1
  12. package/dist/app/assets/apache-Pmp26Uib.js +0 -1
  13. package/dist/app/assets/apex-D8_7TLub.js +0 -1
  14. package/dist/app/assets/apl-CORt7UWP.js +0 -1
  15. package/dist/app/assets/applescript-Co6uUVPk.js +0 -1
  16. package/dist/app/assets/ara-BRHolxvo.js +0 -1
  17. package/dist/app/assets/asciidoc-Ve4PFQV2.js +0 -1
  18. package/dist/app/assets/asm-D_Q5rh1f.js +0 -1
  19. package/dist/app/assets/astro-HNnZUWAn.js +0 -1
  20. package/dist/app/assets/aurora-x-D-2ljcwZ.js +0 -1
  21. package/dist/app/assets/awk-DMzUqQB5.js +0 -1
  22. package/dist/app/assets/ayu-dark-DYE7WIF3.js +0 -1
  23. package/dist/app/assets/ayu-light-BA47KaF1.js +0 -1
  24. package/dist/app/assets/ayu-mirage-32ctXXKs.js +0 -1
  25. package/dist/app/assets/ballerina-BFfxhgS-.js +0 -1
  26. package/dist/app/assets/bat-BkioyH1T.js +0 -1
  27. package/dist/app/assets/beancount-k_qm7-4y.js +0 -1
  28. package/dist/app/assets/berry-uYugtg8r.js +0 -1
  29. package/dist/app/assets/bibtex-CHM0blh-.js +0 -1
  30. package/dist/app/assets/bicep-Bmn6On1c.js +0 -1
  31. package/dist/app/assets/bird2-BIv1doCn.js +0 -1
  32. package/dist/app/assets/blade-BjGOyj-B.js +0 -1
  33. package/dist/app/assets/bsl-BO_Y6i37.js +0 -1
  34. package/dist/app/assets/c-BIGW1oBm.js +0 -1
  35. package/dist/app/assets/c3-eo99z4R2.js +0 -1
  36. package/dist/app/assets/cadence-Bv_4Rxtq.js +0 -1
  37. package/dist/app/assets/cairo-KRGpt6FW.js +0 -1
  38. package/dist/app/assets/catppuccin-frappe-DFWUc33u.js +0 -1
  39. package/dist/app/assets/catppuccin-latte-C9dUb6Cb.js +0 -1
  40. package/dist/app/assets/catppuccin-macchiato-DQyhUUbL.js +0 -1
  41. package/dist/app/assets/catppuccin-mocha-D87Tk5Gz.js +0 -1
  42. package/dist/app/assets/clarity-D53aC0YG.js +0 -1
  43. package/dist/app/assets/clojure-P80f7IUj.js +0 -1
  44. package/dist/app/assets/cmake-D1j8_8rp.js +0 -1
  45. package/dist/app/assets/cobol-nBiQ_Alo.js +0 -1
  46. package/dist/app/assets/codeowners-Bp6g37R7.js +0 -1
  47. package/dist/app/assets/codeql-DsOJ9woJ.js +0 -1
  48. package/dist/app/assets/coffee-Ch7k5sss.js +0 -1
  49. package/dist/app/assets/common-lisp-Cg-RD9OK.js +0 -1
  50. package/dist/app/assets/coq-DkFqJrB1.js +0 -1
  51. package/dist/app/assets/cpp-CofmeUqb.js +0 -1
  52. package/dist/app/assets/crystal-DNxU26gB.js +0 -1
  53. package/dist/app/assets/csharp-COcwbKMJ.js +0 -1
  54. package/dist/app/assets/css-CLj8gQPS.js +0 -1
  55. package/dist/app/assets/csv-fuZLfV_i.js +0 -1
  56. package/dist/app/assets/cue-D82EKSYY.js +0 -1
  57. package/dist/app/assets/cypher-COkxafJQ.js +0 -1
  58. package/dist/app/assets/d-85-TOEBH.js +0 -1
  59. package/dist/app/assets/dark-plus-C3mMm8J8.js +0 -1
  60. package/dist/app/assets/dart-bE4Kk8sk.js +0 -1
  61. package/dist/app/assets/dax-CEL-wOlO.js +0 -1
  62. package/dist/app/assets/desktop-BmXAJ9_W.js +0 -1
  63. package/dist/app/assets/diff-D97Zzqfu.js +0 -1
  64. package/dist/app/assets/docker-BcOcwvcX.js +0 -1
  65. package/dist/app/assets/dotenv-Da5cRb03.js +0 -1
  66. package/dist/app/assets/dracula-BzJJZx-M.js +0 -1
  67. package/dist/app/assets/dracula-soft-BXkSAIEj.js +0 -1
  68. package/dist/app/assets/dream-maker-BtqSS_iP.js +0 -1
  69. package/dist/app/assets/edge-FbVlp4U3.js +0 -1
  70. package/dist/app/assets/elixir-CkH2-t6x.js +0 -1
  71. package/dist/app/assets/elm-DbKCFpqz.js +0 -1
  72. package/dist/app/assets/emacs-lisp-CXvaQtF9.js +0 -1
  73. package/dist/app/assets/erb-BYCe7drp.js +0 -1
  74. package/dist/app/assets/erlang-DsQrWhSR.js +0 -1
  75. package/dist/app/assets/everforest-dark-BgDCqdQA.js +0 -1
  76. package/dist/app/assets/everforest-light-C8M2exoo.js +0 -1
  77. package/dist/app/assets/fennel-BYunw83y.js +0 -1
  78. package/dist/app/assets/fish-BvzEVeQv.js +0 -1
  79. package/dist/app/assets/fluent-C4IJs8-o.js +0 -1
  80. package/dist/app/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
  81. package/dist/app/assets/fortran-free-form-BxgE0vQu.js +0 -1
  82. package/dist/app/assets/fsharp-CXgrBDvD.js +0 -1
  83. package/dist/app/assets/gdresource-BOOCDP_w.js +0 -1
  84. package/dist/app/assets/gdscript-C5YyOfLZ.js +0 -1
  85. package/dist/app/assets/gdshader-DkwncUOv.js +0 -1
  86. package/dist/app/assets/genie-D0YGMca9.js +0 -1
  87. package/dist/app/assets/gherkin-DyxjwDmM.js +0 -1
  88. package/dist/app/assets/git-commit-F4YmCXRG.js +0 -1
  89. package/dist/app/assets/git-rebase-r7XF79zn.js +0 -1
  90. package/dist/app/assets/github-dark-DHJKELXO.js +0 -1
  91. package/dist/app/assets/github-dark-default-Cuk6v7N8.js +0 -1
  92. package/dist/app/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
  93. package/dist/app/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
  94. package/dist/app/assets/github-light-DAi9KRSo.js +0 -1
  95. package/dist/app/assets/github-light-default-D7oLnXFd.js +0 -1
  96. package/dist/app/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
  97. package/dist/app/assets/gleam-BspZqrRM.js +0 -1
  98. package/dist/app/assets/glimmer-js-ByusRIyA.js +0 -1
  99. package/dist/app/assets/glimmer-ts-BfAWNZQY.js +0 -1
  100. package/dist/app/assets/glsl-DplSGwfg.js +0 -1
  101. package/dist/app/assets/gn-n2N0HUVH.js +0 -1
  102. package/dist/app/assets/gnuplot-DdkO51Og.js +0 -1
  103. package/dist/app/assets/go-C27-OAKa.js +0 -1
  104. package/dist/app/assets/graphql-ChdNCCLP.js +0 -1
  105. package/dist/app/assets/groovy-gcz8RCvz.js +0 -1
  106. package/dist/app/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
  107. package/dist/app/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
  108. package/dist/app/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
  109. package/dist/app/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
  110. package/dist/app/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
  111. package/dist/app/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
  112. package/dist/app/assets/hack-i7_Ulhet.js +0 -1
  113. package/dist/app/assets/haml-D5jkg6IW.js +0 -1
  114. package/dist/app/assets/handlebars-BpdQsYii.js +0 -1
  115. package/dist/app/assets/haskell-Df6bDoY_.js +0 -1
  116. package/dist/app/assets/haxe-CzTSHFRz.js +0 -1
  117. package/dist/app/assets/hcl-BWvSN4gD.js +0 -1
  118. package/dist/app/assets/hjson-D5-asLiD.js +0 -1
  119. package/dist/app/assets/hlsl-D3lLCCz7.js +0 -1
  120. package/dist/app/assets/horizon-BUw7H-hv.js +0 -1
  121. package/dist/app/assets/horizon-bright-CUuTKBJd.js +0 -1
  122. package/dist/app/assets/houston-DnULxvSX.js +0 -1
  123. package/dist/app/assets/html-derivative-DlHx6ybY.js +0 -1
  124. package/dist/app/assets/html-pp8916En.js +0 -1
  125. package/dist/app/assets/http-jrhK8wxY.js +0 -1
  126. package/dist/app/assets/hurl-irOxFIW8.js +0 -1
  127. package/dist/app/assets/hxml-Bvhsp5Yf.js +0 -1
  128. package/dist/app/assets/hy-DFXneXwc.js +0 -1
  129. package/dist/app/assets/imba-DGztddWO.js +0 -1
  130. package/dist/app/assets/index-BBYiZjoU.js +0 -238
  131. package/dist/app/assets/index-DU8KNBjo.css +0 -32
  132. package/dist/app/assets/ini-BEwlwnbL.js +0 -1
  133. package/dist/app/assets/java-CylS5w8V.js +0 -1
  134. package/dist/app/assets/javascript-wDzz0qaB.js +0 -1
  135. package/dist/app/assets/jinja-f2NsQr07.js +0 -1
  136. package/dist/app/assets/jison-wvAkD_A8.js +0 -1
  137. package/dist/app/assets/json-Cp-IABpG.js +0 -1
  138. package/dist/app/assets/json5-C9tS-k6U.js +0 -1
  139. package/dist/app/assets/jsonc-Des-eS-w.js +0 -1
  140. package/dist/app/assets/jsonl-DcaNXYhu.js +0 -1
  141. package/dist/app/assets/jsonnet-DFQXde-d.js +0 -1
  142. package/dist/app/assets/jssm-C2t-YnRu.js +0 -1
  143. package/dist/app/assets/jsx-g9-lgVsj.js +0 -1
  144. package/dist/app/assets/julia-CxzCAyBv.js +0 -1
  145. package/dist/app/assets/just-VxiPbLrw.js +0 -1
  146. package/dist/app/assets/kanagawa-dragon-CkXjmgJE.js +0 -1
  147. package/dist/app/assets/kanagawa-lotus-CfQXZHmo.js +0 -1
  148. package/dist/app/assets/kanagawa-wave-DWedfzmr.js +0 -1
  149. package/dist/app/assets/kdl-DV7GczEv.js +0 -1
  150. package/dist/app/assets/kotlin-BdnUsdx6.js +0 -1
  151. package/dist/app/assets/kusto-wEQ09or8.js +0 -1
  152. package/dist/app/assets/laserwave-DUszq2jm.js +0 -1
  153. package/dist/app/assets/latex-CWtU0Tv5.js +0 -1
  154. package/dist/app/assets/lean-BZvkOJ9d.js +0 -1
  155. package/dist/app/assets/less-B1dDrJ26.js +0 -1
  156. package/dist/app/assets/light-plus-B7mTdjB0.js +0 -1
  157. package/dist/app/assets/liquid-C0sCDyMI.js +0 -1
  158. package/dist/app/assets/llvm-DjAJT7YJ.js +0 -1
  159. package/dist/app/assets/log-2UxHyX5q.js +0 -1
  160. package/dist/app/assets/logo-BtOb2qkB.js +0 -1
  161. package/dist/app/assets/lua-BaeVxFsk.js +0 -1
  162. package/dist/app/assets/luau-C-HG3fhB.js +0 -1
  163. package/dist/app/assets/make-CHLpvVh8.js +0 -1
  164. package/dist/app/assets/markdown-Cvjx9yec.js +0 -1
  165. package/dist/app/assets/marko-DjSrsDqO.js +0 -1
  166. package/dist/app/assets/material-theme-D5KoaKCx.js +0 -1
  167. package/dist/app/assets/material-theme-darker-BfHTSMKl.js +0 -1
  168. package/dist/app/assets/material-theme-lighter-B0m2ddpp.js +0 -1
  169. package/dist/app/assets/material-theme-ocean-CyktbL80.js +0 -1
  170. package/dist/app/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
  171. package/dist/app/assets/matlab-D7o27uSR.js +0 -1
  172. package/dist/app/assets/mdc-DTYItulj.js +0 -1
  173. package/dist/app/assets/mdx-Cmh6b_Ma.js +0 -1
  174. package/dist/app/assets/mermaid-mWjccvbQ.js +0 -1
  175. package/dist/app/assets/min-dark-CafNBF8u.js +0 -1
  176. package/dist/app/assets/min-light-CTRr51gU.js +0 -1
  177. package/dist/app/assets/mipsasm-CKIfxQSi.js +0 -1
  178. package/dist/app/assets/mojo-rZm6bMo-.js +0 -1
  179. package/dist/app/assets/monokai-D4h5O-jR.js +0 -1
  180. package/dist/app/assets/moonbit-_H4v1dQx.js +0 -1
  181. package/dist/app/assets/move-IF9eRakj.js +0 -1
  182. package/dist/app/assets/narrat-DRg8JJMk.js +0 -1
  183. package/dist/app/assets/nextflow-C-mBbutL.js +0 -1
  184. package/dist/app/assets/nextflow-groovy-vE_lwT2v.js +0 -1
  185. package/dist/app/assets/nginx-BpAMiNFr.js +0 -1
  186. package/dist/app/assets/night-owl-C39BiMTA.js +0 -1
  187. package/dist/app/assets/night-owl-light-CMTm3GFP.js +0 -1
  188. package/dist/app/assets/nim-BIad80T-.js +0 -1
  189. package/dist/app/assets/nix-CwoSXNpI.js +0 -1
  190. package/dist/app/assets/nord-Ddv68eIx.js +0 -1
  191. package/dist/app/assets/nushell-Cz2AlsmD.js +0 -1
  192. package/dist/app/assets/objective-c-DXmwc3jG.js +0 -1
  193. package/dist/app/assets/objective-cpp-CLxacb5B.js +0 -1
  194. package/dist/app/assets/ocaml-C0hk2d4L.js +0 -1
  195. package/dist/app/assets/odin-BBf5iR-q.js +0 -1
  196. package/dist/app/assets/one-dark-pro-DVMEJ2y_.js +0 -1
  197. package/dist/app/assets/one-light-C3Wv6jpd.js +0 -1
  198. package/dist/app/assets/openscad-C4EeE6gA.js +0 -1
  199. package/dist/app/assets/pascal-D93ZcfNL.js +0 -1
  200. package/dist/app/assets/perl-NvoQZIq0.js +0 -1
  201. package/dist/app/assets/php-R6g_5hLQ.js +0 -1
  202. package/dist/app/assets/pkl-u5AG7uiY.js +0 -1
  203. package/dist/app/assets/plastic-3e1v2bzS.js +0 -1
  204. package/dist/app/assets/plsql-ChMvpjG-.js +0 -1
  205. package/dist/app/assets/po-BTJTHyun.js +0 -1
  206. package/dist/app/assets/poimandres-CS3Unz2-.js +0 -1
  207. package/dist/app/assets/polar-C0HS_06l.js +0 -1
  208. package/dist/app/assets/postcss-CXtECtnM.js +0 -1
  209. package/dist/app/assets/powerquery-CEu0bR-o.js +0 -1
  210. package/dist/app/assets/powershell-Dpen1YoG.js +0 -1
  211. package/dist/app/assets/prisma-Dd19v3D-.js +0 -1
  212. package/dist/app/assets/prolog-CbFg5uaA.js +0 -1
  213. package/dist/app/assets/proto-C7zT0LnQ.js +0 -1
  214. package/dist/app/assets/pug-DKIMFp6K.js +0 -1
  215. package/dist/app/assets/puppet-BMWR74SV.js +0 -1
  216. package/dist/app/assets/purescript-CklMAg4u.js +0 -1
  217. package/dist/app/assets/python-B6aJPvgy.js +0 -1
  218. package/dist/app/assets/qml-3beO22l8.js +0 -1
  219. package/dist/app/assets/qmldir-C8lEn-DE.js +0 -1
  220. package/dist/app/assets/qss-IeuSbFQv.js +0 -1
  221. package/dist/app/assets/r-Dspwwk_N.js +0 -1
  222. package/dist/app/assets/racket-BqYA7rlc.js +0 -1
  223. package/dist/app/assets/raku-DXvB9xmW.js +0 -1
  224. package/dist/app/assets/razor-BDqjjVU7.js +0 -1
  225. package/dist/app/assets/red-bN70gL4F.js +0 -1
  226. package/dist/app/assets/reg-C-SQnVFl.js +0 -1
  227. package/dist/app/assets/regexp-CDVJQ6XC.js +0 -1
  228. package/dist/app/assets/rel-C3B-1QV4.js +0 -1
  229. package/dist/app/assets/riscv-BM1_JUlF.js +0 -1
  230. package/dist/app/assets/ron-D8l8udqQ.js +0 -1
  231. package/dist/app/assets/rose-pine-dawn-DHQR4-dF.js +0 -1
  232. package/dist/app/assets/rose-pine-moon-D4_iv3hh.js +0 -1
  233. package/dist/app/assets/rose-pine-qdsjHGoJ.js +0 -1
  234. package/dist/app/assets/rosmsg-BJDFO7_C.js +0 -1
  235. package/dist/app/assets/rst-CRjBmOyv.js +0 -1
  236. package/dist/app/assets/ruby-Wjq7vjNf.js +0 -1
  237. package/dist/app/assets/rust-B1yitclQ.js +0 -1
  238. package/dist/app/assets/sas-cz2c8ADy.js +0 -1
  239. package/dist/app/assets/sass-Cj5Yp3dK.js +0 -1
  240. package/dist/app/assets/scala-C151Ov-r.js +0 -1
  241. package/dist/app/assets/scheme-C98Dy4si.js +0 -1
  242. package/dist/app/assets/scss-D5BDwBP9.js +0 -1
  243. package/dist/app/assets/sdbl-DVxCFoDh.js +0 -1
  244. package/dist/app/assets/shaderlab-Dg9Lc6iA.js +0 -1
  245. package/dist/app/assets/shellscript-Yzrsuije.js +0 -1
  246. package/dist/app/assets/shellsession-BADoaaVG.js +0 -1
  247. package/dist/app/assets/slack-dark-BthQWCQV.js +0 -1
  248. package/dist/app/assets/slack-ochin-DqwNpetd.js +0 -1
  249. package/dist/app/assets/smalltalk-BERRCDM3.js +0 -1
  250. package/dist/app/assets/snazzy-light-Bw305WKR.js +0 -1
  251. package/dist/app/assets/solarized-dark-DXbdFlpD.js +0 -1
  252. package/dist/app/assets/solarized-light-L9t79GZl.js +0 -1
  253. package/dist/app/assets/solidity-rGO070M0.js +0 -1
  254. package/dist/app/assets/soy-8wufbnw4.js +0 -1
  255. package/dist/app/assets/sparql-rVzFXLq3.js +0 -1
  256. package/dist/app/assets/splunk-BtCnVYZw.js +0 -1
  257. package/dist/app/assets/sql-BLtJtn59.js +0 -1
  258. package/dist/app/assets/ssh-config-_ykCGR6B.js +0 -1
  259. package/dist/app/assets/stata-BH5u7GGu.js +0 -1
  260. package/dist/app/assets/stylus-BEDo0Tqx.js +0 -1
  261. package/dist/app/assets/surrealql-Bq5Q-fJD.js +0 -1
  262. package/dist/app/assets/svelte-Cy7k_4gC.js +0 -1
  263. package/dist/app/assets/swift-D82vCrfD.js +0 -1
  264. package/dist/app/assets/synthwave-84-CbfX1IO0.js +0 -1
  265. package/dist/app/assets/system-verilog-CnnmHF94.js +0 -1
  266. package/dist/app/assets/systemd-4A_iFExJ.js +0 -1
  267. package/dist/app/assets/talonscript-CkByrt1z.js +0 -1
  268. package/dist/app/assets/tasl-QIJgUcNo.js +0 -1
  269. package/dist/app/assets/tcl-dwOrl1Do.js +0 -1
  270. package/dist/app/assets/templ-DhtptRzy.js +0 -1
  271. package/dist/app/assets/terraform-BETggiCN.js +0 -1
  272. package/dist/app/assets/tex-idrVyKtj.js +0 -1
  273. package/dist/app/assets/tokyo-night-hegEt444.js +0 -1
  274. package/dist/app/assets/toml-vGWfd6FD.js +0 -1
  275. package/dist/app/assets/ts-tags-DQrlYJgV.js +0 -1
  276. package/dist/app/assets/tsv-B_m7g4N7.js +0 -1
  277. package/dist/app/assets/tsx-COt5Ahok.js +0 -1
  278. package/dist/app/assets/turtle-BsS91CYL.js +0 -1
  279. package/dist/app/assets/twig-xg9kU7Mw.js +0 -1
  280. package/dist/app/assets/typescript-BPQ3VLAy.js +0 -1
  281. package/dist/app/assets/typespec-CAFt9gP4.js +0 -1
  282. package/dist/app/assets/typst-DHCkPAjA.js +0 -1
  283. package/dist/app/assets/v-BcVCzyr7.js +0 -1
  284. package/dist/app/assets/vala-CsfeWuGM.js +0 -1
  285. package/dist/app/assets/vb-D17OF-Vu.js +0 -1
  286. package/dist/app/assets/verilog-BQ8w6xss.js +0 -1
  287. package/dist/app/assets/vesper-DU1UobuO.js +0 -1
  288. package/dist/app/assets/vhdl-CeAyd5Ju.js +0 -1
  289. package/dist/app/assets/viml-CJc9bBzg.js +0 -1
  290. package/dist/app/assets/vitesse-black-Bkuqu6BP.js +0 -1
  291. package/dist/app/assets/vitesse-dark-D0r3Knsf.js +0 -1
  292. package/dist/app/assets/vitesse-light-CVO1_9PV.js +0 -1
  293. package/dist/app/assets/vue-D2xRrEX4.js +0 -1
  294. package/dist/app/assets/vue-html-AaS7Mt5G.js +0 -1
  295. package/dist/app/assets/vue-vine-BoDAl6tE.js +0 -1
  296. package/dist/app/assets/vyper-CDx5xZoG.js +0 -1
  297. package/dist/app/assets/wasm-CG6Dc4jp.js +0 -1
  298. package/dist/app/assets/wasm-MzD3tlZU.js +0 -1
  299. package/dist/app/assets/wenyan-BV7otONQ.js +0 -1
  300. package/dist/app/assets/wgsl-Dx-B1_4e.js +0 -1
  301. package/dist/app/assets/wikitext-BhOHFoWU.js +0 -1
  302. package/dist/app/assets/wit-5i3qLPDT.js +0 -1
  303. package/dist/app/assets/wolfram-lXgVvXCa.js +0 -1
  304. package/dist/app/assets/xml-sdJ4AIDG.js +0 -1
  305. package/dist/app/assets/xsl-CtQFsRM5.js +0 -1
  306. package/dist/app/assets/yaml-Buea-lGh.js +0 -1
  307. package/dist/app/assets/zenscript-DVFEvuxE.js +0 -1
  308. package/dist/app/assets/zig-VOosw3JB.js +0 -1
  309. package/dist/app/index.html +0 -13
  310. package/dist/chunk-6DDCZPRP.js +0 -1474
  311. package/dist/chunk-HULFFF7R.js +0 -25
  312. package/dist/chunk-KB4MYP36.js +0 -8
  313. package/dist/chunk-P23NZBHE.js +0 -5130
  314. package/dist/chunk-TDYQG5PB.js +0 -1621
  315. package/dist/chunk-XU2SE4LZ.js +0 -3864
  316. package/dist/chunk-XXVDY7BO.js +0 -53
  317. package/dist/chunk-ZXPWUU3S.js +0 -110
  318. package/dist/dist-GBG4FGPZ.js +0 -1806
  319. package/dist/dist-XGPL3ARQ.js +0 -94
  320. package/dist/glob-RMMK6FVW-M34I5XTP.js +0 -8
  321. package/dist/registry-VQVHAEPP-MGYPDXYJ.js +0 -13
  322. package/dist/schema-SOLWPA3E-CEUVS57H.js +0 -13
  323. package/dist/session-Q7S3ITUV-CECGQJC5.js +0 -18
  324. package/dist/storage-YSEEBFV7-N75L4HBF.js +0 -28
@@ -1,1806 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- CodeAgent
4
- } from "./chunk-P23NZBHE.js";
5
- import "./chunk-XU2SE4LZ.js";
6
- import "./chunk-TDYQG5PB.js";
7
- import "./chunk-ZXPWUU3S.js";
8
- import {
9
- Database
10
- } from "./chunk-6DDCZPRP.js";
11
- import "./chunk-HULFFF7R.js";
12
- import "./chunk-KB4MYP36.js";
13
- import "./chunk-XXVDY7BO.js";
14
-
15
- // ../server/dist/chunk-LAEF7B45.js
16
- import http from "http";
17
- import { fileURLToPath } from "url";
18
- import path3 from "path";
19
- import os from "os";
20
- import fs4 from "fs";
21
- import fsPromises from "fs/promises";
22
- import { execFile, spawn as cpSpawn } from "child_process";
23
- import { WebSocketServer, WebSocket as WS } from "ws";
24
- import * as pty from "node-pty";
25
- import fs from "fs";
26
- import nodePath from "path";
27
- import fs2 from "fs/promises";
28
- import { existsSync, statSync, readdirSync } from "fs";
29
- import path from "path";
30
- import { spawn as spawn2 } from "child_process";
31
- import { spawn as spawn22 } from "child_process";
32
- import fs3 from "fs/promises";
33
- import path2 from "path";
34
- var SqlJsStorage = class {
35
- db = null;
36
- noSqlDb = null;
37
- dbPath;
38
- flushTimer = null;
39
- constructor(dbPath) {
40
- this.dbPath = dbPath ?? null;
41
- }
42
- async connect(migrations) {
43
- if (this.noSqlDb) return this.noSqlDb;
44
- const initSqlJs = (await import("sql.js")).default;
45
- const SQL = await initSqlJs();
46
- if (this.dbPath && fs.existsSync(this.dbPath)) {
47
- const buffer = fs.readFileSync(this.dbPath);
48
- this.db = new SQL.Database(new Uint8Array(buffer));
49
- } else {
50
- this.db = new SQL.Database();
51
- }
52
- this.db.run("PRAGMA foreign_keys = ON");
53
- this.applyMigrations(migrations);
54
- this.flushSync();
55
- const raw = this.createRawDb();
56
- const { SqliteNoSqlDb } = await import("./dist-XGPL3ARQ.js");
57
- this.noSqlDb = new SqliteNoSqlDb(raw);
58
- return this.noSqlDb;
59
- }
60
- // ── Flush to disk ──────────────────────────────────────────────
61
- /** Schedule an async flush (debounced 100ms). */
62
- scheduleFlush() {
63
- if (!this.dbPath) return;
64
- if (this.flushTimer) return;
65
- this.flushTimer = setTimeout(() => {
66
- this.flushTimer = null;
67
- this.flushSync();
68
- }, 100);
69
- }
70
- /** Synchronously write the entire database to disk. */
71
- flushSync() {
72
- if (!this.dbPath || !this.db) return;
73
- const dir = nodePath.dirname(this.dbPath);
74
- fs.mkdirSync(dir, { recursive: true });
75
- const data = this.db.export();
76
- fs.writeFileSync(this.dbPath, Buffer.from(data));
77
- }
78
- // ── RawSqliteDb wrapper ────────────────────────────────────────
79
- createRawDb() {
80
- const db2 = this.db;
81
- const self = this;
82
- return {
83
- run(sql, params) {
84
- db2.run(sql, params);
85
- self.scheduleFlush();
86
- },
87
- get(sql, params) {
88
- const stmt = db2.prepare(sql);
89
- if (params) stmt.bind(params);
90
- if (!stmt.step()) {
91
- stmt.free();
92
- return void 0;
93
- }
94
- const result = stmt.getAsObject();
95
- stmt.free();
96
- return result;
97
- },
98
- all(sql, params) {
99
- const stmt = db2.prepare(sql);
100
- if (params) stmt.bind(params);
101
- const results = [];
102
- while (stmt.step()) {
103
- results.push(stmt.getAsObject());
104
- }
105
- stmt.free();
106
- return results;
107
- },
108
- transaction(fn) {
109
- db2.run("BEGIN TRANSACTION");
110
- try {
111
- fn();
112
- db2.run("COMMIT");
113
- self.scheduleFlush();
114
- } catch (e) {
115
- db2.run("ROLLBACK");
116
- throw e;
117
- }
118
- }
119
- };
120
- }
121
- // ── Migrations ─────────────────────────────────────────────────
122
- applyMigrations(entries) {
123
- if (!this.db) throw new Error("SqlJsStorage: db not initialized");
124
- this.db.run(`
125
- CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (
126
- id INTEGER PRIMARY KEY AUTOINCREMENT,
127
- hash TEXT NOT NULL,
128
- created_at INTEGER
129
- )
130
- `);
131
- const applied = /* @__PURE__ */ new Set();
132
- const rows = this.db.exec(`SELECT hash FROM "__drizzle_migrations"`);
133
- if (rows.length > 0) {
134
- for (const row of rows[0].values) {
135
- applied.add(row[0]);
136
- }
137
- }
138
- for (const entry of entries) {
139
- const hash = entry.name;
140
- if (applied.has(hash)) continue;
141
- this.db.run(entry.sql);
142
- this.db.run(
143
- `INSERT INTO "__drizzle_migrations" (hash, created_at) VALUES (?, ?)`,
144
- [hash, entry.timestamp]
145
- );
146
- }
147
- }
148
- /** Run raw SQL (for server-specific DDL like extra tables). */
149
- exec(sql) {
150
- if (!this.db) throw new Error("SqlJsStorage: db not initialized");
151
- this.db.run(sql);
152
- this.scheduleFlush();
153
- }
154
- /** Run a SELECT query and return rows as objects. */
155
- query(sql, params) {
156
- if (!this.db) throw new Error("SqlJsStorage: db not initialized");
157
- const stmt = this.db.prepare(sql);
158
- if (params) stmt.bind(params);
159
- const results = [];
160
- while (stmt.step()) {
161
- results.push(stmt.getAsObject());
162
- }
163
- stmt.free();
164
- return results;
165
- }
166
- close() {
167
- if (this.flushTimer) {
168
- clearTimeout(this.flushTimer);
169
- this.flushTimer = null;
170
- }
171
- this.flushSync();
172
- if (this.db) {
173
- this.db.close();
174
- this.db = null;
175
- }
176
- this.noSqlDb = null;
177
- }
178
- };
179
- var NodeFS = class {
180
- async exists(p) {
181
- return existsSync(p);
182
- }
183
- async stat(p) {
184
- try {
185
- const s = statSync(p);
186
- return {
187
- size: typeof s.size === "bigint" ? Number(s.size) : s.size,
188
- isDirectory: s.isDirectory(),
189
- isFile: s.isFile(),
190
- mtimeMs: s.mtimeMs
191
- };
192
- } catch {
193
- return void 0;
194
- }
195
- }
196
- async readText(p) {
197
- return fs2.readFile(p, "utf-8");
198
- }
199
- async readBytes(p) {
200
- return fs2.readFile(p);
201
- }
202
- async readDir(p) {
203
- const entries = readdirSync(p, { withFileTypes: true });
204
- return entries.map((e) => ({
205
- name: e.name,
206
- isDirectory: e.isDirectory(),
207
- isFile: e.isFile()
208
- }));
209
- }
210
- async write(p, content) {
211
- try {
212
- await fs2.writeFile(p, content);
213
- } catch (e) {
214
- if (e?.code === "ENOENT") {
215
- await fs2.mkdir(path.dirname(p), { recursive: true });
216
- await fs2.writeFile(p, content);
217
- return;
218
- }
219
- throw e;
220
- }
221
- }
222
- async mkdir(p) {
223
- await fs2.mkdir(p, { recursive: true });
224
- }
225
- async remove(p) {
226
- await fs2.unlink(p).catch(() => {
227
- });
228
- }
229
- async grep(pattern, searchPath, options) {
230
- return new Promise((resolve) => {
231
- const args = [
232
- "--json",
233
- "--line-number",
234
- "--column",
235
- "--no-heading",
236
- ...options?.maxResults ? ["--max-count", String(options.maxResults)] : [],
237
- ...options?.include?.flatMap((g) => ["--glob", g]) ?? [],
238
- pattern,
239
- searchPath
240
- ];
241
- const rg = spawn2("rg", args, { stdio: ["ignore", "pipe", "pipe"] });
242
- let output = "";
243
- rg.stdout.on("data", (data) => {
244
- output += data.toString();
245
- });
246
- rg.on("close", () => {
247
- const results = [];
248
- for (const line of output.split("\n")) {
249
- if (!line.trim()) continue;
250
- try {
251
- const parsed = JSON.parse(line);
252
- if (parsed.type === "match") {
253
- results.push({
254
- file: parsed.data.path.text,
255
- line: parsed.data.line_number,
256
- column: parsed.data.submatches?.[0]?.start ?? 0,
257
- content: parsed.data.lines.text.trimEnd()
258
- });
259
- }
260
- } catch {
261
- }
262
- }
263
- resolve(results);
264
- });
265
- rg.on("error", () => resolve([]));
266
- });
267
- }
268
- async glob(pattern, options = {}) {
269
- const searchPath = options.cwd ?? process.cwd();
270
- const { glob: fsGlob } = await import("fs/promises").catch(() => ({ glob: void 0 }));
271
- if (fsGlob) {
272
- try {
273
- const results = [];
274
- for await (const entry of fsGlob(pattern, { cwd: searchPath })) {
275
- if (options.absolute) {
276
- results.push(path.resolve(searchPath, entry));
277
- } else {
278
- results.push(entry);
279
- }
280
- }
281
- return results;
282
- } catch {
283
- }
284
- }
285
- return new Promise((resolve) => {
286
- const rg = spawn2("rg", ["--files", "--glob", pattern, searchPath], {
287
- stdio: ["ignore", "pipe", "pipe"]
288
- });
289
- let output = "";
290
- rg.stdout.on("data", (data) => {
291
- output += data.toString();
292
- });
293
- rg.on("close", () => {
294
- resolve(
295
- output.split("\n").map((l) => l.trim()).filter(Boolean)
296
- );
297
- });
298
- rg.on("error", () => resolve([]));
299
- });
300
- }
301
- };
302
- var NodeSearchProvider = class {
303
- async grep(options) {
304
- options.signal?.throwIfAborted();
305
- return new Promise((resolve, reject) => {
306
- const args = ["-rnH", "--color=never"];
307
- if (options.include) {
308
- args.push(`--include=${options.include}`);
309
- }
310
- args.push("--exclude-dir=.git");
311
- args.push("-E");
312
- args.push("--", options.pattern, options.path);
313
- const proc = spawn22("grep", args, {
314
- stdio: ["ignore", "pipe", "pipe"],
315
- signal: options.signal
316
- });
317
- let output = "";
318
- proc.stdout.on("data", (data) => {
319
- output += data.toString();
320
- });
321
- proc.on("close", () => {
322
- const results = [];
323
- for (const line of output.split("\n")) {
324
- if (!line.trim()) continue;
325
- const match = line.match(/^(.+?):(\d+):(.*)$/);
326
- if (match) {
327
- let content = match[3];
328
- if (options.maxLineLength !== void 0 && content.length > options.maxLineLength) {
329
- content = content.slice(0, options.maxLineLength) + "...";
330
- }
331
- results.push({
332
- file: match[1],
333
- line: parseInt(match[2], 10),
334
- column: 0,
335
- content
336
- });
337
- }
338
- }
339
- resolve(results);
340
- });
341
- proc.on("error", (error) => {
342
- reject(error);
343
- });
344
- });
345
- }
346
- async listFiles(options) {
347
- options.signal?.throwIfAborted();
348
- const showHidden = options.hidden === true;
349
- const results = [];
350
- const limit = options.limit ?? Infinity;
351
- const excludePatterns = [".git"];
352
- const includePatterns = [];
353
- for (const g of options.glob ?? []) {
354
- if (g.startsWith("!")) {
355
- excludePatterns.push(g.slice(1).replace(/[/*]+$/, ""));
356
- } else {
357
- includePatterns.push(g);
358
- }
359
- }
360
- const walk = async (dir, depth) => {
361
- if (results.length >= limit) return;
362
- if (options.maxDepth !== void 0 && depth > options.maxDepth) return;
363
- options.signal?.throwIfAborted();
364
- let entries;
365
- try {
366
- entries = await fs3.readdir(dir, { withFileTypes: true });
367
- } catch {
368
- return;
369
- }
370
- for (const entry of entries) {
371
- if (results.length >= limit) return;
372
- const name = entry.name;
373
- if (!showHidden && name.startsWith(".")) continue;
374
- const fullPath = path2.join(dir, name);
375
- const relativePath = path2.relative(options.cwd, fullPath);
376
- if (excludePatterns.some((p) => relativePath.startsWith(p) || name === p)) continue;
377
- const isDir = entry.isDirectory() || options.follow && entry.isSymbolicLink();
378
- if (isDir) {
379
- await walk(fullPath, depth + 1);
380
- } else if (entry.isFile()) {
381
- if (includePatterns.length > 0) {
382
- const matches = includePatterns.some((p) => simpleGlobMatch(name, p));
383
- if (!matches) continue;
384
- }
385
- results.push(relativePath);
386
- }
387
- }
388
- };
389
- await walk(options.cwd, 0);
390
- return results;
391
- }
392
- async tree(options) {
393
- const limit = options.limit ?? 50;
394
- const files = await this.listFiles({ cwd: options.cwd, signal: options.signal });
395
- function dir(node, name) {
396
- const existing = node.children.get(name);
397
- if (existing) return existing;
398
- const next = { name, children: /* @__PURE__ */ new Map() };
399
- node.children.set(name, next);
400
- return next;
401
- }
402
- const root = { name: "", children: /* @__PURE__ */ new Map() };
403
- for (const file of files) {
404
- if (file.includes(".opencode")) continue;
405
- const parts = file.split(/[\/\\]/);
406
- if (parts.length < 2) continue;
407
- let node = root;
408
- for (const part of parts.slice(0, -1)) {
409
- node = dir(node, part);
410
- }
411
- }
412
- function count(node) {
413
- let total2 = 0;
414
- for (const child of node.children.values()) {
415
- total2 += 1 + count(child);
416
- }
417
- return total2;
418
- }
419
- const total = count(root);
420
- const lines = [];
421
- const queue = [];
422
- for (const child of Array.from(root.children.values()).sort((a, b) => a.name.localeCompare(b.name))) {
423
- queue.push({ node: child, path: child.name });
424
- }
425
- let used = 0;
426
- for (let i = 0; i < queue.length && used < limit; i++) {
427
- const { node, path: p } = queue[i];
428
- lines.push(p);
429
- used++;
430
- for (const child of Array.from(node.children.values()).sort((a, b) => a.name.localeCompare(b.name))) {
431
- queue.push({ node: child, path: `${p}/${child.name}` });
432
- }
433
- }
434
- if (total > used) lines.push(`[${total - used} truncated]`);
435
- return lines.join("\n");
436
- }
437
- };
438
- function simpleGlobMatch(filename, pattern) {
439
- if (pattern === "*") return true;
440
- if (pattern.startsWith("*.")) {
441
- const ext = pattern.slice(1);
442
- if (ext.startsWith(".{") && ext.endsWith("}")) {
443
- const exts = ext.slice(2, -1).split(",");
444
- return exts.some((e) => filename.endsWith(`.${e}`));
445
- }
446
- return filename.endsWith(ext);
447
- }
448
- return filename === pattern;
449
- }
450
- var ANYCODE_DIR = path3.join(os.homedir(), ".anycode");
451
- var DB_PATH = path3.join(ANYCODE_DIR, "data.db");
452
- var userSettings = (() => {
453
- try {
454
- return JSON.parse(fs4.readFileSync(path3.join(ANYCODE_DIR, "settings.json"), "utf-8"));
455
- } catch {
456
- return {};
457
- }
458
- })();
459
- var PROVIDER = process.env.PROVIDER ?? "anthropic";
460
- var MODEL = process.env.MODEL ?? userSettings.MODEL ?? "claude-sonnet-4-20250514";
461
- var API_KEY = process.env.API_KEY ?? userSettings.API_KEY;
462
- var BASE_URL = process.env.BASE_URL ?? userSettings.BASE_URL;
463
- var PORT = parseInt(process.env.PORT ?? "3210", 10);
464
- var PREVIEW_PORT = parseInt(process.env.PREVIEW_PORT ?? String(PORT + 1), 10);
465
- if (!API_KEY) {
466
- console.error("\u274C Missing API_KEY");
467
- console.error("Run 'anycode start' to configure, or set API_KEY env var.");
468
- process.exit(1);
469
- }
470
- process.on("uncaughtException", (err) => {
471
- console.error("\u26A0 Uncaught exception:", err.message);
472
- });
473
- process.on("unhandledRejection", (reason) => {
474
- console.error("\u26A0 Unhandled rejection:", reason instanceof Error ? reason.message : reason);
475
- });
476
- function makePaths() {
477
- const dataPath = path3.join(ANYCODE_DIR, "data");
478
- fs4.mkdirSync(dataPath, { recursive: true });
479
- return dataPath;
480
- }
481
- var NodeShellProvider = class {
482
- platform = process.platform;
483
- shell;
484
- constructor() {
485
- const s = process.env.SHELL;
486
- const BLACKLIST = /* @__PURE__ */ new Set(["fish", "nu"]);
487
- if (s && !BLACKLIST.has(path3.basename(s))) {
488
- this.shell = s;
489
- } else {
490
- this.shell = process.platform === "darwin" ? "/bin/zsh" : "/bin/sh";
491
- }
492
- }
493
- spawn(command, opts) {
494
- return cpSpawn(command, {
495
- shell: this.shell,
496
- cwd: opts.cwd,
497
- env: { ...process.env, ...opts.env },
498
- stdio: ["ignore", "pipe", "pipe"],
499
- detached: true
500
- });
501
- }
502
- async kill(proc, opts) {
503
- const pid = proc.pid;
504
- if (!pid || opts?.exited?.()) return;
505
- const SIGKILL_TIMEOUT_MS = 200;
506
- try {
507
- process.kill(-pid, "SIGTERM");
508
- await new Promise((r) => setTimeout(r, SIGKILL_TIMEOUT_MS));
509
- if (!opts?.exited?.()) process.kill(-pid, "SIGKILL");
510
- } catch {
511
- proc.kill("SIGTERM");
512
- await new Promise((r) => setTimeout(r, SIGKILL_TIMEOUT_MS));
513
- if (!opts?.exited?.()) proc.kill("SIGKILL");
514
- }
515
- }
516
- };
517
- var NodeGitProvider = class {
518
- async run(args, opts = {}) {
519
- return new Promise((resolve) => {
520
- execFile("git", args, {
521
- cwd: opts.cwd,
522
- env: opts.env ? { ...process.env, ...opts.env } : void 0,
523
- maxBuffer: 50 * 1024 * 1024,
524
- encoding: "buffer"
525
- }, (error, stdout, stderr) => {
526
- const stdoutBuf = Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout ?? "");
527
- const stderrBuf = Buffer.isBuffer(stderr) ? stderr : Buffer.from(stderr ?? "");
528
- resolve({
529
- exitCode: error ? error.code ?? 1 : 0,
530
- text: () => stdoutBuf.toString(),
531
- stdout: new Uint8Array(stdoutBuf),
532
- stderr: new Uint8Array(stderrBuf)
533
- });
534
- });
535
- });
536
- }
537
- };
538
- var sessions = /* @__PURE__ */ new Map();
539
- var PROVIDER_ID = PROVIDER;
540
- var sharedStorage;
541
- var db;
542
- function createAgentConfig(directory, sessionId, terminal, preview) {
543
- return {
544
- directory,
545
- fs: new NodeFS(),
546
- search: new NodeSearchProvider(),
547
- storage: sharedStorage,
548
- shell: new NodeShellProvider(),
549
- git: new NodeGitProvider(),
550
- dataPath: makePaths(),
551
- ...sessionId ? { sessionId } : {},
552
- ...terminal ? { terminal } : {},
553
- ...preview ? { preview } : {},
554
- provider: {
555
- id: PROVIDER_ID,
556
- apiKey: API_KEY,
557
- model: MODEL,
558
- ...BASE_URL ? { baseUrl: BASE_URL } : {}
559
- },
560
- settings: userSettings,
561
- config: {
562
- model: `${PROVIDER_ID}/${MODEL}`,
563
- small_model: `${PROVIDER_ID}/${MODEL}`,
564
- provider: {
565
- [PROVIDER_ID]: {
566
- // Use @ai-sdk/anthropic for Claude models — it natively handles
567
- // thinking blocks and signatures. Other models use openai-compatible.
568
- npm: /claude/i.test(MODEL) ? "@ai-sdk/anthropic" : "@ai-sdk/openai-compatible",
569
- ...BASE_URL ? { api: BASE_URL } : {},
570
- options: {
571
- apiKey: API_KEY,
572
- ...BASE_URL ? { baseURL: BASE_URL } : {}
573
- },
574
- models: {
575
- [MODEL]: {
576
- name: MODEL,
577
- attachment: true,
578
- tool_call: true,
579
- temperature: true,
580
- reasoning: true,
581
- limit: { context: 2e5, output: 32e3 },
582
- cost: { input: 0, output: 0 }
583
- }
584
- }
585
- }
586
- }
587
- }
588
- };
589
- }
590
- function registerSession(id, agent, directory, createdAt) {
591
- const entry = { id, agent, directory, createdAt };
592
- sessions.set(id, entry);
593
- agent.on("directory.set", (data) => {
594
- const dir = data.directory;
595
- entry.directory = dir;
596
- try {
597
- agent.setWorkingDirectory(dir);
598
- } catch {
599
- }
600
- db.update("user_session", { op: "eq", field: "session_id", value: id }, { directory: dir });
601
- console.log(`\u{1F4C2} Session ${id} directory set to: ${dir}`);
602
- pushState(id);
603
- watchDirectory(id, dir);
604
- });
605
- let pushTimer = null;
606
- agent.on("file.edited", () => {
607
- if (!entry.directory) return;
608
- if (pushTimer) clearTimeout(pushTimer);
609
- pushTimer = setTimeout(() => pushState(id), 300);
610
- });
611
- return entry;
612
- }
613
- async function resumeSession(row) {
614
- const sessionId = row.session_id;
615
- const cached = sessions.get(sessionId);
616
- if (cached) return cached;
617
- const dir = row.directory || "";
618
- const tp = getOrCreateTerminalProvider(sessionId);
619
- const pp = getOrCreatePreviewProvider(sessionId);
620
- const agent = new CodeAgent(createAgentConfig(dir, sessionId, tp, pp));
621
- await agent.init();
622
- const entry = registerSession(sessionId, agent, dir, row.time_created);
623
- if (dir) {
624
- try {
625
- agent.setWorkingDirectory(dir);
626
- } catch {
627
- }
628
- watchDirectory(sessionId, dir);
629
- }
630
- console.log(`\u267B\uFE0F Session ${sessionId} resumed`);
631
- return entry;
632
- }
633
- async function createNewWindow(userId, isDefault = false) {
634
- const tempId = `temp-${Date.now()}`;
635
- const tp = getOrCreateTerminalProvider(tempId);
636
- const pp = getOrCreatePreviewProvider(tempId);
637
- const agent = new CodeAgent(createAgentConfig("", void 0, tp, pp));
638
- await agent.init();
639
- const sessionId = agent.sessionId;
640
- const now = Date.now();
641
- terminalProviders.delete(tempId);
642
- terminalProviders.set(sessionId, tp);
643
- previewProviders.delete(tempId);
644
- previewProviders.set(sessionId, pp);
645
- tp.sessionId = sessionId;
646
- pp.sessionId = sessionId;
647
- const entry = registerSession(sessionId, agent, "", now);
648
- db.insert("user_session", {
649
- user_id: userId,
650
- session_id: sessionId,
651
- directory: "",
652
- time_created: now,
653
- is_default: isDefault ? 1 : 0
654
- });
655
- console.log(`\u2705 Window ${sessionId} created for user ${userId}${isDefault ? " (default)" : ""}`);
656
- return entry;
657
- }
658
- async function getOrCreateSession(userId) {
659
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
660
- const defaultRow = rows.find((r) => r.is_default === 1) || rows[0];
661
- if (defaultRow) {
662
- if (defaultRow.is_default !== 1) {
663
- db.update("user_session", { op: "eq", field: "session_id", value: defaultRow.session_id }, { is_default: 1 });
664
- }
665
- return resumeSession(defaultRow);
666
- }
667
- return createNewWindow(userId, true);
668
- }
669
- async function getAllWindows(userId) {
670
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
671
- const entries = [];
672
- for (const row of rows) {
673
- entries.push(await resumeSession(row));
674
- }
675
- return entries;
676
- }
677
- function deleteWindow(sessionId) {
678
- const row = db.findOne("user_session", { op: "eq", field: "session_id", value: sessionId });
679
- if (!row) return false;
680
- if (row.is_default === 1) return false;
681
- const session = sessions.get(sessionId);
682
- if (session) {
683
- sessions.delete(sessionId);
684
- }
685
- const tp = terminalProviders.get(sessionId);
686
- if (tp && tp.exists()) {
687
- try {
688
- tp.destroy();
689
- } catch {
690
- }
691
- }
692
- terminalProviders.delete(sessionId);
693
- db.remove("user_session", { op: "eq", field: "session_id", value: sessionId });
694
- console.log(`\u{1F5D1} Window ${sessionId} deleted`);
695
- return true;
696
- }
697
- function getSession(id) {
698
- return sessions.get(id);
699
- }
700
- var IGNORE = /* @__PURE__ */ new Set([".git", "node_modules", ".next", "dist", ".opencode", ".anycode", ".any-code", "__pycache__", ".venv", ".DS_Store"]);
701
- async function listDir(dir) {
702
- if (!dir) return [];
703
- try {
704
- const entries = await fsPromises.readdir(dir, { withFileTypes: true });
705
- return entries.filter((e) => (!e.name.startsWith(".") || e.name === ".gitignore") && !IGNORE.has(e.name)).sort((a, b) => {
706
- const ad = a.isDirectory() ? 0 : 1, bd = b.isDirectory() ? 0 : 1;
707
- return ad !== bd ? ad - bd : a.name.localeCompare(b.name);
708
- }).map((e) => ({ name: e.name, type: e.isDirectory() ? "dir" : "file" }));
709
- } catch {
710
- return [];
711
- }
712
- }
713
- var gitProvider = new NodeGitProvider();
714
- async function getGitChanges(dir) {
715
- if (!dir) return [];
716
- try {
717
- const result = await gitProvider.run(["status", "--porcelain", "-uall"], { cwd: dir });
718
- if (result.exitCode !== 0) return [];
719
- const text = result.text();
720
- if (!text.trim()) return [];
721
- return text.split("\n").filter((line) => line.trim()).map((line) => {
722
- const xy = line.slice(0, 2);
723
- const file = line.slice(3);
724
- let status = xy.trim().charAt(0) || "?";
725
- if (xy[0] === "?" || xy[1] === "?") status = "?";
726
- return { file, status };
727
- });
728
- } catch {
729
- return [];
730
- }
731
- }
732
- var sessionClients = /* @__PURE__ */ new Map();
733
- var sessionChatAbort = /* @__PURE__ */ new Map();
734
- var lastStateJson = /* @__PURE__ */ new Map();
735
- function getSessionClients(sessionId) {
736
- let set = sessionClients.get(sessionId);
737
- if (!set) {
738
- set = /* @__PURE__ */ new Set();
739
- sessionClients.set(sessionId, set);
740
- }
741
- return set;
742
- }
743
- function removeClient(sessionId, client) {
744
- const clients = sessionClients.get(sessionId);
745
- if (clients) {
746
- clients.delete(client);
747
- if (clients.size === 0) sessionClients.delete(sessionId);
748
- }
749
- }
750
- function broadcast(sessionId, data) {
751
- const clients = sessionClients.get(sessionId);
752
- if (!clients) return;
753
- const json = JSON.stringify(data);
754
- for (const c of clients) {
755
- if (c.readyState === WS.OPEN) c.send(json);
756
- }
757
- }
758
- var PollingClient = class {
759
- readyState = 1;
760
- // OPEN
761
- id;
762
- sessionId;
763
- lastActivity;
764
- queue = [];
765
- pendingRes = null;
766
- pollTimer = null;
767
- constructor(id, sessionId) {
768
- this.id = id;
769
- this.sessionId = sessionId;
770
- this.lastActivity = Date.now();
771
- }
772
- /** Called by broadcast — queues a JSON string for the next poll */
773
- send(data) {
774
- this.queue.push(data);
775
- this.tryFlush();
776
- }
777
- /** Attach a long-poll response. Flushes immediately if messages are queued. */
778
- hold(res, timeoutMs = 3e4) {
779
- this.lastActivity = Date.now();
780
- this.abortPoll();
781
- this.pendingRes = res;
782
- this.pollTimer = setTimeout(() => {
783
- this.pollTimer = null;
784
- this.flush();
785
- }, timeoutMs);
786
- res.on("close", () => {
787
- if (this.pendingRes === res) {
788
- if (this.pollTimer) {
789
- clearTimeout(this.pollTimer);
790
- this.pollTimer = null;
791
- }
792
- this.pendingRes = null;
793
- }
794
- });
795
- this.tryFlush();
796
- }
797
- close() {
798
- this.readyState = 3;
799
- this.abortPoll();
800
- this.queue = [];
801
- }
802
- tryFlush() {
803
- if (!this.pendingRes || this.queue.length === 0) return;
804
- this.flush();
805
- }
806
- flush() {
807
- if (!this.pendingRes) return;
808
- if (this.pollTimer) {
809
- clearTimeout(this.pollTimer);
810
- this.pollTimer = null;
811
- }
812
- const messages = this.queue.splice(0);
813
- this.pendingRes.writeHead(200, { "Content-Type": "application/json" });
814
- this.pendingRes.end(`[${messages.join(",")}]`);
815
- this.pendingRes = null;
816
- }
817
- abortPoll() {
818
- if (this.pollTimer) {
819
- clearTimeout(this.pollTimer);
820
- this.pollTimer = null;
821
- }
822
- if (this.pendingRes) {
823
- this.pendingRes.writeHead(200, { "Content-Type": "application/json" });
824
- this.pendingRes.end("[]");
825
- this.pendingRes = null;
826
- }
827
- }
828
- };
829
- var pollingClients = /* @__PURE__ */ new Map();
830
- async function handleClientMessage(sessionId, client, msg) {
831
- if (msg.type === "ls") {
832
- const session = getSession(sessionId);
833
- const dir = session.directory;
834
- if (!dir) return;
835
- const target = path3.resolve(dir, msg.path || "");
836
- if (!target.startsWith(path3.resolve(dir))) return;
837
- const entries = await listDir(target);
838
- client.send(JSON.stringify({ type: "ls", path: msg.path || "", entries }));
839
- }
840
- if (msg.type === "readFile") {
841
- const session = getSession(sessionId);
842
- const dir = session.directory;
843
- if (!dir) return;
844
- const target = path3.resolve(dir, msg.path || "");
845
- if (!target.startsWith(path3.resolve(dir))) return;
846
- try {
847
- const content = await fsPromises.readFile(target, "utf-8");
848
- client.send(JSON.stringify({ type: "fileContent", path: msg.path || "", content }));
849
- } catch {
850
- client.send(JSON.stringify({ type: "fileContent", path: msg.path || "", content: null, error: "\u8BFB\u53D6\u5931\u8D25" }));
851
- }
852
- }
853
- if (msg.type === "chat.send") {
854
- const session = getSession(sessionId);
855
- if (!session) return;
856
- const { message, fileContext } = msg;
857
- let effectiveMessage = message;
858
- if (fileContext?.file && Array.isArray(fileContext.lines) && fileContext.lines.length > 0) {
859
- const lines = fileContext.lines;
860
- const start = lines[0];
861
- const end = lines[lines.length - 1];
862
- const range = start === end ? `L${start}` : `L${start}\u2013${end}`;
863
- effectiveMessage = `[\u7528\u6237\u9009\u4E2D\u4E86\u6587\u4EF6 ${fileContext.file} \u7684 ${range} \u884C]
864
-
865
- ${message}`;
866
- }
867
- const contextLabel = fileContext ? `[${fileContext.file} L${fileContext.lines[0]}\u2013${fileContext.lines[fileContext.lines.length - 1]}]
868
- ${message}` : message;
869
- broadcast(sessionId, { type: "chat.userMessage", text: contextLabel });
870
- let aborted = false;
871
- sessionChatAbort.set(sessionId, () => {
872
- aborted = true;
873
- });
874
- try {
875
- for await (const event of session.agent.chat(effectiveMessage)) {
876
- if (aborted) break;
877
- broadcast(sessionId, { type: "chat.event", event });
878
- }
879
- } catch (err) {
880
- broadcast(sessionId, { type: "chat.event", event: { type: "error", error: err.message } });
881
- }
882
- sessionChatAbort.delete(sessionId);
883
- broadcast(sessionId, { type: "chat.done" });
884
- }
885
- if (msg.type === "chat.stop") {
886
- sessionChatAbort.get(sessionId)?.();
887
- }
888
- }
889
- var watchers = /* @__PURE__ */ new Map();
890
- function watchDirectory(sessionId, dir) {
891
- const existing = watchers.get(sessionId);
892
- if (existing) existing.close();
893
- let timer = null;
894
- const debouncedPush = () => {
895
- if (timer) clearTimeout(timer);
896
- timer = setTimeout(() => pushState(sessionId), 500);
897
- };
898
- try {
899
- const watcher = fs4.watch(dir, { recursive: true }, (eventType, filename) => {
900
- if (filename && (filename.startsWith(".git/") || filename.startsWith("node_modules/"))) return;
901
- debouncedPush();
902
- });
903
- watchers.set(sessionId, watcher);
904
- console.log(`\u{1F441} Watching directory: ${dir}`);
905
- } catch (err) {
906
- console.error(`\u274C fs.watch failed for ${dir}:`, err);
907
- }
908
- }
909
- async function buildState(sessionId) {
910
- const session = getSession(sessionId);
911
- if (!session) return null;
912
- const dir = session.directory;
913
- const changes = dir ? await getGitChanges(dir) : [];
914
- const topLevel = dir ? await listDir(dir) : [];
915
- return {
916
- type: "state",
917
- directory: dir,
918
- changes,
919
- topLevel,
920
- previewPort: previewSessionId === sessionId && previewTarget ? PREVIEW_PORT : null
921
- };
922
- }
923
- async function pushState(sessionId) {
924
- try {
925
- const payload = await buildState(sessionId);
926
- if (!payload) return;
927
- const json = JSON.stringify(payload);
928
- const prev = lastStateJson.get(sessionId);
929
- if (prev === json) return;
930
- lastStateJson.set(sessionId, json);
931
- const clientCount = sessionClients.get(sessionId)?.size ?? 0;
932
- console.log(`\u{1F4E4} pushState(${sessionId}): dir="${payload.directory}", topLevel=${payload.topLevel.length} entries, changes=${payload.changes.length}, clients=${clientCount}`);
933
- const clients = sessionClients.get(sessionId);
934
- if (!clients) return;
935
- for (const c of clients) {
936
- if (c.readyState === WS.OPEN) c.send(json);
937
- }
938
- } catch (err) {
939
- console.error(`\u274C pushState error:`, err);
940
- }
941
- }
942
- async function sendStateTo(sessionId, client) {
943
- try {
944
- let json = lastStateJson.get(sessionId);
945
- if (!json) {
946
- const payload = await buildState(sessionId);
947
- if (!payload) return;
948
- json = JSON.stringify(payload);
949
- lastStateJson.set(sessionId, json);
950
- }
951
- if (client.readyState === WS.OPEN) client.send(json);
952
- } catch (err) {
953
- console.error(`\u274C sendStateTo error:`, err);
954
- }
955
- }
956
- function stripAnsi(s) {
957
- return s.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*\x07)/g, "");
958
- }
959
- var MAX_BUFFER_LINES = 5e3;
960
- var MAX_RAW_BUFFER = 200;
961
- var NodeTerminalProvider = class {
962
- proc = null;
963
- lines = [];
964
- currentLine = "";
965
- rawBuffer = [];
966
- wsClients = /* @__PURE__ */ new Set();
967
- sessionId;
968
- constructor(sessionId) {
969
- this.sessionId = sessionId;
970
- }
971
- exists() {
972
- return this.proc !== null;
973
- }
974
- create() {
975
- if (this.proc) throw new Error("Terminal already exists. Destroy it first.");
976
- const session = getSession(this.sessionId);
977
- const cwd = session?.directory || os.homedir();
978
- const shell = process.env.SHELL || (process.platform === "win32" ? "powershell.exe" : "/bin/bash");
979
- if (!fs4.existsSync(cwd)) {
980
- throw new Error(`Terminal cwd does not exist: ${cwd}`);
981
- }
982
- console.log(`\u{1F5A5} Terminal creating: shell=${shell}, cwd=${cwd}, sessionId=${this.sessionId}`);
983
- this.lines = [];
984
- this.currentLine = "";
985
- this.rawBuffer = [];
986
- const env = {};
987
- for (const [k, v] of Object.entries(process.env)) {
988
- if (v !== void 0) env[k] = v;
989
- }
990
- env.PROMPT_EOL_MARK = "";
991
- env.CLICOLOR = "1";
992
- env.CLICOLOR_FORCE = "1";
993
- env.LSCOLORS = "GxFxCxDxBxegedabagaced";
994
- const proc = pty.spawn(shell, [], {
995
- name: "xterm-256color",
996
- cols: 80,
997
- rows: 24,
998
- cwd,
999
- env
1000
- });
1001
- console.log(`\u{1F5A5} Terminal created for session ${this.sessionId} (pid ${proc.pid}, cwd ${cwd})`);
1002
- proc.onData((data) => {
1003
- this.appendToBuffer(data);
1004
- this.rawBuffer.push(data);
1005
- if (this.rawBuffer.length > MAX_RAW_BUFFER) {
1006
- this.rawBuffer.splice(0, this.rawBuffer.length - MAX_RAW_BUFFER);
1007
- }
1008
- for (const ws of this.wsClients) {
1009
- if (ws.readyState === WS.OPEN) {
1010
- ws.send(JSON.stringify({ type: "terminal.output", data }));
1011
- }
1012
- }
1013
- });
1014
- proc.onExit(({ exitCode }) => {
1015
- console.log(`\u{1F5A5} Terminal exited for session ${this.sessionId} (code ${exitCode})`);
1016
- this.proc = null;
1017
- for (const ws of this.wsClients) {
1018
- if (ws.readyState === WS.OPEN) {
1019
- ws.send(JSON.stringify({ type: "terminal.exited", exitCode }));
1020
- ws.send(JSON.stringify({ type: "terminal.none" }));
1021
- }
1022
- }
1023
- });
1024
- this.proc = proc;
1025
- for (const ws of this.wsClients) {
1026
- if (ws.readyState === WS.OPEN) {
1027
- ws.send(JSON.stringify({ type: "terminal.ready" }));
1028
- }
1029
- }
1030
- }
1031
- destroy() {
1032
- if (!this.proc) throw new Error("No terminal exists.");
1033
- console.log(`\u{1F5A5} Terminal destroyed for session ${this.sessionId}`);
1034
- this.proc.kill();
1035
- this.proc = null;
1036
- this.lines = [];
1037
- this.currentLine = "";
1038
- this.rawBuffer = [];
1039
- for (const ws of this.wsClients) {
1040
- if (ws.readyState === WS.OPEN) {
1041
- ws.send(JSON.stringify({ type: "terminal.none" }));
1042
- }
1043
- }
1044
- }
1045
- write(data) {
1046
- if (!this.proc) throw new Error("No terminal exists.");
1047
- this.proc.write(data);
1048
- }
1049
- read(lineCount) {
1050
- if (!this.proc) throw new Error("No terminal exists.");
1051
- const allLines = this.currentLine ? [...this.lines, this.currentLine] : [...this.lines];
1052
- const start = Math.max(0, allLines.length - lineCount);
1053
- return allLines.slice(start).join("\n");
1054
- }
1055
- /** Resize the PTY (called from WS client) */
1056
- resize(cols, rows) {
1057
- if (this.proc && cols > 0 && rows > 0) {
1058
- this.proc.resize(cols, rows);
1059
- }
1060
- }
1061
- /** Get buffered raw output for replay */
1062
- getRawBuffer() {
1063
- return this.rawBuffer;
1064
- }
1065
- /** Register a WebSocket client for live output */
1066
- addClient(ws) {
1067
- this.wsClients.add(ws);
1068
- }
1069
- /** Unregister a WebSocket client */
1070
- removeClient(ws) {
1071
- this.wsClients.delete(ws);
1072
- }
1073
- /** Handle input from a WebSocket client */
1074
- handleWsMessage(raw) {
1075
- try {
1076
- const msg = JSON.parse(raw.toString());
1077
- if (msg.type === "terminal.input" && this.proc) {
1078
- this.proc.write(msg.data);
1079
- } else if (msg.type === "terminal.resize") {
1080
- this.resize(msg.cols, msg.rows);
1081
- }
1082
- } catch {
1083
- }
1084
- }
1085
- appendToBuffer(data) {
1086
- const clean = stripAnsi(data);
1087
- const lines = clean.split("\n");
1088
- for (let i = 0; i < lines.length; i++) {
1089
- const segment = lines[i];
1090
- if (i === 0) {
1091
- this.handleCR(segment);
1092
- } else {
1093
- this.lines.push(this.currentLine);
1094
- this.currentLine = "";
1095
- this.handleCR(segment);
1096
- if (this.lines.length > MAX_BUFFER_LINES) {
1097
- this.lines.splice(0, this.lines.length - MAX_BUFFER_LINES);
1098
- }
1099
- }
1100
- }
1101
- }
1102
- /** Handle \r within a segment: text after the last \r overwrites from column 0 */
1103
- handleCR(segment) {
1104
- const crParts = segment.split("\r");
1105
- if (crParts.length === 1) {
1106
- this.currentLine += segment;
1107
- } else {
1108
- for (const part of crParts) {
1109
- if (part === "") continue;
1110
- if (part.length >= this.currentLine.length) {
1111
- this.currentLine = part;
1112
- } else {
1113
- this.currentLine = part + this.currentLine.slice(part.length);
1114
- }
1115
- }
1116
- }
1117
- }
1118
- };
1119
- var terminalProviders = /* @__PURE__ */ new Map();
1120
- function getOrCreateTerminalProvider(sessionId) {
1121
- let tp = terminalProviders.get(sessionId);
1122
- if (!tp) {
1123
- tp = new NodeTerminalProvider(sessionId);
1124
- terminalProviders.set(sessionId, tp);
1125
- }
1126
- return tp;
1127
- }
1128
- function handleTerminalWs(ws, sessionId) {
1129
- const tp = getOrCreateTerminalProvider(sessionId);
1130
- tp.addClient(ws);
1131
- if (tp.exists()) {
1132
- ws.send(JSON.stringify({ type: "terminal.ready" }));
1133
- for (const chunk of tp.getRawBuffer()) {
1134
- ws.send(JSON.stringify({ type: "terminal.output", data: chunk }));
1135
- }
1136
- } else {
1137
- ws.send(JSON.stringify({ type: "terminal.none" }));
1138
- }
1139
- ws.on("message", (raw) => tp.handleWsMessage(raw));
1140
- ws.on("close", () => {
1141
- tp.removeClient(ws);
1142
- console.log(`\u{1F5A5} Terminal WS closed for session ${sessionId}`);
1143
- });
1144
- }
1145
- var previewTarget = null;
1146
- var previewSessionId = null;
1147
- var NodePreviewProvider = class {
1148
- sessionId;
1149
- constructor(sessionId) {
1150
- this.sessionId = sessionId;
1151
- }
1152
- setPreviewTarget(forwardedLocalUrl) {
1153
- previewTarget = forwardedLocalUrl.replace(/\/+$/, "");
1154
- previewSessionId = this.sessionId;
1155
- console.log(`\u{1F517} Preview proxy: :${PREVIEW_PORT} \u2192 ${previewTarget} (session ${this.sessionId})`);
1156
- broadcast(this.sessionId, {
1157
- type: "preview",
1158
- port: PREVIEW_PORT
1159
- });
1160
- }
1161
- };
1162
- var previewProviders = /* @__PURE__ */ new Map();
1163
- function getOrCreatePreviewProvider(sessionId) {
1164
- let pp = previewProviders.get(sessionId);
1165
- if (!pp) {
1166
- pp = new NodePreviewProvider(sessionId);
1167
- previewProviders.set(sessionId, pp);
1168
- }
1169
- return pp;
1170
- }
1171
- var previewServer = http.createServer((req, res) => {
1172
- res.setHeader("Access-Control-Allow-Origin", "*");
1173
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
1174
- res.setHeader("Access-Control-Allow-Headers", "*");
1175
- if (req.method === "OPTIONS") {
1176
- res.writeHead(204);
1177
- res.end();
1178
- return;
1179
- }
1180
- if (!previewTarget) {
1181
- res.writeHead(502, { "Content-Type": "text/plain" });
1182
- res.end("No preview target configured");
1183
- return;
1184
- }
1185
- try {
1186
- const targetUrl = previewTarget + (req.url || "/");
1187
- const parsed = new URL(targetUrl);
1188
- const options = {
1189
- hostname: parsed.hostname,
1190
- port: parsed.port,
1191
- path: parsed.pathname + parsed.search,
1192
- method: req.method,
1193
- headers: { ...req.headers, host: parsed.host }
1194
- };
1195
- const proxyReq = http.request(options, (proxyRes) => {
1196
- res.writeHead(proxyRes.statusCode || 502, proxyRes.headers);
1197
- proxyRes.pipe(res);
1198
- });
1199
- proxyReq.on("error", (err) => {
1200
- if (!res.headersSent) res.writeHead(502, { "Content-Type": "text/plain" });
1201
- res.end(`Preview proxy error: ${err.message}`);
1202
- });
1203
- req.pipe(proxyReq);
1204
- } catch (err) {
1205
- res.writeHead(502, { "Content-Type": "text/plain" });
1206
- res.end(`Invalid proxy target: ${err.message}`);
1207
- }
1208
- });
1209
- previewServer.on("upgrade", (req, socket, head) => {
1210
- if (!previewTarget) {
1211
- socket.destroy();
1212
- return;
1213
- }
1214
- try {
1215
- const parsed = new URL(previewTarget);
1216
- const targetWs = `ws://${parsed.hostname}:${parsed.port}${req.url || "/"}`;
1217
- const wsTarget = new URL(targetWs);
1218
- const options = {
1219
- hostname: wsTarget.hostname,
1220
- port: wsTarget.port,
1221
- path: wsTarget.pathname + wsTarget.search,
1222
- method: "GET",
1223
- headers: { ...req.headers, host: wsTarget.host }
1224
- };
1225
- const proxyReq = http.request(options);
1226
- proxyReq.on("upgrade", (_proxyRes, proxySocket, proxyHead) => {
1227
- socket.write(
1228
- "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n" + Object.entries(_proxyRes.headers).filter(([k]) => !["upgrade", "connection"].includes(k.toLowerCase())).map(([k, v]) => `${k}: ${v}`).join("\r\n") + "\r\n\r\n"
1229
- );
1230
- if (proxyHead.length > 0) socket.write(proxyHead);
1231
- proxySocket.pipe(socket);
1232
- socket.pipe(proxySocket);
1233
- });
1234
- proxyReq.on("error", () => socket.destroy());
1235
- socket.on("error", () => proxyReq.destroy());
1236
- proxyReq.end();
1237
- } catch {
1238
- socket.destroy();
1239
- }
1240
- });
1241
- function adminHTML() {
1242
- return (
1243
- /* html */
1244
- `<!DOCTYPE html>
1245
- <html lang="en">
1246
- <head>
1247
- <meta charset="utf-8">
1248
- <meta name="viewport" content="width=device-width, initial-scale=1">
1249
- <title>AnyCode Server Admin</title>
1250
- <style>
1251
- *{box-sizing:border-box;margin:0;padding:0}
1252
- :root{--bg:#1a1b26;--surface:#24283b;--border:#3b4261;--text:#a9b1d6;
1253
- --bright:#c0caf5;--accent:#7aa2f7;--green:#9ece6a;--red:#f7768e;--yellow:#e0af68;
1254
- --mono:'JetBrains Mono','Fira Code','SF Mono',monospace;
1255
- --sans:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
1256
- body{font-family:var(--sans);background:var(--bg);color:var(--text);
1257
- min-height:100vh;display:flex;justify-content:center;padding:24px 16px}
1258
- .container{width:100%;max-width:520px}
1259
- h1{font-size:18px;color:var(--bright);margin-bottom:16px;display:flex;align-items:center;gap:8px}
1260
- h1 .dot{width:10px;height:10px;border-radius:50%;background:var(--green);
1261
- animation:pulse 2s infinite}
1262
- @keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
1263
- .card{background:var(--surface);border:1px solid var(--border);border-radius:8px;
1264
- padding:14px;margin-bottom:10px}
1265
- .card h2{font-size:11px;text-transform:uppercase;letter-spacing:1px;
1266
- color:var(--accent);margin-bottom:10px;font-weight:600}
1267
- .row{display:flex;justify-content:space-between;align-items:center;
1268
- padding:5px 0;border-bottom:1px solid rgba(59,66,97,0.3);font-size:12px}
1269
- .row:last-child{border-bottom:none}
1270
- .label{color:var(--text)}
1271
- .value{color:var(--bright);font-family:var(--mono);font-size:11px}
1272
- .value.green{color:var(--green)} .value.yellow{color:var(--yellow)} .value.red{color:var(--red)}
1273
- .sessions{max-height:200px;overflow-y:auto}
1274
- .session-item{padding:6px 8px;border-bottom:1px solid rgba(59,66,97,0.3);font-size:11px;
1275
- display:flex;justify-content:space-between;align-items:center;cursor:pointer}
1276
- .session-item:hover{background:rgba(122,162,247,0.08)}
1277
- .session-title{color:var(--bright);max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1278
- .session-status{font-family:var(--mono);font-size:10px;padding:1px 6px;border-radius:3px}
1279
- .session-status.idle{background:rgba(158,206,106,0.15);color:var(--green)}
1280
- .session-status.busy{background:rgba(122,162,247,0.15);color:var(--accent);animation:pulse 1.5s infinite}
1281
- .errors{max-height:120px;overflow-y:auto}
1282
- .error-item{padding:4px 0;border-bottom:1px solid rgba(59,66,97,0.2);font-size:10px;color:var(--red)}
1283
- .error-time{color:var(--text);font-family:var(--mono);margin-right:6px}
1284
- .footer{text-align:center;margin-top:16px;font-size:10px;color:rgba(169,177,214,0.3)}
1285
- </style>
1286
- </head>
1287
- <body>
1288
- <div class="container">
1289
- <h1><span class="dot"></span> AnyCode Server</h1>
1290
- <div class="card">
1291
- <h2>\u2699 Configuration</h2>
1292
- <div class="row"><span class="label">Provider</span><span class="value">${PROVIDER}</span></div>
1293
- <div class="row"><span class="label">Model</span><span class="value">${MODEL}</span></div>
1294
- <div class="row"><span class="label">Port</span><span class="value">${PORT}</span></div>
1295
- <div class="row"><span class="label">Sessions</span><span class="value" id="session-count">0</span></div>
1296
- </div>
1297
- <div class="card">
1298
- <h2>\u{1F4CA} Runtime Stats</h2>
1299
- <div class="row"><span class="label">Uptime</span><span class="value green" id="uptime">\u2014</span></div>
1300
- <div class="row"><span class="label">Messages</span><span class="value" id="msg-count">0</span></div>
1301
- <div class="row"><span class="label">Tokens (in/out/reason)</span><span class="value" id="tokens">\u2014</span></div>
1302
- <div class="row"><span class="label">Total Cost</span><span class="value yellow" id="cost">$0</span></div>
1303
- <div class="row"><span class="label">Active Session</span><span class="value" id="session">\u2014</span></div>
1304
- </div>
1305
- <div class="card" id="errors-card" style="display:none">
1306
- <h2>\u26A0 Recent Errors</h2>
1307
- <div class="errors" id="errors"></div>
1308
- </div>
1309
- <div class="footer">any-code-server v0.0.1</div>
1310
- </div>
1311
- <script>
1312
- function fmtK(n){return n>=1000?(n/1000).toFixed(1)+'k':String(n)}
1313
- function fmtDur(ms){
1314
- const h=Math.floor(ms/3600000),m=Math.floor((ms%3600000)/60000),s=Math.floor((ms%60000)/1000)
1315
- return h>0?h+'h '+m+'m '+s+'s':m>0?m+'m '+s+'s':s+'s'
1316
- }
1317
- async function refresh(){
1318
- try{
1319
- const r=await fetch('/api/status');const d=await r.json()
1320
- document.getElementById('uptime').textContent=fmtDur(d.stats.uptimeMs)
1321
- document.getElementById('msg-count').textContent=d.stats.totalMessages
1322
- const t=d.stats.totalTokens
1323
- document.getElementById('tokens').textContent=fmtK(t.input)+' / '+fmtK(t.output)+' / '+fmtK(t.reasoning)
1324
- document.getElementById('cost').textContent='$'+d.stats.totalCost.toFixed(4)
1325
- document.getElementById('session').textContent=d.sessionId||'none'
1326
- const ec=document.getElementById('errors-card'),el=document.getElementById('errors')
1327
- if(d.stats.errors.length>0){
1328
- ec.style.display='block'
1329
- el.innerHTML=d.stats.errors.map(e=>'<div class="error-item"><span class="error-time">'+new Date(e.time).toLocaleTimeString()+'</span>'+e.message.slice(0,80)+'</div>').join('')
1330
- }else{ec.style.display='none'}
1331
- }catch(e){}
1332
- }
1333
- refresh();setInterval(refresh,2000)
1334
- </script>
1335
- </body></html>`
1336
- );
1337
- }
1338
- var MIME_TYPES = {
1339
- ".html": "text/html",
1340
- ".css": "text/css",
1341
- ".js": "application/javascript",
1342
- ".json": "application/json",
1343
- ".png": "image/png",
1344
- ".jpg": "image/jpeg",
1345
- ".svg": "image/svg+xml",
1346
- ".ico": "image/x-icon",
1347
- ".woff2": "font/woff2",
1348
- ".woff": "font/woff",
1349
- ".ttf": "font/ttf"
1350
- };
1351
- var __filename = fileURLToPath(import.meta.url);
1352
- var __dirname = path3.dirname(__filename);
1353
- var APP_DIST = fs4.existsSync(path3.resolve(__dirname, "app")) ? path3.resolve(__dirname, "app") : path3.resolve(__dirname, "../../app/dist");
1354
- function serveStatic(req, res) {
1355
- const url = req.url || "/";
1356
- const filePath = path3.join(APP_DIST, url);
1357
- if (fs4.existsSync(filePath) && fs4.statSync(filePath).isFile()) {
1358
- const ext = path3.extname(filePath);
1359
- res.writeHead(200, { "Content-Type": MIME_TYPES[ext] || "application/octet-stream" });
1360
- fs4.createReadStream(filePath).pipe(res);
1361
- return true;
1362
- }
1363
- return false;
1364
- }
1365
- function serveAppIndex(res) {
1366
- const indexPath = path3.join(APP_DIST, "index.html");
1367
- if (fs4.existsSync(indexPath)) {
1368
- const webSocket = userSettings.webSocket === true;
1369
- const configScript = `<script>window.__ANYCODE_CONFIG__=${JSON.stringify({ webSocket })}</script>`;
1370
- let html = fs4.readFileSync(indexPath, "utf-8");
1371
- html = html.replace("</head>", `${configScript}</head>`);
1372
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1373
- res.end(html);
1374
- return true;
1375
- }
1376
- return false;
1377
- }
1378
- var server = http.createServer(async (req, res) => {
1379
- res.setHeader("Access-Control-Allow-Origin", "*");
1380
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
1381
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
1382
- if (req.method === "OPTIONS") {
1383
- res.writeHead(204);
1384
- res.end();
1385
- return;
1386
- }
1387
- if (req.method === "POST" && req.url === "/api/poll/connect") {
1388
- let body = "";
1389
- for await (const chunk of req) body += chunk;
1390
- const { sessionId } = body ? JSON.parse(body) : {};
1391
- const session = sessionId ? getSession(sessionId) : void 0;
1392
- if (!session) {
1393
- res.writeHead(404, { "Content-Type": "application/json" });
1394
- res.end(JSON.stringify({ error: "Session not found" }));
1395
- return;
1396
- }
1397
- const channelId = Math.random().toString(36).slice(2) + Date.now().toString(36);
1398
- const client = new PollingClient(channelId, sessionId);
1399
- pollingClients.set(channelId, client);
1400
- getSessionClients(sessionId).add(client);
1401
- console.log(`\u{1F50C} Poll client connected to session ${sessionId} (channel=${channelId})`);
1402
- sendStateTo(sessionId, client);
1403
- res.writeHead(200, { "Content-Type": "application/json" });
1404
- res.end(JSON.stringify({ channelId }));
1405
- return;
1406
- }
1407
- if (req.method === "GET" && req.url?.startsWith("/api/poll?")) {
1408
- const url = new URL(req.url, `http://localhost:${PORT}`);
1409
- const channelId = url.searchParams.get("channelId");
1410
- const client = channelId ? pollingClients.get(channelId) : void 0;
1411
- if (!client || client.readyState !== 1) {
1412
- res.writeHead(404, { "Content-Type": "application/json" });
1413
- res.end(JSON.stringify({ error: "Channel not found" }));
1414
- return;
1415
- }
1416
- client.hold(res);
1417
- return;
1418
- }
1419
- if (req.method === "POST" && req.url === "/api/poll/send") {
1420
- let body = "";
1421
- for await (const chunk of req) body += chunk;
1422
- const { channelId, data } = body ? JSON.parse(body) : {};
1423
- const client = channelId ? pollingClients.get(channelId) : void 0;
1424
- if (!client || client.readyState !== 1) {
1425
- res.writeHead(404, { "Content-Type": "application/json" });
1426
- res.end(JSON.stringify({ error: "Channel not found" }));
1427
- return;
1428
- }
1429
- client.lastActivity = Date.now();
1430
- handleClientMessage(client.sessionId, client, data).catch(() => {
1431
- });
1432
- res.writeHead(200, { "Content-Type": "application/json" });
1433
- res.end(JSON.stringify({ ok: true }));
1434
- return;
1435
- }
1436
- if (req.method === "POST" && req.url === "/api/poll/close") {
1437
- let body = "";
1438
- for await (const chunk of req) body += chunk;
1439
- const { channelId } = body ? JSON.parse(body) : {};
1440
- const client = channelId ? pollingClients.get(channelId) : void 0;
1441
- if (client) {
1442
- client.close();
1443
- removeClient(client.sessionId, client);
1444
- pollingClients.delete(channelId);
1445
- console.log(`\u{1F50C} Poll client disconnected (channel=${channelId})`);
1446
- }
1447
- res.writeHead(200, { "Content-Type": "application/json" });
1448
- res.end(JSON.stringify({ ok: true }));
1449
- return;
1450
- }
1451
- if (req.method === "POST" && req.url === "/api/sessions") {
1452
- (async () => {
1453
- let body = "";
1454
- for await (const chunk of req) body += chunk;
1455
- const { userId } = body ? JSON.parse(body) : {};
1456
- if (!userId) {
1457
- res.writeHead(400, { "Content-Type": "application/json" });
1458
- res.end(JSON.stringify({ error: "userId is required" }));
1459
- return;
1460
- }
1461
- getOrCreateSession(userId).then((entry) => {
1462
- res.writeHead(200, { "Content-Type": "application/json" });
1463
- res.end(JSON.stringify({ id: entry.id, directory: entry.directory }));
1464
- }).catch((err) => {
1465
- res.writeHead(500, { "Content-Type": "application/json" });
1466
- res.end(JSON.stringify({ error: err.message }));
1467
- });
1468
- })();
1469
- return;
1470
- }
1471
- if (req.method === "GET" && req.url === "/api/sessions") {
1472
- const list = Array.from(sessions.values()).map((s) => ({
1473
- id: s.id,
1474
- directory: s.directory,
1475
- createdAt: s.createdAt
1476
- }));
1477
- res.writeHead(200, { "Content-Type": "application/json" });
1478
- res.end(JSON.stringify(list));
1479
- return;
1480
- }
1481
- if (req.method === "GET" && req.url?.startsWith("/api/windows")) {
1482
- const url = new URL(req.url, `http://localhost:${PORT}`);
1483
- const userId = url.searchParams.get("userId");
1484
- if (!userId) {
1485
- res.writeHead(400, { "Content-Type": "application/json" });
1486
- res.end(JSON.stringify({ error: "userId is required" }));
1487
- return;
1488
- }
1489
- getAllWindows(userId).then((entries) => {
1490
- const rows = db.findMany("user_session", { filter: { op: "eq", field: "user_id", value: userId } });
1491
- const defaultMap = new Map(rows.map((r) => [r.session_id, r.is_default === 1]));
1492
- const list = entries.map((e) => ({
1493
- id: e.id,
1494
- directory: e.directory,
1495
- createdAt: e.createdAt,
1496
- isDefault: defaultMap.get(e.id) ?? false
1497
- }));
1498
- res.writeHead(200, { "Content-Type": "application/json" });
1499
- res.end(JSON.stringify(list));
1500
- }).catch((err) => {
1501
- res.writeHead(500, { "Content-Type": "application/json" });
1502
- res.end(JSON.stringify({ error: err.message }));
1503
- });
1504
- return;
1505
- }
1506
- if (req.method === "POST" && req.url === "/api/windows") {
1507
- (async () => {
1508
- let body = "";
1509
- for await (const chunk of req) body += chunk;
1510
- const { userId } = body ? JSON.parse(body) : {};
1511
- if (!userId) {
1512
- res.writeHead(400, { "Content-Type": "application/json" });
1513
- res.end(JSON.stringify({ error: "userId is required" }));
1514
- return;
1515
- }
1516
- createNewWindow(userId, false).then((entry) => {
1517
- res.writeHead(200, { "Content-Type": "application/json" });
1518
- res.end(JSON.stringify({ id: entry.id, directory: entry.directory, isDefault: false }));
1519
- }).catch((err) => {
1520
- res.writeHead(500, { "Content-Type": "application/json" });
1521
- res.end(JSON.stringify({ error: err.message }));
1522
- });
1523
- })();
1524
- return;
1525
- }
1526
- const windowDeleteMatch = req.url?.match(/^\/api\/windows\/([^/?]+)$/);
1527
- if (req.method === "DELETE" && windowDeleteMatch) {
1528
- const ok = deleteWindow(windowDeleteMatch[1]);
1529
- if (ok) {
1530
- res.writeHead(200, { "Content-Type": "application/json" });
1531
- res.end(JSON.stringify({ ok: true }));
1532
- } else {
1533
- res.writeHead(400, { "Content-Type": "application/json" });
1534
- res.end(JSON.stringify({ error: "Cannot delete default window or window not found" }));
1535
- }
1536
- return;
1537
- }
1538
- const sessionMatch = req.url?.match(/^\/api\/sessions\/([^/?]+)(?:\/([a-z]+))?/);
1539
- if (req.method === "GET" && sessionMatch) {
1540
- const session = getSession(sessionMatch[1]);
1541
- if (!session) {
1542
- res.writeHead(404, { "Content-Type": "application/json" });
1543
- res.end(JSON.stringify({ error: "Session not found" }));
1544
- return;
1545
- }
1546
- const sub = sessionMatch[2];
1547
- const url = new URL(req.url, `http://localhost:${PORT}`);
1548
- if (sub === "state") {
1549
- const dir = session.directory;
1550
- const [topLevel, changes] = await Promise.all([
1551
- dir ? listDir(dir) : Promise.resolve([]),
1552
- dir ? getGitChanges(dir) : Promise.resolve([])
1553
- ]);
1554
- const hasPreview = previewSessionId === session.id && previewTarget;
1555
- res.writeHead(200, { "Content-Type": "application/json" });
1556
- res.end(JSON.stringify({ directory: dir, topLevel, changes, previewPort: hasPreview ? PREVIEW_PORT : null }));
1557
- return;
1558
- }
1559
- if (sub === "ls") {
1560
- const subPath = url.searchParams.get("path") || "";
1561
- const dir = session.directory;
1562
- if (!dir) {
1563
- res.writeHead(200, { "Content-Type": "application/json" });
1564
- res.end(JSON.stringify({ entries: [] }));
1565
- return;
1566
- }
1567
- const target = path3.resolve(dir, subPath);
1568
- if (!target.startsWith(path3.resolve(dir))) {
1569
- res.writeHead(403, { "Content-Type": "application/json" });
1570
- res.end(JSON.stringify({ error: "Forbidden" }));
1571
- return;
1572
- }
1573
- const entries = await listDir(target);
1574
- res.writeHead(200, { "Content-Type": "application/json" });
1575
- res.end(JSON.stringify({ entries }));
1576
- return;
1577
- }
1578
- if (sub === "file") {
1579
- const filePath = url.searchParams.get("path") || "";
1580
- const dir = session.directory;
1581
- if (!dir) {
1582
- res.writeHead(200, { "Content-Type": "application/json" });
1583
- res.end(JSON.stringify({ content: null, error: "No directory" }));
1584
- return;
1585
- }
1586
- const target = path3.resolve(dir, filePath);
1587
- if (!target.startsWith(path3.resolve(dir))) {
1588
- res.writeHead(403, { "Content-Type": "application/json" });
1589
- res.end(JSON.stringify({ error: "Forbidden" }));
1590
- return;
1591
- }
1592
- try {
1593
- const content = await fsPromises.readFile(target, "utf-8");
1594
- res.writeHead(200, { "Content-Type": "application/json" });
1595
- res.end(JSON.stringify({ content }));
1596
- } catch {
1597
- res.writeHead(200, { "Content-Type": "application/json" });
1598
- res.end(JSON.stringify({ content: null, error: "\u8BFB\u53D6\u5931\u8D25" }));
1599
- }
1600
- return;
1601
- }
1602
- if (sub === "diff") {
1603
- const filePath = url.searchParams.get("path") || "";
1604
- const dir = session.directory;
1605
- if (!dir) {
1606
- res.writeHead(200, { "Content-Type": "application/json" });
1607
- res.end(JSON.stringify({ added: [], removed: [] }));
1608
- return;
1609
- }
1610
- try {
1611
- const added = [];
1612
- const removed = [];
1613
- let result = await gitProvider.run(
1614
- ["diff", "--unified=0", "--", filePath],
1615
- { cwd: dir }
1616
- );
1617
- if (result.exitCode !== 0 || !result.text().trim()) {
1618
- result = await gitProvider.run(
1619
- ["diff", "--unified=0", "--cached", "--", filePath],
1620
- { cwd: dir }
1621
- );
1622
- }
1623
- const diffText = result.text();
1624
- const hunkRe = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/gm;
1625
- let m;
1626
- while (m = hunkRe.exec(diffText)) {
1627
- const oldStart = parseInt(m[1], 10);
1628
- const oldCount = parseInt(m[2] ?? "1", 10);
1629
- const newStart = parseInt(m[3], 10);
1630
- const newCount = parseInt(m[4] ?? "1", 10);
1631
- for (let i = 0; i < oldCount; i++) removed.push(oldStart + i);
1632
- for (let i = 0; i < newCount; i++) added.push(newStart + i);
1633
- }
1634
- if (!diffText.trim()) {
1635
- try {
1636
- const target = path3.resolve(dir, filePath);
1637
- if (target.startsWith(path3.resolve(dir))) {
1638
- const content = await fsPromises.readFile(target, "utf-8");
1639
- const lineCount = content.split("\n").length;
1640
- for (let i = 1; i <= lineCount; i++) added.push(i);
1641
- }
1642
- } catch {
1643
- }
1644
- }
1645
- res.writeHead(200, { "Content-Type": "application/json" });
1646
- res.end(JSON.stringify({ added, removed }));
1647
- } catch {
1648
- res.writeHead(200, { "Content-Type": "application/json" });
1649
- res.end(JSON.stringify({ added: [], removed: [] }));
1650
- }
1651
- return;
1652
- }
1653
- res.writeHead(200, { "Content-Type": "application/json" });
1654
- res.end(JSON.stringify({
1655
- id: session.id,
1656
- directory: session.directory,
1657
- createdAt: session.createdAt
1658
- }));
1659
- return;
1660
- }
1661
- if (req.method === "GET" && req.url === "/api/status") {
1662
- const list = Array.from(sessions.values()).map((s) => ({
1663
- id: s.id,
1664
- directory: s.directory,
1665
- stats: s.agent.getStats(),
1666
- sessionId: s.agent.sessionId
1667
- }));
1668
- res.writeHead(200, { "Content-Type": "application/json" });
1669
- res.end(JSON.stringify({ sessions: list }));
1670
- return;
1671
- }
1672
- if (req.method === "GET" && req.url?.startsWith("/api/messages")) {
1673
- const url = new URL(req.url, `http://localhost:${PORT}`);
1674
- const sessionId = url.searchParams.get("sessionId");
1675
- const session = sessionId ? getSession(sessionId) : void 0;
1676
- if (!session) {
1677
- res.writeHead(404, { "Content-Type": "application/json" });
1678
- res.end(JSON.stringify({ error: "Session not found" }));
1679
- return;
1680
- }
1681
- session.agent.getSessionMessages({ limit: 30 }).then((messages) => {
1682
- res.writeHead(200, { "Content-Type": "application/json" });
1683
- res.end(JSON.stringify(messages));
1684
- }).catch((err) => {
1685
- res.writeHead(500, { "Content-Type": "application/json" });
1686
- res.end(JSON.stringify({ error: err.message }));
1687
- });
1688
- return;
1689
- }
1690
- if (req.method === "GET" && req.url === "/admin") {
1691
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1692
- res.end(adminHTML());
1693
- return;
1694
- }
1695
- if (req.method === "GET") {
1696
- if (serveStatic(req, res)) return;
1697
- if (serveAppIndex(res)) return;
1698
- }
1699
- res.writeHead(404, { "Content-Type": "application/json" });
1700
- res.end(JSON.stringify({ error: "Not found" }));
1701
- });
1702
- async function startServer() {
1703
- console.log("\u{1F680} Starting any-code-server\u2026");
1704
- sharedStorage = new SqlJsStorage(DB_PATH);
1705
- const migrations = Database.getMigrations();
1706
- db = await sharedStorage.connect(migrations);
1707
- const cols = sharedStorage.query(`PRAGMA table_info("user_session")`);
1708
- if (cols.length > 0) {
1709
- const hasIsDefault = cols.some((c) => c.name === "is_default");
1710
- const pkCol = cols.find((c) => c.pk === 1);
1711
- const needsPkMigration = pkCol && pkCol.name === "user_id";
1712
- if (!hasIsDefault || needsPkMigration) {
1713
- console.log("\u{1F504} Migrating user_session table\u2026");
1714
- if (!hasIsDefault) {
1715
- sharedStorage.exec(`ALTER TABLE "user_session" ADD COLUMN "is_default" INTEGER NOT NULL DEFAULT 0`);
1716
- sharedStorage.exec(`UPDATE "user_session" SET "is_default" = 1`);
1717
- }
1718
- if (needsPkMigration) {
1719
- sharedStorage.exec(`CREATE TABLE "user_session_new" (
1720
- "session_id" TEXT PRIMARY KEY,
1721
- "user_id" TEXT NOT NULL,
1722
- "directory" TEXT NOT NULL DEFAULT '',
1723
- "time_created" INTEGER NOT NULL,
1724
- "is_default" INTEGER NOT NULL DEFAULT 0
1725
- )`);
1726
- sharedStorage.exec(`INSERT INTO "user_session_new" SELECT "session_id","user_id","directory","time_created","is_default" FROM "user_session"`);
1727
- sharedStorage.exec(`DROP TABLE "user_session"`);
1728
- sharedStorage.exec(`ALTER TABLE "user_session_new" RENAME TO "user_session"`);
1729
- }
1730
- console.log("\u2705 user_session migration complete");
1731
- }
1732
- } else {
1733
- sharedStorage.exec(`
1734
- CREATE TABLE IF NOT EXISTS "user_session" (
1735
- "session_id" TEXT PRIMARY KEY,
1736
- "user_id" TEXT NOT NULL,
1737
- "directory" TEXT NOT NULL DEFAULT '',
1738
- "time_created" INTEGER NOT NULL,
1739
- "is_default" INTEGER NOT NULL DEFAULT 0
1740
- )
1741
- `);
1742
- }
1743
- const appDistExists = fs4.existsSync(APP_DIST);
1744
- setInterval(() => {
1745
- const now = Date.now();
1746
- for (const [id, client] of pollingClients) {
1747
- if (now - client.lastActivity > 6e4) {
1748
- console.log(`\u{1F9F9} Cleaning up stale poll client (channel=${id})`);
1749
- client.close();
1750
- removeClient(client.sessionId, client);
1751
- pollingClients.delete(id);
1752
- }
1753
- }
1754
- }, 3e4);
1755
- const wss = new WebSocketServer({ server });
1756
- wss.on("connection", (ws, req) => {
1757
- const url = new URL(req.url || "/", `http://localhost:${PORT}`);
1758
- const sessionId = url.searchParams.get("sessionId");
1759
- if (!sessionId || !getSession(sessionId)) {
1760
- ws.close(4001, "Invalid session");
1761
- return;
1762
- }
1763
- if (url.pathname === "/terminal") {
1764
- handleTerminalWs(ws, sessionId);
1765
- return;
1766
- }
1767
- const clients = getSessionClients(sessionId);
1768
- clients.add(ws);
1769
- console.log(`\u{1F50C} WS client connected to session ${sessionId} (${clients.size} total)`);
1770
- sendStateTo(sessionId, ws);
1771
- ws.on("message", async (raw) => {
1772
- try {
1773
- const msg = JSON.parse(raw.toString());
1774
- handleClientMessage(sessionId, ws, msg).catch(() => {
1775
- });
1776
- } catch {
1777
- }
1778
- });
1779
- ws.on("close", () => {
1780
- removeClient(sessionId, ws);
1781
- });
1782
- });
1783
- const HOST = process.env.HOST ?? "0.0.0.0";
1784
- previewServer.listen(PREVIEW_PORT, HOST, () => {
1785
- console.log(`\u{1F441} Preview proxy: http://${HOST}:${PREVIEW_PORT}`);
1786
- });
1787
- server.listen(PORT, HOST, () => {
1788
- console.log(`\u{1F310} http://${HOST}:${PORT}`);
1789
- console.log(`\u{1F916} Provider: ${PROVIDER} / ${MODEL}`);
1790
- console.log(`\u{1F5A5} Admin: http://${HOST}:${PORT}/admin`);
1791
- if (appDistExists) {
1792
- console.log(`\u{1F4F1} App: http://${HOST}:${PORT}`);
1793
- } else {
1794
- console.log(`\u26A0 App dist not found at ${APP_DIST} \u2014 run 'pnpm --filter app build' first`);
1795
- }
1796
- console.log(`\u{1F4CB} Sessions: POST /api/sessions to create`);
1797
- console.log(`\u{1F50C} WebSocket: ws://${HOST}:${PORT}?sessionId=xxx`);
1798
- });
1799
- }
1800
- export {
1801
- CodeAgent,
1802
- NodeFS,
1803
- NodeSearchProvider,
1804
- SqlJsStorage,
1805
- startServer
1806
- };