relay-ide 0.1.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 (506) hide show
  1. package/README.md +259 -0
  2. package/dist/bin/claude-remote-cli.js +390 -0
  3. package/dist/bin/relay-ide.js +390 -0
  4. package/dist/frontend/assets/abap-BdImnpbu.js +1 -0
  5. package/dist/frontend/assets/actionscript-3-CoDkCxhg.js +1 -0
  6. package/dist/frontend/assets/ada-bCR0ucgS.js +1 -0
  7. package/dist/frontend/assets/andromeeda-C4gqWexZ.js +1 -0
  8. package/dist/frontend/assets/angular-html-DA-rfuFy.js +1 -0
  9. package/dist/frontend/assets/angular-ts-BrjP3tb8.js +1 -0
  10. package/dist/frontend/assets/apache-Pmp26Uib.js +1 -0
  11. package/dist/frontend/assets/apex-D8_7TLub.js +1 -0
  12. package/dist/frontend/assets/apl-CORt7UWP.js +1 -0
  13. package/dist/frontend/assets/applescript-Co6uUVPk.js +1 -0
  14. package/dist/frontend/assets/ara-BRHolxvo.js +1 -0
  15. package/dist/frontend/assets/asciidoc-Ve4PFQV2.js +1 -0
  16. package/dist/frontend/assets/asm-D_Q5rh1f.js +1 -0
  17. package/dist/frontend/assets/astro-HNnZUWAn.js +1 -0
  18. package/dist/frontend/assets/aurora-x-D-2ljcwZ.js +1 -0
  19. package/dist/frontend/assets/awk-DMzUqQB5.js +1 -0
  20. package/dist/frontend/assets/ayu-dark-DYE7WIF3.js +1 -0
  21. package/dist/frontend/assets/ayu-light-BA47KaF1.js +1 -0
  22. package/dist/frontend/assets/ayu-mirage-32ctXXKs.js +1 -0
  23. package/dist/frontend/assets/ballerina-BFfxhgS-.js +1 -0
  24. package/dist/frontend/assets/bat-BkioyH1T.js +1 -0
  25. package/dist/frontend/assets/beancount-k_qm7-4y.js +1 -0
  26. package/dist/frontend/assets/berry-uYugtg8r.js +1 -0
  27. package/dist/frontend/assets/bibtex-CHM0blh-.js +1 -0
  28. package/dist/frontend/assets/bicep-Bmn6On1c.js +1 -0
  29. package/dist/frontend/assets/bird2-BIv1doCn.js +1 -0
  30. package/dist/frontend/assets/blade-BjGOyj-B.js +1 -0
  31. package/dist/frontend/assets/bsl-BO_Y6i37.js +1 -0
  32. package/dist/frontend/assets/c-BIGW1oBm.js +1 -0
  33. package/dist/frontend/assets/c3-eo99z4R2.js +1 -0
  34. package/dist/frontend/assets/cadence-Bv_4Rxtq.js +1 -0
  35. package/dist/frontend/assets/cairo-KRGpt6FW.js +1 -0
  36. package/dist/frontend/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  37. package/dist/frontend/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  38. package/dist/frontend/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  39. package/dist/frontend/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  40. package/dist/frontend/assets/clarity-D53aC0YG.js +1 -0
  41. package/dist/frontend/assets/clojure-P80f7IUj.js +1 -0
  42. package/dist/frontend/assets/cmake-D1j8_8rp.js +1 -0
  43. package/dist/frontend/assets/cobol-nBiQ_Alo.js +1 -0
  44. package/dist/frontend/assets/codeowners-Bp6g37R7.js +1 -0
  45. package/dist/frontend/assets/codeql-DsOJ9woJ.js +1 -0
  46. package/dist/frontend/assets/coffee-Ch7k5sss.js +1 -0
  47. package/dist/frontend/assets/common-lisp-Cg-RD9OK.js +1 -0
  48. package/dist/frontend/assets/coq-DkFqJrB1.js +1 -0
  49. package/dist/frontend/assets/cpp-CofmeUqb.js +1 -0
  50. package/dist/frontend/assets/crystal-DNxU26gB.js +1 -0
  51. package/dist/frontend/assets/csharp-COcwbKMJ.js +1 -0
  52. package/dist/frontend/assets/css-CLj8gQPS.js +1 -0
  53. package/dist/frontend/assets/csv-fuZLfV_i.js +1 -0
  54. package/dist/frontend/assets/cue-D82EKSYY.js +1 -0
  55. package/dist/frontend/assets/cypher-COkxafJQ.js +1 -0
  56. package/dist/frontend/assets/d-85-TOEBH.js +1 -0
  57. package/dist/frontend/assets/dark-plus-C3mMm8J8.js +1 -0
  58. package/dist/frontend/assets/dart-bE4Kk8sk.js +1 -0
  59. package/dist/frontend/assets/dax-CEL-wOlO.js +1 -0
  60. package/dist/frontend/assets/desktop-BmXAJ9_W.js +1 -0
  61. package/dist/frontend/assets/diff-D97Zzqfu.js +1 -0
  62. package/dist/frontend/assets/docker-BcOcwvcX.js +1 -0
  63. package/dist/frontend/assets/dotenv-Da5cRb03.js +1 -0
  64. package/dist/frontend/assets/dracula-BzJJZx-M.js +1 -0
  65. package/dist/frontend/assets/dracula-soft-BXkSAIEj.js +1 -0
  66. package/dist/frontend/assets/dream-maker-BtqSS_iP.js +1 -0
  67. package/dist/frontend/assets/edge-FbVlp4U3.js +1 -0
  68. package/dist/frontend/assets/elixir-CkH2-t6x.js +1 -0
  69. package/dist/frontend/assets/elm-DbKCFpqz.js +1 -0
  70. package/dist/frontend/assets/emacs-lisp-CXvaQtF9.js +1 -0
  71. package/dist/frontend/assets/erb-BYCe7drp.js +1 -0
  72. package/dist/frontend/assets/erlang-DsQrWhSR.js +1 -0
  73. package/dist/frontend/assets/everforest-dark-BgDCqdQA.js +1 -0
  74. package/dist/frontend/assets/everforest-light-C8M2exoo.js +1 -0
  75. package/dist/frontend/assets/fennel-BYunw83y.js +1 -0
  76. package/dist/frontend/assets/fish-BvzEVeQv.js +1 -0
  77. package/dist/frontend/assets/fluent-C4IJs8-o.js +1 -0
  78. package/dist/frontend/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  79. package/dist/frontend/assets/fortran-free-form-BxgE0vQu.js +1 -0
  80. package/dist/frontend/assets/fsharp-CXgrBDvD.js +1 -0
  81. package/dist/frontend/assets/gdresource-BOOCDP_w.js +1 -0
  82. package/dist/frontend/assets/gdscript-C5YyOfLZ.js +1 -0
  83. package/dist/frontend/assets/gdshader-DkwncUOv.js +1 -0
  84. package/dist/frontend/assets/genie-D0YGMca9.js +1 -0
  85. package/dist/frontend/assets/gherkin-DyxjwDmM.js +1 -0
  86. package/dist/frontend/assets/git-commit-F4YmCXRG.js +1 -0
  87. package/dist/frontend/assets/git-rebase-r7XF79zn.js +1 -0
  88. package/dist/frontend/assets/github-dark-DHJKELXO.js +1 -0
  89. package/dist/frontend/assets/github-dark-default-Cuk6v7N8.js +1 -0
  90. package/dist/frontend/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  91. package/dist/frontend/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  92. package/dist/frontend/assets/github-light-DAi9KRSo.js +1 -0
  93. package/dist/frontend/assets/github-light-default-D7oLnXFd.js +1 -0
  94. package/dist/frontend/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  95. package/dist/frontend/assets/gleam-BspZqrRM.js +1 -0
  96. package/dist/frontend/assets/glimmer-js-ByusRIyA.js +1 -0
  97. package/dist/frontend/assets/glimmer-ts-BfAWNZQY.js +1 -0
  98. package/dist/frontend/assets/glsl-DplSGwfg.js +1 -0
  99. package/dist/frontend/assets/gn-n2N0HUVH.js +1 -0
  100. package/dist/frontend/assets/gnuplot-DdkO51Og.js +1 -0
  101. package/dist/frontend/assets/go-C27-OAKa.js +1 -0
  102. package/dist/frontend/assets/graphql-ChdNCCLP.js +1 -0
  103. package/dist/frontend/assets/groovy-gcz8RCvz.js +1 -0
  104. package/dist/frontend/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  105. package/dist/frontend/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  106. package/dist/frontend/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  107. package/dist/frontend/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  108. package/dist/frontend/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  109. package/dist/frontend/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  110. package/dist/frontend/assets/hack-i7_Ulhet.js +1 -0
  111. package/dist/frontend/assets/haml-D5jkg6IW.js +1 -0
  112. package/dist/frontend/assets/handlebars-BpdQsYii.js +1 -0
  113. package/dist/frontend/assets/haskell-Df6bDoY_.js +1 -0
  114. package/dist/frontend/assets/haxe-CzTSHFRz.js +1 -0
  115. package/dist/frontend/assets/hcl-BWvSN4gD.js +1 -0
  116. package/dist/frontend/assets/hjson-D5-asLiD.js +1 -0
  117. package/dist/frontend/assets/hlsl-D3lLCCz7.js +1 -0
  118. package/dist/frontend/assets/horizon-BUw7H-hv.js +1 -0
  119. package/dist/frontend/assets/horizon-bright-CUuTKBJd.js +1 -0
  120. package/dist/frontend/assets/houston-DnULxvSX.js +1 -0
  121. package/dist/frontend/assets/html-derivative-DlHx6ybY.js +1 -0
  122. package/dist/frontend/assets/html-pp8916En.js +1 -0
  123. package/dist/frontend/assets/http-jrhK8wxY.js +1 -0
  124. package/dist/frontend/assets/hurl-irOxFIW8.js +1 -0
  125. package/dist/frontend/assets/hxml-Bvhsp5Yf.js +1 -0
  126. package/dist/frontend/assets/hy-DFXneXwc.js +1 -0
  127. package/dist/frontend/assets/imba-DGztddWO.js +1 -0
  128. package/dist/frontend/assets/ini-BEwlwnbL.js +1 -0
  129. package/dist/frontend/assets/java-CylS5w8V.js +1 -0
  130. package/dist/frontend/assets/javascript-wDzz0qaB.js +1 -0
  131. package/dist/frontend/assets/jinja-f2NsQr07.js +1 -0
  132. package/dist/frontend/assets/jison-wvAkD_A8.js +1 -0
  133. package/dist/frontend/assets/json-Cp-IABpG.js +1 -0
  134. package/dist/frontend/assets/json5-C9tS-k6U.js +1 -0
  135. package/dist/frontend/assets/jsonc-Des-eS-w.js +1 -0
  136. package/dist/frontend/assets/jsonl-DcaNXYhu.js +1 -0
  137. package/dist/frontend/assets/jsonnet-DFQXde-d.js +1 -0
  138. package/dist/frontend/assets/jssm-C2t-YnRu.js +1 -0
  139. package/dist/frontend/assets/jsx-g9-lgVsj.js +1 -0
  140. package/dist/frontend/assets/julia-CxzCAyBv.js +1 -0
  141. package/dist/frontend/assets/just-VxiPbLrw.js +1 -0
  142. package/dist/frontend/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  143. package/dist/frontend/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  144. package/dist/frontend/assets/kanagawa-wave-DWedfzmr.js +1 -0
  145. package/dist/frontend/assets/kdl-DV7GczEv.js +1 -0
  146. package/dist/frontend/assets/kotlin-BdnUsdx6.js +1 -0
  147. package/dist/frontend/assets/kusto-wEQ09or8.js +1 -0
  148. package/dist/frontend/assets/laserwave-DUszq2jm.js +1 -0
  149. package/dist/frontend/assets/latex-CWtU0Tv5.js +1 -0
  150. package/dist/frontend/assets/lean-BZvkOJ9d.js +1 -0
  151. package/dist/frontend/assets/less-B1dDrJ26.js +1 -0
  152. package/dist/frontend/assets/light-plus-B7mTdjB0.js +1 -0
  153. package/dist/frontend/assets/liquid-C0sCDyMI.js +1 -0
  154. package/dist/frontend/assets/llvm-DjAJT7YJ.js +1 -0
  155. package/dist/frontend/assets/log-2UxHyX5q.js +1 -0
  156. package/dist/frontend/assets/logo-BtOb2qkB.js +1 -0
  157. package/dist/frontend/assets/lua-BaeVxFsk.js +1 -0
  158. package/dist/frontend/assets/luau-C-HG3fhB.js +1 -0
  159. package/dist/frontend/assets/main-CL5_Wlhv.css +32 -0
  160. package/dist/frontend/assets/main-Czet4Z1x.js +371 -0
  161. package/dist/frontend/assets/make-CHLpvVh8.js +1 -0
  162. package/dist/frontend/assets/markdown-Cvjx9yec.js +1 -0
  163. package/dist/frontend/assets/marko-DjSrsDqO.js +1 -0
  164. package/dist/frontend/assets/material-theme-D5KoaKCx.js +1 -0
  165. package/dist/frontend/assets/material-theme-darker-BfHTSMKl.js +1 -0
  166. package/dist/frontend/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  167. package/dist/frontend/assets/material-theme-ocean-CyktbL80.js +1 -0
  168. package/dist/frontend/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  169. package/dist/frontend/assets/matlab-D7o27uSR.js +1 -0
  170. package/dist/frontend/assets/mdc-DTYItulj.js +1 -0
  171. package/dist/frontend/assets/mdx-Cmh6b_Ma.js +1 -0
  172. package/dist/frontend/assets/mermaid-mWjccvbQ.js +1 -0
  173. package/dist/frontend/assets/min-dark-CafNBF8u.js +1 -0
  174. package/dist/frontend/assets/min-light-CTRr51gU.js +1 -0
  175. package/dist/frontend/assets/mipsasm-CKIfxQSi.js +1 -0
  176. package/dist/frontend/assets/mojo-rZm6bMo-.js +1 -0
  177. package/dist/frontend/assets/monokai-D4h5O-jR.js +1 -0
  178. package/dist/frontend/assets/moonbit-_H4v1dQx.js +1 -0
  179. package/dist/frontend/assets/move-IF9eRakj.js +1 -0
  180. package/dist/frontend/assets/narrat-DRg8JJMk.js +1 -0
  181. package/dist/frontend/assets/nextflow-C-mBbutL.js +1 -0
  182. package/dist/frontend/assets/nextflow-groovy-vE_lwT2v.js +1 -0
  183. package/dist/frontend/assets/nginx-BpAMiNFr.js +1 -0
  184. package/dist/frontend/assets/night-owl-C39BiMTA.js +1 -0
  185. package/dist/frontend/assets/night-owl-light-CMTm3GFP.js +1 -0
  186. package/dist/frontend/assets/nim-BIad80T-.js +1 -0
  187. package/dist/frontend/assets/nix-CwoSXNpI.js +1 -0
  188. package/dist/frontend/assets/nord-Ddv68eIx.js +1 -0
  189. package/dist/frontend/assets/nushell-Cz2AlsmD.js +1 -0
  190. package/dist/frontend/assets/objective-c-DXmwc3jG.js +1 -0
  191. package/dist/frontend/assets/objective-cpp-CLxacb5B.js +1 -0
  192. package/dist/frontend/assets/ocaml-C0hk2d4L.js +1 -0
  193. package/dist/frontend/assets/odin-BBf5iR-q.js +1 -0
  194. package/dist/frontend/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  195. package/dist/frontend/assets/one-light-C3Wv6jpd.js +1 -0
  196. package/dist/frontend/assets/openscad-C4EeE6gA.js +1 -0
  197. package/dist/frontend/assets/pascal-D93ZcfNL.js +1 -0
  198. package/dist/frontend/assets/perl-NvoQZIq0.js +1 -0
  199. package/dist/frontend/assets/php-R6g_5hLQ.js +1 -0
  200. package/dist/frontend/assets/pkl-u5AG7uiY.js +1 -0
  201. package/dist/frontend/assets/plastic-3e1v2bzS.js +1 -0
  202. package/dist/frontend/assets/plsql-ChMvpjG-.js +1 -0
  203. package/dist/frontend/assets/po-BTJTHyun.js +1 -0
  204. package/dist/frontend/assets/poimandres-CS3Unz2-.js +1 -0
  205. package/dist/frontend/assets/polar-C0HS_06l.js +1 -0
  206. package/dist/frontend/assets/postcss-CXtECtnM.js +1 -0
  207. package/dist/frontend/assets/powerquery-CEu0bR-o.js +1 -0
  208. package/dist/frontend/assets/powershell-Dpen1YoG.js +1 -0
  209. package/dist/frontend/assets/prisma-Dd19v3D-.js +1 -0
  210. package/dist/frontend/assets/prolog-CbFg5uaA.js +1 -0
  211. package/dist/frontend/assets/proto-C7zT0LnQ.js +1 -0
  212. package/dist/frontend/assets/pug-DKIMFp6K.js +1 -0
  213. package/dist/frontend/assets/puppet-BMWR74SV.js +1 -0
  214. package/dist/frontend/assets/purescript-CklMAg4u.js +1 -0
  215. package/dist/frontend/assets/python-B6aJPvgy.js +1 -0
  216. package/dist/frontend/assets/qml-3beO22l8.js +1 -0
  217. package/dist/frontend/assets/qmldir-C8lEn-DE.js +1 -0
  218. package/dist/frontend/assets/qss-IeuSbFQv.js +1 -0
  219. package/dist/frontend/assets/r-Dspwwk_N.js +1 -0
  220. package/dist/frontend/assets/racket-BqYA7rlc.js +1 -0
  221. package/dist/frontend/assets/raku-DXvB9xmW.js +1 -0
  222. package/dist/frontend/assets/razor-BDqjjVU7.js +1 -0
  223. package/dist/frontend/assets/red-bN70gL4F.js +1 -0
  224. package/dist/frontend/assets/reg-C-SQnVFl.js +1 -0
  225. package/dist/frontend/assets/regexp-CDVJQ6XC.js +1 -0
  226. package/dist/frontend/assets/rel-C3B-1QV4.js +1 -0
  227. package/dist/frontend/assets/riscv-BM1_JUlF.js +1 -0
  228. package/dist/frontend/assets/ron-D8l8udqQ.js +1 -0
  229. package/dist/frontend/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  230. package/dist/frontend/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  231. package/dist/frontend/assets/rose-pine-qdsjHGoJ.js +1 -0
  232. package/dist/frontend/assets/rosmsg-BJDFO7_C.js +1 -0
  233. package/dist/frontend/assets/rst-CRjBmOyv.js +1 -0
  234. package/dist/frontend/assets/ruby-Wjq7vjNf.js +1 -0
  235. package/dist/frontend/assets/rust-B1yitclQ.js +1 -0
  236. package/dist/frontend/assets/sas-cz2c8ADy.js +1 -0
  237. package/dist/frontend/assets/sass-Cj5Yp3dK.js +1 -0
  238. package/dist/frontend/assets/scala-C151Ov-r.js +1 -0
  239. package/dist/frontend/assets/scheme-C98Dy4si.js +1 -0
  240. package/dist/frontend/assets/scss-D5BDwBP9.js +1 -0
  241. package/dist/frontend/assets/sdbl-DVxCFoDh.js +1 -0
  242. package/dist/frontend/assets/shaderlab-Dg9Lc6iA.js +1 -0
  243. package/dist/frontend/assets/shellscript-Yzrsuije.js +1 -0
  244. package/dist/frontend/assets/shellsession-BADoaaVG.js +1 -0
  245. package/dist/frontend/assets/slack-dark-BthQWCQV.js +1 -0
  246. package/dist/frontend/assets/slack-ochin-DqwNpetd.js +1 -0
  247. package/dist/frontend/assets/smalltalk-BERRCDM3.js +1 -0
  248. package/dist/frontend/assets/snazzy-light-Bw305WKR.js +1 -0
  249. package/dist/frontend/assets/solarized-dark-DXbdFlpD.js +1 -0
  250. package/dist/frontend/assets/solarized-light-L9t79GZl.js +1 -0
  251. package/dist/frontend/assets/solidity-rGO070M0.js +1 -0
  252. package/dist/frontend/assets/soy-8wufbnw4.js +1 -0
  253. package/dist/frontend/assets/sparql-rVzFXLq3.js +1 -0
  254. package/dist/frontend/assets/splunk-BtCnVYZw.js +1 -0
  255. package/dist/frontend/assets/sql-BLtJtn59.js +1 -0
  256. package/dist/frontend/assets/ssh-config-_ykCGR6B.js +1 -0
  257. package/dist/frontend/assets/stata-BH5u7GGu.js +1 -0
  258. package/dist/frontend/assets/stylus-BEDo0Tqx.js +1 -0
  259. package/dist/frontend/assets/surrealql-Bq5Q-fJD.js +1 -0
  260. package/dist/frontend/assets/svelte-Cy7k_4gC.js +1 -0
  261. package/dist/frontend/assets/swift-D82vCrfD.js +1 -0
  262. package/dist/frontend/assets/synthwave-84-CbfX1IO0.js +1 -0
  263. package/dist/frontend/assets/system-verilog-CnnmHF94.js +1 -0
  264. package/dist/frontend/assets/systemd-4A_iFExJ.js +1 -0
  265. package/dist/frontend/assets/talonscript-CkByrt1z.js +1 -0
  266. package/dist/frontend/assets/tasl-QIJgUcNo.js +1 -0
  267. package/dist/frontend/assets/tcl-dwOrl1Do.js +1 -0
  268. package/dist/frontend/assets/templ-DhtptRzy.js +1 -0
  269. package/dist/frontend/assets/terraform-BETggiCN.js +1 -0
  270. package/dist/frontend/assets/tex-idrVyKtj.js +1 -0
  271. package/dist/frontend/assets/tokyo-night-hegEt444.js +1 -0
  272. package/dist/frontend/assets/toml-vGWfd6FD.js +1 -0
  273. package/dist/frontend/assets/ts-tags-DQrlYJgV.js +1 -0
  274. package/dist/frontend/assets/tsv-B_m7g4N7.js +1 -0
  275. package/dist/frontend/assets/tsx-COt5Ahok.js +1 -0
  276. package/dist/frontend/assets/turtle-BsS91CYL.js +1 -0
  277. package/dist/frontend/assets/twig-xg9kU7Mw.js +1 -0
  278. package/dist/frontend/assets/typescript-BPQ3VLAy.js +1 -0
  279. package/dist/frontend/assets/typespec-CAFt9gP4.js +1 -0
  280. package/dist/frontend/assets/typst-DHCkPAjA.js +1 -0
  281. package/dist/frontend/assets/v-BcVCzyr7.js +1 -0
  282. package/dist/frontend/assets/vala-CsfeWuGM.js +1 -0
  283. package/dist/frontend/assets/vb-D17OF-Vu.js +1 -0
  284. package/dist/frontend/assets/verilog-BQ8w6xss.js +1 -0
  285. package/dist/frontend/assets/vesper-DU1UobuO.js +1 -0
  286. package/dist/frontend/assets/vhdl-CeAyd5Ju.js +1 -0
  287. package/dist/frontend/assets/viml-CJc9bBzg.js +1 -0
  288. package/dist/frontend/assets/vitesse-black-Bkuqu6BP.js +1 -0
  289. package/dist/frontend/assets/vitesse-dark-D0r3Knsf.js +1 -0
  290. package/dist/frontend/assets/vitesse-light-CVO1_9PV.js +1 -0
  291. package/dist/frontend/assets/vue-D2xRrEX4.js +1 -0
  292. package/dist/frontend/assets/vue-html-AaS7Mt5G.js +1 -0
  293. package/dist/frontend/assets/vue-vine-BoDAl6tE.js +1 -0
  294. package/dist/frontend/assets/vyper-CDx5xZoG.js +1 -0
  295. package/dist/frontend/assets/wasm-CG6Dc4jp.js +1 -0
  296. package/dist/frontend/assets/wasm-MzD3tlZU.js +1 -0
  297. package/dist/frontend/assets/wenyan-BV7otONQ.js +1 -0
  298. package/dist/frontend/assets/wgsl-Dx-B1_4e.js +1 -0
  299. package/dist/frontend/assets/wikitext-BhOHFoWU.js +1 -0
  300. package/dist/frontend/assets/wit-5i3qLPDT.js +1 -0
  301. package/dist/frontend/assets/wolfram-lXgVvXCa.js +1 -0
  302. package/dist/frontend/assets/xml-sdJ4AIDG.js +1 -0
  303. package/dist/frontend/assets/xsl-CtQFsRM5.js +1 -0
  304. package/dist/frontend/assets/yaml-Buea-lGh.js +1 -0
  305. package/dist/frontend/assets/zenscript-DVFEvuxE.js +1 -0
  306. package/dist/frontend/assets/zig-VOosw3JB.js +1 -0
  307. package/dist/frontend/icon-192.png +0 -0
  308. package/dist/frontend/icon-512.png +0 -0
  309. package/dist/frontend/icon.svg +8 -0
  310. package/dist/frontend/index.html +30 -0
  311. package/dist/frontend/manifest.json +25 -0
  312. package/dist/frontend/sw.js +66 -0
  313. package/dist/server/agent-events.js +39 -0
  314. package/dist/server/analytics.js +885 -0
  315. package/dist/server/auth.js +65 -0
  316. package/dist/server/belayer/executor.js +200 -0
  317. package/dist/server/belayer/intake.js +27 -0
  318. package/dist/server/belayer/pipeline.js +97 -0
  319. package/dist/server/belayer/pr-lifecycle.js +69 -0
  320. package/dist/server/belayer/prompts.js +154 -0
  321. package/dist/server/belayer/types.js +23 -0
  322. package/dist/server/branch-linker.js +137 -0
  323. package/dist/server/browser-content.js +145 -0
  324. package/dist/server/clipboard.js +63 -0
  325. package/dist/server/codex-hooks-adapter.js +93 -0
  326. package/dist/server/config.js +325 -0
  327. package/dist/server/gh-routes.js +163 -0
  328. package/dist/server/gh.js +276 -0
  329. package/dist/server/git-routes.js +154 -0
  330. package/dist/server/git.js +694 -0
  331. package/dist/server/github-app.js +218 -0
  332. package/dist/server/github-graphql.js +178 -0
  333. package/dist/server/hooks.js +373 -0
  334. package/dist/server/index.js +1549 -0
  335. package/dist/server/integration-github.js +137 -0
  336. package/dist/server/integration-jira.js +210 -0
  337. package/dist/server/integration-linear.js +176 -0
  338. package/dist/server/logger.js +18 -0
  339. package/dist/server/mobile-input-pipeline.js +129 -0
  340. package/dist/server/opencode-relay.js +53 -0
  341. package/dist/server/org-dashboard.js +241 -0
  342. package/dist/server/output-parsers/claude-parser.js +56 -0
  343. package/dist/server/output-parsers/codex-parser.js +13 -0
  344. package/dist/server/output-parsers/index.js +14 -0
  345. package/dist/server/output-parsers/null-parser.js +12 -0
  346. package/dist/server/output-parsers/opencode-parser.js +77 -0
  347. package/dist/server/pty-handler.js +586 -0
  348. package/dist/server/push.js +84 -0
  349. package/dist/server/review-poller.js +237 -0
  350. package/dist/server/sdk-handler.js +539 -0
  351. package/dist/server/service.js +189 -0
  352. package/dist/server/sessions.js +638 -0
  353. package/dist/server/telemetry.js +236 -0
  354. package/dist/server/ticket-transitions.js +166 -0
  355. package/dist/server/types.js +146 -0
  356. package/dist/server/utils.js +23 -0
  357. package/dist/server/watcher.js +661 -0
  358. package/dist/server/webhook-manager.js +547 -0
  359. package/dist/server/webhooks.js +73 -0
  360. package/dist/server/workspace-groups.js +363 -0
  361. package/dist/server/workspaces.js +1207 -0
  362. package/dist/server/ws.js +192 -0
  363. package/dist/test/EmptyState.spec.js +51 -0
  364. package/dist/test/action-coverage.test.js +139 -0
  365. package/dist/test/actions/registry.test.js +59 -0
  366. package/dist/test/actions/shortcuts.test.js +79 -0
  367. package/dist/test/agent-events.test.js +151 -0
  368. package/dist/test/analytics.test.js +158 -0
  369. package/dist/test/attention.test.js +91 -0
  370. package/dist/test/auth.test.js +105 -0
  371. package/dist/test/backend-state.test.js +47 -0
  372. package/dist/test/belayer-executor.test.js +33 -0
  373. package/dist/test/belayer-intake.test.js +44 -0
  374. package/dist/test/belayer-pipeline.test.js +113 -0
  375. package/dist/test/belayer-pr-lifecycle.test.js +26 -0
  376. package/dist/test/belayer-prompts.test.js +60 -0
  377. package/dist/test/belayer-types.test.js +69 -0
  378. package/dist/test/bin/claude-remote-cli.js +214 -0
  379. package/dist/test/boot-state.test.js +133 -0
  380. package/dist/test/branch-lifecycle.test.js +75 -0
  381. package/dist/test/branch-linker.test.js +236 -0
  382. package/dist/test/branch-rename.test.js +45 -0
  383. package/dist/test/branch-watcher.test.js +115 -0
  384. package/dist/test/browser-cli.test.js +91 -0
  385. package/dist/test/browser-content.test.js +93 -0
  386. package/dist/test/browser-tabs-ui.test.js +39 -0
  387. package/dist/test/changed-files-api.test.js +140 -0
  388. package/dist/test/clipboard.test.js +12 -0
  389. package/dist/test/codex-hooks-adapter.test.js +237 -0
  390. package/dist/test/components/EmptyState.spec.js +51 -0
  391. package/dist/test/components/ErrorToast.spec.js +65 -0
  392. package/dist/test/components/TuiCheckbox.spec.js +120 -0
  393. package/dist/test/components/TuiInput.spec.js +186 -0
  394. package/dist/test/components/leaf-component-migration.spec.js +104 -0
  395. package/dist/test/config-freshness.test.js +63 -0
  396. package/dist/test/config.test.js +813 -0
  397. package/dist/test/diff-summary.test.js +98 -0
  398. package/dist/test/display-state.test.js +179 -0
  399. package/dist/test/event-message-types.test.js +32 -0
  400. package/dist/test/file-tree-utils.test.js +167 -0
  401. package/dist/test/framework-types.test.js +183 -0
  402. package/dist/test/frameworks-api.test.js +93 -0
  403. package/dist/test/frontend/src/lib/pr-state.js +114 -0
  404. package/dist/test/fs-browse.test.js +246 -0
  405. package/dist/test/fuzzy-scorer.test.js +145 -0
  406. package/dist/test/gh-routes.test.js +156 -0
  407. package/dist/test/git-changed-files.test.js +152 -0
  408. package/dist/test/git-routes.test.js +146 -0
  409. package/dist/test/git-utils.test.js +68 -0
  410. package/dist/test/git-watcher.test.js +110 -0
  411. package/dist/test/git.test.js +140 -0
  412. package/dist/test/github-app.test.js +455 -0
  413. package/dist/test/github-graphql.test.js +301 -0
  414. package/dist/test/greetings.test.js +83 -0
  415. package/dist/test/hooks-agent-event.test.js +412 -0
  416. package/dist/test/hooks.test.js +149 -0
  417. package/dist/test/integration-github.test.js +220 -0
  418. package/dist/test/integration-jira.test.js +238 -0
  419. package/dist/test/integration-linear.test.js +293 -0
  420. package/dist/test/mobile-input.test.js +235 -0
  421. package/dist/test/opencode-relay.test.js +107 -0
  422. package/dist/test/org-dashboard.test.js +349 -0
  423. package/dist/test/output-parser.test.js +217 -0
  424. package/dist/test/paths.test.js +32 -0
  425. package/dist/test/pr-state.test.js +407 -0
  426. package/dist/test/pr-status.test.js +82 -0
  427. package/dist/test/presets.test.js +242 -0
  428. package/dist/test/pty-handler-multi-agent.test.js +149 -0
  429. package/dist/test/pty-handler.test.js +146 -0
  430. package/dist/test/pull-requests.test.js +78 -0
  431. package/dist/test/review-poller.test.js +349 -0
  432. package/dist/test/server/analytics.js +121 -0
  433. package/dist/test/server/auth.js +63 -0
  434. package/dist/test/server/branch-linker.js +124 -0
  435. package/dist/test/server/clipboard.js +56 -0
  436. package/dist/test/server/config.js +137 -0
  437. package/dist/test/server/git.js +308 -0
  438. package/dist/test/server/hooks.js +196 -0
  439. package/dist/test/server/index.js +1124 -0
  440. package/dist/test/server/integration-github.js +117 -0
  441. package/dist/test/server/integration-jira.js +164 -0
  442. package/dist/test/server/integration-linear.js +176 -0
  443. package/dist/test/server/mobile-input-pipeline.js +123 -0
  444. package/dist/test/server/org-dashboard.js +184 -0
  445. package/dist/test/server/output-parsers/claude-parser.js +54 -0
  446. package/dist/test/server/output-parsers/codex-parser.js +13 -0
  447. package/dist/test/server/output-parsers/index.js +7 -0
  448. package/dist/test/server/pty-handler.js +310 -0
  449. package/dist/test/server/push.js +80 -0
  450. package/dist/test/server/review-poller.js +218 -0
  451. package/dist/test/server/service.js +169 -0
  452. package/dist/test/server/sessions.js +434 -0
  453. package/dist/test/server/ticket-transitions.js +216 -0
  454. package/dist/test/server/types.js +20 -0
  455. package/dist/test/server/utils.js +22 -0
  456. package/dist/test/server/watcher.js +139 -0
  457. package/dist/test/server/workspaces.js +657 -0
  458. package/dist/test/server/ws.js +152 -0
  459. package/dist/test/server-startup.test.js +62 -0
  460. package/dist/test/service.test.js +43 -0
  461. package/dist/test/session-analytics-api.test.js +123 -0
  462. package/dist/test/session-analytics.test.js +425 -0
  463. package/dist/test/session-intent.test.js +249 -0
  464. package/dist/test/sessions.test.js +1152 -0
  465. package/dist/test/sidebar-items.test.js +164 -0
  466. package/dist/test/stores/boot-state-store.test.js +165 -0
  467. package/dist/test/stores/sessions-logic.test.js +191 -0
  468. package/dist/test/stores/toasts-store.test.js +66 -0
  469. package/dist/test/stores/ui-store.test.js +203 -0
  470. package/dist/test/stores/unread-store.test.js +97 -0
  471. package/dist/test/telemetry-api.test.js +54 -0
  472. package/dist/test/telemetry-sync.test.js +68 -0
  473. package/dist/test/telemetry.test.js +295 -0
  474. package/dist/test/terminal-zoom.test.js +102 -0
  475. package/dist/test/test/analytics.test.js +152 -0
  476. package/dist/test/test/auth.test.js +95 -0
  477. package/dist/test/test/branch-linker.test.js +231 -0
  478. package/dist/test/test/branch-rename.test.js +45 -0
  479. package/dist/test/test/clipboard.test.js +12 -0
  480. package/dist/test/test/config.test.js +281 -0
  481. package/dist/test/test/fs-browse.test.js +202 -0
  482. package/dist/test/test/git.test.js +67 -0
  483. package/dist/test/test/hooks.test.js +139 -0
  484. package/dist/test/test/integration-github.test.js +203 -0
  485. package/dist/test/test/integration-jira.test.js +294 -0
  486. package/dist/test/test/integration-linear.test.js +293 -0
  487. package/dist/test/test/mobile-input.test.js +193 -0
  488. package/dist/test/test/org-dashboard.test.js +240 -0
  489. package/dist/test/test/output-parser.test.js +95 -0
  490. package/dist/test/test/paths.test.js +32 -0
  491. package/dist/test/test/pr-state.test.js +220 -0
  492. package/dist/test/test/pull-requests.test.js +67 -0
  493. package/dist/test/test/review-poller.test.js +235 -0
  494. package/dist/test/test/service.test.js +43 -0
  495. package/dist/test/test/sessions.test.js +750 -0
  496. package/dist/test/test/ticket-transitions.test.js +130 -0
  497. package/dist/test/test/version.test.js +34 -0
  498. package/dist/test/test/worktrees.test.js +256 -0
  499. package/dist/test/ticket-transitions.test.js +312 -0
  500. package/dist/test/unread.test.js +23 -0
  501. package/dist/test/version.test.js +34 -0
  502. package/dist/test/webhook-manager.test.js +484 -0
  503. package/dist/test/webhooks.test.js +208 -0
  504. package/dist/test/workspace-groups.test.js +377 -0
  505. package/dist/test/worktrees.test.js +531 -0
  506. package/package.json +88 -0
@@ -0,0 +1,98 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { generateFileSummary } from '../frontend/src/lib/diff-summary.js';
4
+ describe('generateFileSummary', () => {
5
+ it('returns "deleted file" for deleted status', () => {
6
+ assert.equal(generateFileSummary('', 'foo.ts', 'deleted'), 'deleted file');
7
+ });
8
+ it('returns "new file" for untracked with no meaningful content', () => {
9
+ const diff = [
10
+ '+++ b/empty.ts',
11
+ '+import foo from "bar"',
12
+ '+// just a comment',
13
+ ].join('\n');
14
+ assert.equal(generateFileSummary(diff, 'empty.ts', 'untracked'), 'new file');
15
+ });
16
+ it('returns "new file: <line>" for untracked with meaningful content', () => {
17
+ const diff = [
18
+ '+++ b/handler.ts',
19
+ '+import express from "express"',
20
+ '+export function handleRequest(req: Request) {',
21
+ ].join('\n');
22
+ const result = generateFileSummary(diff, 'handler.ts', 'untracked');
23
+ assert.match(result, /^new file: export function handleRequest/);
24
+ });
25
+ it('detects a single added function', () => {
26
+ const diff = [
27
+ '--- a/server.ts',
28
+ '+++ b/server.ts',
29
+ '@@ -10,0 +11,3 @@',
30
+ '+function validateInput(data: unknown) {',
31
+ '+ return data != null;',
32
+ '+}',
33
+ ].join('\n');
34
+ assert.equal(generateFileSummary(diff, 'server.ts', 'modified'), 'added validateInput()');
35
+ });
36
+ it('detects multiple added functions', () => {
37
+ const diff = [
38
+ '--- a/utils.ts',
39
+ '+++ b/utils.ts',
40
+ '@@ -10,0 +11,6 @@',
41
+ '+function first() {',
42
+ '+ return 1;',
43
+ '+}',
44
+ '+function second() {',
45
+ '+ return 2;',
46
+ '+}',
47
+ ].join('\n');
48
+ assert.equal(generateFileSummary(diff, 'utils.ts', 'modified'), 'added 2 functions');
49
+ });
50
+ it('detects modified function from hunk headers', () => {
51
+ const diff = [
52
+ '--- a/api.ts',
53
+ '+++ b/api.ts',
54
+ '@@ -5,3 +5,4 @@ handleRequest',
55
+ ' const x = 1;',
56
+ '+const y = 2;',
57
+ ' return x;',
58
+ ].join('\n');
59
+ const result = generateFileSummary(diff, 'api.ts', 'modified');
60
+ assert.match(result, /modified \d+ lines? in handleRequest\(\)/);
61
+ });
62
+ it('detects multiple modified functions from hunk headers', () => {
63
+ const diff = [
64
+ '--- a/api.ts',
65
+ '+++ b/api.ts',
66
+ '@@ -5,3 +5,4 @@ parseInput',
67
+ ' const x = 1;',
68
+ '+const y = 2;',
69
+ '@@ -20,3 +21,4 @@ formatOutput',
70
+ ' const a = 1;',
71
+ '+const b = 2;',
72
+ ].join('\n');
73
+ assert.equal(generateFileSummary(diff, 'api.ts', 'modified'), 'modified 2 functions');
74
+ });
75
+ it('falls back to +N -N lines when no functions detected', () => {
76
+ const diff = [
77
+ '--- a/config.json',
78
+ '+++ b/config.json',
79
+ '@@ -1,3 +1,4 @@',
80
+ ' {',
81
+ '+ "newKey": true,',
82
+ ' "existing": false',
83
+ '- "removed": true',
84
+ ' }',
85
+ ].join('\n');
86
+ assert.equal(generateFileSummary(diff, 'config.json', 'modified'), '+1 -1 lines');
87
+ });
88
+ it('truncates long first meaningful line for untracked files', () => {
89
+ const longLine = 'x'.repeat(100);
90
+ const diff = [
91
+ '+++ b/long.ts',
92
+ '+import foo from "bar"',
93
+ `+${longLine}`,
94
+ ].join('\n');
95
+ const result = generateFileSummary(diff, 'long.ts', 'untracked');
96
+ assert.ok(result.length <= 72, `Expected truncated result but got length ${result.length}`);
97
+ });
98
+ });
@@ -0,0 +1,179 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { transitionDisplayState, shouldNotify, } from '../frontend/src/lib/state/display-state.js';
4
+ describe('transitionDisplayState', () => {
5
+ const transitionTable = [
6
+ [
7
+ 'initializing',
8
+ { type: 'backend-state-changed', state: 'running' },
9
+ 'running',
10
+ 'initializing + backend-state-changed(running) → running',
11
+ ],
12
+ [
13
+ 'initializing',
14
+ { type: 'backend-state-changed', state: 'idle' },
15
+ 'unseen-idle',
16
+ 'initializing + backend-state-changed(idle) → unseen-idle',
17
+ ],
18
+ [
19
+ 'running',
20
+ { type: 'backend-state-changed', state: 'idle' },
21
+ 'unseen-idle',
22
+ 'running + backend-state-changed(idle) → unseen-idle',
23
+ ],
24
+ [
25
+ 'running',
26
+ { type: 'backend-state-changed', state: 'permission' },
27
+ 'permission',
28
+ 'running + backend-state-changed(permission) → permission',
29
+ ],
30
+ [
31
+ 'unseen-idle',
32
+ { type: 'user-viewed' },
33
+ 'seen-idle',
34
+ 'unseen-idle + user-viewed → seen-idle',
35
+ ],
36
+ [
37
+ 'seen-idle',
38
+ { type: 'backend-state-changed', state: 'running' },
39
+ 'running',
40
+ 'seen-idle + backend-state-changed(running) → running',
41
+ ],
42
+ [
43
+ 'seen-idle',
44
+ { type: 'backend-state-changed', state: 'idle' },
45
+ 'seen-idle',
46
+ 'seen-idle + backend-state-changed(idle) → seen-idle (CRITICAL INVARIANT)',
47
+ ],
48
+ [
49
+ 'permission',
50
+ { type: 'user-viewed' },
51
+ 'permission',
52
+ 'permission + user-viewed → permission (approval must be given, not just viewed)',
53
+ ],
54
+ [
55
+ 'permission',
56
+ { type: 'backend-state-changed', state: 'running' },
57
+ 'running',
58
+ 'permission + backend-state-changed(running) → running',
59
+ ],
60
+ [
61
+ 'running',
62
+ { type: 'session-ended' },
63
+ 'inactive',
64
+ 'running + session-ended → inactive',
65
+ ],
66
+ [
67
+ 'unseen-idle',
68
+ { type: 'backend-state-changed', state: 'idle' },
69
+ 'unseen-idle',
70
+ 'unseen-idle + backend-state-changed(idle) → unseen-idle (idempotent)',
71
+ ],
72
+ [
73
+ 'seen-idle',
74
+ { type: 'session-ended' },
75
+ 'inactive',
76
+ 'seen-idle + session-ended → inactive',
77
+ ],
78
+ [
79
+ 'running',
80
+ {
81
+ type: 'backend-state-changed',
82
+ state: 'permission',
83
+ permissionType: 'question',
84
+ },
85
+ 'needs-answer',
86
+ 'running + backend-state-changed(permission, question) → needs-answer',
87
+ ],
88
+ [
89
+ 'running',
90
+ {
91
+ type: 'backend-state-changed',
92
+ state: 'permission',
93
+ permissionType: 'approval',
94
+ },
95
+ 'permission',
96
+ 'running + backend-state-changed(permission, approval) → permission',
97
+ ],
98
+ [
99
+ 'running',
100
+ { type: 'backend-state-changed', state: 'permission' },
101
+ 'permission',
102
+ 'running + backend-state-changed(permission, no type) → permission (backward compat)',
103
+ ],
104
+ [
105
+ 'needs-answer',
106
+ { type: 'user-viewed' },
107
+ 'needs-answer',
108
+ 'needs-answer + user-viewed → needs-answer (question must be answered, not just viewed)',
109
+ ],
110
+ [
111
+ 'needs-answer',
112
+ { type: 'backend-state-changed', state: 'running' },
113
+ 'running',
114
+ 'needs-answer + backend-state-changed(running) → running',
115
+ ],
116
+ [
117
+ 'running',
118
+ { type: 'backend-state-changed', state: 'error' },
119
+ 'error',
120
+ 'running + backend-state-changed(error) → error',
121
+ ],
122
+ [
123
+ 'error',
124
+ { type: 'session-ended' },
125
+ 'inactive',
126
+ 'error + session-ended → inactive',
127
+ ],
128
+ [
129
+ 'error',
130
+ { type: 'user-viewed' },
131
+ 'error',
132
+ 'error + user-viewed → error (stays — error needs acknowledgment, not just viewing)',
133
+ ],
134
+ [
135
+ 'permission',
136
+ { type: 'backend-state-changed', state: 'idle' },
137
+ 'unseen-idle',
138
+ 'permission + backend-state-changed(idle) → unseen-idle (escape stuck attention state)',
139
+ ],
140
+ [
141
+ 'needs-answer',
142
+ { type: 'backend-state-changed', state: 'idle' },
143
+ 'unseen-idle',
144
+ 'needs-answer + backend-state-changed(idle) → unseen-idle (escape stuck attention state)',
145
+ ],
146
+ [
147
+ 'error',
148
+ { type: 'backend-state-changed', state: 'idle' },
149
+ 'unseen-idle',
150
+ 'error + backend-state-changed(idle) → unseen-idle (escape stuck attention state)',
151
+ ],
152
+ ];
153
+ for (const [current, event, expected, description] of transitionTable) {
154
+ it(description, () => {
155
+ const result = transitionDisplayState(current, event);
156
+ assert.equal(result, expected);
157
+ });
158
+ }
159
+ });
160
+ describe('shouldNotify', () => {
161
+ it('running → unseen-idle → true', () => {
162
+ assert.equal(shouldNotify('running', 'unseen-idle'), true);
163
+ });
164
+ it('running → permission → true', () => {
165
+ assert.equal(shouldNotify('running', 'permission'), true);
166
+ });
167
+ it('initializing → unseen-idle → false', () => {
168
+ assert.equal(shouldNotify('initializing', 'unseen-idle'), false);
169
+ });
170
+ it('seen-idle → seen-idle → false', () => {
171
+ assert.equal(shouldNotify('seen-idle', 'seen-idle'), false);
172
+ });
173
+ it('running → needs-answer → true', () => {
174
+ assert.equal(shouldNotify('running', 'needs-answer'), true);
175
+ });
176
+ it('running → error → true', () => {
177
+ assert.equal(shouldNotify('running', 'error'), true);
178
+ });
179
+ });
@@ -0,0 +1,32 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import { execFileSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ import fs from 'node:fs';
6
+ function findTsc(startDir) {
7
+ let dir = startDir;
8
+ for (let i = 0; i < 5; i++) {
9
+ const candidate = path.join(dir, 'node_modules', '.bin', 'tsc');
10
+ if (fs.existsSync(candidate))
11
+ return candidate;
12
+ const parent = path.dirname(dir);
13
+ if (parent === dir)
14
+ break;
15
+ dir = parent;
16
+ }
17
+ return 'tsc'; // fallback to PATH
18
+ }
19
+ test('EventMessage types compile without errors', () => {
20
+ const tscPath = findTsc(process.cwd());
21
+ try {
22
+ execFileSync(tscPath, ['--noEmit', '--strict', '-p', 'tsconfig.json'], {
23
+ cwd: process.cwd(),
24
+ encoding: 'utf-8',
25
+ });
26
+ assert.ok(true, 'TypeScript compilation succeeded');
27
+ }
28
+ catch (err) {
29
+ const e = err;
30
+ assert.fail(`TypeScript compilation failed:\n${e.stdout ?? ''}\n${e.stderr ?? ''}`);
31
+ }
32
+ });
@@ -0,0 +1,167 @@
1
+ import { test, describe } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildChangedFilesTree, flattenVisibleNodes, findMostRecentlyChanged, parseLineReference, statusToBadge, statusToBadgeColor, } from '../frontend/src/lib/file-tree-utils.js';
4
+ describe('buildChangedFilesTree', () => {
5
+ test('returns empty array for no files', () => {
6
+ assert.deepStrictEqual(buildChangedFilesTree([]), []);
7
+ });
8
+ test('builds tree from flat file list', () => {
9
+ const files = [
10
+ {
11
+ path: 'src/index.ts',
12
+ status: 'modified',
13
+ additions: 5,
14
+ deletions: 2,
15
+ directory: 'src',
16
+ },
17
+ {
18
+ path: 'src/utils.ts',
19
+ status: 'added',
20
+ additions: 10,
21
+ deletions: 0,
22
+ directory: 'src',
23
+ },
24
+ ];
25
+ const tree = buildChangedFilesTree(files);
26
+ assert.equal(tree.length, 1); // single "src" directory
27
+ assert.equal(tree[0].name, 'src');
28
+ assert.equal(tree[0].isDirectory, true);
29
+ assert.equal(tree[0].children.length, 2);
30
+ assert.equal(tree[0].fileCount, 2);
31
+ assert.equal(tree[0].additions, 15);
32
+ assert.equal(tree[0].deletions, 2);
33
+ });
34
+ test('collapses single-child directories', () => {
35
+ const files = [
36
+ {
37
+ path: 'a/b/c/file.ts',
38
+ status: 'modified',
39
+ additions: 1,
40
+ deletions: 0,
41
+ directory: 'a/b/c',
42
+ },
43
+ ];
44
+ const tree = buildChangedFilesTree(files);
45
+ // a/b/c should collapse into one node "a/b/c"
46
+ assert.equal(tree.length, 1);
47
+ assert.ok(tree[0].name.includes('a'));
48
+ assert.ok(tree[0].name.includes('c'));
49
+ });
50
+ test('sorts directories before files', () => {
51
+ const files = [
52
+ {
53
+ path: 'z-file.ts',
54
+ status: 'modified',
55
+ additions: 1,
56
+ deletions: 0,
57
+ directory: '',
58
+ },
59
+ {
60
+ path: 'a-dir/inner.ts',
61
+ status: 'added',
62
+ additions: 1,
63
+ deletions: 0,
64
+ directory: 'a-dir',
65
+ },
66
+ ];
67
+ const tree = buildChangedFilesTree(files);
68
+ assert.equal(tree[0].isDirectory, true);
69
+ assert.equal(tree[1].isDirectory, false);
70
+ });
71
+ test('aggregates stats to parent directories', () => {
72
+ const files = [
73
+ {
74
+ path: 'src/a.ts',
75
+ status: 'modified',
76
+ additions: 3,
77
+ deletions: 1,
78
+ directory: 'src',
79
+ },
80
+ {
81
+ path: 'src/b.ts',
82
+ status: 'added',
83
+ additions: 7,
84
+ deletions: 0,
85
+ directory: 'src',
86
+ },
87
+ ];
88
+ const tree = buildChangedFilesTree(files);
89
+ const srcNode = tree[0];
90
+ assert.equal(srcNode.additions, 10);
91
+ assert.equal(srcNode.deletions, 1);
92
+ assert.equal(srcNode.fileCount, 2);
93
+ });
94
+ });
95
+ describe('flattenVisibleNodes', () => {
96
+ test('returns empty for empty tree', () => {
97
+ assert.deepStrictEqual(flattenVisibleNodes([]), []);
98
+ });
99
+ test('flattens expanded directories', () => {
100
+ const files = [
101
+ {
102
+ path: 'src/index.ts',
103
+ status: 'modified',
104
+ additions: 1,
105
+ deletions: 0,
106
+ directory: 'src',
107
+ },
108
+ ];
109
+ const tree = buildChangedFilesTree(files);
110
+ const flat = flattenVisibleNodes(tree);
111
+ assert.equal(flat.length, 2); // src dir + index.ts file
112
+ });
113
+ test('hides children of collapsed directories', () => {
114
+ const files = [
115
+ {
116
+ path: 'src/index.ts',
117
+ status: 'modified',
118
+ additions: 1,
119
+ deletions: 0,
120
+ directory: 'src',
121
+ },
122
+ ];
123
+ const tree = buildChangedFilesTree(files);
124
+ tree[0].expanded = false;
125
+ const flat = flattenVisibleNodes(tree);
126
+ assert.equal(flat.length, 1); // only src dir, child hidden
127
+ });
128
+ });
129
+ describe('findMostRecentlyChanged', () => {
130
+ test('returns new files not in previous set', () => {
131
+ const prev = ['a.ts', 'b.ts'];
132
+ const curr = ['a.ts', 'b.ts', 'c.ts'];
133
+ assert.deepStrictEqual(findMostRecentlyChanged(prev, curr), ['c.ts']);
134
+ });
135
+ test('returns empty when no new files', () => {
136
+ const prev = ['a.ts', 'b.ts'];
137
+ const curr = ['a.ts', 'b.ts'];
138
+ assert.deepStrictEqual(findMostRecentlyChanged(prev, curr), []);
139
+ });
140
+ test('returns all files when previous is empty', () => {
141
+ const result = findMostRecentlyChanged([], ['a.ts', 'b.ts']);
142
+ assert.deepStrictEqual(result, ['a.ts', 'b.ts']);
143
+ });
144
+ });
145
+ describe('parseLineReference', () => {
146
+ test('formats as backtick-wrapped filepath:linenum', () => {
147
+ assert.equal(parseLineReference('src/index.ts', 42), '`src/index.ts:42`');
148
+ });
149
+ });
150
+ describe('statusToBadge', () => {
151
+ test('maps all statuses to single characters', () => {
152
+ assert.equal(statusToBadge('added'), 'A');
153
+ assert.equal(statusToBadge('modified'), 'M');
154
+ assert.equal(statusToBadge('deleted'), 'D');
155
+ assert.equal(statusToBadge('renamed'), 'R');
156
+ assert.equal(statusToBadge('untracked'), '?');
157
+ });
158
+ });
159
+ describe('statusToBadgeColor', () => {
160
+ test('maps all statuses to CSS variables', () => {
161
+ assert.equal(statusToBadgeColor('added'), 'var(--status-success)');
162
+ assert.equal(statusToBadgeColor('modified'), 'var(--status-warning)');
163
+ assert.equal(statusToBadgeColor('deleted'), 'var(--status-error)');
164
+ assert.equal(statusToBadgeColor('renamed'), 'var(--status-info)');
165
+ assert.equal(statusToBadgeColor('untracked'), 'var(--text-muted)');
166
+ });
167
+ });
@@ -0,0 +1,183 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { BUILTIN_FRAMEWORKS, AGENT_COMMANDS, AGENT_CONTINUE_ARGS, AGENT_YOLO_ARGS, resolveFramework, } from '../server/types.js';
4
+ // ── BUILTIN_FRAMEWORKS structure ──
5
+ test('BUILTIN_FRAMEWORKS contains claude, codex, and opencode', () => {
6
+ assert.ok('claude' in BUILTIN_FRAMEWORKS);
7
+ assert.ok('codex' in BUILTIN_FRAMEWORKS);
8
+ assert.ok('opencode' in BUILTIN_FRAMEWORKS);
9
+ });
10
+ test('claude framework has correct values', () => {
11
+ const claude = BUILTIN_FRAMEWORKS['claude'];
12
+ assert.equal(claude.id, 'claude');
13
+ assert.equal(claude.displayName, 'Claude Code');
14
+ assert.equal(claude.command, 'claude');
15
+ assert.deepEqual(claude.continueArgs, ['--continue']);
16
+ assert.deepEqual(claude.yoloArgs, ['--dangerously-skip-permissions']);
17
+ assert.equal(claude.parserType, 'claude');
18
+ assert.equal(claude.eventSource, 'hooks');
19
+ assert.equal(claude.capabilities.supportsHooks, true);
20
+ assert.equal(claude.capabilities.supportsContinue, true);
21
+ assert.equal(claude.capabilities.supportsYolo, true);
22
+ assert.equal(claude.capabilities.supportsTelemetry, true);
23
+ });
24
+ test('codex framework has correct values', () => {
25
+ const codex = BUILTIN_FRAMEWORKS['codex'];
26
+ assert.equal(codex.id, 'codex');
27
+ assert.equal(codex.displayName, 'Codex');
28
+ assert.equal(codex.command, 'codex');
29
+ assert.deepEqual(codex.continueArgs, ['resume', '--last']);
30
+ assert.deepEqual(codex.yoloArgs, [
31
+ '--ask-for-approval',
32
+ 'never',
33
+ '--sandbox',
34
+ 'workspace-write',
35
+ ]);
36
+ assert.equal(codex.parserType, 'codex');
37
+ assert.equal(codex.eventSource, 'hooks');
38
+ assert.equal(codex.capabilities.supportsHooks, true);
39
+ assert.equal(codex.capabilities.supportsContinue, true);
40
+ assert.equal(codex.capabilities.supportsYolo, true);
41
+ assert.equal(codex.capabilities.supportsTelemetry, false);
42
+ });
43
+ test('opencode framework has correct values', () => {
44
+ const opencode = BUILTIN_FRAMEWORKS['opencode'];
45
+ assert.equal(opencode.id, 'opencode');
46
+ assert.equal(opencode.displayName, 'OpenCode');
47
+ assert.equal(opencode.command, 'opencode');
48
+ assert.deepEqual(opencode.continueArgs, ['--continue']);
49
+ assert.deepEqual(opencode.yoloArgs, []);
50
+ assert.equal(opencode.parserType, 'opencode');
51
+ assert.equal(opencode.eventSource, 'plugin');
52
+ assert.equal(opencode.capabilities.supportsHooks, false);
53
+ assert.equal(opencode.capabilities.supportsContinue, true);
54
+ assert.equal(opencode.capabilities.supportsYolo, true);
55
+ assert.equal(opencode.capabilities.supportsTelemetry, true);
56
+ });
57
+ test('opencode yoloEnv contains OPENCODE_CONFIG_CONTENT with permission JSON', () => {
58
+ const opencode = BUILTIN_FRAMEWORKS['opencode'];
59
+ assert.ok(opencode.yoloEnv, 'yoloEnv should be defined');
60
+ assert.ok('OPENCODE_CONFIG_CONTENT' in opencode.yoloEnv);
61
+ const parsed = JSON.parse(opencode.yoloEnv['OPENCODE_CONFIG_CONTENT']);
62
+ assert.ok(parsed.permission, 'permission key should exist');
63
+ assert.equal(parsed.permission.read, 'allow');
64
+ assert.equal(parsed.permission.edit, 'allow');
65
+ assert.equal(parsed.permission.bash, 'allow');
66
+ });
67
+ // ── resolveFramework ──
68
+ test('resolveFramework returns builtin framework unmodified when no config override', () => {
69
+ const result = resolveFramework({}, 'claude');
70
+ assert.deepEqual(result, BUILTIN_FRAMEWORKS['claude']);
71
+ });
72
+ test('resolveFramework returns builtin codex when no config override', () => {
73
+ const result = resolveFramework({}, 'codex');
74
+ assert.deepEqual(result, BUILTIN_FRAMEWORKS['codex']);
75
+ });
76
+ test('resolveFramework applies top-level overrides from config.frameworks', () => {
77
+ const result = resolveFramework({
78
+ frameworks: {
79
+ claude: {
80
+ commandOverride: '/usr/local/bin/claude',
81
+ displayName: 'My Claude',
82
+ },
83
+ },
84
+ }, 'claude');
85
+ assert.equal(result.commandOverride, '/usr/local/bin/claude');
86
+ assert.equal(result.displayName, 'My Claude');
87
+ // non-overridden fields remain unchanged
88
+ assert.equal(result.command, 'claude');
89
+ assert.deepEqual(result.continueArgs, ['--continue']);
90
+ });
91
+ test('resolveFramework deep merges capabilities from config.frameworks', () => {
92
+ const result = resolveFramework({
93
+ frameworks: {
94
+ claude: {
95
+ capabilities: {
96
+ supportsHooks: false,
97
+ },
98
+ },
99
+ },
100
+ }, 'claude');
101
+ assert.equal(result.capabilities.supportsHooks, false);
102
+ // other capabilities should remain from builtin
103
+ assert.equal(result.capabilities.supportsContinue, true);
104
+ assert.equal(result.capabilities.supportsYolo, true);
105
+ assert.equal(result.capabilities.supportsTelemetry, true);
106
+ });
107
+ test('resolveFramework supports fully custom framework from config.frameworks', () => {
108
+ const customFramework = {
109
+ id: 'myagent',
110
+ displayName: 'My Agent',
111
+ command: 'myagent',
112
+ continueArgs: ['--resume'],
113
+ yoloArgs: [],
114
+ parserType: 'myagent',
115
+ eventSource: 'parser',
116
+ capabilities: {
117
+ supportsHooks: false,
118
+ supportsContinue: true,
119
+ supportsYolo: false,
120
+ supportsTelemetry: false,
121
+ },
122
+ };
123
+ const result = resolveFramework({ frameworks: { myagent: customFramework } }, 'myagent');
124
+ assert.equal(result.id, 'myagent');
125
+ assert.equal(result.displayName, 'My Agent');
126
+ assert.equal(result.command, 'myagent');
127
+ });
128
+ test('resolveFramework throws for unknown framework not in config', () => {
129
+ assert.throws(() => resolveFramework({}, 'nonexistent'), /unknown.*framework|framework.*unknown|nonexistent/i);
130
+ });
131
+ test('resolveFramework throws for unknown framework not in config.frameworks', () => {
132
+ assert.throws(() => resolveFramework({ frameworks: { other: { id: 'other' } } }, 'nonexistent'), /unknown.*framework|framework.*unknown|nonexistent/i);
133
+ });
134
+ test('resolveFramework throws for custom framework missing required fields', () => {
135
+ assert.throws(() => resolveFramework({ frameworks: { bad: { id: 'bad' } } }, 'bad'), /must define.*command|must define.*continueArgs|must define.*capabilities/i);
136
+ });
137
+ // ── Backward-compat aliases ──
138
+ test('AGENT_COMMANDS is derived from BUILTIN_FRAMEWORKS', () => {
139
+ assert.equal(AGENT_COMMANDS['claude'], BUILTIN_FRAMEWORKS['claude'].command);
140
+ assert.equal(AGENT_COMMANDS['codex'], BUILTIN_FRAMEWORKS['codex'].command);
141
+ assert.equal(AGENT_COMMANDS['opencode'], BUILTIN_FRAMEWORKS['opencode'].command);
142
+ });
143
+ test('AGENT_CONTINUE_ARGS is derived from BUILTIN_FRAMEWORKS', () => {
144
+ assert.deepEqual(AGENT_CONTINUE_ARGS['claude'], BUILTIN_FRAMEWORKS['claude'].continueArgs);
145
+ assert.deepEqual(AGENT_CONTINUE_ARGS['codex'], BUILTIN_FRAMEWORKS['codex'].continueArgs);
146
+ assert.deepEqual(AGENT_CONTINUE_ARGS['opencode'], BUILTIN_FRAMEWORKS['opencode'].continueArgs);
147
+ });
148
+ test('AGENT_YOLO_ARGS is derived from BUILTIN_FRAMEWORKS', () => {
149
+ assert.deepEqual(AGENT_YOLO_ARGS['claude'], BUILTIN_FRAMEWORKS['claude'].yoloArgs);
150
+ assert.deepEqual(AGENT_YOLO_ARGS['codex'], BUILTIN_FRAMEWORKS['codex'].yoloArgs);
151
+ assert.deepEqual(AGENT_YOLO_ARGS['opencode'], BUILTIN_FRAMEWORKS['opencode'].yoloArgs);
152
+ });
153
+ test('AGENT_COMMANDS still has claude and codex for backward compat', () => {
154
+ assert.equal(AGENT_COMMANDS['claude'], 'claude');
155
+ assert.equal(AGENT_COMMANDS['codex'], 'codex');
156
+ });
157
+ test('AGENT_CONTINUE_ARGS still has claude and codex for backward compat', () => {
158
+ assert.deepEqual(AGENT_CONTINUE_ARGS['claude'], ['--continue']);
159
+ assert.deepEqual(AGENT_CONTINUE_ARGS['codex'], ['resume', '--last']);
160
+ });
161
+ test('AGENT_YOLO_ARGS still has claude and codex for backward compat', () => {
162
+ assert.deepEqual(AGENT_YOLO_ARGS['claude'], [
163
+ '--dangerously-skip-permissions',
164
+ ]);
165
+ assert.deepEqual(AGENT_YOLO_ARGS['codex'], [
166
+ '--ask-for-approval',
167
+ 'never',
168
+ '--sandbox',
169
+ 'workspace-write',
170
+ ]);
171
+ });
172
+ // ── EventSourceType type check ──
173
+ test('EventSourceType values are used correctly in BUILTIN_FRAMEWORKS', () => {
174
+ const validSources = [
175
+ 'hooks',
176
+ 'plugin',
177
+ 'parser',
178
+ 'timer',
179
+ ];
180
+ for (const fw of Object.values(BUILTIN_FRAMEWORKS)) {
181
+ assert.ok(validSources.includes(fw.eventSource), `${fw.id} eventSource should be valid`);
182
+ }
183
+ });