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,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ /** Source code for the opencode relay plugin — written to opencode's plugin directory */
5
+ const RELAY_PLUGIN_SOURCE = `
6
+ // OpenCode plugin that relays lifecycle events to relay-ide server.
7
+ // Reads CRC_RELAY_URL, CRC_SESSION_ID, CRC_RELAY_TOKEN from env (injected per session by PTY handler).
8
+ export default async () => {
9
+ const relayUrl = process.env.CRC_RELAY_URL;
10
+ const sessionId = process.env.CRC_SESSION_ID;
11
+ const token = process.env.CRC_RELAY_TOKEN;
12
+
13
+ if (!relayUrl || !sessionId || !token) return {};
14
+
15
+ const relay = async (eventType, data = {}) => {
16
+ try {
17
+ await fetch(\`\${relayUrl}/hooks/agent-event\`, {
18
+ method: 'POST',
19
+ headers: { 'Content-Type': 'application/json' },
20
+ body: JSON.stringify({ sessionId, token, eventType, data, timestamp: new Date().toISOString() }),
21
+ });
22
+ } catch { /* best-effort, don't crash opencode */ }
23
+ };
24
+
25
+ return {
26
+ 'session.created': async () => relay('session.started'),
27
+ 'session.idle': async () => relay('session.idle'),
28
+ 'session.status': async (input) => relay('state.changed', { status: input }),
29
+ 'session.error': async (input) => relay('state.changed', { status: 'error', error: input }),
30
+ 'permission.asked': async (input) => relay('permission.requested', { permission: input }),
31
+ 'permission.replied': async (input) => relay('permission.resolved', { reply: input }),
32
+ 'tool.execute.before': async (input) => relay('tool.started', { tool: input }),
33
+ 'tool.execute.after': async (input, output) => relay('tool.finished', { tool: input, result: output }),
34
+ 'message.updated': async (input) => relay('telemetry.updated', { message: input }),
35
+ };
36
+ };
37
+ `.trim();
38
+ /**
39
+ * Write the relay plugin to opencode's global plugin directory.
40
+ * Idempotent — overwrites the same file each time.
41
+ *
42
+ * @param pluginDir - Override the plugin directory (defaults to ~/.config/opencode/plugins). Used in tests.
43
+ * @returns The path to the written plugin file.
44
+ */
45
+ export function installOpencodeRelayPlugin(pluginDir) {
46
+ const dir = pluginDir ?? path.join(os.homedir(), '.config', 'opencode', 'plugins');
47
+ fs.mkdirSync(dir, { recursive: true });
48
+ const pluginPath = path.join(dir, 'crc-relay.ts');
49
+ fs.writeFileSync(pluginPath, RELAY_PLUGIN_SOURCE, 'utf-8');
50
+ return pluginPath;
51
+ }
52
+ /** Exported for testing */
53
+ export { RELAY_PLUGIN_SOURCE };
@@ -0,0 +1,241 @@
1
+ import path from 'node:path';
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { Router } from 'express';
5
+ import { loadConfig } from './config.js';
6
+ import { buildRepoMap } from './git.js';
7
+ import { createLogger } from './logger.js';
8
+ const execFileAsync = promisify(execFile);
9
+ const logger = createLogger('org-dashboard');
10
+ const GH_TIMEOUT_MS = 10_000;
11
+ const CACHE_TTL_MS = 60_000;
12
+ /**
13
+ * Extracts "owner/repo" from a GitHub API repository_url.
14
+ * e.g. "https://api.github.com/repos/owner/repo" → "owner/repo"
15
+ */
16
+ function repoFromApiUrl(repositoryUrl) {
17
+ const match = repositoryUrl.match(/\/repos\/([^/]+\/[^/]+)$/);
18
+ return match ? (match[1] ?? null) : null;
19
+ }
20
+ // Router factory
21
+ /**
22
+ * Creates and returns an Express Router that handles all /org-dashboard routes.
23
+ *
24
+ * Caller is responsible for mounting and applying auth middleware:
25
+ * app.use('/org-dashboard', requireAuth, createOrgDashboardRouter({ configPath }));
26
+ */
27
+ export function createOrgDashboardRouter(deps) {
28
+ const { configPath } = deps;
29
+ const exec = deps.execAsync ?? execFileAsync;
30
+ const router = Router();
31
+ // Server-lifetime cache for GitHub user login
32
+ let cachedUser = null;
33
+ // 60s in-memory cache for search results
34
+ let cache = null;
35
+ function getConfig() {
36
+ return loadConfig(configPath);
37
+ }
38
+ // GET /org-dashboard/prs — list all open PRs involving the current user across all workspaces
39
+ router.get('/prs', async (_req, res) => {
40
+ const config = getConfig();
41
+ const workspacePaths = config.repos ?? [];
42
+ if (workspacePaths.length === 0) {
43
+ const response = {
44
+ prs: [],
45
+ error: 'no_workspaces',
46
+ };
47
+ res.json(response);
48
+ return;
49
+ }
50
+ // Return cached results if still fresh
51
+ const now = Date.now();
52
+ if (cache && now - cache.fetchedAt < CACHE_TTL_MS) {
53
+ const response = { prs: cache.prs };
54
+ res.json(response);
55
+ return;
56
+ }
57
+ // Resolve GitHub user (cached for server lifetime)
58
+ if (!cachedUser) {
59
+ try {
60
+ const { stdout } = await exec('gh', ['api', 'user', '--jq', '.login'], {
61
+ timeout: GH_TIMEOUT_MS,
62
+ });
63
+ cachedUser = stdout.trim();
64
+ }
65
+ catch (err) {
66
+ const errCode = err.code;
67
+ if (errCode === 'ENOENT') {
68
+ const response = {
69
+ prs: [],
70
+ error: 'gh_not_in_path',
71
+ };
72
+ res.json(response);
73
+ return;
74
+ }
75
+ const response = {
76
+ prs: [],
77
+ error: 'gh_not_authenticated',
78
+ };
79
+ res.json(response);
80
+ return;
81
+ }
82
+ }
83
+ const currentUser = cachedUser;
84
+ // Build repo → workspace path map
85
+ const repoMap = await buildRepoMap(workspacePaths, exec);
86
+ // Check for GraphQL path (GitHub App token)
87
+ const githubToken = config.github?.accessToken;
88
+ if (githubToken && deps.fetchGraphQL) {
89
+ try {
90
+ const result = await deps.fetchGraphQL(githubToken, repoMap);
91
+ cachedUser = result.username;
92
+ const prs = result.prs;
93
+ prs.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
94
+ cache = { prs, fetchedAt: now };
95
+ // Fire ticket transitions (same best-effort as below)
96
+ if (deps.checkPrTransitions && deps.getBranchLinks) {
97
+ deps
98
+ .getBranchLinks()
99
+ .then((links) => deps.checkPrTransitions(prs, links))
100
+ .catch(() => { });
101
+ }
102
+ const response = { prs };
103
+ res.json(response);
104
+ return;
105
+ }
106
+ catch (err) {
107
+ logger.warn('[org-dashboard] GraphQL fetch failed, falling back to gh CLI:', err instanceof Error ? err.message : String(err));
108
+ }
109
+ }
110
+ // Single gh search API call
111
+ let searchResponse;
112
+ try {
113
+ const { stdout } = await exec('gh', ['api', 'search/issues?q=is:pr+is:open+involves:@me&per_page=100'], { timeout: GH_TIMEOUT_MS });
114
+ searchResponse = JSON.parse(stdout);
115
+ }
116
+ catch (err) {
117
+ const msg = err instanceof Error ? err.message : String(err);
118
+ const errCode = err.code;
119
+ if (msg.includes('ETIMEDOUT') || msg.includes('timed out')) {
120
+ const response = { prs: [], error: 'gh_timeout' };
121
+ res.json(response);
122
+ return;
123
+ }
124
+ if (errCode === 'ENOENT') {
125
+ const response = {
126
+ prs: [],
127
+ error: 'gh_not_in_path',
128
+ };
129
+ res.json(response);
130
+ return;
131
+ }
132
+ const response = {
133
+ prs: [],
134
+ error: 'gh_not_authenticated',
135
+ };
136
+ res.json(response);
137
+ return;
138
+ }
139
+ const items = searchResponse.items ?? [];
140
+ // Filter to only repos matching workspace paths and map to PullRequest
141
+ const prs = [];
142
+ for (const item of items) {
143
+ // The search API can return non-PR issues — skip them
144
+ if (!item.pull_request)
145
+ continue;
146
+ const ownerRepo = repoFromApiUrl(item.repository_url);
147
+ if (!ownerRepo)
148
+ continue;
149
+ const wsPath = repoMap.get(ownerRepo.toLowerCase());
150
+ if (!wsPath)
151
+ continue;
152
+ // Determine role
153
+ const isAuthor = item.user.login === currentUser;
154
+ const isReviewer = !isAuthor &&
155
+ Array.isArray(item.requested_reviewers) &&
156
+ item.requested_reviewers.some((r) => r.login === currentUser);
157
+ if (!isAuthor && !isReviewer)
158
+ continue;
159
+ const role = isAuthor ? 'author' : 'reviewer';
160
+ const repoName = path.basename(wsPath);
161
+ prs.push({
162
+ number: item.number,
163
+ title: item.title,
164
+ url: item.html_url,
165
+ headRefName: item.pull_request?.head?.ref ?? '',
166
+ baseRefName: item.pull_request?.base?.ref ?? '',
167
+ state: 'OPEN',
168
+ author: item.user.login,
169
+ role,
170
+ updatedAt: item.updated_at,
171
+ additions: 0,
172
+ deletions: 0,
173
+ reviewDecision: null,
174
+ mergeable: null,
175
+ isDraft: false,
176
+ ciStatus: null,
177
+ repoName,
178
+ repoPath: wsPath,
179
+ });
180
+ }
181
+ // Sort by updatedAt descending
182
+ prs.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
183
+ // Update cache
184
+ cache = { prs, fetchedAt: now };
185
+ // Fire ticket transitions check (best-effort, don't block response)
186
+ // Include recently merged PRs for MERGED->ready-for-qa transitions
187
+ if (deps.checkPrTransitions && deps.getBranchLinks) {
188
+ const transitionPrs = [...prs];
189
+ // Fetch recently merged PRs (last 7 days) for transition checks
190
+ try {
191
+ const mergedSince = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
192
+ .toISOString()
193
+ .split('T')[0];
194
+ const { stdout: mergedStdout } = await exec('gh', [
195
+ 'api',
196
+ `search/issues?q=is:pr+is:merged+merged:>=${mergedSince}+involves:@me&per_page=50`,
197
+ ], { timeout: GH_TIMEOUT_MS });
198
+ const mergedResponse = JSON.parse(mergedStdout);
199
+ for (const item of mergedResponse.items ?? []) {
200
+ if (!item.pull_request)
201
+ continue;
202
+ const ownerRepo = repoFromApiUrl(item.repository_url);
203
+ if (!ownerRepo)
204
+ continue;
205
+ const wsPath = repoMap.get(ownerRepo.toLowerCase());
206
+ if (!wsPath)
207
+ continue;
208
+ transitionPrs.push({
209
+ number: item.number,
210
+ title: item.title,
211
+ url: item.html_url,
212
+ headRefName: item.pull_request?.head?.ref ?? '',
213
+ baseRefName: item.pull_request?.base?.ref ?? '',
214
+ state: 'MERGED',
215
+ author: item.user.login,
216
+ role: 'author',
217
+ updatedAt: item.updated_at,
218
+ additions: 0,
219
+ deletions: 0,
220
+ reviewDecision: null,
221
+ mergeable: null,
222
+ isDraft: false,
223
+ ciStatus: null,
224
+ repoName: path.basename(wsPath),
225
+ repoPath: wsPath,
226
+ });
227
+ }
228
+ }
229
+ catch {
230
+ // Merged PR fetch is best-effort — don't block transitions
231
+ }
232
+ deps
233
+ .getBranchLinks()
234
+ .then((links) => deps.checkPrTransitions(transitionPrs, links))
235
+ .catch(() => { });
236
+ }
237
+ const response = { prs };
238
+ res.json(response);
239
+ });
240
+ return router;
241
+ }
@@ -0,0 +1,56 @@
1
+ // Duplicated from utils.ts to preserve output-parsers/ module boundary
2
+ const ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]|\x1b\[\?[0-9;]*[hlm]|\x1b\[[0-9]*[ABCDJKH]/g;
3
+ /**
4
+ * Claude Code output parser.
5
+ *
6
+ * Claude Code uses a React/Ink TUI. This parser detects semantic state
7
+ * transitions by pattern-matching on cleaned terminal output.
8
+ */
9
+ export class ClaudeOutputParser {
10
+ currentState = 'initializing';
11
+ hasSeenFirstPrompt = false;
12
+ onData(chunk, _recentScrollback) {
13
+ const clean = chunk.replace(ANSI_RE, '');
14
+ if (!clean.trim())
15
+ return null;
16
+ const newState = this.classify(clean);
17
+ if (newState && newState !== this.currentState) {
18
+ this.currentState = newState;
19
+ return { state: newState };
20
+ }
21
+ return null;
22
+ }
23
+ reset() {
24
+ this.currentState = 'initializing';
25
+ this.hasSeenFirstPrompt = false;
26
+ }
27
+ get state() {
28
+ return this.currentState;
29
+ }
30
+ classify(clean) {
31
+ // Permission prompt detection (highest priority)
32
+ if (/\bAllow\b/.test(clean) && /\bDeny\b/.test(clean)) {
33
+ return 'permission-prompt';
34
+ }
35
+ // Error detection
36
+ if (/^Error:|^ERROR:|✗\s|error:/m.test(clean)) {
37
+ return 'error';
38
+ }
39
+ // Waiting for input: the ">" prompt on its own line, or initial greeting
40
+ if (/^>\s*$/m.test(clean) ||
41
+ /How can I help/i.test(clean) ||
42
+ /What would you like/i.test(clean)) {
43
+ this.hasSeenFirstPrompt = true;
44
+ return 'waiting-for-input';
45
+ }
46
+ // Processing: substantive output after the first prompt
47
+ if (this.hasSeenFirstPrompt && clean.trim().length > 0) {
48
+ return 'processing';
49
+ }
50
+ // Still initializing if we haven't seen the first prompt
51
+ if (!this.hasSeenFirstPrompt) {
52
+ return 'initializing';
53
+ }
54
+ return null;
55
+ }
56
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Codex output parser — stub.
3
+ *
4
+ * Always returns null, which tells the system to fall back to
5
+ * timer-based idle detection. Replace with real pattern matching
6
+ * when Codex TUI patterns are mapped.
7
+ */
8
+ export class CodexOutputParser {
9
+ onData(_chunk, _recentScrollback) {
10
+ return null;
11
+ }
12
+ reset() { }
13
+ }
@@ -0,0 +1,14 @@
1
+ import { ClaudeOutputParser } from './claude-parser.js';
2
+ import { CodexOutputParser } from './codex-parser.js';
3
+ import { OpencodeOutputParser } from './opencode-parser.js';
4
+ import { NullOutputParser } from './null-parser.js';
5
+ /**
6
+ * Registry: factory per parser type. Unknown keys return undefined (fall back to timer-based detection).
7
+ * Keys match AgentFramework.parserType values. 'none' is for frameworks that opt out of parsing.
8
+ */
9
+ export const outputParsers = {
10
+ claude: () => new ClaudeOutputParser(),
11
+ codex: () => new CodexOutputParser(),
12
+ opencode: () => new OpencodeOutputParser(),
13
+ none: () => new NullOutputParser(),
14
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Null output parser — always returns null.
3
+ *
4
+ * Used for agents with no known output patterns. Falls back to
5
+ * timer-based idle detection in the calling code.
6
+ */
7
+ export class NullOutputParser {
8
+ onData(_chunk, _recentScrollback) {
9
+ return null;
10
+ }
11
+ reset() { }
12
+ }
@@ -0,0 +1,77 @@
1
+ // Duplicated from utils.ts to preserve output-parsers/ module boundary
2
+ const ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]|\x1b\[\?[0-9;]*[hlm]|\x1b\[[0-9]*[ABCDJKH]/g;
3
+ /**
4
+ * OpenCode output parser.
5
+ *
6
+ * OpenCode uses a Bubble Tea TUI. This parser detects semantic state
7
+ * transitions by pattern-matching on cleaned terminal output.
8
+ *
9
+ * Key patterns:
10
+ * Permission prompt: lines starting with `!` followed by "permission"
11
+ * Tool use (processing): `$` bash, `<-` edit, `->` read, `*` glob/grep, `%` webfetch
12
+ * Agent header: `> build . provider/model` — indicates initializing/resuming
13
+ * Waiting for input: bare `>` prompt or "Ready" / "assistant: done" patterns
14
+ */
15
+ export class OpencodeOutputParser {
16
+ currentState = 'initializing';
17
+ hasSeenFirstPrompt = false;
18
+ onData(chunk, _recentScrollback) {
19
+ const clean = chunk.replace(ANSI_RE, '');
20
+ if (!clean.trim())
21
+ return null;
22
+ const newState = this.classify(clean);
23
+ if (newState && newState !== this.currentState) {
24
+ this.currentState = newState;
25
+ return { state: newState };
26
+ }
27
+ return null;
28
+ }
29
+ reset() {
30
+ this.currentState = 'initializing';
31
+ this.hasSeenFirstPrompt = false;
32
+ }
33
+ get state() {
34
+ return this.currentState;
35
+ }
36
+ classify(clean) {
37
+ // Permission prompt: highest priority — line starting with ! followed by "permission"
38
+ if (/^!\s.*permission/im.test(clean)) {
39
+ return 'permission-prompt';
40
+ }
41
+ // Waiting for input: "Ready" or "assistant: done" patterns
42
+ if (/\bReady\b/.test(clean) || /assistant:\s*done/i.test(clean)) {
43
+ this.hasSeenFirstPrompt = true;
44
+ return 'waiting-for-input';
45
+ }
46
+ // Bare `>` prompt on its own line (not followed by provider/model info)
47
+ if (/^>\s*$/m.test(clean)) {
48
+ this.hasSeenFirstPrompt = true;
49
+ return 'waiting-for-input';
50
+ }
51
+ // Agent header: `> build . provider/model` — initializing/resuming
52
+ // Matches `>` followed by typical opencode startup text (not bare >)
53
+ if (/^>\s+\S+.*\//m.test(clean)) {
54
+ this.hasSeenFirstPrompt = true;
55
+ return 'initializing';
56
+ }
57
+ // Tool icons indicating active processing (after first prompt seen)
58
+ if (this.hasSeenFirstPrompt &&
59
+ (/^\$\s/m.test(clean) || // bash/shell
60
+ /^<-\s/m.test(clean) || // file edit
61
+ /^->\s/m.test(clean) || // file read
62
+ /^\*\s/m.test(clean) || // glob/grep
63
+ /^%\s/m.test(clean)) // webfetch
64
+ ) {
65
+ return 'processing';
66
+ }
67
+ // General processing: substantive output after first prompt
68
+ if (this.hasSeenFirstPrompt && clean.trim().length > 0) {
69
+ return 'processing';
70
+ }
71
+ // Still initializing before first prompt
72
+ if (!this.hasSeenFirstPrompt) {
73
+ return 'initializing';
74
+ }
75
+ return null;
76
+ }
77
+ }