@axhub/genie 0.1.7 → 0.1.9

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 (411) hide show
  1. package/README.md +1 -1
  2. package/dist/api-docs.html +2 -2
  3. package/dist/assets/App-IUhj6pRQ.js +546 -0
  4. package/dist/assets/App-qxJ8_QYu.css +32 -0
  5. package/dist/assets/ReviewApp-B8aNlXpI.js +1 -0
  6. package/dist/assets/_basePickBy-DF_C8v-X.js +1 -0
  7. package/dist/assets/_baseUniq-Dl8X6bvw.js +1 -0
  8. package/dist/assets/abap-BdImnpbu.js +1 -0
  9. package/dist/assets/actionscript-3-CoDkCxhg.js +1 -0
  10. package/dist/assets/ada-bCR0ucgS.js +1 -0
  11. package/dist/assets/andromeeda-C4gqWexZ.js +1 -0
  12. package/dist/assets/angular-html-CU67Zn6k.js +1 -0
  13. package/dist/assets/angular-ts-BwZT4LLn.js +1 -0
  14. package/dist/assets/apache-Pmp26Uib.js +1 -0
  15. package/dist/assets/apex-D8_7TLub.js +1 -0
  16. package/dist/assets/apl-dKokRX4l.js +1 -0
  17. package/dist/assets/applescript-Co6uUVPk.js +1 -0
  18. package/dist/assets/ara-BRHolxvo.js +1 -0
  19. package/dist/assets/arc-TwO_Ni8v.js +1 -0
  20. package/dist/assets/architectureDiagram-2XIMDMQ5-Dgm9kjQy.js +36 -0
  21. package/dist/assets/asciidoc-Ve4PFQV2.js +1 -0
  22. package/dist/assets/asm-D_Q5rh1f.js +1 -0
  23. package/dist/assets/astro-CbQHKStN.js +1 -0
  24. package/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
  25. package/dist/assets/awk-DMzUqQB5.js +1 -0
  26. package/dist/assets/ayu-dark-DYE7WIF3.js +1 -0
  27. package/dist/assets/ayu-light-BA47KaF1.js +1 -0
  28. package/dist/assets/ayu-mirage-32ctXXKs.js +1 -0
  29. package/dist/assets/ballerina-BFfxhgS-.js +1 -0
  30. package/dist/assets/bat-BkioyH1T.js +1 -0
  31. package/dist/assets/beancount-k_qm7-4y.js +1 -0
  32. package/dist/assets/berry-uYugtg8r.js +1 -0
  33. package/dist/assets/bibtex-CHM0blh-.js +1 -0
  34. package/dist/assets/bicep-Bmn6On1c.js +1 -0
  35. package/dist/assets/bird2-DPOp833l.js +1 -0
  36. package/dist/assets/blade-D4QpJJKB.js +1 -0
  37. package/dist/assets/blockDiagram-WCTKOSBZ-BhTxXYHE.js +132 -0
  38. package/dist/assets/bsl-BO_Y6i37.js +1 -0
  39. package/dist/assets/c-BIGW1oBm.js +1 -0
  40. package/dist/assets/c3-eo99z4R2.js +1 -0
  41. package/dist/assets/c4Diagram-IC4MRINW-D3xrrPyf.js +10 -0
  42. package/dist/assets/cadence-Bv_4Rxtq.js +1 -0
  43. package/dist/assets/cairo-KRGpt6FW.js +1 -0
  44. package/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  45. package/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  46. package/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  47. package/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  48. package/dist/assets/channel-D6xYGBae.js +1 -0
  49. package/dist/assets/chunk-4BX2VUAB-Fb3wkGSX.js +1 -0
  50. package/dist/assets/chunk-55IACEB6-CQwPJLM_.js +1 -0
  51. package/dist/assets/chunk-FMBD7UC4-B3SocdK3.js +15 -0
  52. package/dist/assets/chunk-JSJVCQXG-4LjhKVWX.js +1 -0
  53. package/dist/assets/chunk-KX2RTZJC-B5NX8jxL.js +1 -0
  54. package/dist/assets/chunk-NQ4KR5QH-6puKzw3k.js +220 -0
  55. package/dist/assets/chunk-QZHKN3VN-CxscPgdC.js +1 -0
  56. package/dist/assets/chunk-WL4C6EOR-uBFUeI3B.js +189 -0
  57. package/dist/assets/clarity-D53aC0YG.js +1 -0
  58. package/dist/assets/classDiagram-VBA2DB6C-CAq2xBD7.js +1 -0
  59. package/dist/assets/classDiagram-v2-RAHNMMFH-CAq2xBD7.js +1 -0
  60. package/dist/assets/clojure-P80f7IUj.js +1 -0
  61. package/dist/assets/clone-Ci5Ji0hp.js +1 -0
  62. package/dist/assets/cmake-D1j8_8rp.js +1 -0
  63. package/dist/assets/cobol-nwyudZeR.js +1 -0
  64. package/dist/assets/codeowners-Bp6g37R7.js +1 -0
  65. package/dist/assets/codeql-DsOJ9woJ.js +1 -0
  66. package/dist/assets/coffee-Ch7k5sss.js +1 -0
  67. package/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
  68. package/dist/assets/coq-DkFqJrB1.js +1 -0
  69. package/dist/assets/cose-bilkent-S5V4N54A-DlbARPn2.js +1 -0
  70. package/dist/assets/cpp-CofmeUqb.js +1 -0
  71. package/dist/assets/crystal-tKQVLTB8.js +1 -0
  72. package/dist/assets/csharp-COcwbKMJ.js +1 -0
  73. package/dist/assets/css-DPfMkruS.js +1 -0
  74. package/dist/assets/csv-fuZLfV_i.js +1 -0
  75. package/dist/assets/cue-D82EKSYY.js +1 -0
  76. package/dist/assets/cypher-COkxafJQ.js +1 -0
  77. package/dist/assets/cytoscape.esm-2ZfV8NB5.js +331 -0
  78. package/dist/assets/d-85-TOEBH.js +1 -0
  79. package/dist/assets/dagre-KLK3FWXG-D5rHdqja.js +4 -0
  80. package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
  81. package/dist/assets/dart-CF10PKvl.js +1 -0
  82. package/dist/assets/dax-CEL-wOlO.js +1 -0
  83. package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  84. package/dist/assets/desktop-BmXAJ9_W.js +1 -0
  85. package/dist/assets/diagram-E7M64L7V-1UmM7jTs.js +24 -0
  86. package/dist/assets/diagram-IFDJBPK2-BiB8xLQb.js +43 -0
  87. package/dist/assets/diagram-P4PSJMXO-D0DHiPZv.js +24 -0
  88. package/dist/assets/diff-D97Zzqfu.js +1 -0
  89. package/dist/assets/docker-BcOcwvcX.js +1 -0
  90. package/dist/assets/dotenv-Da5cRb03.js +1 -0
  91. package/dist/assets/dracula-BzJJZx-M.js +1 -0
  92. package/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
  93. package/dist/assets/dream-maker-BtqSS_iP.js +1 -0
  94. package/dist/assets/edge-BkV0erSs.js +1 -0
  95. package/dist/assets/elixir-CDX3lj18.js +1 -0
  96. package/dist/assets/elm-DbKCFpqz.js +1 -0
  97. package/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
  98. package/dist/assets/erDiagram-INFDFZHY-CnRJ2Jix.js +70 -0
  99. package/dist/assets/erb-B12qg9BL.js +1 -0
  100. package/dist/assets/erlang-DsQrWhSR.js +1 -0
  101. package/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
  102. package/dist/assets/everforest-light-C8M2exoo.js +1 -0
  103. package/dist/assets/fennel-BYunw83y.js +1 -0
  104. package/dist/assets/fish-BvzEVeQv.js +1 -0
  105. package/dist/assets/flowDiagram-PKNHOUZH-CEgo6QRr.js +162 -0
  106. package/dist/assets/fluent-C4IJs8-o.js +1 -0
  107. package/dist/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  108. package/dist/assets/fortran-free-form-BxgE0vQu.js +1 -0
  109. package/dist/assets/fsharp-CXgrBDvD.js +1 -0
  110. package/dist/assets/ganttDiagram-A5KZAMGK-BIuQLJvD.js +292 -0
  111. package/dist/assets/gdresource-BOOCDP_w.js +1 -0
  112. package/dist/assets/gdscript-C5YyOfLZ.js +1 -0
  113. package/dist/assets/gdshader-DkwncUOv.js +1 -0
  114. package/dist/assets/genie-D0YGMca9.js +1 -0
  115. package/dist/assets/gherkin-DyxjwDmM.js +1 -0
  116. package/dist/assets/git-commit-F4YmCXRG.js +1 -0
  117. package/dist/assets/git-rebase-r7XF79zn.js +1 -0
  118. package/dist/assets/gitGraphDiagram-K3NZZRJ6-BgM4MazK.js +65 -0
  119. package/dist/assets/github-dark-DHJKELXO.js +1 -0
  120. package/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
  121. package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  122. package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  123. package/dist/assets/github-light-DAi9KRSo.js +1 -0
  124. package/dist/assets/github-light-default-D7oLnXFd.js +1 -0
  125. package/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  126. package/dist/assets/gleam-BspZqrRM.js +1 -0
  127. package/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
  128. package/dist/assets/glimmer-ts-U6CK756n.js +1 -0
  129. package/dist/assets/glsl-DplSGwfg.js +1 -0
  130. package/dist/assets/gn-n2N0HUVH.js +1 -0
  131. package/dist/assets/gnuplot-DdkO51Og.js +1 -0
  132. package/dist/assets/go-CxLEBnE3.js +1 -0
  133. package/dist/assets/graph-CAfp4sq_.js +1 -0
  134. package/dist/assets/graphql-ChdNCCLP.js +1 -0
  135. package/dist/assets/groovy-gcz8RCvz.js +1 -0
  136. package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  137. package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  138. package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  139. package/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  140. package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  141. package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  142. package/dist/assets/hack-CaT9iCJl.js +1 -0
  143. package/dist/assets/haml-B8DHNrY2.js +1 -0
  144. package/dist/assets/handlebars-BL8al0AC.js +1 -0
  145. package/dist/assets/haskell-Df6bDoY_.js +1 -0
  146. package/dist/assets/haxe-CzTSHFRz.js +1 -0
  147. package/dist/assets/hcl-BWvSN4gD.js +1 -0
  148. package/dist/assets/highlighted-body-TPN3WLV5-qMmmT5JC.js +1 -0
  149. package/dist/assets/hjson-D5-asLiD.js +1 -0
  150. package/dist/assets/hlsl-D3lLCCz7.js +1 -0
  151. package/dist/assets/horizon-BUw7H-hv.js +1 -0
  152. package/dist/assets/horizon-bright-Cn-bp-IR.js +1 -0
  153. package/dist/assets/houston-DnULxvSX.js +1 -0
  154. package/dist/assets/html-GMplVEZG.js +1 -0
  155. package/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
  156. package/dist/assets/http-jrhK8wxY.js +1 -0
  157. package/dist/assets/hurl-irOxFIW8.js +1 -0
  158. package/dist/assets/hxml-Bvhsp5Yf.js +1 -0
  159. package/dist/assets/hy-DFXneXwc.js +1 -0
  160. package/dist/assets/imba-DGztddWO.js +1 -0
  161. package/dist/assets/index-DIJsxqXa.css +1 -0
  162. package/dist/assets/index-DLN_-tVh.js +2 -0
  163. package/dist/assets/infoDiagram-LFFYTUFH-CWSerJ0x.js +2 -0
  164. package/dist/assets/ini-BEwlwnbL.js +1 -0
  165. package/dist/assets/init-Gi6I4Gst.js +1 -0
  166. package/dist/assets/ishikawaDiagram-PHBUUO56-CzeVsiJ6.js +70 -0
  167. package/dist/assets/java-CylS5w8V.js +1 -0
  168. package/dist/assets/javascript-wDzz0qaB.js +1 -0
  169. package/dist/assets/jinja-4LBKfQ-Z.js +1 -0
  170. package/dist/assets/jison-wvAkD_A8.js +1 -0
  171. package/dist/assets/journeyDiagram-4ABVD52K-D_NYt9lf.js +139 -0
  172. package/dist/assets/json-Cp-IABpG.js +1 -0
  173. package/dist/assets/json5-C9tS-k6U.js +1 -0
  174. package/dist/assets/jsonc-Des-eS-w.js +1 -0
  175. package/dist/assets/jsonl-DcaNXYhu.js +1 -0
  176. package/dist/assets/jsonnet-DFQXde-d.js +1 -0
  177. package/dist/assets/jssm-C2t-YnRu.js +1 -0
  178. package/dist/assets/jsx-g9-lgVsj.js +1 -0
  179. package/dist/assets/julia-CxzCAyBv.js +1 -0
  180. package/dist/assets/just-Cw27pwNe.js +1 -0
  181. package/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  182. package/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  183. package/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
  184. package/dist/assets/kanban-definition-K7BYSVSG-CX7AUuup.js +89 -0
  185. package/dist/assets/kdl-DV7GczEv.js +1 -0
  186. package/dist/assets/kotlin-BdnUsdx6.js +1 -0
  187. package/dist/assets/kusto-DZf3V79B.js +1 -0
  188. package/dist/assets/laserwave-DUszq2jm.js +1 -0
  189. package/dist/assets/latex-CWtU0Tv5.js +1 -0
  190. package/dist/assets/layout-DSvVDs_y.js +1 -0
  191. package/dist/assets/lean-BZvkOJ9d.js +1 -0
  192. package/dist/assets/less-B1dDrJ26.js +1 -0
  193. package/dist/assets/light-plus-B7mTdjB0.js +1 -0
  194. package/dist/assets/linear-CVh3kWAl.js +1 -0
  195. package/dist/assets/liquid-DYVedYrR.js +1 -0
  196. package/dist/assets/llvm-DjAJT7YJ.js +1 -0
  197. package/dist/assets/log-2UxHyX5q.js +1 -0
  198. package/dist/assets/logo-BtOb2qkB.js +1 -0
  199. package/dist/assets/lua-BaeVxFsk.js +1 -0
  200. package/dist/assets/luau-C-HG3fhB.js +1 -0
  201. package/dist/assets/make-CHLpvVh8.js +1 -0
  202. package/dist/assets/markdown-Cvjx9yec.js +1 -0
  203. package/dist/assets/marko-CnJfTvn9.js +1 -0
  204. package/dist/assets/material-theme-D5KoaKCx.js +1 -0
  205. package/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
  206. package/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  207. package/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
  208. package/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  209. package/dist/assets/matlab-D7o27uSR.js +1 -0
  210. package/dist/assets/mdc-BMNejdWA.js +1 -0
  211. package/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  212. package/dist/assets/mermaid-O7DHMXV3-CrPRD2Zy.js +964 -0
  213. package/dist/assets/mermaid-mWjccvbQ.js +1 -0
  214. package/dist/assets/min-dark-CafNBF8u.js +1 -0
  215. package/dist/assets/min-light-CTRr51gU.js +1 -0
  216. package/dist/assets/mindmap-definition-YRQLILUH-w_orDc4B.js +68 -0
  217. package/dist/assets/mipsasm-CKIfxQSi.js +1 -0
  218. package/dist/assets/mojo-rZm6bMo-.js +1 -0
  219. package/dist/assets/monokai-D4h5O-jR.js +1 -0
  220. package/dist/assets/moonbit-_H4v1dQx.js +1 -0
  221. package/dist/assets/move-IF9eRakj.js +1 -0
  222. package/dist/assets/narrat-DRg8JJMk.js +1 -0
  223. package/dist/assets/nextflow-Zz6hmt5N.js +1 -0
  224. package/dist/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  225. package/dist/assets/nginx-BpAMiNFr.js +1 -0
  226. package/dist/assets/night-owl-C39BiMTA.js +1 -0
  227. package/dist/assets/night-owl-light-CMTm3GFP.js +1 -0
  228. package/dist/assets/nim-CVrawwO9.js +1 -0
  229. package/dist/assets/nix-CwoSXNpI.js +1 -0
  230. package/dist/assets/nord-Ddv68eIx.js +1 -0
  231. package/dist/assets/nushell-Cz2AlsmD.js +1 -0
  232. package/dist/assets/objective-c-DXmwc3jG.js +1 -0
  233. package/dist/assets/objective-cpp-CLxacb5B.js +1 -0
  234. package/dist/assets/ocaml-C0hk2d4L.js +1 -0
  235. package/dist/assets/odin-BBf5iR-q.js +1 -0
  236. package/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  237. package/dist/assets/one-light-C3Wv6jpd.js +1 -0
  238. package/dist/assets/openscad-C4EeE6gA.js +1 -0
  239. package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  240. package/dist/assets/pascal-D93ZcfNL.js +1 -0
  241. package/dist/assets/perl-C0TMdlhV.js +1 -0
  242. package/dist/assets/php-Dhbhpdrm.js +1 -0
  243. package/dist/assets/pieDiagram-SKSYHLDU-Ddit1h2q.js +30 -0
  244. package/dist/assets/pkl-u5AG7uiY.js +1 -0
  245. package/dist/assets/plastic-3e1v2bzS.js +1 -0
  246. package/dist/assets/plsql-ChMvpjG-.js +1 -0
  247. package/dist/assets/po-BTJTHyun.js +1 -0
  248. package/dist/assets/poimandres-CS3Unz2-.js +1 -0
  249. package/dist/assets/polar-C0HS_06l.js +1 -0
  250. package/dist/assets/postcss-CXtECtnM.js +1 -0
  251. package/dist/assets/powerquery-CEu0bR-o.js +1 -0
  252. package/dist/assets/powershell-Dpen1YoG.js +1 -0
  253. package/dist/assets/prisma-Dd19v3D-.js +1 -0
  254. package/dist/assets/prolog-CbFg5uaA.js +1 -0
  255. package/dist/assets/proto-C7zT0LnQ.js +1 -0
  256. package/dist/assets/pug-CGlum2m_.js +1 -0
  257. package/dist/assets/puppet-BMWR74SV.js +1 -0
  258. package/dist/assets/purescript-CklMAg4u.js +1 -0
  259. package/dist/assets/python-B6aJPvgy.js +1 -0
  260. package/dist/assets/qml-3beO22l8.js +1 -0
  261. package/dist/assets/qmldir-C8lEn-DE.js +1 -0
  262. package/dist/assets/qss-IeuSbFQv.js +1 -0
  263. package/dist/assets/quadrantDiagram-337W2JSQ-DVw1s8Ut.js +7 -0
  264. package/dist/assets/r-Dspwwk_N.js +1 -0
  265. package/dist/assets/racket-BqYA7rlc.js +1 -0
  266. package/dist/assets/raku-DXvB9xmW.js +1 -0
  267. package/dist/assets/razor-Uh8Bk_45.js +1 -0
  268. package/dist/assets/red-bN70gL4F.js +1 -0
  269. package/dist/assets/reg-C-SQnVFl.js +1 -0
  270. package/dist/assets/regexp-CDVJQ6XC.js +1 -0
  271. package/dist/assets/rel-C3B-1QV4.js +1 -0
  272. package/dist/assets/requirementDiagram-Z7DCOOCP-DQPZpp_9.js +73 -0
  273. package/dist/assets/riscv-BM1_JUlF.js +1 -0
  274. package/dist/assets/ron-D8l8udqQ.js +1 -0
  275. package/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  276. package/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  277. package/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
  278. package/dist/assets/rosmsg-BJDFO7_C.js +1 -0
  279. package/dist/assets/rst-BrH8l1NY.js +1 -0
  280. package/dist/assets/ruby-Dw2BHqvy.js +1 -0
  281. package/dist/assets/rust-B1yitclQ.js +1 -0
  282. package/dist/assets/sankeyDiagram-WA2Y5GQK-CfbFynOx.js +10 -0
  283. package/dist/assets/sas-cz2c8ADy.js +1 -0
  284. package/dist/assets/sass-Cj5Yp3dK.js +1 -0
  285. package/dist/assets/scala-C151Ov-r.js +1 -0
  286. package/dist/assets/scheme-C98Dy4si.js +1 -0
  287. package/dist/assets/scss-OYdSNvt2.js +1 -0
  288. package/dist/assets/sdbl-DVxCFoDh.js +1 -0
  289. package/dist/assets/sequenceDiagram-2WXFIKYE-BO9n1wra.js +145 -0
  290. package/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
  291. package/dist/assets/shellscript-Yzrsuije.js +1 -0
  292. package/dist/assets/shellsession-BADoaaVG.js +1 -0
  293. package/dist/assets/slack-dark-BthQWCQV.js +1 -0
  294. package/dist/assets/slack-ochin-DqwNpetd.js +1 -0
  295. package/dist/assets/smalltalk-BERRCDM3.js +1 -0
  296. package/dist/assets/snazzy-light-Bw305WKR.js +1 -0
  297. package/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
  298. package/dist/assets/solarized-light-L9t79GZl.js +1 -0
  299. package/dist/assets/solidity-rGO070M0.js +1 -0
  300. package/dist/assets/soy-Brmx7dQM.js +1 -0
  301. package/dist/assets/sparql-rVzFXLq3.js +1 -0
  302. package/dist/assets/splunk-BtCnVYZw.js +1 -0
  303. package/dist/assets/sql-BLtJtn59.js +1 -0
  304. package/dist/assets/ssh-config-_ykCGR6B.js +1 -0
  305. package/dist/assets/stata-BH5u7GGu.js +1 -0
  306. package/dist/assets/stateDiagram-RAJIS63D-CRL3ceNd.js +1 -0
  307. package/dist/assets/stateDiagram-v2-FVOUBMTO-CZOgjDCg.js +1 -0
  308. package/dist/assets/stylus-BEDo0Tqx.js +1 -0
  309. package/dist/assets/surrealql-Bq5Q-fJD.js +1 -0
  310. package/dist/assets/svelte-C_ipcX3V.js +1 -0
  311. package/dist/assets/swift-D82vCrfD.js +1 -0
  312. package/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
  313. package/dist/assets/system-verilog-CnnmHF94.js +1 -0
  314. package/dist/assets/systemd-4A_iFExJ.js +1 -0
  315. package/dist/assets/talonscript-CkByrt1z.js +1 -0
  316. package/dist/assets/tasl-QIJgUcNo.js +1 -0
  317. package/dist/assets/tcl-dwOrl1Do.js +1 -0
  318. package/dist/assets/templ-P3uqSqPl.js +1 -0
  319. package/dist/assets/terraform-BETggiCN.js +1 -0
  320. package/dist/assets/tex-idrVyKtj.js +1 -0
  321. package/dist/assets/timeline-definition-YZTLITO2-BR7smGEM.js +61 -0
  322. package/dist/assets/tokyo-night-hegEt444.js +1 -0
  323. package/dist/assets/toml-vGWfd6FD.js +1 -0
  324. package/dist/assets/treemap-KZPCXAKY-DkR8x0Kw.js +162 -0
  325. package/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
  326. package/dist/assets/tsv-B_m7g4N7.js +1 -0
  327. package/dist/assets/tsx-COt5Ahok.js +1 -0
  328. package/dist/assets/turtle-BsS91CYL.js +1 -0
  329. package/dist/assets/twig-DNn4PbVi.js +1 -0
  330. package/dist/assets/typescript-BPQ3VLAy.js +1 -0
  331. package/dist/assets/typespec-BGHnOYBU.js +1 -0
  332. package/dist/assets/typst-DHCkPAjA.js +1 -0
  333. package/dist/assets/v-BcVCzyr7.js +1 -0
  334. package/dist/assets/vala-CsfeWuGM.js +1 -0
  335. package/dist/assets/vb-D17OF-Vu.js +1 -0
  336. package/dist/assets/{vendor-codemirror-B88_OPWf.js → vendor-codemirror-D5if-Qdt.js} +3 -3
  337. package/dist/assets/{vendor-react-C3RJLQGO.js → vendor-react-CSz7XC90.js} +11 -11
  338. package/dist/assets/vennDiagram-LZ73GAT5-DS7XpPV_.js +34 -0
  339. package/dist/assets/verilog-BQ8w6xss.js +1 -0
  340. package/dist/assets/vesper-DU1UobuO.js +1 -0
  341. package/dist/assets/vhdl-CeAyd5Ju.js +1 -0
  342. package/dist/assets/viml-CJc9bBzg.js +1 -0
  343. package/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
  344. package/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
  345. package/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
  346. package/dist/assets/vue-DN_0RTcg.js +1 -0
  347. package/dist/assets/vue-html-AaS7Mt5G.js +1 -0
  348. package/dist/assets/vue-vine-CQOfvN7w.js +1 -0
  349. package/dist/assets/vyper-CDx5xZoG.js +1 -0
  350. package/dist/assets/wasm-CG6Dc4jp.js +1 -0
  351. package/dist/assets/wasm-MzD3tlZU.js +1 -0
  352. package/dist/assets/wenyan-BV7otONQ.js +1 -0
  353. package/dist/assets/wgsl-Dx-B1_4e.js +1 -0
  354. package/dist/assets/wikitext-BhOHFoWU.js +1 -0
  355. package/dist/assets/wit-5i3qLPDT.js +1 -0
  356. package/dist/assets/wolfram-lXgVvXCa.js +1 -0
  357. package/dist/assets/xml-sdJ4AIDG.js +1 -0
  358. package/dist/assets/xsl-CtQFsRM5.js +1 -0
  359. package/dist/assets/xychartDiagram-JWTSCODW-BgjSBvNS.js +7 -0
  360. package/dist/assets/yaml-Buea-lGh.js +1 -0
  361. package/dist/assets/zenscript-DVFEvuxE.js +1 -0
  362. package/dist/assets/zig-VOosw3JB.js +1 -0
  363. package/dist/index.html +37 -23
  364. package/dist/manifest.json +2 -2
  365. package/dist/sw.js +18 -46
  366. package/package.json +12 -7
  367. package/server/bin/codex-sdk-wrapper.js +49 -0
  368. package/server/channels/core/ChannelManager.js +399 -0
  369. package/server/channels/core/PluginManager.js +59 -0
  370. package/server/channels/index.js +3 -0
  371. package/server/channels/plugins/BasePlugin.js +46 -0
  372. package/server/channels/plugins/dingtalk/DingTalkAdapter.js +156 -0
  373. package/server/channels/plugins/dingtalk/DingTalkPlugin.js +592 -0
  374. package/server/channels/plugins/dingtalk/index.js +2 -0
  375. package/server/channels/plugins/lark/LarkAdapter.js +100 -0
  376. package/server/channels/plugins/lark/LarkCards.js +43 -0
  377. package/server/channels/plugins/lark/LarkPlugin.js +260 -0
  378. package/server/channels/runtime/AgentRuntimeAdapter.js +176 -0
  379. package/server/channels/runtime/DingTalkStreamWriter.js +105 -0
  380. package/server/channels/runtime/LarkStreamWriter.js +99 -0
  381. package/server/channels/store/ChannelStore.js +202 -0
  382. package/server/claude-sdk.js +151 -3
  383. package/server/cli.js +21 -21
  384. package/server/database/db.js +449 -275
  385. package/server/gemini-cli.js +106 -19
  386. package/server/index.js +87 -108
  387. package/server/load-env.js +16 -13
  388. package/server/openai-codex.js +146 -10
  389. package/server/projects.js +340 -331
  390. package/server/routes/agent.js +429 -30
  391. package/server/routes/auth.js +14 -36
  392. package/server/routes/channels.js +221 -0
  393. package/server/routes/cli-auth.js +117 -124
  394. package/server/routes/commands.js +16 -26
  395. package/server/routes/git.js +5 -16
  396. package/server/routes/projects.js +2 -7
  397. package/server/routes/session-core.js +177 -0
  398. package/server/session-core/abortSession.js +48 -0
  399. package/server/session-core/eventStore.js +139 -0
  400. package/server/session-core/providerAdapters.js +84 -0
  401. package/server/session-core/providerDiscovery.js +235 -0
  402. package/server/session-core/runtimeWriter.js +55 -0
  403. package/server/utils/agentCallback.js +273 -0
  404. package/server/utils/codexPath.js +47 -0
  405. package/shared/conversationEvents.js +1031 -0
  406. package/shared/modelConstants.js +18 -24
  407. package/dist/assets/index-C2r-Jzfw.js +0 -897
  408. package/dist/assets/index-COkoBQi5.css +0 -32
  409. package/server/cursor-cli.js +0 -276
  410. package/server/database/init.sql +0 -52
  411. package/server/routes/cursor.js +0 -795
@@ -101,11 +101,68 @@ function emitTextChunks(ws, sessionId, chunks) {
101
101
  });
102
102
  }
103
103
 
104
+ function formatGeminiProcessError(code, stderrOutput) {
105
+ const normalizedStderr = String(stderrOutput || '').trim();
106
+ if (normalizedStderr) {
107
+ const apiMessageMatch =
108
+ normalizedStderr.match(/"message":"([^"]+)"/) ||
109
+ normalizedStderr.match(/message:\s*"([^"]+)"/i) ||
110
+ normalizedStderr.match(/ApiError:\s*\{.*?"message":"([^"]+)"/i) ||
111
+ normalizedStderr.match(/Error when talking to Gemini API[\s\S]*?message":"([^"]+)"/i);
112
+
113
+ if (apiMessageMatch?.[1]) {
114
+ return apiMessageMatch[1];
115
+ }
116
+
117
+ const firstMeaningfulLine = normalizedStderr
118
+ .split('\n')
119
+ .map((line) => line.trim())
120
+ .find((line) => line && !line.startsWith('at '));
121
+
122
+ if (firstMeaningfulLine) {
123
+ return firstMeaningfulLine;
124
+ }
125
+
126
+ return normalizedStderr;
127
+ }
128
+
129
+ return `Gemini CLI exited with code ${code}`;
130
+ }
131
+
132
+ function extractGeminiEventError(event) {
133
+ if (!event || typeof event !== 'object') {
134
+ return null;
135
+ }
136
+
137
+ const candidates = [
138
+ event?.error?.message,
139
+ event?.error?.details,
140
+ event?.result?.error?.message,
141
+ event?.result?.error,
142
+ event?.data?.error?.message,
143
+ event?.data?.error,
144
+ event?.message
145
+ ];
146
+
147
+ for (const candidate of candidates) {
148
+ const normalized = String(candidate || '').trim();
149
+ if (normalized) {
150
+ return normalized;
151
+ }
152
+ }
153
+
154
+ return null;
155
+ }
156
+
104
157
  async function queryGemini(command, options = {}, ws) {
105
158
  return new Promise((resolve, reject) => {
106
159
  const { sessionId, cwd, projectPath, resume, model, permissionMode } = options;
107
160
  let capturedSessionId = sessionId;
108
161
  let sentSessionCreated = false;
162
+ let stderrBuffer = '';
163
+ let fatalErrorSent = false;
164
+ let sawSuccessfulTerminalEvent = false;
165
+ let sawErroredTerminalEvent = false;
109
166
 
110
167
  const args = ['-y', '@google/gemini-cli'];
111
168
 
@@ -142,6 +199,19 @@ async function queryGemini(command, options = {}, ws) {
142
199
  activeGeminiProcesses.set(processRegistryKey, geminiProcess);
143
200
 
144
201
  const finalizeSessionId = () => capturedSessionId || sessionId || null;
202
+ const emitFatalError = (errorMessage) => {
203
+ if (fatalErrorSent || !errorMessage) {
204
+ return;
205
+ }
206
+
207
+ fatalErrorSent = true;
208
+ ws.send({
209
+ type: 'claude-error',
210
+ error: errorMessage,
211
+ provider: 'gemini',
212
+ sessionId: finalizeSessionId()
213
+ });
214
+ };
145
215
 
146
216
  const handleJsonEvent = (event) => {
147
217
  const incomingSessionId = event?.session_id || event?.sessionId || event?.data?.session_id || event?.data?.sessionId;
@@ -169,6 +239,15 @@ async function queryGemini(command, options = {}, ws) {
169
239
 
170
240
  const type = event?.type || event?.event || event?.kind;
171
241
  if (type === 'result' || type === 'done' || type === 'complete') {
242
+ const eventStatus = String(event?.status || event?.result?.status || '').trim().toLowerCase();
243
+ const eventError = extractGeminiEventError(event);
244
+ if (eventStatus === 'error' || eventError) {
245
+ sawErroredTerminalEvent = true;
246
+ emitFatalError(eventError || 'Gemini CLI request failed');
247
+ return;
248
+ }
249
+
250
+ sawSuccessfulTerminalEvent = true;
172
251
  ws.send({
173
252
  type: 'claude-response',
174
253
  data: { type: 'content_block_stop' },
@@ -204,11 +283,13 @@ async function queryGemini(command, options = {}, ws) {
204
283
  });
205
284
 
206
285
  geminiProcess.stderr.on('data', (data) => {
207
- ws.send({
208
- type: 'claude-error',
209
- error: data.toString(),
210
- sessionId: finalizeSessionId()
211
- });
286
+ const chunk = data.toString();
287
+ stderrBuffer += chunk;
288
+
289
+ const normalizedChunk = chunk.trim();
290
+ if (normalizedChunk) {
291
+ console.warn('Gemini CLI stderr:', normalizedChunk);
292
+ }
212
293
  });
213
294
 
214
295
  geminiProcess.on('close', (code) => {
@@ -223,29 +304,35 @@ async function queryGemini(command, options = {}, ws) {
223
304
 
224
305
  activeGeminiProcesses.delete(processRegistryKey);
225
306
 
226
- ws.send({
227
- type: 'claude-complete',
228
- sessionId: finalizeSessionId(),
229
- provider: 'gemini',
230
- exitCode: code,
231
- isNewSession: !sessionId && !!command
232
- });
307
+ if (code === 0 && !sawErroredTerminalEvent) {
308
+ if (!sawSuccessfulTerminalEvent) {
309
+ ws.send({
310
+ type: 'claude-response',
311
+ data: { type: 'content_block_stop' },
312
+ provider: 'gemini',
313
+ sessionId: finalizeSessionId()
314
+ });
315
+ }
233
316
 
234
- if (code === 0) {
317
+ ws.send({
318
+ type: 'claude-complete',
319
+ sessionId: finalizeSessionId(),
320
+ provider: 'gemini',
321
+ exitCode: code,
322
+ isNewSession: !sessionId && !!command
323
+ });
235
324
  resolve();
236
325
  } else {
237
- reject(new Error(`Gemini CLI exited with code ${code}`));
326
+ const errorMessage = formatGeminiProcessError(code, stderrBuffer);
327
+ emitFatalError(errorMessage);
328
+ reject(new Error(errorMessage));
238
329
  }
239
330
  });
240
331
 
241
332
  geminiProcess.on('error', (error) => {
242
333
  activeGeminiProcesses.delete(processRegistryKey);
243
334
 
244
- ws.send({
245
- type: 'claude-error',
246
- error: error.message,
247
- sessionId: finalizeSessionId()
248
- });
335
+ emitFatalError(error.message);
249
336
 
250
337
  reject(error);
251
338
  });
package/server/index.js CHANGED
@@ -73,30 +73,33 @@ import pty from 'node-pty';
73
73
  import fetch from 'node-fetch';
74
74
  import mime from 'mime-types';
75
75
 
76
- import { getProjects, getSessions, getSessionMessages, renameProject, deleteSession, deleteProject, addProjectManually, extractProjectDirectory, clearProjectDirectoryCache, getGeminiSessionMessages } from './projects.js';
77
- import { queryClaudeSDK, abortClaudeSDKSession, isClaudeSDKSessionActive, getActiveClaudeSDKSessions, resolveToolApproval } from './claude-sdk.js';
78
- import { spawnCursor, abortCursorSession, isCursorSessionActive, getActiveCursorSessions } from './cursor-cli.js';
79
- import { queryCodex, abortCodexSession, isCodexSessionActive, getActiveCodexSessions } from './openai-codex.js';
80
- import { queryGemini, abortGeminiSession, isGeminiSessionActive, getActiveGeminiSessions } from './gemini-cli.js';
81
- import { queryOpencode, abortOpencodeSession, isOpencodeSessionActive, getActiveOpencodeSessions } from './opencode-cli.js';
76
+ import { getProjects, getSessions, getSessionMessages, renameProject, deleteSession, deleteProject, addProjectManually, extractProjectDirectory, clearProjectDirectoryCache, clearProviderSessionLookupCaches, getGeminiSessionMessages } from './projects.js';
77
+ import { queryClaudeSDK, isClaudeSDKSessionActive, getActiveClaudeSDKSessions, resolveToolApproval } from './claude-sdk.js';
78
+ import { queryCodex, isCodexSessionActive, getActiveCodexSessions } from './openai-codex.js';
79
+ import { queryGemini, isGeminiSessionActive, getActiveGeminiSessions } from './gemini-cli.js';
80
+ import { queryOpencode, isOpencodeSessionActive, getActiveOpencodeSessions } from './opencode-cli.js';
82
81
  import gitRoutes from './routes/git.js';
83
82
  import authRoutes from './routes/auth.js';
84
83
  import mcpRoutes from './routes/mcp.js';
85
- import cursorRoutes from './routes/cursor.js';
86
84
  import taskmasterRoutes from './routes/taskmaster.js';
87
85
  import mcpUtilsRoutes from './routes/mcp-utils.js';
88
86
  import commandsRoutes from './routes/commands.js';
89
87
  import settingsRoutes from './routes/settings.js';
88
+ import channelsRoutes from './routes/channels.js';
90
89
  import agentRoutes from './routes/agent.js';
91
90
  import projectsRoutes, { WORKSPACES_ROOT, validateWorkspacePath } from './routes/projects.js';
92
91
  import cliAuthRoutes from './routes/cli-auth.js';
93
92
  import userRoutes from './routes/user.js';
94
93
  import codexRoutes from './routes/codex.js';
95
94
  import opencodeRoutes from './routes/opencode.js';
95
+ import sessionCoreRoutes from './routes/session-core.js';
96
96
  import { parseCodexTokenCountInfo } from './utils/codexTokenUsage.js';
97
97
  import { initializeDatabase } from './database/db.js';
98
98
  import { validateApiKey, authenticateToken, authenticateWebSocket } from './middleware/auth.js';
99
99
  import { IS_PLATFORM } from './constants/config.js';
100
+ import { getChannelManager } from './channels/index.js';
101
+ import { SessionEventMirrorWriter } from './session-core/runtimeWriter.js';
102
+ import { abortAgentSessionWithWriter } from './session-core/abortSession.js';
100
103
 
101
104
  // File system watcher for projects folder
102
105
  let projectsWatcher = null;
@@ -241,10 +244,26 @@ function broadcastProgress(progress) {
241
244
  });
242
245
  }
243
246
 
244
- // Setup file system watcher for Claude projects folder using chokidar
247
+ function extractSessionIdFromChangedFile(filePath) {
248
+ const basename = path.basename(filePath || '', path.extname(filePath || ''));
249
+ if (!basename) {
250
+ return null;
251
+ }
252
+
253
+ const directMatch = basename.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i);
254
+ if (directMatch?.[1]) {
255
+ return directMatch[1];
256
+ }
257
+
258
+ return basename || null;
259
+ }
260
+
261
+ // Setup file system watcher for project and provider session folders using chokidar
245
262
  async function setupProjectsWatcher() {
246
263
  const chokidar = (await import('chokidar')).default;
247
264
  const claudeProjectsPath = path.join(os.homedir(), '.claude', 'projects');
265
+ const codexSessionsPath = path.join(os.homedir(), '.codex', 'sessions');
266
+ const watchRoots = [claudeProjectsPath, codexSessionsPath];
248
267
 
249
268
  if (projectsWatcher) {
250
269
  projectsWatcher.close();
@@ -252,7 +271,7 @@ async function setupProjectsWatcher() {
252
271
 
253
272
  try {
254
273
  // Initialize chokidar watcher with optimized settings
255
- projectsWatcher = chokidar.watch(claudeProjectsPath, {
274
+ projectsWatcher = chokidar.watch(watchRoots, {
256
275
  ignored: [
257
276
  '**/node_modules/**',
258
277
  '**/.git/**',
@@ -287,17 +306,26 @@ async function setupProjectsWatcher() {
287
306
 
288
307
  // Clear project directory cache when files change
289
308
  clearProjectDirectoryCache();
309
+ clearProviderSessionLookupCaches();
290
310
 
291
311
  // Get updated projects list
292
312
  const updatedProjects = await getProjects(broadcastProgress);
293
313
 
294
314
  // Notify all connected clients about the project changes
315
+ const changedProvider = filePath.startsWith(codexSessionsPath)
316
+ ? 'codex'
317
+ : 'claude';
318
+ const changedFileRoot = changedProvider === 'codex'
319
+ ? codexSessionsPath
320
+ : claudeProjectsPath;
295
321
  const updateMessage = JSON.stringify({
296
322
  type: 'projects_updated',
297
323
  projects: updatedProjects,
298
324
  timestamp: new Date().toISOString(),
299
325
  changeType: eventType,
300
- changedFile: path.relative(claudeProjectsPath, filePath)
326
+ changedFile: path.relative(changedFileRoot, filePath),
327
+ changedProvider,
328
+ changedSessionId: extractSessionIdFromChangedFile(filePath)
301
329
  });
302
330
 
303
331
  connectedClients.forEach(client => {
@@ -431,9 +459,6 @@ app.use('/api/git', authenticateToken, gitRoutes);
431
459
  // MCP API Routes (protected)
432
460
  app.use('/api/mcp', authenticateToken, mcpRoutes);
433
461
 
434
- // Cursor API Routes (protected)
435
- app.use('/api/cursor', authenticateToken, cursorRoutes);
436
-
437
462
  // TaskMaster API Routes (protected)
438
463
  app.use('/api/taskmaster', authenticateToken, taskmasterRoutes);
439
464
 
@@ -446,6 +471,9 @@ app.use('/api/commands', authenticateToken, commandsRoutes);
446
471
  // Settings API Routes (protected)
447
472
  app.use('/api/settings', authenticateToken, settingsRoutes);
448
473
 
474
+ // Channels API Routes (protected)
475
+ app.use('/api/channels', authenticateToken, channelsRoutes);
476
+
449
477
  // CLI Authentication API Routes (protected)
450
478
  app.use('/api/cli', authenticateToken, cliAuthRoutes);
451
479
 
@@ -455,6 +483,7 @@ app.use('/api/user', authenticateToken, userRoutes);
455
483
  // Codex API Routes (protected)
456
484
  app.use('/api/codex', authenticateToken, codexRoutes);
457
485
  app.use('/api/opencode', authenticateToken, opencodeRoutes);
486
+ app.use('/api/session-core', authenticateToken, sessionCoreRoutes);
458
487
 
459
488
  // Agent API Routes (uses API key authentication)
460
489
  app.use('/api/agent', agentRoutes);
@@ -1047,11 +1076,13 @@ function handleChatConnection(ws) {
1047
1076
  connectedClients.add(ws);
1048
1077
 
1049
1078
  // Wrap WebSocket with writer for consistent interface with SSEStreamWriter
1050
- const writer = new WebSocketWriter(ws);
1079
+ const baseWriter = new WebSocketWriter(ws);
1080
+ const getSessionWriter = (provider = 'claude') => new SessionEventMirrorWriter(baseWriter, provider);
1051
1081
 
1052
1082
  ws.on('message', async (message) => {
1083
+ let data = null;
1053
1084
  try {
1054
- const data = JSON.parse(message);
1085
+ data = JSON.parse(message);
1055
1086
 
1056
1087
  if (data.type === 'claude-command') {
1057
1088
  console.log('[DEBUG] User message:', data.command || '[Continue/Resume]');
@@ -1059,62 +1090,34 @@ function handleChatConnection(ws) {
1059
1090
  console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New');
1060
1091
 
1061
1092
  // Use Claude Agents SDK
1062
- await queryClaudeSDK(data.command, data.options, writer);
1063
- } else if (data.type === 'cursor-command') {
1064
- console.log('[DEBUG] Cursor message:', data.command || '[Continue/Resume]');
1065
- console.log('📁 Project:', data.options?.cwd || 'Unknown');
1066
- console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New');
1067
- console.log('🤖 Model:', data.options?.model || 'default');
1068
- await spawnCursor(data.command, data.options, writer);
1093
+ await queryClaudeSDK(data.command, data.options, new SessionEventMirrorWriter(baseWriter, 'claude'));
1069
1094
  } else if (data.type === 'codex-command') {
1070
1095
  console.log('[DEBUG] Codex message:', data.command || '[Continue/Resume]');
1071
1096
  console.log('📁 Project:', data.options?.projectPath || data.options?.cwd || 'Unknown');
1072
1097
  console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New');
1073
1098
  console.log('🤖 Model:', data.options?.model || 'default');
1074
- await queryCodex(data.command, data.options, writer);
1099
+ await queryCodex(data.command, data.options, new SessionEventMirrorWriter(baseWriter, 'codex'));
1075
1100
  } else if (data.type === 'gemini-command') {
1076
1101
  console.log('[DEBUG] Gemini message:', data.command || '[Continue/Resume]');
1077
1102
  console.log('📁 Project:', data.options?.projectPath || data.options?.cwd || 'Unknown');
1078
1103
  console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New');
1079
1104
  console.log('🤖 Model:', data.options?.model || 'default');
1080
- await queryGemini(data.command, data.options, writer);
1105
+ await queryGemini(data.command, data.options, new SessionEventMirrorWriter(baseWriter, 'gemini'));
1081
1106
  } else if (data.type === 'opencode-command') {
1082
1107
  console.log('[DEBUG] OpenCode message:', data.command || '[Continue/Resume]');
1083
1108
  console.log('📁 Project:', data.options?.projectPath || data.options?.cwd || 'Unknown');
1084
1109
  console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New');
1085
1110
  console.log('🤖 Model:', data.options?.model || 'default');
1086
- await queryOpencode(data.command, data.options, writer);
1087
- } else if (data.type === 'cursor-resume') {
1088
- // Backward compatibility: treat as cursor-command with resume and no prompt
1089
- console.log('[DEBUG] Cursor resume session (compat):', data.sessionId);
1090
- await spawnCursor('', {
1091
- sessionId: data.sessionId,
1092
- resume: true,
1093
- cwd: data.options?.cwd
1094
- }, writer);
1111
+ await queryOpencode(data.command, data.options, new SessionEventMirrorWriter(baseWriter, 'opencode'));
1095
1112
  } else if (data.type === 'abort-session') {
1096
1113
  console.log('[DEBUG] Abort session request:', data.sessionId);
1097
- const provider = data.provider || 'claude';
1098
- let success;
1099
-
1100
- if (provider === 'cursor') {
1101
- success = abortCursorSession(data.sessionId);
1102
- } else if (provider === 'codex') {
1103
- success = abortCodexSession(data.sessionId);
1104
- } else if (provider === 'gemini') {
1105
- success = abortGeminiSession(data.sessionId);
1106
- } else if (provider === 'opencode') {
1107
- success = abortOpencodeSession(data.sessionId);
1108
- } else {
1109
- // Use Claude Agents SDK
1110
- success = await abortClaudeSDKSession(data.sessionId);
1111
- }
1112
-
1113
- writer.send({
1114
- type: 'session-aborted',
1115
- sessionId: data.sessionId,
1114
+ const provider = typeof data.provider === 'string' && data.provider.trim()
1115
+ ? data.provider.trim().toLowerCase()
1116
+ : 'claude';
1117
+ await abortAgentSessionWithWriter({
1116
1118
  provider,
1117
- success
1119
+ sessionId: data.sessionId,
1120
+ writer: getSessionWriter(provider)
1118
1121
  });
1119
1122
  } else if (data.type === 'claude-permission-response') {
1120
1123
  // Relay UI approval decisions back into the SDK control flow.
@@ -1128,24 +1131,13 @@ function handleChatConnection(ws) {
1128
1131
  rememberEntry: data.rememberEntry
1129
1132
  });
1130
1133
  }
1131
- } else if (data.type === 'cursor-abort') {
1132
- console.log('[DEBUG] Abort Cursor session:', data.sessionId);
1133
- const success = abortCursorSession(data.sessionId);
1134
- writer.send({
1135
- type: 'session-aborted',
1136
- sessionId: data.sessionId,
1137
- provider: 'cursor',
1138
- success
1139
- });
1140
1134
  } else if (data.type === 'check-session-status') {
1141
1135
  // Check if a specific session is currently processing
1142
1136
  const provider = data.provider || 'claude';
1143
1137
  const sessionId = data.sessionId;
1138
+ const sessionWriter = getSessionWriter(provider);
1144
1139
  let isActive;
1145
-
1146
- if (provider === 'cursor') {
1147
- isActive = isCursorSessionActive(sessionId);
1148
- } else if (provider === 'codex') {
1140
+ if (provider === 'codex') {
1149
1141
  isActive = isCodexSessionActive(sessionId);
1150
1142
  } else if (provider === 'gemini') {
1151
1143
  isActive = isGeminiSessionActive(sessionId);
@@ -1156,7 +1148,7 @@ function handleChatConnection(ws) {
1156
1148
  isActive = isClaudeSDKSessionActive(sessionId);
1157
1149
  }
1158
1150
 
1159
- writer.send({
1151
+ sessionWriter.send({
1160
1152
  type: 'session-status',
1161
1153
  sessionId,
1162
1154
  provider,
@@ -1165,22 +1157,22 @@ function handleChatConnection(ws) {
1165
1157
  } else if (data.type === 'get-active-sessions') {
1166
1158
  // Get all currently active sessions
1167
1159
  const activeSessions = {
1168
- claude: getActiveClaudeSDKSessions(),
1169
- cursor: getActiveCursorSessions(),
1170
- codex: getActiveCodexSessions(),
1160
+ claude: getActiveClaudeSDKSessions(), codex: getActiveCodexSessions(),
1171
1161
  gemini: getActiveGeminiSessions(),
1172
1162
  opencode: getActiveOpencodeSessions()
1173
1163
  };
1174
- writer.send({
1164
+ baseWriter.send({
1175
1165
  type: 'active-sessions',
1176
1166
  sessions: activeSessions
1177
1167
  });
1178
1168
  }
1179
1169
  } catch (error) {
1180
1170
  console.error('[ERROR] Chat WebSocket error:', error.message);
1181
- writer.send({
1171
+ baseWriter.send({
1182
1172
  type: 'error',
1183
- error: error.message
1173
+ error: error.message,
1174
+ provider: typeof data?.type === 'string' ? data.type.replace(/-command$/, '') : undefined,
1175
+ sessionId: data?.sessionId || data?.options?.sessionId || null
1184
1176
  });
1185
1177
  }
1186
1178
  });
@@ -1212,11 +1204,9 @@ function handleShellConnection(ws) {
1212
1204
  const initialCommand = data.initialCommand;
1213
1205
  const isPlainShell = data.isPlainShell || (!!initialCommand && !hasSession) || provider === 'plain-shell';
1214
1206
 
1215
- // Login commands (Claude/Cursor auth) should never reuse cached sessions
1207
+ // Login commands should never reuse cached sessions
1216
1208
  const isLoginCommand = initialCommand && (
1217
- initialCommand.includes('setup-token') ||
1218
- initialCommand.includes('cursor-agent login') ||
1219
- initialCommand.includes('auth login')
1209
+ initialCommand.includes('setup-token') || initialCommand.includes('auth login')
1220
1210
  );
1221
1211
 
1222
1212
  // Include command hash in session key so different commands get separate sessions
@@ -1275,7 +1265,7 @@ function handleShellConnection(ws) {
1275
1265
  if (isPlainShell) {
1276
1266
  welcomeMsg = `\x1b[36mStarting terminal in: ${projectPath}\x1b[0m\r\n`;
1277
1267
  } else {
1278
- const providerName = provider === 'cursor' ? 'Cursor' : provider === 'gemini' ? 'Gemini' : 'Claude';
1268
+ const providerName = provider === 'codex' ? 'Codex' : provider === 'gemini' ? 'Gemini' : provider === 'opencode' ? 'OpenCode' : 'Claude';
1279
1269
  welcomeMsg = hasSession ?
1280
1270
  `\x1b[36mResuming ${providerName} session ${sessionId} in: ${projectPath}\x1b[0m\r\n` :
1281
1271
  `\x1b[36mStarting new ${providerName} session in: ${projectPath}\x1b[0m\r\n`;
@@ -1296,21 +1286,6 @@ function handleShellConnection(ws) {
1296
1286
  } else {
1297
1287
  shellCommand = `cd "${projectPath}" && ${initialCommand}`;
1298
1288
  }
1299
- } else if (provider === 'cursor') {
1300
- // Use cursor-agent command
1301
- if (os.platform() === 'win32') {
1302
- if (hasSession && sessionId) {
1303
- shellCommand = `Set-Location -Path "${projectPath}"; cursor-agent --resume="${sessionId}"`;
1304
- } else {
1305
- shellCommand = `Set-Location -Path "${projectPath}"; cursor-agent`;
1306
- }
1307
- } else {
1308
- if (hasSession && sessionId) {
1309
- shellCommand = `cd "${projectPath}" && cursor-agent --resume="${sessionId}"`;
1310
- } else {
1311
- shellCommand = `cd "${projectPath}" && cursor-agent`;
1312
- }
1313
- }
1314
1289
  } else if (provider === 'gemini') {
1315
1290
  if (os.platform() === 'win32') {
1316
1291
  if (hasSession && sessionId) {
@@ -1761,18 +1736,6 @@ app.get('/api/projects/:projectName/sessions/:sessionId/token-usage', authentica
1761
1736
  if (!safeSessionId) {
1762
1737
  return res.status(400).json({ error: 'Invalid sessionId' });
1763
1738
  }
1764
-
1765
- // Handle Cursor sessions - they use SQLite and don't have token usage info
1766
- if (provider === 'cursor') {
1767
- return res.json({
1768
- used: 0,
1769
- total: 0,
1770
- breakdown: { input: 0, cacheCreation: 0, cacheRead: 0 },
1771
- unsupported: true,
1772
- message: 'Token usage tracking not available for Cursor sessions'
1773
- });
1774
- }
1775
-
1776
1739
  // Handle Codex sessions
1777
1740
  if (provider === 'codex') {
1778
1741
  const codexSessionsDir = path.join(homeDir, '.codex', 'sessions');
@@ -2086,16 +2049,31 @@ function clearRuntimeStatusFile() {
2086
2049
  }
2087
2050
 
2088
2051
  function registerShutdownHandlers() {
2089
- process.on('exit', () => {
2052
+ process.on('exit', async () => {
2053
+ try {
2054
+ await getChannelManager().shutdown();
2055
+ } catch (error) {
2056
+ console.warn('[WARN] Failed to shutdown channel manager on exit:', error.message);
2057
+ }
2090
2058
  clearRuntimeStatusFile();
2091
2059
  });
2092
2060
 
2093
- process.on('SIGINT', () => {
2061
+ process.on('SIGINT', async () => {
2062
+ try {
2063
+ await getChannelManager().shutdown();
2064
+ } catch (error) {
2065
+ console.warn('[WARN] Failed to shutdown channel manager on SIGINT:', error.message);
2066
+ }
2094
2067
  clearRuntimeStatusFile();
2095
2068
  process.exit(0);
2096
2069
  });
2097
2070
 
2098
- process.on('SIGTERM', () => {
2071
+ process.on('SIGTERM', async () => {
2072
+ try {
2073
+ await getChannelManager().shutdown();
2074
+ } catch (error) {
2075
+ console.warn('[WARN] Failed to shutdown channel manager on SIGTERM:', error.message);
2076
+ }
2099
2077
  clearRuntimeStatusFile();
2100
2078
  process.exit(0);
2101
2079
  });
@@ -2106,6 +2084,7 @@ async function startServer() {
2106
2084
  try {
2107
2085
  // Initialize authentication database
2108
2086
  await initializeDatabase();
2087
+ await getChannelManager().initialize();
2109
2088
 
2110
2089
  // Check if running in production mode (dist folder exists)
2111
2090
  const distIndexPath = path.join(__dirname, '../dist/index.html');
@@ -7,18 +7,21 @@ import { dirname } from 'path';
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = dirname(__filename);
9
9
 
10
- try {
11
- const envPath = path.join(__dirname, '../.env');
12
- const envFile = fs.readFileSync(envPath, 'utf8');
13
- envFile.split('\n').forEach(line => {
14
- const trimmedLine = line.trim();
15
- if (trimmedLine && !trimmedLine.startsWith('#')) {
16
- const [key, ...valueParts] = trimmedLine.split('=');
17
- if (key && valueParts.length > 0 && !process.env[key]) {
18
- process.env[key] = valueParts.join('=').trim();
10
+ const envPath = path.join(__dirname, '../.env');
11
+
12
+ if (fs.existsSync(envPath)) {
13
+ try {
14
+ const envFile = fs.readFileSync(envPath, 'utf8');
15
+ envFile.split('\n').forEach(line => {
16
+ const trimmedLine = line.trim();
17
+ if (trimmedLine && !trimmedLine.startsWith('#')) {
18
+ const [key, ...valueParts] = trimmedLine.split('=');
19
+ if (key && valueParts.length > 0 && !process.env[key]) {
20
+ process.env[key] = valueParts.join('=').trim();
21
+ }
19
22
  }
20
- }
21
- });
22
- } catch (e) {
23
- console.log('No .env file found or error reading it:', e.message);
23
+ });
24
+ } catch (error) {
25
+ console.warn('[WARN] Failed to read .env file:', error.message);
26
+ }
24
27
  }