@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
@@ -7,10 +7,19 @@ import crypto from 'crypto';
7
7
  import { userDb, apiKeysDb, githubTokensDb } from '../database/db.js';
8
8
  import { addProjectManually } from '../projects.js';
9
9
  import { queryClaudeSDK } from '../claude-sdk.js';
10
- import { spawnCursor } from '../cursor-cli.js';
11
10
  import { queryCodex } from '../openai-codex.js';
12
11
  import { queryGemini } from '../gemini-cli.js';
13
12
  import { queryOpencode } from '../opencode-cli.js';
13
+ import { SessionEventMirrorWriter } from '../session-core/runtimeWriter.js';
14
+ import { ABORTABLE_AGENT_PROVIDERS, abortAgentSessionWithWriter, isAbortableAgentProvider } from '../session-core/abortSession.js';
15
+ import {
16
+ buildAgentCallbackPayload,
17
+ createAgentCallbackEventId,
18
+ createEmptyTokenSummary,
19
+ normalizeAgentCallbackConfig,
20
+ scheduleAgentCallbackDelivery,
21
+ shouldDeliverAgentCallback
22
+ } from '../utils/agentCallback.js';
14
23
  import { Octokit } from '@octokit/rest';
15
24
  import { CODEX_MODELS, GEMINI_MODELS, OPENCODE_MODELS } from '../../shared/modelConstants.js';
16
25
  import { IS_PLATFORM } from '../constants/config.js';
@@ -21,7 +30,11 @@ function buildSessionNavigation(sessionId) {
21
30
  const normalizedSessionId = typeof sessionId === 'string' && sessionId.trim() ? sessionId.trim() : null;
22
31
  const sessionPath = normalizedSessionId ? `/session/${normalizedSessionId}` : null;
23
32
  const frontendPort = process.env.VITE_PORT || '5173';
24
- const sessionUrl = normalizedSessionId ? `http://localhost:${frontendPort}${sessionPath}` : null;
33
+ const configuredFrontendUrl = typeof process.env.FRONTEND_URL === 'string'
34
+ ? process.env.FRONTEND_URL.trim().replace(/\/+$/, '')
35
+ : '';
36
+ const frontendBaseUrl = configuredFrontendUrl || `http://localhost:${frontendPort}`;
37
+ const sessionUrl = normalizedSessionId ? `${frontendBaseUrl}${sessionPath}` : null;
25
38
 
26
39
  return {
27
40
  sessionPath,
@@ -628,6 +641,182 @@ class ResponseCollector {
628
641
  }
629
642
  }
630
643
 
644
+ class AgentSessionAbortedError extends Error {
645
+ constructor(message = 'Session aborted') {
646
+ super(message);
647
+ this.name = 'AgentSessionAbortedError';
648
+ }
649
+ }
650
+
651
+ function extractTerminalErrorMessage(payload) {
652
+ if (!payload || typeof payload !== 'object') {
653
+ return null;
654
+ }
655
+
656
+ if (typeof payload.error === 'string' && payload.error.trim()) {
657
+ return payload.error.trim();
658
+ }
659
+
660
+ if (payload.error && typeof payload.error.message === 'string' && payload.error.message.trim()) {
661
+ return payload.error.message.trim();
662
+ }
663
+
664
+ const nestedData = payload.data;
665
+ if (nestedData && typeof nestedData === 'object') {
666
+ if (typeof nestedData.error === 'string' && nestedData.error.trim()) {
667
+ return nestedData.error.trim();
668
+ }
669
+
670
+ if (nestedData.error && typeof nestedData.error.message === 'string' && nestedData.error.message.trim()) {
671
+ return nestedData.error.message.trim();
672
+ }
673
+
674
+ if (typeof nestedData.message === 'string' && nestedData.message.trim()) {
675
+ return nestedData.message.trim();
676
+ }
677
+ }
678
+
679
+ return null;
680
+ }
681
+
682
+ class CallbackCaptureWriter {
683
+ constructor() {
684
+ this.sessionId = null;
685
+ this.assistantMessages = [];
686
+ this.tokenSummary = createEmptyTokenSummary();
687
+ this.terminalState = null;
688
+ this.terminalErrorMessage = null;
689
+ }
690
+
691
+ send(payload) {
692
+ if (!payload || typeof payload !== 'object') {
693
+ return;
694
+ }
695
+
696
+ if (typeof payload.sessionId === 'string' && payload.sessionId.trim()) {
697
+ this.sessionId = payload.sessionId.trim();
698
+ }
699
+
700
+ if (payload.type === 'session-created' && typeof payload.sessionId === 'string' && payload.sessionId.trim()) {
701
+ this.sessionId = payload.sessionId.trim();
702
+ }
703
+
704
+ if (payload.type === 'token-budget' && payload.data && typeof payload.data === 'object') {
705
+ this.tokenSummary = {
706
+ inputTokens: Number(payload.data.inputTokens) || 0,
707
+ outputTokens: Number(payload.data.outputTokens) || 0,
708
+ cacheReadTokens: Number(payload.data.cacheReadTokens) || 0,
709
+ cacheCreationTokens: Number(payload.data.cacheCreationTokens) || 0,
710
+ totalTokens: Number(payload.data.totalTokens) || 0
711
+ };
712
+ }
713
+
714
+ if (payload.type === 'claude-response' && payload.data?.type === 'assistant') {
715
+ this.assistantMessages.push(payload.data);
716
+ }
717
+
718
+ if (
719
+ payload.type === 'codex-response' &&
720
+ payload.data?.type === 'item_done' &&
721
+ payload.data?.itemType === 'agent_message' &&
722
+ typeof payload.data?.content === 'string' &&
723
+ payload.data.content.trim()
724
+ ) {
725
+ this.assistantMessages.push({
726
+ type: 'assistant',
727
+ message: {
728
+ role: 'assistant',
729
+ content: payload.data.content
730
+ }
731
+ });
732
+ }
733
+
734
+ if (payload.type === 'session-aborted') {
735
+ this.terminalState = 'aborted';
736
+ this.terminalErrorMessage = 'Session aborted';
737
+ return;
738
+ }
739
+
740
+ if (payload.type === 'claude-complete' || payload.type === 'codex-complete') {
741
+ this.terminalState = 'completed';
742
+ this.terminalErrorMessage = null;
743
+ return;
744
+ }
745
+
746
+ if (
747
+ payload.type === 'claude-error' ||
748
+ payload.type === 'codex-error' ||
749
+ payload.type === 'error' ||
750
+ (payload.type === 'codex-response' && payload.data?.type === 'turn_failed')
751
+ ) {
752
+ this.terminalState = 'errored';
753
+ this.terminalErrorMessage = extractTerminalErrorMessage(payload) || this.terminalErrorMessage || 'Agent session failed';
754
+ }
755
+ }
756
+
757
+ end() {}
758
+
759
+ setSessionId(sessionId) {
760
+ if (typeof sessionId === 'string' && sessionId.trim()) {
761
+ this.sessionId = sessionId.trim();
762
+ }
763
+ }
764
+
765
+ getSessionId() {
766
+ return this.sessionId;
767
+ }
768
+
769
+ getAssistantMessages() {
770
+ return this.assistantMessages;
771
+ }
772
+
773
+ getTotalTokens() {
774
+ return this.tokenSummary;
775
+ }
776
+
777
+ getTerminalState() {
778
+ return this.terminalState;
779
+ }
780
+
781
+ getTerminalErrorMessage() {
782
+ return this.terminalErrorMessage;
783
+ }
784
+ }
785
+
786
+ class TeeWriter {
787
+ constructor(primaryWriter, secondaryWriter) {
788
+ this.primaryWriter = primaryWriter;
789
+ this.secondaryWriter = secondaryWriter;
790
+ this.isSSEStreamWriter = !!primaryWriter?.isSSEStreamWriter;
791
+ this.isWebSocketWriter = !!primaryWriter?.isWebSocketWriter;
792
+ }
793
+
794
+ send(payload) {
795
+ this.primaryWriter?.send?.(payload);
796
+ this.secondaryWriter?.send?.(payload);
797
+ }
798
+
799
+ end() {
800
+ this.primaryWriter?.end?.();
801
+ this.secondaryWriter?.end?.();
802
+ }
803
+
804
+ setSessionId(sessionId) {
805
+ this.primaryWriter?.setSessionId?.(sessionId);
806
+ this.secondaryWriter?.setSessionId?.(sessionId);
807
+ }
808
+
809
+ getSessionId() {
810
+ return this.primaryWriter?.getSessionId?.() || this.secondaryWriter?.getSessionId?.() || null;
811
+ }
812
+ }
813
+
814
+ class NoopWriter {
815
+ send() {}
816
+
817
+ end() {}
818
+ }
819
+
631
820
  // ===============================
632
821
  // External API Endpoint
633
822
  // ===============================
@@ -635,7 +824,7 @@ class ResponseCollector {
635
824
  /**
636
825
  * POST /api/agent
637
826
  *
638
- * Trigger an AI agent (Claude, Cursor, Codex, or Gemini) to work on a project.
827
+ * Trigger an AI agent (Claude, Codex, Gemini, or OpenCode) to work on a project.
639
828
  * Supports automatic GitHub branch and pull request creation after successful completion.
640
829
  *
641
830
  * ================================================================================================
@@ -663,7 +852,7 @@ class ResponseCollector {
663
852
  * @param {string} sessionId - (Optional) Existing session ID to resume.
664
853
  * If provided, the request continues that session instead of creating a new one.
665
854
  *
666
- * @param {string} provider - (Optional) AI provider to use. Options: 'claude' | 'cursor' | 'codex' | 'gemini'
855
+ * @param {string} provider - (Optional) AI provider to use. Options: 'claude' | 'codex' | 'gemini' | 'opencode'
667
856
  * Default: 'claude'
668
857
  *
669
858
  * @param {boolean} stream - (Optional) Enable Server-Sent Events (SSE) streaming for real-time updates.
@@ -674,8 +863,7 @@ class ResponseCollector {
674
863
  * @param {string} model - (Optional) Model identifier for providers.
675
864
  *
676
865
  * Claude models: 'sonnet' (default), 'opus', 'haiku', 'opusplan', 'sonnet[1m]'
677
- * Cursor models: 'gpt-5' (default), 'gpt-5.2', 'gpt-5.2-high', 'sonnet-4.5', 'opus-4.5',
678
- * 'gemini-3-pro', 'composer-1', 'auto', 'gpt-5.1', 'gpt-5.1-high',
866
+ * * 'gemini-3-pro', 'composer-1', 'auto', 'gpt-5.1', 'gpt-5.1-high',
679
867
  * 'gpt-5.1-codex', 'gpt-5.1-codex-high', 'gpt-5.1-codex-max',
680
868
  * 'gpt-5.1-codex-max-high', 'opus-4.1', 'grok', and thinking variants
681
869
  * Codex models: 'gpt-5.2' (default), 'gpt-5.1-codex-max', 'o3', 'o4-mini'
@@ -729,6 +917,16 @@ class ResponseCollector {
729
917
  * - If PR already exists: GitHub returns error with details
730
918
  * - Requires either githubUrl OR projectPath with GitHub remote
731
919
  *
920
+ * @param {object} callback - (Optional) Terminal webhook configuration for external systems.
921
+ * Behavior:
922
+ * - Sent once when the run ends as completed, errored, or aborted
923
+ * - Delivery is asynchronous and never blocks the main API response
924
+ * - Not supported with openOnly=true
925
+ * Fields:
926
+ * - url: Required HTTP/HTTPS target URL
927
+ * - events: Optional subset of ["completed", "errored", "aborted"]
928
+ * - secret: Optional shared secret for HMAC signing
929
+ *
732
930
  * ================================================================================================
733
931
  * PATH HANDLING BEHAVIOR
734
932
  * ================================================================================================
@@ -782,9 +980,13 @@ class ResponseCollector {
782
980
  * Input Validations (400 Bad Request):
783
981
  * - Either githubUrl OR projectPath must be provided (not neither)
784
982
  * - message must be non-empty string
785
- * - provider must be 'claude', 'cursor', 'codex', or 'gemini'
983
+ * - provider must be 'claude', 'codex', 'gemini', or 'opencode'
786
984
  * - createBranch/createPR requires githubUrl OR projectPath (not neither)
787
985
  * - branchName must pass Git naming rules (if provided)
986
+ * - callback must be an object when provided
987
+ * - callback.url must be a valid HTTP/HTTPS URL
988
+ * - callback.events can only include completed/errored/aborted
989
+ * - callback is not supported when openOnly=true
788
990
  *
789
991
  * Runtime Validations (500 Internal Server Error or specific error in response):
790
992
  * - projectPath must exist (if used alone)
@@ -843,6 +1045,14 @@ class ResponseCollector {
843
1045
  * Content-Type: application/json
844
1046
  * { success: false, error: "Error description" }
845
1047
  *
1048
+ * Callback Delivery:
1049
+ * Content-Type: application/json
1050
+ * Headers:
1051
+ * - X-Agent-Event
1052
+ * - X-Agent-Event-Id
1053
+ * - X-Agent-Delivery-Attempt
1054
+ * - X-Agent-Signature (only when callback.secret is provided)
1055
+ *
846
1056
  * ================================================================================================
847
1057
  * EXAMPLES
848
1058
  * ================================================================================================
@@ -872,6 +1082,7 @@ class ResponseCollector {
872
1082
  */
873
1083
  router.post('/', validateExternalApiKey, async (req, res) => {
874
1084
  const { githubUrl, projectPath, message, provider = 'claude', model, githubToken, branchName, sessionId, openOnly } = req.body;
1085
+ const startedAt = new Date().toISOString();
875
1086
 
876
1087
  // Parse stream and cleanup as booleans (handle string "true"/"false" from curl)
877
1088
  const stream = req.body.stream === undefined ? true : (req.body.stream === true || req.body.stream === 'true');
@@ -887,10 +1098,17 @@ router.post('/', validateExternalApiKey, async (req, res) => {
887
1098
  // Keep openOnly requests backward-compatible with existing docs/examples:
888
1099
  // cleanup is irrelevant when we only generate session navigation.
889
1100
  const cleanup = isOpenOnly ? false : requestedCleanup;
1101
+ let callbackConfig = null;
1102
+
1103
+ try {
1104
+ callbackConfig = normalizeAgentCallbackConfig(req.body.callback);
1105
+ } catch (error) {
1106
+ return res.status(400).json({ error: error.message });
1107
+ }
890
1108
 
891
1109
  // Validate inputs
892
- if (!['claude', 'cursor', 'codex', 'gemini', 'opencode'].includes(provider)) {
893
- return res.status(400).json({ error: 'provider must be "claude", "cursor", "codex", "gemini", or "opencode"' });
1110
+ if (!['claude', 'codex', 'gemini', 'opencode'].includes(provider)) {
1111
+ return res.status(400).json({ error: 'provider must be "claude", "codex", "gemini", or "opencode"' });
894
1112
  }
895
1113
 
896
1114
  if (sessionId !== undefined && (typeof sessionId !== 'string' || !sessionId.trim())) {
@@ -917,6 +1135,10 @@ router.post('/', validateExternalApiKey, async (req, res) => {
917
1135
  return res.status(400).json({ error: 'createBranch and createPR are not supported when openOnly=true' });
918
1136
  }
919
1137
 
1138
+ if (isOpenOnly && callbackConfig) {
1139
+ return res.status(400).json({ error: 'callback is not supported when openOnly=true' });
1140
+ }
1141
+
920
1142
  // Validate GitHub branch/PR creation requirements
921
1143
  // Allow branch/PR creation with projectPath as long as it has a GitHub remote
922
1144
  if ((createBranch || createPR) && !githubUrl && !projectPath) {
@@ -955,6 +1177,10 @@ router.post('/', validateExternalApiKey, async (req, res) => {
955
1177
 
956
1178
  let finalProjectPath = null;
957
1179
  let writer = null;
1180
+ let transportWriter = null;
1181
+ let callbackCaptureWriter = new CallbackCaptureWriter();
1182
+ let callbackResult = null;
1183
+ let callbackSessionId = normalizedSessionId;
958
1184
 
959
1185
  try {
960
1186
  // Determine the final project path
@@ -1011,26 +1237,28 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1011
1237
  res.setHeader('Connection', 'keep-alive');
1012
1238
  res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering
1013
1239
 
1014
- writer = new SSEStreamWriter(res);
1240
+ transportWriter = new SSEStreamWriter(res);
1015
1241
 
1016
1242
  // Send initial status
1017
- writer.send({
1243
+ transportWriter.send({
1018
1244
  type: 'status',
1019
1245
  message: statusMessage,
1020
1246
  projectPath: finalProjectPath
1021
1247
  });
1022
1248
  } else {
1023
1249
  // Non-streaming mode: collect messages
1024
- writer = new ResponseCollector();
1250
+ transportWriter = new ResponseCollector();
1025
1251
 
1026
1252
  // Collect initial status message
1027
- writer.send({
1253
+ transportWriter.send({
1028
1254
  type: 'status',
1029
1255
  message: statusMessage,
1030
1256
  projectPath: finalProjectPath
1031
1257
  });
1032
1258
  }
1033
1259
 
1260
+ writer = new TeeWriter(transportWriter, callbackCaptureWriter);
1261
+
1034
1262
  // Start the appropriate session
1035
1263
  if (provider === 'claude') {
1036
1264
  console.log('🤖 Starting Claude SDK session');
@@ -1042,18 +1270,6 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1042
1270
  model: model,
1043
1271
  permissionMode: 'bypassPermissions' // Bypass all permissions for API calls
1044
1272
  }, writer);
1045
-
1046
- } else if (provider === 'cursor') {
1047
- console.log('🖱️ Starting Cursor CLI session');
1048
-
1049
- await spawnCursor(normalizedMessage, {
1050
- projectPath: finalProjectPath,
1051
- cwd: finalProjectPath,
1052
- sessionId: normalizedSessionId,
1053
- resume: !!normalizedSessionId,
1054
- model: model || undefined,
1055
- skipPermissions: true // Bypass permissions for Cursor
1056
- }, writer);
1057
1273
  } else if (provider === 'codex') {
1058
1274
  console.log('🤖 Starting Codex SDK session');
1059
1275
 
@@ -1088,6 +1304,17 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1088
1304
  }, writer);
1089
1305
  }
1090
1306
 
1307
+ callbackSessionId = writer.getSessionId() || callbackCaptureWriter.getSessionId() || normalizedSessionId;
1308
+
1309
+ const terminalState = callbackCaptureWriter.getTerminalState();
1310
+ if (terminalState === 'errored') {
1311
+ throw new Error(callbackCaptureWriter.getTerminalErrorMessage() || `${provider} session failed`);
1312
+ }
1313
+
1314
+ if (terminalState !== 'completed') {
1315
+ throw new AgentSessionAbortedError();
1316
+ }
1317
+
1091
1318
  // Handle GitHub branch and PR creation after successful agent completion
1092
1319
  let branchInfo = null;
1093
1320
  let prInfo = null;
@@ -1270,15 +1497,26 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1270
1497
  }
1271
1498
 
1272
1499
  // Handle response based on streaming mode
1500
+ callbackSessionId = writer.getSessionId() || callbackCaptureWriter.getSessionId() || normalizedSessionId;
1501
+ const { sessionPath, sessionUrl } = buildSessionNavigation(callbackSessionId);
1502
+
1273
1503
  if (stream) {
1504
+ callbackResult = {
1505
+ sessionPath,
1506
+ sessionUrl,
1507
+ messages: callbackCaptureWriter.getAssistantMessages(),
1508
+ tokens: callbackCaptureWriter.getTotalTokens(),
1509
+ branch: branchInfo,
1510
+ pullRequest: prInfo
1511
+ };
1512
+
1274
1513
  // Streaming mode: end the SSE stream
1275
1514
  writer.end();
1276
1515
  } else {
1277
1516
  // Non-streaming mode: send filtered messages and token summary as JSON
1278
- const assistantMessages = writer.getAssistantMessages();
1279
- const tokenSummary = writer.getTotalTokens();
1280
- const resolvedSessionId = writer.getSessionId() || normalizedSessionId;
1281
- const { sessionPath, sessionUrl } = buildSessionNavigation(resolvedSessionId);
1517
+ const assistantMessages = transportWriter.getAssistantMessages();
1518
+ const tokenSummary = transportWriter.getTotalTokens();
1519
+ const resolvedSessionId = transportWriter.getSessionId() || callbackSessionId;
1282
1520
 
1283
1521
  const response = {
1284
1522
  success: true,
@@ -1299,9 +1537,37 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1299
1537
  response.pullRequest = prInfo;
1300
1538
  }
1301
1539
 
1540
+ callbackResult = {
1541
+ sessionPath,
1542
+ sessionUrl,
1543
+ messages: assistantMessages,
1544
+ tokens: tokenSummary,
1545
+ branch: branchInfo,
1546
+ pullRequest: prInfo
1547
+ };
1548
+
1302
1549
  res.json(response);
1303
1550
  }
1304
1551
 
1552
+ if (callbackConfig && shouldDeliverAgentCallback(callbackConfig, 'completed')) {
1553
+ const payload = buildAgentCallbackPayload({
1554
+ event: 'completed',
1555
+ eventId: createAgentCallbackEventId(),
1556
+ sessionId: callbackSessionId,
1557
+ provider,
1558
+ projectPath: finalProjectPath,
1559
+ isResumed: !!normalizedSessionId,
1560
+ startedAt,
1561
+ finishedAt: new Date().toISOString(),
1562
+ result: callbackResult
1563
+ });
1564
+
1565
+ void scheduleAgentCallbackDelivery({
1566
+ callback: callbackConfig,
1567
+ payload
1568
+ });
1569
+ }
1570
+
1305
1571
  // Clean up if requested
1306
1572
  if (cleanup && githubUrl) {
1307
1573
  // Only cleanup if we cloned a repo (not for existing project paths)
@@ -1313,6 +1579,15 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1313
1579
 
1314
1580
  } catch (error) {
1315
1581
  console.error('❌ External session error:', error);
1582
+ const terminalEvent = error instanceof AgentSessionAbortedError ? 'aborted' : 'errored';
1583
+ callbackSessionId = (writer && writer.getSessionId()) || callbackCaptureWriter.getSessionId() || normalizedSessionId;
1584
+ const { sessionPath, sessionUrl } = buildSessionNavigation(callbackSessionId);
1585
+ callbackResult = {
1586
+ sessionPath,
1587
+ sessionUrl,
1588
+ messages: callbackCaptureWriter.getAssistantMessages(),
1589
+ tokens: callbackCaptureWriter.getTotalTokens()
1590
+ };
1316
1591
 
1317
1592
  // Clean up on error
1318
1593
  if (finalProjectPath && cleanup && githubUrl) {
@@ -1328,7 +1603,8 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1328
1603
  res.setHeader('Cache-Control', 'no-cache');
1329
1604
  res.setHeader('Connection', 'keep-alive');
1330
1605
  res.setHeader('X-Accel-Buffering', 'no');
1331
- writer = new SSEStreamWriter(res);
1606
+ transportWriter = new SSEStreamWriter(res);
1607
+ writer = new TeeWriter(transportWriter, callbackCaptureWriter);
1332
1608
  }
1333
1609
 
1334
1610
  if (!res.writableEnded) {
@@ -1345,6 +1621,129 @@ router.post('/', validateExternalApiKey, async (req, res) => {
1345
1621
  error: error.message
1346
1622
  });
1347
1623
  }
1624
+
1625
+ if (callbackConfig && shouldDeliverAgentCallback(callbackConfig, terminalEvent)) {
1626
+ const callbackError = terminalEvent === 'aborted'
1627
+ ? { message: 'Session aborted' }
1628
+ : { message: error.message };
1629
+
1630
+ const payload = buildAgentCallbackPayload({
1631
+ event: terminalEvent,
1632
+ eventId: createAgentCallbackEventId(),
1633
+ sessionId: callbackSessionId,
1634
+ provider,
1635
+ projectPath: finalProjectPath,
1636
+ isResumed: !!normalizedSessionId,
1637
+ startedAt,
1638
+ finishedAt: new Date().toISOString(),
1639
+ result: callbackResult,
1640
+ error: callbackError
1641
+ });
1642
+
1643
+ void scheduleAgentCallbackDelivery({
1644
+ callback: callbackConfig,
1645
+ payload
1646
+ });
1647
+ }
1648
+ }
1649
+ });
1650
+
1651
+ /**
1652
+ * POST /api/agent/abort
1653
+ *
1654
+ * Interrupt an active AI agent session.
1655
+ *
1656
+ * ================================================================================================
1657
+ * REQUEST BODY PARAMETERS
1658
+ * ================================================================================================
1659
+ *
1660
+ * @param {string} sessionId - (Required) Session ID to interrupt.
1661
+ * @param {string} provider - (Optional) AI provider for the active session.
1662
+ * Options: 'claude' | 'codex' | 'gemini' | 'opencode'
1663
+ * Default: 'claude'
1664
+ *
1665
+ * ================================================================================================
1666
+ * VALIDATION & ERROR HANDLING
1667
+ * ================================================================================================
1668
+ *
1669
+ * Input Validations (400 Bad Request):
1670
+ * - sessionId must be a non-empty string
1671
+ * - provider must be 'claude', 'codex', 'gemini', or 'opencode' when provided
1672
+ *
1673
+ * Success Response (200 OK):
1674
+ * {
1675
+ * success: true,
1676
+ * aborted: true,
1677
+ * sessionId: "session-123",
1678
+ * provider: "claude",
1679
+ * message: "Session aborted"
1680
+ * }
1681
+ *
1682
+ * Not Found Response (200 OK):
1683
+ * {
1684
+ * success: false,
1685
+ * aborted: false,
1686
+ * sessionId: "session-123",
1687
+ * provider: "claude",
1688
+ * error: "Active session not found"
1689
+ * }
1690
+ *
1691
+ * Error Response:
1692
+ * HTTP Status: 400, 401, 500
1693
+ * Content-Type: application/json
1694
+ * { success: false, error: "Error description" }
1695
+ */
1696
+ router.post('/abort', validateExternalApiKey, async (req, res) => {
1697
+ const normalizedSessionId = typeof req.body.sessionId === 'string' ? req.body.sessionId.trim() : '';
1698
+ const provider = typeof req.body.provider === 'string' && req.body.provider.trim()
1699
+ ? req.body.provider.trim().toLowerCase()
1700
+ : 'claude';
1701
+
1702
+ if (!normalizedSessionId) {
1703
+ return res.status(400).json({
1704
+ success: false,
1705
+ error: 'sessionId is required'
1706
+ });
1707
+ }
1708
+
1709
+ if (!isAbortableAgentProvider(provider)) {
1710
+ return res.status(400).json({
1711
+ success: false,
1712
+ error: `provider must be one of: ${ABORTABLE_AGENT_PROVIDERS.join(', ')}`
1713
+ });
1714
+ }
1715
+
1716
+ try {
1717
+ const writer = new SessionEventMirrorWriter(new NoopWriter(), provider);
1718
+ const { success } = await abortAgentSessionWithWriter({
1719
+ provider,
1720
+ sessionId: normalizedSessionId,
1721
+ writer
1722
+ });
1723
+
1724
+ if (!success) {
1725
+ return res.json({
1726
+ success: false,
1727
+ aborted: false,
1728
+ sessionId: normalizedSessionId,
1729
+ provider,
1730
+ error: 'Active session not found'
1731
+ });
1732
+ }
1733
+
1734
+ return res.json({
1735
+ success: true,
1736
+ aborted: true,
1737
+ sessionId: normalizedSessionId,
1738
+ provider,
1739
+ message: 'Session aborted'
1740
+ });
1741
+ } catch (error) {
1742
+ console.error('❌ External abort session error:', error);
1743
+ return res.status(500).json({
1744
+ success: false,
1745
+ error: error.message
1746
+ });
1348
1747
  }
1349
1748
  });
1350
1749