miko-code 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 (379) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/bin/miko +10 -0
  4. package/dist/client/antigravity.webp +0 -0
  5. package/dist/client/assets/abap-BdImnpbu.js +1 -0
  6. package/dist/client/assets/actionscript-3-CoDkCxhg.js +1 -0
  7. package/dist/client/assets/ada-bCR0ucgS.js +1 -0
  8. package/dist/client/assets/andromeeda-C4gqWexZ.js +1 -0
  9. package/dist/client/assets/angular-html-CU67Zn6k.js +1 -0
  10. package/dist/client/assets/angular-ts-BwZT4LLn.js +1 -0
  11. package/dist/client/assets/apache-Pmp26Uib.js +1 -0
  12. package/dist/client/assets/apex-D8_7TLub.js +1 -0
  13. package/dist/client/assets/apl-dKokRX4l.js +1 -0
  14. package/dist/client/assets/applescript-Co6uUVPk.js +1 -0
  15. package/dist/client/assets/ara-BRHolxvo.js +1 -0
  16. package/dist/client/assets/asciidoc-Ve4PFQV2.js +1 -0
  17. package/dist/client/assets/asm-D_Q5rh1f.js +1 -0
  18. package/dist/client/assets/astro-CbQHKStN.js +1 -0
  19. package/dist/client/assets/aurora-x-D-2ljcwZ.js +1 -0
  20. package/dist/client/assets/awk-DMzUqQB5.js +1 -0
  21. package/dist/client/assets/ayu-dark-DYE7WIF3.js +1 -0
  22. package/dist/client/assets/ayu-light-BA47KaF1.js +1 -0
  23. package/dist/client/assets/ayu-mirage-32ctXXKs.js +1 -0
  24. package/dist/client/assets/ballerina-BFfxhgS-.js +1 -0
  25. package/dist/client/assets/bat-BkioyH1T.js +1 -0
  26. package/dist/client/assets/beancount-k_qm7-4y.js +1 -0
  27. package/dist/client/assets/berry-uYugtg8r.js +1 -0
  28. package/dist/client/assets/bibtex-CHM0blh-.js +1 -0
  29. package/dist/client/assets/bicep-Bmn6On1c.js +1 -0
  30. package/dist/client/assets/bird2-DPOp833l.js +1 -0
  31. package/dist/client/assets/blade-D4QpJJKB.js +1 -0
  32. package/dist/client/assets/bsl-BO_Y6i37.js +1 -0
  33. package/dist/client/assets/c-BIGW1oBm.js +1 -0
  34. package/dist/client/assets/c3-eo99z4R2.js +1 -0
  35. package/dist/client/assets/cadence-Bv_4Rxtq.js +1 -0
  36. package/dist/client/assets/cairo-KRGpt6FW.js +1 -0
  37. package/dist/client/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  38. package/dist/client/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  39. package/dist/client/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  40. package/dist/client/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  41. package/dist/client/assets/clarity-D53aC0YG.js +1 -0
  42. package/dist/client/assets/clojure-P80f7IUj.js +1 -0
  43. package/dist/client/assets/cmake-D1j8_8rp.js +1 -0
  44. package/dist/client/assets/cobol-nwyudZeR.js +1 -0
  45. package/dist/client/assets/codeowners-Bp6g37R7.js +1 -0
  46. package/dist/client/assets/codeql-DsOJ9woJ.js +1 -0
  47. package/dist/client/assets/coffee-Ch7k5sss.js +1 -0
  48. package/dist/client/assets/common-lisp-Cg-RD9OK.js +1 -0
  49. package/dist/client/assets/coq-DkFqJrB1.js +1 -0
  50. package/dist/client/assets/cpp-CofmeUqb.js +1 -0
  51. package/dist/client/assets/crystal-tKQVLTB8.js +1 -0
  52. package/dist/client/assets/csharp-COcwbKMJ.js +1 -0
  53. package/dist/client/assets/css-DPfMkruS.js +1 -0
  54. package/dist/client/assets/csv-fuZLfV_i.js +1 -0
  55. package/dist/client/assets/cue-D82EKSYY.js +1 -0
  56. package/dist/client/assets/cypher-COkxafJQ.js +1 -0
  57. package/dist/client/assets/d-85-TOEBH.js +1 -0
  58. package/dist/client/assets/dark-plus-C3mMm8J8.js +1 -0
  59. package/dist/client/assets/dart-CF10PKvl.js +1 -0
  60. package/dist/client/assets/dax-CEL-wOlO.js +1 -0
  61. package/dist/client/assets/desktop-BmXAJ9_W.js +1 -0
  62. package/dist/client/assets/diff-D97Zzqfu.js +1 -0
  63. package/dist/client/assets/docker-BcOcwvcX.js +1 -0
  64. package/dist/client/assets/dotenv-Da5cRb03.js +1 -0
  65. package/dist/client/assets/dracula-BzJJZx-M.js +1 -0
  66. package/dist/client/assets/dracula-soft-BXkSAIEj.js +1 -0
  67. package/dist/client/assets/dream-maker-BtqSS_iP.js +1 -0
  68. package/dist/client/assets/edge-BkV0erSs.js +1 -0
  69. package/dist/client/assets/elixir-CDX3lj18.js +1 -0
  70. package/dist/client/assets/elm-DbKCFpqz.js +1 -0
  71. package/dist/client/assets/emacs-lisp-C9XAeP06.js +1 -0
  72. package/dist/client/assets/erb-B12qg9BL.js +1 -0
  73. package/dist/client/assets/erlang-DsQrWhSR.js +1 -0
  74. package/dist/client/assets/everforest-dark-BgDCqdQA.js +1 -0
  75. package/dist/client/assets/everforest-light-C8M2exoo.js +1 -0
  76. package/dist/client/assets/fennel-BYunw83y.js +1 -0
  77. package/dist/client/assets/fish-BvzEVeQv.js +1 -0
  78. package/dist/client/assets/fluent-C4IJs8-o.js +1 -0
  79. package/dist/client/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  80. package/dist/client/assets/fortran-free-form-BxgE0vQu.js +1 -0
  81. package/dist/client/assets/fsharp-CXgrBDvD.js +1 -0
  82. package/dist/client/assets/gdresource-BOOCDP_w.js +1 -0
  83. package/dist/client/assets/gdscript-C5YyOfLZ.js +1 -0
  84. package/dist/client/assets/gdshader-DkwncUOv.js +1 -0
  85. package/dist/client/assets/genie-D0YGMca9.js +1 -0
  86. package/dist/client/assets/gherkin-DyxjwDmM.js +1 -0
  87. package/dist/client/assets/git-commit-F4YmCXRG.js +1 -0
  88. package/dist/client/assets/git-rebase-r7XF79zn.js +1 -0
  89. package/dist/client/assets/github-dark-DHJKELXO.js +1 -0
  90. package/dist/client/assets/github-dark-default-Cuk6v7N8.js +1 -0
  91. package/dist/client/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  92. package/dist/client/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  93. package/dist/client/assets/github-light-DAi9KRSo.js +1 -0
  94. package/dist/client/assets/github-light-default-D7oLnXFd.js +1 -0
  95. package/dist/client/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  96. package/dist/client/assets/gleam-BspZqrRM.js +1 -0
  97. package/dist/client/assets/glimmer-js-Rg0-pVw9.js +1 -0
  98. package/dist/client/assets/glimmer-ts-U6CK756n.js +1 -0
  99. package/dist/client/assets/glsl-DplSGwfg.js +1 -0
  100. package/dist/client/assets/gn-n2N0HUVH.js +1 -0
  101. package/dist/client/assets/gnuplot-DdkO51Og.js +1 -0
  102. package/dist/client/assets/go-CxLEBnE3.js +1 -0
  103. package/dist/client/assets/graphql-ChdNCCLP.js +1 -0
  104. package/dist/client/assets/groovy-gcz8RCvz.js +1 -0
  105. package/dist/client/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  106. package/dist/client/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  107. package/dist/client/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  108. package/dist/client/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  109. package/dist/client/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  110. package/dist/client/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  111. package/dist/client/assets/hack-CaT9iCJl.js +1 -0
  112. package/dist/client/assets/haml-B8DHNrY2.js +1 -0
  113. package/dist/client/assets/handlebars-BL8al0AC.js +1 -0
  114. package/dist/client/assets/haskell-Df6bDoY_.js +1 -0
  115. package/dist/client/assets/haxe-CzTSHFRz.js +1 -0
  116. package/dist/client/assets/hcl-BWvSN4gD.js +1 -0
  117. package/dist/client/assets/hjson-D5-asLiD.js +1 -0
  118. package/dist/client/assets/hlsl-D3lLCCz7.js +1 -0
  119. package/dist/client/assets/horizon-BUw7H-hv.js +1 -0
  120. package/dist/client/assets/horizon-bright-Cn-bp-IR.js +1 -0
  121. package/dist/client/assets/houston-DnULxvSX.js +1 -0
  122. package/dist/client/assets/html-GMplVEZG.js +1 -0
  123. package/dist/client/assets/html-derivative-BFtXZ54Q.js +1 -0
  124. package/dist/client/assets/http-jrhK8wxY.js +1 -0
  125. package/dist/client/assets/hurl-irOxFIW8.js +1 -0
  126. package/dist/client/assets/hxml-Bvhsp5Yf.js +1 -0
  127. package/dist/client/assets/hy-DFXneXwc.js +1 -0
  128. package/dist/client/assets/imba-DGztddWO.js +1 -0
  129. package/dist/client/assets/index-C07zYq_-.css +32 -0
  130. package/dist/client/assets/index-Ce3hNHfL.js +2351 -0
  131. package/dist/client/assets/ini-BEwlwnbL.js +1 -0
  132. package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  133. package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  134. package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  135. package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  136. package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  137. package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  138. package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  139. package/dist/client/assets/java-CylS5w8V.js +1 -0
  140. package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
  141. package/dist/client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  142. package/dist/client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  143. package/dist/client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  144. package/dist/client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  145. package/dist/client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  146. package/dist/client/assets/jinja-4LBKfQ-Z.js +1 -0
  147. package/dist/client/assets/jison-wvAkD_A8.js +1 -0
  148. package/dist/client/assets/json-Cp-IABpG.js +1 -0
  149. package/dist/client/assets/json5-C9tS-k6U.js +1 -0
  150. package/dist/client/assets/jsonc-Des-eS-w.js +1 -0
  151. package/dist/client/assets/jsonl-DcaNXYhu.js +1 -0
  152. package/dist/client/assets/jsonnet-DFQXde-d.js +1 -0
  153. package/dist/client/assets/jssm-C2t-YnRu.js +1 -0
  154. package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
  155. package/dist/client/assets/julia-CxzCAyBv.js +1 -0
  156. package/dist/client/assets/just-Cw27pwNe.js +1 -0
  157. package/dist/client/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  158. package/dist/client/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  159. package/dist/client/assets/kanagawa-wave-DWedfzmr.js +1 -0
  160. package/dist/client/assets/kdl-DV7GczEv.js +1 -0
  161. package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
  162. package/dist/client/assets/kusto-DZf3V79B.js +1 -0
  163. package/dist/client/assets/laserwave-DUszq2jm.js +1 -0
  164. package/dist/client/assets/latex-CWtU0Tv5.js +1 -0
  165. package/dist/client/assets/lean-BZvkOJ9d.js +1 -0
  166. package/dist/client/assets/less-B1dDrJ26.js +1 -0
  167. package/dist/client/assets/light-plus-B7mTdjB0.js +1 -0
  168. package/dist/client/assets/liquid-DYVedYrR.js +1 -0
  169. package/dist/client/assets/llvm-DjAJT7YJ.js +1 -0
  170. package/dist/client/assets/log-2UxHyX5q.js +1 -0
  171. package/dist/client/assets/logo-BtOb2qkB.js +1 -0
  172. package/dist/client/assets/lua-BaeVxFsk.js +1 -0
  173. package/dist/client/assets/luau-C-HG3fhB.js +1 -0
  174. package/dist/client/assets/make-CHLpvVh8.js +1 -0
  175. package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
  176. package/dist/client/assets/marko-CnJfTvn9.js +1 -0
  177. package/dist/client/assets/material-theme-D5KoaKCx.js +1 -0
  178. package/dist/client/assets/material-theme-darker-BfHTSMKl.js +1 -0
  179. package/dist/client/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  180. package/dist/client/assets/material-theme-ocean-CyktbL80.js +1 -0
  181. package/dist/client/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  182. package/dist/client/assets/matlab-D7o27uSR.js +1 -0
  183. package/dist/client/assets/mdc-BMNejdWA.js +1 -0
  184. package/dist/client/assets/mdx-Cmh6b_Ma.js +1 -0
  185. package/dist/client/assets/mermaid-mWjccvbQ.js +1 -0
  186. package/dist/client/assets/min-dark-CafNBF8u.js +1 -0
  187. package/dist/client/assets/min-light-CTRr51gU.js +1 -0
  188. package/dist/client/assets/mipsasm-CKIfxQSi.js +1 -0
  189. package/dist/client/assets/mojo-rZm6bMo-.js +1 -0
  190. package/dist/client/assets/monokai-D4h5O-jR.js +1 -0
  191. package/dist/client/assets/moonbit-_H4v1dQx.js +1 -0
  192. package/dist/client/assets/move-IF9eRakj.js +1 -0
  193. package/dist/client/assets/narrat-DRg8JJMk.js +1 -0
  194. package/dist/client/assets/nextflow-Zz6hmt5N.js +1 -0
  195. package/dist/client/assets/nextflow-groovy-BeH2EWoN.js +1 -0
  196. package/dist/client/assets/nginx-BpAMiNFr.js +1 -0
  197. package/dist/client/assets/night-owl-C39BiMTA.js +1 -0
  198. package/dist/client/assets/night-owl-light-CMTm3GFP.js +1 -0
  199. package/dist/client/assets/nim-CVrawwO9.js +1 -0
  200. package/dist/client/assets/nix-CwoSXNpI.js +1 -0
  201. package/dist/client/assets/nord-Ddv68eIx.js +1 -0
  202. package/dist/client/assets/nushell-Cz2AlsmD.js +1 -0
  203. package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
  204. package/dist/client/assets/objective-cpp-CLxacb5B.js +1 -0
  205. package/dist/client/assets/ocaml-C0hk2d4L.js +1 -0
  206. package/dist/client/assets/odin-BBf5iR-q.js +1 -0
  207. package/dist/client/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  208. package/dist/client/assets/one-light-C3Wv6jpd.js +1 -0
  209. package/dist/client/assets/openscad-C4EeE6gA.js +1 -0
  210. package/dist/client/assets/pascal-D93ZcfNL.js +1 -0
  211. package/dist/client/assets/perl-C0TMdlhV.js +1 -0
  212. package/dist/client/assets/php-Dhbhpdrm.js +1 -0
  213. package/dist/client/assets/pierre-dark-DF2SEV7i.js +1 -0
  214. package/dist/client/assets/pierre-light-DOlZxES8.js +1 -0
  215. package/dist/client/assets/pkl-u5AG7uiY.js +1 -0
  216. package/dist/client/assets/plastic-3e1v2bzS.js +1 -0
  217. package/dist/client/assets/plsql-ChMvpjG-.js +1 -0
  218. package/dist/client/assets/po-BTJTHyun.js +1 -0
  219. package/dist/client/assets/poimandres-CS3Unz2-.js +1 -0
  220. package/dist/client/assets/polar-C0HS_06l.js +1 -0
  221. package/dist/client/assets/postcss-CXtECtnM.js +1 -0
  222. package/dist/client/assets/powerquery-CEu0bR-o.js +1 -0
  223. package/dist/client/assets/powershell-Dpen1YoG.js +1 -0
  224. package/dist/client/assets/prisma-Dd19v3D-.js +1 -0
  225. package/dist/client/assets/prolog-CbFg5uaA.js +1 -0
  226. package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
  227. package/dist/client/assets/pug-CGlum2m_.js +1 -0
  228. package/dist/client/assets/puppet-BMWR74SV.js +1 -0
  229. package/dist/client/assets/purescript-CklMAg4u.js +1 -0
  230. package/dist/client/assets/python-B6aJPvgy.js +1 -0
  231. package/dist/client/assets/qml-3beO22l8.js +1 -0
  232. package/dist/client/assets/qmldir-C8lEn-DE.js +1 -0
  233. package/dist/client/assets/qss-IeuSbFQv.js +1 -0
  234. package/dist/client/assets/r-Dspwwk_N.js +1 -0
  235. package/dist/client/assets/racket-BqYA7rlc.js +1 -0
  236. package/dist/client/assets/raku-DXvB9xmW.js +1 -0
  237. package/dist/client/assets/razor-Uh8Bk_45.js +1 -0
  238. package/dist/client/assets/red-bN70gL4F.js +1 -0
  239. package/dist/client/assets/reg-C-SQnVFl.js +1 -0
  240. package/dist/client/assets/regexp-CDVJQ6XC.js +1 -0
  241. package/dist/client/assets/rel-C3B-1QV4.js +1 -0
  242. package/dist/client/assets/riscv-BM1_JUlF.js +1 -0
  243. package/dist/client/assets/ron-D8l8udqQ.js +1 -0
  244. package/dist/client/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
  245. package/dist/client/assets/rose-pine-moon-D4_iv3hh.js +1 -0
  246. package/dist/client/assets/rose-pine-qdsjHGoJ.js +1 -0
  247. package/dist/client/assets/rosmsg-BJDFO7_C.js +1 -0
  248. package/dist/client/assets/rst-BrH8l1NY.js +1 -0
  249. package/dist/client/assets/ruby-Dw2BHqvy.js +1 -0
  250. package/dist/client/assets/rust-B1yitclQ.js +1 -0
  251. package/dist/client/assets/sas-cz2c8ADy.js +1 -0
  252. package/dist/client/assets/sass-Cj5Yp3dK.js +1 -0
  253. package/dist/client/assets/scala-C151Ov-r.js +1 -0
  254. package/dist/client/assets/scheme-C98Dy4si.js +1 -0
  255. package/dist/client/assets/scratchpad-page-DcMny6uZ.js +1 -0
  256. package/dist/client/assets/scss-OYdSNvt2.js +1 -0
  257. package/dist/client/assets/sdbl-DVxCFoDh.js +1 -0
  258. package/dist/client/assets/shaderlab-Dg9Lc6iA.js +1 -0
  259. package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
  260. package/dist/client/assets/shellsession-BADoaaVG.js +1 -0
  261. package/dist/client/assets/slack-dark-BthQWCQV.js +1 -0
  262. package/dist/client/assets/slack-ochin-DqwNpetd.js +1 -0
  263. package/dist/client/assets/smalltalk-BERRCDM3.js +1 -0
  264. package/dist/client/assets/snazzy-light-Bw305WKR.js +1 -0
  265. package/dist/client/assets/solarized-dark-DXbdFlpD.js +1 -0
  266. package/dist/client/assets/solarized-light-L9t79GZl.js +1 -0
  267. package/dist/client/assets/solidity-rGO070M0.js +1 -0
  268. package/dist/client/assets/soy-Brmx7dQM.js +1 -0
  269. package/dist/client/assets/sparql-rVzFXLq3.js +1 -0
  270. package/dist/client/assets/splunk-BtCnVYZw.js +1 -0
  271. package/dist/client/assets/sql-BLtJtn59.js +1 -0
  272. package/dist/client/assets/ssh-config-_ykCGR6B.js +1 -0
  273. package/dist/client/assets/stata-BH5u7GGu.js +1 -0
  274. package/dist/client/assets/stylus-BEDo0Tqx.js +1 -0
  275. package/dist/client/assets/surrealql-Bq5Q-fJD.js +1 -0
  276. package/dist/client/assets/svelte-C_ipcX3V.js +1 -0
  277. package/dist/client/assets/swift-D82vCrfD.js +1 -0
  278. package/dist/client/assets/synthwave-84-CbfX1IO0.js +1 -0
  279. package/dist/client/assets/system-verilog-CnnmHF94.js +1 -0
  280. package/dist/client/assets/systemd-4A_iFExJ.js +1 -0
  281. package/dist/client/assets/talonscript-CkByrt1z.js +1 -0
  282. package/dist/client/assets/tasl-QIJgUcNo.js +1 -0
  283. package/dist/client/assets/tcl-dwOrl1Do.js +1 -0
  284. package/dist/client/assets/templ-P3uqSqPl.js +1 -0
  285. package/dist/client/assets/terraform-BETggiCN.js +1 -0
  286. package/dist/client/assets/tex-idrVyKtj.js +1 -0
  287. package/dist/client/assets/tokyo-night-hegEt444.js +1 -0
  288. package/dist/client/assets/toml-vGWfd6FD.js +1 -0
  289. package/dist/client/assets/ts-tags-zn1MmPIZ.js +1 -0
  290. package/dist/client/assets/tsv-B_m7g4N7.js +1 -0
  291. package/dist/client/assets/tsx-COt5Ahok.js +1 -0
  292. package/dist/client/assets/turtle-BsS91CYL.js +1 -0
  293. package/dist/client/assets/twig-DNn4PbVi.js +1 -0
  294. package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
  295. package/dist/client/assets/typespec-BGHnOYBU.js +1 -0
  296. package/dist/client/assets/typst-DHCkPAjA.js +1 -0
  297. package/dist/client/assets/v-BcVCzyr7.js +1 -0
  298. package/dist/client/assets/vala-CsfeWuGM.js +1 -0
  299. package/dist/client/assets/vb-D17OF-Vu.js +1 -0
  300. package/dist/client/assets/verilog-BQ8w6xss.js +1 -0
  301. package/dist/client/assets/vesper-DU1UobuO.js +1 -0
  302. package/dist/client/assets/vhdl-CeAyd5Ju.js +1 -0
  303. package/dist/client/assets/viml-CJc9bBzg.js +1 -0
  304. package/dist/client/assets/vitesse-black-Bkuqu6BP.js +1 -0
  305. package/dist/client/assets/vitesse-dark-D0r3Knsf.js +1 -0
  306. package/dist/client/assets/vitesse-light-CVO1_9PV.js +1 -0
  307. package/dist/client/assets/vue-DN_0RTcg.js +1 -0
  308. package/dist/client/assets/vue-html-AaS7Mt5G.js +1 -0
  309. package/dist/client/assets/vue-vine-CQOfvN7w.js +1 -0
  310. package/dist/client/assets/vyper-CDx5xZoG.js +1 -0
  311. package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
  312. package/dist/client/assets/wasm-MzD3tlZU.js +1 -0
  313. package/dist/client/assets/wenyan-BV7otONQ.js +1 -0
  314. package/dist/client/assets/wgsl-Dx-B1_4e.js +1 -0
  315. package/dist/client/assets/wikitext-BhOHFoWU.js +1 -0
  316. package/dist/client/assets/wit-5i3qLPDT.js +1 -0
  317. package/dist/client/assets/wolfram-lXgVvXCa.js +1 -0
  318. package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
  319. package/dist/client/assets/xsl-CtQFsRM5.js +1 -0
  320. package/dist/client/assets/yaml-Buea-lGh.js +1 -0
  321. package/dist/client/assets/zenscript-DVFEvuxE.js +1 -0
  322. package/dist/client/assets/zig-VOosw3JB.js +1 -0
  323. package/dist/client/cursor.png +0 -0
  324. package/dist/client/favicon.svg +17 -0
  325. package/dist/client/finder.png +0 -0
  326. package/dist/client/icons/claude.svg +1 -0
  327. package/dist/client/icons/openai.svg +1 -0
  328. package/dist/client/images/github.png +0 -0
  329. package/dist/client/index.html +15 -0
  330. package/dist/client/logo.svg +17 -0
  331. package/dist/client/terminal.png +0 -0
  332. package/dist/client/vscode.png +0 -0
  333. package/dist/client/warp.png +0 -0
  334. package/package.json +107 -0
  335. package/src/server/agent-instruction-attachments.ts +458 -0
  336. package/src/server/agent.ts +1879 -0
  337. package/src/server/cli-runtime.ts +418 -0
  338. package/src/server/cli-supervisor.ts +90 -0
  339. package/src/server/cli.ts +102 -0
  340. package/src/server/codex-app-server-protocol.ts +478 -0
  341. package/src/server/codex-app-server.ts +1645 -0
  342. package/src/server/data-dir-lock.ts +128 -0
  343. package/src/server/diff-store.ts +1587 -0
  344. package/src/server/durable-file.ts +74 -0
  345. package/src/server/event-store.ts +1448 -0
  346. package/src/server/event.ts +249 -0
  347. package/src/server/external-file-access.ts +48 -0
  348. package/src/server/external-open.ts +259 -0
  349. package/src/server/generate-title.ts +75 -0
  350. package/src/server/git-refresh-poller.ts +92 -0
  351. package/src/server/github-rest-client.ts +176 -0
  352. package/src/server/harness-types.ts +24 -0
  353. package/src/server/keybindings.ts +203 -0
  354. package/src/server/machine-name.ts +22 -0
  355. package/src/server/paths.ts +51 -0
  356. package/src/server/pr-manager.ts +1204 -0
  357. package/src/server/pr-refresh-poller.ts +126 -0
  358. package/src/server/process-utils.ts +18 -0
  359. package/src/server/provider-catalog.ts +90 -0
  360. package/src/server/quick-response.ts +274 -0
  361. package/src/server/read-models.ts +311 -0
  362. package/src/server/restart.ts +33 -0
  363. package/src/server/scratchpad-manager.ts +87 -0
  364. package/src/server/server.ts +759 -0
  365. package/src/server/share.ts +126 -0
  366. package/src/server/terminal-manager.ts +371 -0
  367. package/src/server/update-manager.ts +250 -0
  368. package/src/server/uploads.ts +191 -0
  369. package/src/server/workspace-file-search.ts +191 -0
  370. package/src/server/workspace-manager.ts +627 -0
  371. package/src/server/workspace-polling.ts +10 -0
  372. package/src/server/ws-router.ts +1039 -0
  373. package/src/shared/branding.ts +69 -0
  374. package/src/shared/dev-ports.ts +100 -0
  375. package/src/shared/ports.ts +2 -0
  376. package/src/shared/protocol.ts +217 -0
  377. package/src/shared/tools.ts +324 -0
  378. package/src/shared/types.ts +1220 -0
  379. package/tsconfig.json +35 -0
@@ -0,0 +1,627 @@
1
+ import { mkdir, realpath, stat } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import path from 'node:path';
4
+ import { getWorktreesDir } from 'src/shared/branding';
5
+ import type { WorkspaceGitHubSnapshot, WorkspaceHealthState } from 'src/shared/types';
6
+ import { type DiffStore, extractGitHubRepoSlug, runGit } from './diff-store';
7
+ import type { SessionRecord, WorkspaceRecord } from './event';
8
+ import type { EventStore } from './event-store';
9
+ import type { PrManager } from './pr-manager';
10
+
11
+ const WORKSPACE_CODE_NAMES = [
12
+ 'atlas',
13
+ 'orion',
14
+ 'vega',
15
+ 'argo',
16
+ 'sirius',
17
+ 'lyra',
18
+ 'nova',
19
+ 'apollo',
20
+ 'helios',
21
+ 'selene',
22
+ 'phoenix',
23
+ 'pegasus',
24
+ 'perseus',
25
+ 'oberon',
26
+ 'europa',
27
+ 'callisto',
28
+ 'triton',
29
+ 'janus',
30
+ 'hyperion',
31
+ 'prometheus',
32
+ 'daedalus',
33
+ 'icarus',
34
+ 'hermes',
35
+ 'athena',
36
+ 'artemis',
37
+ 'aurora',
38
+ ];
39
+
40
+ const PR_REFRESH_COOLDOWN_MS = 60 * 1000;
41
+ const MAX_WORKSPACE_NAME_SUFFIX = 100;
42
+
43
+ export type WorkspaceTurnIntent =
44
+ | 'commit_and_push'
45
+ | 'pull_latest_main'
46
+ | 'create_pr'
47
+ | 'fix_ci'
48
+ | 'resolve_merge_conflicts'
49
+ | 'address_review_comments'
50
+ | 'review';
51
+
52
+ export interface WorkspaceCreateResult {
53
+ workspace: WorkspaceRecord;
54
+ session: SessionRecord | null;
55
+ }
56
+
57
+ interface WorkspaceManagerDeps {
58
+ diffStore?: Pick<DiffStore, 'refreshWorkspaceGitSnapshot'>;
59
+ prManager?: Pick<
60
+ PrManager,
61
+ 'getWorkspaceGitHubSnapshot' | 'refreshWorkspacePrState' | 'clearWorkspaceGitHubSnapshot'
62
+ >;
63
+ worktreesRoot?: string;
64
+ onWorkspaceSetupStateChanged?: (workspaceId: string) => void | Promise<void>;
65
+ }
66
+
67
+ async function pathExists(localPath: string) {
68
+ try {
69
+ await stat(localPath);
70
+ return true;
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+
76
+ async function resolvePhysicalPath(localPath: string) {
77
+ return realpath(localPath).catch(() => path.resolve(localPath));
78
+ }
79
+
80
+ function sanitizeBranchName(value: string) {
81
+ return value
82
+ .trim()
83
+ .toLowerCase()
84
+ .replace(/[^a-z0-9._/-]+/gu, '-')
85
+ .replace(/\/+/gu, '-')
86
+ .replace(/^-+|-+$/gu, '')
87
+ .replace(/\.lock$/u, '');
88
+ }
89
+
90
+ function formatGitFailure(result: Awaited<ReturnType<typeof runGit>>) {
91
+ return [result.stderr.trim(), result.stdout.trim()].filter(Boolean).join('\n');
92
+ }
93
+
94
+ function assertGitSuccess(result: Awaited<ReturnType<typeof runGit>>, message: string) {
95
+ if (result.exitCode === 0) return;
96
+ const detail = formatGitFailure(result);
97
+ throw new Error(detail ? `${message}: ${detail}` : message);
98
+ }
99
+
100
+ async function getExistingLocalBranches(repoPath: string) {
101
+ const result = await runGit(
102
+ ['for-each-ref', '--format=%(refname:short)', 'refs/heads'],
103
+ repoPath,
104
+ );
105
+
106
+ assertGitSuccess(result, 'Git could not list local branches');
107
+
108
+ return new Set(
109
+ result.stdout
110
+ .split(/\r?\n/u)
111
+ .map((line) => line.trim())
112
+ .filter(Boolean),
113
+ );
114
+ }
115
+
116
+ async function getExistingRemoteBranchNames(repoPath: string) {
117
+ const result = await runGit(
118
+ ['for-each-ref', '--format=%(refname:short)', 'refs/remotes'],
119
+ repoPath,
120
+ );
121
+
122
+ assertGitSuccess(result, 'Git could not list remote branches');
123
+
124
+ return new Set(
125
+ result.stdout
126
+ .split(/\r?\n/u)
127
+ .map((line) => line.trim())
128
+ .filter(Boolean)
129
+ .map((branch) => branch.replace(/^origin\//u, ''))
130
+ .filter((branch) => branch !== 'HEAD'),
131
+ );
132
+ }
133
+
134
+ async function getExistingWorktreePaths(repoPath: string) {
135
+ const result = await runGit(['worktree', 'list', '--porcelain'], repoPath);
136
+ assertGitSuccess(result, 'Git could not list worktrees');
137
+
138
+ return new Set(
139
+ result.stdout
140
+ .split(/\r?\n/u)
141
+ .filter((line) => line.startsWith('worktree '))
142
+ .map((line) => path.resolve(line.slice('worktree '.length).trim())),
143
+ );
144
+ }
145
+
146
+ async function isValidBranchName(repoPath: string, branchName: string) {
147
+ const result = await runGit(['check-ref-format', '--branch', branchName], repoPath);
148
+ return result.exitCode === 0;
149
+ }
150
+
151
+ async function branchHasUpstream(repoPath: string) {
152
+ const result = await runGit(
153
+ ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'],
154
+ repoPath,
155
+ );
156
+ return result.exitCode === 0;
157
+ }
158
+
159
+ async function remoteBranchExists(repoPath: string, branchName: string) {
160
+ const result = await runGit(
161
+ ['rev-parse', '--verify', '--quiet', `refs/remotes/origin/${branchName}`],
162
+ repoPath,
163
+ );
164
+ return result.exitCode === 0;
165
+ }
166
+
167
+ async function getOriginRemoteUrl(repoPath: string) {
168
+ const result = await runGit(['remote', 'get-url', 'origin'], repoPath);
169
+ return result.exitCode === 0 ? result.stdout.trim() : null;
170
+ }
171
+
172
+ export class WorkspaceManager {
173
+ private readonly diffStore: WorkspaceManagerDeps['diffStore'];
174
+ private readonly prManager: WorkspaceManagerDeps['prManager'];
175
+ private readonly worktreesRoot: string;
176
+ private readonly onWorkspaceSetupStateChanged: WorkspaceManagerDeps['onWorkspaceSetupStateChanged'];
177
+ private readonly pendingTurnIntentBySessionId = new Map<string, WorkspaceTurnIntent>();
178
+ private readonly lastPrRefreshAtByWorkspaceId = new Map<string, number>();
179
+
180
+ constructor(
181
+ private readonly eventStore: EventStore,
182
+ deps: WorkspaceManagerDeps = {},
183
+ ) {
184
+ this.diffStore = deps.diffStore;
185
+ this.prManager = deps.prManager;
186
+ this.worktreesRoot = deps.worktreesRoot ?? getWorktreesDir(homedir());
187
+ this.onWorkspaceSetupStateChanged = deps.onWorkspaceSetupStateChanged;
188
+ }
189
+
190
+ private async notifyWorkspaceSetupStateChanged(workspaceId: string) {
191
+ if (!this.onWorkspaceSetupStateChanged) return;
192
+ try {
193
+ await this.onWorkspaceSetupStateChanged(workspaceId);
194
+ } catch (error) {
195
+ console.error('[workspace-manager] failed to broadcast workspace setup state change', {
196
+ workspaceId,
197
+ error,
198
+ });
199
+ }
200
+ }
201
+
202
+ private getWorktreePath(directoryId: string, branchName: string) {
203
+ return path.join(this.worktreesRoot, directoryId, branchName);
204
+ }
205
+
206
+ private async generateWorkspaceIdentity(directoryId: string, directoryPath: string) {
207
+ const metadataBranches = new Set(
208
+ this.eventStore
209
+ .listWorkspacesByDirectory(directoryId)
210
+ .map((workspace) => workspace.branchName),
211
+ );
212
+
213
+ const metadataPaths = new Set(
214
+ this.eventStore.listWorkspaces().map((workspace) => path.resolve(workspace.localPath)),
215
+ );
216
+
217
+ const localBranches = await getExistingLocalBranches(directoryPath);
218
+ const worktreePaths = await getExistingWorktreePaths(directoryPath);
219
+
220
+ for (let suffix = 1; suffix <= MAX_WORKSPACE_NAME_SUFFIX; suffix++) {
221
+ for (const codeName of WORKSPACE_CODE_NAMES) {
222
+ const branchName = suffix === 1 ? codeName : `${codeName}-${suffix}`;
223
+ const localPath = this.getWorktreePath(directoryId, branchName);
224
+ const resolvedPath = path.resolve(localPath);
225
+
226
+ if (metadataBranches.has(branchName) || localBranches.has(branchName)) continue;
227
+ if (metadataPaths.has(resolvedPath) || worktreePaths.has(resolvedPath)) continue;
228
+
229
+ if (await pathExists(resolvedPath)) continue;
230
+ if (!(await isValidBranchName(directoryPath, branchName))) continue;
231
+
232
+ return { branchName, localPath: resolvedPath };
233
+ }
234
+ }
235
+
236
+ throw new Error('Could not generate a unique workspace branch and worktree path');
237
+ }
238
+
239
+ private async generateContinuationBranchName(
240
+ directoryId: string,
241
+ directoryPath: string,
242
+ currentBranchName: string,
243
+ ) {
244
+ const directoryWorkspaces = this.eventStore.listWorkspacesByDirectory(directoryId);
245
+ const metadataBranches = new Set(directoryWorkspaces.map((workspace) => workspace.branchName));
246
+ const knownPrHeads = new Set(
247
+ directoryWorkspaces
248
+ .map((workspace) => workspace.pullRequest?.headRefName)
249
+ .filter((headRefName): headRefName is string => Boolean(headRefName)),
250
+ );
251
+ const localBranches = await getExistingLocalBranches(directoryPath);
252
+ const remoteBranches = await getExistingRemoteBranchNames(directoryPath);
253
+ const baseName = sanitizeBranchName(currentBranchName) || currentBranchName;
254
+
255
+ for (let suffix = 1; suffix <= MAX_WORKSPACE_NAME_SUFFIX; suffix++) {
256
+ const branchName = `${baseName}-v${suffix}`;
257
+ if (
258
+ metadataBranches.has(branchName) ||
259
+ knownPrHeads.has(branchName) ||
260
+ localBranches.has(branchName) ||
261
+ remoteBranches.has(branchName)
262
+ ) {
263
+ continue;
264
+ }
265
+ if (!(await isValidBranchName(directoryPath, branchName))) continue;
266
+ return branchName;
267
+ }
268
+
269
+ throw new Error('Could not generate a unique workspace branch name');
270
+ }
271
+
272
+ private async resolveBaseRef(directoryPath: string) {
273
+ await runGit(['fetch', 'origin', 'main', '--prune'], directoryPath);
274
+
275
+ const originMain = await runGit(
276
+ ['rev-parse', '--verify', '--quiet', 'refs/remotes/origin/main'],
277
+ directoryPath,
278
+ );
279
+
280
+ if (originMain.exitCode === 0) return 'origin/main';
281
+
282
+ const localMain = await runGit(
283
+ ['rev-parse', '--verify', '--quiet', 'refs/heads/main'],
284
+ directoryPath,
285
+ );
286
+
287
+ if (localMain.exitCode === 0) return 'main';
288
+
289
+ throw new Error('Directory must have a main branch before creating a workspace');
290
+ }
291
+
292
+ async refreshWorkspacePrStage(
293
+ workspaceId: string,
294
+ options?: { force?: boolean },
295
+ ): Promise<{ refreshed: boolean; snapshot: WorkspaceGitHubSnapshot | null }> {
296
+ if (!this.prManager) return { refreshed: false, snapshot: null };
297
+
298
+ const now = Date.now();
299
+ const lastRefreshedAt = this.lastPrRefreshAtByWorkspaceId.get(workspaceId) ?? 0;
300
+ if (!options?.force && now - lastRefreshedAt < PR_REFRESH_COOLDOWN_MS) {
301
+ return {
302
+ refreshed: false,
303
+ snapshot: this.prManager.getWorkspaceGitHubSnapshot(workspaceId),
304
+ };
305
+ }
306
+
307
+ const snapshot = await this.prManager.refreshWorkspacePrState(workspaceId);
308
+ this.lastPrRefreshAtByWorkspaceId.set(workspaceId, Date.now());
309
+ return { refreshed: true, snapshot };
310
+ }
311
+
312
+ markWorkspaceInstructionTurnStarted(args: {
313
+ sessionId: string;
314
+ workspaceId: string;
315
+ intent: WorkspaceTurnIntent;
316
+ }) {
317
+ const session = this.eventStore.requireSession(args.sessionId);
318
+ if (session.workspaceId !== args.workspaceId) {
319
+ throw new Error('Session does not belong to workspace');
320
+ }
321
+
322
+ if (
323
+ args.intent !== 'commit_and_push' &&
324
+ args.intent !== 'pull_latest_main' &&
325
+ args.intent !== 'create_pr' &&
326
+ args.intent !== 'fix_ci' &&
327
+ args.intent !== 'resolve_merge_conflicts' &&
328
+ args.intent !== 'address_review_comments' &&
329
+ args.intent !== 'review'
330
+ ) {
331
+ throw new Error('Unknown workspace instruction turn intent');
332
+ }
333
+
334
+ this.pendingTurnIntentBySessionId.set(args.sessionId, args.intent);
335
+ }
336
+
337
+ clearWorkspaceInstructionTurn(sessionId: string) {
338
+ this.pendingTurnIntentBySessionId.delete(sessionId);
339
+ }
340
+
341
+ async handleWorkspaceTurnSettled(args: { sessionId: string }): Promise<{ changed: boolean }> {
342
+ const intent = this.pendingTurnIntentBySessionId.get(args.sessionId);
343
+ this.pendingTurnIntentBySessionId.delete(args.sessionId);
344
+
345
+ const session = this.eventStore.getSession(args.sessionId);
346
+ if (!session) return { changed: false };
347
+
348
+ const workspace = this.eventStore.getWorkspace(session.workspaceId);
349
+ if (!workspace) return { changed: false };
350
+
351
+ let changed = false;
352
+
353
+ if (this.diffStore) {
354
+ try {
355
+ changed =
356
+ (await this.diffStore.refreshWorkspaceGitSnapshot(workspace.id, workspace.localPath)) ||
357
+ changed;
358
+ } catch (error) {
359
+ console.error('[workspace-manager] failed to refresh workspace git snapshot', {
360
+ workspaceId: workspace.id,
361
+ error,
362
+ });
363
+ }
364
+ }
365
+
366
+ const shouldRefreshPrStage =
367
+ intent === 'create_pr' ||
368
+ intent === 'fix_ci' ||
369
+ intent === 'resolve_merge_conflicts' ||
370
+ intent === 'address_review_comments' ||
371
+ intent === 'review' ||
372
+ workspace.reviewState === 'in_review';
373
+ if (shouldRefreshPrStage) {
374
+ try {
375
+ const prResult = await this.refreshWorkspacePrStage(workspace.id, {
376
+ force:
377
+ intent === 'create_pr' ||
378
+ intent === 'fix_ci' ||
379
+ intent === 'resolve_merge_conflicts' ||
380
+ intent === 'address_review_comments' ||
381
+ intent === 'review',
382
+ });
383
+ changed = prResult.refreshed || changed;
384
+ } catch (error) {
385
+ console.error('[workspace-manager] failed to refresh workspace PR stage', {
386
+ workspaceId: workspace.id,
387
+ error,
388
+ });
389
+ }
390
+ }
391
+
392
+ return { changed };
393
+ }
394
+
395
+ async getWorkspaceHealthState(workspaceId: string): Promise<WorkspaceHealthState> {
396
+ const workspace = this.eventStore.requireWorkspace(workspaceId);
397
+ const directory = this.eventStore.requireDirectory(workspace.directoryId);
398
+
399
+ if (!(await pathExists(directory.localPath))) return 'source_missing';
400
+ if (!(await pathExists(workspace.localPath))) return 'workspace_missing';
401
+
402
+ const worktreeTopLevel = await runGit(['rev-parse', '--show-toplevel'], workspace.localPath);
403
+ if (worktreeTopLevel.exitCode !== 0) return 'git_invalid';
404
+ const [actualTopLevel, expectedTopLevel] = await Promise.all([
405
+ resolvePhysicalPath(worktreeTopLevel.stdout.trim()),
406
+ resolvePhysicalPath(workspace.localPath),
407
+ ]);
408
+ if (actualTopLevel !== expectedTopLevel) return 'worktree_mismatch';
409
+
410
+ const currentBranch = await runGit(['branch', '--show-current'], workspace.localPath);
411
+ const branchName = currentBranch.stdout.trim();
412
+ if (!branchName) return 'detached_head';
413
+ if (branchName !== workspace.branchName) return 'branch_missing';
414
+
415
+ const originSlug = extractGitHubRepoSlug(await getOriginRemoteUrl(workspace.localPath));
416
+ const expectedSlug = `${directory.githubOwner}/${directory.githubRepo}`;
417
+ if (originSlug !== expectedSlug) return 'repo_mismatch';
418
+
419
+ return 'healthy';
420
+ }
421
+
422
+ async createWorkspace(directoryId: string): Promise<WorkspaceCreateResult> {
423
+ const directory = this.eventStore.requireDirectory(directoryId);
424
+ const identity = await this.generateWorkspaceIdentity(directory.id, directory.localPath);
425
+ const workspace = await this.eventStore.createWorkspace({
426
+ directoryId,
427
+ localPath: identity.localPath,
428
+ branchName: identity.branchName,
429
+ });
430
+ await this.notifyWorkspaceSetupStateChanged(workspace.id);
431
+
432
+ try {
433
+ await mkdir(path.dirname(identity.localPath), { recursive: true });
434
+ const baseRef = await this.resolveBaseRef(directory.localPath);
435
+ const result = await runGit(
436
+ ['worktree', 'add', '-b', identity.branchName, '--no-track', identity.localPath, baseRef],
437
+ directory.localPath,
438
+ );
439
+
440
+ if (result.exitCode !== 0) {
441
+ throw new Error(formatGitFailure(result) || 'Git could not create the workspace worktree');
442
+ }
443
+
444
+ await this.eventStore.markWorkspaceSetupCompleted(workspace.id);
445
+ await this.notifyWorkspaceSetupStateChanged(workspace.id);
446
+ const session = await this.eventStore.createSession(workspace.id);
447
+ await this.diffStore
448
+ ?.refreshWorkspaceGitSnapshot(workspace.id, identity.localPath)
449
+ .catch((error) => {
450
+ console.error('[workspace-manager] failed to refresh new workspace git snapshot', {
451
+ workspaceId: workspace.id,
452
+ error,
453
+ });
454
+ });
455
+ return { workspace: this.eventStore.requireWorkspace(workspace.id), session };
456
+ } catch (error) {
457
+ const message = error instanceof Error ? error.message : String(error);
458
+ await this.eventStore.markWorkspaceSetupFailed(workspace.id, message);
459
+ await this.notifyWorkspaceSetupStateChanged(workspace.id);
460
+ return { workspace: this.eventStore.requireWorkspace(workspace.id), session: null };
461
+ }
462
+ }
463
+
464
+ async renameWorkspaceBranch(workspaceId: string, nextBranchName: string) {
465
+ const workspace = this.eventStore.requireWorkspace(workspaceId);
466
+ if (workspace.reviewState !== 'in_progress' || workspace.pullRequest !== undefined) {
467
+ throw new Error('Cannot rename a workspace branch after PR creation');
468
+ }
469
+
470
+ const branchName = sanitizeBranchName(nextBranchName);
471
+ if (!branchName) throw new Error('Branch name is required');
472
+ if (workspace.branchName === branchName) return workspace;
473
+
474
+ const previousBranchName = workspace.branchName;
475
+ const directory = this.eventStore.requireDirectory(workspace.directoryId);
476
+ const currentBranch = await runGit(['branch', '--show-current'], workspace.localPath);
477
+ if (currentBranch.stdout.trim() !== previousBranchName) {
478
+ throw new Error('Workspace worktree is not on the expected branch');
479
+ }
480
+
481
+ if (
482
+ (await branchHasUpstream(workspace.localPath)) ||
483
+ (await remoteBranchExists(directory.localPath, workspace.branchName))
484
+ ) {
485
+ throw new Error('Cannot rename a workspace branch after it has been pushed');
486
+ }
487
+
488
+ if (!(await isValidBranchName(directory.localPath, branchName))) {
489
+ throw new Error('Branch name is not valid');
490
+ }
491
+
492
+ if (
493
+ this.eventStore
494
+ .listWorkspacesByDirectory(directory.id)
495
+ .some((candidate) => candidate.id !== workspace.id && candidate.branchName === branchName)
496
+ ) {
497
+ throw new Error('Workspace branch is already in use for this directory');
498
+ }
499
+
500
+ const localBranches = await getExistingLocalBranches(directory.localPath);
501
+ if (localBranches.has(branchName)) {
502
+ throw new Error('A local branch with this name already exists');
503
+ }
504
+
505
+ const result = await runGit(['branch', '-m', branchName], workspace.localPath);
506
+ if (result.exitCode !== 0) {
507
+ throw new Error(formatGitFailure(result) || 'Git could not rename the workspace branch');
508
+ }
509
+
510
+ try {
511
+ await this.eventStore.setWorkspaceBranch(workspace.id, branchName);
512
+ } catch (error) {
513
+ const rollback = await runGit(['branch', '-m', workspace.branchName], workspace.localPath);
514
+ if (rollback.exitCode !== 0) {
515
+ console.error('[workspace-manager] failed to rollback workspace branch rename', {
516
+ workspaceId: workspace.id,
517
+ fromBranchName: branchName,
518
+ toBranchName: workspace.branchName,
519
+ error: formatGitFailure(rollback),
520
+ });
521
+ }
522
+ throw error;
523
+ }
524
+
525
+ await this.diffStore?.refreshWorkspaceGitSnapshot(workspace.id, workspace.localPath);
526
+ return this.eventStore.requireWorkspace(workspace.id);
527
+ }
528
+
529
+ async continueWorkspaceOnNewBranch(workspaceId: string) {
530
+ const workspace = this.eventStore.requireWorkspace(workspaceId);
531
+ if (workspace.setupState !== 'ready') throw new Error('Workspace is not ready');
532
+ if (workspace.reviewState !== 'done' && workspace.reviewState !== 'closed') {
533
+ throw new Error('Workspace can only continue after its pull request is merged or closed');
534
+ }
535
+
536
+ const previousBranchName = workspace.branchName;
537
+ const previousPullRequest = workspace.pullRequest;
538
+ const previousReviewState = workspace.reviewState;
539
+ const directory = this.eventStore.requireDirectory(workspace.directoryId);
540
+ const currentBranch = await runGit(['branch', '--show-current'], workspace.localPath);
541
+ if (currentBranch.stdout.trim() !== previousBranchName) {
542
+ throw new Error('Workspace worktree is not on the expected branch');
543
+ }
544
+
545
+ const baseRef = await this.resolveBaseRef(directory.localPath);
546
+ const branchName = await this.generateContinuationBranchName(
547
+ directory.id,
548
+ directory.localPath,
549
+ previousBranchName,
550
+ );
551
+ const checkout = await runGit(
552
+ ['checkout', '--no-track', '-b', branchName, baseRef],
553
+ workspace.localPath,
554
+ );
555
+ if (checkout.exitCode !== 0) {
556
+ throw new Error(formatGitFailure(checkout) || 'Git could not create the continuation branch');
557
+ }
558
+
559
+ try {
560
+ await this.eventStore.setWorkspaceBranch(workspace.id, branchName);
561
+ await this.eventStore.clearWorkspacePullRequest(workspace.id);
562
+ await this.eventStore.setWorkspaceReviewState(workspace.id, 'in_progress');
563
+ } catch (error) {
564
+ console.error('[workspace-manager] continuation branch created but metadata update failed', {
565
+ workspaceId: workspace.id,
566
+ branchName,
567
+ error,
568
+ });
569
+ const checkoutPrevious = await runGit(['checkout', previousBranchName], workspace.localPath);
570
+ if (checkoutPrevious.exitCode !== 0) {
571
+ console.error('[workspace-manager] failed to rollback continuation checkout', {
572
+ workspaceId: workspace.id,
573
+ branchName,
574
+ error: formatGitFailure(checkoutPrevious),
575
+ });
576
+ } else {
577
+ const deleteBranch = await runGit(['branch', '-D', branchName], workspace.localPath);
578
+ if (deleteBranch.exitCode !== 0) {
579
+ console.error('[workspace-manager] failed to delete rolled-back continuation branch', {
580
+ workspaceId: workspace.id,
581
+ branchName,
582
+ error: formatGitFailure(deleteBranch),
583
+ });
584
+ }
585
+ }
586
+ try {
587
+ if (this.eventStore.requireWorkspace(workspace.id).branchName !== previousBranchName) {
588
+ await this.eventStore.setWorkspaceBranch(workspace.id, previousBranchName);
589
+ }
590
+ if (previousPullRequest) {
591
+ await this.eventStore.observeWorkspacePullRequest(workspace.id, previousPullRequest);
592
+ }
593
+ await this.eventStore.setWorkspaceReviewState(workspace.id, previousReviewState);
594
+ } catch (rollbackError) {
595
+ console.error('[workspace-manager] failed to rollback continuation metadata', {
596
+ workspaceId: workspace.id,
597
+ branchName,
598
+ error: rollbackError,
599
+ });
600
+ }
601
+ throw error;
602
+ }
603
+
604
+ this.prManager?.clearWorkspaceGitHubSnapshot(workspace.id);
605
+
606
+ await this.diffStore
607
+ ?.refreshWorkspaceGitSnapshot(workspace.id, workspace.localPath)
608
+ .catch((error) => {
609
+ console.error('[workspace-manager] failed to refresh continued workspace git snapshot', {
610
+ workspaceId: workspace.id,
611
+ error,
612
+ });
613
+ });
614
+
615
+ if (this.prManager) {
616
+ this.prManager.clearWorkspaceGitHubSnapshot(workspace.id);
617
+ await this.refreshWorkspacePrStage(workspace.id, { force: true }).catch((error) => {
618
+ console.error('[workspace-manager] failed to refresh continued workspace PR snapshot', {
619
+ workspaceId: workspace.id,
620
+ error,
621
+ });
622
+ });
623
+ }
624
+
625
+ return this.eventStore.requireWorkspace(workspace.id);
626
+ }
627
+ }
@@ -0,0 +1,10 @@
1
+ import type { WorkspaceRecord } from './event';
2
+
3
+ export function shouldPollActiveWorkspace(workspace: WorkspaceRecord) {
4
+ return (
5
+ workspace.visibilityState === 'active' &&
6
+ workspace.setupState === 'ready' &&
7
+ workspace.reviewState !== 'done' &&
8
+ workspace.reviewState !== 'closed'
9
+ );
10
+ }