@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
@@ -0,0 +1,1052 @@
1
+ import { spawn } from 'child_process';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import { promises as fs } from 'fs';
5
+ import crypto from 'crypto';
6
+ import { Octokit } from '@octokit/rest';
7
+
8
+ import { githubTokensDb } from '../database/db.js';
9
+ import { addProjectManually } from '../projects.js';
10
+ import { queryClaudeSDK } from '../claude-sdk.js';
11
+ import { queryCodex } from '../openai-codex.js';
12
+ import { queryGemini } from '../gemini-cli.js';
13
+ import { queryOpencode } from '../opencode-cli.js';
14
+ import {
15
+ buildAgentCallbackPayload,
16
+ createAgentCallbackEventId,
17
+ createEmptyTokenSummary,
18
+ normalizeAgentCallbackConfig,
19
+ scheduleAgentCallbackDelivery,
20
+ shouldDeliverAgentCallback
21
+ } from '../utils/agentCallback.js';
22
+ import { normalizeExternalImages } from '../utils/agentImages.js';
23
+ import { resolveWorkingDirectory } from '../utils/defaultWorkingDirectory.js';
24
+ import { CODEX_MODELS, GEMINI_MODELS, OPENCODE_MODELS } from '../../shared/modelConstants.js';
25
+
26
+ export const SUPPORTED_EXTERNAL_AGENT_PROVIDERS = ['claude', 'codex', 'gemini', 'opencode'];
27
+
28
+ function createRequestError(message, statusCode = 400) {
29
+ const error = new Error(message);
30
+ error.statusCode = statusCode;
31
+ return error;
32
+ }
33
+
34
+ function parseBoolean(value, fallback) {
35
+ if (value === undefined) {
36
+ return fallback;
37
+ }
38
+ return value === true || value === 'true';
39
+ }
40
+
41
+ export function buildSessionNavigation(sessionId) {
42
+ const normalizedSessionId = typeof sessionId === 'string' && sessionId.trim() ? sessionId.trim() : null;
43
+ const sessionPath = normalizedSessionId ? `/session/${normalizedSessionId}` : null;
44
+ const frontendPort = process.env.VITE_PORT || '5173';
45
+ const configuredFrontendUrl = typeof process.env.FRONTEND_URL === 'string'
46
+ ? process.env.FRONTEND_URL.trim().replace(/\/+$/, '')
47
+ : '';
48
+ const frontendBaseUrl = configuredFrontendUrl || `http://localhost:${frontendPort}`;
49
+ const sessionUrl = normalizedSessionId ? `${frontendBaseUrl}${sessionPath}` : null;
50
+
51
+ return {
52
+ sessionPath,
53
+ sessionUrl
54
+ };
55
+ }
56
+
57
+ export function normalizeExternalAgentRunRequest(body = {}) {
58
+ const { githubUrl, projectPath, message, model, githubToken, branchName, sessionId, openOnly } = body;
59
+ const provider = typeof body.provider === 'string' ? body.provider.trim() : 'claude';
60
+ const stream = parseBoolean(body.stream, true);
61
+ const requestedCleanup = parseBoolean(body.cleanup, true);
62
+ const createBranch = branchName ? true : parseBoolean(body.createBranch, false);
63
+ const createPR = parseBoolean(body.createPR, false);
64
+ const normalizedSessionId = typeof sessionId === 'string' && sessionId.trim() ? sessionId.trim() : null;
65
+ const normalizedMessage = typeof message === 'string' ? message.trim() : '';
66
+ const requestedOpenOnly = openOnly === true || openOnly === 'true';
67
+ const isOpenOnly = requestedOpenOnly || (!normalizedMessage && !!normalizedSessionId);
68
+ const cleanup = isOpenOnly ? false : requestedCleanup;
69
+ const images = normalizeExternalImages(body.images);
70
+ const resolvedProjectPath = githubUrl ? projectPath : resolveWorkingDirectory({ projectPath });
71
+
72
+ let callbackConfig = null;
73
+ try {
74
+ callbackConfig = normalizeAgentCallbackConfig(body.callback);
75
+ } catch (error) {
76
+ throw createRequestError(error.message, 400);
77
+ }
78
+
79
+ if (!SUPPORTED_EXTERNAL_AGENT_PROVIDERS.includes(provider)) {
80
+ throw createRequestError('provider must be "claude", "codex", "gemini", or "opencode"', 400);
81
+ }
82
+
83
+ if (sessionId !== undefined && (typeof sessionId !== 'string' || !sessionId.trim())) {
84
+ throw createRequestError('sessionId must be a non-empty string when provided', 400);
85
+ }
86
+
87
+ if (isOpenOnly && !normalizedSessionId) {
88
+ throw createRequestError('sessionId is required when message is empty or openOnly=true', 400);
89
+ }
90
+
91
+ if (!isOpenOnly && !normalizedMessage) {
92
+ throw createRequestError('message is required unless openOnly=true', 400);
93
+ }
94
+
95
+ if (isOpenOnly && githubUrl) {
96
+ throw createRequestError('githubUrl is not supported when openOnly=true', 400);
97
+ }
98
+
99
+ if (isOpenOnly && (createBranch || createPR)) {
100
+ throw createRequestError('createBranch and createPR are not supported when openOnly=true', 400);
101
+ }
102
+
103
+ if (isOpenOnly && callbackConfig) {
104
+ throw createRequestError('callback is not supported when openOnly=true', 400);
105
+ }
106
+
107
+ if (isOpenOnly && images.length > 0) {
108
+ throw createRequestError('images is not supported when openOnly=true', 400);
109
+ }
110
+
111
+ if (images.length > 0 && provider !== 'claude' && provider !== 'codex') {
112
+ throw createRequestError(`images is not supported for provider "${provider}"`, 400);
113
+ }
114
+
115
+ return {
116
+ githubUrl,
117
+ projectPath: resolvedProjectPath,
118
+ message,
119
+ normalizedMessage,
120
+ provider,
121
+ model,
122
+ githubToken,
123
+ branchName,
124
+ sessionId,
125
+ normalizedSessionId,
126
+ openOnly,
127
+ requestedOpenOnly,
128
+ isOpenOnly,
129
+ createBranch,
130
+ createPR,
131
+ stream,
132
+ requestedCleanup,
133
+ cleanup,
134
+ callbackConfig,
135
+ images
136
+ };
137
+ }
138
+
139
+ export function normalizeExternalAgentAbortRequest(body = {}) {
140
+ const normalizedSessionId = typeof body.sessionId === 'string' ? body.sessionId.trim() : '';
141
+ const provider = typeof body.provider === 'string' && body.provider.trim()
142
+ ? body.provider.trim().toLowerCase()
143
+ : 'claude';
144
+
145
+ if (!normalizedSessionId) {
146
+ throw createRequestError('sessionId is required', 400);
147
+ }
148
+
149
+ if (!SUPPORTED_EXTERNAL_AGENT_PROVIDERS.includes(provider)) {
150
+ throw createRequestError(`provider must be one of: ${SUPPORTED_EXTERNAL_AGENT_PROVIDERS.join(', ')}`, 400);
151
+ }
152
+
153
+ return {
154
+ sessionId: normalizedSessionId,
155
+ provider
156
+ };
157
+ }
158
+
159
+ async function getGitRemoteUrl(repoPath) {
160
+ return new Promise((resolve, reject) => {
161
+ const gitProcess = spawn('git', ['config', '--get', 'remote.origin.url'], {
162
+ cwd: repoPath,
163
+ stdio: ['pipe', 'pipe', 'pipe']
164
+ });
165
+
166
+ let stdout = '';
167
+ let stderr = '';
168
+
169
+ gitProcess.stdout.on('data', (data) => {
170
+ stdout += data.toString();
171
+ });
172
+
173
+ gitProcess.stderr.on('data', (data) => {
174
+ stderr += data.toString();
175
+ });
176
+
177
+ gitProcess.on('close', (code) => {
178
+ if (code === 0) {
179
+ resolve(stdout.trim());
180
+ } else {
181
+ reject(new Error(`Failed to get git remote: ${stderr}`));
182
+ }
183
+ });
184
+
185
+ gitProcess.on('error', (error) => {
186
+ reject(new Error(`Failed to execute git: ${error.message}`));
187
+ });
188
+ });
189
+ }
190
+
191
+ function normalizeGitHubUrl(url) {
192
+ let normalized = url.replace(/\.git$/, '');
193
+ normalized = normalized.replace(/^git@github\.com:/, 'https://github.com/');
194
+ normalized = normalized.replace(/\/$/, '');
195
+ return normalized.toLowerCase();
196
+ }
197
+
198
+ function parseGitHubUrl(url) {
199
+ const match = url.match(/github\.com[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
200
+ if (!match) {
201
+ throw new Error('Invalid GitHub URL format');
202
+ }
203
+
204
+ return {
205
+ owner: match[1],
206
+ repo: match[2].replace(/\.git$/, '')
207
+ };
208
+ }
209
+
210
+ function autogenerateBranchName(message) {
211
+ let branchName = message
212
+ .toLowerCase()
213
+ .replace(/[^a-z0-9\s-]/g, '')
214
+ .replace(/\s+/g, '-')
215
+ .replace(/-+/g, '-')
216
+ .replace(/^-|-$/g, '');
217
+
218
+ if (!branchName) {
219
+ branchName = 'task';
220
+ }
221
+
222
+ const timestamp = Date.now().toString(36).slice(-6);
223
+ const suffix = `-${timestamp}`;
224
+ const maxBaseLength = 50 - suffix.length;
225
+
226
+ if (branchName.length > maxBaseLength) {
227
+ branchName = branchName.substring(0, maxBaseLength);
228
+ }
229
+
230
+ branchName = branchName.replace(/-$/, '').replace(/^-+/, '');
231
+
232
+ if (!branchName || branchName.startsWith('-')) {
233
+ branchName = 'task';
234
+ }
235
+
236
+ branchName = `${branchName}${suffix}`;
237
+
238
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(branchName)) {
239
+ return `branch-${timestamp}`;
240
+ }
241
+
242
+ return branchName;
243
+ }
244
+
245
+ function validateBranchName(branchName) {
246
+ if (!branchName || branchName.trim() === '') {
247
+ return { valid: false, error: 'Branch name cannot be empty' };
248
+ }
249
+
250
+ const invalidPatterns = [
251
+ { pattern: /^\./, message: 'Branch name cannot start with a dot' },
252
+ { pattern: /\.$/, message: 'Branch name cannot end with a dot' },
253
+ { pattern: /\.\./, message: 'Branch name cannot contain consecutive dots (..)' },
254
+ { pattern: /\s/, message: 'Branch name cannot contain spaces' },
255
+ { pattern: /[~^:?*\[\\]/, message: 'Branch name cannot contain special characters: ~ ^ : ? * [ \\' },
256
+ { pattern: /@{/, message: 'Branch name cannot contain @{' },
257
+ { pattern: /\/$/, message: 'Branch name cannot end with a slash' },
258
+ { pattern: /^\//, message: 'Branch name cannot start with a slash' },
259
+ { pattern: /\/\//, message: 'Branch name cannot contain consecutive slashes' },
260
+ { pattern: /\.lock$/, message: 'Branch name cannot end with .lock' }
261
+ ];
262
+
263
+ for (const { pattern, message } of invalidPatterns) {
264
+ if (pattern.test(branchName)) {
265
+ return { valid: false, error: message };
266
+ }
267
+ }
268
+
269
+ if (/[\x00-\x1F\x7F]/.test(branchName)) {
270
+ return { valid: false, error: 'Branch name cannot contain control characters' };
271
+ }
272
+
273
+ return { valid: true };
274
+ }
275
+
276
+ async function getCommitMessages(projectPath, limit = 5) {
277
+ return new Promise((resolve, reject) => {
278
+ const gitProcess = spawn('git', ['log', `-${limit}`, '--pretty=format:%s'], {
279
+ cwd: projectPath,
280
+ stdio: ['pipe', 'pipe', 'pipe']
281
+ });
282
+
283
+ let stdout = '';
284
+ let stderr = '';
285
+
286
+ gitProcess.stdout.on('data', (data) => {
287
+ stdout += data.toString();
288
+ });
289
+
290
+ gitProcess.stderr.on('data', (data) => {
291
+ stderr += data.toString();
292
+ });
293
+
294
+ gitProcess.on('close', (code) => {
295
+ if (code === 0) {
296
+ resolve(stdout.trim().split('\n').filter((msg) => msg.length > 0));
297
+ } else {
298
+ reject(new Error(`Failed to get commit messages: ${stderr}`));
299
+ }
300
+ });
301
+
302
+ gitProcess.on('error', (error) => {
303
+ reject(new Error(`Failed to execute git: ${error.message}`));
304
+ });
305
+ });
306
+ }
307
+
308
+ async function createGitHubPR(octokit, owner, repo, branchName, title, body, baseBranch = 'main') {
309
+ const { data: pr } = await octokit.pulls.create({
310
+ owner,
311
+ repo,
312
+ title,
313
+ head: branchName,
314
+ base: baseBranch,
315
+ body
316
+ });
317
+
318
+ return {
319
+ number: pr.number,
320
+ url: pr.html_url
321
+ };
322
+ }
323
+
324
+ async function cloneGitHubRepo(githubUrl, githubToken = null, projectPath) {
325
+ return new Promise(async (resolve, reject) => {
326
+ try {
327
+ if (!githubUrl || !githubUrl.includes('github.com')) {
328
+ throw new Error('Invalid GitHub URL');
329
+ }
330
+
331
+ const cloneDir = path.resolve(projectPath);
332
+ let directoryExists = false;
333
+ try {
334
+ await fs.access(cloneDir);
335
+ directoryExists = true;
336
+ } catch {
337
+ directoryExists = false;
338
+ }
339
+
340
+ if (directoryExists) {
341
+ try {
342
+ const existingUrl = await getGitRemoteUrl(cloneDir);
343
+ const normalizedExisting = normalizeGitHubUrl(existingUrl);
344
+ const normalizedRequested = normalizeGitHubUrl(githubUrl);
345
+
346
+ if (normalizedExisting === normalizedRequested) {
347
+ return resolve(cloneDir);
348
+ }
349
+
350
+ throw new Error(`Directory ${cloneDir} already exists with a different repository (${existingUrl}). Expected: ${githubUrl}`);
351
+ } catch (error) {
352
+ if (error.message && error.message.includes('different repository')) {
353
+ throw error;
354
+ }
355
+ throw new Error(`Directory ${cloneDir} already exists but is not a valid git repository or git command failed`);
356
+ }
357
+ }
358
+
359
+ await fs.mkdir(path.dirname(cloneDir), { recursive: true });
360
+
361
+ let cloneUrl = githubUrl;
362
+ if (githubToken) {
363
+ cloneUrl = githubUrl.replace('https://github.com', `https://${githubToken}@github.com`);
364
+ }
365
+
366
+ const gitProcess = spawn('git', ['clone', '--depth', '1', cloneUrl, cloneDir], {
367
+ stdio: ['pipe', 'pipe', 'pipe']
368
+ });
369
+
370
+ let stderr = '';
371
+
372
+ gitProcess.stderr.on('data', (data) => {
373
+ stderr += data.toString();
374
+ });
375
+
376
+ gitProcess.on('close', (code) => {
377
+ if (code === 0) {
378
+ resolve(cloneDir);
379
+ } else {
380
+ reject(new Error(`Git clone failed: ${stderr}`));
381
+ }
382
+ });
383
+
384
+ gitProcess.on('error', (error) => {
385
+ reject(new Error(`Failed to execute git: ${error.message}`));
386
+ });
387
+ } catch (error) {
388
+ reject(error);
389
+ }
390
+ });
391
+ }
392
+
393
+ async function cleanupProject(projectPath, sessionId = null) {
394
+ try {
395
+ if (!projectPath.includes('.claude/external-projects')) {
396
+ console.warn('Refusing to clean up non-external project:', projectPath);
397
+ return;
398
+ }
399
+
400
+ await fs.rm(projectPath, { recursive: true, force: true });
401
+
402
+ if (sessionId) {
403
+ try {
404
+ const sessionPath = path.join(os.homedir(), '.claude', 'sessions', sessionId);
405
+ await fs.rm(sessionPath, { recursive: true, force: true });
406
+ } catch (error) {
407
+ console.error('Failed to clean up session directory:', error.message);
408
+ }
409
+ }
410
+ } catch (error) {
411
+ console.error('Failed to clean up project:', error);
412
+ }
413
+ }
414
+
415
+ export class SSEStreamWriter {
416
+ constructor(res) {
417
+ this.res = res;
418
+ this.sessionId = null;
419
+ this.isSSEStreamWriter = true;
420
+ }
421
+
422
+ send(data) {
423
+ if (!this.res.writableEnded) {
424
+ this.res.write(`data: ${JSON.stringify(data)}\n\n`);
425
+ }
426
+ }
427
+
428
+ end() {
429
+ if (!this.res.writableEnded) {
430
+ this.res.write('data: {"type":"done"}\n\n');
431
+ this.res.end();
432
+ }
433
+ }
434
+
435
+ setSessionId(sessionId) {
436
+ this.sessionId = sessionId;
437
+ }
438
+
439
+ getSessionId() {
440
+ return this.sessionId;
441
+ }
442
+ }
443
+
444
+ export class ResponseCollector {
445
+ constructor() {
446
+ this.messages = [];
447
+ this.sessionId = null;
448
+ }
449
+
450
+ send(data) {
451
+ this.messages.push(data);
452
+ if (data && typeof data === 'object' && data.sessionId) {
453
+ this.sessionId = data.sessionId;
454
+ }
455
+ }
456
+
457
+ end() {}
458
+
459
+ setSessionId(sessionId) {
460
+ this.sessionId = sessionId;
461
+ }
462
+
463
+ getSessionId() {
464
+ return this.sessionId;
465
+ }
466
+ }
467
+
468
+ export class AgentSessionAbortedError extends Error {
469
+ constructor(message = 'Session aborted') {
470
+ super(message);
471
+ this.name = 'AgentSessionAbortedError';
472
+ }
473
+ }
474
+
475
+ function extractTerminalErrorMessage(payload) {
476
+ if (!payload || typeof payload !== 'object') {
477
+ return null;
478
+ }
479
+
480
+ if (typeof payload.error === 'string' && payload.error.trim()) {
481
+ return payload.error.trim();
482
+ }
483
+
484
+ if (payload.error && typeof payload.error.message === 'string' && payload.error.message.trim()) {
485
+ return payload.error.message.trim();
486
+ }
487
+
488
+ const nestedData = payload.data;
489
+ if (nestedData && typeof nestedData === 'object') {
490
+ if (typeof nestedData.error === 'string' && nestedData.error.trim()) {
491
+ return nestedData.error.trim();
492
+ }
493
+
494
+ if (nestedData.error && typeof nestedData.error.message === 'string' && nestedData.error.message.trim()) {
495
+ return nestedData.error.message.trim();
496
+ }
497
+
498
+ if (typeof nestedData.message === 'string' && nestedData.message.trim()) {
499
+ return nestedData.message.trim();
500
+ }
501
+ }
502
+
503
+ return null;
504
+ }
505
+
506
+ export class CallbackCaptureWriter {
507
+ constructor() {
508
+ this.sessionId = null;
509
+ this.assistantMessages = [];
510
+ this.tokenSummary = createEmptyTokenSummary();
511
+ this.terminalState = null;
512
+ this.terminalErrorMessage = null;
513
+ }
514
+
515
+ send(payload) {
516
+ if (!payload || typeof payload !== 'object') {
517
+ return;
518
+ }
519
+
520
+ if (typeof payload.sessionId === 'string' && payload.sessionId.trim()) {
521
+ this.sessionId = payload.sessionId.trim();
522
+ }
523
+
524
+ if (payload.type === 'session-created' && typeof payload.sessionId === 'string' && payload.sessionId.trim()) {
525
+ this.sessionId = payload.sessionId.trim();
526
+ }
527
+
528
+ if (payload.type === 'token-budget' && payload.data && typeof payload.data === 'object') {
529
+ this.tokenSummary = {
530
+ inputTokens: Number(payload.data.inputTokens) || 0,
531
+ outputTokens: Number(payload.data.outputTokens) || 0,
532
+ cacheReadTokens: Number(payload.data.cacheReadTokens) || 0,
533
+ cacheCreationTokens: Number(payload.data.cacheCreationTokens) || 0,
534
+ totalTokens: Number(payload.data.totalTokens) || 0
535
+ };
536
+ }
537
+
538
+ if (payload.type === 'claude-response' && payload.data?.type === 'assistant') {
539
+ this.assistantMessages.push(payload.data);
540
+ }
541
+
542
+ if (
543
+ payload.type === 'codex-response' &&
544
+ payload.data?.type === 'item_done' &&
545
+ payload.data?.itemType === 'agent_message' &&
546
+ typeof payload.data?.content === 'string' &&
547
+ payload.data.content.trim()
548
+ ) {
549
+ this.assistantMessages.push({
550
+ type: 'assistant',
551
+ message: {
552
+ role: 'assistant',
553
+ content: payload.data.content
554
+ }
555
+ });
556
+ }
557
+
558
+ if (payload.type === 'session-aborted') {
559
+ this.terminalState = 'aborted';
560
+ this.terminalErrorMessage = 'Session aborted';
561
+ return;
562
+ }
563
+
564
+ if (payload.type === 'claude-complete' || payload.type === 'codex-complete') {
565
+ this.terminalState = 'completed';
566
+ this.terminalErrorMessage = null;
567
+ return;
568
+ }
569
+
570
+ if (
571
+ payload.type === 'claude-error' ||
572
+ payload.type === 'codex-error' ||
573
+ payload.type === 'error' ||
574
+ (payload.type === 'codex-response' && payload.data?.type === 'turn_failed')
575
+ ) {
576
+ this.terminalState = 'errored';
577
+ this.terminalErrorMessage = extractTerminalErrorMessage(payload) || this.terminalErrorMessage || 'Agent session failed';
578
+ }
579
+ }
580
+
581
+ end() {}
582
+
583
+ setSessionId(sessionId) {
584
+ if (typeof sessionId === 'string' && sessionId.trim()) {
585
+ this.sessionId = sessionId.trim();
586
+ }
587
+ }
588
+
589
+ getSessionId() {
590
+ return this.sessionId;
591
+ }
592
+
593
+ getAssistantMessages() {
594
+ return this.assistantMessages;
595
+ }
596
+
597
+ getTotalTokens() {
598
+ return this.tokenSummary;
599
+ }
600
+
601
+ getTerminalState() {
602
+ return this.terminalState;
603
+ }
604
+
605
+ getTerminalErrorMessage() {
606
+ return this.terminalErrorMessage;
607
+ }
608
+ }
609
+
610
+ export class TeeWriter {
611
+ constructor(primaryWriter, secondaryWriter) {
612
+ this.primaryWriter = primaryWriter;
613
+ this.secondaryWriter = secondaryWriter;
614
+ this.isSSEStreamWriter = !!primaryWriter?.isSSEStreamWriter;
615
+ this.isWebSocketWriter = !!primaryWriter?.isWebSocketWriter;
616
+ }
617
+
618
+ send(payload) {
619
+ this.primaryWriter?.send?.(payload);
620
+ this.secondaryWriter?.send?.(payload);
621
+ }
622
+
623
+ end() {
624
+ this.primaryWriter?.end?.();
625
+ this.secondaryWriter?.end?.();
626
+ }
627
+
628
+ setSessionId(sessionId) {
629
+ this.primaryWriter?.setSessionId?.(sessionId);
630
+ this.secondaryWriter?.setSessionId?.(sessionId);
631
+ }
632
+
633
+ getSessionId() {
634
+ return this.primaryWriter?.getSessionId?.() || this.secondaryWriter?.getSessionId?.() || null;
635
+ }
636
+ }
637
+
638
+ export class NoopWriter {
639
+ send() {}
640
+
641
+ end() {}
642
+ }
643
+
644
+ async function runProviderSession({ provider, message, images, finalProjectPath, sessionId, model, writer }) {
645
+ if (provider === 'claude') {
646
+ await queryClaudeSDK(message, {
647
+ projectPath: finalProjectPath,
648
+ cwd: finalProjectPath,
649
+ sessionId,
650
+ model,
651
+ permissionMode: 'bypassPermissions',
652
+ images
653
+ }, writer);
654
+ return;
655
+ }
656
+
657
+ if (provider === 'codex') {
658
+ await queryCodex(message, {
659
+ projectPath: finalProjectPath,
660
+ cwd: finalProjectPath,
661
+ sessionId,
662
+ model: model || CODEX_MODELS.DEFAULT,
663
+ permissionMode: 'bypassPermissions',
664
+ images
665
+ }, writer);
666
+ return;
667
+ }
668
+
669
+ if (provider === 'gemini') {
670
+ await queryGemini(message, {
671
+ projectPath: finalProjectPath,
672
+ cwd: finalProjectPath,
673
+ sessionId,
674
+ resume: !!sessionId,
675
+ model: model || GEMINI_MODELS.DEFAULT,
676
+ permissionMode: 'bypassPermissions'
677
+ }, writer);
678
+ return;
679
+ }
680
+
681
+ if (provider === 'opencode') {
682
+ await queryOpencode(message, {
683
+ projectPath: finalProjectPath,
684
+ cwd: finalProjectPath,
685
+ sessionId,
686
+ resume: !!sessionId,
687
+ model: model || OPENCODE_MODELS.DEFAULT,
688
+ permissionMode: 'bypassPermissions'
689
+ }, writer);
690
+ }
691
+ }
692
+
693
+ async function maybeCreateBranchAndPR({
694
+ user,
695
+ githubToken,
696
+ githubUrl,
697
+ finalProjectPath,
698
+ branchName,
699
+ message,
700
+ createBranch,
701
+ createPR,
702
+ transportWriter
703
+ }) {
704
+ let branchInfo = null;
705
+ let prInfo = null;
706
+
707
+ if (!createBranch && !createPR) {
708
+ return { branchInfo, prInfo };
709
+ }
710
+
711
+ try {
712
+ const tokenToUse = githubToken || githubTokensDb.getActiveGithubToken(user?.id);
713
+ if (!tokenToUse) {
714
+ throw new Error('GitHub token required for branch/PR creation. Please configure a GitHub token in settings.');
715
+ }
716
+
717
+ const octokit = new Octokit({ auth: tokenToUse });
718
+ let repoUrl = githubUrl;
719
+
720
+ if (!repoUrl) {
721
+ repoUrl = await getGitRemoteUrl(finalProjectPath);
722
+ if (!repoUrl.includes('github.com')) {
723
+ throw new Error('Project does not have a GitHub remote configured');
724
+ }
725
+ }
726
+
727
+ const { owner, repo } = parseGitHubUrl(repoUrl);
728
+ const finalBranchName = branchName || autogenerateBranchName(message);
729
+
730
+ if (branchName) {
731
+ const validation = validateBranchName(finalBranchName);
732
+ if (!validation.valid) {
733
+ throw new Error(`Invalid branch name: ${validation.error}`);
734
+ }
735
+ }
736
+
737
+ if (createBranch) {
738
+ await new Promise((resolve, reject) => {
739
+ const checkoutProcess = spawn('git', ['checkout', '-b', finalBranchName], {
740
+ cwd: finalProjectPath,
741
+ stdio: 'pipe'
742
+ });
743
+
744
+ let stderr = '';
745
+ checkoutProcess.stderr.on('data', (data) => {
746
+ stderr += data.toString();
747
+ });
748
+
749
+ checkoutProcess.on('close', (code) => {
750
+ if (code === 0) {
751
+ resolve();
752
+ return;
753
+ }
754
+
755
+ if (stderr.includes('already exists')) {
756
+ const checkoutExisting = spawn('git', ['checkout', finalBranchName], {
757
+ cwd: finalProjectPath,
758
+ stdio: 'pipe'
759
+ });
760
+ checkoutExisting.on('close', (checkoutCode) => {
761
+ if (checkoutCode === 0) {
762
+ resolve();
763
+ } else {
764
+ reject(new Error(`Failed to checkout existing branch: ${stderr}`));
765
+ }
766
+ });
767
+ return;
768
+ }
769
+
770
+ reject(new Error(`Failed to create branch: ${stderr}`));
771
+ });
772
+ });
773
+
774
+ await new Promise((resolve, reject) => {
775
+ const pushProcess = spawn('git', ['push', '-u', 'origin', finalBranchName], {
776
+ cwd: finalProjectPath,
777
+ stdio: 'pipe'
778
+ });
779
+
780
+ let stderr = '';
781
+ pushProcess.stderr.on('data', (data) => {
782
+ stderr += data.toString();
783
+ });
784
+
785
+ pushProcess.on('close', (code) => {
786
+ if (code === 0 || stderr.includes('already exists') || stderr.includes('up-to-date')) {
787
+ resolve();
788
+ } else {
789
+ reject(new Error(`Failed to push branch: ${stderr}`));
790
+ }
791
+ });
792
+ });
793
+
794
+ branchInfo = {
795
+ name: finalBranchName,
796
+ url: `https://github.com/${owner}/${repo}/tree/${finalBranchName}`
797
+ };
798
+ }
799
+
800
+ if (createPR) {
801
+ const commitMessages = await getCommitMessages(finalProjectPath, 5);
802
+ const prTitle = commitMessages.length > 0 ? commitMessages[0] : message;
803
+ let prBody = '## Changes\n\n';
804
+ if (commitMessages.length > 0) {
805
+ prBody += commitMessages.map((msg) => `- ${msg}`).join('\n');
806
+ } else {
807
+ prBody += `Agent task: ${message}`;
808
+ }
809
+ prBody += '\n\n---\n*This pull request was automatically created by Axhub Genie Agent.*';
810
+
811
+ prInfo = await createGitHubPR(octokit, owner, repo, finalBranchName, prTitle, prBody, 'main');
812
+ }
813
+
814
+ if (branchInfo) {
815
+ transportWriter?.send?.({
816
+ type: 'github-branch',
817
+ branch: branchInfo
818
+ });
819
+ }
820
+
821
+ if (prInfo) {
822
+ transportWriter?.send?.({
823
+ type: 'github-pr',
824
+ pullRequest: prInfo
825
+ });
826
+ }
827
+ } catch (error) {
828
+ transportWriter?.send?.({
829
+ type: 'github-error',
830
+ error: error.message
831
+ });
832
+
833
+ branchInfo = { error: error.message };
834
+ prInfo = { error: error.message };
835
+ }
836
+
837
+ return { branchInfo, prInfo };
838
+ }
839
+
840
+ export async function runExternalAgentRequest({
841
+ user,
842
+ request,
843
+ transportWriter,
844
+ endTransportOnFinish = false
845
+ }) {
846
+ const normalized = request?.normalizedMessage !== undefined
847
+ ? request
848
+ : normalizeExternalAgentRunRequest(request);
849
+ const startedAt = new Date().toISOString();
850
+
851
+ if (normalized.isOpenOnly) {
852
+ const response = {
853
+ success: true,
854
+ openOnly: true,
855
+ sessionId: normalized.normalizedSessionId,
856
+ ...buildSessionNavigation(normalized.normalizedSessionId),
857
+ isResumed: true,
858
+ message: 'Session link generated. No model call triggered.'
859
+ };
860
+
861
+ transportWriter?.send?.({
862
+ type: 'open-only',
863
+ ...response
864
+ });
865
+
866
+ if (endTransportOnFinish) {
867
+ transportWriter?.end?.();
868
+ }
869
+
870
+ return response;
871
+ }
872
+
873
+ let finalProjectPath = null;
874
+ let branchInfo = null;
875
+ let prInfo = null;
876
+ const callbackCaptureWriter = new CallbackCaptureWriter();
877
+ const writer = new TeeWriter(transportWriter, callbackCaptureWriter);
878
+ let callbackSessionId = normalized.normalizedSessionId;
879
+ let callbackResult = null;
880
+
881
+ try {
882
+ if (normalized.githubUrl) {
883
+ const tokenToUse = normalized.githubToken || githubTokensDb.getActiveGithubToken(user?.id);
884
+ let targetPath = normalized.projectPath;
885
+ if (!targetPath) {
886
+ const repoHash = crypto.createHash('md5').update(normalized.githubUrl + Date.now()).digest('hex');
887
+ targetPath = path.join(os.homedir(), '.claude', 'external-projects', repoHash);
888
+ }
889
+
890
+ finalProjectPath = await cloneGitHubRepo(normalized.githubUrl.trim(), tokenToUse, targetPath);
891
+ } else {
892
+ finalProjectPath = resolveWorkingDirectory({ projectPath: normalized.projectPath });
893
+ try {
894
+ await fs.access(finalProjectPath);
895
+ } catch {
896
+ throw new Error(`Project path does not exist: ${finalProjectPath}`);
897
+ }
898
+ }
899
+
900
+ try {
901
+ await addProjectManually(finalProjectPath);
902
+ } catch (error) {
903
+ if (!(error.message && error.message.includes('Project already configured'))) {
904
+ throw error;
905
+ }
906
+ }
907
+
908
+ const statusMessage = normalized.normalizedSessionId
909
+ ? (normalized.githubUrl ? 'Repository cloned and session resumed' : 'Session resumed')
910
+ : (normalized.githubUrl ? 'Repository cloned and session started' : 'Session started');
911
+
912
+ transportWriter?.send?.({
913
+ type: 'status',
914
+ message: statusMessage,
915
+ projectPath: finalProjectPath
916
+ });
917
+
918
+ await runProviderSession({
919
+ provider: normalized.provider,
920
+ message: normalized.normalizedMessage,
921
+ images: normalized.images,
922
+ finalProjectPath,
923
+ sessionId: normalized.normalizedSessionId,
924
+ model: normalized.model,
925
+ writer
926
+ });
927
+
928
+ callbackSessionId = writer.getSessionId() || callbackCaptureWriter.getSessionId() || normalized.normalizedSessionId;
929
+ const terminalState = callbackCaptureWriter.getTerminalState();
930
+
931
+ if (terminalState === 'errored') {
932
+ throw new Error(callbackCaptureWriter.getTerminalErrorMessage() || `${normalized.provider} session failed`);
933
+ }
934
+
935
+ if (terminalState !== 'completed') {
936
+ throw new AgentSessionAbortedError();
937
+ }
938
+
939
+ ({ branchInfo, prInfo } = await maybeCreateBranchAndPR({
940
+ user,
941
+ githubToken: normalized.githubToken,
942
+ githubUrl: normalized.githubUrl,
943
+ finalProjectPath,
944
+ branchName: normalized.branchName,
945
+ message: normalized.message,
946
+ createBranch: normalized.createBranch,
947
+ createPR: normalized.createPR,
948
+ transportWriter
949
+ }));
950
+
951
+ callbackSessionId = writer.getSessionId() || callbackCaptureWriter.getSessionId() || normalized.normalizedSessionId;
952
+ const navigation = buildSessionNavigation(callbackSessionId);
953
+ const response = {
954
+ success: true,
955
+ sessionId: callbackSessionId,
956
+ ...navigation,
957
+ isResumed: !!normalized.normalizedSessionId,
958
+ messages: callbackCaptureWriter.getAssistantMessages(),
959
+ tokens: callbackCaptureWriter.getTotalTokens(),
960
+ projectPath: finalProjectPath
961
+ };
962
+
963
+ if (branchInfo) {
964
+ response.branch = branchInfo;
965
+ }
966
+ if (prInfo) {
967
+ response.pullRequest = prInfo;
968
+ }
969
+
970
+ callbackResult = {
971
+ sessionPath: navigation.sessionPath,
972
+ sessionUrl: navigation.sessionUrl,
973
+ messages: response.messages,
974
+ tokens: response.tokens,
975
+ branch: branchInfo,
976
+ pullRequest: prInfo
977
+ };
978
+
979
+ if (normalized.callbackConfig && shouldDeliverAgentCallback(normalized.callbackConfig, 'completed')) {
980
+ const payload = buildAgentCallbackPayload({
981
+ event: 'completed',
982
+ eventId: createAgentCallbackEventId(),
983
+ sessionId: callbackSessionId,
984
+ provider: normalized.provider,
985
+ projectPath: finalProjectPath,
986
+ isResumed: !!normalized.normalizedSessionId,
987
+ startedAt,
988
+ finishedAt: new Date().toISOString(),
989
+ result: callbackResult
990
+ });
991
+
992
+ void scheduleAgentCallbackDelivery({
993
+ callback: normalized.callbackConfig,
994
+ payload
995
+ });
996
+ }
997
+
998
+ if (normalized.cleanup && normalized.githubUrl) {
999
+ const sessionIdForCleanup = writer.getSessionId();
1000
+ setTimeout(() => {
1001
+ cleanupProject(finalProjectPath, sessionIdForCleanup);
1002
+ }, 5000);
1003
+ }
1004
+
1005
+ if (endTransportOnFinish) {
1006
+ transportWriter?.end?.();
1007
+ }
1008
+
1009
+ return response;
1010
+ } catch (error) {
1011
+ callbackSessionId = writer.getSessionId() || callbackCaptureWriter.getSessionId() || normalized.normalizedSessionId;
1012
+ callbackResult = {
1013
+ ...buildSessionNavigation(callbackSessionId),
1014
+ messages: callbackCaptureWriter.getAssistantMessages(),
1015
+ tokens: callbackCaptureWriter.getTotalTokens(),
1016
+ branch: branchInfo,
1017
+ pullRequest: prInfo
1018
+ };
1019
+
1020
+ if (finalProjectPath && normalized.cleanup && normalized.githubUrl) {
1021
+ const sessionIdForCleanup = writer.getSessionId();
1022
+ await cleanupProject(finalProjectPath, sessionIdForCleanup);
1023
+ }
1024
+
1025
+ const terminalEvent = error instanceof AgentSessionAbortedError ? 'aborted' : 'errored';
1026
+ if (normalized.callbackConfig && shouldDeliverAgentCallback(normalized.callbackConfig, terminalEvent)) {
1027
+ const callbackError = terminalEvent === 'aborted'
1028
+ ? { message: 'Session aborted' }
1029
+ : { message: error.message };
1030
+
1031
+ const payload = buildAgentCallbackPayload({
1032
+ event: terminalEvent,
1033
+ eventId: createAgentCallbackEventId(),
1034
+ sessionId: callbackSessionId,
1035
+ provider: normalized.provider,
1036
+ projectPath: finalProjectPath,
1037
+ isResumed: !!normalized.normalizedSessionId,
1038
+ startedAt,
1039
+ finishedAt: new Date().toISOString(),
1040
+ result: callbackResult,
1041
+ error: callbackError
1042
+ });
1043
+
1044
+ void scheduleAgentCallbackDelivery({
1045
+ callback: normalized.callbackConfig,
1046
+ payload
1047
+ });
1048
+ }
1049
+
1050
+ throw error;
1051
+ }
1052
+ }