@sma1lboy/rove 0.9.238 → 0.9.239

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 (237) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/{chunk-77w83wgh.js → chunk-0k91029d.js} +1 -1
  3. package/dist/cli/chunk-0mj358p5.js +3 -0
  4. package/dist/cli/chunk-0n7w8t48.js +2 -0
  5. package/dist/cli/{chunk-grt1e2s8.js → chunk-0wrh5s5y.js} +2 -2
  6. package/dist/cli/{chunk-nntg9d85.js → chunk-0y4qgnby.js} +1 -1
  7. package/dist/cli/chunk-1brfxbvg.js +4 -0
  8. package/dist/cli/{chunk-bhqracn8.js → chunk-20qm75rb.js} +1 -1
  9. package/dist/cli/chunk-21fm5tks.js +2 -0
  10. package/dist/cli/{chunk-bkbmqec2.js → chunk-28zg6p31.js} +1 -1
  11. package/dist/cli/chunk-2andp9gs.js +2 -0
  12. package/dist/cli/{chunk-r2pztgm6.js → chunk-2bgmby1d.js} +1 -1
  13. package/dist/cli/{chunk-hk8mc43r.js → chunk-2s2xy444.js} +5 -5
  14. package/dist/cli/chunk-2vgc5cyj.js +2 -0
  15. package/dist/cli/chunk-2x9yc5nx.js +2 -0
  16. package/dist/cli/chunk-30kjq5m7.js +2 -0
  17. package/dist/cli/{chunk-mkksdcsw.js → chunk-3342qzve.js} +1 -1
  18. package/dist/cli/chunk-3aqhytyy.js +3 -0
  19. package/dist/cli/chunk-3c58659p.js +2 -0
  20. package/dist/cli/chunk-3d1hjrq0.js +2 -0
  21. package/dist/cli/chunk-41x1hrqe.js +3 -0
  22. package/dist/cli/{chunk-mhg40es1.js → chunk-4hestsjp.js} +1 -1
  23. package/dist/cli/{chunk-s1p650mm.js → chunk-53cyns0f.js} +1 -1
  24. package/dist/cli/chunk-576r5nht.js +5 -0
  25. package/dist/cli/{chunk-acw32w13.js → chunk-5akk3wap.js} +6 -5
  26. package/dist/cli/chunk-7cce0st1.js +3 -0
  27. package/dist/cli/{chunk-zyd6k6ak.js → chunk-7q43tysm.js} +1 -1
  28. package/dist/cli/chunk-8bn6eg67.js +8 -0
  29. package/dist/cli/chunk-8rf7nzan.js +4 -0
  30. package/dist/cli/chunk-96cjpssp.js +3 -0
  31. package/dist/cli/{chunk-bs7v83x0.js → chunk-9aydqazr.js} +1 -1
  32. package/dist/cli/{chunk-7txq91d9.js → chunk-9jsm6h5y.js} +1 -1
  33. package/dist/cli/{chunk-pz907kve.js → chunk-9w5g7frx.js} +1 -1
  34. package/dist/cli/{chunk-vnpqemb0.js → chunk-a7kq09ke.js} +1 -1
  35. package/dist/cli/chunk-acxznk3y.js +2 -0
  36. package/dist/cli/chunk-adkva3ep.js +6 -0
  37. package/dist/cli/{chunk-nvqdmx7q.js → chunk-ag3txfg2.js} +1 -1
  38. package/dist/cli/{chunk-2rg6aw59.js → chunk-atmaakwp.js} +1 -1
  39. package/dist/cli/chunk-axsm0gn5.js +3 -0
  40. package/dist/cli/chunk-b0ssvpht.js +3 -0
  41. package/dist/cli/chunk-b39sdtt0.js +3 -0
  42. package/dist/cli/{chunk-2yd128k1.js → chunk-b9q8c2qg.js} +6 -6
  43. package/dist/cli/{chunk-g56km26e.js → chunk-bn73kd6z.js} +1 -1
  44. package/dist/cli/chunk-c2m55b72.js +4 -0
  45. package/dist/cli/{chunk-b503z32q.js → chunk-c60qsnfw.js} +3 -3
  46. package/dist/cli/{chunk-ch0ehc06.js → chunk-cbc1h345.js} +1 -1
  47. package/dist/cli/{chunk-dnbh8hsm.js → chunk-cbjh43yc.js} +1 -1
  48. package/dist/cli/{chunk-pzbrj3gd.js → chunk-cmcn8e8x.js} +1 -1
  49. package/dist/cli/{chunk-cv1kaq8a.js → chunk-cp89n425.js} +5 -5
  50. package/dist/cli/chunk-cst86kt3.js +2 -0
  51. package/dist/cli/chunk-des00203.js +2 -0
  52. package/dist/cli/chunk-dgs0m8r4.js +3 -0
  53. package/dist/cli/chunk-dkgxz9hf.js +5 -0
  54. package/dist/cli/{chunk-gqphk56d.js → chunk-ekg3h5z3.js} +7 -7
  55. package/dist/cli/chunk-fert44x2.js +2 -0
  56. package/dist/cli/chunk-ff1h2qxd.js +2 -0
  57. package/dist/cli/{chunk-cv6r89jp.js → chunk-ffs26p85.js} +1 -1
  58. package/dist/cli/chunk-fft50thp.js +3 -0
  59. package/dist/cli/{chunk-hp32tbes.js → chunk-fg62y5fm.js} +1 -1
  60. package/dist/cli/{chunk-s9a974w9.js → chunk-fvmee0tr.js} +1 -1
  61. package/dist/cli/chunk-g4c4ffqp.js +20 -0
  62. package/dist/cli/{chunk-k7g060qr.js → chunk-g4j41mky.js} +2 -2
  63. package/dist/cli/{chunk-j6kataan.js → chunk-g5c5jytr.js} +1 -1
  64. package/dist/cli/{chunk-1bm6sryf.js → chunk-ga1pb0mr.js} +1 -1
  65. package/dist/cli/{chunk-dqndd97s.js → chunk-gkdfct7t.js} +2 -2
  66. package/dist/cli/chunk-gqydm0q8.js +2 -0
  67. package/dist/cli/chunk-gvrtrvnz.js +96 -0
  68. package/dist/cli/chunk-h2m7em1e.js +3 -0
  69. package/dist/cli/chunk-h33m6cc6.js +8 -0
  70. package/dist/cli/{chunk-ynbfqbn9.js → chunk-h3fckxn3.js} +1 -1
  71. package/dist/cli/chunk-h7y9v8k1.js +4 -0
  72. package/dist/cli/{chunk-32mv1yy6.js → chunk-h9cg0j3a.js} +1 -1
  73. package/dist/cli/{chunk-h4qv19v8.js → chunk-hbn1t161.js} +1 -1
  74. package/dist/cli/{chunk-mb1e73jm.js → chunk-hen7jj2h.js} +2 -2
  75. package/dist/cli/{chunk-3es6spp4.js → chunk-hq9tbzqa.js} +2 -2
  76. package/dist/cli/{chunk-snjte1rd.js → chunk-hr2xky15.js} +1 -1
  77. package/dist/cli/{chunk-s0snbj93.js → chunk-kb6xw0fw.js} +1 -1
  78. package/dist/cli/{chunk-8h0khkap.js → chunk-ker4971f.js} +2 -2
  79. package/dist/cli/{chunk-vyb5a2rh.js → chunk-kg9kmwt9.js} +1 -1
  80. package/dist/cli/chunk-ktzbg4jg.js +2 -0
  81. package/dist/cli/chunk-m4f5h05c.js +10 -0
  82. package/dist/cli/chunk-m6q44xc0.js +2 -0
  83. package/dist/cli/{chunk-hq2n27y1.js → chunk-mw0ysrpd.js} +1 -1
  84. package/dist/cli/{chunk-2cwb64fj.js → chunk-n5dea05t.js} +1 -1
  85. package/dist/cli/chunk-nc46gddg.js +3 -0
  86. package/dist/cli/{chunk-jhbc9nx2.js → chunk-nckmga7j.js} +1 -1
  87. package/dist/cli/chunk-nem2x959.js +2 -0
  88. package/dist/cli/chunk-ng12dprz.js +2 -0
  89. package/dist/cli/chunk-npwzmmv9.js +3 -0
  90. package/dist/cli/chunk-nzh30nty.js +4 -0
  91. package/dist/cli/{chunk-gqrh2gp1.js → chunk-p024scd4.js} +1 -1
  92. package/dist/cli/chunk-p18ehv9y.js +7 -0
  93. package/dist/cli/chunk-p6qr8sen.js +2 -0
  94. package/dist/cli/{chunk-3sg5v7cg.js → chunk-p83wf4zw.js} +2 -2
  95. package/dist/cli/{chunk-s278gjet.js → chunk-pdvyfz3n.js} +1 -1
  96. package/dist/cli/chunk-pe6wnsww.js +2 -0
  97. package/dist/cli/{chunk-z5fnv7nk.js → chunk-pqzbk1cz.js} +25 -23
  98. package/dist/cli/chunk-prqeddy7.js +3 -0
  99. package/dist/cli/chunk-pvm3fc44.js +2 -0
  100. package/dist/cli/chunk-qd5zgq91.js +10 -0
  101. package/dist/cli/chunk-qvfdqrbf.js +3 -0
  102. package/dist/cli/{chunk-2xsem13q.js → chunk-qzsahxd9.js} +1 -1
  103. package/dist/cli/{chunk-0wgheepg.js → chunk-rahv4nrm.js} +3 -3
  104. package/dist/cli/chunk-rqyaf0dw.js +4 -0
  105. package/dist/cli/chunk-s57vy3k3.js +2 -0
  106. package/dist/cli/{chunk-g2advs8t.js → chunk-sak1tphp.js} +1 -1
  107. package/dist/cli/{chunk-vdcn6h48.js → chunk-snhcvjdb.js} +1 -1
  108. package/dist/cli/chunk-ss8c3b25.js +3 -0
  109. package/dist/cli/{chunk-bav389wj.js → chunk-svm809bx.js} +1 -1
  110. package/dist/cli/chunk-t8v9rpdx.js +2 -0
  111. package/dist/cli/{chunk-j4xfsn9g.js → chunk-tbrkck2f.js} +1 -1
  112. package/dist/cli/chunk-tdhk4dz8.js +4 -0
  113. package/dist/cli/chunk-try1f2h3.js +3 -0
  114. package/dist/cli/{chunk-aj7fkrha.js → chunk-tsj1054w.js} +1 -1
  115. package/dist/cli/{chunk-t3wwsz29.js → chunk-tvk46rfs.js} +1 -1
  116. package/dist/cli/{chunk-4d54zgc7.js → chunk-twyda1p8.js} +2 -2
  117. package/dist/cli/{chunk-s1e0e9hc.js → chunk-vej49hnt.js} +2 -2
  118. package/dist/cli/chunk-w2sp489k.js +3 -0
  119. package/dist/cli/chunk-wfhnbnbw.js +2 -0
  120. package/dist/cli/{chunk-0wh2ff77.js → chunk-whbm14qr.js} +2 -2
  121. package/dist/cli/{chunk-ww4fbx8h.js → chunk-wtb8cycx.js} +2 -2
  122. package/dist/cli/chunk-wvmjdnhk.js +2 -0
  123. package/dist/cli/chunk-x9s14ppv.js +4 -0
  124. package/dist/cli/{chunk-dq2mh3b3.js → chunk-xv8fhxxm.js} +1 -1
  125. package/dist/cli/{chunk-85pk7c74.js → chunk-xx166cdv.js} +1 -1
  126. package/dist/cli/{chunk-ssfj9td0.js → chunk-y8tysjc2.js} +15 -13
  127. package/dist/cli/{chunk-y3k1accw.js → chunk-yexx8nec.js} +1 -1
  128. package/dist/cli/{chunk-9prawccj.js → chunk-yt15y085.js} +1 -1
  129. package/dist/cli/{chunk-n0mg67wn.js → chunk-ytxk6zqc.js} +1 -1
  130. package/dist/cli/chunk-yvjgwnb9.js +2 -0
  131. package/dist/cli/{chunk-n24dmy2r.js → chunk-yxt1y0n3.js} +9 -9
  132. package/dist/cli/chunk-ze0htjr5.js +2 -0
  133. package/dist/cli/chunk-zeb0sttx.js +2 -0
  134. package/dist/cli/chunk-znjcesdr.js +5 -0
  135. package/dist/cli/chunk-zsfyj36g.js +3 -0
  136. package/dist/cli/chunk-zt49bbg9.js +3 -0
  137. package/dist/cli/chunk-zt7wfnva.js +3 -0
  138. package/dist/cli/{chunk-6rvzzrd7.js → chunk-zx2n95qe.js} +1 -1
  139. package/dist/cli/{chunk-zwgns5ce.js → chunk-zxsbz3kk.js} +1 -1
  140. package/dist/cli/index.js +12 -10
  141. package/dist/cli/pty-host-node.mjs +880 -169
  142. package/dist/cli/rove-run.js +1 -1
  143. package/dist/cli/rove.js +6 -6
  144. package/dist/skills/rove/SKILL.md +1 -1
  145. package/dist/skills/rove/references/api-flags.md +5 -5
  146. package/dist/web-ui/assets/{harness-CQ-1WI4q.js → harness-BHiciz5A.js} +2 -2
  147. package/dist/web-ui/assets/{index-_ttAn6pY.js → index-BkxJISAI.js} +2 -2
  148. package/dist/web-ui/assets/{index-C4dLQEqf.css → index-nMJ42IGm.css} +1 -1
  149. package/dist/web-ui/index.html +2 -2
  150. package/dist/web-ui/origin-policy.mjs +1 -1
  151. package/dist/web-ui/pty-server.mjs +24 -10
  152. package/dist/web-ui/pty-session-lifecycle.mjs +9 -13
  153. package/package.json +6 -8
  154. package/dist/cli/chunk-05jej26n.js +0 -3
  155. package/dist/cli/chunk-079cyb2e.js +0 -4
  156. package/dist/cli/chunk-1265fmzk.js +0 -3
  157. package/dist/cli/chunk-1da3bqjc.js +0 -4
  158. package/dist/cli/chunk-1tx1s5v6.js +0 -2
  159. package/dist/cli/chunk-507zn8rs.js +0 -3
  160. package/dist/cli/chunk-53afdybj.js +0 -3
  161. package/dist/cli/chunk-544bwsss.js +0 -4
  162. package/dist/cli/chunk-67ev8k22.js +0 -2
  163. package/dist/cli/chunk-6s5mev2n.js +0 -4
  164. package/dist/cli/chunk-6x5vzzpx.js +0 -3
  165. package/dist/cli/chunk-7s1kx9ez.js +0 -2
  166. package/dist/cli/chunk-85mk6j0s.js +0 -3
  167. package/dist/cli/chunk-8hbtca1g.js +0 -3
  168. package/dist/cli/chunk-8pa1ph1s.js +0 -7
  169. package/dist/cli/chunk-9ek7xm94.js +0 -8
  170. package/dist/cli/chunk-9k47xr7m.js +0 -2
  171. package/dist/cli/chunk-9mtxxsb3.js +0 -2
  172. package/dist/cli/chunk-a1k2z44b.js +0 -2
  173. package/dist/cli/chunk-a3yyrabb.js +0 -2
  174. package/dist/cli/chunk-ahnk6zx3.js +0 -2
  175. package/dist/cli/chunk-bc18gat5.js +0 -4
  176. package/dist/cli/chunk-be757xzj.js +0 -3
  177. package/dist/cli/chunk-bw73t1zw.js +0 -5
  178. package/dist/cli/chunk-c2tevj9f.js +0 -2
  179. package/dist/cli/chunk-d1agt94n.js +0 -8
  180. package/dist/cli/chunk-dc31fzrm.js +0 -2
  181. package/dist/cli/chunk-dw853n4w.js +0 -3
  182. package/dist/cli/chunk-eawt4n4g.js +0 -2
  183. package/dist/cli/chunk-egx76ah2.js +0 -5
  184. package/dist/cli/chunk-ex1a2djb.js +0 -2
  185. package/dist/cli/chunk-f5e3dcxe.js +0 -2
  186. package/dist/cli/chunk-fwb72vzc.js +0 -2
  187. package/dist/cli/chunk-fxs82dsx.js +0 -4
  188. package/dist/cli/chunk-g3r1dwy9.js +0 -3
  189. package/dist/cli/chunk-ge30p4s5.js +0 -3
  190. package/dist/cli/chunk-gmgsxdrf.js +0 -10
  191. package/dist/cli/chunk-he76emdm.js +0 -2
  192. package/dist/cli/chunk-hgx20x94.js +0 -2
  193. package/dist/cli/chunk-hnfp317x.js +0 -2
  194. package/dist/cli/chunk-hq4b3fca.js +0 -3
  195. package/dist/cli/chunk-janvvpv5.js +0 -8
  196. package/dist/cli/chunk-jvxh93nz.js +0 -3
  197. package/dist/cli/chunk-k6nxyxyh.js +0 -3
  198. package/dist/cli/chunk-k8tspshr.js +0 -2
  199. package/dist/cli/chunk-md8k7c5w.js +0 -2
  200. package/dist/cli/chunk-mppda1wq.js +0 -3
  201. package/dist/cli/chunk-ppwpjm39.js +0 -3
  202. package/dist/cli/chunk-pvw2y93q.js +0 -25
  203. package/dist/cli/chunk-pw6yfj10.js +0 -3
  204. package/dist/cli/chunk-q4nehkj9.js +0 -2
  205. package/dist/cli/chunk-qagek3wg.js +0 -5
  206. package/dist/cli/chunk-r8xqvg26.js +0 -2
  207. package/dist/cli/chunk-rz8zs7j8.js +0 -3
  208. package/dist/cli/chunk-sb0ns0c7.js +0 -3
  209. package/dist/cli/chunk-tcj36cqg.js +0 -2
  210. package/dist/cli/chunk-vejgnmcp.js +0 -2
  211. package/dist/cli/chunk-vzqrj32e.js +0 -2
  212. package/dist/cli/chunk-wpsbyq4s.js +0 -2
  213. package/dist/cli/chunk-wtqxv2rv.js +0 -39
  214. package/dist/cli/chunk-y05d79az.js +0 -2
  215. package/dist/cli/chunk-y4048296.js +0 -4
  216. package/dist/cli/chunk-y8fqdnh3.js +0 -3
  217. package/dist/cli/chunk-ygd572ee.js +0 -4
  218. package/dist/cli/chunk-yj5pjxx2.js +0 -2
  219. package/dist/cli/chunk-zja9chrd.js +0 -4
  220. package/dist/cli/chunk-zwej00t0.js +0 -5
  221. package/dist/cli/kobe-run.js +0 -3
  222. package/dist/cli/kobe.js +0 -7
  223. package/dist/completions/kobe.bash +0 -25
  224. package/dist/completions/kobe.fish +0 -27
  225. package/dist/completions/kobe.zsh +0 -35
  226. /package/dist/cli/{chunk-hqbmzz4t.js → chunk-0422g8ac.js} +0 -0
  227. /package/dist/cli/{chunk-khj0apc7.js → chunk-2tfnscxk.js} +0 -0
  228. /package/dist/cli/{chunk-7q67dz4c.js → chunk-4250pw6r.js} +0 -0
  229. /package/dist/cli/{chunk-xsrcwcjc.js → chunk-5mhvjytn.js} +0 -0
  230. /package/dist/cli/{chunk-ef39ym8f.js → chunk-7bgbansg.js} +0 -0
  231. /package/dist/cli/{chunk-nh4wvyz3.js → chunk-atn06ncf.js} +0 -0
  232. /package/dist/cli/{chunk-h4n8ffqy.js → chunk-dmzg9zdc.js} +0 -0
  233. /package/dist/cli/{chunk-w25b7xxz.js → chunk-etfh8f4z.js} +0 -0
  234. /package/dist/cli/{chunk-hape5vwj.js → chunk-hpay0ax8.js} +0 -0
  235. /package/dist/cli/{chunk-f10n6063.js → chunk-pn5ygqn6.js} +0 -0
  236. /package/dist/cli/{chunk-rcyasw34.js → chunk-rxqdw6s5.js} +0 -0
  237. /package/dist/cli/{chunk-exfyqsdd.js → chunk-vjvkkrzc.js} +0 -0
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{connectIfRunning,connectOrStartDaemon}from"./chunk-wtqxv2rv.js";async function openDaemonSession(opts={}){let client=opts.mode==="require-running"?await connectIfRunning():await connectOrStartDaemon();if(!client)return null;return{client,close:()=>client.close()}}async function resolveActiveTaskId(client){let activeId=null,off=client.onChannel("active-task",(payload)=>{activeId=payload.taskId});try{await client.subscribe()}finally{off()}return activeId}
2
+ import{connectIfRunning,connectOrStartDaemon}from"./chunk-96cjpssp.js";async function openDaemonSession(opts={}){let client=opts.mode==="require-running"?await connectIfRunning():await connectOrStartDaemon();if(!client)return null;return{client,close:()=>client.close()}}async function resolveActiveTaskId(client){let activeId=null,off=client.onChannel("active-task",(payload)=>{activeId=payload.taskId});try{await client.subscribe()}finally{off()}return activeId}
3
3
  export{openDaemonSession,resolveActiveTaskId};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{parsePorcelain,pickPushedChanges,readWorktreeChanges,sameWorktreeChanges}from"./chunk-k6nxyxyh.js";import"./chunk-h4n8ffqy.js";import"./chunk-6xppe9bj.js";import"./chunk-40dgv828.js";import"./chunk-wqfp8d9w.js";export{sameWorktreeChanges,readWorktreeChanges,pickPushedChanges,parsePorcelain};
2
+ import{parsePorcelain,pickPushedChanges,readWorktreeChanges,sameWorktreeChanges}from"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-40dgv828.js";import"./chunk-wqfp8d9w.js";export{sameWorktreeChanges,readWorktreeChanges,pickPushedChanges,parsePorcelain};
@@ -1,7 +1,7 @@
1
1
  // @bun
2
- import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-hk8mc43r.js";import"./chunk-bav389wj.js";import{ensurePluginEnginesLoaded}from"./chunk-ynbfqbn9.js";import"./chunk-gqrh2gp1.js";import{openDaemonSession}from"./chunk-snjte1rd.js";import"./chunk-77w83wgh.js";import"./chunk-17e2tgyg.js";import"./chunk-ch0ehc06.js";import"./chunk-mppda1wq.js";import"./chunk-mhg40es1.js";import"./chunk-r2pztgm6.js";import"./chunk-1da3bqjc.js";import"./chunk-85mk6j0s.js";import"./chunk-xsrcwcjc.js";import"./chunk-nh4wvyz3.js";import"./chunk-qkehg2c1.js";import"./chunk-6rvzzrd7.js";import"./chunk-g56km26e.js";import"./chunk-n24dmy2r.js";import"./chunk-dnbh8hsm.js";import"./chunk-2apszxn2.js";import"./chunk-g2advs8t.js";import"./chunk-ygd572ee.js";import"./chunk-rcyasw34.js";import"./chunk-7q67dz4c.js";import"./chunk-jhbc9nx2.js";import"./chunk-exfyqsdd.js";import"./chunk-s278gjet.js";import{ApiError,splitDaemonCode}from"./chunk-f7zjggfv.js";import"./chunk-egx76ah2.js";import"./chunk-hape5vwj.js";import"./chunk-j6kataan.js";import"./chunk-ssfj9td0.js";import"./chunk-zwej00t0.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-w25b7xxz.js";import"./chunk-6xppe9bj.js";import"./chunk-jvxh93nz.js";import"./chunk-wtqxv2rv.js";import"./chunk-pz907kve.js";import"./chunk-nvqdmx7q.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-y3k1accw.js";import"./chunk-bw73t1zw.js";import"./chunk-7kysxgbq.js";import"./chunk-2xsem13q.js";import"./chunk-xy8be792.js";import"./chunk-05jej26n.js";import"./chunk-be757xzj.js";import"./chunk-32mv1yy6.js";import"./chunk-40dgv828.js";import"./chunk-mkksdcsw.js";import"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-vdcn6h48.js";import"./chunk-ge30p4s5.js";import"./chunk-nhakrm1f.js";import"./chunk-pxk2c2vj.js";import"./chunk-qagek3wg.js";import"./chunk-544bwsss.js";import"./chunk-hqbmzz4t.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";function emit(value,pretty){let warning=takeIdentityWarning(),payload=warning&&value&&typeof value==="object"&&!Array.isArray(value)?{...value,identityWarning:warning}:value,text=pretty?JSON.stringify(payload,null,2):JSON.stringify(payload);process.stdout.write(`${text}
2
+ import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-2s2xy444.js";import"./chunk-svm809bx.js";import{ensurePluginEnginesLoaded}from"./chunk-h3fckxn3.js";import"./chunk-p024scd4.js";import{openDaemonSession}from"./chunk-hr2xky15.js";import"./chunk-0k91029d.js";import"./chunk-17e2tgyg.js";import"./chunk-cbc1h345.js";import"./chunk-qvfdqrbf.js";import"./chunk-4hestsjp.js";import"./chunk-2bgmby1d.js";import"./chunk-rqyaf0dw.js";import"./chunk-41x1hrqe.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-zx2n95qe.js";import"./chunk-bn73kd6z.js";import"./chunk-yxt1y0n3.js";import"./chunk-cbjh43yc.js";import"./chunk-2apszxn2.js";import"./chunk-sak1tphp.js";import"./chunk-x9s14ppv.js";import"./chunk-rxqdw6s5.js";import"./chunk-4250pw6r.js";import"./chunk-nckmga7j.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-dkgxz9hf.js";import"./chunk-hpay0ax8.js";import"./chunk-g5c5jytr.js";import"./chunk-y8tysjc2.js";import"./chunk-576r5nht.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-6xppe9bj.js";import{ApiError,splitDaemonCode}from"./chunk-f7zjggfv.js";import"./chunk-zsfyj36g.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-yexx8nec.js";import"./chunk-znjcesdr.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import"./chunk-7cce0st1.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-pxk2c2vj.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";function emit(value,pretty){let warning=takeIdentityWarning(),payload=warning&&value&&typeof value==="object"&&!Array.isArray(value)?{...value,identityWarning:warning}:value,text=pretty?JSON.stringify(payload,null,2):JSON.stringify(payload);process.stdout.write(`${text}
3
3
  `)}function fail(message,code,exitCode=1,data){process.stderr.write(`${JSON.stringify({error:{message,code,...data}})}
4
4
  `),process.exit(exitCode)}function makeContext(verb,flags,client,runtime){return{args:new VerbArgs(verb,flags),client,runtime}}var USAGE_ERROR_CODES=new Set(["BAD_VERB","UNKNOWN_VERB","BAD_FLAG","MISSING_FLAG","MISSING_VERB","BAD_DAEMON"]);function toApiError(err){if(err instanceof ApiError)return err;let message=errorMessage(err);if(/task not found/i.test(message))return new ApiError(message,"TASK_NOT_FOUND",{hint:"that task id does not exist (deleted or mistyped) \u2014 list live tasks and retry with a real id",nextCommandArgs:["api","list"]});if(/unknown daemon request:/i.test(message))return versionSkewError(message);let coded=splitDaemonCode(message);if(coded)return new ApiError(coded.rest,coded.code);return new ApiError(message,"RPC_ERROR")}function versionSkewError(message){return new ApiError(message,"DAEMON_VERSION_SKEW",{hint:"the running daemon is a different build than this CLI, so it does not serve this verb \u2014 restart the daemon to pick up this build, then retry (if the verb is gone for good, `rove api schema` lists what this daemon actually serves)",nextCommandArgs:["daemon","restart"]})}async function invokeVerb(verbName,argv,deps){let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);let booleanFlags=new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name)),parsed=parseFlags(argv,booleanFlags);validateAgainstSpec(verb,parsed.flags);try{return await verb.handler(makeContext(verb,parsed.flags,deps.client,deps.runtime??defaultApiRuntime))}catch(err){throw toApiError(err)}}async function runApiSubcommand(argv){let[verbName,...rest]=argv;if(!verbName||verbName==="--help"||verbName==="-h"||verbName==="help"){if(!verbName)fail(apiUsage(),"MISSING_VERB",2);process.stdout.write(`${apiUsage()}
5
5
  `);return}ensurePluginEnginesLoaded();let verb=findVerb(verbName);if(!verb){let err=unknownVerbError(verbName);fail(`${err.message}
6
6
  ${apiUsage()}`,err.code,2,err.data)}let booleanFlags=new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name)),parsed;try{parsed=parseFlags(rest,booleanFlags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}if(parsed.help){process.stdout.write(`${verbHelp(verb)}
7
- `);return}try{validateAgainstSpec(verb,parsed.flags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}let session=null;if(!verb.offline)try{session=await openDaemonSession()}catch(err){fail(`could not reach or start the Rove daemon: ${errorMessage(err)}`,"BAD_DAEMON",2,{hint:"check whether the daemon is up (and why it is not), then retry the same command",nextCommandArgs:["daemon","status"]})}try{let{assertLocalTask}=await import("./chunk-eawt4n4g.js");await assertLocalTask(parsed.flags.get("task-id"));let result=await verb.handler(makeContext(verb,parsed.flags,session?.client??null,defaultApiRuntime));emit(result,parsed.pretty)}catch(err){if(err instanceof ApiError&&err.code==="PARTIAL_FANOUT")emit(err.data,parsed.pretty),session?.close(),process.exit(3);let apiErr=toApiError(err);fail(apiErr.message,apiErr.code,USAGE_ERROR_CODES.has(apiErr.code)?2:1,apiErr.data)}finally{session?.close()}}export{verbSchema,verbHelp,validateAgainstSpec,toApiError,schemaIndex,runApiSubcommand,parseFlags,parseAgentsSpec,invokeVerb,fullSchema,findVerb,deliverPrompt,defaultApiRuntime,buildCountPlan,apiUsage,VerbArgs,VERB_GROUPS,VERBS,ApiError,API_VERBS,API_SCHEMA_VERSION};
7
+ `);return}try{validateAgainstSpec(verb,parsed.flags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}let session=null;if(!verb.offline)try{session=await openDaemonSession()}catch(err){fail(`could not reach or start the Rove daemon: ${errorMessage(err)}`,"BAD_DAEMON",2,{hint:"check whether the daemon is up (and why it is not), then retry the same command",nextCommandArgs:["daemon","status"]})}try{let{assertLocalTask}=await import("./chunk-21fm5tks.js");await assertLocalTask(parsed.flags.get("task-id"));let result=await verb.handler(makeContext(verb,parsed.flags,session?.client??null,defaultApiRuntime));emit(result,parsed.pretty)}catch(err){if(err instanceof ApiError&&err.code==="PARTIAL_FANOUT")emit(err.data,parsed.pretty),session?.close(),process.exit(3);let apiErr=toApiError(err);fail(apiErr.message,apiErr.code,USAGE_ERROR_CODES.has(apiErr.code)?2:1,apiErr.data)}finally{session?.close()}}export{verbSchema,verbHelp,validateAgainstSpec,toApiError,schemaIndex,runApiSubcommand,parseFlags,parseAgentsSpec,invokeVerb,fullSchema,findVerb,deliverPrompt,defaultApiRuntime,buildCountPlan,apiUsage,VerbArgs,VERB_GROUPS,VERBS,ApiError,API_VERBS,API_SCHEMA_VERSION};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{readFileSync,statSync}from"fs";import{isAbsolute,join,resolve}from"path";var DEFAULT_BASE_REF_CANDIDATES=["origin/main","origin/master","main","master"];function mtime(path){let st=statSync(path,{throwIfNoEntry:!1});return st?st.mtimeMs:null}function readText(path){try{return readFileSync(path,"utf8")}catch{return null}}function resolveGitDirs(worktreePath){let dotGit=join(worktreePath,".git"),st=statSync(dotGit,{throwIfNoEntry:!1});if(!st)return null;let gitDir=dotGit;if(!st.isDirectory()){let pointer=readText(dotGit)?.match(/^gitdir:\s*(.+)$/m)?.[1]?.trim();if(!pointer)return null;gitDir=isAbsolute(pointer)?pointer:resolve(worktreePath,pointer)}let common=readText(join(gitDir,"commondir"))?.trim(),commonDir=common?isAbsolute(common)?common:resolve(gitDir,common):gitDir;return{gitDir,commonDir}}function looseRefPaths(dirs,ref){let rel=ref.startsWith("refs/")?ref:`refs/remotes/${ref}`,alt=ref.startsWith("refs/")?null:`refs/heads/${ref}`,names=alt?[rel,alt]:[rel],out=[];for(let name of names)if(out.push(join(dirs.gitDir,name)),dirs.commonDir!==dirs.gitDir)out.push(join(dirs.commonDir,name));return out}function readRefSha(dirs,ref){for(let path of looseRefPaths(dirs,ref)){let raw=readText(path)?.trim();if(raw&&/^[0-9a-f]{40,64}$/.test(raw))return raw}let packed=readText(join(dirs.commonDir,"packed-refs"));if(!packed)return null;let wanted=new Set(looseRefPaths(dirs,ref).map((p)=>p.replace(/^.*?(refs\/)/,"$1")));for(let line of packed.split(`
2
+ import{readFileSync,statSync}from"fs";import{isAbsolute,join,resolve}from"path";var DEFAULT_BASE_REF_CANDIDATES=["origin/main","origin/master","main","master"];function mtime(path){let st=statSync(path,{throwIfNoEntry:!1});return st?st.mtimeMs:null}function readText(path){try{return readFileSync(path,"utf8")}catch{return null}}function resolveGitDirs(worktreePath){let dotGit=join(worktreePath,".git"),st=statSync(dotGit,{throwIfNoEntry:!1});if(!st)return null;let gitDir=dotGit;if(!st.isDirectory()){let pointer=readText(dotGit)?.match(/^gitdir:\s*(.+)$/m)?.[1]?.trim();if(!pointer)return null;gitDir=isAbsolute(pointer)?pointer:resolve(worktreePath,pointer)}let common=readText(join(gitDir,"commondir"))?.trim(),commonDir=common?isAbsolute(common)?common:resolve(gitDir,common):gitDir;return{gitDir,commonDir}}function refNameCandidates(ref){if(ref.startsWith("refs/"))return[ref];return[`refs/remotes/${ref}`,`refs/heads/${ref}`]}function looseRefPaths(dirs,ref){let out=[];for(let name of refNameCandidates(ref))if(out.push(join(dirs.gitDir,name)),dirs.commonDir!==dirs.gitDir)out.push(join(dirs.commonDir,name));return out}function readRefSha(dirs,ref){for(let path of looseRefPaths(dirs,ref)){let raw=readText(path)?.trim();if(raw&&/^[0-9a-f]{40,64}$/.test(raw))return raw}let packed=readText(join(dirs.commonDir,"packed-refs"));if(!packed)return null;let wanted=new Set(refNameCandidates(ref));for(let line of packed.split(`
3
3
  `)){if(!line||line.startsWith("#")||line.startsWith("^"))continue;let[sha,name]=line.split(" ",2);if(sha&&name&&wanted.has(name.trim()))return sha}return null}function readHeadSha(dirs){let head=readText(join(dirs.gitDir,"HEAD"))?.trim();if(!head)return null;if(/^[0-9a-f]{40,64}$/.test(head))return head;let ref=head.match(/^ref:\s*(.+)$/)?.[1]?.trim();return ref?readRefSha(dirs,ref):null}function worktreeFingerprint(worktreePath,baseRef){try{let dirs=resolveGitDirs(worktreePath);if(!dirs)return null;let head=readText(join(dirs.gitDir,"HEAD"))?.trim();if(!head)return null;let parts=[head,mtime(worktreePath),mtime(join(dirs.gitDir,"index")),mtime(join(dirs.gitDir,"HEAD")),mtime(join(dirs.gitDir,"FETCH_HEAD")),mtime(join(dirs.commonDir,"FETCH_HEAD")),mtime(join(dirs.commonDir,"packed-refs"))],headRef=head.match(/^ref:\s*(.+)$/)?.[1]?.trim();if(headRef)for(let path of looseRefPaths(dirs,headRef))parts.push(mtime(path));parts.push(mtime(join(dirs.commonDir,"refs/remotes/origin/HEAD")));for(let ref of baseRef?[baseRef,...DEFAULT_BASE_REF_CANDIDATES]:DEFAULT_BASE_REF_CANDIDATES)for(let path of looseRefPaths(dirs,ref))parts.push(mtime(path));return parts.join("|")}catch{return null}}
4
4
  export{DEFAULT_BASE_REF_CANDIDATES,resolveGitDirs,readRefSha,readHeadSha,worktreeFingerprint};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{readLastActiveTaskId,writeLastActiveTaskId}from"./chunk-n5dea05t.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{writeLastActiveTaskId,readLastActiveTaskId};
@@ -0,0 +1,10 @@
1
+ // @bun
2
+ import{DIRTY_WORKTREE_CODE,canonicalize,describeDirtyWorktreeWork,isRoveManagedPath,isUnderManagedWorktreesRoot,managedWorktreeRootForPath,remoteManagedRootForPath,remoteWorktreePathFor,requireAbsolute,worktreePathFor}from"./chunk-qvfdqrbf.js";import{execHostForRepo,execHostForWorktreePath}from"./chunk-cbjh43yc.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{getRemoteRepoConfig}from"./chunk-h9cg0j3a.js";import path3 from"path";function parseDirtyPaths(stdout){return stdout.split(`
3
+ `).filter((line)=>line.length>3).map((line)=>line.slice(3).trim()).filter((line)=>line.length>0)}function isDirtyOutput(stdout){return parseDirtyPaths(stdout).length>0}var defaultExecDeps={execForRepo:execHostForRepo,execForPath:execHostForWorktreePath,remoteBasePath(repoKey){return getRemoteRepoConfig(repoKey)?.basePath??null}};class GitCommandError extends Error{args;cwd;exitCode;stdout;stderr;constructor(args,cwd,result){super(`git ${args.join(" ")} (cwd=${cwd}) exited with code ${result.exitCode}: ${result.stderr.trim()||result.stdout.trim()}`);this.name="GitCommandError",this.args=args,this.cwd=cwd,this.exitCode=result.exitCode,this.stdout=result.stdout,this.stderr=result.stderr}}var MAX_IGNORED_ENTRY_KB=65536;function parseIgnoredPaths(stdoutZ){return stdoutZ.split("\x00").filter((entry)=>entry.startsWith("!! ")).map((entry)=>entry.slice(3)).filter((p)=>p.length>0)}var DU_ARGV_BUDGET_BYTES=98304;function parseDuKb(stdout){let sizes=new Map;for(let line of stdout.split(`
4
+ `)){let m=/^(\d+)\s+(.+)$/.exec(line.trim());if(m?.[1]&&m[2])sizes.set(m[2],Number.parseInt(m[1],10))}return sizes}async function duKb(exec,worktreePath,paths){let sizes=new Map,batch=[],bytes=0,flush=async()=>{if(batch.length===0)return;let du=await exec.run(["du","-sk","--",...batch],{cwd:worktreePath});for(let[p,kb]of parseDuKb(du.stdout))sizes.set(p,kb);batch.length=0,bytes=0};for(let p of paths){if(p.includes(`
5
+ `)){let one=await exec.run(["du","-sk","--",p],{cwd:worktreePath}),kb=/^\s*(\d+)/.exec(one.stdout)?.[1];if(one.exitCode===0&&kb)sizes.set(p,Number.parseInt(kb,10));continue}if(bytes+p.length+1>DU_ARGV_BUDGET_BYTES)await flush();batch.push(p),bytes+=p.length+1}return await flush(),sizes}async function smallIgnoredPaths(exec,worktreePath){try{let status=await exec.run(["git","status","--porcelain","-z","--ignored"],{cwd:worktreePath,env:READ_ONLY_GIT_ENV});if(status.exitCode!==0)return"unknown";let paths=parseIgnoredPaths(status.stdout);if(paths.length===0)return[];let sizes=await duKb(exec,worktreePath,paths);return paths.filter((p)=>{let kb=sizes.get(p);return kb!==void 0&&kb<=MAX_IGNORED_ENTRY_KB})}catch{return"unknown"}}async function gitlinkPaths(git,tree){let out=await git(["ls-tree","-r",tree]);if(out.exitCode!==0)return[];return out.stdout.split(`
6
+ `).filter((line)=>line.startsWith("160000 ")).map((line)=>line.slice(line.indexOf("\t")+1)).filter((p)=>p.length>0)}function branchRefSlug(branch){return(branch??"").replace(/[\u0000-\u0020\u007f~^:?*[\\/]+/g,"-").replace(/@\{/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]+|[-.]+$/g,"")||"detached"}function salvageRef(branch,now){let stamp=now.toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");return`refs/rove/salvage/${branchRefSlug(branch)}-${stamp}`}async function createSalvageRef(git,preferred,commit){for(let attempt=1;attempt<=50;attempt++){let ref=attempt===1?preferred:`${preferred}-${attempt}`;if((await git(["update-ref",ref,commit,""])).exitCode===0)return ref}return null}async function salvageWorktree(deps,exec,worktreePath,now=new Date){let git=(args)=>deps.runGit(exec,args,{cwd:worktreePath,allowFail:!0});try{let status=await git(["status","--porcelain"]);if(status.exitCode!==0)return null;let probe=await smallIgnoredPaths(exec,worktreePath),ignored=probe==="unknown"?[]:probe;if(status.stdout.trim().length===0&&ignored.length===0)return null;let indexPath=(await git(["rev-parse","--git-path","rove-salvage-index"])).stdout.trim();if(!indexPath)return null;let withIndex=(args)=>deps.runGit(exec,args,{cwd:worktreePath,allowFail:!0,env:{GIT_INDEX_FILE:indexPath}}),head=(await git(["rev-parse","HEAD"])).stdout.trim(),branch=(await git(["rev-parse","--abbrev-ref","HEAD"])).stdout.trim();try{if(head&&(await withIndex(["read-tree",head])).exitCode!==0)return null;if((await withIndex(["add","-A"])).exitCode!==0)return null;if(ignored.length>0)await withIndex(["add","-f","--",...ignored]);let tree=(await withIndex(["write-tree"])).stdout.trim();if(!tree)return null;let message=`rove salvage: force-removed worktree ${worktreePath}`,commit=(await withIndex(head?["commit-tree",tree,"-p",head,"-m",message]:["commit-tree",tree,"-m",message])).stdout.trim();if(!commit)return null;let ref=await createSalvageRef(git,salvageRef(branch&&branch!=="HEAD"?branch:null,now),commit);if(!ref)return null;return{ref,commit,uncaptured:await gitlinkPaths(git,tree)}}finally{await exec.run(["rm","-f",indexPath],{cwd:worktreePath}).catch(()=>{return})}}catch{return null}}async function anchorBranchTip(deps,exec,repo,branch,now=new Date){if(!branch||branch==="HEAD")return null;let git=(args)=>deps.runGit(exec,args,{cwd:repo,allowFail:!0});try{let tipOut=await git(["rev-parse","--verify",`refs/heads/${branch}`]),tip=tipOut.stdout.trim();if(tipOut.exitCode!==0||!tip)return null;let holders=await git(["for-each-ref","--contains",tip,"--format=%(refname)"]);if(holders.exitCode===0){if(holders.stdout.split(`
7
+ `).map((l)=>l.trim()).filter((l)=>l.length>0&&l!==`refs/heads/${branch}`).length>0)return null}let ref=salvageRef(branch,now);if((await git(["update-ref",ref,tip])).exitCode!==0)return null;return{ref,commit:tip,uncaptured:[]}}catch{return null}}async function branchExists(deps,ctx,branch){return(await deps.runGit(ctx.exec,["show-ref","--verify","--quiet",`refs/heads/${branch}`],{cwd:ctx.dir,allowFail:!0,readOnly:!0})).exitCode===0}async function deleteBranchIn(deps,exec,repo,branch,force){if(!branch||branch==="HEAD")return{deleted:!1,reason:"no branch to delete"};let out=await deps.runGit(exec,["branch",force?"-D":"-d",branch],{cwd:repo,allowFail:!0});if(out.exitCode===0)return{deleted:!0};if(!await branchExists(deps,{exec,dir:repo,remote:exec.isRemote},branch))return{deleted:!0};return{deleted:!1,reason:out.stderr.trim()||out.stdout.trim()||`git branch exited ${out.exitCode}`}}async function deleteBranchAnchored(deps,exec,repo,branch,opts){if(opts.force)opts.onAnchor?.(await anchorBranchTip(deps,exec,repo,branch));return await deleteBranchIn(deps,exec,repo,branch,opts.force)}async function branchHasUpstream(deps,worktreePath,branch){return(await deps.runGit(deps.execAt(worktreePath),["for-each-ref","--format=%(upstream)",`refs/heads/${branch}`],{cwd:worktreePath,readOnly:!0})).stdout.trim().length>0}async function hasLocalBranch(deps,worktreePath,branch){return(await deps.runGit(deps.execAt(worktreePath),["show-ref","--verify","--quiet",`refs/heads/${branch}`],{cwd:worktreePath,allowFail:!0,readOnly:!0})).exitCode===0}async function renameBranch(deps,worktreePath,from,to){let exec=deps.execAt(worktreePath);if(from===to)return;let repo=await deps.findRepoFor(exec,worktreePath);if(!repo)throw Error(`renameBranch(): ${worktreePath} is not a git worktree`);let out=await deps.runGit(exec,["branch","-m",from,to],{cwd:repo,allowFail:!0});if(out.exitCode===0)return;let ctx={exec,dir:repo,remote:exec.isRemote};if(!await branchExists(deps,ctx,from)&&await branchExists(deps,ctx,to))return;throw new GitCommandError(["branch","-m",from,to],repo,out)}import fs from"fs";import path from"path";async function mapWithLimit(items,limit,fn){let results=Array(items.length),next=0,worker=async()=>{for(;;){let i=next++;if(i>=items.length)return;results[i]=await fn(items[i])}},width=Math.max(1,Math.min(limit,items.length));return await Promise.all(Array.from({length:width},worker)),results}var PROBE_CONCURRENCY=6;function parseWorktreeListPorcelain(out){let records=[],current=null;for(let rawLine of out.split(`
8
+ `)){let line=rawLine.replace(/\r$/,"");if(line===""){if(current)records.push(current);current=null;continue}if(!current)current={};if(line.startsWith("worktree "))current.path=line.slice(9);else if(line.startsWith("HEAD "))current.head=line.slice(5);else if(line.startsWith("branch ")){let ref=line.slice(7);current.branch=ref.startsWith("refs/heads/")?ref.slice(11):ref}else if(line==="detached")current.detached=!0;else if(line==="bare")current.bare=!0}if(current)records.push(current);return records}async function lastActivityMs(deps,ctx,worktreePath){try{let stdout=await deps.runGitStdoutAt(ctx,worktreePath,["log","-1","--format=%ct"]),secs=Number.parseInt(stdout.trim(),10);if(Number.isFinite(secs)&&secs>0)return secs*1000}catch{}if(!ctx.exec.isRemote)try{return fs.statSync(worktreePath).mtimeMs}catch{}return 0}async function listBranchNames(deps,repo){let ctx=deps.ctxFor(repo);requireAbsolute("repo",ctx.dir);let stdout;try{stdout=await deps.runGitStdout(ctx,["for-each-ref","--format=%(refname)","refs/heads","refs/remotes/origin"])}catch{return[]}let names=new Set;for(let line of stdout.split(`
9
+ `)){let name=line.trim().replace(/^refs\/(?:heads|remotes\/origin)\//,"");if(name&&name!=="HEAD")names.add(name)}return[...names]}async function listManaged(deps,repo){let ctx=deps.ctxFor(repo);requireAbsolute("repo",ctx.dir);let all=parseWorktreeListPorcelain(await deps.runGitStdout(ctx,["worktree","list","--porcelain"])),kept=[];for(let entry of all){if(!entry.path)continue;let callerRoot=ctx.remote?remoteManagedRootForPath(ctx.dir,entry.path):managedWorktreeRootForPath(repo,entry.path);if(!callerRoot)continue;if(!entry.branch||entry.detached)continue;let rel=path.relative(canonicalize(callerRoot),canonicalize(entry.path));kept.push({callerPath:path.join(callerRoot,rel),probePath:entry.path,branch:entry.branch,head:entry.head??""})}return mapWithLimit(kept,PROBE_CONCURRENCY,async(e)=>({path:e.callerPath,branch:e.branch,head:e.head,dirty:await deps.isDirty(e.probePath).catch(()=>null)}))}async function listAllAdoptable(deps,repo){let ctx=deps.ctxFor(repo),adoptable=await adoptablePaths(deps,ctx),infos=await mapWithLimit(adoptable,PROBE_CONCURRENCY,async(entry)=>{let[dirty,activityMs]=await Promise.all([deps.isDirty(entry.path).catch(()=>null),lastActivityMs(deps,ctx,entry.path)]);return{path:entry.path,branch:entry.branch,head:entry.head,dirty,roveManaged:ctx.remote?remoteManagedRootForPath(ctx.dir,entry.path)!==null:isRoveManagedPath(repo,entry.path),lastActivityMs:activityMs}});return infos.sort((a,b)=>b.lastActivityMs-a.lastActivityMs),infos}async function adoptablePaths(deps,ctx){requireAbsolute("repo",ctx.dir);let all=parseWorktreeListPorcelain(await deps.runGitStdout(ctx,["worktree","list","--porcelain"])),canon=(p)=>ctx.remote?p:canonicalize(p),canonRepo=canon(ctx.dir),canonMain=all.find((entry)=>entry.path)?.path,canonMainPath=canonMain?canon(canonMain):null,kept=[];for(let entry of all){if(!entry.path)continue;if(entry.bare)continue;if(!entry.branch||entry.detached)continue;let canonEntry=canon(entry.path);if(canonMainPath!==null&&canonEntry===canonMainPath)continue;if(canonEntry===canonRepo)continue;kept.push({path:entry.path,branch:entry.branch,head:entry.head??""})}return kept}async function unreadableWorktreeNames(deps,ctx){if(ctx.remote)return[];requireAbsolute("repo",ctx.dir);let adminRoot;try{let common=(await deps.runGitStdout(ctx,["rev-parse","--git-common-dir"])).trim();if(!common)return[];adminRoot=path.join(path.resolve(ctx.dir,common),"worktrees")}catch{return[]}let names;try{names=fs.readdirSync(adminRoot,{withFileTypes:!0}).filter((entry)=>entry.isDirectory()).map((entry)=>entry.name)}catch{return[]}if(names.length===0)return[];let listed;try{listed=await deps.runGitStdout(ctx,["worktree","list","--porcelain"])}catch{return[]}let reported=new Set(parseWorktreeListPorcelain(listed).filter((entry)=>entry.path).map((entry)=>canonicalize(entry.path))),missing=[];for(let name of names){let gitdir;try{gitdir=fs.readFileSync(path.join(adminRoot,name,"gitdir"),"utf8").trim()}catch{missing.push(name);continue}if(gitdir&&!reported.has(canonicalize(path.dirname(gitdir))))missing.push(name)}return missing}import path2 from"path";async function isRegisteredWorktree(deps,exec,repo,worktreePath){let out=await deps.runGit(exec,["worktree","list","--porcelain"],{cwd:repo,allowFail:!0,readOnly:!0});if(out.exitCode!==0)return!1;let same=(a,b)=>exec.isRemote?a===b:canonicalize(a)===canonicalize(b);return parseWorktreeListPorcelain(out.stdout).some((e)=>e.path!==void 0&&same(e.path,worktreePath))}async function deregisteredWorktreeResidue(exec,worktreePath){let pointer=(await exec.readFile(`${worktreePath}/.git`))?.trim().match(/^gitdir:\s*(.+)$/)?.[1]?.trim();if(!pointer)return!1;let marker="/worktrees/",at=pointer.lastIndexOf(marker);if(at<0)return!1;return await exec.exists(pointer.slice(0,at))}function dirtyRefusal(worktreePath,ignored,dirty=[]){return`${DIRTY_WORKTREE_CODE}: ${worktreePath} has ${describeDirtyWorktreeWork(ignored,dirty)} \u2014 forcing the removal salvages it to a ref first`}async function removeWorktree(deps,worktreePath,opts){requireAbsolute("path",worktreePath);let exec=deps.execForPath(worktreePath),force=opts?.force===!0;if(!await exec.exists(worktreePath)){let goneRepo=opts?.repo??await deps.findRepoFor(exec,path2.dirname(worktreePath));if(goneRepo){if(await deps.runGit(exec,["worktree","prune"],{cwd:goneRepo,allowFail:!0}),opts?.deleteBranch===!0&&opts.branch){let outcome=await deleteBranchAnchored(deps.branchDeps(),exec,goneRepo,opts.branch,{force});if(!outcome.deleted)opts.onBranchKept?.({branch:opts.branch,reason:outcome.reason})}}return}let repo=await deps.findRepoFor(exec,worktreePath);if(repo===null||!await isRegisteredWorktree(deps,exec,repo,worktreePath)){if(await deregisteredWorktreeResidue(exec,worktreePath)){opts?.onResidue?.({path:worktreePath,reason:"a previous removal deregistered the worktree"});return}if(repo){opts?.onResidue?.({path:worktreePath,reason:"a previous removal deregistered the worktree"});return}if(!force)throw Error(`remove(): ${worktreePath} is not a git worktree`);if(!isUnderManagedWorktreesRoot(worktreePath,opts?.repo))throw Error(`remove(): ${worktreePath} has no reachable git repo and is not under a Rove worktrees root; refusing to delete it`);if(opts?.onSalvage?.(null),await exec.run(["rm","-rf",worktreePath]),await exec.exists(worktreePath))opts?.onResidue?.({path:worktreePath,reason:"the directory could not be deleted"});return}let branch=opts?.deleteBranch?await deps.currentBranch(worktreePath).catch(()=>null)??opts.branch??null:null;if(force){let salvaged=await salvageWorktree({runGit:(e,a,o)=>deps.runGit(e,a,o)},exec,worktreePath);opts?.onSalvage?.(salvaged)}else{let dirty=await deps.dirtyPaths(worktreePath);if(dirty.length>0)throw Error(dirtyRefusal(worktreePath,[],dirty));let ignored=await deps.ignoredWork(worktreePath);if(ignored==="unknown"||ignored.length>0)throw Error(dirtyRefusal(worktreePath,ignored))}let args=force?["worktree","remove","--force",worktreePath]:["worktree","remove",worktreePath],result=await deps.runGit(exec,args,{cwd:repo,allowFail:!0});if(result.exitCode!==0){if(await isRegisteredWorktree(deps,exec,repo,worktreePath))throw new GitCommandError(args,repo,result);opts?.onResidue?.({path:worktreePath,reason:result.stderr.trim()||result.stdout.trim()||"unknown"})}if(await deps.runGit(exec,["worktree","prune"],{cwd:repo,allowFail:!0}),branch){let outcome=await deleteBranchAnchored(deps.branchDeps(),exec,repo,branch,{force});if(!outcome.deleted)opts?.onBranchKept?.({branch,reason:outcome.reason})}}class GitWorktreeManager{execDeps;constructor(execDeps=defaultExecDeps){this.execDeps=execDeps}ctxFor(repoKey){let basePath=this.execDeps.remoteBasePath(repoKey);return basePath?{exec:this.execDeps.execForRepo(repoKey),dir:basePath,remote:!0}:{exec:this.execDeps.execForRepo(repoKey),dir:repoKey,remote:!1}}async runGit(exec,args,opts){if(!opts.cwd)throw Error("runGit(): cwd is required; refusing to inherit from process.cwd()");let env=opts.readOnly?{...opts.env,...READ_ONLY_GIT_ENV}:opts.env,r=await exec.run(["git",...args],{cwd:opts.cwd,env}),result={stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode};if(result.exitCode!==0&&!opts.allowFail)throw new GitCommandError(args,opts.cwd,result);return result}async create(repo,branch,worktreePath,baseRef){let ctx=this.ctxFor(repo);if(requireAbsolute("repo",ctx.dir),requireAbsolute("path",worktreePath),!branch)throw Error("create(): branch must be a non-empty string");if(await ctx.exec.exists(worktreePath)){let existing=await this.tryDescribe(ctx,worktreePath);if(existing){if(existing.branch!==branch)throw Error(`worktree at ${worktreePath} is on branch '${existing.branch}', refusing to hijack to '${branch}'`);return existing}throw Error(`create(): ${worktreePath} exists but is not a registered git worktree`)}await ctx.exec.mkdirp(path3.dirname(worktreePath));let args=await branchExists(this.branchDeps(),ctx,branch)?["worktree","add",worktreePath,branch]:baseRef?["worktree","add","-b",branch,worktreePath,baseRef]:["worktree","add","-b",branch,worktreePath];await this.runGit(ctx.exec,args,{cwd:ctx.dir});let info=await this.tryDescribe(ctx,worktreePath);if(!info)throw Error(`create(): git reported success but ${worktreePath} is not a worktree`);if(info.branch!==branch)throw Error(`create(): post-condition failed \u2014 expected branch '${branch}' at ${worktreePath}, got '${info.branch}'`);return info}async createForTask(args){let basePath=this.execDeps.remoteBasePath(args.repo),target=basePath?remoteWorktreePathFor(basePath,args.slug):worktreePathFor(args.repo,args.slug);return this.create(args.repo,args.branch,target,args.baseRef)}async remove(worktreePath,opts){await removeWorktree({runGit:(exec,args,runOpts)=>this.runGit(exec,args,runOpts),execForPath:(p)=>this.execDeps.execForPath(p),findRepoFor:(exec,p)=>this.findRepoFor(exec,p),currentBranch:(p)=>this.currentBranch(p),dirtyPaths:(p)=>this.dirtyPaths(p),ignoredWork:(p)=>this.ignoredWork(p),branchDeps:()=>this.branchDeps()},worktreePath,opts)}async deleteBranch(repo,branch,opts){let ctx=this.ctxFor(repo);return requireAbsolute("repo",ctx.dir),await deleteBranchAnchored(this.branchDeps(),ctx.exec,ctx.dir,branch,{force:opts?.force===!0,onAnchor:opts?.onAnchor})}execAt(worktreePath){return requireAbsolute("path",worktreePath),this.execDeps.execForPath(worktreePath)}branchDeps(){return{runGit:(exec,args,opts)=>this.runGit(exec,args,opts),execAt:(worktreePath)=>this.execAt(worktreePath),findRepoFor:(exec,worktreePath)=>this.findRepoFor(exec,worktreePath)}}listDeps(){return{ctxFor:(repoKey)=>this.ctxFor(repoKey),runGitStdout:async(ctx,args)=>(await this.runGit(ctx.exec,args,{cwd:ctx.dir,readOnly:!0})).stdout,runGitStdoutAt:async(ctx,cwd,args)=>(await this.runGit(ctx.exec,args,{cwd,readOnly:!0})).stdout,isDirty:(worktreePath)=>this.isDirty(worktreePath)}}list(repo){return listManaged(this.listDeps(),repo)}listAll(repo){return listAllAdoptable(this.listDeps(),repo)}listAdoptablePaths(repo){return adoptablePaths(this.listDeps(),this.ctxFor(repo))}listUnreadableWorktrees(repo){return unreadableWorktreeNames(this.listDeps(),this.ctxFor(repo))}listBranchNames(repo){return listBranchNames(this.listDeps(),repo)}async pathExists(worktreePath){return this.execAt(worktreePath).exists(worktreePath)}async pruneWorktrees(repo){let ctx=this.ctxFor(repo);requireAbsolute("repo",ctx.dir),await this.runGit(ctx.exec,["worktree","prune"],{cwd:ctx.dir,allowFail:!0})}async isDirty(worktreePath){return(await this.dirtyPaths(worktreePath)).length>0}async dirtyPaths(worktreePath){let out=await this.runGit(this.execAt(worktreePath),["status","--porcelain"],{cwd:worktreePath,readOnly:!0});return parseDirtyPaths(out.stdout)}async ignoredWork(worktreePath){return smallIgnoredPaths(this.execAt(worktreePath),worktreePath)}async currentBranch(worktreePath){let name=(await this.runGit(this.execAt(worktreePath),["rev-parse","--abbrev-ref","HEAD"],{cwd:worktreePath,readOnly:!0})).stdout.trim();if(!name||name==="HEAD")throw Error(`currentBranch(): ${worktreePath} is in detached-HEAD state`);return name}branchHasUpstream(worktreePath,branch){return branchHasUpstream(this.branchDeps(),worktreePath,branch)}hasLocalBranch(worktreePath,branch){return hasLocalBranch(this.branchDeps(),worktreePath,branch)}renameBranch(worktreePath,from,to){return renameBranch(this.branchDeps(),worktreePath,from,to)}async tryDescribe(ctx,worktreePath){let out=await this.runGit(ctx.exec,["worktree","list","--porcelain"],{cwd:ctx.dir,readOnly:!0}),entries=parseWorktreeListPorcelain(out.stdout),norm=(p)=>ctx.remote?p:canonicalize(p),target=norm(worktreePath),match=entries.find((e)=>e.path&&norm(e.path)===target);if(!match||!match.path||!match.branch||match.detached)return null;return{path:worktreePath,branch:match.branch,head:match.head??"",dirty:await this.isDirty(match.path)}}async findRepoFor(exec,worktreePath){try{let out=await this.runGit(exec,["rev-parse","--git-common-dir"],{cwd:worktreePath,allowFail:!0,readOnly:!0});if(out.exitCode!==0)return null;let gitDir=out.stdout.trim();if(!gitDir)return null;let absolute=path3.isAbsolute(gitDir)?gitDir:path3.resolve(worktreePath,gitDir);return path3.basename(absolute)===".git"?path3.dirname(absolute):absolute}catch(err){if(err instanceof GitCommandError)return null;throw err}}}
10
+ export{parseDirtyPaths,isDirtyOutput,defaultExecDeps,GitWorktreeManager};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{GitWorktreeManager}from"./chunk-m4f5h05c.js";import"./chunk-qvfdqrbf.js";import"./chunk-41x1hrqe.js";import"./chunk-cbjh43yc.js";import"./chunk-2apszxn2.js";import"./chunk-sak1tphp.js";import"./chunk-6xppe9bj.js";import"./chunk-2brn8e1y.js";import"./chunk-7kysxgbq.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{GitWorktreeManager};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{isProcessAlive}from"./chunk-vnpqemb0.js";import{randomBytes}from"crypto";import{linkSync,mkdirSync,readFileSync,unlinkSync,writeFileSync}from"fs";import{link,mkdir,readFile,unlink,writeFile}from"fs/promises";import{dirname}from"path";class LockfileError extends Error{heldByPid;constructor(message,heldByPid){super(message);this.name="LockfileError",this.heldByPid=heldByPid}}async function acquire(lockPath,opts={}){await mkdir(dirname(lockPath),{recursive:!0});let token=`${process.pid}:${randomBytes(8).toString("hex")}`,sidecar=`${lockPath}.${token.replace(":","-")}`;for(;;){await writeFile(sidecar,token);try{return await link(sidecar,lockPath),token}catch(err){if(err.code!=="EEXIST")throw err}finally{await unlink(sidecar).catch(()=>{})}let holder;try{holder=(await readFile(lockPath,"utf8")).trim()}catch(err){if(err.code!=="ENOENT")throw err;continue}let holderPid=Number.parseInt(holder,10),alive=Number.isFinite(holderPid)&&holderPid>0&&isProcessAlive(holderPid);if(alive&&!opts.forceTakeover)throw new LockfileError(`task index is locked by another Rove instance (pid ${holderPid})`,holderPid);console.warn(`[rove] removing stale lockfile at ${lockPath} (was held by pid ${holderPid}${alive?", forced":", process gone"})`),releaseSync(lockPath,holder)}}async function release(lockPath,token){let current;try{current=(await readFile(lockPath,"utf8")).trim()}catch(err){if(err.code==="ENOENT")return;throw err}if(current!==token)return;try{await unlink(lockPath)}catch(err){if(err.code==="ENOENT")return;throw err}}function sleepSync(ms){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,ms)}function acquireSync(lockPath,timeoutMs=5000){mkdirSync(dirname(lockPath),{recursive:!0});let token=`${process.pid}:${randomBytes(8).toString("hex")}`,sidecar=`${lockPath}.${token.replace(":","-")}`,deadline=Date.now()+timeoutMs;for(;;){writeFileSync(sidecar,token);try{return linkSync(sidecar,lockPath),token}catch(err){if(err.code!=="EEXIST")throw err}finally{try{unlinkSync(sidecar)}catch{}}let holder;try{holder=readFileSync(lockPath,"utf8").trim()}catch(err){if(err.code!=="ENOENT")throw err;continue}let holderPid=Number.parseInt(holder,10);if(Number.isFinite(holderPid)&&holderPid>0&&isProcessAlive(holderPid)){if(Date.now()>=deadline)throw new LockfileError(`${lockPath} is locked by another Rove instance (pid ${holderPid})`,holderPid);sleepSync(25);continue}console.warn(`[rove] removing stale lockfile at ${lockPath} (was held by pid ${holderPid}, process gone)`),releaseSync(lockPath,holder)}}function releaseSync(lockPath,token){try{if(readFileSync(lockPath,"utf8").trim()!==token)return;unlinkSync(lockPath)}catch(err){if(err.code!=="ENOENT")throw err}}
2
+ import{isProcessAlive}from"./chunk-a7kq09ke.js";import{randomBytes}from"crypto";import{linkSync,mkdirSync,readFileSync,unlinkSync,writeFileSync}from"fs";import{link,mkdir,readFile,unlink,writeFile}from"fs/promises";import{dirname}from"path";class LockfileError extends Error{heldByPid;constructor(message,heldByPid){super(message);this.name="LockfileError",this.heldByPid=heldByPid}}async function acquire(lockPath,opts={}){await mkdir(dirname(lockPath),{recursive:!0});let token=`${process.pid}:${randomBytes(8).toString("hex")}`,sidecar=`${lockPath}.${token.replace(":","-")}`;for(;;){await writeFile(sidecar,token);try{return await link(sidecar,lockPath),token}catch(err){if(err.code!=="EEXIST")throw err}finally{await unlink(sidecar).catch(()=>{})}let holder;try{holder=(await readFile(lockPath,"utf8")).trim()}catch(err){if(err.code!=="ENOENT")throw err;continue}let holderPid=Number.parseInt(holder,10),alive=Number.isFinite(holderPid)&&holderPid>0&&isProcessAlive(holderPid);if(alive&&!opts.forceTakeover)throw new LockfileError(`task index is locked by another Rove instance (pid ${holderPid})`,holderPid);console.warn(`[rove] removing stale lockfile at ${lockPath} (was held by pid ${holderPid}${alive?", forced":", process gone"})`),releaseSync(lockPath,holder)}}async function release(lockPath,token){let current;try{current=(await readFile(lockPath,"utf8")).trim()}catch(err){if(err.code==="ENOENT")return;throw err}if(current!==token)return;try{await unlink(lockPath)}catch(err){if(err.code==="ENOENT")return;throw err}}function sleepSync(ms){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,ms)}function acquireSync(lockPath,timeoutMs=5000){mkdirSync(dirname(lockPath),{recursive:!0});let token=`${process.pid}:${randomBytes(8).toString("hex")}`,sidecar=`${lockPath}.${token.replace(":","-")}`,deadline=Date.now()+timeoutMs;for(;;){writeFileSync(sidecar,token);try{return linkSync(sidecar,lockPath),token}catch(err){if(err.code!=="EEXIST")throw err}finally{try{unlinkSync(sidecar)}catch{}}let holder;try{holder=readFileSync(lockPath,"utf8").trim()}catch(err){if(err.code!=="ENOENT")throw err;continue}let holderPid=Number.parseInt(holder,10);if(Number.isFinite(holderPid)&&holderPid>0&&isProcessAlive(holderPid)){if(Date.now()>=deadline)throw new LockfileError(`${lockPath} is locked by another Rove instance (pid ${holderPid})`,holderPid);sleepSync(25);continue}console.warn(`[rove] removing stale lockfile at ${lockPath} (was held by pid ${holderPid}, process gone)`),releaseSync(lockPath,holder)}}function releaseSync(lockPath,token){try{if(readFileSync(lockPath,"utf8").trim()!==token)return;unlinkSync(lockPath)}catch(err){if(err.code!=="ENOENT")throw err}}
3
3
  export{LockfileError,acquire,release,acquireSync,releaseSync};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{loadStateFile,patchStateFile}from"./chunk-zyd6k6ak.js";var LAST_ACTIVE_TASK_KEY="lastActive.taskId";function readLastActiveTaskId(){let value=loadStateFile()[LAST_ACTIVE_TASK_KEY];return typeof value==="string"&&value?value:null}function writeLastActiveTaskId(id){patchStateFile({[LAST_ACTIVE_TASK_KEY]:id})}
2
+ import{loadStateFile,patchStateFile}from"./chunk-7q43tysm.js";var LAST_ACTIVE_TASK_KEY="lastActive.taskId";function readLastActiveTaskId(){let value=loadStateFile()[LAST_ACTIVE_TASK_KEY];return typeof value==="string"&&value?value:null}function writeLastActiveTaskId(id){patchStateFile({[LAST_ACTIVE_TASK_KEY]:id})}
3
3
  export{readLastActiveTaskId,writeLastActiveTaskId};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ var ROVE_PRODUCT_NAME="rove",ROVE_STATE_DIR_BASENAME=".rove",ROVE_CONFIG_DIR_BASENAME="rove";function readRoveEnv(suffix,env=process.env){return env[`ROVE_${suffix}`]?.trim()||void 0}function readRoveHomeDirEnv(env=process.env){return readRoveEnv("HOME_DIR",env)}
3
+ export{ROVE_PRODUCT_NAME,ROVE_STATE_DIR_BASENAME,ROVE_CONFIG_DIR_BASENAME,readRoveEnv,readRoveHomeDirEnv};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{BUNDLED_THEME_JSONS,parseRgbLiteral}from"./chunk-s278gjet.js";import{kvStatePath}from"./chunk-8hbtca1g.js";import{DEFAULT_LOCALE,isLocaleId}from"./chunk-ge30p4s5.js";import{RGBA as RGBA3}from"@opentui/core";import{RGBA}from"@opentui/core";var BREATH_TICKS=30,SPEED_MIN=0.2,SPEED_SWING=0.9333333333333333,INK_FLOOR=0.3;function breathLevel(tick){return 0.5-0.5*Math.cos(2*Math.PI*tick/BREATH_TICKS)}function breathPhase(tick){let wave=tick/2-BREATH_TICKS/(4*Math.PI)*Math.sin(2*Math.PI*tick/BREATH_TICKS);return SPEED_MIN*tick+SPEED_SWING*wave}function breathGlyph(frames,tick){let index=Math.floor(breathPhase(tick)+0.000000001)%frames.length;return frames[index]??frames[0]??""}function mixInk(accent,muted,share){if(accent.intent!=="rgb"||muted.intent!=="rgb")return accent;let[ar,ag,ab,aa]=accent.toInts(),[mr,mg,mb]=muted.toInts(),mix=(a,m)=>Math.round(m+(a-m)*share);return RGBA.fromInts(mix(ar,mr),mix(ag,mg),mix(ab,mb),aa)}function breathColor(accent,muted,tick){return mixInk(accent,muted,INK_FLOOR+(1-INK_FLOOR)*breathLevel(tick))}var toLinear=(v)=>v<=0.04045?v/12.92:((v+0.055)/1.055)**2.4,toGamma=(v)=>v<=0.0031308?12.92*v:1.055*v**0.4166666666666667-0.055;function toOklch(color){let[r,g,b]=color.toInts().map((v)=>toLinear(v/255)),l=Math.cbrt(0.4122214708*r+0.5363325363*g+0.0514459929*b),m=Math.cbrt(0.2119034982*r+0.6806995451*g+0.1073969566*b),s=Math.cbrt(0.0883024619*r+0.2817188376*g+0.6299787005*b),L=0.2104542553*l+0.793617785*m-0.0040720468*s,A=1.9779984951*l-2.428592205*m+0.4505937099*s,B=0.0259040371*l+0.7827717662*m-0.808675766*s;return{l:L,c:Math.hypot(A,B),h:Math.atan2(B,A)}}function linearRgb({l:L,c,h}){let A=c*Math.cos(h),B=c*Math.sin(h),l=(L+0.3963377774*A+0.2158037573*B)**3,m=(L-0.1055613458*A-0.0638541728*B)**3,s=(L-0.0894841775*A-1.291485548*B)**3;return[4.0767416621*l-3.3077115913*m+0.2309699292*s,-1.2684380046*l+2.6097574011*m-0.3413193965*s,-0.0041960863*l-0.7034186147*m+1.707614701*s]}function fromOklch(color,alpha){let ch=(v)=>Math.round(Math.min(1,Math.max(0,toGamma(v)))*255),[r,g,b]=linearRgb(color);return RGBA.fromInts(ch(r),ch(g),ch(b),alpha)}function turnHue(accent,deg,lightness=1,chroma=1){if(accent.intent!=="rgb")return accent;let base=toOklch(accent),turned={l:base.l*lightness,c:base.c*chroma,h:base.h+deg*Math.PI/180};return fromOklch(turned,accent.toInts()[3])}var inGamut=(color)=>linearRgb(color).every((v)=>v>=-0.0001&&v<=1.0001);function inkAtHue(deg,lightness,chroma,alpha=255){let h=deg*Math.PI/180,c=chroma;while(c>0&&!inGamut({l:lightness,c,h}))c-=0.005;return fromOklch({l:lightness,c:Math.max(0,c),h},alpha)}function oklchCusp(deg){let key=Math.round(deg)%360,hit=cuspCache.get(key);if(hit)return hit;let h=key*Math.PI/180,best={l:1,c:0};for(let l=0.2;l<=1;l+=0.01){let lo=0,hi=0.4;for(let i=0;i<16;i++){let mid=(lo+hi)/2;if(inGamut({l,c:mid,h}))lo=mid;else hi=mid}if(lo>best.c)best={l,c:lo}}return cuspCache.set(key,best),best}var cuspCache=new Map;import{RGBA as RGBA2}from"@opentui/core";var HOST_TEXT_MIN_CONTRAST=4.5;function srgbChannelToLinear(c){let v=c/255;return v<=0.04045?v/12.92:((v+0.055)/1.055)**2.4}function relativeLuminance([r,g,b]){return 0.2126*srgbChannelToLinear(r)+0.7152*srgbChannelToLinear(g)+0.0722*srgbChannelToLinear(b)}function contrastRatioTriplet(fg,bg){let l1=relativeLuminance(fg),l2=relativeLuminance(bg),lighter=Math.max(l1,l2),darker=Math.min(l1,l2);return(lighter+0.05)/(darker+0.05)}function rgbToHsl([r,g,b]){let rn=r/255,gn=g/255,bn=b/255,max=Math.max(rn,gn,bn),min=Math.min(rn,gn,bn),l=(max+min)/2;if(max===min)return[0,0,l];let d=max-min,s=l>0.5?d/(2-max-min):d/(max+min),h;if(max===rn)h=((gn-bn)/d+(gn<bn?6:0))*60;else if(max===gn)h=((bn-rn)/d+2)*60;else h=((rn-gn)/d+4)*60;return[h,s,l]}function hslToRgb(h,s,l){if(s===0){let v=Math.round(l*255);return[v,v,v]}let q=l<0.5?l*(1+s):l+s-l*s,p=2*l-q,channel=(t)=>{let tn=t;if(tn<0)tn+=1;if(tn>1)tn-=1;let c=tn<0.16666666666666666?p+(q-p)*6*tn:tn<0.5?q:tn<0.6666666666666666?p+(q-p)*(0.6666666666666666-tn)*6:p;return Math.round(c*255)};return[channel(h/360+0.3333333333333333),channel(h/360),channel(h/360-0.3333333333333333)]}var MID_HOST_LUMINANCE=0.5;function ensureContrast(fg,bg,minRatio=HOST_TEXT_MIN_CONTRAST){let fgInts=fg.toInts(),bgInts=bg.toInts(),fgTriplet=[fgInts[0],fgInts[1],fgInts[2]],bgTriplet=[bgInts[0],bgInts[1],bgInts[2]];if(contrastRatioTriplet(fgTriplet,bgTriplet)>=minRatio)return fg;let[h,s,l]=rgbToHsl(fgTriplet),lighten=relativeLuminance(bgTriplet)<=MID_HOST_LUMINANCE,at=(lightness)=>contrastRatioTriplet(hslToRgb(h,s,lightness),bgTriplet),lo=lighten?l:0,hi=lighten?1:l;for(let i=0;i<32;i++){let mid=(lo+hi)/2;if(at(mid)>=minRatio)if(lighten)hi=mid;else lo=mid;else if(lighten)lo=mid;else hi=mid}let[r,g,b]=hslToRgb(h,s,lighten?hi:lo);return RGBA2.fromInts(r,g,b,fgInts[3])}var BUNDLED_THEMES=BUNDLED_THEME_JSONS,DEFAULT_THEME="claude";function hasBundledTheme(name){return Boolean(BUNDLED_THEMES[name])}var THEME_MODE_PREFERENCES=["dark","light","auto"],DEFAULT_THEME_MODE="dark";function resolveThemeMode(preference,detected){return preference==="auto"?detected??"dark":preference}var FOCUS_ACCENT_SLOTS=["primary","success","info"];function resolveTheme(theme,mode="dark"){let defs=theme.defs??{};function resolve(c,chain=[]){if(typeof c==="string"){if(c==="transparent"||c==="none")return RGBA3.fromInts(0,0,0,0);if(c.startsWith("#"))return RGBA3.fromHex(c);let rgb=parseRgbLiteral(c);if(rgb)return RGBA3.fromInts(rgb.r,rgb.g,rgb.b,rgb.a);if(chain.includes(c))return RGBA3.fromInts(0,0,0);let next=defs[c]??theme.theme[c];if(next===void 0)return RGBA3.fromInts(0,0,0);return resolve(next,[...chain,c])}return resolve(c[mode],chain)}let out={};for(let[k,v]of Object.entries(theme.theme))out[k]=resolve(v);let text=out.text??RGBA3.fromHex("#ffffff"),background=out.background??RGBA3.fromHex("#000000");return{...{primary:out.primary??text,secondary:out.secondary??text,accent:out.accent??out.primary??text,error:out.error??text,warning:out.warning??text,warningOnHost:out.warning??text,success:out.success??text,info:out.info??text,text,textMuted:out.textMuted??text,background,backgroundPanel:out.backgroundPanel??background,backgroundElement:out.backgroundElement??background,backgroundMenu:out.backgroundMenu??out.backgroundElement??background,backgroundDialog:out.backgroundDialog??out.backgroundPanel??background,border:out.border??text,borderActive:out.borderActive??out.border??text,borderSubtle:out.borderSubtle??out.border??text,diffAdded:out.diffAdded??out.success??text,diffRemoved:out.diffRemoved??out.error??text,diffContext:out.diffContext??out.textMuted??text,diffHunkHeader:out.diffHunkHeader??out.textMuted??text,diffAddedBg:out.diffAddedBg??background,diffRemovedBg:out.diffRemovedBg??background,selectedListItemText:out.selectedListItemText??background},...out}}function applyDisplayOverlay(base,focusAccent,transparentBackground,hostBackground){let v={...base,focusAccent:base[focusAccent]??base.primary,warningOnHost:base.warning};if(!transparentBackground)return v;let[backgroundR,backgroundG,backgroundB]=base.background.toInts(),[panelR,panelG,panelB]=base.backgroundPanel.toInts(),transparent={...v,background:RGBA3.fromInts(backgroundR,backgroundG,backgroundB,0),backgroundPanel:RGBA3.fromInts(panelR,panelG,panelB,0)};if(!hostBackground)return transparent;return{...transparent,text:ensureContrast(transparent.text,hostBackground),textMuted:ensureContrast(transparent.textMuted,hostBackground),warningOnHost:ensureContrast(transparent.warning,hostBackground)}}function diffInks(theme,colorblind){let added=(ink)=>colorblind?turnHue(ink,60,1,0.71):ink;return{added:added(theme.diffAdded),removed:theme.diffRemoved,addedBg:added(theme.diffAddedBg),removedBg:theme.diffRemovedBg}}import{readFileSync}from"fs";var LOCALE_KEY="locale";function defaultTransparentBackground(platform=process.platform){return platform!=="win32"}function readPersistedUiPrefs(fallbackTheme,isKnownTheme=hasBundledTheme){try{let parsed=JSON.parse(readFileSync(kvStatePath(),"utf8")),theme=typeof parsed.activeTheme==="string"&&isKnownTheme(parsed.activeTheme)?parsed.activeTheme:fallbackTheme,themeMode=THEME_MODE_PREFERENCES.includes(parsed.themeMode)?parsed.themeMode:DEFAULT_THEME_MODE,transparent=typeof parsed.transparentBackground==="boolean"?parsed.transparentBackground:defaultTransparentBackground(),focusAccent=typeof parsed.focusAccent==="string"&&FOCUS_ACCENT_SLOTS.includes(parsed.focusAccent)?parsed.focusAccent:null,locale=isLocaleId(parsed[LOCALE_KEY])?parsed[LOCALE_KEY]:DEFAULT_LOCALE;return{theme,themeMode,transparent,focusAccent,locale}}catch{return{theme:fallbackTheme,themeMode:DEFAULT_THEME_MODE,transparent:defaultTransparentBackground(),focusAccent:null,locale:DEFAULT_LOCALE}}}
2
+ import{BUNDLED_THEME_JSONS,parseRgbLiteral}from"./chunk-pdvyfz3n.js";import{kvStatePath}from"./chunk-prqeddy7.js";import{DEFAULT_LOCALE,isLocaleId}from"./chunk-zt49bbg9.js";import{RGBA as RGBA3}from"@opentui/core";import{RGBA}from"@opentui/core";var BREATH_TICKS=30,SPEED_MIN=0.2,SPEED_SWING=0.9333333333333333,INK_FLOOR=0.3;function breathLevel(tick){return 0.5-0.5*Math.cos(2*Math.PI*tick/BREATH_TICKS)}function breathPhase(tick){let wave=tick/2-BREATH_TICKS/(4*Math.PI)*Math.sin(2*Math.PI*tick/BREATH_TICKS);return SPEED_MIN*tick+SPEED_SWING*wave}function breathGlyph(frames,tick){let index=Math.floor(breathPhase(tick)+0.000000001)%frames.length;return frames[index]??frames[0]??""}function mixInk(accent,muted,share){if(accent.intent!=="rgb"||muted.intent!=="rgb")return accent;let[ar,ag,ab,aa]=accent.toInts(),[mr,mg,mb]=muted.toInts(),mix=(a,m)=>Math.round(m+(a-m)*share);return RGBA.fromInts(mix(ar,mr),mix(ag,mg),mix(ab,mb),aa)}function breathColor(accent,muted,tick){return mixInk(accent,muted,INK_FLOOR+(1-INK_FLOOR)*breathLevel(tick))}var toLinear=(v)=>v<=0.04045?v/12.92:((v+0.055)/1.055)**2.4,toGamma=(v)=>v<=0.0031308?12.92*v:1.055*v**0.4166666666666667-0.055;function toOklch(color){let[r,g,b]=color.toInts().map((v)=>toLinear(v/255)),l=Math.cbrt(0.4122214708*r+0.5363325363*g+0.0514459929*b),m=Math.cbrt(0.2119034982*r+0.6806995451*g+0.1073969566*b),s=Math.cbrt(0.0883024619*r+0.2817188376*g+0.6299787005*b),L=0.2104542553*l+0.793617785*m-0.0040720468*s,A=1.9779984951*l-2.428592205*m+0.4505937099*s,B=0.0259040371*l+0.7827717662*m-0.808675766*s;return{l:L,c:Math.hypot(A,B),h:Math.atan2(B,A)}}function linearRgb({l:L,c,h}){let A=c*Math.cos(h),B=c*Math.sin(h),l=(L+0.3963377774*A+0.2158037573*B)**3,m=(L-0.1055613458*A-0.0638541728*B)**3,s=(L-0.0894841775*A-1.291485548*B)**3;return[4.0767416621*l-3.3077115913*m+0.2309699292*s,-1.2684380046*l+2.6097574011*m-0.3413193965*s,-0.0041960863*l-0.7034186147*m+1.707614701*s]}function fromOklch(color,alpha){let ch=(v)=>Math.round(Math.min(1,Math.max(0,toGamma(v)))*255),[r,g,b]=linearRgb(color);return RGBA.fromInts(ch(r),ch(g),ch(b),alpha)}function turnHue(accent,deg,lightness=1,chroma=1){if(accent.intent!=="rgb")return accent;let base=toOklch(accent),turned={l:base.l*lightness,c:base.c*chroma,h:base.h+deg*Math.PI/180};return fromOklch(turned,accent.toInts()[3])}var inGamut=(color)=>linearRgb(color).every((v)=>v>=-0.0001&&v<=1.0001);function inkAtHue(deg,lightness,chroma,alpha=255){let h=deg*Math.PI/180,c=chroma;while(c>0&&!inGamut({l:lightness,c,h}))c-=0.005;return fromOklch({l:lightness,c:Math.max(0,c),h},alpha)}function oklchCusp(deg){let key=Math.round(deg)%360,hit=cuspCache.get(key);if(hit)return hit;let h=key*Math.PI/180,best={l:1,c:0};for(let l=0.2;l<=1;l+=0.01){let lo=0,hi=0.4;for(let i=0;i<16;i++){let mid=(lo+hi)/2;if(inGamut({l,c:mid,h}))lo=mid;else hi=mid}if(lo>best.c)best={l,c:lo}}return cuspCache.set(key,best),best}var cuspCache=new Map;import{RGBA as RGBA2}from"@opentui/core";var HOST_TEXT_MIN_CONTRAST=4.5;function srgbChannelToLinear(c){let v=c/255;return v<=0.04045?v/12.92:((v+0.055)/1.055)**2.4}function relativeLuminance([r,g,b]){return 0.2126*srgbChannelToLinear(r)+0.7152*srgbChannelToLinear(g)+0.0722*srgbChannelToLinear(b)}function contrastRatioTriplet(fg,bg){let l1=relativeLuminance(fg),l2=relativeLuminance(bg),lighter=Math.max(l1,l2),darker=Math.min(l1,l2);return(lighter+0.05)/(darker+0.05)}function rgbToHsl([r,g,b]){let rn=r/255,gn=g/255,bn=b/255,max=Math.max(rn,gn,bn),min=Math.min(rn,gn,bn),l=(max+min)/2;if(max===min)return[0,0,l];let d=max-min,s=l>0.5?d/(2-max-min):d/(max+min),h;if(max===rn)h=((gn-bn)/d+(gn<bn?6:0))*60;else if(max===gn)h=((bn-rn)/d+2)*60;else h=((rn-gn)/d+4)*60;return[h,s,l]}function hslToRgb(h,s,l){if(s===0){let v=Math.round(l*255);return[v,v,v]}let q=l<0.5?l*(1+s):l+s-l*s,p=2*l-q,channel=(t)=>{let tn=t;if(tn<0)tn+=1;if(tn>1)tn-=1;let c=tn<0.16666666666666666?p+(q-p)*6*tn:tn<0.5?q:tn<0.6666666666666666?p+(q-p)*(0.6666666666666666-tn)*6:p;return Math.round(c*255)};return[channel(h/360+0.3333333333333333),channel(h/360),channel(h/360-0.3333333333333333)]}var MID_HOST_LUMINANCE=0.5;function ensureContrast(fg,bg,minRatio=HOST_TEXT_MIN_CONTRAST){let fgInts=fg.toInts(),bgInts=bg.toInts(),fgTriplet=[fgInts[0],fgInts[1],fgInts[2]],bgTriplet=[bgInts[0],bgInts[1],bgInts[2]];if(contrastRatioTriplet(fgTriplet,bgTriplet)>=minRatio)return fg;let[h,s,l]=rgbToHsl(fgTriplet),lighten=relativeLuminance(bgTriplet)<=MID_HOST_LUMINANCE,at=(lightness)=>contrastRatioTriplet(hslToRgb(h,s,lightness),bgTriplet),lo=lighten?l:0,hi=lighten?1:l;for(let i=0;i<32;i++){let mid=(lo+hi)/2;if(at(mid)>=minRatio)if(lighten)hi=mid;else lo=mid;else if(lighten)lo=mid;else hi=mid}let[r,g,b]=hslToRgb(h,s,lighten?hi:lo);return RGBA2.fromInts(r,g,b,fgInts[3])}var BUNDLED_THEMES=BUNDLED_THEME_JSONS,DEFAULT_THEME="claude";function hasBundledTheme(name){return Boolean(BUNDLED_THEMES[name])}var THEME_MODE_PREFERENCES=["dark","light","auto"],DEFAULT_THEME_MODE="dark";function resolveThemeMode(preference,detected){return preference==="auto"?detected??"dark":preference}var FOCUS_ACCENT_SLOTS=["primary","success","info"];function resolveTheme(theme,mode="dark"){let defs=theme.defs??{};function resolve(c,chain=[]){if(typeof c==="string"){if(c==="transparent"||c==="none")return RGBA3.fromInts(0,0,0,0);if(c.startsWith("#"))return RGBA3.fromHex(c);let rgb=parseRgbLiteral(c);if(rgb)return RGBA3.fromInts(rgb.r,rgb.g,rgb.b,rgb.a);if(chain.includes(c))return RGBA3.fromInts(0,0,0);let next=defs[c]??theme.theme[c];if(next===void 0)return RGBA3.fromInts(0,0,0);return resolve(next,[...chain,c])}return resolve(c[mode],chain)}let out={};for(let[k,v]of Object.entries(theme.theme))out[k]=resolve(v);let text=out.text??RGBA3.fromHex("#ffffff"),background=out.background??RGBA3.fromHex("#000000");return{...{primary:out.primary??text,secondary:out.secondary??text,accent:out.accent??out.primary??text,error:out.error??text,warning:out.warning??text,warningOnHost:out.warning??text,success:out.success??text,info:out.info??text,text,textMuted:out.textMuted??text,background,backgroundPanel:out.backgroundPanel??background,backgroundElement:out.backgroundElement??background,backgroundMenu:out.backgroundMenu??out.backgroundElement??background,backgroundDialog:out.backgroundDialog??out.backgroundPanel??background,border:out.border??text,borderActive:out.borderActive??out.border??text,borderSubtle:out.borderSubtle??out.border??text,diffAdded:out.diffAdded??out.success??text,diffRemoved:out.diffRemoved??out.error??text,diffContext:out.diffContext??out.textMuted??text,diffHunkHeader:out.diffHunkHeader??out.textMuted??text,diffAddedBg:out.diffAddedBg??background,diffRemovedBg:out.diffRemovedBg??background,selectedListItemText:out.selectedListItemText??background},...out}}function applyDisplayOverlay(base,focusAccent,transparentBackground,hostBackground){let v={...base,focusAccent:base[focusAccent]??base.primary,warningOnHost:base.warning};if(!transparentBackground)return v;let[backgroundR,backgroundG,backgroundB]=base.background.toInts(),[panelR,panelG,panelB]=base.backgroundPanel.toInts(),transparent={...v,background:RGBA3.fromInts(backgroundR,backgroundG,backgroundB,0),backgroundPanel:RGBA3.fromInts(panelR,panelG,panelB,0)};if(!hostBackground)return transparent;return{...transparent,text:ensureContrast(transparent.text,hostBackground),textMuted:ensureContrast(transparent.textMuted,hostBackground),warningOnHost:ensureContrast(transparent.warning,hostBackground)}}function diffInks(theme,colorblind){let added=(ink)=>colorblind?turnHue(ink,60,1,0.71):ink;return{added:added(theme.diffAdded),removed:theme.diffRemoved,addedBg:added(theme.diffAddedBg),removedBg:theme.diffRemovedBg}}import{readFileSync}from"fs";var LOCALE_KEY="locale";function defaultTransparentBackground(platform=process.platform){return platform!=="win32"}function readPersistedUiPrefs(fallbackTheme,isKnownTheme=hasBundledTheme){try{let parsed=JSON.parse(readFileSync(kvStatePath(),"utf8")),theme=typeof parsed.activeTheme==="string"&&isKnownTheme(parsed.activeTheme)?parsed.activeTheme:fallbackTheme,themeMode=THEME_MODE_PREFERENCES.includes(parsed.themeMode)?parsed.themeMode:DEFAULT_THEME_MODE,transparent=typeof parsed.transparentBackground==="boolean"?parsed.transparentBackground:defaultTransparentBackground(),focusAccent=typeof parsed.focusAccent==="string"&&FOCUS_ACCENT_SLOTS.includes(parsed.focusAccent)?parsed.focusAccent:null,locale=isLocaleId(parsed[LOCALE_KEY])?parsed[LOCALE_KEY]:DEFAULT_LOCALE;return{theme,themeMode,transparent,focusAccent,locale}}catch{return{theme:fallbackTheme,themeMode:DEFAULT_THEME_MODE,transparent:defaultTransparentBackground(),focusAccent:null,locale:DEFAULT_LOCALE}}}
3
3
  export{breathGlyph,mixInk,breathColor,toOklch,turnHue,inkAtHue,oklchCusp,relativeLuminance,ensureContrast,BUNDLED_THEMES,DEFAULT_THEME,THEME_MODE_PREFERENCES,DEFAULT_THEME_MODE,resolveThemeMode,resolveTheme,applyDisplayOverlay,diffInks,LOCALE_KEY,readPersistedUiPrefs};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{fetchMarketplace,searchMarketplace}from"./chunk-1brfxbvg.js";import"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{searchMarketplace,fetchMarketplace};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{addRemoteRepo,addSavedRepo,backfillSavedReposFromProjects,getCustomEngineIds,getDisabledEngineIds,getPersistedString,getPersistedValue,getRemoteRepoConfig,getRemoteRepos,getRepoInitOverride,getSavedRepos,isGitRepo,isRemoteProjectsEnabled,isRemoteRepoKey,isValidBranchName,normalizeSavedRepos,remoteRepoKey,removeSavedRepo,resolveMainRepoRoot,resolveRepoRoot,setPersistedString,setRepoInitOverride,statePath}from"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{statePath,setRepoInitOverride,setPersistedString,resolveRepoRoot,resolveMainRepoRoot,removeSavedRepo,remoteRepoKey,normalizeSavedRepos,isValidBranchName,isRemoteRepoKey,isRemoteProjectsEnabled,isGitRepo,getSavedRepos,getRepoInitOverride,getRemoteRepos,getRemoteRepoConfig,getPersistedValue,getPersistedString,getDisabledEngineIds,getCustomEngineIds,backfillSavedReposFromProjects,addSavedRepo,addRemoteRepo};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{preRenameStateDir}from"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveEnv,readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import{createHash}from"crypto";import{existsSync,readFileSync}from"fs";import{homedir,tmpdir}from"os";import{join}from"path";function stateDirs(homeDir){return{canonical:join(homeDir,ROVE_STATE_DIR_BASENAME),legacy:preRenameStateDir(homeDir)}}function pidIsLive(pidPath){try{let pid=Number.parseInt(readFileSync(pidPath,"utf8").trim(),10);if(!Number.isInteger(pid)||pid<=1)return!1;return process.kill(pid,0),!0}catch{return!1}}function runtimePath(homeDir,name,pidName){let{canonical,legacy}=stateDirs(homeDir),canonicalPath=join(canonical,name);if(pidIsLive(join(canonical,pidName)))return canonicalPath;let legacyPath=join(legacy,name);if(existsSync(legacyPath)&&pidIsLive(join(legacy,pidName)))return legacyPath;return canonicalPath}function runtimeDataPath(homeDir,name){return join(stateDirs(homeDir).canonical,name)}var SOCKET_PATH_SAFETY_LIMIT=100;function shortHomeTag(homeDir){return createHash("sha1").update(homeDir).digest("hex").slice(0,8)}function fitSocketPath(naturalPath,homeDir,role,pidTag){if(Buffer.byteLength(naturalPath,"utf8")<=SOCKET_PATH_SAFETY_LIMIT)return naturalPath;let tag=shortHomeTag(homeDir),suffix=pidTag===void 0?"":`-${pidTag}`,fallback=join(tmpdir(),`rove-${tag}-${role}${suffix}.sock`);if(Buffer.byteLength(fallback,"utf8")<=SOCKET_PATH_SAFETY_LIMIT)return fallback;throw Error(`daemon socket path exceeds ${SOCKET_PATH_SAFETY_LIMIT} bytes even after fallback: ${fallback}`)}function defaultDaemonSocketPath(homeDir){let override=readRoveEnv("DAEMON_SOCKET_PATH");if(override)return override;let explicit=homeDir??readRoveHomeDirEnv();if(explicit&&explicit.length>0)return fitSocketPath(join(explicit,ROVE_STATE_DIR_BASENAME,"daemon.sock"),explicit,"daemon");let runtimeDir=process.env.XDG_RUNTIME_DIR;if(runtimeDir&&runtimeDir.length>0)return fitSocketPath(join(runtimeDir,"rove.sock"),runtimeDir,"daemon");let home=homedir();return fitSocketPath(join(home,ROVE_STATE_DIR_BASENAME,"daemon.sock"),home,"daemon")}function resolveDaemonHomeDir(homeDir){let explicit=homeDir??readRoveHomeDirEnv();return explicit&&explicit.length>0?explicit:homedir()}function defaultDaemonPidPath(homeDir=readRoveHomeDirEnv()??homedir()){let override=readRoveEnv("DAEMON_PID_PATH");if(override)return override;return runtimePath(homeDir,"daemon.pid","daemon.pid")}function defaultDaemonLogPath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"daemon.log")}function defaultClientLogPath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"client.log")}function isWindowsPipePath(path){return path.startsWith("\\\\.\\pipe\\")||path.startsWith("//./pipe/")}function windowsPipePath(homeDir,role){return`\\\\.\\pipe\\rove-${shortHomeTag(homeDir)}-${role}`}function defaultPtyHostSocketPath(homeDir,platform=process.platform){let override=readRoveEnv("PTY_SOCKET_PATH");if(override)return override;let explicit=homeDir??readRoveHomeDirEnv();if(platform==="win32")return windowsPipePath(explicit||homedir(),"pty");if(explicit&&explicit.length>0)return fitSocketPath(join(explicit,ROVE_STATE_DIR_BASENAME,"pty.sock"),explicit,"pty");let runtimeDir=process.env.XDG_RUNTIME_DIR;if(runtimeDir&&runtimeDir.length>0)return fitSocketPath(join(runtimeDir,"rove-pty.sock"),runtimeDir,"pty");let home=homedir();return fitSocketPath(join(home,ROVE_STATE_DIR_BASENAME,"pty.sock"),home,"pty")}function defaultPtyHostPidPath(homeDir=readRoveHomeDirEnv()??homedir()){let override=readRoveEnv("PTY_PID_PATH");if(override)return override;return runtimePath(homeDir,"pty.pid","pty.pid")}function defaultPtyHostLogPath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"pty.log")}function defaultPtyExitsPath(homeDir=readRoveHomeDirEnv()??homedir()){return runtimeDataPath(homeDir,"pty-exits.json")}function defaultWebTokenPath(homeDir=readRoveHomeDirEnv()??homedir()){return runtimeDataPath(homeDir,"web-token")}function defaultPtyFreezeDir(homeDir=readRoveHomeDirEnv()??homedir()){return runtimeDataPath(homeDir,"pty-sessions")}function defaultDeliveryLockDir(homeDir=readRoveHomeDirEnv()??homedir()){return runtimeDataPath(homeDir,"delivery-locks")}
3
+ export{shortHomeTag,fitSocketPath,defaultDaemonSocketPath,resolveDaemonHomeDir,defaultDaemonPidPath,defaultDaemonLogPath,defaultClientLogPath,isWindowsPipePath,windowsPipePath,defaultPtyHostSocketPath,defaultPtyHostPidPath,defaultPtyHostLogPath,defaultPtyExitsPath,defaultWebTokenPath,defaultPtyFreezeDir,defaultDeliveryLockDir};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{canonPath,normalizeMainRepo,randomDirTaskSuffix,repoWorkingDir,samePrStatus,titleFromRepo}from"./chunk-tvk46rfs.js";import{GitWorktreeManager,defaultExecDeps,isDirtyOutput,parseDirtyPaths}from"./chunk-m4f5h05c.js";import{readLastActiveTaskId,writeLastActiveTaskId}from"./chunk-n5dea05t.js";import{PLACEHOLDER_TASK_TITLE,isPlaceholderDerivedBranch,sanitizeTaskTitle}from"./chunk-cbc1h345.js";import{CannotDeleteMainTaskError,DirtyWorktreeError,EmptyBranchDirtyWorktreeError,EmptyBranchError,GitCommandFailedError,IllegalTransitionError,InvalidWorktreeNameError,LandConflictError,MainCheckoutDirtyError,MissingRefError,TaskDeletingError,TaskNotFoundError,WorktreeNameTakenError,WorktreeRemoveFailedError,canonicalize,listWorktreeDirNames}from"./chunk-qvfdqrbf.js";import{detectLanguage}from"./chunk-hpay0ax8.js";import{resolvePreferredVendor}from"./chunk-xv8fhxxm.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";import{addSavedRepo,getSavedRepos,isGitRepo,removeSavedRepo,resolveRepoRoot}from"./chunk-h9cg0j3a.js";import{projectRejection,rejectionReason}from"./chunk-3342qzve.js";import{createStateCell}from"./chunk-nhakrm1f.js";import{pathIdentity,pathWithin,samePath}from"./chunk-pn5ygqn6.js";async function createTaskRow(deps,input){if(!input.repo)throw Error("createTask: repo is required");let repo=(await deps.mainTasks.ensureIfEligible(input.repo,input.projectIntent??"explicit"))?.repo??normalizeMainRepo(input.repo).repo,title=sanitizeTaskTitle(input.title??PLACEHOLDER_TASK_TITLE)||PLACEHOLDER_TASK_TITLE,worktreeName=input.worktreeName?.trim();if(worktreeName)await deps.claimWorktreeName(repo,worktreeName);return await deps.store.create({repo,title,branch:input.branch??"",worktreePath:"",status:"backlog",kind:"task",vendor:input.vendor??DEFAULT_TASK_VENDOR,...input.command?.trim()?{command:input.command.trim()}:{},...input.modelEffort?{modelEffort:input.modelEffort}:{},...input.model?.trim()?{model:input.model.trim()}:{},...input.tier?.trim()?{tier:input.tier.trim()}:{},...input.groupId?{groupId:input.groupId}:{},...input.dispatcher?{dispatcher:input.dispatcher}:{},...input.routine?{routine:input.routine}:{},...input.baseRef?.trim()?{baseRef:input.baseRef.trim()}:{},...worktreeName?{worktreeName}:{}})}async function openDirectoryTaskRow(deps,input){if(!input.dir)throw Error("openDirectoryTask: dir is required");let dir=canonPath(input.dir);return deps.store.create({repo:dir,title:input.scratch?"":`${titleFromRepo(dir)}-${randomDirTaskSuffix()}`,branch:"",worktreePath:dir,status:"backlog",kind:"dir",...input.scratch?{scratch:!0}:{},vendor:input.vendor??resolvePreferredVendor()})}async function adoptScratchRepoRow(deps,id,repo){let task=deps.store.get(id);if(!task||task.kind!=="dir"||task.scratch!==!0)return;let dir=canonPath(repo);await deps.store.update(id,{repo:dir,worktreePath:dir,scratch:!1,title:titleFromRepo(dir)})}function baseRepoCtx(repo,deps){let basePath=deps.remoteBasePath(repo);return{exec:deps.execForRepo(repo),dir:basePath??repo}}async function landGit(exec,dir,args,opts){let r=await exec.run(["git",...args],{cwd:dir,env:opts?.readOnly?READ_ONLY_GIT_ENV:void 0});return{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}}async function isDirty(exec,dir){return isDirtyOutput((await landGit(exec,dir,["status","--porcelain"],{readOnly:!0})).stdout)}async function landPreflight(task,deps=defaultExecDeps){let refuse=(pf,refusal)=>{let refused={...pf,refusal};return{...refused,message:landRefusalError(task,refused).message}},branch=task.branch.trim();if(!branch)throw Error(`landPreflight: task ${task.id} has no branch to land (never materialised)`);let{exec,dir}=baseRepoCtx(task.repo,deps),headOut=await landGit(exec,dir,["symbolic-ref","--short","HEAD"],{readOnly:!0}),landedOn=headOut.stdout.trim();if(headOut.exitCode!==0||!landedOn){let headCommit=await landGit(exec,dir,["rev-parse","--verify","--quiet","HEAD"],{readOnly:!0}),detached=headCommit.exitCode===0&&headCommit.stdout.trim().length>0;return refuse({branch,landedOn:"",baseDir:dir},detached?"DETACHED_HEAD":"UNREADABLE_BASE")}if(landedOn===branch)return refuse({branch,landedOn,baseDir:dir},"SAME_BRANCH");let baseDirty=await isDirty(exec,dir),aheadOut=await landGit(exec,dir,["rev-list","--count",`${landedOn}..${branch}`],{readOnly:!0});if(aheadOut.exitCode!==0){let baseHead=await landGit(exec,dir,["rev-parse","--verify","--quiet","HEAD"],{readOnly:!0});if(baseHead.exitCode!==0||!baseHead.stdout.trim())return refuse({branch,landedOn,baseDirty,baseDir:dir},"UNBORN_BASE");return refuse({branch,landedOn,baseDirty,baseDir:dir},baseDirty?"MAIN_CHECKOUT_DIRTY":"MISSING_REF")}let parsed=Number.parseInt(aheadOut.stdout.trim(),10),base={branch,landedOn,baseDirty,baseDir:dir,...Number.isFinite(parsed)?{ahead:parsed}:{}};if(baseDirty)return refuse(base,"MAIN_CHECKOUT_DIRTY");if(base.ahead!==0)return base;let worktreePath=task.worktreePath.trim();if(worktreePath){let manager=new GitWorktreeManager(deps),dirty=!1;try{dirty=await manager.isDirty(worktreePath)}catch{dirty=!1}if(dirty){let wtExec=deps.execForPath(worktreePath),files=parseDirtyPaths((await landGit(wtExec,worktreePath,["status","--porcelain"],{readOnly:!0})).stdout);return refuse({...base,dirtyFiles:files},"EMPTY_BRANCH_DIRTY_WORKTREE")}}return refuse(base,"EMPTY_BRANCH")}function landRefusalError(task,pf){switch(pf.refusal){case"DETACHED_HEAD":return Error(`landTask: base checkout at ${pf.baseDir} is in detached-HEAD state; check out a branch first`);case"UNREADABLE_BASE":return Error(`landTask: could not read HEAD of the base checkout at ${pf.baseDir} \u2014 is it still a git repo?`);case"UNBORN_BASE":return Error(`landTask: base checkout at ${pf.baseDir} is on '${pf.landedOn}' but has no commits yet, so there is nothing to merge '${pf.branch}' into; make the first commit there (or \`git merge --ff-only ${pf.branch}\`) and land again`);case"SAME_BRANCH":return Error(`landTask: base checkout is already on '${pf.branch}' \u2014 nothing to land onto`);case"MAIN_CHECKOUT_DIRTY":return new MainCheckoutDirtyError(task.repo,pf.baseDir);case"MISSING_REF":return new MissingRefError(pf.branch,pf.landedOn,pf.baseDir);case"EMPTY_BRANCH_DIRTY_WORKTREE":return new EmptyBranchDirtyWorktreeError(pf.branch,pf.landedOn,task.worktreePath.trim(),[...pf.dirtyFiles??[]]);case"EMPTY_BRANCH":return new EmptyBranchError(pf.branch,pf.landedOn)}}async function landTaskWithCleanup(task,opts,deps){if(task.kind==="main")throw Error("landTask: a main task has no branch to land");if(task.kind==="dir")throw Error("landTask: a directory task has no Rove-managed branch to land");let result=await landTask(task,{strategy:opts.strategy}),worktree=opts.removeWorktree===!1?void 0:await removeLandedWorktree(task,opts.callerCwd,deps),branchAnchor=null,branchKept,worktreeGone=!task.worktreePath.trim()||worktree?.removed===!0;if(opts.deleteBranch&&!worktreeGone)branchKept={reason:worktree?.reason??`worktree ${task.worktreePath} was kept, and still has the branch checked out`};else if(opts.deleteBranch){let outcome=await deps.worktrees.deleteBranch(task.repo,result.branch,{force:!0,onAnchor:(record)=>{branchAnchor=record}});if(!outcome.deleted)branchKept={reason:outcome.reason}}return{...result,...worktree?{worktree}:{},...branchAnchor?{branchAnchor}:{},...branchKept?{branchKept}:{}}}async function removeLandedWorktree(task,callerCwd,deps){let worktreePath=task.worktreePath.trim();if(!worktreePath)return{removed:!1,reason:"task has no worktree on disk (never materialised)"};let wt=canonicalize(worktreePath);if(samePath(wt,canonicalize(task.repo)))return{removed:!1,reason:"refusing to remove the base checkout"};if(callerCwd){if(pathWithin(wt,canonicalize(callerCwd))!==null)return{removed:!1,reason:`refusing to remove the caller's own worktree (${worktreePath}) \u2014 re-run from outside it`}}if(deps.tearDownSession)try{await deps.tearDownSession(task.id)}catch{}let residue;try{await deps.worktrees.remove(worktreePath,{onResidue:(r)=>{residue=r}})}catch(err){return{removed:!1,reason:errText(err)}}try{await deps.clearWorktreePath(task.id)}catch(err){return{removed:!0,reason:`worktree removed, but clearing the task's worktree path failed: ${errText(err)}`,...residue?{residue}:{}}}return{removed:!0,...residue?{residue}:{}}}function errText(err){return err instanceof Error?err.message:String(err)}async function conflictedFiles(exec,dir){return(await landGit(exec,dir,["diff","--name-only","--diff-filter=U"],{readOnly:!0})).stdout.split(`
3
+ `).map((l)=>l.trim()).filter((l)=>l.length>0)}async function landTask(task,input={},deps=defaultExecDeps){let strategy=input.strategy??"merge",preflight=await landPreflight(task,deps);if(preflight.refusal)throw landRefusalError(task,{...preflight,refusal:preflight.refusal});let{branch,landedOn}=preflight,{exec,dir}=baseRepoCtx(task.repo,deps);if(strategy==="squash"){if((await landGit(exec,dir,["merge","--squash",branch])).exitCode!==0){let files=await conflictedFiles(exec,dir);throw await landGit(exec,dir,["merge","--abort"]).catch(()=>{}),await landGit(exec,dir,["reset","--hard","HEAD"]).catch(()=>{}),new LandConflictError(task.id,branch,files)}let commit=await landGit(exec,dir,["commit","--no-edit","-m",`Land ${branch} (squash)`]);if(commit.exitCode!==0){if((await landGit(exec,dir,["diff","--cached","--quiet"],{readOnly:!0})).exitCode===0)throw await landGit(exec,dir,["reset","--hard","HEAD"]).catch(()=>{}),Error(`landTask: '${branch}' has nothing to land onto '${landedOn}' (already merged or empty)`);throw new GitCommandFailedError(`commit (squash-landing '${branch}' onto '${landedOn}')`,commit.stderr,"the squashed merge is left STAGED in the base checkout \u2014 fix the cause and `git commit` it, or `git reset --hard HEAD` to discard")}}else{let before=(await landGit(exec,dir,["rev-parse","HEAD"],{readOnly:!0})).stdout.trim(),merge=await landGit(exec,dir,["merge","--no-ff","-m",`Land ${branch}`,branch]);if(merge.exitCode!==0){let files=await conflictedFiles(exec,dir);if(await landGit(exec,dir,["merge","--abort"]).catch(()=>{}),files.length===0)throw new GitCommandFailedError(`merge --no-ff (landing '${branch}' onto '${landedOn}')`,merge.stderr,"the merge was aborted, so the base checkout is unchanged");throw new LandConflictError(task.id,branch,files)}let after=(await landGit(exec,dir,["rev-parse","HEAD"],{readOnly:!0})).stdout.trim();if(before===after)throw Error(`landTask: '${branch}' has nothing to land onto '${landedOn}' (already merged or empty)`)}let shaOut=await landGit(exec,dir,["rev-parse","--short","HEAD"],{readOnly:!0});return{branch,strategy,landedOn,commit:shaOut.stdout.trim()}}class MainTaskCoordinator{store;forgetWorktree;locks=new Map;constructor(store,forgetWorktree){this.store=store;this.forgetWorktree=forgetWorktree}async ensure(repo){let task=await this.ensureIfEligible(repo,"explicit");if(task)return task;let{repo:normalizedRepo}=normalizeMainRepo(repo),rejected=projectRejection(normalizedRepo,isGitRepo,"explicit")??"notGitRepo";throw Error(`cannot add ${normalizedRepo} as a project: ${rejectionReason(rejected)}`)}async ensureIfEligible(repo,intent="derived"){let{repo:normalizedRepo,key}=normalizeMainRepo(repo),onThisRoot=(task)=>normalizeMainRepo(task.repo).key===key,existing=this.store.list().find((task)=>task.kind==="main"&&onThisRoot(task));if(existing)return existing;if(projectRejection(normalizedRepo,isGitRepo,intent))return null;let inflight=this.locks.get(key);if(inflight)return inflight;let promise=(async()=>{addSavedRepo(normalizedRepo,{intent:"explicit"});let adoptable=this.store.list().find((task)=>task.kind==="dir"&&task.scratch!==!0&&onThisRoot(task));if(adoptable)return await this.store.update(adoptable.id,this.mainShape(normalizedRepo));return await this.store.create({...this.mainShape(normalizedRepo),status:"backlog",vendor:resolvePreferredVendor(normalizedRepo)})})();this.locks.set(key,promise);try{return await promise}finally{this.locks.delete(key)}}mainShape(normalizedRepo){return{kind:"main",title:titleFromRepo(normalizedRepo),repo:normalizedRepo,branch:"",worktreePath:repoWorkingDir(normalizedRepo)}}async forget(repo){if(!repo)throw Error("forgetProject: repo is required");let key=normalizeMainRepo(repo).key;for(let saved of getSavedRepos())if(normalizeMainRepo(saved).key===key)removeSavedRepo(saved);for(let task of this.store.list()){if(task.kind!=="main")continue;if(normalizeMainRepo(task.repo).key!==key)continue;await this.store.remove(task.id),this.forgetWorktree(task.id)}}}function promotableDirTasks(deps){let claimed=new Set(deps.tasks.filter((task)=>task.kind==="main").map((task)=>pathIdentity(task.repo))),seen=new Set,out=[];for(let task of deps.tasks){if(task.kind!=="dir"||task.scratch===!0)continue;let path=task.repo,key=pathIdentity(path);if(!path||claimed.has(key)||seen.has(key))continue;if(!deps.isRepoRoot(path))continue;seen.add(key),out.push(task)}return out}class TaskDeletionCoordinator{store;worktrees;forgetTask;onSalvage;onResidue;onBranchKept;constructor(store,worktrees,forgetTask,onSalvage,onResidue,onBranchKept){this.store=store;this.worktrees=worktrees;this.forgetTask=forgetTask;this.onSalvage=onSalvage;this.onResidue=onResidue;this.onBranchKept=onBranchKept}async prepare(id,opts){let task=this.store.get(id);if(!task)return!1;if(task.kind==="main")throw new CannotDeleteMainTaskError;if(task.deletion?.phase==="queued"||task.deletion?.phase==="running")return!0;let force=opts?.force===!0;if(task.worktreePath&&!force&&task.kind!=="dir"){let dirty=[],ignored=[],probed=!0;try{dirty=await this.worktrees.dirtyPaths(task.worktreePath)}catch{probed=!1}if(probed&&dirty.length===0)ignored=await this.worktrees.ignoredWork(task.worktreePath);if(dirty.length>0||ignored==="unknown"||ignored.length>0)throw new DirtyWorktreeError(task.id,ignored,dirty)}return await this.store.update(task.id,{deletion:{phase:"queued",force,deleteBranch:opts?.deleteBranch===!0,requestedAt:new Date().toISOString()}}),!0}async begin(id){let task=this.store.get(id);if(!task||!task.deletion||task.deletion.phase==="error")return!1;if(task.deletion.phase!=="running")await this.store.update(task.id,{deletion:{...task.deletion,phase:"running"}});return!0}async finish(id){let task=this.store.get(id);if(!task?.deletion||task.deletion.phase!=="running")return;try{if(task.worktreePath&&task.kind!=="dir")await this.worktrees.remove(task.worktreePath,{force:task.deletion.force,deleteBranch:task.deletion.deleteBranch===!0,repo:task.repo,branch:task.branch,onSalvage:(record)=>{if(record)this.onSalvage?.(task.id,record)},onResidue:(residue)=>this.onResidue?.(task.id,residue),onBranchKept:(kept)=>this.onBranchKept?.(task.id,kept)})}catch(cause){let failure=new WorktreeRemoveFailedError(task.id,cause);throw await this.store.update(task.id,{deletion:{...task.deletion,phase:"error",error:errorMessage(failure)}}),failure}await this.store.remove(task.id),this.forgetTask(task.id)}async deleteNow(id,opts){if(!await this.prepare(id,opts))return;if(!await this.begin(id))return;await this.finish(id)}}var TYPE_PREFIXES=new Set(["feat","feature","fix","bugfix","hotfix","chore","docs","doc","refactor","test","tests","ci","build","perf","style","revert","release"]),BRAND_TOKENS=new Set(["rove"]);function inferBranchStyle(names){let typed=new Map,bare=0;for(let raw of new Set(names)){let name=raw.trim();if(!name||name==="HEAD")continue;let slash=name.indexOf("/");if(slash===-1){bare+=1;continue}let prefix=name.slice(0,slash);if(TYPE_PREFIXES.has(prefix))typed.set(prefix,(typed.get(prefix)??0)+1)}let typedTotal=0;for(let n of typed.values())typedTotal+=n;if(typedTotal===0||typedTotal<bare)return{kind:"bare"};let best="",bestN=0;for(let[prefix,n]of typed)if(n>bestN||n===bestN&&(best===""||prefix<best))best=prefix,bestN=n;return{kind:"typed",defaultPrefix:best}}function slugTokens(title){return title.toLowerCase().replace(/[^a-z0-9]+/g,"-").split("-").filter((t)=>t.length>0&&!BRAND_TOKENS.has(t))}function capSlug(tokens){return tokens.join("-").slice(0,32).replace(/-+$/,"")}function identitySlug(taskId){return`task-${taskId.slice(-6).toLowerCase()}`}function deriveConventionBranch(title,style,taskId){let tokens=slugTokens(title);if(style.kind==="typed"){let first=tokens[0];return`${first!==void 0&&TYPE_PREFIXES.has(first)?tokens.shift():style.defaultPrefix}/${capSlug(tokens)||identitySlug(taskId)}`}return capSlug(tokens)||identitySlug(taskId)}function uniqueBranchName(base,taken,taskId){if(!taken.has(base))return base;for(let n=2;n<=99;n+=1){let candidate=`${base}-${n}`;if(!taken.has(candidate))return candidate}return`${base}-${taskId.slice(-6).toLowerCase()}`}class TaskEditor{store;worktrees;constructor(store,worktrees){this.store=store,this.worktrees=worktrees}requireTask(id){let task=this.store.get(id);if(!task)throw new TaskNotFoundError(String(id));return task}async setTitle(id,title){let trimmed=sanitizeTaskTitle(title);if(!trimmed)throw Error("setTitle: title is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.title===trimmed&&task.scratch!==!0)return;await this.store.update(task.id,{title:trimmed,...task.scratch===!0?{scratch:!1}:{}}),await this.followBranchToTitle(task,trimmed)}async followBranchToTitle(taskBefore,newTitle){if(taskBefore.kind==="main"||!taskBefore.worktreePath)return;if(!isPlaceholderDerivedBranch(taskBefore.branch,taskBefore.id))return;try{let names=await this.worktrees.listBranchNames(taskBefore.repo),base=deriveConventionBranch(newTitle,inferBranchStyle(names),taskBefore.id);if(base===taskBefore.branch)return;if(await this.worktrees.branchHasUpstream(taskBefore.worktreePath,taskBefore.branch))return;let taken=new Set(names.filter((n)=>n!==taskBefore.branch)),nextBranch=uniqueBranchName(base,taken,taskBefore.id);await this.setBranch(taskBefore.id,nextBranch)}catch(err){console.error(`[rove] follow-branch-to-title failed for ${taskBefore.id}:`,err)}}async setBranch(id,branch){let trimmed=branch.trim();if(!trimmed)throw Error("setBranch: branch is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.kind==="main")throw Error("setBranch: a main task tracks the repo's own branch; rename it with git directly");if(task.kind==="dir")throw Error("setBranch: a directory task tracks its own checkout; rename branches with git directly");if(task.branch===trimmed)return;if(task.worktreePath)await this.worktrees.renameBranch(task.worktreePath,task.branch,trimmed);await this.store.update(task.id,{branch:trimmed})}async observeLanguage(id,text){let observed=detectLanguage(text);if(!observed)return;let task=this.requireTask(id);if(task.observedLanguage===observed)return;await this.store.update(task.id,{observedLanguage:observed})}async setVendor(id,vendor,effort,model){let task=this.requireTask(id),nextEffort=effort?.trim()?effort.trim():void 0,effortChanges=effort!==void 0&&task.modelEffort!==nextEffort,nextModel=model?.trim()?model.trim():void 0,modelChanges=model!==void 0&&task.model!==nextModel;if(task.vendor===vendor&&!effortChanges&&!modelChanges)return;await this.store.update(task.id,{vendor,...effort!==void 0?{modelEffort:nextEffort}:{},...model!==void 0?{model:nextModel}:{}})}async setCommand(id,command,vendor){let trimmed=command.trim();if(!trimmed)throw Error("setCommand: command is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.command===trimmed&&(vendor===void 0||task.vendor===vendor))return;await this.store.update(task.id,{command:trimmed,...vendor?{vendor}:{}})}async setPinned(id,pinned){let task=this.requireTask(id);if(task.kind==="main")return;let next=pinned??!task.pinned;if((task.pinned??!1)===next)return;await this.store.update(task.id,{pinned:next})}async moveTask(id,delta){let task=this.requireTask(id);await this.store.move(task.id,delta,this.movePartition(task))}async moveTaskToTop(id){let task=this.requireTask(id);await this.store.moveToFront(task.id,this.movePartition(task))}movePartition(task){let isMain=task.kind==="main";return this.store.list().filter((t)=>isMain?(t.kind??"task")==="main":(t.kind??"task")!=="main"&&samePath(t.repo,task.repo)&&(t.pinned??!1)===(task.pinned??!1)).map((t)=>String(t.id))}async setStatus(id,status){let task=this.requireTask(id);if(task.status===status)return;if(task.status==="done"&&status==="error"||task.status==="error"&&status==="done")throw new IllegalTransitionError(task.status,status,task.id);await this.store.update(task.id,{status})}async setWorkerReport(id,report){let task=this.requireTask(id),next={...task.report,...report,at:new Date().toISOString()};await this.store.update(task.id,{report:next})}async setPRStatus(id,prStatus){let task=this.requireTask(id);if((task.prStatus?.lastError??null)===(prStatus?.lastError??null)&&samePrStatus(task.prStatus,prStatus??void 0))return;await this.store.update(task.id,{prStatus:prStatus??void 0})}async setQuotaResume(id,state){let task=this.requireTask(id);if((task.quotaResume?.resumeAt??null)===(state?.resumeAt??null))return;await this.store.update(task.id,{quotaResume:state??void 0})}async setLinkedWorkItem(id,item){let task=this.requireTask(id);if((task.linkedWorkItem?.url??null)===(item?.url??null))return;await this.store.update(task.id,{linkedWorkItem:item??void 0})}async setPrompt(id,prompt){if(prompt.trim().length===0)throw Error("setPrompt: prompt is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.prompt===prompt)return;await this.store.update(task.id,{prompt})}}import{basename}from"path";var ANIMAL_NAMES=["aardvark","addax","adder","agouti","albatross","alpaca","anaconda","anchovy","anglerfish","anole","anteater","antelope","ape","argali","armadillo","avocet","axolotl","baboon","badger","banteng","barracuda","basilisk","bass","bat","beagle","bear","beaver","bee","beetle","beluga","betta","bison","blackbird","blenny","bluebird","bluegill","boar","bobcat","bonito","bovid","buffalo","bullfrog","bunting","bushbuck","butterfly","buzzard","caiman","camel","canary","capybara","caracal","cardinal","caribou","carp","cassowary","caterpillar","catfish","chameleon","chamois","char","cheetah","chickadee","chimp","chinchilla","chipmunk","chough","cicada","civet","clam","clownfish","cobra","cockatoo","condor","coot","copperhead","coral","cormorant","cougar","coyote","crab","crane","crawfish","crayfish","cricket","crocodile","crow","cuckoo","curlew","cuttlefish","deer","dikdik","dingo","dolphin","donkey","dormouse","dotterel","dove","dragonfly","dromedary","duck","dugong","dunlin","eagle","echidna","eel","egret","eider","eland","elephant","elk","emu","ermine","falcon","fawn","ferret","finch","firefly","flamingo","flounder","fox","frog","gadwall","gannet","gaur","gazelle","gecko","gemsbok","gerbil","gharial","gibbon","gnu","goat","goby","godwit","goldfish","goose","gopher","goral","gorilla","goshawk","grackle","grasshopper","grayling","grebe","grouse","guanaco","guillemot","guineafowl","guppy","halibut","hammerhead","hamster","hare","harrier","hartebeest","hawk","hedgehog","heron","herring","hippo","hornbill","hornet","horse","hummingbird","hyena","ibex","ibis","iguana","impala","indri","jacana","jackal","jaguar","jay","jellyfish","jerboa","junco","kakapo","kangaroo","kestrel","killdeer","kingfisher","kinglet","kite","kiwi","koala","kookaburra","krait","krill","kudu","ladybug","lamprey","langur","lapwing","lark","lemming","lemur","leopard","limpet","lion","lionfish","lizard","llama","lobster","locust","loon","lorikeet","loris","lynx","macaque","macaw","mackerel","magpie","mallard","mamba","mammoth","manatee","mandrill","manta","mantis","marlin","marmoset","marmot","marten","meerkat","merganser","mink","minnow","mole","mongoose","monitor","monkey","moose","moth","mouflon","mouse","mudpuppy","mule","muntjac","musk","muskox","muskrat","mussel","mustang","narwhal","newt","nightingale","numbat","nuthatch","nyala","ocelot","octopus","okapi","opossum","orangutan","orca","oriole","oryx","osprey","ostrich","otter","owl","oyster","oystercatcher","paca","panda","pangolin","panther","parakeet","parrot","parrotfish","partridge","peafowl","pelican","penguin","perch","petrel","pheasant","pigeon","pika","pike","pintail","pipefish","platypus","plover","pollock","pony","porcupine","porpoise","possum","ptarmigan","puffin","puma","pupfish","python","quail","quetzal","quokka","quoll","rabbit","raccoon","rail","rat","rattler","raven","ray","redpoll","reindeer","remora","rhino","roadrunner","robin","rook","sable","sailfish","salamander","salmon","sandpiper","sardine","scallop","scaup","scorpion","seahorse","seal","serval","shark","shearwater","shrew","shrike","shrimp","siskin","sitatunga","skate","skink","skua","skunk","sloth","smelt","snail","snipe","solenodon","sparrow","spider","springbok","squid","squirrel","starfish","starling","stilt","stingray","stoat","stork","sunbird","sunfish","swallow","swan","swift","swordfish","tahr","takin","tamarin","tanager","tapir","tarantula","tarpon","tarsier","teal","tenrec","terrapin","tern","tetra","thrasher","thrush","tiger","toad","tortoise","toucan","treecreeper","treefrog","trout","tuatara","tuna","turkey","turtle","urchin","urial","vicuna","viper","vole","vulture","wagtail","wallaby","walleye","walrus","warbler","warthog","waterbuck","weasel","wildebeest","wolf","wolverine","wombat","woodcock","woodpecker","wrasse","wren","yak","zebra","zebu","zorilla"];class SlugAllocator{activeSlugs;random;pool;pendingByRepo=new Map;chain=Promise.resolve();constructor(activeSlugs,options={}){this.activeSlugs=activeSlugs;if(this.random=options.random??Math.random,this.pool=options.pool??ANIMAL_NAMES,this.pool.length===0)throw Error("SlugAllocator: animal pool cannot be empty")}async allocate(repo){let previous=this.chain,release;this.chain=new Promise((resolve)=>{release=resolve}),await previous;try{return await this.pickLocked(repo)}finally{release()}}async claim(repo,slug){let previous=this.chain,release;this.chain=new Promise((resolve)=>{release=resolve}),await previous;try{if((await this.occupiedSlugs(repo)).has(slug))throw new WorktreeNameTakenError(slug);return this.addPending(repo,slug),slug}finally{release()}}commit(repo,slug){this.deletePending(repo,slug)}cancel(repo,slug){this.deletePending(repo,slug)}async pickLocked(repo){let occupied=await this.occupiedSlugs(repo),candidates=this.pool.filter((n)=>!occupied.has(n));if(candidates.length>0){let pick=candidates[Math.floor(this.random()*candidates.length)];return this.addPending(repo,pick),pick}let base=this.pool[Math.floor(this.random()*this.pool.length)];for(let v=2;;v++){let candidate=`${base}-v${v}`;if(!occupied.has(candidate))return this.addPending(repo,candidate),candidate}}async occupiedSlugs(repo){let set=new Set(this.pendingByRepo.get(repo)??[]);for(let slug of this.activeSlugs(repo))if(slug)set.add(slug);for(let dir of await listWorktreeDirNames(repo))set.add(dir);return set}addPending(repo,slug){let pending=this.pendingByRepo.get(repo);if(!pending)pending=new Set,this.pendingByRepo.set(repo,pending);pending.add(slug)}deletePending(repo,slug){let pending=this.pendingByRepo.get(repo);if(!pending)return;if(pending.delete(slug),pending.size===0)this.pendingByRepo.delete(repo)}}var WORKTREE_NAME_RE=/^[A-Za-z0-9_][A-Za-z0-9._-]*$/;class WorktreeCoordinator{store;worktrees;canonPath;ensureProject;slugs;worktreeLocks=new Map;adoptLocks=new Map;reservedBranches=new Set;constructor(store,worktrees,canonPath2,ensureProject){this.store=store,this.worktrees=worktrees,this.canonPath=canonPath2,this.ensureProject=ensureProject,this.slugs=new SlugAllocator((repo)=>this.store.list().filter((t)=>samePath(t.repo,repo)&&t.kind!=="main").map((t)=>{return t.worktreePath.match(/([^/\\]+)[/\\]*$/)?.[1]??""}).filter((s)=>s.length>0))}async claimWorktreeName(repo,name){if(!WORKTREE_NAME_RE.test(name))throw new InvalidWorktreeNameError(name);return await this.slugs.claim(repo,name)}forget(id){this.worktreeLocks.delete(id)}async ensure(task){let inflight=this.worktreeLocks.get(task.id);if(inflight)return inflight;let work=this.createWorktree(task);this.worktreeLocks.set(task.id,work);try{return await work}finally{this.worktreeLocks.delete(task.id)}}async createWorktree(task){let slug=task.worktreeName||await this.slugs.allocate(task.repo),branch=task.branch||await this.deriveAutoBranch(task),baseRef=task.baseRef,info;try{info=await this.worktrees.createForTask({repo:task.repo,slug,branch,baseRef})}catch(err){throw this.slugs.cancel(task.repo,slug),err}finally{this.reservedBranches.delete(branch)}try{await this.store.update(task.id,{worktreePath:info.path,branch})}catch(err){throw await this.rollbackWorktree(info.path),this.slugs.cancel(task.repo,slug),err}return this.slugs.commit(task.repo,slug),info.path}async deriveAutoBranch(task){let names=await this.worktrees.listBranchNames(task.repo),base=deriveConventionBranch(task.title,inferBranchStyle(names),task.id),taken=new Set([...names,...this.reservedBranches]),branch=uniqueBranchName(base,taken,task.id);return this.reservedBranches.add(branch),branch}async rollbackWorktree(worktreePath){try{await this.worktrees.remove(worktreePath,{force:!0})}catch(err){console.error(`[rove] ensureWorktree rollback failed for ${worktreePath}:`,err)}}async discoverAdoptable(repo){let all=await this.worktrees.listAll(repo),linked=new Set(this.store.list().filter((t)=>t.worktreePath).map((t)=>this.canonPath(t.worktreePath)));return all.filter((wt)=>!linked.has(this.canonPath(wt.path)))}async adopt(input){let target=this.canonPath(input.worktreePath),inflight=this.adoptLocks.get(target);if(inflight)return inflight;let work=this.adoptLocked(input,target);this.adoptLocks.set(target,work);try{return await work}finally{this.adoptLocks.delete(target)}}async adoptLocked(input,target){let existing=this.store.list().find((t)=>t.worktreePath&&this.canonPath(t.worktreePath)===target);if(existing){if(input.ifExists==="return")return existing;throw Error(`adoptWorktree: ${input.worktreePath} is already adopted as a task`)}let match=(await this.worktrees.listAdoptablePaths(input.repo)).find((wt)=>this.canonPath(wt.path)===target);if(!match)throw Error(`adoptWorktree: ${input.worktreePath} is not an adoptable git worktree of ${input.repo} (unknown, detached, or the main checkout)`);let branch=input.branch?.trim()||match.branch,title=(input.title??basename(match.path)).trim()||PLACEHOLDER_TASK_TITLE;return await this.ensureProject(input.repo),this.store.create({repo:input.repo,title,branch,worktreePath:match.path,status:"backlog",kind:"task",vendor:input.vendor??DEFAULT_TASK_VENDOR})}}class Orchestrator{store;worktrees;worktreeCoordinator;editor;deletions;tasksAcc;activeTaskAcc;unsubscribeStore;mainTasks;tearDownSession;constructor(deps){this.store=deps.store,this.worktrees=deps.worktrees,this.tearDownSession=deps.tearDownSession,this.worktreeCoordinator=new WorktreeCoordinator(this.store,this.worktrees,canonPath,(repo)=>this.mainTasks.ensureIfEligible(repo)),this.mainTasks=new MainTaskCoordinator(this.store,(id)=>this.worktreeCoordinator.forget(id)),this.editor=new TaskEditor(this.store,this.worktrees),this.deletions=new TaskDeletionCoordinator(this.store,this.worktrees,(id)=>this.worktreeCoordinator.forget(id),deps.onSalvage,deps.onWorktreeResidue,deps.onBranchKept),this.tasksAcc=createStateCell(this.store.list());let persistedFocus=readLastActiveTaskId();this.activeTaskAcc=createStateCell(persistedFocus&&this.store.get(persistedFocus)?persistedFocus:null),this.unsubscribeStore=this.store.subscribe((snapshot)=>{this.tasksAcc.set(snapshot.slice())})}async init(){try{let promotable=promotableDirTasks({tasks:this.store.list(),isRepoRoot:(path)=>isGitRepo(path)&&samePath(resolveRepoRoot(path),path)});for(let task of promotable)await this.mainTasks.ensureIfEligible(task.repo,"explicit")}catch{}}activeTaskSignal(){return this.activeTaskAcc}async setActiveTask(id){let next=id===null?null:String(id);if(next&&this.store.get(next)?.deletion)throw new TaskDeletingError(next);if(this.activeTaskAcc.set(next),next&&this.store.get(next))writeLastActiveTaskId(next),this.store.touchRecency(next)}tasksSignal(){return this.tasksAcc}subscribeTasks(listener){return this.store.subscribe(listener)}dispose(){this.unsubscribeStore()}listTasks(){return this.store.list()}getTask(id){return this.store.get(id)}createTask=(input)=>createTaskRow({store:this.store,mainTasks:this.mainTasks,claimWorktreeName:(repo,name)=>this.worktreeCoordinator.claimWorktreeName(repo,name)},input);openDirectoryTask=(input)=>openDirectoryTaskRow({store:this.store},input);adoptScratchRepo=(id,repo)=>adoptScratchRepoRow({store:this.store},id,repo);async ensureMainTask(repo){return await this.mainTasks.ensure(repo)}async ensureWorktree(id){let task=this.requireTask(id);if(task.deletion)throw new TaskDeletingError(String(task.id));if(task.kind==="main")return repoWorkingDir(task.repo);if(task.kind==="dir")return task.worktreePath;if(task.worktreePath){if(await this.worktrees.pathExists(task.worktreePath))return task.worktreePath;return await this.worktrees.pruneWorktrees(task.repo),await this.store.update(task.id,{worktreePath:""}),this.worktreeCoordinator.ensure({...task,worktreePath:""})}return this.worktreeCoordinator.ensure(task)}async clearWorktreePath(id){let task=this.store.get(id);if(!task||!task.worktreePath)return;if(task.kind==="main"||task.kind==="dir")return;await this.store.update(task.id,{worktreePath:""}),this.worktreeCoordinator.forget(task.id)}setTitle=(id,title)=>this.editor.setTitle(id,title);setBranch=(id,branch)=>this.editor.setBranch(id,branch);observeLanguage=(id,text)=>this.editor.observeLanguage(id,text);setVendor=(id,vendor,effort,model)=>this.editor.setVendor(id,vendor,effort,model);setCommand=(id,command,vendor)=>this.editor.setCommand(id,command,vendor);setPinned=(id,pinned)=>this.editor.setPinned(id,pinned);moveTask=(id,delta)=>this.editor.moveTask(id,delta);moveTaskToTop=(id)=>this.editor.moveTaskToTop(id);setStatus=(id,status)=>this.editor.setStatus(id,status);setWorkerReport=(id,report)=>this.editor.setWorkerReport(id,report);setPRStatus=(id,prStatus)=>this.editor.setPRStatus(id,prStatus);setLinkedWorkItem=(id,item)=>this.editor.setLinkedWorkItem(id,item);setQuotaResume=(id,state)=>this.editor.setQuotaResume(id,state);setPrompt=(id,prompt)=>this.editor.setPrompt(id,prompt);async deleteTask(id,opts){await this.deletions.deleteNow(id,opts)}async prepareTaskDeletion(id,opts){return this.deletions.prepare(id,opts)}async beginTaskDeletion(id){return this.deletions.begin(id)}async finishTaskDeletion(id){return this.deletions.finish(id)}async landPreflight(id){let task=this.requireTask(id);if(task.kind==="main")throw Error("landTask: a main task has no branch to land");if(task.kind==="dir")throw Error("landTask: a directory task has no Rove-managed branch to land");if(task.deletion)throw new TaskDeletingError(String(task.id));return landPreflight(task)}async landTask(id,opts){let task=this.requireTask(id);if(task.deletion)throw new TaskDeletingError(String(task.id));return landTaskWithCleanup(task,opts??{},{worktrees:this.worktrees,clearWorktreePath:(tid)=>this.clearWorktreePath(tid),tearDownSession:this.tearDownSession})}async forgetProject(repo){await this.mainTasks.forget(repo)}async discoverAdoptableWorktrees(repo){if(!repo)throw Error("discoverAdoptableWorktrees: repo is required");return this.worktreeCoordinator.discoverAdoptable(repo)}async adoptWorktree(input){if(!input.repo)throw Error("adoptWorktree: repo is required");if(!input.worktreePath)throw Error("adoptWorktree: worktreePath is required");return this.worktreeCoordinator.adopt(input)}requireTask(id){let task=this.store.get(id);if(!task)throw new TaskNotFoundError(String(id));return task}}
4
+ export{Orchestrator};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{interactiveEngineCommand,listPresetIds}from"./chunk-ygd572ee.js";import{engineEntry}from"./chunk-ssfj9td0.js";import{installedEngineIds}from"./chunk-zwej00t0.js";import{spawnSync}from"child_process";import{statSync}from"fs";import path from"path";function whichOnPath(bin){let bunWhich=globalThis.Bun?.which;if(bunWhich)return bunWhich(bin);let out=spawnSync(process.platform==="win32"?"where":"which",[bin],{encoding:"utf8"});if(out.status!==0)return null;return out.stdout.split(`
2
+ import{interactiveEngineCommand,listPresetIds}from"./chunk-x9s14ppv.js";import{engineEntry}from"./chunk-y8tysjc2.js";import{installedEngineIds}from"./chunk-576r5nht.js";import{spawnSync}from"child_process";import{statSync}from"fs";import path from"path";function whichOnPath(bin){let bunWhich=globalThis.Bun?.which;if(bunWhich)return bunWhich(bin);let out=spawnSync(process.platform==="win32"?"where":"which",[bin],{encoding:"utf8"});if(out.status!==0)return null;return out.stdout.split(`
3
3
  `).map((l)=>l.trim()).find(Boolean)??null}var defaultDeps={which:whichOnPath,command:(vendor)=>interactiveEngineCommand(vendor)};function probeLaunchBinary(argv,which){let bin=argv[0]?.trim();if(!bin)return{found:!1,error:"no launch command"};if(bin.includes(path.sep)||bin.startsWith(".")){try{if(statSync(bin).isFile())return{found:!0,path:bin}}catch{}return{found:!1,error:`not found at ${bin}`}}let found=which(bin);return found?{found:!0,path:found}:{found:!1,error:"not found on PATH"}}async function detectEngineStatus(vendor,over={}){let deps={...defaultDeps,...over},detector=engineEntry(vendor).detectAccount;if(!detector)return{vendor,binary:probeLaunchBinary(deps.command(vendor),deps.which),account:null};let status=await detector(deps.accountDeps),binary=status.binary.found?status.binary:probeLaunchBinary(deps.command(vendor),deps.which);return{vendor,binary,account:status.account,accountError:status.accountError}}function detectEngineStatuses(vendors,over={}){return Promise.all(vendors.map((v)=>detectEngineStatus(v,over)))}function describeAccount(account){if(account===null)return"login not detectable";switch(account.kind){case"oauth":return"email"in account?`logged in (${account.email}${account.organization?`, ${account.organization}`:""})`:"logged in";case"chatgpt":return`logged in (${account.email}${account.plan?`, ${account.plan}`:""})`;case"apikey":return"API key";case"token":return`token (${account.source})`;default:return"no account"}}function engineUsable(status){return status.binary.found&&status.account?.kind!=="none"}async function probeableEngineIds(){return[...new Set([...listPresetIds(),...await installedEngineIds()])]}function summarizeEngines(statuses){let usable=[],signedOut=[];for(let status of statuses)if(engineUsable(status))usable.push(status.vendor);else if(status.binary.found)signedOut.push(status.vendor);return{usable,signedOut}}
4
4
  export{detectEngineStatus,detectEngineStatuses,describeAccount,probeableEngineIds,summarizeEngines};
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import{binaryAvailable,resolveEditorCommand}from"./chunk-hbn1t161.js";import"./chunk-6xppe9bj.js";import"./chunk-7kysxgbq.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import{kvStatePath}from"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{existsSync,mkdirSync,writeFileSync}from"fs";import{dirname}from"path";var CLI_NAME=ROVE_PRODUCT_NAME;function printUsage(out){out.write([`Usage: ${CLI_NAME} config [--path]`,"","Open Rove's user config (state.json \u2014 theme, locale, engine + editor prefs)","in your editor. The editor is your configured one (Settings \u2192 General \u2192","Editor); left on Auto it is $VISUAL / $EDITOR, else the first of","nvim / vim / emacs / nano.","Rove re-reads the file on its next launch.","","Options:"," --path Print the config file path and exit (don't open an editor)"," -h, --help Print this help",""].join(`
3
+ `))}async function runConfigSubcommand(argv=[]){if(argv.some((a)=>a==="-h"||a==="--help"||a==="help")){printUsage(process.stdout);return}let path=kvStatePath();if(argv.some((a)=>a==="--path"||a==="path")){console.log(path);return}let unknown=argv.find((a)=>a.length>0);if(unknown!==void 0)process.stderr.write(`${CLI_NAME} config: unexpected argument "${unknown}"
4
+ `),printUsage(process.stderr),process.exit(2);if(!existsSync(path))mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`{}
5
+ `);let resolved=await resolveEditorCommand(path);if(!resolved||!await binaryAvailable(resolved.bin))process.stderr.write(`${CLI_NAME} config: no editor found \u2014 set $EDITOR (or Settings \u2192 General \u2192 Editor), or edit directly:
6
+ ${path}
7
+ `),process.exit(1);let proc=Bun.spawn(["sh","-c",resolved.command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"});process.exit(await proc.exited)}export{runConfigSubcommand};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{ensureGlobalRoveHooks}from"./chunk-h33m6cc6.js";import{publishRoveTerminalTitle}from"./chunk-3aqhytyy.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-rqyaf0dw.js";import"./chunk-y8tysjc2.js";import"./chunk-576r5nht.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-2brn8e1y.js";import"./chunk-yexx8nec.js";import"./chunk-znjcesdr.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import{takeWelcome}from"./chunk-qd5zgq91.js";import{LAST_RUN_VERSION_KEY,enforceResetGate}from"./chunk-8rf7nzan.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import{CURRENT_VERSION,compareSemver}from"./chunk-7cce0st1.js";import{maybeHintSkillInstall}from"./chunk-g4c4ffqp.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import{loadStateFile,patchStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";var WHATS_NEW_SEEN_KEY="app.whatsNewSeenVersion";function whatsNewFromVersion(state,current=CURRENT_VERSION){let stamped=state[WHATS_NEW_SEEN_KEY]??state[LAST_RUN_VERSION_KEY];if(typeof stamped!=="string"||stamped.length===0)return null;return compareSemver(current,stamped)>0?stamped:null}function takeWhatsNew(){let from=whatsNewFromVersion(loadStateFile());try{patchStateFile({[WHATS_NEW_SEEN_KEY]:CURRENT_VERSION})}catch{}return from}async function startTui(){let whatsNewFrom=takeWhatsNew(),welcome=takeWelcome();enforceResetGate(),publishRoveTerminalTitle(),await maybeHintSkillInstall(),await ensureGlobalRoveHooks();let{loadPluginEngines}=await import("./chunk-ff1h2qxd.js");loadPluginEngines();let{startWorkspaceHost}=await import("./chunk-pqzbk1cz.js");await startWorkspaceHost({whatsNewFrom,welcome})}export{startTui};
@@ -1,12 +1,12 @@
1
1
  // @bun
2
- import{discoverMachine}from"./chunk-ww4fbx8h.js";import{addMachine,defaultMachineAlias,duplicateAliasOf,getMachine,isValidMachineAlias,listMachines,machineSocketDir,parseSshTarget,readMachines,removeMachine,sanitizeAlias,setMachineIdentity,sshTargetOf}from"./chunk-bs7v83x0.js";import{activeCliName}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import{loadStateFile}from"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";var CLI_NAME=activeCliName(),MACHINE_USAGE=[`Usage: ${CLI_NAME} machine <add|remove|list> [options]`,"","Manage the other computers running Rove. Each one is reached over SSH;","its tasks appear in the sidebar under a row of its own.","","Commands:"," add <ssh-target> Register a machine (verifies it before saving)"," remove <alias> Forget a machine (nothing on it is touched)"," list Show registered machines","","Add options:"," --alias <name> Local name for the machine (default: the target you typed)"," --port <n> SSH port (default: whatever ssh_config says)"," --identity <file> SSH private key (default: ssh-agent / ssh_config)",""," <ssh-target> is [user@]host[:port] \u2014 usually just an ssh_config Host alias."," The machine must already have Rove installed (`npm i -g @sma1lboy/rove`).",""].join(`
2
+ import{discoverMachine}from"./chunk-wtb8cycx.js";import{addMachine,defaultMachineAlias,duplicateAliasOf,getMachine,isValidMachineAlias,listMachines,machineSocketDir,parseSshTarget,readMachines,removeMachine,sanitizeAlias,setMachineIdentity,sshTargetOf}from"./chunk-9aydqazr.js";import{loadStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";var CLI_NAME=ROVE_PRODUCT_NAME,MACHINE_USAGE=[`Usage: ${CLI_NAME} machine <add|remove|list> [options]`,"","Manage the other computers running Rove. Each one is reached over SSH;","its tasks appear in the sidebar under a row of its own.","","Commands:"," add <ssh-target> Register a machine (verifies it before saving)"," remove <alias> Forget a machine (nothing on it is touched)"," list Show registered machines","","Add options:"," --alias <name> Local name for the machine (default: the target you typed)"," --port <n> SSH port (default: whatever ssh_config says)"," --identity <file> SSH private key (default: ssh-agent / ssh_config)",""," <ssh-target> is [user@]host[:port] \u2014 usually just an ssh_config Host alias."," The machine must already have Rove installed (`npm i -g @sma1lboy/rove`).",""].join(`
3
3
  `);function usageError(message){process.stderr.write(`${CLI_NAME} machine: ${message}
4
4
 
5
5
  ${MACHINE_USAGE}
6
6
  `),process.exit(2)}function fail(message){process.stderr.write(`${CLI_NAME} machine: ${message}
7
7
  `),process.exit(1)}function flagValue(argv,name){for(let i=0;i<argv.length;i++){let arg=argv[i];if(arg===void 0)continue;if(arg.startsWith(`--${name}=`))return arg.slice(name.length+3);if(arg!==`--${name}`)continue;let value=argv[i+1];if(value===void 0||value.startsWith("--"))usageError(`--${name} needs a value`);return value}return}async function runMachineSubcommand(argv){let[verb,...rest]=argv;if(!verb||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${MACHINE_USAGE}
8
8
  `);return}if(verb==="list")return list();if(verb==="add")return await add(rest);if(verb==="remove")return remove(rest);usageError(`unknown verb "${verb}"`)}async function add(argv){let target=positionalOf(argv);if(!target)usageError("add needs an ssh target, e.g. `machine add narwhal`");let parsed=parseSshTarget(target);if(!parsed)usageError(`"${target}" is not a valid ssh target ([user@]host[:port])`);let portFlag=flagValue(argv,"port"),port=portFlag?Number(portFlag):parsed.port;if(port!==void 0&&(!Number.isInteger(port)||port<1||port>65535))usageError("--port must be 1-65535");let identity=flagValue(argv,"identity"),requested=flagValue(argv,"alias");if(requested&&!isValidMachineAlias(requested))usageError(`--alias must be letters/digits/._- and cannot be "local" (got "${requested}")`);let probeAlias=requested??sanitizeAlias(parsed.host),config={host:parsed.host,...parsed.user?{user:parsed.user}:{},...port?{port}:{},auth:identity?{kind:"key",keyPath:identity}:{kind:"key"}};process.stderr.write(`${CLI_NAME} machine: contacting ${sshTargetOf(config)}\u2026
9
- `);let found=await discoverMachine(probeAlias,config);if(!found.ok)fail(found.message);let alias=requested??defaultMachineAlias({typedHost:parsed.host,typedUser:parsed.user,port,remoteHostname:found.status.hostname});if(!isValidMachineAlias(alias))fail(`could not derive a usable alias from "${found.status.hostname}" \u2014 pass --alias`);let identityTriple={hostname:found.status.hostname,homeDir:found.status.homeDir,daemonPid:found.status.daemonPid},duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identityTriple),sockets={daemon:found.status.socketPath,pty:found.status.ptySocketPath};addMachine(alias,{...config,identity:identityTriple,sockets}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-fwb72vzc.js"),up=await ensureForwards({alias,config,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(process.stdout.write(`${CLI_NAME} machine: ${alias} \u2192 ${sshTargetOf(config)} (rove ${found.status.kobeVersion||"?"} on ${found.status.hostname||"?"})
9
+ `);let found=await discoverMachine(probeAlias,config);if(!found.ok)fail(found.message);let alias=requested??defaultMachineAlias({typedHost:parsed.host,typedUser:parsed.user,port,remoteHostname:found.status.hostname});if(!isValidMachineAlias(alias))fail(`could not derive a usable alias from "${found.status.hostname}" \u2014 pass --alias`);let identityTriple={hostname:found.status.hostname,homeDir:found.status.homeDir,daemonPid:found.status.daemonPid},duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identityTriple),sockets={daemon:found.status.socketPath,pty:found.status.ptySocketPath};addMachine(alias,{...config,identity:identityTriple,sockets}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-3c58659p.js"),up=await ensureForwards({alias,config,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(process.stdout.write(`${CLI_NAME} machine: ${alias} \u2192 ${sshTargetOf(config)} (rove ${found.status.roveVersion||"?"} on ${found.status.hostname||"?"})
10
10
  `),!up)process.stderr.write(`${CLI_NAME} machine: registered, but could not forward ${alias}'s socket yet \u2014 it will show as offline until the connection comes up
11
11
  `);if(duplicate)process.stdout.write(`${CLI_NAME} machine: ${alias} is the same machine as ${duplicate} (hostname/homeDir/pid match) \u2014 the sidebar shows one row
12
12
  `)}function remove(argv){let alias=argv[0];if(!alias)usageError("remove needs an alias, e.g. `machine remove narwhal`");if(!getMachine(alias))fail(`no machine named "${alias}" (see \`${CLI_NAME} machine list\`)`);removeMachine(alias),process.stdout.write(`${CLI_NAME} machine: removed ${alias}. Nothing on that machine was changed \u2014 its daemon, tasks and worktrees are untouched.
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{errorMessage}from"./chunk-2brn8e1y.js";import{roveStateDir}from"./chunk-8hbtca1g.js";var claude_default={$schema:"https://opencode.ai/theme.json",defs:{darkBg:"#141413",darkBgRaised:"#1A1917",darkBgInset:"#2B2A27",darkBgMenu:"#33312E",darkBorderSubtle:"#2B2A27",darkBorder:"#3A3835",darkBorderActive:"#5C5853",darkText:"#EAE7DF",darkTextMuted:"#A9A39A",darkTextSubtle:"#6B665F",darkPrimary:"#CC785C",darkSecondary:"#D4967E",darkAccent:"#CC785C",darkAccentHover:"#E0AB96",darkRed:"#D47563",darkOrange:"#D97757",darkYellow:"#E8C96B",darkGreen:"#9ACA86",darkBlue:"#61AAF2",darkViolet:"#9B87F5",darkTerracotta:"#BF4D43",lightBg:"#FAF9F5",lightBgRaised:"#F0EEE6",lightBgInset:"#EAE7DF",lightBgMenu:"#E2DED4",lightBorderSubtle:"#EAE7DF",lightBorder:"#D9D5CC",lightBorderActive:"#A9A39A",lightText:"#1A1917",lightTextMuted:"#6B665F",lightTextSubtle:"#8D877D",lightPrimary:"#C96442",lightSecondary:"#B85F3D",lightAccent:"#CC785C",lightAccentHover:"#B85F3D",lightRed:"#A84B3A",lightOrange:"#C96442",lightYellow:"#8A6220",lightGreen:"#2E7C4C",lightBlue:"#207FDE",lightViolet:"#7B5BB6",lightTerracotta:"#BF4D43"},theme:{primary:{dark:"darkPrimary",light:"lightPrimary"},secondary:{dark:"darkSecondary",light:"lightSecondary"},accent:{dark:"darkAccent",light:"lightAccent"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkYellow",light:"lightYellow"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkBlue",light:"lightBlue"},text:{dark:"darkText",light:"lightText"},textMuted:{dark:"darkTextMuted",light:"lightTextMuted"},background:{dark:"darkBg",light:"lightBg"},backgroundPanel:{dark:"darkBgRaised",light:"lightBgRaised"},backgroundElement:{dark:"darkBgInset",light:"lightBgInset"},backgroundMenu:{dark:"darkBgMenu",light:"lightBgMenu"},backgroundDialog:{dark:"darkBgRaised",light:"lightBgRaised"},border:{dark:"darkBorder",light:"lightBorder"},borderActive:{dark:"darkBorderActive",light:"lightBorderActive"},borderSubtle:{dark:"darkBorderSubtle",light:"lightBorderSubtle"},diffAdded:{dark:"darkGreen",light:"lightGreen"},diffRemoved:{dark:"darkRed",light:"lightRed"},diffContext:{dark:"darkTextMuted",light:"lightTextSubtle"},diffHunkHeader:{dark:"darkTextMuted",light:"lightTextSubtle"},diffHighlightAdded:{dark:"#B5E0A0",light:"#1F6638"},diffHighlightRemoved:{dark:"#E89180",light:"#8A3A2C"},diffAddedBg:{dark:"#1F2A1F",light:"#E5EEDF"},diffRemovedBg:{dark:"#2A1F1C",light:"#F5DAD3"},diffContextBg:{dark:"darkBgRaised",light:"lightBgRaised"},diffLineNumber:{dark:"darkTextSubtle",light:"lightTextSubtle"},diffAddedLineNumberBg:{dark:"#1A2419",light:"#D5E2CC"},diffRemovedLineNumberBg:{dark:"#241915",light:"#EBC8BE"},markdownText:{dark:"darkText",light:"lightText"},markdownHeading:{dark:"darkPrimary",light:"lightPrimary"},markdownLink:{dark:"darkAccent",light:"lightAccent"},markdownLinkText:{dark:"darkBlue",light:"lightBlue"},markdownCode:{dark:"darkSecondary",light:"lightSecondary"},markdownBlockQuote:{dark:"darkTextMuted",light:"lightTextMuted"},markdownEmph:{dark:"darkYellow",light:"lightYellow"},markdownStrong:{dark:"darkPrimary",light:"lightPrimary"},markdownHorizontalRule:{dark:"darkTextMuted",light:"lightTextMuted"},markdownListItem:{dark:"darkAccent",light:"lightAccent"},markdownListEnumeration:{dark:"darkBlue",light:"lightBlue"},markdownImage:{dark:"darkAccent",light:"lightAccent"},markdownImageText:{dark:"darkBlue",light:"lightBlue"},markdownCodeBlock:{dark:"darkText",light:"lightText"},markdownQuote:{dark:"darkTextMuted",light:"lightTextMuted"},syntaxComment:{dark:"darkTextSubtle",light:"lightTextSubtle"},syntaxKeyword:{dark:"darkPrimary",light:"lightPrimary"},syntaxFunction:{dark:"darkBlue",light:"lightBlue"},syntaxVariable:{dark:"darkText",light:"lightText"},syntaxString:{dark:"darkGreen",light:"lightGreen"},syntaxNumber:{dark:"darkOrange",light:"lightOrange"},syntaxType:{dark:"darkViolet",light:"lightViolet"},syntaxOperator:{dark:"darkSecondary",light:"lightSecondary"},syntaxPunctuation:{dark:"darkText",light:"lightText"},selectedListItemText:{dark:"darkBg",light:"lightBg"}}};var conductor_default={$schema:"https://opencode.ai/theme.json",defs:{darkStep1:"#0a0a0a",darkStep2:"#111111",darkStep3:"#181818",darkStep4:"#1f1f1f",darkStep5:"#2a2a2a",darkStep6:"#363636",darkStep7:"#444444",darkStep8:"#5a5a5a",darkStep9:"#7a7a7a",darkStep10:"#9a9a9a",darkStep11:"#909090",darkStep12:"#e8e8e8",darkAccent:"#7da5c8",darkAccentBright:"#9bc3e3",darkRed:"#e06c75",darkOrange:"#d6a668",darkGreen:"#7fd88f",darkCyan:"#7da5c8",darkYellow:"#d6a668",lightStep1:"#fafafa",lightStep2:"#f3f3f3",lightStep3:"#ececec",lightStep4:"#e2e2e2",lightStep5:"#d4d4d4",lightStep6:"#bdbdbd",lightStep7:"#9c9c9c",lightStep8:"#7c7c7c",lightStep9:"#5b5b5b",lightStep10:"#404040",lightStep11:"#6c6c6c",lightStep12:"#1a1a1a",lightAccent:"#3d6f9f",lightAccentBright:"#1a4f87",lightRed:"#c9343a",lightOrange:"#a06b1a",lightGreen:"#3d9a57",lightCyan:"#3d6f9f",lightYellow:"#a06b1a"},theme:{primary:{dark:"darkStep12",light:"lightStep12"},secondary:{dark:"darkAccentBright",light:"lightAccentBright"},accent:{dark:"darkAccent",light:"lightAccent"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkOrange",light:"lightOrange"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkCyan",light:"lightCyan"},text:{dark:"darkStep12",light:"lightStep12"},textMuted:{dark:"darkStep11",light:"lightStep11"},background:{dark:"darkStep1",light:"lightStep1"},backgroundPanel:{dark:"darkStep2",light:"lightStep2"},backgroundElement:{dark:"darkStep3",light:"lightStep3"},backgroundMenu:{dark:"darkStep4",light:"lightStep4"},border:{dark:"darkStep6",light:"lightStep6"},borderActive:{dark:"darkStep8",light:"lightStep8"},borderSubtle:{dark:"darkStep4",light:"lightStep4"},diffAdded:{dark:"#7fd88f",light:"#3d9a57"},diffRemoved:{dark:"#e06c75",light:"#c9343a"},diffContext:{dark:"darkStep10",light:"lightStep10"},diffHunkHeader:{dark:"darkStep10",light:"lightStep10"},diffHighlightAdded:{dark:"#9be5ad",light:"#2d7a3f"},diffHighlightRemoved:{dark:"#f08490",light:"#a82530"},diffAddedBg:{dark:"#15241a",light:"#d8efdc"},diffRemovedBg:{dark:"#2a1518",light:"#f5dadc"},diffContextBg:{dark:"darkStep2",light:"lightStep2"},diffLineNumber:{dark:"darkStep9",light:"lightStep9"},diffAddedLineNumberBg:{dark:"#0f1c14",light:"#c5deca"},diffRemovedLineNumberBg:{dark:"#221012",light:"#e5c5c8"},markdownText:{dark:"darkStep12",light:"lightStep12"},markdownHeading:{dark:"darkStep12",light:"lightStep12"},markdownLink:{dark:"darkAccent",light:"lightAccent"},markdownCode:{dark:"darkAccentBright",light:"lightAccentBright"},markdownCodeBlock:{dark:"darkStep12",light:"lightStep12"},markdownQuote:{dark:"darkStep11",light:"lightStep11"},selectedListItemText:{dark:"darkStep1",light:"lightStep1"}}};var skylight_default={$schema:"https://raw.githubusercontent.com/sma1lboy/rove/main/packages/kobe/src/tui/context/theme/theme.schema.json",defs:{dayBg:"#FAFBFC",dayBgRaised:"#F2F5F8",dayBgInset:"#E7ECF2",dayBgFloat:"#FFFFFF",dayBorderSubtle:"#E4E9EF",dayBorder:"#D5DCE4",dayBorderActive:"#7F8C9D",dayText:"#16202C",dayTextMuted:"#556174",dayTextSubtle:"#8591A1",daySky:"#006F9E",dayViolet:"#7440D8",dayBlue:"#2E58D4",dayGreen:"#1A7746",dayAmber:"#8F5C00",dayRed:"#C22E29",nightBg:"#0B0D10",nightBgRaised:"#111419",nightBgInset:"#1A1F27",nightBgMenu:"#20262F",nightBgFloat:"#14181E",nightBorderSubtle:"#1C2129",nightBorder:"#272D36",nightBorderActive:"#5A6676",nightText:"#E6EBF1",nightTextMuted:"#95A0AF",nightTextSubtle:"#687384",nightSky:"#2FC0EC",nightViolet:"#B08CFF",nightBlue:"#7C9BFF",nightGreen:"#56CF8A",nightAmber:"#EFBC66",nightRed:"#FF6B5E"},theme:{primary:{dark:"nightSky",light:"daySky"},secondary:{dark:"nightViolet",light:"dayViolet"},accent:{dark:"nightSky",light:"daySky"},error:{dark:"nightRed",light:"dayRed"},warning:{dark:"nightAmber",light:"dayAmber"},success:{dark:"nightGreen",light:"dayGreen"},info:{dark:"nightBlue",light:"dayBlue"},text:{dark:"nightText",light:"dayText"},textMuted:{dark:"nightTextMuted",light:"dayTextMuted"},background:{dark:"nightBg",light:"dayBg"},backgroundPanel:{dark:"nightBgRaised",light:"dayBgRaised"},backgroundElement:{dark:"nightBgInset",light:"dayBgInset"},backgroundMenu:{dark:"nightBgMenu",light:"dayBgFloat"},backgroundDialog:{dark:"nightBgFloat",light:"dayBgFloat"},border:{dark:"nightBorder",light:"dayBorder"},borderActive:{dark:"nightBorderActive",light:"dayBorderActive"},borderSubtle:{dark:"nightBorderSubtle",light:"dayBorderSubtle"},diffAdded:{dark:"nightGreen",light:"dayGreen"},diffRemoved:{dark:"nightRed",light:"dayRed"},diffContext:{dark:"nightTextMuted",light:"dayTextMuted"},diffHunkHeader:{dark:"nightTextMuted",light:"dayTextMuted"},diffHighlightAdded:{dark:"#8FE3B0",light:"#145F38"},diffHighlightRemoved:{dark:"#FF9A90",light:"#9E2320"},diffAddedBg:{dark:"#10241A",light:"#E2F2E8"},diffRemovedBg:{dark:"#2A1517",light:"#FBE4E2"},diffContextBg:{dark:"nightBgRaised",light:"dayBgRaised"},diffLineNumber:{dark:"nightTextSubtle",light:"dayTextSubtle"},diffAddedLineNumberBg:{dark:"#0D1E15",light:"#D3EBDC"},diffRemovedLineNumberBg:{dark:"#231113",light:"#F5D3D0"},markdownText:{dark:"nightText",light:"dayText"},markdownHeading:{dark:"nightSky",light:"daySky"},markdownLink:{dark:"nightBlue",light:"dayBlue"},markdownLinkText:{dark:"nightBlue",light:"dayBlue"},markdownCode:{dark:"nightViolet",light:"dayViolet"},markdownBlockQuote:{dark:"nightTextMuted",light:"dayTextMuted"},markdownEmph:{dark:"nightAmber",light:"dayAmber"},markdownStrong:{dark:"nightText",light:"dayText"},markdownHorizontalRule:{dark:"nightBorderActive",light:"dayBorderActive"},markdownListItem:{dark:"nightSky",light:"daySky"},markdownListEnumeration:{dark:"nightSky",light:"daySky"},markdownImage:{dark:"nightBlue",light:"dayBlue"},markdownImageText:{dark:"nightBlue",light:"dayBlue"},markdownCodeBlock:{dark:"nightText",light:"dayText"},markdownQuote:{dark:"nightTextMuted",light:"dayTextMuted"},syntaxComment:{dark:"nightTextSubtle",light:"dayTextSubtle"},syntaxKeyword:{dark:"nightViolet",light:"dayViolet"},syntaxFunction:{dark:"nightBlue",light:"dayBlue"},syntaxVariable:{dark:"nightText",light:"dayText"},syntaxString:{dark:"nightGreen",light:"dayGreen"},syntaxNumber:{dark:"nightAmber",light:"dayAmber"},syntaxType:{dark:"nightSky",light:"daySky"},syntaxOperator:{dark:"nightTextMuted",light:"dayTextMuted"},syntaxPunctuation:{dark:"nightTextMuted",light:"dayTextMuted"},selectedListItemText:{dark:"nightBg",light:"dayBg"}}};var tokyonight_default={$schema:"https://opencode.ai/theme.json",defs:{darkStep1:"#1a1b26",darkStep2:"#1e2030",darkStep3:"#222436",darkStep4:"#292e42",darkStep5:"#3b4261",darkStep6:"#545c7e",darkStep7:"#737aa2",darkStep8:"#9099b2",darkStep9:"#82aaff",darkStep10:"#89b4fa",darkStep11:"#828bb8",darkStep12:"#c8d3f5",darkRed:"#ff757f",darkOrange:"#ff966c",darkYellow:"#ffc777",darkGreen:"#c3e88d",darkCyan:"#86e1fc",darkPurple:"#c099ff",lightStep1:"#e1e2e7",lightStep2:"#d5d6db",lightStep3:"#c8c9ce",lightStep4:"#b9bac1",lightStep5:"#a8aecb",lightStep6:"#9699a8",lightStep7:"#737a8c",lightStep8:"#5a607d",lightStep9:"#2e7de9",lightStep10:"#1a6ce7",lightStep11:"#8990a3",lightStep12:"#3760bf",lightRed:"#f52a65",lightOrange:"#b15c00",lightYellow:"#8c6c3e",lightGreen:"#587539",lightCyan:"#007197",lightPurple:"#9854f1"},theme:{primary:{dark:"darkStep9",light:"lightStep9"},secondary:{dark:"darkPurple",light:"lightPurple"},accent:{dark:"darkCyan",light:"lightCyan"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkOrange",light:"lightOrange"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkStep9",light:"lightStep9"},text:{dark:"darkStep12",light:"lightStep12"},textMuted:{dark:"darkStep11",light:"lightStep11"},background:{dark:"darkStep1",light:"lightStep1"},backgroundPanel:{dark:"darkStep2",light:"lightStep2"},backgroundElement:{dark:"darkStep3",light:"lightStep3"},border:{dark:"darkStep7",light:"lightStep7"},borderActive:{dark:"darkStep8",light:"lightStep8"},borderSubtle:{dark:"darkStep6",light:"lightStep6"},diffAdded:{dark:"#4fd6be",light:"#1e725c"},diffRemoved:{dark:"#c53b53",light:"#c53b53"},diffContext:{dark:"#828bb8",light:"#7086b5"},diffHunkHeader:{dark:"#828bb8",light:"#7086b5"},diffHighlightAdded:{dark:"#b8db87",light:"#4db380"},diffHighlightRemoved:{dark:"#e26a75",light:"#f52a65"},diffAddedBg:{dark:"#20303b",light:"#d5e5d5"},diffRemovedBg:{dark:"#37222c",light:"#f7d8db"},diffContextBg:{dark:"darkStep2",light:"lightStep2"},diffLineNumber:{dark:"#8f909a",light:"#59595b"},diffAddedLineNumberBg:{dark:"#1b2b34",light:"#c5d5c5"},diffRemovedLineNumberBg:{dark:"#2d1f26",light:"#e7c8cb"},markdownText:{dark:"darkStep12",light:"lightStep12"},markdownHeading:{dark:"darkPurple",light:"lightPurple"},markdownLink:{dark:"darkStep9",light:"lightStep9"},markdownLinkText:{dark:"darkCyan",light:"lightCyan"},markdownCode:{dark:"darkGreen",light:"lightGreen"},markdownBlockQuote:{dark:"darkYellow",light:"lightYellow"},markdownEmph:{dark:"darkYellow",light:"lightYellow"},markdownStrong:{dark:"darkOrange",light:"lightOrange"},markdownHorizontalRule:{dark:"darkStep11",light:"lightStep11"},markdownListItem:{dark:"darkStep9",light:"lightStep9"},markdownListEnumeration:{dark:"darkCyan",light:"lightCyan"},markdownImage:{dark:"darkStep9",light:"lightStep9"},markdownImageText:{dark:"darkCyan",light:"lightCyan"},markdownCodeBlock:{dark:"darkStep12",light:"lightStep12"},syntaxComment:{dark:"darkStep11",light:"lightStep11"},syntaxKeyword:{dark:"darkPurple",light:"lightPurple"},syntaxFunction:{dark:"darkStep9",light:"lightStep9"},syntaxVariable:{dark:"darkRed",light:"lightRed"},syntaxString:{dark:"darkGreen",light:"lightGreen"},syntaxNumber:{dark:"darkOrange",light:"lightOrange"},syntaxType:{dark:"darkYellow",light:"lightYellow"},syntaxOperator:{dark:"darkCyan",light:"lightCyan"},syntaxPunctuation:{dark:"darkStep12",light:"lightStep12"}}};var BUNDLED_THEME_JSONS={claude:claude_default,conductor:conductor_default,skylight:skylight_default,tokyonight:tokyonight_default};var RGB_RE=/^rgba?\(([^()]*)\)$/i;function isRgbLiteral(s){return RGB_RE.test(s.trim())}function channel(part){if(!/^\d{1,3}$/.test(part))return null;let n=Number(part);return n<=255?n:null}function alpha(part){if(!/^(?:0|1|0?\.\d+|1\.0+)$/.test(part))return null;return Math.round(Number(part)*255)}function parseRgbLiteral(value){let m=RGB_RE.exec(value.trim());if(!m)return null;let parts=m[1].split(",").map((p)=>p.trim());if(parts.length!==3&&parts.length!==4)return null;let r=channel(parts[0]),g=channel(parts[1]),b=channel(parts[2]);if(r===null||g===null||b===null)return null;let a=parts.length===4?alpha(parts[3]):255;if(a===null)return null;return{r,g,b,a}}function badRgbLiteral(value){if(!isRgbLiteral(value)||parseRgbLiteral(value))return null;return`\`${value}\` is not a valid rgb()/rgba() literal (channels 0-255, alpha 0-1, comma-separated)`}function isPlainObject(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function validateTheme(value){if(!isPlainObject(value))return{ok:!1,reason:"theme must be a JSON object at the top level"};let obj=value;if(!("theme"in obj))return{ok:!1,reason:"missing required key `theme`"};let theme=obj.theme;if(!isPlainObject(theme))return{ok:!1,reason:"`theme` must be an object map"};if("defs"in obj&&obj.defs!==void 0){if(!isPlainObject(obj.defs))return{ok:!1,reason:"`defs` must be an object map"};for(let[k,v]of Object.entries(obj.defs)){if(typeof v!=="string")return{ok:!1,reason:`defs.${k} must be a string (hex like "#abc" or a ref name)`};let bad=badRgbLiteral(v);if(bad)return{ok:!1,reason:`defs.${k}: ${bad}`}}}for(let[slot,raw]of Object.entries(theme)){if(typeof raw==="string"){let bad=badRgbLiteral(raw);if(bad)return{ok:!1,reason:`theme.${slot}: ${bad}`};continue}if(!isPlainObject(raw))return{ok:!1,reason:`theme.${slot} must be a string or a { dark, light } object (got ${raw===null?"null":Array.isArray(raw)?"array":typeof raw})`};let variant=raw;if(typeof variant.dark!=="string")return{ok:!1,reason:`theme.${slot}.dark must be a string`};if(typeof variant.light!=="string")return{ok:!1,reason:`theme.${slot}.light must be a string`};for(let mode of["dark","light"]){let bad=badRgbLiteral(variant[mode]);if(bad)return{ok:!1,reason:`theme.${slot}.${mode}: ${bad}`}}}if("$schema"in obj&&obj.$schema!==void 0&&typeof obj.$schema!=="string")return{ok:!1,reason:"`$schema` must be a string when present"};return{ok:!0,theme:obj}}import{readFileSync,readdirSync}from"fs";import{join}from"path";function userThemesDir(){return join(roveStateDir(),"themes")}function loadUserThemes(){let dir=userThemesDir(),entries;try{entries=readdirSync(dir)}catch{return[]}let out=[];for(let file of entries){if(!file.endsWith(".json"))continue;let path=join(dir,file),parsed;try{let text=readFileSync(path,"utf8");parsed=JSON.parse(text)}catch(err){let msg=errorMessage(err);console.warn(`[rove] skipping user theme ${path}: invalid JSON \u2014 ${msg}`);continue}let result=validateTheme(parsed);if(!result.ok){console.warn(`[rove] skipping user theme ${path}: ${result.reason}`);continue}let name=file.slice(0,-5);out.push({name,theme:result.theme})}return out}
2
+ import{errorMessage}from"./chunk-2brn8e1y.js";import{roveStateDir}from"./chunk-prqeddy7.js";var claude_default={$schema:"https://opencode.ai/theme.json",defs:{darkBg:"#141413",darkBgRaised:"#1A1917",darkBgInset:"#2B2A27",darkBgMenu:"#33312E",darkBorderSubtle:"#2B2A27",darkBorder:"#3A3835",darkBorderActive:"#5C5853",darkText:"#EAE7DF",darkTextMuted:"#A9A39A",darkTextSubtle:"#6B665F",darkPrimary:"#CC785C",darkSecondary:"#D4967E",darkAccent:"#CC785C",darkAccentHover:"#E0AB96",darkRed:"#D47563",darkOrange:"#D97757",darkYellow:"#E8C96B",darkGreen:"#9ACA86",darkBlue:"#61AAF2",darkViolet:"#9B87F5",darkTerracotta:"#BF4D43",lightBg:"#FAF9F5",lightBgRaised:"#F0EEE6",lightBgInset:"#EAE7DF",lightBgMenu:"#E2DED4",lightBorderSubtle:"#EAE7DF",lightBorder:"#D9D5CC",lightBorderActive:"#A9A39A",lightText:"#1A1917",lightTextMuted:"#6B665F",lightTextSubtle:"#8D877D",lightPrimary:"#C96442",lightSecondary:"#B85F3D",lightAccent:"#CC785C",lightAccentHover:"#B85F3D",lightRed:"#A84B3A",lightOrange:"#C96442",lightYellow:"#8A6220",lightGreen:"#2E7C4C",lightBlue:"#207FDE",lightViolet:"#7B5BB6",lightTerracotta:"#BF4D43"},theme:{primary:{dark:"darkPrimary",light:"lightPrimary"},secondary:{dark:"darkSecondary",light:"lightSecondary"},accent:{dark:"darkAccent",light:"lightAccent"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkYellow",light:"lightYellow"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkBlue",light:"lightBlue"},text:{dark:"darkText",light:"lightText"},textMuted:{dark:"darkTextMuted",light:"lightTextMuted"},background:{dark:"darkBg",light:"lightBg"},backgroundPanel:{dark:"darkBgRaised",light:"lightBgRaised"},backgroundElement:{dark:"darkBgInset",light:"lightBgInset"},backgroundMenu:{dark:"darkBgMenu",light:"lightBgMenu"},backgroundDialog:{dark:"darkBgRaised",light:"lightBgRaised"},border:{dark:"darkBorder",light:"lightBorder"},borderActive:{dark:"darkBorderActive",light:"lightBorderActive"},borderSubtle:{dark:"darkBorderSubtle",light:"lightBorderSubtle"},diffAdded:{dark:"darkGreen",light:"lightGreen"},diffRemoved:{dark:"darkRed",light:"lightRed"},diffContext:{dark:"darkTextMuted",light:"lightTextSubtle"},diffHunkHeader:{dark:"darkTextMuted",light:"lightTextSubtle"},diffHighlightAdded:{dark:"#B5E0A0",light:"#1F6638"},diffHighlightRemoved:{dark:"#E89180",light:"#8A3A2C"},diffAddedBg:{dark:"#1F2A1F",light:"#E5EEDF"},diffRemovedBg:{dark:"#2A1F1C",light:"#F5DAD3"},diffContextBg:{dark:"darkBgRaised",light:"lightBgRaised"},diffLineNumber:{dark:"darkTextSubtle",light:"lightTextSubtle"},diffAddedLineNumberBg:{dark:"#1A2419",light:"#D5E2CC"},diffRemovedLineNumberBg:{dark:"#241915",light:"#EBC8BE"},markdownText:{dark:"darkText",light:"lightText"},markdownHeading:{dark:"darkPrimary",light:"lightPrimary"},markdownLink:{dark:"darkAccent",light:"lightAccent"},markdownLinkText:{dark:"darkBlue",light:"lightBlue"},markdownCode:{dark:"darkSecondary",light:"lightSecondary"},markdownBlockQuote:{dark:"darkTextMuted",light:"lightTextMuted"},markdownEmph:{dark:"darkYellow",light:"lightYellow"},markdownStrong:{dark:"darkPrimary",light:"lightPrimary"},markdownHorizontalRule:{dark:"darkTextMuted",light:"lightTextMuted"},markdownListItem:{dark:"darkAccent",light:"lightAccent"},markdownListEnumeration:{dark:"darkBlue",light:"lightBlue"},markdownImage:{dark:"darkAccent",light:"lightAccent"},markdownImageText:{dark:"darkBlue",light:"lightBlue"},markdownCodeBlock:{dark:"darkText",light:"lightText"},markdownQuote:{dark:"darkTextMuted",light:"lightTextMuted"},syntaxComment:{dark:"darkTextSubtle",light:"lightTextSubtle"},syntaxKeyword:{dark:"darkPrimary",light:"lightPrimary"},syntaxFunction:{dark:"darkBlue",light:"lightBlue"},syntaxVariable:{dark:"darkText",light:"lightText"},syntaxString:{dark:"darkGreen",light:"lightGreen"},syntaxNumber:{dark:"darkOrange",light:"lightOrange"},syntaxType:{dark:"darkViolet",light:"lightViolet"},syntaxOperator:{dark:"darkSecondary",light:"lightSecondary"},syntaxPunctuation:{dark:"darkText",light:"lightText"},selectedListItemText:{dark:"darkBg",light:"lightBg"}}};var conductor_default={$schema:"https://opencode.ai/theme.json",defs:{darkStep1:"#0a0a0a",darkStep2:"#111111",darkStep3:"#181818",darkStep4:"#1f1f1f",darkStep5:"#2a2a2a",darkStep6:"#363636",darkStep7:"#444444",darkStep8:"#5a5a5a",darkStep9:"#7a7a7a",darkStep10:"#9a9a9a",darkStep11:"#909090",darkStep12:"#e8e8e8",darkAccent:"#7da5c8",darkAccentBright:"#9bc3e3",darkRed:"#e06c75",darkOrange:"#d6a668",darkGreen:"#7fd88f",darkCyan:"#7da5c8",darkYellow:"#d6a668",lightStep1:"#fafafa",lightStep2:"#f3f3f3",lightStep3:"#ececec",lightStep4:"#e2e2e2",lightStep5:"#d4d4d4",lightStep6:"#bdbdbd",lightStep7:"#9c9c9c",lightStep8:"#7c7c7c",lightStep9:"#5b5b5b",lightStep10:"#404040",lightStep11:"#6c6c6c",lightStep12:"#1a1a1a",lightAccent:"#3d6f9f",lightAccentBright:"#1a4f87",lightRed:"#c9343a",lightOrange:"#a06b1a",lightGreen:"#3d9a57",lightCyan:"#3d6f9f",lightYellow:"#a06b1a"},theme:{primary:{dark:"darkStep12",light:"lightStep12"},secondary:{dark:"darkAccentBright",light:"lightAccentBright"},accent:{dark:"darkAccent",light:"lightAccent"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkOrange",light:"lightOrange"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkCyan",light:"lightCyan"},text:{dark:"darkStep12",light:"lightStep12"},textMuted:{dark:"darkStep11",light:"lightStep11"},background:{dark:"darkStep1",light:"lightStep1"},backgroundPanel:{dark:"darkStep2",light:"lightStep2"},backgroundElement:{dark:"darkStep3",light:"lightStep3"},backgroundMenu:{dark:"darkStep4",light:"lightStep4"},border:{dark:"darkStep6",light:"lightStep6"},borderActive:{dark:"darkStep8",light:"lightStep8"},borderSubtle:{dark:"darkStep4",light:"lightStep4"},diffAdded:{dark:"#7fd88f",light:"#3d9a57"},diffRemoved:{dark:"#e06c75",light:"#c9343a"},diffContext:{dark:"darkStep10",light:"lightStep10"},diffHunkHeader:{dark:"darkStep10",light:"lightStep10"},diffHighlightAdded:{dark:"#9be5ad",light:"#2d7a3f"},diffHighlightRemoved:{dark:"#f08490",light:"#a82530"},diffAddedBg:{dark:"#15241a",light:"#d8efdc"},diffRemovedBg:{dark:"#2a1518",light:"#f5dadc"},diffContextBg:{dark:"darkStep2",light:"lightStep2"},diffLineNumber:{dark:"darkStep9",light:"lightStep9"},diffAddedLineNumberBg:{dark:"#0f1c14",light:"#c5deca"},diffRemovedLineNumberBg:{dark:"#221012",light:"#e5c5c8"},markdownText:{dark:"darkStep12",light:"lightStep12"},markdownHeading:{dark:"darkStep12",light:"lightStep12"},markdownLink:{dark:"darkAccent",light:"lightAccent"},markdownCode:{dark:"darkAccentBright",light:"lightAccentBright"},markdownCodeBlock:{dark:"darkStep12",light:"lightStep12"},markdownQuote:{dark:"darkStep11",light:"lightStep11"},selectedListItemText:{dark:"darkStep1",light:"lightStep1"}}};var skylight_default={$schema:"https://raw.githubusercontent.com/sma1lboy/rove/main/packages/rove/src/tui/context/theme/theme.schema.json",defs:{dayBg:"#FAFBFC",dayBgRaised:"#F2F5F8",dayBgInset:"#E7ECF2",dayBgFloat:"#FFFFFF",dayBorderSubtle:"#E4E9EF",dayBorder:"#D5DCE4",dayBorderActive:"#7F8C9D",dayText:"#16202C",dayTextMuted:"#556174",dayTextSubtle:"#8591A1",daySky:"#006F9E",dayViolet:"#7440D8",dayBlue:"#2E58D4",dayGreen:"#1A7746",dayAmber:"#8F5C00",dayRed:"#C22E29",nightBg:"#0B0D10",nightBgRaised:"#111419",nightBgInset:"#1A1F27",nightBgMenu:"#20262F",nightBgFloat:"#14181E",nightBorderSubtle:"#1C2129",nightBorder:"#272D36",nightBorderActive:"#5A6676",nightText:"#E6EBF1",nightTextMuted:"#95A0AF",nightTextSubtle:"#687384",nightSky:"#2FC0EC",nightViolet:"#B08CFF",nightBlue:"#7C9BFF",nightGreen:"#56CF8A",nightAmber:"#EFBC66",nightRed:"#FF6B5E"},theme:{primary:{dark:"nightSky",light:"daySky"},secondary:{dark:"nightViolet",light:"dayViolet"},accent:{dark:"nightSky",light:"daySky"},error:{dark:"nightRed",light:"dayRed"},warning:{dark:"nightAmber",light:"dayAmber"},success:{dark:"nightGreen",light:"dayGreen"},info:{dark:"nightBlue",light:"dayBlue"},text:{dark:"nightText",light:"dayText"},textMuted:{dark:"nightTextMuted",light:"dayTextMuted"},background:{dark:"nightBg",light:"dayBg"},backgroundPanel:{dark:"nightBgRaised",light:"dayBgRaised"},backgroundElement:{dark:"nightBgInset",light:"dayBgInset"},backgroundMenu:{dark:"nightBgMenu",light:"dayBgFloat"},backgroundDialog:{dark:"nightBgFloat",light:"dayBgFloat"},border:{dark:"nightBorder",light:"dayBorder"},borderActive:{dark:"nightBorderActive",light:"dayBorderActive"},borderSubtle:{dark:"nightBorderSubtle",light:"dayBorderSubtle"},diffAdded:{dark:"nightGreen",light:"dayGreen"},diffRemoved:{dark:"nightRed",light:"dayRed"},diffContext:{dark:"nightTextMuted",light:"dayTextMuted"},diffHunkHeader:{dark:"nightTextMuted",light:"dayTextMuted"},diffHighlightAdded:{dark:"#8FE3B0",light:"#145F38"},diffHighlightRemoved:{dark:"#FF9A90",light:"#9E2320"},diffAddedBg:{dark:"#10241A",light:"#E2F2E8"},diffRemovedBg:{dark:"#2A1517",light:"#FBE4E2"},diffContextBg:{dark:"nightBgRaised",light:"dayBgRaised"},diffLineNumber:{dark:"nightTextSubtle",light:"dayTextSubtle"},diffAddedLineNumberBg:{dark:"#0D1E15",light:"#D3EBDC"},diffRemovedLineNumberBg:{dark:"#231113",light:"#F5D3D0"},markdownText:{dark:"nightText",light:"dayText"},markdownHeading:{dark:"nightSky",light:"daySky"},markdownLink:{dark:"nightBlue",light:"dayBlue"},markdownLinkText:{dark:"nightBlue",light:"dayBlue"},markdownCode:{dark:"nightViolet",light:"dayViolet"},markdownBlockQuote:{dark:"nightTextMuted",light:"dayTextMuted"},markdownEmph:{dark:"nightAmber",light:"dayAmber"},markdownStrong:{dark:"nightText",light:"dayText"},markdownHorizontalRule:{dark:"nightBorderActive",light:"dayBorderActive"},markdownListItem:{dark:"nightSky",light:"daySky"},markdownListEnumeration:{dark:"nightSky",light:"daySky"},markdownImage:{dark:"nightBlue",light:"dayBlue"},markdownImageText:{dark:"nightBlue",light:"dayBlue"},markdownCodeBlock:{dark:"nightText",light:"dayText"},markdownQuote:{dark:"nightTextMuted",light:"dayTextMuted"},syntaxComment:{dark:"nightTextSubtle",light:"dayTextSubtle"},syntaxKeyword:{dark:"nightViolet",light:"dayViolet"},syntaxFunction:{dark:"nightBlue",light:"dayBlue"},syntaxVariable:{dark:"nightText",light:"dayText"},syntaxString:{dark:"nightGreen",light:"dayGreen"},syntaxNumber:{dark:"nightAmber",light:"dayAmber"},syntaxType:{dark:"nightSky",light:"daySky"},syntaxOperator:{dark:"nightTextMuted",light:"dayTextMuted"},syntaxPunctuation:{dark:"nightTextMuted",light:"dayTextMuted"},selectedListItemText:{dark:"nightBg",light:"dayBg"}}};var tokyonight_default={$schema:"https://opencode.ai/theme.json",defs:{darkStep1:"#1a1b26",darkStep2:"#1e2030",darkStep3:"#222436",darkStep4:"#292e42",darkStep5:"#3b4261",darkStep6:"#545c7e",darkStep7:"#737aa2",darkStep8:"#9099b2",darkStep9:"#82aaff",darkStep10:"#89b4fa",darkStep11:"#828bb8",darkStep12:"#c8d3f5",darkRed:"#ff757f",darkOrange:"#ff966c",darkYellow:"#ffc777",darkGreen:"#c3e88d",darkCyan:"#86e1fc",darkPurple:"#c099ff",lightStep1:"#e1e2e7",lightStep2:"#d5d6db",lightStep3:"#c8c9ce",lightStep4:"#b9bac1",lightStep5:"#a8aecb",lightStep6:"#9699a8",lightStep7:"#737a8c",lightStep8:"#5a607d",lightStep9:"#2e7de9",lightStep10:"#1a6ce7",lightStep11:"#8990a3",lightStep12:"#3760bf",lightRed:"#f52a65",lightOrange:"#b15c00",lightYellow:"#8c6c3e",lightGreen:"#587539",lightCyan:"#007197",lightPurple:"#9854f1"},theme:{primary:{dark:"darkStep9",light:"lightStep9"},secondary:{dark:"darkPurple",light:"lightPurple"},accent:{dark:"darkCyan",light:"lightCyan"},error:{dark:"darkRed",light:"lightRed"},warning:{dark:"darkOrange",light:"lightOrange"},success:{dark:"darkGreen",light:"lightGreen"},info:{dark:"darkStep9",light:"lightStep9"},text:{dark:"darkStep12",light:"lightStep12"},textMuted:{dark:"darkStep11",light:"lightStep11"},background:{dark:"darkStep1",light:"lightStep1"},backgroundPanel:{dark:"darkStep2",light:"lightStep2"},backgroundElement:{dark:"darkStep3",light:"lightStep3"},border:{dark:"darkStep7",light:"lightStep7"},borderActive:{dark:"darkStep8",light:"lightStep8"},borderSubtle:{dark:"darkStep6",light:"lightStep6"},diffAdded:{dark:"#4fd6be",light:"#1e725c"},diffRemoved:{dark:"#c53b53",light:"#c53b53"},diffContext:{dark:"#828bb8",light:"#7086b5"},diffHunkHeader:{dark:"#828bb8",light:"#7086b5"},diffHighlightAdded:{dark:"#b8db87",light:"#4db380"},diffHighlightRemoved:{dark:"#e26a75",light:"#f52a65"},diffAddedBg:{dark:"#20303b",light:"#d5e5d5"},diffRemovedBg:{dark:"#37222c",light:"#f7d8db"},diffContextBg:{dark:"darkStep2",light:"lightStep2"},diffLineNumber:{dark:"#8f909a",light:"#59595b"},diffAddedLineNumberBg:{dark:"#1b2b34",light:"#c5d5c5"},diffRemovedLineNumberBg:{dark:"#2d1f26",light:"#e7c8cb"},markdownText:{dark:"darkStep12",light:"lightStep12"},markdownHeading:{dark:"darkPurple",light:"lightPurple"},markdownLink:{dark:"darkStep9",light:"lightStep9"},markdownLinkText:{dark:"darkCyan",light:"lightCyan"},markdownCode:{dark:"darkGreen",light:"lightGreen"},markdownBlockQuote:{dark:"darkYellow",light:"lightYellow"},markdownEmph:{dark:"darkYellow",light:"lightYellow"},markdownStrong:{dark:"darkOrange",light:"lightOrange"},markdownHorizontalRule:{dark:"darkStep11",light:"lightStep11"},markdownListItem:{dark:"darkStep9",light:"lightStep9"},markdownListEnumeration:{dark:"darkCyan",light:"lightCyan"},markdownImage:{dark:"darkStep9",light:"lightStep9"},markdownImageText:{dark:"darkCyan",light:"lightCyan"},markdownCodeBlock:{dark:"darkStep12",light:"lightStep12"},syntaxComment:{dark:"darkStep11",light:"lightStep11"},syntaxKeyword:{dark:"darkPurple",light:"lightPurple"},syntaxFunction:{dark:"darkStep9",light:"lightStep9"},syntaxVariable:{dark:"darkRed",light:"lightRed"},syntaxString:{dark:"darkGreen",light:"lightGreen"},syntaxNumber:{dark:"darkOrange",light:"lightOrange"},syntaxType:{dark:"darkYellow",light:"lightYellow"},syntaxOperator:{dark:"darkCyan",light:"lightCyan"},syntaxPunctuation:{dark:"darkStep12",light:"lightStep12"}}};var BUNDLED_THEME_JSONS={claude:claude_default,conductor:conductor_default,skylight:skylight_default,tokyonight:tokyonight_default};var RGB_RE=/^rgba?\(([^()]*)\)$/i;function isRgbLiteral(s){return RGB_RE.test(s.trim())}function channel(part){if(!/^\d{1,3}$/.test(part))return null;let n=Number(part);return n<=255?n:null}function alpha(part){if(!/^(?:0|1|0?\.\d+|1\.0+)$/.test(part))return null;return Math.round(Number(part)*255)}function parseRgbLiteral(value){let m=RGB_RE.exec(value.trim());if(!m)return null;let parts=m[1].split(",").map((p)=>p.trim());if(parts.length!==3&&parts.length!==4)return null;let r=channel(parts[0]),g=channel(parts[1]),b=channel(parts[2]);if(r===null||g===null||b===null)return null;let a=parts.length===4?alpha(parts[3]):255;if(a===null)return null;return{r,g,b,a}}function badRgbLiteral(value){if(!isRgbLiteral(value)||parseRgbLiteral(value))return null;return`\`${value}\` is not a valid rgb()/rgba() literal (channels 0-255, alpha 0-1, comma-separated)`}function isPlainObject(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function validateTheme(value){if(!isPlainObject(value))return{ok:!1,reason:"theme must be a JSON object at the top level"};let obj=value;if(!("theme"in obj))return{ok:!1,reason:"missing required key `theme`"};let theme=obj.theme;if(!isPlainObject(theme))return{ok:!1,reason:"`theme` must be an object map"};if("defs"in obj&&obj.defs!==void 0){if(!isPlainObject(obj.defs))return{ok:!1,reason:"`defs` must be an object map"};for(let[k,v]of Object.entries(obj.defs)){if(typeof v!=="string")return{ok:!1,reason:`defs.${k} must be a string (hex like "#abc" or a ref name)`};let bad=badRgbLiteral(v);if(bad)return{ok:!1,reason:`defs.${k}: ${bad}`}}}for(let[slot,raw]of Object.entries(theme)){if(typeof raw==="string"){let bad=badRgbLiteral(raw);if(bad)return{ok:!1,reason:`theme.${slot}: ${bad}`};continue}if(!isPlainObject(raw))return{ok:!1,reason:`theme.${slot} must be a string or a { dark, light } object (got ${raw===null?"null":Array.isArray(raw)?"array":typeof raw})`};let variant=raw;if(typeof variant.dark!=="string")return{ok:!1,reason:`theme.${slot}.dark must be a string`};if(typeof variant.light!=="string")return{ok:!1,reason:`theme.${slot}.light must be a string`};for(let mode of["dark","light"]){let bad=badRgbLiteral(variant[mode]);if(bad)return{ok:!1,reason:`theme.${slot}.${mode}: ${bad}`}}}if("$schema"in obj&&obj.$schema!==void 0&&typeof obj.$schema!=="string")return{ok:!1,reason:"`$schema` must be a string when present"};return{ok:!0,theme:obj}}import{readFileSync,readdirSync}from"fs";import{join}from"path";function userThemesDir(){return join(roveStateDir(),"themes")}function loadUserThemes(){let dir=userThemesDir(),entries;try{entries=readdirSync(dir)}catch{return[]}let out=[];for(let file of entries){if(!file.endsWith(".json"))continue;let path=join(dir,file),parsed;try{let text=readFileSync(path,"utf8");parsed=JSON.parse(text)}catch(err){let msg=errorMessage(err);console.warn(`[rove] skipping user theme ${path}: invalid JSON \u2014 ${msg}`);continue}let result=validateTheme(parsed);if(!result.ok){console.warn(`[rove] skipping user theme ${path}: ${result.reason}`);continue}let name=file.slice(0,-5);out.push({name,theme:result.theme})}return out}
3
3
  export{BUNDLED_THEME_JSONS,parseRgbLiteral,validateTheme,userThemesDir,loadUserThemes};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{TaskIndexStore}from"./chunk-h7y9v8k1.js";import"./chunk-qkehg2c1.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-hq9tbzqa.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{TaskIndexStore};