@axhub/genie 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. package/README.md +1 -1
  2. package/dist/api-docs.html +6 -6
  3. package/dist/assets/App-BfaNALgf.js +504 -0
  4. package/dist/assets/App-qxJ8_QYu.css +32 -0
  5. package/dist/assets/ReviewApp-DIT2yWk-.js +1 -0
  6. package/dist/assets/_basePickBy-Dz3NcIVK.js +1 -0
  7. package/dist/assets/_baseUniq-DON_Sg7x.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-Y4G80q-l.js +1 -0
  20. package/dist/assets/architectureDiagram-2XIMDMQ5-D_qR4657.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-NsmAlV5_.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-cbOJM4yr.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-C6KNnXlA.js +1 -0
  49. package/dist/assets/chunk-4BX2VUAB-bLBhl74J.js +1 -0
  50. package/dist/assets/chunk-55IACEB6-D8kNkDUO.js +1 -0
  51. package/dist/assets/chunk-FMBD7UC4-BjR6UbXB.js +15 -0
  52. package/dist/assets/chunk-JSJVCQXG-luNqWn64.js +1 -0
  53. package/dist/assets/chunk-KX2RTZJC-CNnKm6dK.js +1 -0
  54. package/dist/assets/chunk-NQ4KR5QH-Cp9gb43u.js +220 -0
  55. package/dist/assets/chunk-QZHKN3VN-HlVYo2Oq.js +1 -0
  56. package/dist/assets/chunk-WL4C6EOR-CjSZoOGO.js +189 -0
  57. package/dist/assets/clarity-D53aC0YG.js +1 -0
  58. package/dist/assets/classDiagram-VBA2DB6C-BQlzzlH7.js +1 -0
  59. package/dist/assets/classDiagram-v2-RAHNMMFH-BQlzzlH7.js +1 -0
  60. package/dist/assets/clojure-P80f7IUj.js +1 -0
  61. package/dist/assets/clone-DMxS3qWP.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-DZWRjeEd.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-yAzUmqI7.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-CvzlIvDJ.js +24 -0
  86. package/dist/assets/diagram-IFDJBPK2-DFMIJpuM.js +43 -0
  87. package/dist/assets/diagram-P4PSJMXO-KL-J3gyb.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-BXszHbTM.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-Ba43NVp6.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-uLHfhCrg.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-BTEuFaiL.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-h2nuWjx4.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-C6BY7XZJ.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-2198VgsK.css +1 -0
  162. package/dist/assets/index-C6Bb2jGF.js +2 -0
  163. package/dist/assets/infoDiagram-LFFYTUFH-BOLfvCIq.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-BRzQ1ee5.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-DXm_VcMy.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-D_oyzopl.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-Q8YoR_E1.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-B3qNg7di.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-BVZ_4MKo.js +988 -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-CjulgYdi.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-8VzrefxA.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-CFh-ijm2.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-BNPlTs5Q.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-C5l_hYst.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-B4a_rQw8.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-Bt4mMmKB.js +1 -0
  307. package/dist/assets/stateDiagram-v2-FVOUBMTO-6NYMazfq.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-CLYvSw_R.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-ksND0hZK.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-Dz7_EqNA.js} +3 -3
  337. package/dist/assets/{vendor-react-C3RJLQGO.js → vendor-react-Cpt6D04s.js} +11 -11
  338. package/dist/assets/vennDiagram-LZ73GAT5-CaQg4oZK.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-C8dCbTeM.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 +35 -21
  364. package/dist/manifest.json +1 -1
  365. package/dist/sw.js +18 -46
  366. package/package.json +12 -8
  367. package/server/bin/codex-sdk-wrapper.js +49 -0
  368. package/server/channels/runtime/AgentRuntimeAdapter.js +2 -5
  369. package/server/channels/store/ChannelStore.js +73 -107
  370. package/server/claude-sdk.js +160 -6
  371. package/server/cli.js +590 -32
  372. package/server/cli.test.js +76 -0
  373. package/server/database/db.js +438 -372
  374. package/server/external-agent/auth.js +88 -0
  375. package/server/external-agent/service.js +1052 -0
  376. package/server/external-agent/service.test.js +41 -0
  377. package/server/external-agent/ws.js +1526 -0
  378. package/server/external-agent/ws.test.js +289 -0
  379. package/server/gemini-cli.js +108 -20
  380. package/server/index.js +115 -121
  381. package/server/load-env.js +16 -13
  382. package/server/openai-codex.js +165 -11
  383. package/server/opencode-cli.js +3 -2
  384. package/server/projects.js +432 -338
  385. package/server/routes/agent.js +347 -459
  386. package/server/routes/auth.js +14 -36
  387. package/server/routes/cli-auth.js +60 -113
  388. package/server/routes/commands.js +16 -26
  389. package/server/routes/git.js +5 -16
  390. package/server/routes/projects.js +2 -7
  391. package/server/routes/session-core.js +177 -0
  392. package/server/session-core/abortSession.js +48 -0
  393. package/server/session-core/eventStore.js +139 -0
  394. package/server/session-core/providerAdapters.js +84 -0
  395. package/server/session-core/providerDiscovery.js +235 -0
  396. package/server/session-core/runtimeState.js +390 -0
  397. package/server/session-core/runtimeWriter.js +59 -0
  398. package/server/utils/agentCallback.js +273 -0
  399. package/server/utils/agentImages.js +253 -0
  400. package/server/utils/codexPath.js +47 -0
  401. package/server/utils/defaultWorkingDirectory.js +34 -0
  402. package/shared/conversationEvents.js +1071 -0
  403. package/shared/modelConstants.js +18 -24
  404. package/dist/assets/index-CVjMty4a.js +0 -902
  405. package/dist/assets/index-eo5scY_Z.css +0 -32
  406. package/server/cursor-cli.js +0 -276
  407. package/server/database/init.sql +0 -98
  408. package/server/routes/cursor.js +0 -795
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
2
  import bcrypt from 'bcrypt';
3
- import { userDb, db } from '../database/db.js';
3
+ import { userDb } from '../database/db.js';
4
4
  import { generateToken, authenticateToken } from '../middleware/auth.js';
5
5
 
6
6
  const router = express.Router();
@@ -33,45 +33,23 @@ router.post('/register', async (req, res) => {
33
33
  return res.status(400).json({ error: 'Username must be at least 3 characters, password at least 6 characters' });
34
34
  }
35
35
 
36
- // Use a transaction to prevent race conditions
37
- db.prepare('BEGIN').run();
38
- try {
39
- // Check if users already exist (only allow one user)
40
- const hasUsers = userDb.hasUsers();
41
- if (hasUsers) {
42
- db.prepare('ROLLBACK').run();
43
- return res.status(403).json({ error: 'User already exists. This is a single-user system.' });
44
- }
45
-
46
- // Hash password
47
- const saltRounds = 12;
48
- const passwordHash = await bcrypt.hash(password, saltRounds);
49
-
50
- // Create user
51
- const user = userDb.createUser(username, passwordHash);
52
-
53
- // Generate token
54
- const token = generateToken(user);
55
-
56
- // Update last login
57
- userDb.updateLastLogin(user.id);
36
+ const saltRounds = 12;
37
+ const passwordHash = await bcrypt.hash(password, saltRounds);
38
+ const user = userDb.registerUser(username, passwordHash);
39
+ const token = generateToken(user);
58
40
 
59
- db.prepare('COMMIT').run();
60
-
61
- res.json({
62
- success: true,
63
- user: { id: user.id, username: user.username },
64
- token
65
- });
66
- } catch (error) {
67
- db.prepare('ROLLBACK').run();
68
- throw error;
69
- }
41
+ res.json({
42
+ success: true,
43
+ user: { id: user.id, username: user.username },
44
+ token
45
+ });
70
46
 
71
47
  } catch (error) {
72
48
  console.error('Registration error:', error);
73
- if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
49
+ if (error.code === 'USERNAME_EXISTS') {
74
50
  res.status(409).json({ error: 'Username already exists' });
51
+ } else if (error.code === 'USER_EXISTS') {
52
+ res.status(403).json({ error: 'User already exists. This is a single-user system.' });
75
53
  } else {
76
54
  res.status(500).json({ error: 'Internal server error' });
77
55
  }
@@ -132,4 +110,4 @@ router.post('/logout', authenticateToken, (req, res) => {
132
110
  res.json({ success: true, message: 'Logged out successfully' });
133
111
  });
134
112
 
135
- export default router;
113
+ export default router;
@@ -3,19 +3,18 @@ import { spawn } from 'child_process';
3
3
  import fs from 'fs/promises';
4
4
  import path from 'path';
5
5
  import os from 'os';
6
+ import { listOpencodeModels } from '../opencode-cli.js';
6
7
 
7
8
  const router = express.Router();
8
9
  const INSTALLATION_CACHE_TTL_MS = 12 * 60 * 60 * 1000;
9
10
  const SUPPORTED_PROVIDER_COMMANDS = {
10
11
  claude: 'claude',
11
- cursor: 'cursor-agent',
12
12
  codex: 'codex',
13
13
  gemini: 'gemini',
14
14
  opencode: 'opencode'
15
15
  };
16
16
  const PROVIDER_INSTALL_HINTS = {
17
17
  claude: 'Install Claude Code CLI: npm i -g @anthropic-ai/claude-code',
18
- cursor: 'Install Cursor Agent CLI: npm i -g @cursor-ai/cursor-agent',
19
18
  codex: 'Install Codex CLI: npm i -g @openai/codex',
20
19
  gemini: 'Install Gemini CLI: npm i -g @google/gemini-cli',
21
20
  opencode: 'Install OpenCode CLI: npm i -g opencode-ai'
@@ -246,25 +245,6 @@ router.get('/claude/status', async (req, res) => {
246
245
  }
247
246
  });
248
247
 
249
- router.get('/cursor/status', async (req, res) => {
250
- try {
251
- const result = await checkCursorStatus();
252
-
253
- res.json({
254
- authenticated: result.authenticated,
255
- email: result.email,
256
- error: result.error
257
- });
258
-
259
- } catch (error) {
260
- console.error('Error checking Cursor auth status:', error);
261
- res.status(500).json({
262
- authenticated: false,
263
- email: null,
264
- error: error.message
265
- });
266
- }
267
- });
268
248
 
269
249
  router.get('/codex/status', async (req, res) => {
270
250
  try {
@@ -329,6 +309,27 @@ async function checkClaudeCredentials() {
329
309
  email: null
330
310
  };
331
311
  } catch (error) {
312
+ try {
313
+ const configPath = path.join(os.homedir(), '.claude', 'config.json');
314
+ const configContent = await fs.readFile(configPath, 'utf8');
315
+ const config = JSON.parse(configContent);
316
+
317
+ if (typeof config?.primaryApiKey === 'string' && config.primaryApiKey.trim()) {
318
+ return {
319
+ authenticated: true,
320
+ email: 'API Key Auth'
321
+ };
322
+ }
323
+ } catch {
324
+ }
325
+
326
+ if (typeof process.env.ANTHROPIC_API_KEY === 'string' && process.env.ANTHROPIC_API_KEY.trim()) {
327
+ return {
328
+ authenticated: true,
329
+ email: 'API Key Auth'
330
+ };
331
+ }
332
+
332
333
  return {
333
334
  authenticated: false,
334
335
  email: null
@@ -336,98 +337,6 @@ async function checkClaudeCredentials() {
336
337
  }
337
338
  }
338
339
 
339
- function checkCursorStatus() {
340
- return new Promise((resolve) => {
341
- let processCompleted = false;
342
-
343
- const timeout = setTimeout(() => {
344
- if (!processCompleted) {
345
- processCompleted = true;
346
- if (childProcess) {
347
- childProcess.kill();
348
- }
349
- resolve({
350
- authenticated: false,
351
- email: null,
352
- error: 'Command timeout'
353
- });
354
- }
355
- }, 5000);
356
-
357
- let childProcess;
358
- try {
359
- childProcess = spawn('cursor-agent', ['status']);
360
- } catch (err) {
361
- clearTimeout(timeout);
362
- processCompleted = true;
363
- resolve({
364
- authenticated: false,
365
- email: null,
366
- error: 'Cursor CLI not found or not installed'
367
- });
368
- return;
369
- }
370
-
371
- let stdout = '';
372
- let stderr = '';
373
-
374
- childProcess.stdout.on('data', (data) => {
375
- stdout += data.toString();
376
- });
377
-
378
- childProcess.stderr.on('data', (data) => {
379
- stderr += data.toString();
380
- });
381
-
382
- childProcess.on('close', (code) => {
383
- if (processCompleted) return;
384
- processCompleted = true;
385
- clearTimeout(timeout);
386
-
387
- if (code === 0) {
388
- const emailMatch = stdout.match(/Logged in as ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i);
389
-
390
- if (emailMatch) {
391
- resolve({
392
- authenticated: true,
393
- email: emailMatch[1],
394
- output: stdout
395
- });
396
- } else if (stdout.includes('Logged in')) {
397
- resolve({
398
- authenticated: true,
399
- email: 'Logged in',
400
- output: stdout
401
- });
402
- } else {
403
- resolve({
404
- authenticated: false,
405
- email: null,
406
- error: 'Not logged in'
407
- });
408
- }
409
- } else {
410
- resolve({
411
- authenticated: false,
412
- email: null,
413
- error: stderr || 'Not logged in'
414
- });
415
- }
416
- });
417
-
418
- childProcess.on('error', (err) => {
419
- if (processCompleted) return;
420
- processCompleted = true;
421
- clearTimeout(timeout);
422
-
423
- resolve({
424
- authenticated: false,
425
- email: null,
426
- error: 'Cursor CLI not found or not installed'
427
- });
428
- });
429
- });
430
- }
431
340
 
432
341
  async function checkCodexCredentials() {
433
342
  try {
@@ -556,6 +465,37 @@ async function checkOpencodeCredentials() {
556
465
  if (anyFileAccessible) {
557
466
  return { authenticated: false, email: null, error: 'Invalid OpenCode credentials format' };
558
467
  }
468
+
469
+ const configCandidates = [
470
+ path.join(os.homedir(), '.config', 'opencode', 'opencode.json'),
471
+ path.join(os.homedir(), '.opencode', 'opencode.json')
472
+ ];
473
+
474
+ for (const configPath of configCandidates) {
475
+ try {
476
+ const raw = await fs.readFile(configPath, 'utf8');
477
+ const config = JSON.parse(raw);
478
+ const providers = config?.provider;
479
+
480
+ if (providers && typeof providers === 'object' && Object.keys(providers).length > 0) {
481
+ return { authenticated: true, email: 'Configured', error: null };
482
+ }
483
+ } catch {
484
+ }
485
+ }
486
+
487
+ try {
488
+ const discovery = await Promise.race([
489
+ listOpencodeModels({ cwd: process.cwd() }),
490
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 8000))
491
+ ]);
492
+
493
+ if (Array.isArray(discovery?.models) && discovery.models.length > 0) {
494
+ return { authenticated: true, email: 'Configured', error: null };
495
+ }
496
+ } catch {
497
+ }
498
+
559
499
  return { authenticated: false, email: null, error: 'OpenCode not configured' };
560
500
  } catch (error) {
561
501
  return { authenticated: false, email: null, error: 'OpenCode not configured' };
@@ -577,4 +517,11 @@ router.get('/opencode/status', async (req, res) => {
577
517
  }
578
518
  });
579
519
 
520
+ export {
521
+ detectProviderInstallationStatus,
522
+ checkClaudeCredentials, checkCodexCredentials,
523
+ checkGeminiCredentials,
524
+ checkOpencodeCredentials
525
+ };
526
+
580
527
  export default router;
@@ -4,8 +4,8 @@ import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import os from 'os';
6
6
  import matter from 'gray-matter';
7
- import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS, GEMINI_MODELS, OPENCODE_MODELS } from '../../shared/modelConstants.js';
8
- import { listOpencodeModels } from '../opencode-cli.js';
7
+ import { CLAUDE_MODELS, CODEX_MODELS, GEMINI_MODELS, OPENCODE_MODELS } from '../../shared/modelConstants.js';
8
+ import { discoverAllProviders } from '../session-core/providerDiscovery.js';
9
9
 
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = path.dirname(__filename);
@@ -184,39 +184,29 @@ Custom commands can be created in:
184
184
  },
185
185
 
186
186
  '/model': async (args, context) => {
187
- // Read available models from centralized constants
188
- const availableModels = {
189
- claude: CLAUDE_MODELS.OPTIONS.map(o => o.value),
190
- cursor: CURSOR_MODELS.OPTIONS.map(o => o.value),
191
- codex: CODEX_MODELS.OPTIONS.map(o => o.value),
192
- gemini: GEMINI_MODELS.OPTIONS.map(o => o.value),
193
- opencode: OPENCODE_MODELS.OPTIONS.map(o => o.value)
194
- };
187
+ const providerDiscovery = await discoverAllProviders({ projectPath: context?.projectPath });
188
+ const availableModels = providerDiscovery.reduce((acc, item) => {
189
+ acc[item.provider] = Array.isArray(item.models) && item.models.length > 0
190
+ ? item.models.map((entry) => entry.id)
191
+ : (item.provider === 'claude'
192
+ ? CLAUDE_MODELS.OPTIONS.map(o => o.value)
193
+ : item.provider === 'codex'
194
+ ? CODEX_MODELS.OPTIONS.map(o => o.value)
195
+ : item.provider === 'gemini'
196
+ ? GEMINI_MODELS.OPTIONS.map(o => o.value)
197
+ : OPENCODE_MODELS.OPTIONS.map(o => o.value));
198
+ return acc;
199
+ }, {});
195
200
 
196
201
  const currentProvider = context?.provider || 'claude';
197
202
  const providerDefaults = {
198
203
  claude: CLAUDE_MODELS.DEFAULT,
199
- cursor: CURSOR_MODELS.DEFAULT,
200
204
  codex: CODEX_MODELS.DEFAULT,
201
205
  gemini: GEMINI_MODELS.DEFAULT,
202
206
  opencode: OPENCODE_MODELS.DEFAULT
203
207
  };
204
208
  const currentModel = context?.model || providerDefaults[currentProvider] || CLAUDE_MODELS.DEFAULT;
205
- let opencodeDiscovery = null;
206
-
207
- if (context?.projectPath) {
208
- try {
209
- opencodeDiscovery = await listOpencodeModels({
210
- projectPath: context?.projectPath,
211
- cwd: context?.projectPath
212
- });
213
- if (opencodeDiscovery.models.length > 0) {
214
- availableModels.opencode = opencodeDiscovery.models;
215
- }
216
- } catch (error) {
217
- console.warn('Failed to query OpenCode runtime models:', error.message);
218
- }
219
- }
209
+ const opencodeDiscovery = providerDiscovery.find((item) => item.provider === 'opencode') || null;
220
210
 
221
211
  return {
222
212
  type: 'builtin',
@@ -5,7 +5,6 @@ import path from 'path';
5
5
  import { promises as fs } from 'fs';
6
6
  import { extractProjectDirectory } from '../projects.js';
7
7
  import { queryClaudeSDK } from '../claude-sdk.js';
8
- import { spawnCursor } from '../cursor-cli.js';
9
8
  import { queryGemini } from '../gemini-cli.js';
10
9
 
11
10
  const router = express.Router();
@@ -520,8 +519,8 @@ router.post('/generate-commit-message', async (req, res) => {
520
519
  }
521
520
 
522
521
  // Validate provider
523
- if (!['claude', 'cursor', 'gemini'].includes(provider)) {
524
- return res.status(400).json({ error: 'provider must be "claude", "cursor", or "gemini"' });
522
+ if (!['claude', 'gemini'].includes(provider)) {
523
+ return res.status(400).json({ error: 'provider must be "claude" or "gemini"' });
525
524
  }
526
525
 
527
526
  try {
@@ -574,10 +573,10 @@ router.post('/generate-commit-message', async (req, res) => {
574
573
  });
575
574
 
576
575
  /**
577
- * Generates a commit message using AI (Claude SDK, Cursor CLI, or Gemini CLI)
576
+ * Generates a commit message using AI (Claude SDK, Codex, Gemini, or OpenCode)
578
577
  * @param {Array<string>} files - List of changed files
579
578
  * @param {string} diffContext - Git diff content
580
- * @param {string} provider - 'claude', 'cursor', or 'gemini'
579
+ * @param {string} provider - 'claude' or 'gemini'
581
580
  * @param {string} projectPath - Project directory path
582
581
  * @returns {Promise<string>} Generated commit message
583
582
  */
@@ -611,7 +610,7 @@ Generate the commit message:`;
611
610
  const parsed = typeof data === 'string' ? JSON.parse(data) : data;
612
611
  console.log('🔍 Writer received message type:', parsed.type);
613
612
 
614
- // Handle different message formats from Claude SDK and Cursor CLI
613
+ // Handle different message formats from supported providers
615
614
  // Claude SDK sends: {type: 'claude-response', data: {message: {content: [...]}}}
616
615
  if (parsed.type === 'claude-response' && parsed.data) {
617
616
  const message = parsed.data.message || parsed.data;
@@ -626,11 +625,6 @@ Generate the commit message:`;
626
625
  }
627
626
  }
628
627
  }
629
- // Cursor CLI sends: {type: 'cursor-output', output: '...'}
630
- else if (parsed.type === 'cursor-output' && parsed.output) {
631
- console.log('✅ Cursor output:', parsed.output.substring(0, 100));
632
- responseText += parsed.output;
633
- }
634
628
  else if (parsed.type === 'claude-response' && parsed.data?.type === 'content_block_delta' && parsed.data?.delta?.text) {
635
629
  responseText += parsed.data.delta.text;
636
630
  }
@@ -657,11 +651,6 @@ Generate the commit message:`;
657
651
  permissionMode: 'bypassPermissions',
658
652
  model: 'sonnet'
659
653
  }, writer);
660
- } else if (provider === 'cursor') {
661
- await spawnCursor(prompt, {
662
- cwd: projectPath,
663
- skipPermissions: true
664
- }, writer);
665
654
  } else if (provider === 'gemini') {
666
655
  await queryGemini(prompt, {
667
656
  cwd: projectPath,
@@ -4,6 +4,7 @@ import path from 'path';
4
4
  import { spawn } from 'child_process';
5
5
  import os from 'os';
6
6
  import { addProjectManually } from '../projects.js';
7
+ import { githubTokensDb } from '../database/db.js';
7
8
 
8
9
  const router = express.Router();
9
10
 
@@ -311,13 +312,7 @@ router.post('/create-workspace', async (req, res) => {
311
312
  * Helper function to get GitHub token from database
312
313
  */
313
314
  async function getGithubTokenById(tokenId, userId) {
314
- const { getDatabase } = await import('../database/db.js');
315
- const db = await getDatabase();
316
-
317
- const credential = await db.get(
318
- 'SELECT * FROM user_credentials WHERE id = ? AND user_id = ? AND credential_type = ? AND is_active = 1',
319
- [tokenId, userId, 'github_token']
320
- );
315
+ const credential = githubTokensDb.getGithubTokenById(userId, tokenId);
321
316
 
322
317
  // Return in the expected format (github_token field for compatibility)
323
318
  if (credential) {
@@ -0,0 +1,177 @@
1
+ import express from 'express';
2
+ import { getProjects } from '../projects.js';
3
+ import { discoverAllProviders, discoverProvider } from '../session-core/providerDiscovery.js';
4
+ import { getProviderAdapter } from '../session-core/providerAdapters.js';
5
+
6
+ const router = express.Router();
7
+
8
+ function flattenProjectSessions(project) {
9
+ const groups = [
10
+ { provider: 'claude', items: project.sessions || [] },
11
+ { provider: 'codex', items: project.codexSessions || [] },
12
+ { provider: 'gemini', items: project.geminiSessions || [] },
13
+ { provider: 'opencode', items: project.opencodeSessions || [] }
14
+ ];
15
+
16
+ return groups.flatMap(({ provider, items }) => items.map((item) => ({ ...item, provider, __provider: provider })))
17
+ .sort((a, b) => new Date(b.lastActivity || b.updated_at || b.createdAt || 0) - new Date(a.lastActivity || a.updated_at || a.createdAt || 0));
18
+ }
19
+
20
+ router.get('/providers', async (req, res) => {
21
+ try {
22
+ const providers = await discoverAllProviders({ projectPath: req.query.projectPath });
23
+ res.json({ success: true, providers });
24
+ } catch (error) {
25
+ res.status(500).json({ success: false, error: error.message });
26
+ }
27
+ });
28
+
29
+ router.get('/providers/:provider', async (req, res) => {
30
+ try {
31
+ const result = await discoverProvider(req.params.provider, { projectPath: req.query.projectPath });
32
+ res.json({ success: true, ...result });
33
+ } catch (error) {
34
+ res.status(500).json({ success: false, error: error.message });
35
+ }
36
+ });
37
+
38
+ router.get('/projects/:projectName/history-index', async (req, res) => {
39
+ try {
40
+ const projects = await getProjects();
41
+ const project = projects.find((entry) => entry.name === req.params.projectName);
42
+ if (!project) {
43
+ return res.status(404).json({ success: false, error: 'Project not found' });
44
+ }
45
+ res.json({ success: true, project: { name: project.name, fullPath: project.fullPath || project.path, displayName: project.displayName || project.name }, sessions: flattenProjectSessions(project) });
46
+ } catch (error) {
47
+ res.status(500).json({ success: false, error: error.message });
48
+ }
49
+ });
50
+
51
+ router.get('/sessions/:sessionId/resolve', async (req, res) => {
52
+ try {
53
+ const projects = await getProjects();
54
+ const requestedSessionId = String(req.params.sessionId || '').trim();
55
+ const providerHint = typeof req.query.provider === 'string' ? req.query.provider.trim().toLowerCase() : '';
56
+
57
+ if (!requestedSessionId) {
58
+ return res.status(400).json({ success: false, error: 'Session id is required' });
59
+ }
60
+
61
+ const providerOrder = [
62
+ providerHint,
63
+ 'codex',
64
+ 'claude',
65
+ 'gemini',
66
+ 'opencode'
67
+ ].filter((provider, index, all) => provider && all.indexOf(provider) === index);
68
+
69
+ const directProjectMatch = projects.find((project) => {
70
+ const flattened = flattenProjectSessions(project);
71
+ return flattened.some((session) => session.id === requestedSessionId);
72
+ });
73
+
74
+ if (directProjectMatch) {
75
+ const flattened = flattenProjectSessions(directProjectMatch);
76
+ const matchedSession = flattened.find((session) => session.id === requestedSessionId);
77
+
78
+ return res.json({
79
+ success: true,
80
+ found: true,
81
+ provider: matchedSession.provider,
82
+ session: matchedSession,
83
+ project: {
84
+ name: directProjectMatch.name,
85
+ fullPath: directProjectMatch.fullPath || directProjectMatch.path,
86
+ path: directProjectMatch.path,
87
+ displayName: directProjectMatch.displayName || directProjectMatch.name
88
+ }
89
+ });
90
+ }
91
+
92
+ for (const provider of providerOrder) {
93
+ const adapter = getProviderAdapter(provider);
94
+
95
+ for (const project of projects) {
96
+ let sessions = [];
97
+
98
+ try {
99
+ if (provider === 'claude') {
100
+ const result = await adapter.listSessions({ projectName: project.name, limit: 1000, offset: 0 });
101
+ sessions = Array.isArray(result) ? result : [];
102
+ } else {
103
+ sessions = await adapter.listSessions({ projectPath: project.fullPath || project.path, limit: 0 });
104
+ }
105
+ } catch (error) {
106
+ continue;
107
+ }
108
+
109
+ const matchedSession = sessions.find((session) => session.id === requestedSessionId);
110
+ if (!matchedSession) {
111
+ continue;
112
+ }
113
+
114
+ return res.json({
115
+ success: true,
116
+ found: true,
117
+ provider,
118
+ session: matchedSession,
119
+ project: {
120
+ name: project.name,
121
+ fullPath: project.fullPath || project.path,
122
+ path: project.path,
123
+ displayName: project.displayName || project.name
124
+ }
125
+ });
126
+ }
127
+ }
128
+
129
+ res.status(404).json({ success: true, found: false });
130
+ } catch (error) {
131
+ res.status(500).json({ success: false, error: error.message });
132
+ }
133
+ });
134
+
135
+ router.get('/sessions/:provider/:sessionId/events', async (req, res) => {
136
+ try {
137
+ const adapter = getProviderAdapter(req.params.provider);
138
+ const parsedLimit = req.query.limit ? parseInt(req.query.limit, 10) : null;
139
+ const parsedOffset = req.query.offset ? parseInt(req.query.offset, 10) : 0;
140
+ const result = await adapter.loadEvents({
141
+ projectName: req.query.projectName,
142
+ projectPath: req.query.projectPath,
143
+ sessionId: req.params.sessionId,
144
+ limit: parsedLimit,
145
+ offset: parsedOffset
146
+ });
147
+
148
+ const events = Array.isArray(result) ? result : (result?.events || result?.messages || []);
149
+ const total = typeof result?.total === 'number' ? result.total : events.length;
150
+ const hasMore = typeof result?.hasMore === 'boolean' ? result.hasMore : false;
151
+ const offset = typeof result?.offset === 'number' ? result.offset : parsedOffset;
152
+ const limit = Object.prototype.hasOwnProperty.call(result || {}, 'limit')
153
+ ? result.limit
154
+ : parsedLimit;
155
+
156
+ const response = {
157
+ success: true,
158
+ provider: req.params.provider,
159
+ sessionId: req.params.sessionId,
160
+ events,
161
+ total,
162
+ hasMore,
163
+ offset,
164
+ limit
165
+ };
166
+
167
+ if (result && typeof result === 'object' && result.tokenUsage) {
168
+ response.tokenUsage = result.tokenUsage;
169
+ }
170
+
171
+ res.json(response);
172
+ } catch (error) {
173
+ res.status(500).json({ success: false, error: error.message });
174
+ }
175
+ });
176
+
177
+ export default router;
@@ -0,0 +1,48 @@
1
+ import { abortClaudeSDKSession } from '../claude-sdk.js';
2
+ import { abortCodexSession } from '../openai-codex.js';
3
+ import { abortGeminiSession } from '../gemini-cli.js';
4
+ import { abortOpencodeSession } from '../opencode-cli.js';
5
+
6
+ export const ABORTABLE_AGENT_PROVIDERS = ['claude', 'codex', 'gemini', 'opencode'];
7
+
8
+ export function isAbortableAgentProvider(provider) {
9
+ return ABORTABLE_AGENT_PROVIDERS.includes(String(provider || '').trim().toLowerCase());
10
+ }
11
+
12
+ export async function abortAgentSession(provider, sessionId) {
13
+ const normalizedProvider = String(provider || 'claude').trim().toLowerCase();
14
+
15
+ if (normalizedProvider === 'codex') {
16
+ return abortCodexSession(sessionId);
17
+ }
18
+
19
+ if (normalizedProvider === 'gemini') {
20
+ return abortGeminiSession(sessionId);
21
+ }
22
+
23
+ if (normalizedProvider === 'opencode') {
24
+ return abortOpencodeSession(sessionId);
25
+ }
26
+
27
+ return abortClaudeSDKSession(sessionId);
28
+ }
29
+
30
+ export async function abortAgentSessionWithWriter({ provider = 'claude', sessionId, writer }) {
31
+ const normalizedProvider = String(provider || 'claude').trim().toLowerCase();
32
+ const success = await abortAgentSession(normalizedProvider, sessionId);
33
+ const payload = {
34
+ type: 'session-aborted',
35
+ sessionId,
36
+ provider: normalizedProvider,
37
+ success
38
+ };
39
+
40
+ if (writer && typeof writer.send === 'function') {
41
+ writer.send(payload);
42
+ }
43
+
44
+ return {
45
+ success,
46
+ payload
47
+ };
48
+ }