kanna-code 0.19.0 → 0.21.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 (327) hide show
  1. package/dist/client/assets/abap-BdImnpbu.js +1 -0
  2. package/dist/client/assets/actionscript-3-CoDkCxhg.js +1 -0
  3. package/dist/client/assets/ada-bCR0ucgS.js +1 -0
  4. package/dist/client/assets/andromeeda-C4gqWexZ.js +1 -0
  5. package/dist/client/assets/angular-html-CU67Zn6k.js +1 -0
  6. package/dist/client/assets/angular-ts-BwZT4LLn.js +1 -0
  7. package/dist/client/assets/apache-Pmp26Uib.js +1 -0
  8. package/dist/client/assets/apex-D8_7TLub.js +1 -0
  9. package/dist/client/assets/apl-dKokRX4l.js +1 -0
  10. package/dist/client/assets/applescript-Co6uUVPk.js +1 -0
  11. package/dist/client/assets/ara-BRHolxvo.js +1 -0
  12. package/dist/client/assets/asciidoc-Ve4PFQV2.js +1 -0
  13. package/dist/client/assets/asm-D_Q5rh1f.js +1 -0
  14. package/dist/client/assets/astro-CbQHKStN.js +1 -0
  15. package/dist/client/assets/aurora-x-D-2ljcwZ.js +1 -0
  16. package/dist/client/assets/awk-DMzUqQB5.js +1 -0
  17. package/dist/client/assets/ayu-dark-DYE7WIF3.js +1 -0
  18. package/dist/client/assets/ayu-light-BA47KaF1.js +1 -0
  19. package/dist/client/assets/ayu-mirage-32ctXXKs.js +1 -0
  20. package/dist/client/assets/ballerina-BFfxhgS-.js +1 -0
  21. package/dist/client/assets/bat-BkioyH1T.js +1 -0
  22. package/dist/client/assets/beancount-k_qm7-4y.js +1 -0
  23. package/dist/client/assets/berry-uYugtg8r.js +1 -0
  24. package/dist/client/assets/bibtex-CHM0blh-.js +1 -0
  25. package/dist/client/assets/bicep-Bmn6On1c.js +1 -0
  26. package/dist/client/assets/bird2-DPOp833l.js +1 -0
  27. package/dist/client/assets/blade-D4QpJJKB.js +1 -0
  28. package/dist/client/assets/bsl-BO_Y6i37.js +1 -0
  29. package/dist/client/assets/c-BIGW1oBm.js +1 -0
  30. package/dist/client/assets/c3-eo99z4R2.js +1 -0
  31. package/dist/client/assets/cadence-Bv_4Rxtq.js +1 -0
  32. package/dist/client/assets/cairo-KRGpt6FW.js +1 -0
  33. package/dist/client/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  34. package/dist/client/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  35. package/dist/client/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  36. package/dist/client/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  37. package/dist/client/assets/clarity-D53aC0YG.js +1 -0
  38. package/dist/client/assets/clojure-P80f7IUj.js +1 -0
  39. package/dist/client/assets/cmake-D1j8_8rp.js +1 -0
  40. package/dist/client/assets/cobol-nwyudZeR.js +1 -0
  41. package/dist/client/assets/codeowners-Bp6g37R7.js +1 -0
  42. package/dist/client/assets/codeql-DsOJ9woJ.js +1 -0
  43. package/dist/client/assets/coffee-Ch7k5sss.js +1 -0
  44. package/dist/client/assets/common-lisp-Cg-RD9OK.js +1 -0
  45. package/dist/client/assets/coq-DkFqJrB1.js +1 -0
  46. package/dist/client/assets/cpp-CofmeUqb.js +1 -0
  47. package/dist/client/assets/crystal-tKQVLTB8.js +1 -0
  48. package/dist/client/assets/csharp-COcwbKMJ.js +1 -0
  49. package/dist/client/assets/css-DPfMkruS.js +1 -0
  50. package/dist/client/assets/csv-fuZLfV_i.js +1 -0
  51. package/dist/client/assets/cue-D82EKSYY.js +1 -0
  52. package/dist/client/assets/cypher-COkxafJQ.js +1 -0
  53. package/dist/client/assets/d-85-TOEBH.js +1 -0
  54. package/dist/client/assets/dark-plus-C3mMm8J8.js +1 -0
  55. package/dist/client/assets/dart-CF10PKvl.js +1 -0
  56. package/dist/client/assets/dax-CEL-wOlO.js +1 -0
  57. package/dist/client/assets/desktop-BmXAJ9_W.js +1 -0
  58. package/dist/client/assets/diff-D97Zzqfu.js +1 -0
  59. package/dist/client/assets/docker-BcOcwvcX.js +1 -0
  60. package/dist/client/assets/dotenv-Da5cRb03.js +1 -0
  61. package/dist/client/assets/dracula-BzJJZx-M.js +1 -0
  62. package/dist/client/assets/dracula-soft-BXkSAIEj.js +1 -0
  63. package/dist/client/assets/dream-maker-BtqSS_iP.js +1 -0
  64. package/dist/client/assets/edge-BkV0erSs.js +1 -0
  65. package/dist/client/assets/elixir-CDX3lj18.js +1 -0
  66. package/dist/client/assets/elm-DbKCFpqz.js +1 -0
  67. package/dist/client/assets/emacs-lisp-C9XAeP06.js +1 -0
  68. package/dist/client/assets/erb-B12qg9BL.js +1 -0
  69. package/dist/client/assets/erlang-DsQrWhSR.js +1 -0
  70. package/dist/client/assets/everforest-dark-BgDCqdQA.js +1 -0
  71. package/dist/client/assets/everforest-light-C8M2exoo.js +1 -0
  72. package/dist/client/assets/fennel-BYunw83y.js +1 -0
  73. package/dist/client/assets/fish-BvzEVeQv.js +1 -0
  74. package/dist/client/assets/fluent-C4IJs8-o.js +1 -0
  75. package/dist/client/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  76. package/dist/client/assets/fortran-free-form-BxgE0vQu.js +1 -0
  77. package/dist/client/assets/fsharp-CXgrBDvD.js +1 -0
  78. package/dist/client/assets/gdresource-BOOCDP_w.js +1 -0
  79. package/dist/client/assets/gdscript-C5YyOfLZ.js +1 -0
  80. package/dist/client/assets/gdshader-DkwncUOv.js +1 -0
  81. package/dist/client/assets/genie-D0YGMca9.js +1 -0
  82. package/dist/client/assets/gherkin-DyxjwDmM.js +1 -0
  83. package/dist/client/assets/git-commit-F4YmCXRG.js +1 -0
  84. package/dist/client/assets/git-rebase-r7XF79zn.js +1 -0
  85. package/dist/client/assets/github-dark-DHJKELXO.js +1 -0
  86. package/dist/client/assets/github-dark-default-Cuk6v7N8.js +1 -0
  87. package/dist/client/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  88. package/dist/client/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  89. package/dist/client/assets/github-light-DAi9KRSo.js +1 -0
  90. package/dist/client/assets/github-light-default-D7oLnXFd.js +1 -0
  91. package/dist/client/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  92. package/dist/client/assets/gleam-BspZqrRM.js +1 -0
  93. package/dist/client/assets/glimmer-js-Rg0-pVw9.js +1 -0
  94. package/dist/client/assets/glimmer-ts-U6CK756n.js +1 -0
  95. package/dist/client/assets/glsl-DplSGwfg.js +1 -0
  96. package/dist/client/assets/gn-n2N0HUVH.js +1 -0
  97. package/dist/client/assets/gnuplot-DdkO51Og.js +1 -0
  98. package/dist/client/assets/go-CxLEBnE3.js +1 -0
  99. package/dist/client/assets/graphql-ChdNCCLP.js +1 -0
  100. package/dist/client/assets/groovy-gcz8RCvz.js +1 -0
  101. package/dist/client/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  102. package/dist/client/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  103. package/dist/client/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  104. package/dist/client/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  105. package/dist/client/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  106. package/dist/client/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  107. package/dist/client/assets/hack-CaT9iCJl.js +1 -0
  108. package/dist/client/assets/haml-B8DHNrY2.js +1 -0
  109. package/dist/client/assets/handlebars-BL8al0AC.js +1 -0
  110. package/dist/client/assets/haskell-Df6bDoY_.js +1 -0
  111. package/dist/client/assets/haxe-CzTSHFRz.js +1 -0
  112. package/dist/client/assets/hcl-BWvSN4gD.js +1 -0
  113. package/dist/client/assets/hjson-D5-asLiD.js +1 -0
  114. package/dist/client/assets/hlsl-D3lLCCz7.js +1 -0
  115. package/dist/client/assets/horizon-BUw7H-hv.js +1 -0
  116. package/dist/client/assets/horizon-bright-Cn-bp-IR.js +1 -0
  117. package/dist/client/assets/houston-DnULxvSX.js +1 -0
  118. package/dist/client/assets/html-GMplVEZG.js +1 -0
  119. package/dist/client/assets/html-derivative-BFtXZ54Q.js +1 -0
  120. package/dist/client/assets/http-jrhK8wxY.js +1 -0
  121. package/dist/client/assets/hurl-irOxFIW8.js +1 -0
  122. package/dist/client/assets/hxml-Bvhsp5Yf.js +1 -0
  123. package/dist/client/assets/hy-DFXneXwc.js +1 -0
  124. package/dist/client/assets/imba-DGztddWO.js +1 -0
  125. package/dist/client/assets/index-B-8fHyaU.css +32 -0
  126. package/dist/client/assets/index-DrUC3AGz.js +2502 -0
  127. package/dist/client/assets/ini-BEwlwnbL.js +1 -0
  128. package/dist/client/assets/java-CylS5w8V.js +1 -0
  129. package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
  130. package/dist/client/assets/jinja-4LBKfQ-Z.js +1 -0
  131. package/dist/client/assets/jison-wvAkD_A8.js +1 -0
  132. package/dist/client/assets/json-Cp-IABpG.js +1 -0
  133. package/dist/client/assets/json5-C9tS-k6U.js +1 -0
  134. package/dist/client/assets/jsonc-Des-eS-w.js +1 -0
  135. package/dist/client/assets/jsonl-DcaNXYhu.js +1 -0
  136. package/dist/client/assets/jsonnet-DFQXde-d.js +1 -0
  137. package/dist/client/assets/jssm-C2t-YnRu.js +1 -0
  138. package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
  139. package/dist/client/assets/julia-CxzCAyBv.js +1 -0
  140. package/dist/client/assets/just-Cw27pwNe.js +1 -0
  141. package/dist/client/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  142. package/dist/client/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  143. package/dist/client/assets/kanagawa-wave-DWedfzmr.js +1 -0
  144. package/dist/client/assets/kdl-DV7GczEv.js +1 -0
  145. package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
  146. package/dist/client/assets/kusto-DZf3V79B.js +1 -0
  147. package/dist/client/assets/laserwave-DUszq2jm.js +1 -0
  148. package/dist/client/assets/latex-CWtU0Tv5.js +1 -0
  149. package/dist/client/assets/lean-BZvkOJ9d.js +1 -0
  150. package/dist/client/assets/less-B1dDrJ26.js +1 -0
  151. package/dist/client/assets/light-plus-B7mTdjB0.js +1 -0
  152. package/dist/client/assets/liquid-DYVedYrR.js +1 -0
  153. package/dist/client/assets/llvm-DjAJT7YJ.js +1 -0
  154. package/dist/client/assets/log-2UxHyX5q.js +1 -0
  155. package/dist/client/assets/logo-BtOb2qkB.js +1 -0
  156. package/dist/client/assets/lua-BaeVxFsk.js +1 -0
  157. package/dist/client/assets/luau-C-HG3fhB.js +1 -0
  158. package/dist/client/assets/make-CHLpvVh8.js +1 -0
  159. package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
  160. package/dist/client/assets/marko-CnJfTvn9.js +1 -0
  161. package/dist/client/assets/material-theme-D5KoaKCx.js +1 -0
  162. package/dist/client/assets/material-theme-darker-BfHTSMKl.js +1 -0
  163. package/dist/client/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  164. package/dist/client/assets/material-theme-ocean-CyktbL80.js +1 -0
  165. package/dist/client/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  166. package/dist/client/assets/matlab-D7o27uSR.js +1 -0
  167. package/dist/client/assets/mdc-BMNejdWA.js +1 -0
  168. package/dist/client/assets/mdx-Cmh6b_Ma.js +1 -0
  169. package/dist/client/assets/mermaid-mWjccvbQ.js +1 -0
  170. package/dist/client/assets/min-dark-CafNBF8u.js +1 -0
  171. package/dist/client/assets/min-light-CTRr51gU.js +1 -0
  172. package/dist/client/assets/mipsasm-CKIfxQSi.js +1 -0
  173. package/dist/client/assets/mojo-rZm6bMo-.js +1 -0
  174. package/dist/client/assets/monokai-D4h5O-jR.js +1 -0
  175. package/dist/client/assets/moonbit-_H4v1dQx.js +1 -0
  176. package/dist/client/assets/move-IF9eRakj.js +1 -0
  177. package/dist/client/assets/narrat-DRg8JJMk.js +1 -0
  178. package/dist/client/assets/nextflow-Zz6hmt5N.js +1 -0
  179. package/dist/client/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  180. package/dist/client/assets/nginx-BpAMiNFr.js +1 -0
  181. package/dist/client/assets/night-owl-C39BiMTA.js +1 -0
  182. package/dist/client/assets/night-owl-light-CMTm3GFP.js +1 -0
  183. package/dist/client/assets/nim-CVrawwO9.js +1 -0
  184. package/dist/client/assets/nix-CwoSXNpI.js +1 -0
  185. package/dist/client/assets/nord-Ddv68eIx.js +1 -0
  186. package/dist/client/assets/nushell-Cz2AlsmD.js +1 -0
  187. package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
  188. package/dist/client/assets/objective-cpp-CLxacb5B.js +1 -0
  189. package/dist/client/assets/ocaml-C0hk2d4L.js +1 -0
  190. package/dist/client/assets/odin-BBf5iR-q.js +1 -0
  191. package/dist/client/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  192. package/dist/client/assets/one-light-C3Wv6jpd.js +1 -0
  193. package/dist/client/assets/openscad-C4EeE6gA.js +1 -0
  194. package/dist/client/assets/pascal-D93ZcfNL.js +1 -0
  195. package/dist/client/assets/perl-C0TMdlhV.js +1 -0
  196. package/dist/client/assets/php-Dhbhpdrm.js +1 -0
  197. package/dist/client/assets/pierre-dark-DF2SEV7i.js +1 -0
  198. package/dist/client/assets/pierre-light-DOlZxES8.js +1 -0
  199. package/dist/client/assets/pkl-u5AG7uiY.js +1 -0
  200. package/dist/client/assets/plastic-3e1v2bzS.js +1 -0
  201. package/dist/client/assets/plsql-ChMvpjG-.js +1 -0
  202. package/dist/client/assets/po-BTJTHyun.js +1 -0
  203. package/dist/client/assets/poimandres-CS3Unz2-.js +1 -0
  204. package/dist/client/assets/polar-C0HS_06l.js +1 -0
  205. package/dist/client/assets/postcss-CXtECtnM.js +1 -0
  206. package/dist/client/assets/powerquery-CEu0bR-o.js +1 -0
  207. package/dist/client/assets/powershell-Dpen1YoG.js +1 -0
  208. package/dist/client/assets/prisma-Dd19v3D-.js +1 -0
  209. package/dist/client/assets/prolog-CbFg5uaA.js +1 -0
  210. package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
  211. package/dist/client/assets/pug-CGlum2m_.js +1 -0
  212. package/dist/client/assets/puppet-BMWR74SV.js +1 -0
  213. package/dist/client/assets/purescript-CklMAg4u.js +1 -0
  214. package/dist/client/assets/python-B6aJPvgy.js +1 -0
  215. package/dist/client/assets/qml-3beO22l8.js +1 -0
  216. package/dist/client/assets/qmldir-C8lEn-DE.js +1 -0
  217. package/dist/client/assets/qss-IeuSbFQv.js +1 -0
  218. package/dist/client/assets/r-Dspwwk_N.js +1 -0
  219. package/dist/client/assets/racket-BqYA7rlc.js +1 -0
  220. package/dist/client/assets/raku-DXvB9xmW.js +1 -0
  221. package/dist/client/assets/razor-Uh8Bk_45.js +1 -0
  222. package/dist/client/assets/red-bN70gL4F.js +1 -0
  223. package/dist/client/assets/reg-C-SQnVFl.js +1 -0
  224. package/dist/client/assets/regexp-CDVJQ6XC.js +1 -0
  225. package/dist/client/assets/rel-C3B-1QV4.js +1 -0
  226. package/dist/client/assets/riscv-BM1_JUlF.js +1 -0
  227. package/dist/client/assets/ron-D8l8udqQ.js +1 -0
  228. package/dist/client/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  229. package/dist/client/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  230. package/dist/client/assets/rose-pine-qdsjHGoJ.js +1 -0
  231. package/dist/client/assets/rosmsg-BJDFO7_C.js +1 -0
  232. package/dist/client/assets/rst-BrH8l1NY.js +1 -0
  233. package/dist/client/assets/ruby-Dw2BHqvy.js +1 -0
  234. package/dist/client/assets/rust-B1yitclQ.js +1 -0
  235. package/dist/client/assets/sas-cz2c8ADy.js +1 -0
  236. package/dist/client/assets/sass-Cj5Yp3dK.js +1 -0
  237. package/dist/client/assets/scala-C151Ov-r.js +1 -0
  238. package/dist/client/assets/scheme-C98Dy4si.js +1 -0
  239. package/dist/client/assets/scss-OYdSNvt2.js +1 -0
  240. package/dist/client/assets/sdbl-DVxCFoDh.js +1 -0
  241. package/dist/client/assets/shaderlab-Dg9Lc6iA.js +1 -0
  242. package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
  243. package/dist/client/assets/shellsession-BADoaaVG.js +1 -0
  244. package/dist/client/assets/slack-dark-BthQWCQV.js +1 -0
  245. package/dist/client/assets/slack-ochin-DqwNpetd.js +1 -0
  246. package/dist/client/assets/smalltalk-BERRCDM3.js +1 -0
  247. package/dist/client/assets/snazzy-light-Bw305WKR.js +1 -0
  248. package/dist/client/assets/solarized-dark-DXbdFlpD.js +1 -0
  249. package/dist/client/assets/solarized-light-L9t79GZl.js +1 -0
  250. package/dist/client/assets/solidity-rGO070M0.js +1 -0
  251. package/dist/client/assets/soy-Brmx7dQM.js +1 -0
  252. package/dist/client/assets/sparql-rVzFXLq3.js +1 -0
  253. package/dist/client/assets/splunk-BtCnVYZw.js +1 -0
  254. package/dist/client/assets/sql-BLtJtn59.js +1 -0
  255. package/dist/client/assets/ssh-config-_ykCGR6B.js +1 -0
  256. package/dist/client/assets/stata-BH5u7GGu.js +1 -0
  257. package/dist/client/assets/stylus-BEDo0Tqx.js +1 -0
  258. package/dist/client/assets/surrealql-Bq5Q-fJD.js +1 -0
  259. package/dist/client/assets/svelte-C_ipcX3V.js +1 -0
  260. package/dist/client/assets/swift-D82vCrfD.js +1 -0
  261. package/dist/client/assets/synthwave-84-CbfX1IO0.js +1 -0
  262. package/dist/client/assets/system-verilog-CnnmHF94.js +1 -0
  263. package/dist/client/assets/systemd-4A_iFExJ.js +1 -0
  264. package/dist/client/assets/talonscript-CkByrt1z.js +1 -0
  265. package/dist/client/assets/tasl-QIJgUcNo.js +1 -0
  266. package/dist/client/assets/tcl-dwOrl1Do.js +1 -0
  267. package/dist/client/assets/templ-P3uqSqPl.js +1 -0
  268. package/dist/client/assets/terraform-BETggiCN.js +1 -0
  269. package/dist/client/assets/tex-idrVyKtj.js +1 -0
  270. package/dist/client/assets/tokyo-night-hegEt444.js +1 -0
  271. package/dist/client/assets/toml-vGWfd6FD.js +1 -0
  272. package/dist/client/assets/ts-tags-zn1MmPIZ.js +1 -0
  273. package/dist/client/assets/tsv-B_m7g4N7.js +1 -0
  274. package/dist/client/assets/tsx-COt5Ahok.js +1 -0
  275. package/dist/client/assets/turtle-BsS91CYL.js +1 -0
  276. package/dist/client/assets/twig-DNn4PbVi.js +1 -0
  277. package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
  278. package/dist/client/assets/typespec-BGHnOYBU.js +1 -0
  279. package/dist/client/assets/typst-DHCkPAjA.js +1 -0
  280. package/dist/client/assets/v-BcVCzyr7.js +1 -0
  281. package/dist/client/assets/vala-CsfeWuGM.js +1 -0
  282. package/dist/client/assets/vb-D17OF-Vu.js +1 -0
  283. package/dist/client/assets/verilog-BQ8w6xss.js +1 -0
  284. package/dist/client/assets/vesper-DU1UobuO.js +1 -0
  285. package/dist/client/assets/vhdl-CeAyd5Ju.js +1 -0
  286. package/dist/client/assets/viml-CJc9bBzg.js +1 -0
  287. package/dist/client/assets/vitesse-black-Bkuqu6BP.js +1 -0
  288. package/dist/client/assets/vitesse-dark-D0r3Knsf.js +1 -0
  289. package/dist/client/assets/vitesse-light-CVO1_9PV.js +1 -0
  290. package/dist/client/assets/vue-DN_0RTcg.js +1 -0
  291. package/dist/client/assets/vue-html-AaS7Mt5G.js +1 -0
  292. package/dist/client/assets/vue-vine-CQOfvN7w.js +1 -0
  293. package/dist/client/assets/vyper-CDx5xZoG.js +1 -0
  294. package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
  295. package/dist/client/assets/wasm-MzD3tlZU.js +1 -0
  296. package/dist/client/assets/wenyan-BV7otONQ.js +1 -0
  297. package/dist/client/assets/wgsl-Dx-B1_4e.js +1 -0
  298. package/dist/client/assets/wikitext-BhOHFoWU.js +1 -0
  299. package/dist/client/assets/wit-5i3qLPDT.js +1 -0
  300. package/dist/client/assets/wolfram-lXgVvXCa.js +1 -0
  301. package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
  302. package/dist/client/assets/xsl-CtQFsRM5.js +1 -0
  303. package/dist/client/assets/yaml-Buea-lGh.js +1 -0
  304. package/dist/client/assets/zenscript-DVFEvuxE.js +1 -0
  305. package/dist/client/assets/zig-VOosw3JB.js +1 -0
  306. package/dist/client/index.html +2 -2
  307. package/package.json +2 -1
  308. package/src/server/agent.test.ts +589 -1
  309. package/src/server/agent.ts +459 -22
  310. package/src/server/codex-app-server-protocol.ts +28 -0
  311. package/src/server/codex-app-server.test.ts +88 -0
  312. package/src/server/codex-app-server.ts +71 -1
  313. package/src/server/diff-store.test.ts +126 -0
  314. package/src/server/diff-store.ts +365 -0
  315. package/src/server/generate-commit-message.test.ts +59 -0
  316. package/src/server/generate-commit-message.ts +121 -0
  317. package/src/server/read-models.test.ts +1 -1
  318. package/src/server/read-models.ts +6 -1
  319. package/src/server/server.ts +60 -1
  320. package/src/server/terminal-manager.test.ts +37 -4
  321. package/src/server/uploads.ts +4 -0
  322. package/src/server/ws-router.test.ts +5 -5
  323. package/src/server/ws-router.ts +125 -7
  324. package/src/shared/protocol.ts +4 -0
  325. package/src/shared/types.ts +51 -0
  326. package/dist/client/assets/index-C952_xJD.css +0 -32
  327. package/dist/client/assets/index-lgfU0zw2.js +0 -606
@@ -1,5 +1,12 @@
1
1
  import { describe, expect, test } from "bun:test"
2
- import { AgentCoordinator, buildAttachmentHintText, buildPromptText, normalizeClaudeStreamMessage } from "./agent"
2
+ import {
3
+ AgentCoordinator,
4
+ buildAttachmentHintText,
5
+ buildPromptText,
6
+ maxClaudeContextWindowFromModelUsage,
7
+ normalizeClaudeStreamMessage,
8
+ normalizeClaudeUsageSnapshot,
9
+ } from "./agent"
3
10
  import type { HarnessTurn } from "./harness-types"
4
11
  import type { ChatAttachment, TranscriptEntry } from "../shared/types"
5
12
 
@@ -21,6 +28,44 @@ async function waitFor(condition: () => boolean, timeoutMs = 2000) {
21
28
  }
22
29
  }
23
30
 
31
+ class AsyncEventQueue<T> implements AsyncIterable<T> {
32
+ private readonly values: T[] = []
33
+ private readonly waiters: Array<(result: IteratorResult<T>) => void> = []
34
+ private closed = false
35
+
36
+ push(value: T) {
37
+ const waiter = this.waiters.shift()
38
+ if (waiter) {
39
+ waiter({ done: false, value })
40
+ return
41
+ }
42
+ this.values.push(value)
43
+ }
44
+
45
+ close() {
46
+ this.closed = true
47
+ while (this.waiters.length > 0) {
48
+ this.waiters.shift()?.({ done: true, value: undefined as never })
49
+ }
50
+ }
51
+
52
+ [Symbol.asyncIterator](): AsyncIterator<T> {
53
+ return {
54
+ next: async () => {
55
+ if (this.values.length > 0) {
56
+ return { done: false, value: this.values.shift() as T }
57
+ }
58
+ if (this.closed) {
59
+ return { done: true, value: undefined as never }
60
+ }
61
+ return await new Promise<IteratorResult<T>>((resolve) => {
62
+ this.waiters.push(resolve)
63
+ })
64
+ },
65
+ }
66
+ }
67
+ }
68
+
24
69
  describe("normalizeClaudeStreamMessage", () => {
25
70
  test("normalizes assistant tool calls", () => {
26
71
  const entries = normalizeClaudeStreamMessage({
@@ -61,6 +106,43 @@ describe("normalizeClaudeStreamMessage", () => {
61
106
  if (entries[0]?.kind !== "result") throw new Error("unexpected entry")
62
107
  expect(entries[0].durationMs).toBe(3210)
63
108
  })
109
+
110
+ test("normalizes Claude usage snapshots from SDK usage payloads", () => {
111
+ const snapshot = normalizeClaudeUsageSnapshot({
112
+ input_tokens: 4,
113
+ cache_creation_input_tokens: 2715,
114
+ cache_read_input_tokens: 21144,
115
+ output_tokens: 679,
116
+ tool_uses: 2,
117
+ duration_ms: 654,
118
+ }, 200_000)
119
+
120
+ expect(snapshot).toEqual({
121
+ usedTokens: 24_542,
122
+ inputTokens: 23_863,
123
+ cachedInputTokens: 21_144,
124
+ outputTokens: 679,
125
+ lastUsedTokens: 24_542,
126
+ lastInputTokens: 23_863,
127
+ lastCachedInputTokens: 21_144,
128
+ lastOutputTokens: 679,
129
+ toolUses: 2,
130
+ durationMs: 654,
131
+ maxTokens: 200_000,
132
+ compactsAutomatically: false,
133
+ })
134
+ })
135
+
136
+ test("reads the max Claude context window from modelUsage", () => {
137
+ expect(maxClaudeContextWindowFromModelUsage({
138
+ "claude-opus-4-6": {
139
+ contextWindow: 200_000,
140
+ },
141
+ "claude-opus-4-6[1m]": {
142
+ contextWindow: 1_000_000,
143
+ },
144
+ })).toBe(1_000_000)
145
+ })
64
146
  })
65
147
 
66
148
  describe("attachment prompt helpers", () => {
@@ -706,6 +788,370 @@ describe("AgentCoordinator codex integration", () => {
706
788
  expect(store.messages.some((entry) => entry.kind === "interrupted")).toBe(true)
707
789
  })
708
790
 
791
+ test("UI unblocks immediately when result arrives even if stream stays open", async () => {
792
+ let resolveStream!: () => void
793
+
794
+ const fakeCodexManager = {
795
+ async startSession() {},
796
+ async startTurn(): Promise<HarnessTurn> {
797
+ async function* stream() {
798
+ yield {
799
+ type: "transcript" as const,
800
+ entry: timestamped({
801
+ kind: "system_init",
802
+ provider: "codex",
803
+ model: "gpt-5.4",
804
+ tools: [],
805
+ agents: [],
806
+ slashCommands: [],
807
+ mcpServers: [],
808
+ }),
809
+ }
810
+ // Produce the result event
811
+ yield {
812
+ type: "transcript" as const,
813
+ entry: timestamped({
814
+ kind: "result",
815
+ subtype: "success",
816
+ isError: false,
817
+ durationMs: 120_000,
818
+ result: "done",
819
+ }),
820
+ }
821
+ // Stream stays open (simulates background tasks still running)
822
+ await new Promise<void>((resolve) => {
823
+ resolveStream = resolve
824
+ })
825
+ }
826
+
827
+ return {
828
+ provider: "codex",
829
+ stream: stream(),
830
+ interrupt: async () => {},
831
+ close: () => {
832
+ resolveStream?.()
833
+ },
834
+ }
835
+ },
836
+ }
837
+
838
+ const store = createFakeStore()
839
+ const coordinator = new AgentCoordinator({
840
+ store: store as never,
841
+ onStateChange: () => {},
842
+ codexManager: fakeCodexManager as never,
843
+ })
844
+
845
+ await coordinator.send({
846
+ type: "chat.send",
847
+ chatId: "chat-1",
848
+ provider: "codex",
849
+ content: "run something with a background task",
850
+ })
851
+
852
+ // Wait for the result message to be persisted
853
+ await waitFor(() => store.messages.some((entry) => entry.kind === "result"))
854
+
855
+ // The active turn should be removed even though the stream is still open.
856
+ // This is the key assertion: the UI should show idle (not "Running...")
857
+ // so the user can send new messages without hitting stop.
858
+ expect(coordinator.getActiveStatuses().has("chat-1")).toBe(false)
859
+ expect(store.turnFinishedCount).toBe(1)
860
+
861
+ // The stream is still open, so it should be draining
862
+ expect(coordinator.getDrainingChatIds().has("chat-1")).toBe(true)
863
+
864
+ // Clean up the hanging stream
865
+ resolveStream()
866
+
867
+ // After the stream closes, draining should stop
868
+ await waitFor(() => !coordinator.getDrainingChatIds().has("chat-1"))
869
+ })
870
+
871
+ test("stopDraining closes the stream and removes from draining set", async () => {
872
+ let resolveStream!: () => void
873
+ let streamClosed = false
874
+
875
+ const fakeCodexManager = {
876
+ async startSession() {},
877
+ async startTurn(): Promise<HarnessTurn> {
878
+ async function* stream() {
879
+ yield {
880
+ type: "transcript" as const,
881
+ entry: timestamped({
882
+ kind: "system_init",
883
+ provider: "codex",
884
+ model: "gpt-5.4",
885
+ tools: [],
886
+ agents: [],
887
+ slashCommands: [],
888
+ mcpServers: [],
889
+ }),
890
+ }
891
+ yield {
892
+ type: "transcript" as const,
893
+ entry: timestamped({
894
+ kind: "result",
895
+ subtype: "success",
896
+ isError: false,
897
+ durationMs: 0,
898
+ result: "done",
899
+ }),
900
+ }
901
+ await new Promise<void>((resolve) => {
902
+ resolveStream = resolve
903
+ })
904
+ }
905
+
906
+ return {
907
+ provider: "codex",
908
+ stream: stream(),
909
+ interrupt: async () => {},
910
+ close: () => {
911
+ streamClosed = true
912
+ resolveStream?.()
913
+ },
914
+ }
915
+ },
916
+ }
917
+
918
+ const store = createFakeStore()
919
+ const coordinator = new AgentCoordinator({
920
+ store: store as never,
921
+ onStateChange: () => {},
922
+ codexManager: fakeCodexManager as never,
923
+ })
924
+
925
+ await coordinator.send({
926
+ type: "chat.send",
927
+ chatId: "chat-1",
928
+ provider: "codex",
929
+ content: "work",
930
+ })
931
+
932
+ await waitFor(() => coordinator.getDrainingChatIds().has("chat-1"))
933
+
934
+ await coordinator.stopDraining("chat-1")
935
+
936
+ expect(coordinator.getDrainingChatIds().has("chat-1")).toBe(false)
937
+ expect(streamClosed).toBe(true)
938
+ })
939
+
940
+ test("cancel immediately removes active turn so UI shows idle", async () => {
941
+ let resolveInterrupt!: () => void
942
+ const interruptCalled = new Promise<void>((resolve) => {
943
+ resolveInterrupt = resolve
944
+ })
945
+ // interrupt() that hangs until we resolve it — simulating a slow SDK
946
+ let interruptDone = false
947
+
948
+ const fakeCodexManager = {
949
+ async startSession() {},
950
+ async startTurn(): Promise<HarnessTurn> {
951
+ async function* stream() {
952
+ yield {
953
+ type: "transcript" as const,
954
+ entry: timestamped({
955
+ kind: "system_init",
956
+ provider: "codex",
957
+ model: "gpt-5.4",
958
+ tools: [],
959
+ agents: [],
960
+ slashCommands: [],
961
+ mcpServers: [],
962
+ }),
963
+ }
964
+ // Stream that never ends (simulates the SDK hanging)
965
+ await new Promise(() => {})
966
+ }
967
+
968
+ return {
969
+ provider: "codex",
970
+ stream: stream(),
971
+ interrupt: async () => {
972
+ resolveInterrupt()
973
+ // Hang to simulate a slow interrupt
974
+ await new Promise<void>((resolve) => {
975
+ setTimeout(() => {
976
+ interruptDone = true
977
+ resolve()
978
+ }, 100)
979
+ })
980
+ },
981
+ close: () => {},
982
+ }
983
+ },
984
+ }
985
+
986
+ const stateChanges: number[] = []
987
+ const store = createFakeStore()
988
+ const coordinator = new AgentCoordinator({
989
+ store: store as never,
990
+ onStateChange: () => {
991
+ stateChanges.push(Date.now())
992
+ },
993
+ codexManager: fakeCodexManager as never,
994
+ })
995
+
996
+ await coordinator.send({
997
+ type: "chat.send",
998
+ chatId: "chat-1",
999
+ provider: "codex",
1000
+ content: "do something",
1001
+ })
1002
+
1003
+ // Wait for the turn to be running
1004
+ await waitFor(() => coordinator.getActiveStatuses().get("chat-1") === "running")
1005
+
1006
+ // Cancel — this should immediately remove from active turns
1007
+ const cancelPromise = coordinator.cancel("chat-1")
1008
+
1009
+ // The turn should be removed from activeTurns immediately,
1010
+ // BEFORE interrupt() resolves
1011
+ await interruptCalled
1012
+ expect(coordinator.getActiveStatuses().has("chat-1")).toBe(false)
1013
+ expect(interruptDone).toBe(false) // interrupt is still in progress
1014
+
1015
+ await cancelPromise
1016
+
1017
+ // Verify only one "interrupted" message was appended
1018
+ const interruptedMessages = store.messages.filter((entry) => entry.kind === "interrupted")
1019
+ expect(interruptedMessages).toHaveLength(1)
1020
+ })
1021
+
1022
+ test("concurrent cancel calls only produce a single interrupted message", async () => {
1023
+ let resolveStream!: () => void
1024
+
1025
+ const fakeCodexManager = {
1026
+ async startSession() {},
1027
+ async startTurn(): Promise<HarnessTurn> {
1028
+ async function* stream() {
1029
+ yield {
1030
+ type: "transcript" as const,
1031
+ entry: timestamped({
1032
+ kind: "system_init",
1033
+ provider: "codex",
1034
+ model: "gpt-5.4",
1035
+ tools: [],
1036
+ agents: [],
1037
+ slashCommands: [],
1038
+ mcpServers: [],
1039
+ }),
1040
+ }
1041
+ await new Promise<void>((resolve) => {
1042
+ resolveStream = resolve
1043
+ })
1044
+ }
1045
+
1046
+ return {
1047
+ provider: "codex",
1048
+ stream: stream(),
1049
+ interrupt: async () => {
1050
+ resolveStream()
1051
+ },
1052
+ close: () => {},
1053
+ }
1054
+ },
1055
+ }
1056
+
1057
+ const store = createFakeStore()
1058
+ const coordinator = new AgentCoordinator({
1059
+ store: store as never,
1060
+ onStateChange: () => {},
1061
+ codexManager: fakeCodexManager as never,
1062
+ })
1063
+
1064
+ await coordinator.send({
1065
+ type: "chat.send",
1066
+ chatId: "chat-1",
1067
+ provider: "codex",
1068
+ content: "work",
1069
+ })
1070
+
1071
+ await waitFor(() => coordinator.getActiveStatuses().get("chat-1") === "running")
1072
+
1073
+ // Fire multiple cancel calls concurrently (simulating repeated stop button clicks)
1074
+ await Promise.all([
1075
+ coordinator.cancel("chat-1"),
1076
+ coordinator.cancel("chat-1"),
1077
+ coordinator.cancel("chat-1"),
1078
+ ])
1079
+
1080
+ // Only one "interrupted" message should exist
1081
+ const interruptedMessages = store.messages.filter((entry) => entry.kind === "interrupted")
1082
+ expect(interruptedMessages).toHaveLength(1)
1083
+ })
1084
+
1085
+ test("runTurn stops processing events after cancel", async () => {
1086
+ let resolveStream!: () => void
1087
+
1088
+ const fakeCodexManager = {
1089
+ async startSession() {},
1090
+ async startTurn(): Promise<HarnessTurn> {
1091
+ async function* stream() {
1092
+ yield {
1093
+ type: "transcript" as const,
1094
+ entry: timestamped({
1095
+ kind: "system_init",
1096
+ provider: "codex",
1097
+ model: "gpt-5.4",
1098
+ tools: [],
1099
+ agents: [],
1100
+ slashCommands: [],
1101
+ mcpServers: [],
1102
+ }),
1103
+ }
1104
+ // Wait for cancel, then yield another event that should be ignored
1105
+ await new Promise<void>((resolve) => {
1106
+ resolveStream = resolve
1107
+ })
1108
+ // This event arrives after cancel — should not be processed
1109
+ yield {
1110
+ type: "transcript" as const,
1111
+ entry: timestamped({
1112
+ kind: "assistant_text",
1113
+ text: "this should be ignored after cancel",
1114
+ }),
1115
+ }
1116
+ }
1117
+
1118
+ return {
1119
+ provider: "codex",
1120
+ stream: stream(),
1121
+ interrupt: async () => {
1122
+ resolveStream()
1123
+ },
1124
+ close: () => {},
1125
+ }
1126
+ },
1127
+ }
1128
+
1129
+ const store = createFakeStore()
1130
+ const coordinator = new AgentCoordinator({
1131
+ store: store as never,
1132
+ onStateChange: () => {},
1133
+ codexManager: fakeCodexManager as never,
1134
+ })
1135
+
1136
+ await coordinator.send({
1137
+ type: "chat.send",
1138
+ chatId: "chat-1",
1139
+ provider: "codex",
1140
+ content: "work",
1141
+ })
1142
+
1143
+ await waitFor(() => coordinator.getActiveStatuses().get("chat-1") === "running")
1144
+
1145
+ const messageCountBefore = store.messages.filter((entry) => entry.kind === "assistant_text").length
1146
+ await coordinator.cancel("chat-1")
1147
+
1148
+ // Give the stream time to yield the extra event
1149
+ await new Promise((resolve) => setTimeout(resolve, 50))
1150
+
1151
+ const postCancelTextMessages = store.messages.filter((entry) => entry.kind === "assistant_text")
1152
+ expect(postCancelTextMessages.length).toBe(messageCountBefore)
1153
+ })
1154
+
709
1155
  test("cancelling a waiting codex exit-plan prompt discards it without starting a follow-up turn", async () => {
710
1156
  let releaseInterrupt!: () => void
711
1157
  const interrupted = new Promise<void>((resolve) => {
@@ -802,6 +1248,148 @@ describe("AgentCoordinator codex integration", () => {
802
1248
  })
803
1249
  })
804
1250
 
1251
+ describe("AgentCoordinator claude integration", () => {
1252
+ test("reuses a persistent Claude session across turns", async () => {
1253
+ const events = new AsyncEventQueue<any>()
1254
+ const startSessionCalls: Array<{ model: string; planMode: boolean; sessionToken: string | null }> = []
1255
+ const prompts: string[] = []
1256
+
1257
+ const store = createFakeStore()
1258
+ const coordinator = new AgentCoordinator({
1259
+ store: store as never,
1260
+ onStateChange: () => {},
1261
+ startClaudeSession: async (args) => {
1262
+ startSessionCalls.push({
1263
+ model: args.model,
1264
+ planMode: args.planMode,
1265
+ sessionToken: args.sessionToken,
1266
+ })
1267
+
1268
+ return {
1269
+ provider: "claude",
1270
+ stream: events,
1271
+ getAccountInfo: async () => null,
1272
+ interrupt: async () => {},
1273
+ close: () => {},
1274
+ setModel: async () => {},
1275
+ setPermissionMode: async () => {},
1276
+ sendPrompt: async (content: string) => {
1277
+ prompts.push(content)
1278
+ if (prompts.length === 1) {
1279
+ events.push({ type: "session_token" as const, sessionToken: "claude-session-1" })
1280
+ events.push({
1281
+ type: "transcript" as const,
1282
+ entry: timestamped({
1283
+ kind: "system_init",
1284
+ provider: "claude",
1285
+ model: "claude-opus-4-1",
1286
+ tools: [],
1287
+ agents: [],
1288
+ slashCommands: [],
1289
+ mcpServers: [],
1290
+ }),
1291
+ })
1292
+ }
1293
+ events.push({
1294
+ type: "transcript" as const,
1295
+ entry: timestamped({
1296
+ kind: "result",
1297
+ subtype: "success",
1298
+ isError: false,
1299
+ durationMs: 0,
1300
+ result: "done",
1301
+ }),
1302
+ })
1303
+ },
1304
+ }
1305
+ },
1306
+ })
1307
+
1308
+ await coordinator.send({
1309
+ type: "chat.send",
1310
+ chatId: "chat-1",
1311
+ provider: "claude",
1312
+ content: "start background task",
1313
+ model: "claude-opus-4-1",
1314
+ })
1315
+ await waitFor(() => store.turnFinishedCount === 1)
1316
+
1317
+ await coordinator.send({
1318
+ type: "chat.send",
1319
+ chatId: "chat-1",
1320
+ provider: "claude",
1321
+ content: "check task output",
1322
+ model: "claude-opus-4-1",
1323
+ })
1324
+ await waitFor(() => store.turnFinishedCount === 2)
1325
+
1326
+ expect(startSessionCalls).toHaveLength(1)
1327
+ expect(startSessionCalls[0]?.planMode).toBe(false)
1328
+ expect(startSessionCalls[0]?.sessionToken).toBeNull()
1329
+ expect(prompts).toEqual(["start background task", "check task output"])
1330
+ expect(store.chat.sessionToken).toBe("claude-session-1")
1331
+
1332
+ events.close()
1333
+ })
1334
+
1335
+ test("Claude final results clear running state without using draining mode", async () => {
1336
+ const events = new AsyncEventQueue<any>()
1337
+
1338
+ const store = createFakeStore()
1339
+ const coordinator = new AgentCoordinator({
1340
+ store: store as never,
1341
+ onStateChange: () => {},
1342
+ startClaudeSession: async () => ({
1343
+ provider: "claude",
1344
+ stream: events,
1345
+ getAccountInfo: async () => null,
1346
+ interrupt: async () => {},
1347
+ close: () => {},
1348
+ setModel: async () => {},
1349
+ setPermissionMode: async () => {},
1350
+ sendPrompt: async () => {
1351
+ events.push({
1352
+ type: "transcript" as const,
1353
+ entry: timestamped({
1354
+ kind: "system_init",
1355
+ provider: "claude",
1356
+ model: "claude-opus-4-1",
1357
+ tools: [],
1358
+ agents: [],
1359
+ slashCommands: [],
1360
+ mcpServers: [],
1361
+ }),
1362
+ })
1363
+ events.push({
1364
+ type: "transcript" as const,
1365
+ entry: timestamped({
1366
+ kind: "result",
1367
+ subtype: "success",
1368
+ isError: false,
1369
+ durationMs: 0,
1370
+ result: "done",
1371
+ }),
1372
+ })
1373
+ },
1374
+ }),
1375
+ })
1376
+
1377
+ await coordinator.send({
1378
+ type: "chat.send",
1379
+ chatId: "chat-1",
1380
+ provider: "claude",
1381
+ content: "run something",
1382
+ model: "claude-opus-4-1",
1383
+ })
1384
+
1385
+ await waitFor(() => store.turnFinishedCount === 1)
1386
+ expect(coordinator.getActiveStatuses().has("chat-1")).toBe(false)
1387
+ expect(coordinator.getDrainingChatIds().has("chat-1")).toBe(false)
1388
+
1389
+ events.close()
1390
+ })
1391
+ })
1392
+
805
1393
  function createFakeStore() {
806
1394
  const chat = {
807
1395
  id: "chat-1",