@sma1lboy/rove 0.9.252 → 0.9.254

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 (186) hide show
  1. package/dist/cli/{chunk-r0etyq15.js → chunk-08ycv55d.js} +1 -1
  2. package/dist/cli/chunk-0g1me47p.js +2 -0
  3. package/dist/cli/{chunk-cvrtapqt.js → chunk-13msr643.js} +1 -1
  4. package/dist/cli/chunk-18dpws0y.js +2 -0
  5. package/dist/cli/{chunk-gaf6n1ea.js → chunk-1e6jbj70.js} +1 -1
  6. package/dist/cli/{chunk-07jq0271.js → chunk-1mpheecn.js} +1 -1
  7. package/dist/cli/{chunk-57wm48dh.js → chunk-1yzg4hzy.js} +1 -1
  8. package/dist/cli/{chunk-md094j05.js → chunk-278sc87n.js} +1 -1
  9. package/dist/cli/{chunk-q854fweb.js → chunk-3jnw3ftt.js} +1 -1
  10. package/dist/cli/chunk-3r8v2gza.js +2 -0
  11. package/dist/cli/{chunk-34468esa.js → chunk-4mxn5jg6.js} +1 -1
  12. package/dist/cli/{chunk-2ks86x2d.js → chunk-4myck788.js} +1 -1
  13. package/dist/cli/{chunk-sgegp9x9.js → chunk-4zhmbqt3.js} +1 -1
  14. package/dist/cli/chunk-5a6b4kv9.js +4 -0
  15. package/dist/cli/{chunk-5hhr44fc.js → chunk-5b7pd8j5.js} +1 -1
  16. package/dist/cli/chunk-5d0vb6v9.js +2 -0
  17. package/dist/cli/{chunk-9e21z4gn.js → chunk-5fhrns31.js} +1 -1
  18. package/dist/cli/{chunk-m3bz62v4.js → chunk-5j6z32fh.js} +1 -1
  19. package/dist/cli/chunk-5s4g1bkx.js +2 -0
  20. package/dist/cli/{chunk-q2fnt7gm.js → chunk-68gxqtse.js} +1 -1
  21. package/dist/cli/chunk-68pcd00x.js +2 -0
  22. package/dist/cli/chunk-6d5csfp4.js +2 -0
  23. package/dist/cli/{chunk-pgmv2hwf.js → chunk-6g5wvt5m.js} +2 -2
  24. package/dist/cli/{chunk-36pkmg07.js → chunk-6wxnkz3c.js} +10 -10
  25. package/dist/cli/{chunk-jn7vr075.js → chunk-6zvh002j.js} +1 -1
  26. package/dist/cli/{chunk-axmpjma9.js → chunk-7cd1epfw.js} +1 -1
  27. package/dist/cli/chunk-7ghwdjdc.js +3 -0
  28. package/dist/cli/chunk-7wga6bet.js +8 -0
  29. package/dist/cli/{chunk-jwnhthx9.js → chunk-7zpkyrxy.js} +1 -1
  30. package/dist/cli/{chunk-npb9xz3y.js → chunk-80zzjcvp.js} +1 -1
  31. package/dist/cli/{chunk-namxa4wy.js → chunk-8bd054vx.js} +1 -1
  32. package/dist/cli/{chunk-s5k3g5ra.js → chunk-9dendh71.js} +1 -1
  33. package/dist/cli/chunk-9g0vz9dk.js +209 -0
  34. package/dist/cli/chunk-9vd6fv1k.js +3 -0
  35. package/dist/cli/{chunk-tntdcyra.js → chunk-afwh7as3.js} +1 -1
  36. package/dist/cli/{chunk-9sta3ak4.js → chunk-ant4k6dm.js} +1 -1
  37. package/dist/cli/chunk-avz72132.js +3 -0
  38. package/dist/cli/chunk-ax7wzcam.js +2 -0
  39. package/dist/cli/{chunk-zk5qkkb1.js → chunk-axxf5dkq.js} +1 -1
  40. package/dist/cli/{chunk-a7kq09ke.js → chunk-b31cte10.js} +1 -1
  41. package/dist/cli/{chunk-fktvtdkb.js → chunk-bphs6am4.js} +1 -1
  42. package/dist/cli/chunk-cjxvb9vg.js +2 -0
  43. package/dist/cli/chunk-cm923k09.js +52 -0
  44. package/dist/cli/{chunk-6a4xqzqf.js → chunk-d48g9zzm.js} +3 -3
  45. package/dist/cli/{chunk-zzzm2cfx.js → chunk-d4mvprvq.js} +2 -2
  46. package/dist/cli/{chunk-952aedqm.js → chunk-ddc4t38t.js} +1 -1
  47. package/dist/cli/{chunk-resmnaxq.js → chunk-dehnv06q.js} +1 -1
  48. package/dist/cli/{chunk-y1cb8pj5.js → chunk-dqprpnd6.js} +1 -1
  49. package/dist/cli/chunk-dx72asyw.js +2 -0
  50. package/dist/cli/{chunk-e8pv3b92.js → chunk-e5vnptx5.js} +1 -1
  51. package/dist/cli/chunk-edsm15ht.js +4 -0
  52. package/dist/cli/{chunk-2rfyjb3y.js → chunk-ef7ckm5b.js} +1 -1
  53. package/dist/cli/{chunk-s2t9acrv.js → chunk-f6836h0n.js} +1 -1
  54. package/dist/cli/{chunk-s5a5dyab.js → chunk-fnsch8kr.js} +2 -2
  55. package/dist/cli/chunk-ft6ftksv.js +2 -0
  56. package/dist/cli/{chunk-trjve2xz.js → chunk-fwt0t2h7.js} +1 -1
  57. package/dist/cli/{chunk-ra40m849.js → chunk-gb3qb83h.js} +1 -1
  58. package/dist/cli/chunk-ghyz3fd7.js +4 -0
  59. package/dist/cli/chunk-gqpka00s.js +30 -0
  60. package/dist/cli/{chunk-4ays3krf.js → chunk-hqp8b49k.js} +2 -2
  61. package/dist/cli/{chunk-h3q3r1py.js → chunk-hzzq6pdb.js} +1 -1
  62. package/dist/cli/{chunk-x8pk5cyf.js → chunk-j19gkhzh.js} +1 -1
  63. package/dist/cli/{chunk-b67pjyyg.js → chunk-j26zqrnq.js} +1 -1
  64. package/dist/cli/{chunk-24dryfqb.js → chunk-j7831wcj.js} +1 -1
  65. package/dist/cli/{chunk-t3v57v42.js → chunk-j84zbw79.js} +2 -2
  66. package/dist/cli/chunk-j9c9tdfg.js +2 -0
  67. package/dist/cli/{chunk-zcadc92x.js → chunk-jetsx9zr.js} +1 -1
  68. package/dist/cli/{chunk-5q08srg6.js → chunk-jtpjdmb6.js} +1 -1
  69. package/dist/cli/chunk-jwtqe209.js +2 -0
  70. package/dist/cli/{chunk-w2sp489k.js → chunk-k3wzznqw.js} +1 -1
  71. package/dist/cli/chunk-k7ke95vy.js +5 -0
  72. package/dist/cli/chunk-k9ahks28.js +41 -0
  73. package/dist/cli/{chunk-nz9nmp4v.js → chunk-kwd59v51.js} +1 -1
  74. package/dist/cli/{chunk-j6t7xvm3.js → chunk-m0cbndc2.js} +1 -1
  75. package/dist/cli/{chunk-a7m7w6d1.js → chunk-m6qv5rsv.js} +1 -1
  76. package/dist/cli/{chunk-4e1wcgw7.js → chunk-mpdfhvgs.js} +3 -3
  77. package/dist/cli/chunk-mxkm0snt.js +2 -0
  78. package/dist/cli/chunk-n3wdy4z4.js +2 -0
  79. package/dist/cli/{chunk-tfqrc2v1.js → chunk-n5xj11ps.js} +3 -3
  80. package/dist/cli/{chunk-kda565xs.js → chunk-p5902z3e.js} +1 -1
  81. package/dist/cli/chunk-pahcf9td.js +3 -0
  82. package/dist/cli/{chunk-rc8baevh.js → chunk-pkq8n3gs.js} +2 -2
  83. package/dist/cli/{chunk-2bxts9pp.js → chunk-pvah9q79.js} +1 -1
  84. package/dist/cli/chunk-pyv2ywxr.js +3 -0
  85. package/dist/cli/chunk-qb6ktr8a.js +2 -0
  86. package/dist/cli/{chunk-mw0ysrpd.js → chunk-qk5f6p3e.js} +1 -1
  87. package/dist/cli/{chunk-rxge7bh5.js → chunk-qkd4eweb.js} +1 -1
  88. package/dist/cli/{chunk-h7y9v8k1.js → chunk-r4bn0mtb.js} +1 -1
  89. package/dist/cli/{chunk-ayhkcv0w.js → chunk-r7q7s63y.js} +2 -2
  90. package/dist/cli/{chunk-cbd6y9at.js → chunk-rf4z7b6g.js} +1 -1
  91. package/dist/cli/{chunk-25867jnk.js → chunk-rn97jntv.js} +1 -1
  92. package/dist/cli/{chunk-1tebqkdv.js → chunk-rnxk3587.js} +1 -1
  93. package/dist/cli/chunk-s96qnht3.js +2 -0
  94. package/dist/cli/chunk-sma961wh.js +3 -0
  95. package/dist/cli/{chunk-p2jeq98m.js → chunk-stcvcsfm.js} +1 -1
  96. package/dist/cli/{chunk-qh4y4e27.js → chunk-sxhjvr0w.js} +1 -1
  97. package/dist/cli/{chunk-0gxa04rx.js → chunk-sxt12set.js} +1 -1
  98. package/dist/cli/chunk-tbq3t259.js +2 -0
  99. package/dist/cli/{chunk-jp31bpgp.js → chunk-tewt7vre.js} +1 -1
  100. package/dist/cli/{chunk-1v8y9xtk.js → chunk-tmz0wzq8.js} +1 -1
  101. package/dist/cli/{chunk-zb5d61xa.js → chunk-tnft1xw4.js} +1 -1
  102. package/dist/cli/{chunk-032g0ahy.js → chunk-tq6pq1ws.js} +1 -1
  103. package/dist/cli/{chunk-x0rvg54z.js → chunk-v0jvt60f.js} +1 -1
  104. package/dist/cli/{chunk-qyfmfpjg.js → chunk-v7prawj1.js} +1 -1
  105. package/dist/cli/chunk-v8s0s21v.js +2 -0
  106. package/dist/cli/{chunk-t5qayy7m.js → chunk-v9dcyjmj.js} +1 -1
  107. package/dist/cli/chunk-v9fgdd90.js +3 -0
  108. package/dist/cli/chunk-vfwbgx85.js +2 -0
  109. package/dist/cli/{chunk-a1wjg2cv.js → chunk-vvw1njx5.js} +1 -1
  110. package/dist/cli/chunk-vzn94t0z.js +6 -0
  111. package/dist/cli/{chunk-vgknea9y.js → chunk-wbtebbrv.js} +1 -1
  112. package/dist/cli/{chunk-meyfwc50.js → chunk-wkk63qck.js} +1 -1
  113. package/dist/cli/chunk-wn2w5ar9.js +2 -0
  114. package/dist/cli/{chunk-2s762g8n.js → chunk-wsv6tw1b.js} +1 -1
  115. package/dist/cli/{chunk-2n1n70f2.js → chunk-x40h0f1w.js} +1 -1
  116. package/dist/cli/{chunk-0y4qgnby.js → chunk-x5ymh8ev.js} +1 -1
  117. package/dist/cli/{chunk-568q390y.js → chunk-x7r75e3p.js} +2 -2
  118. package/dist/cli/{chunk-7h7270rz.js → chunk-x7ryv67y.js} +2 -2
  119. package/dist/cli/{chunk-phpt1d3e.js → chunk-x951qvk5.js} +1 -1
  120. package/dist/cli/{chunk-ebhbtvhd.js → chunk-xdhs40fx.js} +1 -1
  121. package/dist/cli/chunk-xg6zg6kz.js +2 -0
  122. package/dist/cli/{chunk-21ek142k.js → chunk-xkr7fwvb.js} +1 -1
  123. package/dist/cli/{chunk-nqtvthqg.js → chunk-xpxxgzw9.js} +1 -1
  124. package/dist/cli/{chunk-7j00hbq5.js → chunk-y330t2bt.js} +2 -2
  125. package/dist/cli/{chunk-hq9tbzqa.js → chunk-y55zpren.js} +1 -1
  126. package/dist/cli/chunk-yebn33mf.js +2 -0
  127. package/dist/cli/chunk-ykdpg0zd.js +15 -0
  128. package/dist/cli/{chunk-qstjfseh.js → chunk-yshp8cmx.js} +1 -1
  129. package/dist/cli/chunk-z3zaa155.js +3 -0
  130. package/dist/cli/{chunk-npwzmmv9.js → chunk-z7zm8h1q.js} +2 -2
  131. package/dist/cli/index.js +8 -8
  132. package/dist/cli/pty-host-node.mjs +3 -0
  133. package/dist/cli/rove-run.js +1 -1
  134. package/dist/cli/rove.js +1 -1
  135. package/dist/completions/rove.bash +1 -1
  136. package/dist/completions/rove.fish +1 -1
  137. package/dist/completions/rove.zsh +1 -1
  138. package/dist/skills/rove/SKILL.md +61 -2
  139. package/dist/skills/rove/references/api-flags.md +75 -29
  140. package/dist/web/assets/{index-DHlgMx7L.js → index-BydepNFM.js} +3 -3
  141. package/dist/web/index.html +1 -1
  142. package/dist/web-ui/assets/{harness-BHiciz5A.js → harness-dYkQBfYz.js} +3 -3
  143. package/dist/web-ui/assets/{index-BkxJISAI.js → index-ByMdqeTv.js} +2 -2
  144. package/dist/web-ui/index.html +1 -1
  145. package/package.json +3 -3
  146. package/dist/cli/chunk-17pg88dq.js +0 -22
  147. package/dist/cli/chunk-1zwp3ase.js +0 -2
  148. package/dist/cli/chunk-2bp01vf2.js +0 -2
  149. package/dist/cli/chunk-2g2w5vvn.js +0 -2
  150. package/dist/cli/chunk-564jgrb3.js +0 -2
  151. package/dist/cli/chunk-5qxp7xx3.js +0 -2
  152. package/dist/cli/chunk-6f01fsje.js +0 -2
  153. package/dist/cli/chunk-7zxf47xb.js +0 -2
  154. package/dist/cli/chunk-8e0nmegv.js +0 -2
  155. package/dist/cli/chunk-9dregrj6.js +0 -5
  156. package/dist/cli/chunk-9h940gnr.js +0 -2
  157. package/dist/cli/chunk-9mcpqrx8.js +0 -2
  158. package/dist/cli/chunk-bhm24ne6.js +0 -9
  159. package/dist/cli/chunk-c0ksxg3z.js +0 -3
  160. package/dist/cli/chunk-cb1dg7nz.js +0 -2
  161. package/dist/cli/chunk-ccn7pq03.js +0 -5
  162. package/dist/cli/chunk-cpv1rpc7.js +0 -2
  163. package/dist/cli/chunk-csdttpme.js +0 -52
  164. package/dist/cli/chunk-fz0xfw86.js +0 -2
  165. package/dist/cli/chunk-h89ghyex.js +0 -2
  166. package/dist/cli/chunk-jnj2kk2h.js +0 -3
  167. package/dist/cli/chunk-kqv7t8jk.js +0 -8
  168. package/dist/cli/chunk-kx0wzjj4.js +0 -2
  169. package/dist/cli/chunk-m2t2n474.js +0 -6
  170. package/dist/cli/chunk-n2xemv4a.js +0 -2
  171. package/dist/cli/chunk-n92fz0hn.js +0 -2
  172. package/dist/cli/chunk-nj53wrzz.js +0 -2
  173. package/dist/cli/chunk-pdvyfz3n.js +0 -3
  174. package/dist/cli/chunk-pj3gnkfr.js +0 -3
  175. package/dist/cli/chunk-q3xt0mqt.js +0 -3
  176. package/dist/cli/chunk-qzsahxd9.js +0 -3
  177. package/dist/cli/chunk-r2c5nbcq.js +0 -4
  178. package/dist/cli/chunk-rf0jrh3q.js +0 -2
  179. package/dist/cli/chunk-rj7fwa30.js +0 -2
  180. package/dist/cli/chunk-sbn5pbz9.js +0 -2
  181. package/dist/cli/chunk-va0n5rwm.js +0 -39
  182. package/dist/cli/chunk-va5am5n6.js +0 -2
  183. package/dist/cli/chunk-vd8qqev9.js +0 -4
  184. package/dist/cli/chunk-vwpcv7j1.js +0 -4
  185. package/dist/cli/chunk-yknavm97.js +0 -3
  186. package/dist/cli/chunk-yt24rrvx.js +0 -2
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{errorMessage}from"./chunk-2brn8e1y.js";import{isObject}from"./chunk-7ghwdjdc.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 validateTheme(value){if(!isObject(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(!isObject(theme))return{ok:!1,reason:"`theme` must be an object map"};if("defs"in obj&&obj.defs!==void 0){if(!isObject(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(!isObject(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
+ export{BUNDLED_THEME_JSONS,parseRgbLiteral,validateTheme,userThemesDir,loadUserThemes};
@@ -1,3 +1,3 @@
1
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};
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 defaultDeliveriesPath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"deliveries.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,defaultDeliveriesPath,defaultWebTokenPath,defaultPtyFreezeDir,defaultDeliveryLockDir};
package/dist/cli/index.js CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{matchPathGlob}from"./chunk-kg11c1py.js";import{failureHint}from"./chunk-qyfmfpjg.js";import{switchFlag}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-9sta3ak4.js";import"./chunk-gaf6n1ea.js";import"./chunk-7j00hbq5.js";import{expandTilde}from"./chunk-ag3txfg2.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{CURRENT_VERSION}from"./chunk-j6t7xvm3.js";import{rejectionReason}from"./chunk-3342qzve.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-032g0ahy.js";import"./chunk-q3xt0mqt.js";import"./chunk-cmp64q4j.js";import"./chunk-s5a5dyab.js";import"./chunk-md094j05.js";import"./chunk-hq9tbzqa.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.ROVE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}
3
+ import{matchPathGlob}from"./chunk-kg11c1py.js";import{failureHint}from"./chunk-v7prawj1.js";import{switchFlag}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-ant4k6dm.js";import"./chunk-1e6jbj70.js";import"./chunk-y330t2bt.js";import{expandTilde}from"./chunk-ag3txfg2.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{CURRENT_VERSION}from"./chunk-m0cbndc2.js";import{rejectionReason}from"./chunk-3342qzve.js";import"./chunk-b31cte10.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-tq6pq1ws.js";import"./chunk-sma961wh.js";import"./chunk-cmp64q4j.js";import"./chunk-fnsch8kr.js";import"./chunk-278sc87n.js";import"./chunk-y55zpren.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";import"./chunk-z7zm8h1q.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.ROVE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}
4
4
  ${failureHint(err,opts.cliName)}`;let raw=errorMessage(err),git=summarizeCliGitError(raw,opts.cwd);return`${subject}: ${git??`${raw}
5
- ${failureHint(err,opts.cliName)}`}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-ayhkcv0w.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-vgknea9y.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-b67pjyyg.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-5qxp7xx3.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-t3v57v42.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-axmpjma9.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-ebhbtvhd.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-7h7270rz.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-tfqrc2v1.js");await runMachineSubcommand(args)}],["weixin",async(args)=>{let{runChannelCli}=await import("./chunk-zb5d61xa.js");await runChannelCli("weixin",args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-pgmv2hwf.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-qstjfseh.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-5hhr44fc.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-cvrtapqt.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-6a4xqzqf.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-4e1wcgw7.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-rj7fwa30.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-nj53wrzz.js"),{GitWorktreeManager}=await import("./chunk-2bp01vf2.js"),{Orchestrator}=await import("./chunk-1zwp3ase.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-tntdcyra.js"),{projectRejection}=await import("./chunk-4z01vg3t.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${ROVE_PRODUCT_NAME}: "${arg}" is not a directory (resolved to ${dir}).
6
- `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-cb1dg7nz.js");writeLastActiveTaskId(String(task.id))}});let{publishRoveTerminalTitle}=await import("./chunk-g8wrdp7n.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-9e21z4gn.js");await launchTui()}function topLevelUsage(cliName=ROVE_PRODUCT_NAME){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|doctor|remove|list)"," weixin <verb> Talk to Rove from WeChat (login|logout|status|allow|deny)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"," --web [bridge flags] Serve the browser client on 127.0.0.1 and print its link"].join(`
5
+ ${failureHint(err,opts.cliName)}`}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-r7q7s63y.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-wbtebbrv.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-j26zqrnq.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-0g1me47p.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-j84zbw79.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-7cd1epfw.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-xdhs40fx.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-x7ryv67y.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-n5xj11ps.js");await runMachineSubcommand(args)}],["weixin",async(args)=>{let{runChannelCli}=await import("./chunk-tnft1xw4.js");await runChannelCli("weixin",args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-6g5wvt5m.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-yshp8cmx.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-5b7pd8j5.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-13msr643.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-d48g9zzm.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-mpdfhvgs.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-6d5csfp4.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-v8s0s21v.js"),{GitWorktreeManager}=await import("./chunk-qb6ktr8a.js"),{Orchestrator}=await import("./chunk-cjxvb9vg.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-afwh7as3.js"),{projectRejection}=await import("./chunk-4z01vg3t.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${ROVE_PRODUCT_NAME}: "${arg}" is not a directory (resolved to ${dir}).
6
+ `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-dx72asyw.js");writeLastActiveTaskId(String(task.id))}});let{publishRoveTerminalTitle}=await import("./chunk-g8wrdp7n.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-5fhrns31.js");await launchTui()}function topLevelUsage(cliName=ROVE_PRODUCT_NAME){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|doctor|remove|list)"," weixin <verb> Talk to Rove from WeChat (login|logout|status|allow|deny)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"," --web [bridge flags] Serve the browser client on 127.0.0.1 and print its link"].join(`
7
7
  `)}var CLI_NAME=ROVE_PRODUCT_NAME,ADD_USAGE=[`Usage: ${CLI_NAME} add [path]`,` ${CLI_NAME} add --remote --host <host> --user <user> --path <basePath> [--port N] [--key [path] | --password]`,"","Save a repo for the new-task picker. With --remote, register an SSH-backed","project whose worktrees live on <host>; engine launch over SSH is pending.",""].join(`
8
- `);async function runAddSubcommand(rest){let arg=rest[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(ADD_USAGE);return}if(arg==="--remote"){let{runAddRemote}=await import("./chunk-nqtvthqg.js");await runAddRemote(rest.slice(1));return}if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} add: unknown flag "${arg}"
8
+ `);async function runAddSubcommand(rest){let arg=rest[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(ADD_USAGE);return}if(arg==="--remote"){let{runAddRemote}=await import("./chunk-xpxxgzw9.js");await runAddRemote(rest.slice(1));return}if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} add: unknown flag "${arg}"
9
9
 
10
- ${ADD_USAGE}`),process.exit(2);let target=resolve2(process.cwd(),expandTilde(arg&&arg.length>0?arg:".")),{addSavedRepo}=await import("./chunk-tntdcyra.js"),result=addSavedRepo(target);if(result.rejected)process.stderr.write(`${CLI_NAME} add: "${arg&&arg.length>0?arg:"."}" cannot be a project \u2014 ${rejectionReason(result.rejected)} (resolved to ${result.path}).
10
+ ${ADD_USAGE}`),process.exit(2);let target=resolve2(process.cwd(),expandTilde(arg&&arg.length>0?arg:".")),{addSavedRepo}=await import("./chunk-afwh7as3.js"),result=addSavedRepo(target);if(result.rejected)process.stderr.write(`${CLI_NAME} add: "${arg&&arg.length>0?arg:"."}" cannot be a project \u2014 ${rejectionReason(result.rejected)} (resolved to ${result.path}).
11
11
  `),process.exit(1);if(result.added)console.log(`added ${result.path} (${result.total} saved repo${result.total===1?"":"s"} total)`);else console.log(`already saved: ${result.path}`);await ensureProjectMainTask(result.path),await adoptAllWorktrees(result.path)}async function ensureProjectMainTask(repo){try{await withDaemonOrLocal({daemon:(client)=>client.request("task.ensureMain",{repo}),local:(orch)=>orch.ensureMainTask(repo)})}catch(err){console.error(`(skipped project main-task setup: ${errorMessage(err)}). Run ${CLI_NAME} doctor, then retry ${CLI_NAME} add.`)}}var PURGE_FLAG="--purge-credentials",REMOVE_USAGE=[`Usage: ${CLI_NAME} remove [path] [--purge-credentials]`,"","Forget a saved project (drop it from the new-task picker). Non-destructive:","the repo's files, worktrees, branches and tasks all stay on disk. A remote","(ssh://) project also has its stored connection config dropped.",""," path defaults to the current directory. Pass an exact saved entry (e.g. a"," remote `ssh://user@host` key) to remove it verbatim. Run with no match to"," print the current saved projects.",""," --purge-credentials also delete the remote project's SSH password from"," the OS keychain. Off by default: forgetting a project"," should not silently destroy a stored secret.",""].join(`
12
12
  `);async function runRemoveSubcommand(rest){let purgeCredentials=switchFlag(rest,PURGE_FLAG),arg=rest.filter((a)=>a!==PURGE_FLAG&&!a.startsWith(`${PURGE_FLAG}=`))[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(REMOVE_USAGE);return}if(purgeCredentials===void 0)process.stderr.write(`${CLI_NAME} remove: ${PURGE_FLAG} takes true or false
13
13
 
14
14
  ${REMOVE_USAGE}`),process.exit(2);if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} remove: unknown flag "${arg}"
15
15
 
16
- ${REMOVE_USAGE}`),process.exit(2);let{getRemoteRepoConfig,getSavedRepos,resolveRepoRoot}=await import("./chunk-tntdcyra.js"),saved=getSavedRepos();if(saved.length===0){console.log("no saved projects to remove.");return}let raw=arg&&arg.length>0?arg:".",target=saved.includes(raw)?raw:(()=>{let abs=resolve2(process.cwd(),expandTilde(raw)),top=resolveRepoRoot(abs);if(saved.includes(top))return top;if(saved.includes(abs))return abs;return null})();if(target===null){process.stderr.write(`${CLI_NAME} remove: "${raw}" is not a saved project.
16
+ ${REMOVE_USAGE}`),process.exit(2);let{getRemoteRepoConfig,getSavedRepos,resolveRepoRoot}=await import("./chunk-afwh7as3.js"),saved=getSavedRepos();if(saved.length===0){console.log("no saved projects to remove.");return}let raw=arg&&arg.length>0?arg:".",target=saved.includes(raw)?raw:(()=>{let abs=resolve2(process.cwd(),expandTilde(raw)),top=resolveRepoRoot(abs);if(saved.includes(top))return top;if(saved.includes(abs))return abs;return null})();if(target===null){process.stderr.write(`${CLI_NAME} remove: "${raw}" is not a saved project.
17
17
 
18
18
  Saved projects:
19
19
  `);for(let p of saved)process.stderr.write(` ${p}
@@ -22,8 +22,8 @@ Saved projects:
22
22
 
23
23
  ${ADOPT_USAGE}
24
24
  `),process.exit(2)}async function runAdoptSubcommand(args){let glob,repoArg,vendorArg,yes=!1;for(let i=0;i<args.length;i++){let a=args[i];if(a==="--help"||a==="-h"||a==="help"){process.stdout.write(`${ADOPT_USAGE}
25
- `);return}if(a==="--repo"){if(repoArg=args[++i],repoArg===void 0)adoptUsageError("--repo requires a value")}else if(a==="--vendor"){if(vendorArg=args[++i],vendorArg===void 0)adoptUsageError("--vendor requires a value")}else if(a==="--yes"||a==="-y")yes=!0;else if(a&&!a.startsWith("-")&&glob===void 0)glob=a;else adoptUsageError(`unexpected argument "${a}"`)}let{getCustomEngineIds,resolveRepoRoot}=await import("./chunk-tntdcyra.js"),repo=resolveRepoRoot(resolve2(process.cwd(),expandTilde(repoArg&&repoArg.length>0?repoArg:"."))),typed=vendorArg?.trim();if(typed&&!isBuiltinVendor(typed)&&!getCustomEngineIds().includes(typed)){let known=[...BUILTIN_VENDORS,...getCustomEngineIds()].join(", ");adoptUsageError(`unknown engine "${typed}" \u2014 no task was created. Known engines: ${known}`)}let vendor=coerceVendorId(vendorArg),orch=await openLocalOrchestrator(),worktrees=await orch.discoverAdoptableWorktrees(repo);if(worktrees.length===0){console.log(`no adoptable worktrees for ${repo} \u2014 every git worktree here is already a task`);return}let isMatch=(w)=>!glob||matchPathGlob(glob,w.path);console.log(`adoptable worktrees in ${repo}:`);for(let w of worktrees){let hit=glob?isMatch(w)?"*":" ":"-",tags=[w.dirty===!0?"dirty":w.dirty===null?"dirty?":"",w.roveManaged?"":"external"].filter(Boolean).join(",");console.log(` ${hit} ${w.branch} ${w.path}${tags?` (${tags})`:""}`)}if(!glob){console.log(`
25
+ `);return}if(a==="--repo"){if(repoArg=args[++i],repoArg===void 0)adoptUsageError("--repo requires a value")}else if(a==="--vendor"){if(vendorArg=args[++i],vendorArg===void 0)adoptUsageError("--vendor requires a value")}else if(a==="--yes"||a==="-y")yes=!0;else if(a&&!a.startsWith("-")&&glob===void 0)glob=a;else adoptUsageError(`unexpected argument "${a}"`)}let{getCustomEngineIds,resolveRepoRoot}=await import("./chunk-afwh7as3.js"),repo=resolveRepoRoot(resolve2(process.cwd(),expandTilde(repoArg&&repoArg.length>0?repoArg:"."))),typed=vendorArg?.trim();if(typed&&!isBuiltinVendor(typed)&&!getCustomEngineIds().includes(typed)){let known=[...BUILTIN_VENDORS,...getCustomEngineIds()].join(", ");adoptUsageError(`unknown engine "${typed}" \u2014 no task was created. Known engines: ${known}`)}let vendor=coerceVendorId(vendorArg),orch=await openLocalOrchestrator(),worktrees=await orch.discoverAdoptableWorktrees(repo);if(worktrees.length===0){console.log(`no adoptable worktrees for ${repo} \u2014 every git worktree here is already a task`);return}let isMatch=(w)=>!glob||matchPathGlob(glob,w.path);console.log(`adoptable worktrees in ${repo}:`);for(let w of worktrees){let hit=glob?isMatch(w)?"*":" ":"-",tags=[w.dirty===!0?"dirty":w.dirty===null?"dirty?":"",w.roveManaged?"":"external"].filter(Boolean).join(",");console.log(` ${hit} ${w.branch} ${w.path}${tags?` (${tags})`:""}`)}if(!glob){console.log(`
26
26
  pass a path glob to adopt, e.g. ${CLI_NAME} adopt '${repo}/*' --yes`);return}let matched=worktrees.filter(isMatch);if(matched.length===0){console.log(`
27
27
  no worktrees match glob ${JSON.stringify(glob)}`);return}if(!yes){console.log(`
28
28
  ${matched.length} worktree(s) match \u2014 re-run with --yes to adopt them`);return}await adoptWorktreesInto(orch,repo,matched,vendor),console.log(`done \u2014 adopted ${matched.length} worktree(s)`)}function printTopLevelUsage(out){out.write(`${topLevelUsage()}
29
- `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-25867jnk.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-6a4xqzqf.js");await runSkillSubcommand(["print"]);return}if(subcommand==="--web"){let{runWebSubcommand}=await import("./chunk-2bxts9pp.js");await runWebSubcommand(rest);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishRoveTerminalTitle}=await import("./chunk-g8wrdp7n.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-9e21z4gn.js");await launchTui()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
29
+ `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-rn97jntv.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-d48g9zzm.js");await runSkillSubcommand(["print"]);return}if(subcommand==="--web"){let{runWebSubcommand}=await import("./chunk-pvah9q79.js");await runWebSubcommand(rest);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishRoveTerminalTitle}=await import("./chunk-g8wrdp7n.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-5fhrns31.js");await launchTui()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
@@ -683,6 +683,8 @@ function ensureOwnerOnlyStateDir(homeDir) {
683
683
 
684
684
  // ../rove-daemon/src/daemon/automation-contracts.ts
685
685
  var ROUTINE_RESPONSE_WINDOW_MS = 2 * 60 * 60000;
686
+ // ../rove-daemon/src/daemon/delivery-contracts.ts
687
+ var DELIVERY_STALL_MS = 10 * 60000;
686
688
  // ../rove-plugin-sdk/dist/mod-tree.js
687
689
  var ALLOWED = {
688
690
  box: new Set(["type", "direction", "gap", "padding", "border", "children"]),
@@ -698,6 +700,7 @@ var DAEMON_CHANNELS = [
698
700
  "update",
699
701
  "engine-state",
700
702
  "attention.inbox",
703
+ "gates",
701
704
  "ui-prefs",
702
705
  "keybindings",
703
706
  "task.jobs",
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{migrateRoveClientStateLayout}from"./chunk-tdhk4dz8.js";import{updateStateFile}from"./chunk-zk5qkkb1.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import{kvStatePath}from"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{readFileSync}from"fs";var RENAMED_KEY_PREFIXES=[{from:"autoEffort.",to:"autoRouting."}],NOTHING={moved:0,superseded:0};function legacyRename(key){for(let{from,to}of RENAMED_KEY_PREFIXES)if(key.startsWith(from))return`${to}${key.slice(from.length)}`;return}function isStateObject(text){try{let parsed=JSON.parse(text);return typeof parsed==="object"&&parsed!==null&&!Array.isArray(parsed)}catch{return!1}}function migrateRenamedStateKeys(){let text;try{text=readFileSync(kvStatePath(),"utf8")}catch{return NOTHING}if(!RENAMED_KEY_PREFIXES.some(({from})=>text.includes(`"${from}`)))return NOTHING;if(!isStateObject(text))return NOTHING;let moved=0,superseded=0;try{updateStateFile((state)=>{for(let[key,value]of Object.entries(state)){let renamed=legacyRename(key);if(renamed===void 0)continue;if(renamed in state)superseded+=1;else state[renamed]=value,moved+=1;delete state[key]}return moved+superseded>0})}catch{return NOTHING}return{moved,superseded}}function prepareCliStateLayout(env=process.env){let result=migrateRoveClientStateLayout(env);for(let warning of result.warnings)console.error(`[rove] state migration will retry: ${warning}. Check the source/destination permissions, then relaunch Rove.`);migrateRenamedStateKeys()}prepareCliStateLayout();await import("./index.js");
3
+ import{isObject}from"./chunk-7ghwdjdc.js";import{migrateRoveClientStateLayout}from"./chunk-tdhk4dz8.js";import{updateStateFile}from"./chunk-axxf5dkq.js";import"./chunk-qk5f6p3e.js";import"./chunk-b31cte10.js";import{kvStatePath}from"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-z7zm8h1q.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{readFileSync}from"fs";var RENAMED_KEY_PREFIXES=[{from:"autoEffort.",to:"autoRouting."}],NOTHING={moved:0,superseded:0};function legacyRename(key){for(let{from,to}of RENAMED_KEY_PREFIXES)if(key.startsWith(from))return`${to}${key.slice(from.length)}`;return}function isStateObject(text){try{let parsed=JSON.parse(text);return isObject(parsed)}catch{return!1}}function migrateRenamedStateKeys(){let text;try{text=readFileSync(kvStatePath(),"utf8")}catch{return NOTHING}if(!RENAMED_KEY_PREFIXES.some(({from})=>text.includes(`"${from}`)))return NOTHING;if(!isStateObject(text))return NOTHING;let moved=0,superseded=0;try{updateStateFile((state)=>{for(let[key,value]of Object.entries(state)){let renamed=legacyRename(key);if(renamed===void 0)continue;if(renamed in state)superseded+=1;else state[renamed]=value,moved+=1;delete state[key]}return moved+superseded>0})}catch{return NOTHING}return{moved,superseded}}function prepareCliStateLayout(env=process.env){let result=migrateRoveClientStateLayout(env);for(let warning of result.warnings)console.error(`[rove] state migration will retry: ${warning}. Check the source/destination permissions, then relaunch Rove.`);migrateRenamedStateKeys()}prepareCliStateLayout();await import("./index.js");
package/dist/cli/rove.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{join as n}from"node:path";import{createInterface as a}from"node:readline/promises";import{pathToFileURL as ss}from"node:url";import{spawnSync as Q}from"node:child_process";import{constants as V,accessSync as R}from"node:fs";import{homedir as e}from"node:os";import{basename as I,delimiter as U,dirname as o,join as y}from"node:path";import{fileURLToPath as T}from"node:url";var H={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.252",description:"Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.22","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-bridge":"0.0.13","rove-weixin":"0.0.13",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var q="rove";var k=q;var z="ROVE_BUN",_="ROVE_NO_BUN_BOOTSTRAP",F="ROVE_SKIP_BUN_CHECK",$=H.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",L=(s)=>{try{return R(s,V.X_OK),!0}catch{return!1}},B=(s)=>s==="win32"?"bun.exe":"bun",f=(s)=>{let t=Q(s,["--version"],{encoding:"utf8",timeout:5000});if(t.error||t.status!==0)return null;return t.stdout?.split(`
2
+ import{join as n}from"node:path";import{createInterface as a}from"node:readline/promises";import{pathToFileURL as ss}from"node:url";import{spawnSync as Q}from"node:child_process";import{constants as V,accessSync as R}from"node:fs";import{homedir as e}from"node:os";import{basename as I,delimiter as U,dirname as o,join as y}from"node:path";import{fileURLToPath as T}from"node:url";var H={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.254",description:"Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.22","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-bridge":"0.0.15","rove-weixin":"0.0.15",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var q="rove";var k=q;var z="ROVE_BUN",_="ROVE_NO_BUN_BOOTSTRAP",F="ROVE_SKIP_BUN_CHECK",$=H.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",L=(s)=>{try{return R(s,V.X_OK),!0}catch{return!1}},B=(s)=>s==="win32"?"bun.exe":"bun",f=(s)=>{let t=Q(s,["--version"],{encoding:"utf8",timeout:5000});if(t.error||t.status!==0)return null;return t.stdout?.split(`
3
3
  `)[0]?.trim()??""};function J(s){return s.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function X(s,t=$){let c=J(s),W=J(t);if(!c||!W)return!0;let b=c.split(".").map(Number),g=W.split(".").map(Number);for(let x=0;x<3;x++){let i=b[x]??0,r=g[x]??0;if(i!==r)return i>r}return!0}function Y(s=process.env){return s[F]==="1"}function A(s={}){let t=s.env??process.env,c=s.platform??process.platform,W=s.home??t.HOME??t.USERPROFILE??e(),b=B(c),g=[],x=t[z]?.trim();if(x)g.push(x);for(let G of(t.PATH??t.Path??"").split(U))if(G)g.push(y(G,b));let i=t.BUN_INSTALL?.trim();if(i)g.push(y(i,"bin",b));if(W)g.push(y(W,".bun","bin",b));let r=s.launcherDir;if(r)g.push(y(r,"..","..","node_modules","bun","bin",b)),g.push(y(r,"..","..","..","bun","bin",b));return g}function N(s={}){let t=s.isExecutable??L;return A(s).find((c)=>t(c))??null}function Z(s={}){let t=s.isExecutable??L,c=s.bunVersionOf??f;if(Y(s.env??process.env))return{bun:N(s),stale:null,unusable:null};let W=null,b=null;for(let g of A(s)){if(!t(g))continue;let x=c(g);if(x===null){b??=g;continue}if(X(x))return{bun:g,stale:W,unusable:b};W??={path:g,version:J(x)??x}}return{bun:null,stale:W,unusable:b}}function h(s){return o(T(s))}function C(s){return I(T(s)).replace(/\.[cm]?[jt]s$/,"")}function u(s=process.platform){return s==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(s=k,t=process.platform){let c=t==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${s}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${c}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${z}=/path/to/bun`,""].join(`
4
4
  `)}function j(s,t,c=k){return[`${c}: this machine's Bun is too old for Rove — found ${t} at ${s}, need ${$} or newer.`,"","Rove's terminals are built on Bun's PTY API. An older Bun ignores it silently,","so every terminal and engine tab would open empty and stay empty.","","Upgrade Bun, then run this command again:"," bun upgrade # Bun installed itself (~/.bun)"," brew upgrade bun # Homebrew"," npm install -g bun@latest # npm-managed Bun","",`Have a newer Bun elsewhere? Point Rove at it: ${z}=/path/to/bun`,`Run on this one anyway (unsupported, terminals will be blank): ${F}=1`,""].join(`
5
5
  `)}function v(s,t=k){return[`${t}: the Bun at ${s} could not be run — \`${s} --version\` failed or never returned.`,"","Rove skipped it rather than starting through it, which would hang or fail","with a message from that binary instead of this one.","","Reinstall Bun, then run this command again:"," curl -fsSL https://bun.sh/install | bash","",`Have a working Bun elsewhere? Point Rove at it: ${z}=/path/to/bun`,""].join(`
@@ -12,7 +12,7 @@ _rove() {
12
12
  fi
13
13
  if [[ ${COMP_CWORD} -eq 2 ]]; then
14
14
  case "${prev}" in
15
- api) COMPREPLY=( $(compgen -W "schema engine-list list get-task pty-list collect context digest agent-turns inspect read-output watch add send dispatch interrupt note note-list note-delete pane-open pane-close pane-graphics tab-close tab-new tab-split notify prompt engine-report row-token set-active feedback issue-list issue-create issue-update issue-delete routine-list routine-create routine-update routine-delete routine-run-now routine-respond routine-runs workitem-list workitem-start update land delete ensure-worktree remove-worktree discover-adoptable adopt" -- "${cur}") ) ;;
15
+ api) COMPREPLY=( $(compgen -W "schema engine-list list get-task pty-list collect context digest agent-turns inspect read-output watch deliveries should-run add send dispatch interrupt note note-list note-delete pane-open pane-close pane-graphics tab-close tab-new tab-split notify prompt engine-report row-token set-active report attention-dismiss gate-raise gate-answer gate-withdraw gates feedback issue-list issue-create issue-update issue-delete routine-list routine-create routine-update routine-delete routine-run-now routine-respond routine-runs workitem-list workitem-start update land delete ensure-worktree remove-worktree discover-adoptable adopt" -- "${cur}") ) ;;
16
16
  daemon) COMPREPLY=( $(compgen -W "status start stop restart" -- "${cur}") ) ;;
17
17
  machine) COMPREPLY=( $(compgen -W "add doctor remove list" -- "${cur}") ) ;;
18
18
  plugin) COMPREPLY=( $(compgen -W "install link list search outdated update enable disable unlink uninstall config-dir log action pane" -- "${cur}") ) ;;
@@ -19,7 +19,7 @@ complete -c rove -f -n __fish_use_subcommand -a skill
19
19
  complete -c rove -f -n __fish_use_subcommand -a plugin
20
20
  complete -c rove -f -n __fish_use_subcommand -a feedback
21
21
  complete -c rove -f -n __fish_use_subcommand -a update
22
- complete -c rove -f -n "__fish_seen_subcommand_from api" -a "schema engine-list list get-task pty-list collect context digest agent-turns inspect read-output watch add send dispatch interrupt note note-list note-delete pane-open pane-close pane-graphics tab-close tab-new tab-split notify prompt engine-report row-token set-active feedback issue-list issue-create issue-update issue-delete routine-list routine-create routine-update routine-delete routine-run-now routine-respond routine-runs workitem-list workitem-start update land delete ensure-worktree remove-worktree discover-adoptable adopt"
22
+ complete -c rove -f -n "__fish_seen_subcommand_from api" -a "schema engine-list list get-task pty-list collect context digest agent-turns inspect read-output watch deliveries should-run add send dispatch interrupt note note-list note-delete pane-open pane-close pane-graphics tab-close tab-new tab-split notify prompt engine-report row-token set-active report attention-dismiss gate-raise gate-answer gate-withdraw gates feedback issue-list issue-create issue-update issue-delete routine-list routine-create routine-update routine-delete routine-run-now routine-respond routine-runs workitem-list workitem-start update land delete ensure-worktree remove-worktree discover-adoptable adopt"
23
23
  complete -c rove -f -n "__fish_seen_subcommand_from daemon" -a "status start stop restart"
24
24
  complete -c rove -f -n "__fish_seen_subcommand_from machine" -a "add doctor remove list"
25
25
  complete -c rove -f -n "__fish_seen_subcommand_from plugin" -a "install link list search outdated update enable disable unlink uninstall config-dir log action pane"
@@ -13,7 +13,7 @@ _rove() {
13
13
 
14
14
  verbs=()
15
15
  case "${words[2]}" in
16
- api) verbs=("schema" "engine-list" "list" "get-task" "pty-list" "collect" "context" "digest" "agent-turns" "inspect" "read-output" "watch" "add" "send" "dispatch" "interrupt" "note" "note-list" "note-delete" "pane-open" "pane-close" "pane-graphics" "tab-close" "tab-new" "tab-split" "notify" "prompt" "engine-report" "row-token" "set-active" "feedback" "issue-list" "issue-create" "issue-update" "issue-delete" "routine-list" "routine-create" "routine-update" "routine-delete" "routine-run-now" "routine-respond" "routine-runs" "workitem-list" "workitem-start" "update" "land" "delete" "ensure-worktree" "remove-worktree" "discover-adoptable" "adopt") ;;
16
+ api) verbs=("schema" "engine-list" "list" "get-task" "pty-list" "collect" "context" "digest" "agent-turns" "inspect" "read-output" "watch" "deliveries" "should-run" "add" "send" "dispatch" "interrupt" "note" "note-list" "note-delete" "pane-open" "pane-close" "pane-graphics" "tab-close" "tab-new" "tab-split" "notify" "prompt" "engine-report" "row-token" "set-active" "report" "attention-dismiss" "gate-raise" "gate-answer" "gate-withdraw" "gates" "feedback" "issue-list" "issue-create" "issue-update" "issue-delete" "routine-list" "routine-create" "routine-update" "routine-delete" "routine-run-now" "routine-respond" "routine-runs" "workitem-list" "workitem-start" "update" "land" "delete" "ensure-worktree" "remove-worktree" "discover-adoptable" "adopt") ;;
17
17
  daemon) verbs=("status" "start" "stop" "restart") ;;
18
18
  machine) verbs=("add" "doctor" "remove" "list") ;;
19
19
  plugin) verbs=("install" "link" "list" "search" "outdated" "update" "enable" "disable" "unlink" "uninstall" "config-dir" "log" "action" "pane") ;;
@@ -3,7 +3,7 @@ name: rove
3
3
  description: Use when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell. Also the ONLY channel for messaging another agent session on this machine — `rove api send`, never a peer/MCP side channel.
4
4
  ---
5
5
 
6
- <!-- rove-skill-version: 61 — bump in lockstep with ROVE_SKILL_VERSION (src/lib/skill-install.ts). -->
6
+ <!-- rove-skill-version: 64 — bump in lockstep with ROVE_SKILL_VERSION (src/lib/skill-install.ts). -->
7
7
 
8
8
  # Rove shell control
9
9
 
@@ -273,7 +273,7 @@ turn either. These five carry almost all traffic:
273
273
 
274
274
  ```text
275
275
  add --repo(REQ) --prompt --title --command --count --agents --activate
276
- send --prompt|--prompt-file(REQ) --task-id --tab --command --plain
276
+ send --prompt|--prompt-file(REQ) --task-id --tab --command --plain --expect-report --if-runnable
277
277
  get-task --task-id(REQ) list (no flags)
278
278
  collect --group <groupId> | --task-ids <csv> | --repo
279
279
  ```
@@ -294,6 +294,7 @@ Find your section by what you were ASKED, not by Rove's noun for it:
294
294
  | track work in Rove's own backlog, move a kanban card | issues |
295
295
  | remember this for the repo, leave a field note / 记一笔 | drive |
296
296
  | what did the agent do, per-turn cost, read its screen | read |
297
+ | a prompt ends `[ROVE] … report with: rove api report`; tick a task unattended and want proof it reported, or skip a tick the task can't use | drive (`report`, `send --expect-report`, `send --if-runnable`) / read (`deliveries`, `should-run`) |
297
298
  | make / rename / retarget / land / close a task | create / edit / lifecycle |
298
299
  | materialize or adopt a checkout | worktree |
299
300
  | which engines exist, send Rove product feedback | discover / feedback |
@@ -420,6 +421,17 @@ below the minimum usable size (20×6 cells) falls back to a tab.
420
421
  Panes land in the USER'S live workspace — open them when asked (monitors,
421
422
  logs, dashboards), don't scatter panes for work `add` should own.
422
423
 
424
+ ## Asking the owner (decision gates)
425
+
426
+ A question only the owner can answer goes through a gate, not a MEMO line or the tail of a long report. Raise it, then stop and wait; the answer is pasted back into your tab as `[ROVE GATE g-N answered] …`.
427
+
428
+ | Verb | Purpose |
429
+ |---|---|
430
+ | `gate-raise --task-id "$ROVE_TASK_ID" --question TEXT [--option KEY=LABEL]… [--recommend KEY] [--context TEXT]` | Open a decision gate (≤ 6 options, empty = free text). It shows in the owner's Inbox as `decision_needed`; `--tab` defaults to the tab you run in |
431
+ | `gate-answer --gate g-N [--option KEY] [--text TEXT]` | Answer a gate (owner/coordinator). Saved first, then pasted into the gate's tab; no live engine → `delivered:false`, and the next `send`/routine into that tab carries it |
432
+ | `gate-withdraw --gate g-N` | Drop a question that went moot |
433
+ | `gates [--repo PATH] [--task-id ID] [--status open\|answered\|withdrawn\|all]` | List gates (default open); `context` also carries the repo's open gates |
434
+
423
435
  ## Lifecycle
424
436
 
425
437
  | Verb | Purpose |
@@ -609,6 +621,53 @@ worker died (it may be mid-turn or stuck on a permission prompt): peek with
609
621
  `collect`/`get-task`, nudge with `send`, and never mark a silent task failed
610
622
  or auto-retry it.
611
623
 
624
+ ### Reports: close a delivered prompt with `report`
625
+
626
+ A completion `send` is a message. For work that runs unattended — a routine,
627
+ a standing session, a scheduler ticking a task — Rove can also ask for a
628
+ **report** and notice when it never comes.
629
+
630
+ **Receiving side.** A prompt that ends with `[ROVE] When this turn ends,
631
+ report: rove api report --delivery d-<n> …` (or opens with a
632
+ `[ROVE ROUTINE] … report with: rove api report --delivery d-<n> …` line)
633
+ is an armed delivery. Make `report` the LAST step of the turn, before you
634
+ stop:
635
+
636
+ ```bash
637
+ rove api report --delivery d-41 --outcome done \
638
+ --summary "<what you did, conclusion first>" \
639
+ --evidence "<commit, PR url, test result, path>" --evidence "…" \
640
+ --next "<what the next tick should do>"
641
+ ```
642
+
643
+ `--outcome` is `done`, `partial`, `blocked` (you need the owner or an
644
+ outside fix) or `failed` (you tried and could not). A turn that ends with no
645
+ report is flagged `report_missing` in the owner's Inbox, and the delivery is
646
+ marked `missing`. Reporting again replaces the report; a late report clears
647
+ the flag. For text with quotes or backticks use `--json -` (stdin) with
648
+ `{delivery, outcome, summary, evidence?, next?}`. `routine-respond` is the
649
+ same report as `--outcome done`.
650
+
651
+ **Sending side.** Arm the prompt you send: `rove api send --expect-report
652
+ …` (the reply carries `deliveryId`), or set it once with
653
+ `add --require-report` / `update --require-report on` so every `send` to that
654
+ task is armed. Read what recent ticks did with `rove api deliveries
655
+ --task-id <id> --limit 5` (newest first: outcome, summary, evidence, next,
656
+ or why it went missing) instead of a growing notes file. Silence still never
657
+ proves a worker is dead — `missing` says the turn ended or the engine died
658
+ without a report; look before you act on it.
659
+
660
+ **Don't tick a task that can't use it.** `rove api should-run --task-id <id>`
661
+ prints `{run:true}` (exit 0) or `{run:false, reason, detail?, until?,
662
+ gateIds?}` (exit 3, verdict still on stdout). `reason`, first match wins:
663
+ `awaiting-owner` (an open gate), `report-missing` (the last tick ended
664
+ unreported), `quota` (clears itself at `until`), `engine-error`,
665
+ `engine-dead`, `awaiting-permission`, `busy`. Check and send in one step with
666
+ `rove api send --if-runnable --expect-report --task-id <id> --prompt "…"`:
667
+ a refused tick pastes nothing, replies `{skipped: {…}}` with exit 3 and is
668
+ recorded as a `skipped` delivery. Drop the tick; never queue it for later.
669
+ `get-task` and `collect` carry the same verdict as `runnability`.
670
+
612
671
  ### A task is finished when it is GONE
613
672
 
614
673
  The dispatcher closes tasks. A worker cannot delete itself, so when it reports
@@ -81,6 +81,9 @@ agent-turns --task-id --repo --since-days(7) --limit(200)
81
81
  inspect --task-id
82
82
  read-output --task-id --tab --source{auto|history|terminal}(auto) --cursor --limit
83
83
  watch --task-ids <a,b,c> --group --until(REQ) <STATE[,STATE]> --timeout
84
+ deliveries --task-id(REQ) --limit
85
+ should-run --task-id(REQ) --tab
86
+ gates --repo --task-id --status{open|answered|withdrawn|all}(open)
84
87
  ```
85
88
  <!-- generated:end -->
86
89
 
@@ -89,6 +92,16 @@ watch --task-ids <a,b,c> --group --until(REQ) <STATE[,STATE]> --timeout
89
92
  (what `add --count` returned), a `--task-ids` csv, or a `--repo`; `inspect` is
90
93
  the wider diagnostic — daemon activity, a pty walk, and every tab snapshot.
91
94
 
95
+ `deliveries --task-id` is the task's report log, newest first: for each armed
96
+ prompt its `status` (`awaiting`, `reported`, `missing`, `skipped`), the report
97
+ (`outcome`, `summary`, `evidence`, `next`) or why it went missing (`cause`,
98
+ `note`; a `missing` row also carries `dismissedAt` once the owner dismissed it).
99
+ A `skipped` row is a tick `send --if-runnable` refused: `skipped` is
100
+ the verdict (`reason`, `detail`, `until`, `gateIds`) and `repeats` counts the
101
+ identical refusals (same tab, same reason) that one row stands for. A loop that
102
+ wakes a task reads `deliveries --limit 5` for what the last ticks did, instead
103
+ of a growing notes file.
104
+
92
105
  `pty-list` is what `NO_ENGINE_TAB`'s hint points at: when `.tabs[]` and reality
93
106
  disagree, it is the ground truth for what is actually alive — key, alive, pid,
94
107
  command, OSC title.
@@ -111,30 +124,36 @@ needs numbers, not when you want to know what a task is doing.
111
124
 
112
125
  <!-- generated:begin drive -->
113
126
  ```text
114
- send --task-id --prompt|--prompt-file(REQ) --tab --command --respawn --plain
115
- --allow-empty
116
- dispatch --task-id(REQ) --prompt|--prompt-file(REQ) --tab
117
- interrupt --task-id(REQ) --tab
118
- note --task-id(REQ) --text(REQ)
119
- note-list --repo(REQ)
120
- note-delete --repo(REQ) --id(REQ)
121
- pane-open --task-id --tab --command --direction{right|down}(right)
122
- --placement{split|tab}(split) --title
123
- pane-close --task-id --title(REQ) --tab
124
- pane-graphics --task-id --tab(REQ) --image-id
125
- tab-close --task-id(REQ) --tab(REQ)
126
- tab-new --task-id(REQ) --kind{shell|engine|editor|pane|viewport}(REQ) --command
127
- --file --pane --tab --view-task
128
- tab-split --task-id(REQ) --tab(REQ) --action{open|close|rename|reset}(REQ)
129
- --direction{right|down}(right) --leaf --title --cols --rows
130
- notify --title(REQ) --body --kind(done) --task-id --source
131
- prompt --title(REQ) --placeholder --initial --timeout
132
- engine-report --task-id
133
- --kind{session-start|turn-start|turn-complete|turn-failed|turn-interrupted|awaiting-input|session-end|tool-pre|tool-post|tool-failed|pre-compact|post-compact|subagent-start|subagent-stop}(REQ)
134
- --engine --tab --detail
135
- row-token --task-id(REQ) --text --ttl(60) --key(default)
136
- --tone{info|success|warning|error|muted} --clear
137
- set-active --task-id --none
127
+ send --task-id --prompt|--prompt-file(REQ) --tab --command --respawn --plain
128
+ --allow-empty --expect-report --if-runnable
129
+ dispatch --task-id(REQ) --prompt|--prompt-file(REQ) --tab
130
+ interrupt --task-id(REQ) --tab
131
+ note --task-id(REQ) --text(REQ)
132
+ note-list --repo(REQ)
133
+ note-delete --repo(REQ) --id(REQ)
134
+ pane-open --task-id --tab --command --direction{right|down}(right)
135
+ --placement{split|tab}(split) --title
136
+ pane-close --task-id --title(REQ) --tab
137
+ pane-graphics --task-id --tab(REQ) --image-id
138
+ tab-close --task-id(REQ) --tab(REQ)
139
+ tab-new --task-id(REQ) --kind{shell|engine|editor|pane|viewport}(REQ) --command
140
+ --file --line --pane --tab --view-task
141
+ tab-split --task-id(REQ) --tab(REQ) --action{open|close|rename|reset}(REQ)
142
+ --direction{right|down}(right) --leaf --title --cols --rows
143
+ notify --title(REQ) --body --kind(done) --task-id --source
144
+ prompt --title(REQ) --placeholder --initial --timeout
145
+ engine-report --task-id
146
+ --kind{session-start|turn-start|turn-complete|turn-failed|turn-interrupted|awaiting-input|session-end|tool-pre|tool-post|tool-failed|pre-compact|post-compact|subagent-start|subagent-stop}(REQ)
147
+ --engine --tab --detail
148
+ row-token --task-id(REQ) --text --ttl(60) --key(default)
149
+ --tone{info|success|warning|error|muted} --clear
150
+ set-active --task-id --none
151
+ report --delivery --outcome{done|partial|blocked|failed} --summary --evidence
152
+ --next --json
153
+ attention-dismiss --delivery(REQ)
154
+ gate-raise --task-id(REQ) --tab --question(REQ) --option --recommend --context
155
+ gate-answer --gate(REQ) --option --text
156
+ gate-withdraw --gate(REQ)
138
157
  ```
139
158
  <!-- generated:end -->
140
159
 
@@ -153,6 +172,28 @@ a resolved gotcha; an issue is for work that still needs doing.
153
172
  that legitimately produced no commits (an investigation, a review, a question
154
173
  answered); without it such a report is refused with `EMPTY_SUCCESS_REPORT`.
155
174
 
175
+ **`send --expect-report` asks for a report.** The reply carries `deliveryId`
176
+ (`d-<n>`) and the pasted prompt ends with a `[ROVE] When this turn ends,
177
+ report: rove api report --delivery d-<n> …` line. A task added with
178
+ `add --require-report` (or `update --require-report on`) arms every `send`
179
+ to it. When YOU receive a prompt with that line, finish the turn with
180
+ `report --delivery d-<n> --outcome done|partial|blocked|failed --summary "…"`
181
+ (repeat `--evidence` for commits, PR urls, test results, paths; `--next` for
182
+ what the next tick should do; `--json -` for text with quotes). Run it as the
183
+ last step, before you stop. A turn that ends without it raises a
184
+ `report_missing` Inbox row for the owner. Reporting again replaces the
185
+ report; a late one clears the flag. `outcome` is `blocked` when you need the
186
+ owner, `failed` when you tried and could not. Summary max 32,000 characters.
187
+
188
+ **`send --if-runnable` skips a tick the task can't use.** The daemon checks
189
+ `should-run`, claims the tab and arms the delivery in one step, so two ticks
190
+ arriving together cannot both pass. A refusal pastes nothing and replies
191
+ `{skipped: {run:false, reason, detail?, until?, gateIds?}}` with exit 3
192
+ (a `skipped` delivery is recorded when the send would have owed a report).
193
+ `reason` is `awaiting-owner`, `report-missing`, `quota`, `engine-error`,
194
+ `engine-dead`, `awaiting-permission` or `busy`; `should-run` asks the same
195
+ question without sending. A skip is dropped, never queued.
196
+
156
197
  `notify --kind` styles the toast: `done`, `needs_input`, `error` get severity
157
198
  treatment and an unread mark, anything else renders neutrally.
158
199
 
@@ -182,8 +223,9 @@ clear the shared active task.
182
223
  add --repo(REQ) --title --branch --base-branch --worktree-name --command --effort
183
224
  --tier{swift|standard|deep|auto} --model --count --agents <claude:2,codex:1>
184
225
  --status{backlog|in_progress|in_review|done|canceled|error}(backlog) --pin
185
- --activate(false) --prompt|--prompt-file
226
+ --require-report --expect-report --activate(false) --prompt|--prompt-file
186
227
  update --task-id(REQ) --title --tab --branch --command --model --effort --pinned
228
+ --require-report{on|off}
187
229
  --status{backlog|in_progress|in_review|done|canceled|error} --report-branch
188
230
  --report-pr --report-summary
189
231
  land --task-id(REQ) --dry-run --strategy{merge|squash}(merge) --delete-branch
@@ -313,10 +355,13 @@ and does not shift the schedule. `routine-delete` leaves already-created tasks
313
355
  alone.
314
356
 
315
357
  A delivered routine prompt starts with `[ROVE ROUTINE] "<name>" run #<n> — when
316
- done, report with: … routine-respond --run <runId> --prompt-file -`. When you
317
- received one, finish by answering THAT run: lead with the conclusion, markdown
318
- welcome, 32,000 characters max. Responding again replaces the answer. Nothing
319
- is inferred if you skip it; the run just shows "no response".
358
+ done, report with: … rove api report --delivery d-<n> …`. When you received
359
+ one, finish by reporting THAT delivery (`report --outcome done|partial|blocked|failed
360
+ --summary …`): lead with the conclusion, markdown welcome, 32,000 characters
361
+ max. Reporting again replaces the answer. `routine-respond --run <runId>
362
+ --text …` still works; it is `report --outcome done` on the same delivery.
363
+ Nothing is inferred if you skip it; the run shows "no response" and the
364
+ delivery goes `missing`.
320
365
 
321
366
  Run statuses from `routine-runs`: `dispatched`, `revived` (standing session
322
367
  respawned — files kept, conversation did not), `skipped_precheck` (nothing to do),
@@ -350,6 +395,7 @@ Errors go to stderr as `{"error":{"message","code",...}}`. Most carry `hint`
350
395
  |---|---|---|
351
396
  | `BAD_FLAG` | flag not on that verb | check the table above, then `schema --verb <v>` |
352
397
  | `TASK_NOT_FOUND` | id deleted or mistyped | `rove api list` |
398
+ | `DELIVERY_NOT_FOUND` | `report --delivery` names no delivery | copy the id from the prompt's `[ROVE]` line; `deliveries --task-id <id>` |
353
399
  | `DIRTY_WORKTREE` | `delete` on a worktree with uncommitted files | send the worker back to commit, or `delete --force` to discard |
354
400
  | `ISSUE_NOT_FOUND` | no issue with that number in this repo | `rove api issue-list --repo <path>` |
355
401
  | `NO_ENGINE_TAB` | live tabs exist, none is an engine | `--tab tab-N` from `pty-list`, or `--tab new` |