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,60 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildBrainstormPrompt, buildPlanPrompt, buildExecutionPrompt, buildReviewPrompt, buildStuckPrompt } from '../server/belayer/prompts.js';
4
+ const testTask = {
5
+ source: 'text',
6
+ title: 'Add CSV export',
7
+ description: 'Users should be able to export data as CSV files',
8
+ acceptanceCriteria: ['Export button visible', 'CSV downloads correctly'],
9
+ };
10
+ test('buildBrainstormPrompt includes task title and description', () => {
11
+ const prompt = buildBrainstormPrompt(testTask);
12
+ assert.ok(prompt.includes('Add CSV export'));
13
+ assert.ok(prompt.includes('export data as CSV files'));
14
+ });
15
+ test('buildBrainstormPrompt includes acceptance criteria when present', () => {
16
+ const prompt = buildBrainstormPrompt(testTask);
17
+ assert.ok(prompt.includes('Export button visible'));
18
+ assert.ok(prompt.includes('CSV downloads correctly'));
19
+ });
20
+ test('buildPlanPrompt includes PRD content', () => {
21
+ const prompt = buildPlanPrompt(testTask, '# PRD\n## Goals\nExport CSV');
22
+ assert.ok(prompt.includes('# PRD'));
23
+ assert.ok(prompt.includes('Export CSV'));
24
+ });
25
+ test('buildExecutionPrompt includes plan content', () => {
26
+ const prompt = buildExecutionPrompt(testTask, '# Plan\n## Task 1\nCreate export button');
27
+ assert.ok(prompt.includes('# Plan'));
28
+ assert.ok(prompt.includes('Create export button'));
29
+ });
30
+ test('buildExecutionPrompt includes verdict feedback on retry', () => {
31
+ const verdict = {
32
+ goalName: 'CSV Export',
33
+ pass: false,
34
+ criteriaResults: [{ criterion: 'Export works', met: false, reason: 'Button missing' }],
35
+ summary: 'Export button not found',
36
+ timestamp: new Date().toISOString(),
37
+ };
38
+ const prompt = buildExecutionPrompt(testTask, '# Plan', [verdict]);
39
+ assert.ok(prompt.includes('PREVIOUS REVIEW FEEDBACK'));
40
+ assert.ok(prompt.includes('Button missing'));
41
+ });
42
+ test('buildReviewPrompt includes task spec and acceptance criteria', () => {
43
+ const prompt = buildReviewPrompt(testTask, '/tmp/worktree');
44
+ assert.ok(prompt.includes('Add CSV export'));
45
+ assert.ok(prompt.includes('Export button visible'));
46
+ });
47
+ test('buildReviewPrompt instructs verdict.json output', () => {
48
+ const prompt = buildReviewPrompt(testTask, '/tmp/worktree');
49
+ assert.ok(prompt.includes('verdict.json'));
50
+ });
51
+ test('buildStuckPrompt includes attempt count and verdicts', () => {
52
+ const verdicts = [
53
+ { goalName: 'test', pass: false, criteriaResults: [], summary: 'Failed attempt 1', timestamp: '' },
54
+ { goalName: 'test', pass: false, criteriaResults: [], summary: 'Failed attempt 2', timestamp: '' },
55
+ ];
56
+ const prompt = buildStuckPrompt(testTask, verdicts, 2);
57
+ assert.ok(prompt.includes('2'));
58
+ assert.ok(prompt.includes('Failed attempt 1'));
59
+ assert.ok(prompt.includes('Failed attempt 2'));
60
+ });
@@ -0,0 +1,69 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { DEFAULT_PIPELINE_CONFIG, VALID_TRANSITIONS } from '../server/belayer/types.js';
4
+ test('DEFAULT_PIPELINE_CONFIG has expected defaults', () => {
5
+ assert.deepEqual(DEFAULT_PIPELINE_CONFIG.models, { brainstorm: 'opus', execute: 'opus', review: 'sonnet' });
6
+ assert.equal(DEFAULT_PIPELINE_CONFIG.maxAttempts, 3);
7
+ assert.equal(DEFAULT_PIPELINE_CONFIG.autoPush, true);
8
+ assert.equal(DEFAULT_PIPELINE_CONFIG.targetRepo, '');
9
+ assert.equal(DEFAULT_PIPELINE_CONFIG.baseBranch, 'main');
10
+ });
11
+ test('VALID_TRANSITIONS covers all states', () => {
12
+ const allStates = [
13
+ 'intake', 'brainstorming', 'prd_review', 'planning', 'plan_review',
14
+ 'executing', 'reviewing', 'retry', 'stuck', 'pr_created',
15
+ 'ci_monitoring', 'ready_for_review', 'done', 'failed',
16
+ ];
17
+ for (const state of allStates) {
18
+ assert.ok(state in VALID_TRANSITIONS, `Missing transitions for state: ${state}`);
19
+ }
20
+ });
21
+ test('done state has no valid transitions', () => {
22
+ assert.deepEqual(VALID_TRANSITIONS.done, []);
23
+ });
24
+ test('all active states can transition to failed', () => {
25
+ const allStates = Object.keys(VALID_TRANSITIONS);
26
+ for (const state of allStates) {
27
+ if (state === 'done' || state === 'failed')
28
+ continue;
29
+ assert.ok(VALID_TRANSITIONS[state].includes('failed'), `State ${state} should be able to transition to failed`);
30
+ }
31
+ });
32
+ test('failed can only transition to intake (restart)', () => {
33
+ assert.deepEqual(VALID_TRANSITIONS.failed, ['intake']);
34
+ });
35
+ test('TaskSpec type accepts text source', () => {
36
+ const spec = {
37
+ source: 'text',
38
+ title: 'Test task',
39
+ description: 'A test description',
40
+ };
41
+ assert.equal(spec.source, 'text');
42
+ assert.equal(spec.title, 'Test task');
43
+ });
44
+ test('Pipeline type has correct shape', () => {
45
+ const pipeline = {
46
+ id: 'test-id',
47
+ state: 'intake',
48
+ task: { source: 'text', title: 'Test', description: 'Desc' },
49
+ config: DEFAULT_PIPELINE_CONFIG,
50
+ createdAt: new Date().toISOString(),
51
+ updatedAt: new Date().toISOString(),
52
+ attempts: 0,
53
+ maxAttempts: 3,
54
+ verdicts: [],
55
+ };
56
+ assert.equal(pipeline.state, 'intake');
57
+ assert.equal(pipeline.attempts, 0);
58
+ });
59
+ test('Verdict type has correct shape', () => {
60
+ const verdict = {
61
+ goalName: 'Feature X',
62
+ pass: true,
63
+ criteriaResults: [{ criterion: 'Tests pass', met: true }],
64
+ summary: 'All good',
65
+ timestamp: new Date().toISOString(),
66
+ };
67
+ assert.equal(verdict.pass, true);
68
+ assert.equal(verdict.criteriaResults.length, 1);
69
+ });
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import { execFile, spawn } from 'node:child_process';
5
+ import { promisify } from 'node:util';
6
+ import { fileURLToPath } from 'node:url';
7
+ import * as service from '../server/service.js';
8
+ import { DEFAULTS } from '../server/config.js';
9
+ const execFileAsync = promisify(execFile);
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ function execErrorMessage(err, fallback) {
12
+ const e = err;
13
+ return (e.stderr || e.message || fallback).trimEnd();
14
+ }
15
+ // Parse CLI flags
16
+ const args = process.argv.slice(2);
17
+ if (args.includes('--help') || args.includes('-h')) {
18
+ console.log(`Usage: claude-remote-cli [options]
19
+ claude-remote-cli <command>
20
+
21
+ Commands:
22
+ update Update to the latest version from npm
23
+ install Install as a background service (survives reboot)
24
+ uninstall Stop and remove the background service
25
+ status Show whether the service is running
26
+ worktree Manage git worktrees (wraps git worktree)
27
+ add [path] [-b branch] [--yolo] Create worktree and launch Claude
28
+ remove <path> Forward to git worktree remove
29
+ list Forward to git worktree list
30
+
31
+ Options:
32
+ --bg Shortcut: install and start as background service
33
+ --port <port> Override server port (default: 3456)
34
+ --host <host> Override bind address (default: 0.0.0.0)
35
+ --config <path> Path to config.json (default: ~/.config/claude-remote-cli/config.json)
36
+ --debug-log Enable SDK event debug logging to ~/.config/claude-remote-cli/debug/
37
+ --yolo With 'worktree add': pass --dangerously-skip-permissions to Claude
38
+ --version, -v Show version
39
+ --help, -h Show this help`);
40
+ process.exit(0);
41
+ }
42
+ if (args.includes('--version') || args.includes('-v')) {
43
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
44
+ console.log(pkg.version);
45
+ process.exit(0);
46
+ }
47
+ function getArg(flag) {
48
+ const idx = args.indexOf(flag);
49
+ if (idx === -1 || idx + 1 >= args.length)
50
+ return undefined;
51
+ return args[idx + 1];
52
+ }
53
+ function resolveConfigPath() {
54
+ const explicit = getArg('--config');
55
+ if (explicit)
56
+ return explicit;
57
+ return path.join(service.CONFIG_DIR, 'config.json');
58
+ }
59
+ function runServiceCommand(fn) {
60
+ try {
61
+ fn();
62
+ }
63
+ catch (e) {
64
+ console.error(e.message);
65
+ process.exit(1);
66
+ }
67
+ process.exit(0);
68
+ }
69
+ const command = args[0];
70
+ if (command === 'update') {
71
+ try {
72
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
73
+ console.log(`Current version: ${pkg.version}`);
74
+ console.log('Updating claude-remote-cli...');
75
+ await execFileAsync('npm', ['install', '-g', 'claude-remote-cli@latest']);
76
+ const updatedPkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
77
+ if (updatedPkg.version === pkg.version) {
78
+ console.log(`Already on the latest version (${pkg.version}).`);
79
+ }
80
+ else {
81
+ console.log(`Updated to ${updatedPkg.version}.`);
82
+ if (service.isInstalled()) {
83
+ console.log('Background service detected — restarting...');
84
+ service.uninstall();
85
+ service.install({
86
+ configPath: resolveConfigPath(),
87
+ port: getArg('--port') ?? String(DEFAULTS.port),
88
+ host: getArg('--host') ?? DEFAULTS.host,
89
+ });
90
+ console.log('Service restarted.');
91
+ }
92
+ }
93
+ }
94
+ catch (e) {
95
+ console.error('Update failed:', e.message);
96
+ process.exit(1);
97
+ }
98
+ process.exit(0);
99
+ }
100
+ if (command === 'worktree') {
101
+ const wtArgs = args.slice(1);
102
+ const subCommand = wtArgs[0];
103
+ if (!subCommand) {
104
+ console.error('Usage: claude-remote-cli worktree <add|remove|list> [options]');
105
+ process.exit(1);
106
+ }
107
+ if (subCommand !== 'add') {
108
+ try {
109
+ const result = await execFileAsync('git', ['worktree', ...wtArgs]);
110
+ if (result.stdout)
111
+ console.log(result.stdout.trimEnd());
112
+ }
113
+ catch (err) {
114
+ console.error(execErrorMessage(err, 'git worktree failed'));
115
+ process.exit(1);
116
+ }
117
+ process.exit(0);
118
+ }
119
+ // Handle 'add' -- strip --yolo, determine path, forward to git, then launch claude
120
+ const hasYolo = wtArgs.includes('--yolo');
121
+ const gitWtArgs = wtArgs.filter(function (a) { return a !== '--yolo'; });
122
+ const addSubArgs = gitWtArgs.slice(1);
123
+ let targetDir;
124
+ const bIdx = gitWtArgs.indexOf('-b');
125
+ const branchForDefault = bIdx !== -1 && bIdx + 1 < gitWtArgs.length ? gitWtArgs[bIdx + 1] : undefined;
126
+ if (addSubArgs.length === 0 || addSubArgs[0].startsWith('-')) {
127
+ let repoRoot;
128
+ try {
129
+ const result = await execFileAsync('git', ['rev-parse', '--show-toplevel']);
130
+ repoRoot = result.stdout.trim();
131
+ }
132
+ catch {
133
+ console.error('Not inside a git repository.');
134
+ process.exit(1);
135
+ }
136
+ const dirName = branchForDefault
137
+ ? branchForDefault.replace(/\//g, '-')
138
+ : 'worktree-' + Date.now().toString(36);
139
+ targetDir = path.join(repoRoot, '.worktrees', dirName);
140
+ gitWtArgs.splice(1, 0, targetDir);
141
+ }
142
+ else {
143
+ targetDir = path.resolve(addSubArgs[0]);
144
+ }
145
+ try {
146
+ const result = await execFileAsync('git', ['worktree', ...gitWtArgs]);
147
+ if (result.stdout)
148
+ console.log(result.stdout.trimEnd());
149
+ }
150
+ catch (err) {
151
+ console.error(execErrorMessage(err, 'git worktree add failed'));
152
+ process.exit(1);
153
+ }
154
+ console.log(`Worktree created at ${targetDir}`);
155
+ const claudeArgs = [];
156
+ if (hasYolo)
157
+ claudeArgs.push('--dangerously-skip-permissions');
158
+ console.log(`Launching claude${hasYolo ? ' (yolo mode)' : ''} in ${targetDir}...`);
159
+ const child = spawn('claude', claudeArgs, {
160
+ cwd: targetDir,
161
+ stdio: 'inherit',
162
+ env: { ...process.env, CLAUDECODE: undefined },
163
+ });
164
+ child.on('exit', (code) => {
165
+ process.exit(code ?? 0);
166
+ });
167
+ // Block until child exits via the handler above
168
+ await new Promise(() => { });
169
+ }
170
+ if (command === 'install' || command === 'uninstall' || command === 'status' || args.includes('--bg')) {
171
+ if (command === 'uninstall') {
172
+ runServiceCommand(() => { service.uninstall(); });
173
+ }
174
+ else if (command === 'status') {
175
+ runServiceCommand(() => {
176
+ const st = service.status();
177
+ if (!st.installed) {
178
+ console.log('Service is not installed.');
179
+ }
180
+ else if (st.running) {
181
+ console.log('Service is installed and running.');
182
+ }
183
+ else {
184
+ console.log('Service is installed but not running.');
185
+ }
186
+ });
187
+ }
188
+ else {
189
+ runServiceCommand(() => {
190
+ service.install({
191
+ configPath: resolveConfigPath(),
192
+ port: getArg('--port') ?? String(DEFAULTS.port),
193
+ host: getArg('--host') ?? DEFAULTS.host,
194
+ });
195
+ });
196
+ }
197
+ }
198
+ const configPath = resolveConfigPath();
199
+ const configDir = path.dirname(configPath);
200
+ // Ensure config directory exists
201
+ if (!fs.existsSync(configDir)) {
202
+ fs.mkdirSync(configDir, { recursive: true });
203
+ }
204
+ // Pass config path and CLI overrides to the server
205
+ process.env['CLAUDE_REMOTE_CONFIG'] = configPath;
206
+ const portArg = getArg('--port');
207
+ if (portArg !== undefined)
208
+ process.env['CLAUDE_REMOTE_PORT'] = portArg;
209
+ const hostArg = getArg('--host');
210
+ if (hostArg !== undefined)
211
+ process.env['CLAUDE_REMOTE_HOST'] = hostArg;
212
+ if (args.includes('--debug-log'))
213
+ process.env['CLAUDE_REMOTE_DEBUG_LOG'] = '1';
214
+ await import('../server/index.js');
@@ -0,0 +1,133 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ const SERVICES = [
4
+ 'auth',
5
+ 'workspaces',
6
+ 'sessions',
7
+ 'worktrees',
8
+ 'groups',
9
+ ];
10
+ function createBootLines() {
11
+ return SERVICES.map((service) => ({
12
+ service,
13
+ status: 'pending',
14
+ }));
15
+ }
16
+ function derivePhaseAfterFinish(lines) {
17
+ const fetchLines = lines.filter((l) => l.service !== 'auth');
18
+ const anyFailed = fetchLines.some((l) => l.status === 'fail');
19
+ return anyFailed ? 'degraded' : 'ready';
20
+ }
21
+ function reportFetch(lines, service, status, opts) {
22
+ const idx = lines.findIndex((l) => l.service === service);
23
+ if (idx === -1)
24
+ return lines;
25
+ const updated = [...lines];
26
+ updated[idx] = {
27
+ service,
28
+ status,
29
+ summary: opts?.summary,
30
+ durationMs: opts?.durationMs,
31
+ error: opts?.error,
32
+ };
33
+ return updated;
34
+ }
35
+ describe('boot-state', () => {
36
+ describe('createBootLines', () => {
37
+ it('creates 5 lines for all services', () => {
38
+ const lines = createBootLines();
39
+ assert.strictEqual(lines.length, 5);
40
+ assert.deepStrictEqual(lines.map((l) => l.service), ['auth', 'workspaces', 'sessions', 'worktrees', 'groups']);
41
+ });
42
+ it('all lines start as pending', () => {
43
+ const lines = createBootLines();
44
+ for (const line of lines) {
45
+ assert.strictEqual(line.status, 'pending');
46
+ }
47
+ });
48
+ });
49
+ describe('reportFetch', () => {
50
+ it('updates a known service to loading', () => {
51
+ let lines = createBootLines();
52
+ lines = reportFetch(lines, 'workspaces', 'loading');
53
+ const ws = lines.find((l) => l.service === 'workspaces');
54
+ assert.strictEqual(ws.status, 'loading');
55
+ });
56
+ it('updates a service to ok with summary and duration', () => {
57
+ let lines = createBootLines();
58
+ lines = reportFetch(lines, 'sessions', 'ok', {
59
+ summary: '2 active',
60
+ durationMs: 42,
61
+ });
62
+ const sess = lines.find((l) => l.service === 'sessions');
63
+ assert.strictEqual(sess.status, 'ok');
64
+ assert.strictEqual(sess.summary, '2 active');
65
+ assert.strictEqual(sess.durationMs, 42);
66
+ });
67
+ it('updates a service to fail with error', () => {
68
+ let lines = createBootLines();
69
+ lines = reportFetch(lines, 'worktrees', 'fail', {
70
+ error: 'timeout',
71
+ durationMs: 5000,
72
+ });
73
+ const wt = lines.find((l) => l.service === 'worktrees');
74
+ assert.strictEqual(wt.status, 'fail');
75
+ assert.strictEqual(wt.error, 'timeout');
76
+ assert.strictEqual(wt.durationMs, 5000);
77
+ });
78
+ it('ignores unknown service', () => {
79
+ let lines = createBootLines();
80
+ const original = [...lines];
81
+ lines = reportFetch(lines, 'unknown-service', 'ok');
82
+ assert.deepStrictEqual(lines, original);
83
+ });
84
+ it('does not affect other lines', () => {
85
+ let lines = createBootLines();
86
+ lines = reportFetch(lines, 'auth', 'ok', { durationMs: 10 });
87
+ // All other lines should still be pending
88
+ for (const line of lines) {
89
+ if (line.service !== 'auth') {
90
+ assert.strictEqual(line.status, 'pending', `${line.service} should still be pending`);
91
+ }
92
+ }
93
+ });
94
+ });
95
+ describe('derivePhaseAfterFinish', () => {
96
+ it('returns ready when all non-auth lines are ok', () => {
97
+ let lines = createBootLines();
98
+ lines = reportFetch(lines, 'auth', 'ok');
99
+ lines = reportFetch(lines, 'workspaces', 'ok', { summary: '3 repos' });
100
+ lines = reportFetch(lines, 'sessions', 'ok', { summary: '2 active' });
101
+ lines = reportFetch(lines, 'worktrees', 'ok', { summary: '1 tree' });
102
+ lines = reportFetch(lines, 'groups', 'ok', { summary: '0 groups' });
103
+ assert.strictEqual(derivePhaseAfterFinish(lines), 'ready');
104
+ });
105
+ it('returns degraded when one fetch fails', () => {
106
+ let lines = createBootLines();
107
+ lines = reportFetch(lines, 'auth', 'ok');
108
+ lines = reportFetch(lines, 'workspaces', 'ok', { summary: '3 repos' });
109
+ lines = reportFetch(lines, 'sessions', 'fail', { error: 'timeout' });
110
+ lines = reportFetch(lines, 'worktrees', 'ok', { summary: '1 tree' });
111
+ lines = reportFetch(lines, 'groups', 'ok', { summary: '0 groups' });
112
+ assert.strictEqual(derivePhaseAfterFinish(lines), 'degraded');
113
+ });
114
+ it('returns degraded when all fetches fail', () => {
115
+ let lines = createBootLines();
116
+ lines = reportFetch(lines, 'auth', 'ok');
117
+ lines = reportFetch(lines, 'workspaces', 'fail', { error: 'network' });
118
+ lines = reportFetch(lines, 'sessions', 'fail', { error: 'network' });
119
+ lines = reportFetch(lines, 'worktrees', 'fail', { error: 'network' });
120
+ lines = reportFetch(lines, 'groups', 'fail', { error: 'network' });
121
+ assert.strictEqual(derivePhaseAfterFinish(lines), 'degraded');
122
+ });
123
+ it('ignores auth status when deriving phase', () => {
124
+ let lines = createBootLines();
125
+ lines = reportFetch(lines, 'auth', 'fail'); // auth failed but non-auth are ok
126
+ lines = reportFetch(lines, 'workspaces', 'ok', { summary: '3 repos' });
127
+ lines = reportFetch(lines, 'sessions', 'ok', { summary: '0 active' });
128
+ lines = reportFetch(lines, 'worktrees', 'ok', { summary: '0 trees' });
129
+ lines = reportFetch(lines, 'groups', 'ok', { summary: '0 groups' });
130
+ assert.strictEqual(derivePhaseAfterFinish(lines), 'ready');
131
+ });
132
+ });
133
+ });
@@ -0,0 +1,75 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { isPrMerged, computeBranchLifecycleState } from '../server/git.js';
4
+ describe('isPrMerged', () => {
5
+ it('returns true for MERGED state', () => {
6
+ const pr = { state: 'MERGED' };
7
+ assert.equal(isPrMerged(pr), true);
8
+ });
9
+ it('returns false for OPEN state', () => {
10
+ const pr = { state: 'OPEN' };
11
+ assert.equal(isPrMerged(pr), false);
12
+ });
13
+ it('returns false for CLOSED (not merged) state', () => {
14
+ const pr = { state: 'CLOSED' };
15
+ assert.equal(isPrMerged(pr), false);
16
+ });
17
+ });
18
+ describe('computeBranchLifecycleState', () => {
19
+ it('returns merged when PR is merged', () => {
20
+ const result = computeBranchLifecycleState({
21
+ pr: { state: 'MERGED', number: 42, title: 'Fix auth' },
22
+ isBranchStale: false,
23
+ hasActiveSessions: true,
24
+ isMainBranch: false,
25
+ });
26
+ assert.equal(result.state, 'merged');
27
+ assert.equal(result.prNumber, 42);
28
+ assert.equal(result.prTitle, 'Fix auth');
29
+ });
30
+ it('returns active when branch has active sessions', () => {
31
+ const result = computeBranchLifecycleState({
32
+ pr: null,
33
+ isBranchStale: true,
34
+ hasActiveSessions: true,
35
+ isMainBranch: false,
36
+ });
37
+ assert.equal(result.state, 'active');
38
+ });
39
+ it('returns stale when no sessions and branch is stale', () => {
40
+ const result = computeBranchLifecycleState({
41
+ pr: null,
42
+ isBranchStale: true,
43
+ hasActiveSessions: false,
44
+ isMainBranch: false,
45
+ });
46
+ assert.equal(result.state, 'stale');
47
+ });
48
+ it('returns active when branch is not stale and no sessions', () => {
49
+ const result = computeBranchLifecycleState({
50
+ pr: null,
51
+ isBranchStale: false,
52
+ hasActiveSessions: false,
53
+ isMainBranch: false,
54
+ });
55
+ assert.equal(result.state, 'active');
56
+ });
57
+ it('never returns merged for main branch even if PR is merged', () => {
58
+ const result = computeBranchLifecycleState({
59
+ pr: { state: 'MERGED', number: 1, title: 'Main PR' },
60
+ isBranchStale: false,
61
+ hasActiveSessions: false,
62
+ isMainBranch: true,
63
+ });
64
+ assert.equal(result.state, 'active');
65
+ });
66
+ it('main branch can be stale but never merged', () => {
67
+ const result = computeBranchLifecycleState({
68
+ pr: null,
69
+ isBranchStale: true,
70
+ hasActiveSessions: false,
71
+ isMainBranch: true,
72
+ });
73
+ assert.equal(result.state, 'stale');
74
+ });
75
+ });