@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
@@ -1,361 +1,535 @@
1
- import Database from 'better-sqlite3';
1
+ import crypto from 'crypto';
2
2
  import path from 'path';
3
3
  import fs from 'fs';
4
- import crypto from 'crypto';
5
4
  import { fileURLToPath } from 'url';
6
5
  import { dirname } from 'path';
7
6
 
8
7
  const __filename = fileURLToPath(import.meta.url);
9
8
  const __dirname = dirname(__filename);
10
9
 
11
- // ANSI color codes for terminal output
12
10
  const colors = {
13
- reset: '\x1b[0m',
14
- bright: '\x1b[1m',
15
- cyan: '\x1b[36m',
16
- dim: '\x1b[2m',
11
+ reset: '\x1b[0m',
12
+ bright: '\x1b[1m',
13
+ cyan: '\x1b[36m',
14
+ dim: '\x1b[2m',
17
15
  };
18
16
 
19
17
  const c = {
20
- info: (text) => `${colors.cyan}${text}${colors.reset}`,
21
- bright: (text) => `${colors.bright}${text}${colors.reset}`,
22
- dim: (text) => `${colors.dim}${text}${colors.reset}`,
18
+ info: (text) => `${colors.cyan}${text}${colors.reset}`,
19
+ bright: (text) => `${colors.bright}${text}${colors.reset}`,
20
+ dim: (text) => `${colors.dim}${text}${colors.reset}`,
23
21
  };
24
22
 
25
- // Use DATABASE_PATH environment variable if set, otherwise use default location
26
- const DB_PATH = process.env.DATABASE_PATH || path.join(__dirname, 'auth.db');
27
- const INIT_SQL_PATH = path.join(__dirname, 'init.sql');
28
-
29
- // Ensure database directory exists if custom path is provided
30
- if (process.env.DATABASE_PATH) {
31
- const dbDir = path.dirname(DB_PATH);
32
- try {
33
- if (!fs.existsSync(dbDir)) {
34
- fs.mkdirSync(dbDir, { recursive: true });
35
- console.log(`Created database directory: ${dbDir}`);
36
- }
37
- } catch (error) {
38
- console.error(`Failed to create database directory ${dbDir}:`, error.message);
39
- throw error;
23
+ const DATA_FILE_PATH = process.env.DATA_FILE_PATH || path.join(__dirname, 'state.json');
24
+ const appInstallPath = path.join(__dirname, '../..');
25
+
26
+ const DEFAULT_STATE = Object.freeze({
27
+ meta: {
28
+ version: 1,
29
+ counters: {
30
+ userId: 0,
31
+ apiKeyId: 0,
32
+ credentialId: 0,
33
+ allowedUserId: 0,
34
+ },
35
+ },
36
+ users: [],
37
+ apiKeys: [],
38
+ credentials: [],
39
+ channelPlugins: [],
40
+ channelAllowedUsers: [],
41
+ channelSessions: [],
42
+ });
43
+
44
+ let stateCache = null;
45
+
46
+ function cloneDefaultState() {
47
+ return JSON.parse(JSON.stringify(DEFAULT_STATE));
48
+ }
49
+
50
+ function ensureDataDirectory() {
51
+ const dataDir = path.dirname(DATA_FILE_PATH);
52
+ if (!fs.existsSync(dataDir)) {
53
+ fs.mkdirSync(dataDir, { recursive: true });
54
+ console.log(`Created data directory: ${dataDir}`);
40
55
  }
41
56
  }
42
57
 
43
- // Create database connection
44
- const db = new Database(DB_PATH);
58
+ function normalizeState(rawState) {
59
+ const nextState = cloneDefaultState();
60
+ const source = rawState && typeof rawState === 'object' ? rawState : {};
61
+ const meta = source.meta && typeof source.meta === 'object' ? source.meta : {};
62
+ const counters = meta.counters && typeof meta.counters === 'object' ? meta.counters : {};
63
+
64
+ nextState.meta.version = Number.isFinite(Number(meta.version)) ? Number(meta.version) : 1;
65
+ nextState.meta.counters.userId = Number.isFinite(Number(counters.userId)) ? Number(counters.userId) : 0;
66
+ nextState.meta.counters.apiKeyId = Number.isFinite(Number(counters.apiKeyId)) ? Number(counters.apiKeyId) : 0;
67
+ nextState.meta.counters.credentialId = Number.isFinite(Number(counters.credentialId)) ? Number(counters.credentialId) : 0;
68
+ nextState.meta.counters.allowedUserId = Number.isFinite(Number(counters.allowedUserId)) ? Number(counters.allowedUserId) : 0;
69
+
70
+ nextState.users = Array.isArray(source.users) ? source.users : [];
71
+ nextState.apiKeys = Array.isArray(source.apiKeys) ? source.apiKeys : [];
72
+ nextState.credentials = Array.isArray(source.credentials) ? source.credentials : [];
73
+ nextState.channelPlugins = Array.isArray(source.channelPlugins) ? source.channelPlugins : [];
74
+ nextState.channelAllowedUsers = Array.isArray(source.channelAllowedUsers) ? source.channelAllowedUsers : [];
75
+ nextState.channelSessions = Array.isArray(source.channelSessions) ? source.channelSessions : [];
76
+
77
+ return nextState;
78
+ }
45
79
 
46
- // Show app installation path prominently
47
- const appInstallPath = path.join(__dirname, '../..');
48
- console.log('');
49
- console.log(c.dim(''.repeat(60)));
50
- console.log(`${c.info('[INFO]')} App Installation: ${c.bright(appInstallPath)}`);
51
- console.log(`${c.info('[INFO]')} Database: ${c.dim(path.relative(appInstallPath, DB_PATH))}`);
52
- if (process.env.DATABASE_PATH) {
53
- console.log(` ${c.dim('(Using custom DATABASE_PATH from environment)')}`);
80
+ function persistStateSync(nextState) {
81
+ ensureDataDirectory();
82
+ const tempPath = `${DATA_FILE_PATH}.tmp`;
83
+ fs.writeFileSync(tempPath, `${JSON.stringify(nextState, null, 2)}\n`, 'utf8');
84
+ fs.renameSync(tempPath, DATA_FILE_PATH);
85
+ stateCache = nextState;
54
86
  }
55
- console.log(c.dim('═'.repeat(60)));
56
- console.log('');
57
87
 
58
- const runMigrations = () => {
59
- try {
60
- const tableInfo = db.prepare("PRAGMA table_info(users)").all();
61
- const columnNames = tableInfo.map(col => col.name);
88
+ function loadStateSync() {
89
+ ensureDataDirectory();
62
90
 
63
- if (!columnNames.includes('git_name')) {
64
- console.log('Running migration: Adding git_name column');
65
- db.exec('ALTER TABLE users ADD COLUMN git_name TEXT');
66
- }
91
+ if (stateCache) {
92
+ return stateCache;
93
+ }
67
94
 
68
- if (!columnNames.includes('git_email')) {
69
- console.log('Running migration: Adding git_email column');
70
- db.exec('ALTER TABLE users ADD COLUMN git_email TEXT');
71
- }
95
+ if (!fs.existsSync(DATA_FILE_PATH)) {
96
+ const initialState = cloneDefaultState();
97
+ persistStateSync(initialState);
98
+ return initialState;
99
+ }
72
100
 
73
- if (!columnNames.includes('has_completed_onboarding')) {
74
- console.log('Running migration: Adding has_completed_onboarding column');
75
- db.exec('ALTER TABLE users ADD COLUMN has_completed_onboarding BOOLEAN DEFAULT 0');
76
- }
101
+ const raw = fs.readFileSync(DATA_FILE_PATH, 'utf8').trim();
102
+ const parsed = raw ? JSON.parse(raw) : {};
103
+ const normalized = normalizeState(parsed);
77
104
 
78
- console.log('Database migrations completed successfully');
79
- } catch (error) {
80
- console.error('Error running migrations:', error.message);
81
- throw error;
105
+ if (JSON.stringify(parsed || {}) !== JSON.stringify(normalized)) {
106
+ persistStateSync(normalized);
107
+ return normalized;
82
108
  }
83
- };
84
109
 
85
- // Initialize database with schema
86
- const initializeDatabase = async () => {
87
- try {
88
- const initSQL = fs.readFileSync(INIT_SQL_PATH, 'utf8');
89
- db.exec(initSQL);
90
- console.log('Database initialized successfully');
91
- runMigrations();
92
- } catch (error) {
93
- console.error('Error initializing database:', error.message);
94
- throw error;
110
+ stateCache = normalized;
111
+ return normalized;
112
+ }
113
+
114
+ function getStateSnapshot() {
115
+ return loadStateSync();
116
+ }
117
+
118
+ function updateStateSync(mutator) {
119
+ const currentState = getStateSnapshot();
120
+ const workingCopy = JSON.parse(JSON.stringify(currentState));
121
+ const result = mutator(workingCopy);
122
+ persistStateSync(workingCopy);
123
+ return result;
124
+ }
125
+
126
+ function nextCounter(state, key) {
127
+ state.meta.counters[key] = Number(state.meta.counters[key] || 0) + 1;
128
+ return state.meta.counters[key];
129
+ }
130
+
131
+ function nowIso() {
132
+ return new Date().toISOString();
133
+ }
134
+
135
+ function sanitizeActiveUser(user) {
136
+ if (!user || user.is_active === false) {
137
+ return null;
95
138
  }
96
- };
97
139
 
98
- // User database operations
140
+ return user;
141
+ }
142
+
143
+ function toUserPublic(user) {
144
+ const activeUser = sanitizeActiveUser(user);
145
+ if (!activeUser) return null;
146
+ return {
147
+ id: activeUser.id,
148
+ username: activeUser.username,
149
+ created_at: activeUser.created_at,
150
+ last_login: activeUser.last_login,
151
+ };
152
+ }
153
+
154
+ function findActiveUserById(state, userId) {
155
+ return sanitizeActiveUser(state.users.find((user) => user.id === userId));
156
+ }
157
+
158
+ function findActiveUserByUsername(state, username) {
159
+ return sanitizeActiveUser(state.users.find((user) => user.username === username));
160
+ }
161
+
99
162
  const userDb = {
100
- // Check if any users exist
101
- hasUsers: () => {
102
- try {
103
- const row = db.prepare('SELECT COUNT(*) as count FROM users').get();
104
- return row.count > 0;
105
- } catch (err) {
106
- throw err;
107
- }
108
- },
163
+ hasUsers: () => getStateSnapshot().users.some((user) => user.is_active !== false),
109
164
 
110
- // Create a new user
111
- createUser: (username, passwordHash) => {
112
- try {
113
- const stmt = db.prepare('INSERT INTO users (username, password_hash) VALUES (?, ?)');
114
- const result = stmt.run(username, passwordHash);
115
- return { id: result.lastInsertRowid, username };
116
- } catch (err) {
117
- throw err;
165
+ registerUser: (username, passwordHash) => updateStateSync((state) => {
166
+ if (state.users.some((user) => user.is_active !== false)) {
167
+ const error = new Error('User already exists. This is a single-user system.');
168
+ error.code = 'USER_EXISTS';
169
+ throw error;
118
170
  }
119
- },
120
171
 
121
- // Get user by username
122
- getUserByUsername: (username) => {
123
- try {
124
- const row = db.prepare('SELECT * FROM users WHERE username = ? AND is_active = 1').get(username);
125
- return row;
126
- } catch (err) {
127
- throw err;
172
+ if (state.users.some((user) => user.username === username)) {
173
+ const error = new Error('Username already exists');
174
+ error.code = 'USERNAME_EXISTS';
175
+ throw error;
128
176
  }
129
- },
130
177
 
131
- // Update last login time
132
- updateLastLogin: (userId) => {
133
- try {
134
- db.prepare('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?').run(userId);
135
- } catch (err) {
136
- throw err;
178
+ const timestamp = nowIso();
179
+ const user = {
180
+ id: nextCounter(state, 'userId'),
181
+ username,
182
+ password_hash: passwordHash,
183
+ created_at: timestamp,
184
+ last_login: timestamp,
185
+ is_active: true,
186
+ git_name: null,
187
+ git_email: null,
188
+ has_completed_onboarding: false,
189
+ };
190
+
191
+ state.users.push(user);
192
+ return { id: user.id, username: user.username };
193
+ }),
194
+
195
+ createUser: (username, passwordHash) => updateStateSync((state) => {
196
+ if (state.users.some((user) => user.username === username)) {
197
+ const error = new Error('Username already exists');
198
+ error.code = 'USERNAME_EXISTS';
199
+ throw error;
137
200
  }
138
- },
139
201
 
140
- // Get user by ID
141
- getUserById: (userId) => {
142
- try {
143
- const row = db.prepare('SELECT id, username, created_at, last_login FROM users WHERE id = ? AND is_active = 1').get(userId);
144
- return row;
145
- } catch (err) {
146
- throw err;
202
+ const user = {
203
+ id: nextCounter(state, 'userId'),
204
+ username,
205
+ password_hash: passwordHash,
206
+ created_at: nowIso(),
207
+ last_login: null,
208
+ is_active: true,
209
+ git_name: null,
210
+ git_email: null,
211
+ has_completed_onboarding: false,
212
+ };
213
+ state.users.push(user);
214
+ return { id: user.id, username: user.username };
215
+ }),
216
+
217
+ getUserByUsername: (username) => findActiveUserByUsername(getStateSnapshot(), username) || null,
218
+
219
+ updateLastLogin: (userId) => updateStateSync((state) => {
220
+ const user = findActiveUserById(state, userId);
221
+ if (user) {
222
+ user.last_login = nowIso();
147
223
  }
148
- },
224
+ }),
225
+
226
+ getUserById: (userId) => toUserPublic(findActiveUserById(getStateSnapshot(), userId)),
149
227
 
150
228
  getFirstUser: () => {
151
- try {
152
- const row = db.prepare('SELECT id, username, created_at, last_login FROM users WHERE is_active = 1 LIMIT 1').get();
153
- return row;
154
- } catch (err) {
155
- throw err;
156
- }
229
+ const user = getStateSnapshot().users.find((entry) => entry.is_active !== false);
230
+ return toUserPublic(user);
157
231
  },
158
232
 
159
- updateGitConfig: (userId, gitName, gitEmail) => {
160
- try {
161
- const stmt = db.prepare('UPDATE users SET git_name = ?, git_email = ? WHERE id = ?');
162
- stmt.run(gitName, gitEmail, userId);
163
- } catch (err) {
164
- throw err;
165
- }
166
- },
233
+ updateGitConfig: (userId, gitName, gitEmail) => updateStateSync((state) => {
234
+ const user = findActiveUserById(state, userId);
235
+ if (!user) return;
236
+ user.git_name = gitName || null;
237
+ user.git_email = gitEmail || null;
238
+ }),
167
239
 
168
240
  getGitConfig: (userId) => {
169
- try {
170
- const row = db.prepare('SELECT git_name, git_email FROM users WHERE id = ?').get(userId);
171
- return row;
172
- } catch (err) {
173
- throw err;
241
+ const user = findActiveUserById(getStateSnapshot(), userId);
242
+ if (!user) {
243
+ return null;
174
244
  }
245
+ return {
246
+ git_name: user.git_name || null,
247
+ git_email: user.git_email || null,
248
+ };
175
249
  },
176
250
 
177
- completeOnboarding: (userId) => {
178
- try {
179
- const stmt = db.prepare('UPDATE users SET has_completed_onboarding = 1 WHERE id = ?');
180
- stmt.run(userId);
181
- } catch (err) {
182
- throw err;
251
+ completeOnboarding: (userId) => updateStateSync((state) => {
252
+ const user = findActiveUserById(state, userId);
253
+ if (user) {
254
+ user.has_completed_onboarding = true;
183
255
  }
184
- },
256
+ }),
185
257
 
186
258
  hasCompletedOnboarding: (userId) => {
187
- try {
188
- const row = db.prepare('SELECT has_completed_onboarding FROM users WHERE id = ?').get(userId);
189
- return row?.has_completed_onboarding === 1;
190
- } catch (err) {
191
- throw err;
192
- }
193
- }
259
+ const user = findActiveUserById(getStateSnapshot(), userId);
260
+ return !!user?.has_completed_onboarding;
261
+ },
194
262
  };
195
263
 
196
- // API Keys database operations
197
264
  const apiKeysDb = {
198
- // Generate a new API key
199
- generateApiKey: () => {
200
- return 'ck_' + crypto.randomBytes(32).toString('hex');
201
- },
202
-
203
- // Create a new API key
204
- createApiKey: (userId, keyName) => {
205
- try {
206
- const apiKey = apiKeysDb.generateApiKey();
207
- const stmt = db.prepare('INSERT INTO api_keys (user_id, key_name, api_key) VALUES (?, ?, ?)');
208
- const result = stmt.run(userId, keyName, apiKey);
209
- return { id: result.lastInsertRowid, keyName, apiKey };
210
- } catch (err) {
211
- throw err;
265
+ generateApiKey: () => `ck_${crypto.randomBytes(32).toString('hex')}`,
266
+
267
+ createApiKey: (userId, keyName) => updateStateSync((state) => {
268
+ const timestamp = nowIso();
269
+ const entry = {
270
+ id: nextCounter(state, 'apiKeyId'),
271
+ user_id: userId,
272
+ key_name: keyName,
273
+ api_key: apiKeysDb.generateApiKey(),
274
+ created_at: timestamp,
275
+ last_used: null,
276
+ is_active: true,
277
+ };
278
+ state.apiKeys.push(entry);
279
+ return { id: entry.id, keyName: entry.key_name, apiKey: entry.api_key };
280
+ }),
281
+
282
+ getApiKeys: (userId) => getStateSnapshot().apiKeys
283
+ .filter((entry) => entry.user_id === userId)
284
+ .sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))
285
+ .map((entry) => ({ ...entry })),
286
+
287
+ validateApiKey: (apiKey) => updateStateSync((state) => {
288
+ const entry = state.apiKeys.find((item) => item.api_key === apiKey && item.is_active !== false);
289
+ if (!entry) {
290
+ return null;
212
291
  }
213
- },
214
292
 
215
- // Get all API keys for a user
216
- getApiKeys: (userId) => {
217
- try {
218
- const rows = db.prepare('SELECT id, key_name, api_key, created_at, last_used, is_active FROM api_keys WHERE user_id = ? ORDER BY created_at DESC').all(userId);
219
- return rows;
220
- } catch (err) {
221
- throw err;
293
+ const user = findActiveUserById(state, entry.user_id);
294
+ if (!user) {
295
+ return null;
222
296
  }
223
- },
224
297
 
225
- // Validate API key and get user
226
- validateApiKey: (apiKey) => {
227
- try {
228
- const row = db.prepare(`
229
- SELECT u.id, u.username, ak.id as api_key_id
230
- FROM api_keys ak
231
- JOIN users u ON ak.user_id = u.id
232
- WHERE ak.api_key = ? AND ak.is_active = 1 AND u.is_active = 1
233
- `).get(apiKey);
234
-
235
- if (row) {
236
- // Update last_used timestamp
237
- db.prepare('UPDATE api_keys SET last_used = CURRENT_TIMESTAMP WHERE id = ?').run(row.api_key_id);
238
- }
298
+ entry.last_used = nowIso();
239
299
 
240
- return row;
241
- } catch (err) {
242
- throw err;
243
- }
244
- },
300
+ return {
301
+ id: user.id,
302
+ username: user.username,
303
+ api_key_id: entry.id,
304
+ };
305
+ }),
245
306
 
246
- // Delete an API key
247
- deleteApiKey: (userId, apiKeyId) => {
248
- try {
249
- const stmt = db.prepare('DELETE FROM api_keys WHERE id = ? AND user_id = ?');
250
- const result = stmt.run(apiKeyId, userId);
251
- return result.changes > 0;
252
- } catch (err) {
253
- throw err;
307
+ deleteApiKey: (userId, apiKeyId) => updateStateSync((state) => {
308
+ const index = state.apiKeys.findIndex((entry) => entry.id === apiKeyId && entry.user_id === userId);
309
+ if (index < 0) {
310
+ return false;
254
311
  }
255
- },
256
-
257
- // Toggle API key active status
258
- toggleApiKey: (userId, apiKeyId, isActive) => {
259
- try {
260
- const stmt = db.prepare('UPDATE api_keys SET is_active = ? WHERE id = ? AND user_id = ?');
261
- const result = stmt.run(isActive ? 1 : 0, apiKeyId, userId);
262
- return result.changes > 0;
263
- } catch (err) {
264
- throw err;
312
+ state.apiKeys.splice(index, 1);
313
+ return true;
314
+ }),
315
+
316
+ toggleApiKey: (userId, apiKeyId, isActive) => updateStateSync((state) => {
317
+ const entry = state.apiKeys.find((item) => item.id === apiKeyId && item.user_id === userId);
318
+ if (!entry) {
319
+ return false;
265
320
  }
266
- }
321
+ entry.is_active = !!isActive;
322
+ return true;
323
+ }),
267
324
  };
268
325
 
269
- // User credentials database operations (for GitHub tokens, GitLab tokens, etc.)
270
326
  const credentialsDb = {
271
- // Create a new credential
272
- createCredential: (userId, credentialName, credentialType, credentialValue, description = null) => {
273
- try {
274
- const stmt = db.prepare('INSERT INTO user_credentials (user_id, credential_name, credential_type, credential_value, description) VALUES (?, ?, ?, ?, ?)');
275
- const result = stmt.run(userId, credentialName, credentialType, credentialValue, description);
276
- return { id: result.lastInsertRowid, credentialName, credentialType };
277
- } catch (err) {
278
- throw err;
279
- }
327
+ createCredential: (userId, credentialName, credentialType, credentialValue, description = null) => updateStateSync((state) => {
328
+ const entry = {
329
+ id: nextCounter(state, 'credentialId'),
330
+ user_id: userId,
331
+ credential_name: credentialName,
332
+ credential_type: credentialType,
333
+ credential_value: credentialValue,
334
+ description,
335
+ created_at: nowIso(),
336
+ is_active: true,
337
+ };
338
+ state.credentials.push(entry);
339
+ return { id: entry.id, credentialName: entry.credential_name, credentialType: entry.credential_type };
340
+ }),
341
+
342
+ getCredentials: (userId, credentialType = null) => getStateSnapshot().credentials
343
+ .filter((entry) => entry.user_id === userId && (!credentialType || entry.credential_type === credentialType))
344
+ .sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))
345
+ .map(({ credential_value, ...rest }) => ({ ...rest })),
346
+
347
+ getActiveCredential: (userId, credentialType) => {
348
+ const match = getStateSnapshot().credentials
349
+ .filter((entry) => entry.user_id === userId && entry.credential_type === credentialType && entry.is_active !== false)
350
+ .sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))[0];
351
+ return match?.credential_value || null;
280
352
  },
281
353
 
282
- // Get all credentials for a user, optionally filtered by type
283
- getCredentials: (userId, credentialType = null) => {
284
- try {
285
- let query = 'SELECT id, credential_name, credential_type, description, created_at, is_active FROM user_credentials WHERE user_id = ?';
286
- const params = [userId];
354
+ getCredentialById: (userId, credentialId, credentialType = null) => {
355
+ const entry = getStateSnapshot().credentials.find((item) => (
356
+ item.id === credentialId
357
+ && item.user_id === userId
358
+ && item.is_active !== false
359
+ && (!credentialType || item.credential_type === credentialType)
360
+ ));
361
+ return entry ? { ...entry } : null;
362
+ },
287
363
 
288
- if (credentialType) {
289
- query += ' AND credential_type = ?';
290
- params.push(credentialType);
291
- }
364
+ deleteCredential: (userId, credentialId) => updateStateSync((state) => {
365
+ const index = state.credentials.findIndex((entry) => entry.id === credentialId && entry.user_id === userId);
366
+ if (index < 0) {
367
+ return false;
368
+ }
369
+ state.credentials.splice(index, 1);
370
+ return true;
371
+ }),
372
+
373
+ toggleCredential: (userId, credentialId, isActive) => updateStateSync((state) => {
374
+ const entry = state.credentials.find((item) => item.id === credentialId && item.user_id === userId);
375
+ if (!entry) {
376
+ return false;
377
+ }
378
+ entry.is_active = !!isActive;
379
+ return true;
380
+ }),
381
+ };
292
382
 
293
- query += ' ORDER BY created_at DESC';
383
+ const githubTokensDb = {
384
+ createGithubToken: (userId, tokenName, githubToken, description = null) => credentialsDb.createCredential(userId, tokenName, 'github_token', githubToken, description),
385
+ getGithubTokens: (userId) => credentialsDb.getCredentials(userId, 'github_token'),
386
+ getActiveGithubToken: (userId) => credentialsDb.getActiveCredential(userId, 'github_token'),
387
+ getGithubTokenById: (userId, tokenId) => credentialsDb.getCredentialById(userId, tokenId, 'github_token'),
388
+ deleteGithubToken: (userId, tokenId) => credentialsDb.deleteCredential(userId, tokenId),
389
+ toggleGithubToken: (userId, tokenId, isActive) => credentialsDb.toggleCredential(userId, tokenId, isActive),
390
+ };
294
391
 
295
- const rows = db.prepare(query).all(...params);
296
- return rows;
297
- } catch (err) {
298
- throw err;
299
- }
392
+ const channelDb = {
393
+ getPlugin(pluginId) {
394
+ return getStateSnapshot().channelPlugins.find((entry) => entry.id === pluginId) || null;
300
395
  },
301
396
 
302
- // Get active credential value for a user by type (returns most recent active)
303
- getActiveCredential: (userId, credentialType) => {
304
- try {
305
- const row = db.prepare('SELECT credential_value FROM user_credentials WHERE user_id = ? AND credential_type = ? AND is_active = 1 ORDER BY created_at DESC LIMIT 1').get(userId, credentialType);
306
- return row?.credential_value || null;
307
- } catch (err) {
308
- throw err;
309
- }
397
+ upsertPlugin(plugin) {
398
+ return updateStateSync((state) => {
399
+ const index = state.channelPlugins.findIndex((entry) => entry.id === plugin.id);
400
+ if (index >= 0) {
401
+ state.channelPlugins[index] = { ...state.channelPlugins[index], ...plugin };
402
+ } else {
403
+ state.channelPlugins.push({ ...plugin });
404
+ }
405
+ return { ...state.channelPlugins.find((entry) => entry.id === plugin.id) };
406
+ });
310
407
  },
311
408
 
312
- // Delete a credential
313
- deleteCredential: (userId, credentialId) => {
314
- try {
315
- const stmt = db.prepare('DELETE FROM user_credentials WHERE id = ? AND user_id = ?');
316
- const result = stmt.run(credentialId, userId);
317
- return result.changes > 0;
318
- } catch (err) {
319
- throw err;
320
- }
409
+ listAllowedUsers(platform) {
410
+ return getStateSnapshot().channelAllowedUsers
411
+ .filter((entry) => entry.platform_type === platform)
412
+ .sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))
413
+ .map((entry) => ({ ...entry }));
321
414
  },
322
415
 
323
- // Toggle credential active status
324
- toggleCredential: (userId, credentialId, isActive) => {
325
- try {
326
- const stmt = db.prepare('UPDATE user_credentials SET is_active = ? WHERE id = ? AND user_id = ?');
327
- const result = stmt.run(isActive ? 1 : 0, credentialId, userId);
328
- return result.changes > 0;
329
- } catch (err) {
330
- throw err;
331
- }
332
- }
333
- };
416
+ addAllowedUser(platform, { userId, displayName = null, note = null }) {
417
+ return updateStateSync((state) => {
418
+ const duplicate = state.channelAllowedUsers.find((entry) => entry.platform_type === platform && entry.user_id === userId);
419
+ if (duplicate) {
420
+ const error = new Error('Allowed user already exists');
421
+ error.code = 'CHANNEL_ALLOWED_USER_EXISTS';
422
+ throw error;
423
+ }
334
424
 
335
- // Backward compatibility - keep old names pointing to new system
336
- const githubTokensDb = {
337
- createGithubToken: (userId, tokenName, githubToken, description = null) => {
338
- return credentialsDb.createCredential(userId, tokenName, 'github_token', githubToken, description);
425
+ const timestamp = nowIso();
426
+ const entry = {
427
+ id: nextCounter(state, 'allowedUserId'),
428
+ platform_type: platform,
429
+ user_id: userId,
430
+ display_name: displayName,
431
+ note,
432
+ is_active: true,
433
+ created_at: timestamp,
434
+ updated_at: timestamp,
435
+ };
436
+ state.channelAllowedUsers.push(entry);
437
+ return { ...entry };
438
+ });
339
439
  },
340
- getGithubTokens: (userId) => {
341
- return credentialsDb.getCredentials(userId, 'github_token');
440
+
441
+ removeAllowedUser(platform, id) {
442
+ return updateStateSync((state) => {
443
+ const index = state.channelAllowedUsers.findIndex((entry) => entry.platform_type === platform && entry.id === id);
444
+ if (index < 0) return false;
445
+ state.channelAllowedUsers.splice(index, 1);
446
+ return true;
447
+ });
342
448
  },
343
- getActiveGithubToken: (userId) => {
344
- return credentialsDb.getActiveCredential(userId, 'github_token');
449
+
450
+ toggleAllowedUser(platform, id, isActive) {
451
+ return updateStateSync((state) => {
452
+ const entry = state.channelAllowedUsers.find((item) => item.platform_type === platform && item.id === id);
453
+ if (!entry) return false;
454
+ entry.is_active = !!isActive;
455
+ entry.updated_at = nowIso();
456
+ return true;
457
+ });
345
458
  },
346
- deleteGithubToken: (userId, tokenId) => {
347
- return credentialsDb.deleteCredential(userId, tokenId);
459
+
460
+ isAllowedUser(platform, userId) {
461
+ return !!getStateSnapshot().channelAllowedUsers.find((entry) => entry.platform_type === platform && entry.user_id === userId && entry.is_active !== false);
462
+ },
463
+
464
+ getChannelSession({ platform, userId, chatId, backend }) {
465
+ const entry = getStateSnapshot().channelSessions.find((item) => (
466
+ item.platform_type === platform
467
+ && item.user_id === userId
468
+ && item.chat_id === chatId
469
+ && item.backend === backend
470
+ ));
471
+ return entry ? { ...entry } : null;
472
+ },
473
+
474
+ upsertChannelSession({ platform, userId, chatId, backend, providerSessionId, projectPath }) {
475
+ return updateStateSync((state) => {
476
+ const timestamp = nowIso();
477
+ const existing = state.channelSessions.find((item) => (
478
+ item.platform_type === platform
479
+ && item.user_id === userId
480
+ && item.chat_id === chatId
481
+ && item.backend === backend
482
+ ));
483
+
484
+ if (existing) {
485
+ existing.provider_session_id = providerSessionId || null;
486
+ existing.project_path = projectPath || null;
487
+ existing.updated_at = timestamp;
488
+ return { ...existing };
489
+ }
490
+
491
+ const entry = {
492
+ id: crypto.randomUUID(),
493
+ platform_type: platform,
494
+ user_id: userId,
495
+ chat_id: chatId,
496
+ backend,
497
+ provider_session_id: providerSessionId || null,
498
+ project_path: projectPath || null,
499
+ updated_at: timestamp,
500
+ };
501
+ state.channelSessions.push(entry);
502
+ return { ...entry };
503
+ });
348
504
  },
349
- toggleGithubToken: (userId, tokenId, isActive) => {
350
- return credentialsDb.toggleCredential(userId, tokenId, isActive);
351
- }
352
505
  };
353
506
 
507
+ async function initializeDatabase() {
508
+ const state = getStateSnapshot();
509
+
510
+ console.log('');
511
+ console.log(c.dim('═'.repeat(60)));
512
+ console.log(`${c.info('[INFO]')} App Installation: ${c.bright(appInstallPath)}`);
513
+ console.log(`${c.info('[INFO]')} Data File: ${c.dim(path.relative(appInstallPath, DATA_FILE_PATH))}`);
514
+ if (process.env.DATA_FILE_PATH) {
515
+ console.log(` ${c.dim('(Using custom DATA_FILE_PATH from environment)')}`);
516
+ }
517
+ console.log(c.dim('═'.repeat(60)));
518
+ console.log('');
519
+ console.log('Data file initialized successfully');
520
+ return state;
521
+ }
522
+
523
+ function getDataFilePath() {
524
+ return DATA_FILE_PATH;
525
+ }
526
+
354
527
  export {
355
- db,
356
528
  initializeDatabase,
529
+ getDataFilePath,
357
530
  userDb,
358
531
  apiKeysDb,
359
532
  credentialsDb,
360
- githubTokensDb // Backward compatibility
361
- };
533
+ githubTokensDb,
534
+ channelDb,
535
+ };