@sma1lboy/rove 0.9.237 → 0.9.239

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/{chunk-63xy91mc.js → chunk-0k91029d.js} +1 -1
  3. package/dist/cli/chunk-0mj358p5.js +3 -0
  4. package/dist/cli/chunk-0n7w8t48.js +2 -0
  5. package/dist/cli/{chunk-v4y0sf0x.js → chunk-0wrh5s5y.js} +2 -2
  6. package/dist/cli/chunk-0y4qgnby.js +3 -0
  7. package/dist/cli/chunk-1brfxbvg.js +4 -0
  8. package/dist/cli/{chunk-tdze2mnn.js → chunk-20qm75rb.js} +1 -1
  9. package/dist/cli/chunk-21fm5tks.js +2 -0
  10. package/dist/cli/{chunk-bkbmqec2.js → chunk-28zg6p31.js} +1 -1
  11. package/dist/cli/chunk-2andp9gs.js +2 -0
  12. package/dist/cli/{chunk-r2pztgm6.js → chunk-2bgmby1d.js} +1 -1
  13. package/dist/cli/{chunk-5e39zhvj.js → chunk-2s2xy444.js} +5 -5
  14. package/dist/cli/chunk-2vgc5cyj.js +2 -0
  15. package/dist/cli/chunk-2x9yc5nx.js +2 -0
  16. package/dist/cli/chunk-30kjq5m7.js +2 -0
  17. package/dist/cli/{chunk-mkksdcsw.js → chunk-3342qzve.js} +1 -1
  18. package/dist/cli/chunk-3aqhytyy.js +3 -0
  19. package/dist/cli/chunk-3c58659p.js +2 -0
  20. package/dist/cli/chunk-3d1hjrq0.js +2 -0
  21. package/dist/cli/chunk-41x1hrqe.js +3 -0
  22. package/dist/cli/{chunk-mhg40es1.js → chunk-4hestsjp.js} +1 -1
  23. package/dist/cli/{chunk-s1p650mm.js → chunk-53cyns0f.js} +1 -1
  24. package/dist/cli/chunk-576r5nht.js +5 -0
  25. package/dist/cli/{chunk-rvx5zz72.js → chunk-5akk3wap.js} +6 -5
  26. package/dist/cli/chunk-7cce0st1.js +3 -0
  27. package/dist/cli/{chunk-zyd6k6ak.js → chunk-7q43tysm.js} +1 -1
  28. package/dist/cli/chunk-8bn6eg67.js +8 -0
  29. package/dist/cli/chunk-8rf7nzan.js +4 -0
  30. package/dist/cli/chunk-96cjpssp.js +3 -0
  31. package/dist/cli/{chunk-bs7v83x0.js → chunk-9aydqazr.js} +1 -1
  32. package/dist/cli/{chunk-7txq91d9.js → chunk-9jsm6h5y.js} +1 -1
  33. package/dist/cli/{chunk-pz907kve.js → chunk-9w5g7frx.js} +1 -1
  34. package/dist/cli/{chunk-vnpqemb0.js → chunk-a7kq09ke.js} +1 -1
  35. package/dist/cli/chunk-acxznk3y.js +2 -0
  36. package/dist/cli/chunk-adkva3ep.js +6 -0
  37. package/dist/cli/{chunk-nvqdmx7q.js → chunk-ag3txfg2.js} +1 -1
  38. package/dist/cli/{chunk-2rg6aw59.js → chunk-atmaakwp.js} +1 -1
  39. package/dist/cli/chunk-axsm0gn5.js +3 -0
  40. package/dist/cli/chunk-b0ssvpht.js +3 -0
  41. package/dist/cli/chunk-b39sdtt0.js +3 -0
  42. package/dist/cli/{chunk-qyzvcgva.js → chunk-b9q8c2qg.js} +6 -6
  43. package/dist/cli/{chunk-g56km26e.js → chunk-bn73kd6z.js} +1 -1
  44. package/dist/cli/chunk-c2m55b72.js +4 -0
  45. package/dist/cli/{chunk-3gmzrstj.js → chunk-c60qsnfw.js} +3 -3
  46. package/dist/cli/{chunk-ch0ehc06.js → chunk-cbc1h345.js} +1 -1
  47. package/dist/cli/{chunk-dnbh8hsm.js → chunk-cbjh43yc.js} +1 -1
  48. package/dist/cli/{chunk-kbje1cpy.js → chunk-cmcn8e8x.js} +1 -1
  49. package/dist/cli/{chunk-cv1kaq8a.js → chunk-cp89n425.js} +5 -5
  50. package/dist/cli/chunk-cst86kt3.js +2 -0
  51. package/dist/cli/chunk-des00203.js +2 -0
  52. package/dist/cli/chunk-dgs0m8r4.js +3 -0
  53. package/dist/cli/chunk-dkgxz9hf.js +5 -0
  54. package/dist/cli/{chunk-gqphk56d.js → chunk-ekg3h5z3.js} +7 -7
  55. package/dist/cli/chunk-fert44x2.js +2 -0
  56. package/dist/cli/chunk-ff1h2qxd.js +2 -0
  57. package/dist/cli/{chunk-cv6r89jp.js → chunk-ffs26p85.js} +1 -1
  58. package/dist/cli/chunk-fft50thp.js +3 -0
  59. package/dist/cli/{chunk-hp32tbes.js → chunk-fg62y5fm.js} +1 -1
  60. package/dist/cli/{chunk-s9a974w9.js → chunk-fvmee0tr.js} +1 -1
  61. package/dist/cli/chunk-g4c4ffqp.js +20 -0
  62. package/dist/cli/{chunk-k7g060qr.js → chunk-g4j41mky.js} +2 -2
  63. package/dist/cli/{chunk-j6kataan.js → chunk-g5c5jytr.js} +1 -1
  64. package/dist/cli/{chunk-4bmap7dg.js → chunk-ga1pb0mr.js} +1 -1
  65. package/dist/cli/{chunk-dqndd97s.js → chunk-gkdfct7t.js} +2 -2
  66. package/dist/cli/chunk-gqydm0q8.js +2 -0
  67. package/dist/cli/chunk-gvrtrvnz.js +96 -0
  68. package/dist/cli/chunk-h2m7em1e.js +3 -0
  69. package/dist/cli/chunk-h33m6cc6.js +8 -0
  70. package/dist/cli/{chunk-ynbfqbn9.js → chunk-h3fckxn3.js} +1 -1
  71. package/dist/cli/chunk-h7y9v8k1.js +4 -0
  72. package/dist/cli/{chunk-32mv1yy6.js → chunk-h9cg0j3a.js} +1 -1
  73. package/dist/cli/{chunk-h4qv19v8.js → chunk-hbn1t161.js} +1 -1
  74. package/dist/cli/{chunk-12kgbrj1.js → chunk-hen7jj2h.js} +2 -2
  75. package/dist/cli/{chunk-3es6spp4.js → chunk-hq9tbzqa.js} +2 -2
  76. package/dist/cli/{chunk-snjte1rd.js → chunk-hr2xky15.js} +1 -1
  77. package/dist/cli/{chunk-s0snbj93.js → chunk-kb6xw0fw.js} +1 -1
  78. package/dist/cli/{chunk-40dk2add.js → chunk-ker4971f.js} +2 -2
  79. package/dist/cli/{chunk-vyb5a2rh.js → chunk-kg9kmwt9.js} +1 -1
  80. package/dist/cli/chunk-ktzbg4jg.js +2 -0
  81. package/dist/cli/chunk-m4f5h05c.js +10 -0
  82. package/dist/cli/chunk-m6q44xc0.js +2 -0
  83. package/dist/cli/{chunk-hq2n27y1.js → chunk-mw0ysrpd.js} +1 -1
  84. package/dist/cli/{chunk-2cwb64fj.js → chunk-n5dea05t.js} +1 -1
  85. package/dist/cli/chunk-nc46gddg.js +3 -0
  86. package/dist/cli/{chunk-jhbc9nx2.js → chunk-nckmga7j.js} +1 -1
  87. package/dist/cli/chunk-nem2x959.js +2 -0
  88. package/dist/cli/chunk-ng12dprz.js +2 -0
  89. package/dist/cli/chunk-npwzmmv9.js +3 -0
  90. package/dist/cli/chunk-nzh30nty.js +4 -0
  91. package/dist/cli/{chunk-gqrh2gp1.js → chunk-p024scd4.js} +1 -1
  92. package/dist/cli/chunk-p18ehv9y.js +7 -0
  93. package/dist/cli/chunk-p6qr8sen.js +2 -0
  94. package/dist/cli/{chunk-3sg5v7cg.js → chunk-p83wf4zw.js} +2 -2
  95. package/dist/cli/{chunk-s278gjet.js → chunk-pdvyfz3n.js} +1 -1
  96. package/dist/cli/chunk-pe6wnsww.js +2 -0
  97. package/dist/cli/{chunk-dhtsd706.js → chunk-pqzbk1cz.js} +25 -23
  98. package/dist/cli/chunk-prqeddy7.js +3 -0
  99. package/dist/cli/chunk-pvm3fc44.js +2 -0
  100. package/dist/cli/chunk-qd5zgq91.js +10 -0
  101. package/dist/cli/chunk-qvfdqrbf.js +3 -0
  102. package/dist/cli/{chunk-2xsem13q.js → chunk-qzsahxd9.js} +1 -1
  103. package/dist/cli/{chunk-aj3fk7xz.js → chunk-rahv4nrm.js} +3 -3
  104. package/dist/cli/chunk-rqyaf0dw.js +4 -0
  105. package/dist/cli/chunk-s57vy3k3.js +2 -0
  106. package/dist/cli/{chunk-g2advs8t.js → chunk-sak1tphp.js} +1 -1
  107. package/dist/cli/{chunk-vdcn6h48.js → chunk-snhcvjdb.js} +1 -1
  108. package/dist/cli/chunk-ss8c3b25.js +3 -0
  109. package/dist/cli/{chunk-bav389wj.js → chunk-svm809bx.js} +1 -1
  110. package/dist/cli/chunk-t8v9rpdx.js +2 -0
  111. package/dist/cli/{chunk-j4xfsn9g.js → chunk-tbrkck2f.js} +1 -1
  112. package/dist/cli/chunk-tdhk4dz8.js +4 -0
  113. package/dist/cli/chunk-try1f2h3.js +3 -0
  114. package/dist/cli/{chunk-b9ywdsdj.js → chunk-tsj1054w.js} +1 -1
  115. package/dist/cli/{chunk-t3wwsz29.js → chunk-tvk46rfs.js} +1 -1
  116. package/dist/cli/{chunk-4d54zgc7.js → chunk-twyda1p8.js} +2 -2
  117. package/dist/cli/{chunk-s1e0e9hc.js → chunk-vej49hnt.js} +2 -2
  118. package/dist/cli/chunk-w2sp489k.js +3 -0
  119. package/dist/cli/chunk-wfhnbnbw.js +2 -0
  120. package/dist/cli/{chunk-0wh2ff77.js → chunk-whbm14qr.js} +2 -2
  121. package/dist/cli/{chunk-ww4fbx8h.js → chunk-wtb8cycx.js} +2 -2
  122. package/dist/cli/chunk-wvmjdnhk.js +2 -0
  123. package/dist/cli/chunk-x9s14ppv.js +4 -0
  124. package/dist/cli/{chunk-dq2mh3b3.js → chunk-xv8fhxxm.js} +1 -1
  125. package/dist/cli/{chunk-85pk7c74.js → chunk-xx166cdv.js} +1 -1
  126. package/dist/cli/{chunk-ssfj9td0.js → chunk-y8tysjc2.js} +15 -13
  127. package/dist/cli/{chunk-y3k1accw.js → chunk-yexx8nec.js} +1 -1
  128. package/dist/cli/{chunk-9prawccj.js → chunk-yt15y085.js} +1 -1
  129. package/dist/cli/{chunk-n0mg67wn.js → chunk-ytxk6zqc.js} +1 -1
  130. package/dist/cli/chunk-yvjgwnb9.js +2 -0
  131. package/dist/cli/{chunk-n24dmy2r.js → chunk-yxt1y0n3.js} +9 -9
  132. package/dist/cli/chunk-ze0htjr5.js +2 -0
  133. package/dist/cli/chunk-zeb0sttx.js +2 -0
  134. package/dist/cli/chunk-znjcesdr.js +5 -0
  135. package/dist/cli/chunk-zsfyj36g.js +3 -0
  136. package/dist/cli/chunk-zt49bbg9.js +3 -0
  137. package/dist/cli/chunk-zt7wfnva.js +3 -0
  138. package/dist/cli/{chunk-6rvzzrd7.js → chunk-zx2n95qe.js} +1 -1
  139. package/dist/cli/{chunk-c4dx3er1.js → chunk-zxsbz3kk.js} +1 -1
  140. package/dist/cli/index.js +12 -10
  141. package/dist/cli/pty-host-node.mjs +1189 -177
  142. package/dist/cli/rove-run.js +1 -1
  143. package/dist/cli/rove.js +6 -6
  144. package/dist/skills/rove/SKILL.md +1 -1
  145. package/dist/skills/rove/references/api-flags.md +5 -5
  146. package/dist/web-ui/assets/harness-BHiciz5A.js +87 -0
  147. package/dist/web-ui/assets/{index-D2wALq0b.js → index-BkxJISAI.js} +2 -2
  148. package/dist/web-ui/assets/index-nMJ42IGm.css +1 -0
  149. package/dist/web-ui/index.html +2 -2
  150. package/dist/web-ui/origin-policy.mjs +1 -1
  151. package/dist/web-ui/pty-server.mjs +66 -8
  152. package/dist/web-ui/pty-session-lifecycle.mjs +49 -14
  153. package/package.json +6 -8
  154. package/dist/cli/chunk-05jej26n.js +0 -3
  155. package/dist/cli/chunk-072x915d.js +0 -2
  156. package/dist/cli/chunk-079cyb2e.js +0 -4
  157. package/dist/cli/chunk-1da3bqjc.js +0 -4
  158. package/dist/cli/chunk-1m7cp5ze.js +0 -3
  159. package/dist/cli/chunk-1q8tbbpz.js +0 -2
  160. package/dist/cli/chunk-1tx1s5v6.js +0 -2
  161. package/dist/cli/chunk-4y1fdz34.js +0 -3
  162. package/dist/cli/chunk-53afdybj.js +0 -3
  163. package/dist/cli/chunk-544bwsss.js +0 -4
  164. package/dist/cli/chunk-5bsk7qmg.js +0 -8
  165. package/dist/cli/chunk-6s5mev2n.js +0 -4
  166. package/dist/cli/chunk-6x5vzzpx.js +0 -3
  167. package/dist/cli/chunk-7s1kx9ez.js +0 -2
  168. package/dist/cli/chunk-85mk6j0s.js +0 -3
  169. package/dist/cli/chunk-8hbtca1g.js +0 -3
  170. package/dist/cli/chunk-8pa1ph1s.js +0 -7
  171. package/dist/cli/chunk-9k47xr7m.js +0 -2
  172. package/dist/cli/chunk-9mtxxsb3.js +0 -2
  173. package/dist/cli/chunk-a3yyrabb.js +0 -2
  174. package/dist/cli/chunk-a8et9f63.js +0 -4
  175. package/dist/cli/chunk-ahnk6zx3.js +0 -2
  176. package/dist/cli/chunk-bc18gat5.js +0 -4
  177. package/dist/cli/chunk-bw73t1zw.js +0 -5
  178. package/dist/cli/chunk-c2tevj9f.js +0 -2
  179. package/dist/cli/chunk-d1agt94n.js +0 -8
  180. package/dist/cli/chunk-dc31fzrm.js +0 -2
  181. package/dist/cli/chunk-dw853n4w.js +0 -3
  182. package/dist/cli/chunk-eawt4n4g.js +0 -2
  183. package/dist/cli/chunk-efx1gqmp.js +0 -2
  184. package/dist/cli/chunk-egx76ah2.js +0 -5
  185. package/dist/cli/chunk-ex1a2djb.js +0 -2
  186. package/dist/cli/chunk-f5e3dcxe.js +0 -2
  187. package/dist/cli/chunk-fwb72vzc.js +0 -2
  188. package/dist/cli/chunk-fxs82dsx.js +0 -4
  189. package/dist/cli/chunk-g3r1dwy9.js +0 -3
  190. package/dist/cli/chunk-ge30p4s5.js +0 -3
  191. package/dist/cli/chunk-gmgsxdrf.js +0 -10
  192. package/dist/cli/chunk-he76emdm.js +0 -2
  193. package/dist/cli/chunk-hgx20x94.js +0 -2
  194. package/dist/cli/chunk-hkq7c6hy.js +0 -2
  195. package/dist/cli/chunk-hnfp317x.js +0 -2
  196. package/dist/cli/chunk-hq4b3fca.js +0 -3
  197. package/dist/cli/chunk-jvxh93nz.js +0 -3
  198. package/dist/cli/chunk-k6nxyxyh.js +0 -3
  199. package/dist/cli/chunk-k8tspshr.js +0 -2
  200. package/dist/cli/chunk-kavsx69v.js +0 -3
  201. package/dist/cli/chunk-md8k7c5w.js +0 -2
  202. package/dist/cli/chunk-mppda1wq.js +0 -3
  203. package/dist/cli/chunk-ppwpjm39.js +0 -3
  204. package/dist/cli/chunk-pvw2y93q.js +0 -25
  205. package/dist/cli/chunk-pw6yfj10.js +0 -3
  206. package/dist/cli/chunk-q4nehkj9.js +0 -2
  207. package/dist/cli/chunk-qagek3wg.js +0 -5
  208. package/dist/cli/chunk-rz8zs7j8.js +0 -3
  209. package/dist/cli/chunk-sb0ns0c7.js +0 -3
  210. package/dist/cli/chunk-sp99y6eb.js +0 -2
  211. package/dist/cli/chunk-vejgnmcp.js +0 -2
  212. package/dist/cli/chunk-vz5g1p3w.js +0 -3
  213. package/dist/cli/chunk-vzqrj32e.js +0 -2
  214. package/dist/cli/chunk-wpsbyq4s.js +0 -2
  215. package/dist/cli/chunk-wtqxv2rv.js +0 -39
  216. package/dist/cli/chunk-xhgmnvjz.js +0 -8
  217. package/dist/cli/chunk-y05d79az.js +0 -2
  218. package/dist/cli/chunk-y8fqdnh3.js +0 -3
  219. package/dist/cli/chunk-ygd572ee.js +0 -4
  220. package/dist/cli/chunk-zja9chrd.js +0 -4
  221. package/dist/cli/chunk-zwej00t0.js +0 -5
  222. package/dist/cli/kobe-run.js +0 -3
  223. package/dist/cli/kobe.js +0 -7
  224. package/dist/completions/kobe.bash +0 -25
  225. package/dist/completions/kobe.fish +0 -27
  226. package/dist/completions/kobe.zsh +0 -35
  227. package/dist/web-ui/assets/harness-CLsfHgXB.js +0 -86
  228. package/dist/web-ui/assets/index-B4knjCIs.css +0 -1
  229. /package/dist/cli/{chunk-hqbmzz4t.js → chunk-0422g8ac.js} +0 -0
  230. /package/dist/cli/{chunk-khj0apc7.js → chunk-2tfnscxk.js} +0 -0
  231. /package/dist/cli/{chunk-7q67dz4c.js → chunk-4250pw6r.js} +0 -0
  232. /package/dist/cli/{chunk-xsrcwcjc.js → chunk-5mhvjytn.js} +0 -0
  233. /package/dist/cli/{chunk-ef39ym8f.js → chunk-7bgbansg.js} +0 -0
  234. /package/dist/cli/{chunk-nh4wvyz3.js → chunk-atn06ncf.js} +0 -0
  235. /package/dist/cli/{chunk-h4n8ffqy.js → chunk-dmzg9zdc.js} +0 -0
  236. /package/dist/cli/{chunk-w25b7xxz.js → chunk-etfh8f4z.js} +0 -0
  237. /package/dist/cli/{chunk-hape5vwj.js → chunk-hpay0ax8.js} +0 -0
  238. /package/dist/cli/{chunk-f10n6063.js → chunk-pn5ygqn6.js} +0 -0
  239. /package/dist/cli/{chunk-rcyasw34.js → chunk-rxqdw6s5.js} +0 -0
  240. /package/dist/cli/{chunk-exfyqsdd.js → chunk-vjvkkrzc.js} +0 -0
package/README.md CHANGED
@@ -18,11 +18,11 @@ rove add /path/to/repo
18
18
  rove
19
19
  ```
20
20
 
21
- The CLI runs on the Bun runtime. The published `rove` / `kobe` bins are node
21
+ The CLI runs on the Bun runtime. The published `rove` / `rove` bins are node
22
22
  launchers that re-exec through Bun, so an `npm install -g` or `npx` on a
23
23
  machine without Bun still ends up with a working Rove.
24
24
 
25
- The package also keeps `kobe` as a compatibility alias. Both executable names
25
+ The package also keeps `rove` as a compatibility alias. Both executable names
26
26
  copy supported legacy state into `~/.rove` and `~/.config/rove` without deleting
27
27
  or overwriting the old files; daemon-owned stores wait until the legacy writer
28
28
  has stopped.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CURRENT_VERSION,repoSlug}from"./chunk-4y1fdz34.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
2
+ import{CURRENT_VERSION,repoSlug}from"./chunk-7cce0st1.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
3
3
  query($owner: String!, $name: String!) {
4
4
  repository(owner: $owner, name: $name) {
5
5
  id
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ class ClientWriter{socket;highWaterMark;onOverflow;queue=new Map;snapshots=new Map;sequence=0;queuedBytes=0;paused=!1;droppedFrames=0;overflowed=!1;constructor(socket,options={}){this.socket=socket;this.highWaterMark=options.highWaterMark??8388608,this.onOverflow=options.onOverflow??(()=>socket.destroy())}get isPaused(){return this.paused}get pendingBytes(){return this.queuedBytes}get pendingCount(){return this.queue.size}get dropped(){return this.droppedFrames}write(line,replaceKey=null){if(this.overflowed)return;if(!this.paused){if(!this.safeWrite(line))this.pause();return}if(replaceKey!==null){let previous=this.snapshots.get(replaceKey);if(previous!==void 0)this.dequeue(previous),this.droppedFrames++}let id=this.sequence++,frame={line,bytes:Buffer.byteLength(line),replaceKey};if(this.queue.set(id,frame),replaceKey!==null)this.snapshots.set(replaceKey,id);if(this.queuedBytes+=frame.bytes,this.queuedBytes<=this.highWaterMark)return;this.overflowed=!0,this.queue.clear(),this.snapshots.clear(),this.queuedBytes=0,this.onOverflow()}dequeue(id){let frame=this.queue.get(id);if(!frame)return;if(this.queue.delete(id),this.queuedBytes-=frame.bytes,frame.replaceKey!==null)this.snapshots.delete(frame.replaceKey)}pause(){this.paused=!0,this.socket.once("drain",()=>{if(this.paused=!1,this.overflowed)return;for(let[id,frame]of this.queue)if(this.dequeue(id),!this.safeWrite(frame.line)){this.pause();return}})}safeWrite(line){try{return this.socket.write(line)}catch{return!0}}}function objectPayload(payload){if(!payload||typeof payload!=="object"||Array.isArray(payload))return{};return payload}function requireString(payload,key){let value=payload[key];if(typeof value!=="string"||value.length===0)throw Error(`${key} is required`);return value}function optionalString(payload,key){let value=payload[key];if(value===void 0||value===null||value==="")return;if(typeof value!=="string")throw Error(`${key} must be a string`);return value}function optionalBoolean(payload,key){let value=payload[key];if(value===void 0||value===null)return;if(typeof value!=="boolean")throw Error(`${key} must be a boolean`);return value}function requireNumber(payload,key){let value=payload[key];if(typeof value!=="number"||!Number.isFinite(value))throw Error(`${key} must be a finite number`);return value}function optionalNumber(payload,key){let value=payload[key];if(value===void 0||value===null)return;if(typeof value!=="number"||!Number.isFinite(value))throw Error(`${key} must be a finite number`);return value}function optionalVendor(payload,key){let value=optionalString(payload,key);return value&&value.trim().length>0?value:void 0}function optionalActivityDetail(payload){let raw=payload.detail;if(!raw||typeof raw!=="object"||Array.isArray(raw))return;let d=raw,out={};if(d.failure==="rate_limit"||d.failure==="billing"||d.failure==="other")out.failure=d.failure;if(d.waiting==="permission"||d.waiting==="input")out.waiting=d.waiting;if(typeof d.note==="string")out.note=d.note;let tool=d.tool;if(tool&&typeof tool==="object"&&!Array.isArray(tool))out.tool={...typeof tool.name==="string"?{name:tool.name}:{},...typeof tool.id==="string"?{id:tool.id}:{}};let compact=d.compact;if(compact&&typeof compact==="object"&&!Array.isArray(compact))out.compact=compact.trigger==="manual"||compact.trigger==="auto"?{trigger:compact.trigger}:{};let subagent=d.subagent;if(subagent&&typeof subagent==="object"&&!Array.isArray(subagent))out.subagent={...typeof subagent.type==="string"?{type:subagent.type}:{},...typeof subagent.id==="string"?{id:subagent.id}:{}};return Object.keys(out).length>0?out:void 0}class LineReceiver{maxBytes;storage=Buffer.alloc(0);length=0;failed=!1;constructor(maxBytes=8388608){this.maxBytes=maxBytes}get pendingBytes(){return this.length}push(chunk,onLine){if(this.failed)return!1;let start=0;while(start<chunk.length){let newline=chunk.indexOf(10,start),end=newline===-1?chunk.length:newline,size=this.length+end-start;if(size>this.maxBytes)return this.failed=!0,this.storage=Buffer.alloc(0),this.length=0,!1;if(size>this.storage.length){let capacity=Math.min(this.maxBytes,Math.max(size,this.storage.length*2,1024)),grown=Buffer.allocUnsafe(capacity);this.storage.copy(grown,0,0,this.length),this.storage=grown}if(chunk.copy(this.storage,this.length,start,end),this.length=size,newline===-1)return!0;let line=this.storage.toString("utf8",0,this.length);this.length=0,onLine(line),start=newline+1}return!0}}
3
+ export{ClientWriter,objectPayload,requireString,optionalString,optionalBoolean,requireNumber,optionalNumber,optionalVendor,optionalActivityDetail,LineReceiver};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{detectShell,installCompletions,recordWelcomeChoices,runPendingWelcomeInstalls,settleWelcomeInstall}from"./chunk-qd5zgq91.js";import"./chunk-8rf7nzan.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import"./chunk-7cce0st1.js";import"./chunk-g4c4ffqp.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{settleWelcomeInstall,runPendingWelcomeInstalls,recordWelcomeChoices,installCompletions,detectShell};
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{stopLegacyTmux}from"./chunk-dqndd97s.js";import{clearFrozenSessions}from"./chunk-1m7cp5ze.js";import"./chunk-7q67dz4c.js";import{stopDaemonProcess}from"./chunk-pz907kve.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{stampResetGate}from"./chunk-a8et9f63.js";import"./chunk-4y1fdz34.js";import{activeCliName}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import{kvStatePath,legacyKobeKvStatePath,legacyKobeStateDir,roveStateDir}from"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-qagek3wg.js";import"./chunk-544bwsss.js";import"./chunk-hqbmzz4t.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import{defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyFreezeDir,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";import{unlink}from"fs/promises";import{join}from"path";import{createInterface}from"readline";var CLI_NAME=activeCliName();function printUsage(out){out.write([`Usage: ${CLI_NAME} reset [--hard] [--yes]`,"","Recover a wedged install: stop the daemon, Hosted PTY host, and any pre-v0.8 tmux sessions.","This ends background terminal and engine sessions; the next launch starts fresh.","Never touches your git worktrees.","","Options:"," --hard Also DELETE the task index and the whole settings file"," (saved projects, custom engines, theme, language, onboarding)"," -y, --yes Skip the interactive confirmation. REQUIRED without a terminal;"," a non-interactive run without it exits 2 and changes nothing."," -h, --help Print this help",""].join(`
2
+ import{stopLegacyTmux}from"./chunk-gkdfct7t.js";import{clearFrozenSessions}from"./chunk-0y4qgnby.js";import"./chunk-4250pw6r.js";import{stopDaemonProcess}from"./chunk-9w5g7frx.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{stampResetGate}from"./chunk-8rf7nzan.js";import"./chunk-7cce0st1.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import{kvStatePath,legacyRoveKvStatePath,legacyRoveStateDir,roveStateDir}from"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import{defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyFreezeDir,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";import{unlink}from"fs/promises";import{join}from"path";import{createInterface}from"readline";var CLI_NAME=ROVE_PRODUCT_NAME;function printUsage(out){out.write([`Usage: ${CLI_NAME} reset [--hard] [--yes]`,"","Recover a wedged install: stop the daemon, Hosted PTY host, and any pre-v0.8 tmux sessions.","This ends background terminal and engine sessions; the next launch starts fresh.","Never touches your git worktrees.","","Options:"," --hard Also DELETE the task index and the whole settings file"," (saved projects, custom engines, theme, language, onboarding)"," -y, --yes Skip the interactive confirmation. REQUIRED without a terminal;"," a non-interactive run without it exits 2 and changes nothing."," -h, --help Print this help",""].join(`
3
3
  `))}function taskCount(path){try{let parsed=JSON.parse(readFileSync(path,"utf8"));return Array.isArray(parsed.tasks)?parsed.tasks.length:null}catch{return null}}function stateSummary(path){let parsed;try{parsed=JSON.parse(readFileSync(path,"utf8"))}catch{return[]}let count=(key)=>Array.isArray(parsed[key])?parsed[key].length:0,lines=[` saved projects: ${count("savedRepos")}`,` custom engines: ${count("customEngineIds")} (their launch commands live here and nowhere else)`],present=[["activeTheme","theme"],["defaultVendor","default engine"],["locale","language"],["onboarded","onboarding (the wizard runs again)"]].filter(([key])=>parsed[key]!==void 0).map(([,label])=>label);if(present.length>0)lines.push(` also set: ${present.join(", ")}`);return lines.push(` ${Object.keys(parsed).length} setting(s) in total`),lines}async function confirmTty(prompt){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(prompt,resolve));return/^y(es)?$/i.test(answer.trim())}finally{readline.close()}}async function removeStateFile(path,label){try{await unlink(path),console.log(` removed ${label} (${path})`)}catch(err){if(err.code==="ENOENT")console.log(` ${label}: already absent`);else throw Error(`failed to remove ${label} (${path}): ${errorMessage(err)}`)}}async function runResetSubcommand(argv){if(argv.some((arg)=>arg==="--help"||arg==="-h"||arg==="help")){printUsage(process.stdout);return}let known=new Set(["--hard","--yes","-y"]),unknown=argv.find((arg)=>!known.has(arg));if(unknown!==void 0)process.stderr.write(`${CLI_NAME} reset: unknown argument "${unknown}"
4
4
 
5
- `),printUsage(process.stderr),process.exit(2);let hard=argv.includes("--hard"),yes=argv.includes("--yes")||argv.includes("-y"),daemonSocket=defaultDaemonSocketPath(),tasksPath=join(roveStateDir(),"tasks.json"),legacyTasksPath=join(legacyKobeStateDir(),"tasks.json"),statePath=kvStatePath(),legacyStatePath=legacyKobeKvStatePath();if(console.log(`${CLI_NAME} reset will:`),console.log(" \u2022 stop the Rove daemon (graceful \u2192 SIGTERM \u2192 SIGKILL)"),console.log(` \u2022 remove its socket + pidfile (${daemonSocket})`),console.log(" \u2022 stop the standalone Hosted PTY host and all background terminal/engine sessions"),console.log(" \u2022 stop any pre-v0.8 tmux sessions after SIGTERM-ing their pane process groups"),hard){let count=taskCount(tasksPath)??taskCount(legacyTasksPath);console.log(` \u2022 DELETE the task index${count===null?"":` (${count} task(s))`} \u2014 ${tasksPath}`),console.log(` \u2022 DELETE the whole settings file \u2014 ${statePath}`);for(let line of stateSummary(statePath))console.log(line);console.log(" \u2022 DELETE the pre-Rove task/UI indexes too, so migration cannot restore reset state")}if(console.log(" \u2022 NOT touch your git worktrees under ~/.rove/worktrees/, ~/.kobe/worktrees/, or repo-local roots"),!hard)console.log(" (your task list, settings & worktrees are kept \u2014 add --hard to also delete the task index and settings file)");if(!yes){if(!process.stdin.isTTY){console.log(`
5
+ `),printUsage(process.stderr),process.exit(2);let hard=argv.includes("--hard"),yes=argv.includes("--yes")||argv.includes("-y"),daemonSocket=defaultDaemonSocketPath(),tasksPath=join(roveStateDir(),"tasks.json"),legacyTasksPath=join(legacyRoveStateDir(),"tasks.json"),statePath=kvStatePath(),legacyStatePath=legacyRoveKvStatePath();if(console.log(`${CLI_NAME} reset will:`),console.log(" \u2022 stop the Rove daemon (graceful \u2192 SIGTERM \u2192 SIGKILL)"),console.log(` \u2022 remove its socket + pidfile (${daemonSocket})`),console.log(" \u2022 stop the standalone Hosted PTY host and all background terminal/engine sessions"),console.log(" \u2022 stop any pre-v0.8 tmux sessions after SIGTERM-ing their pane process groups"),hard){let count=taskCount(tasksPath)??taskCount(legacyTasksPath);console.log(` \u2022 DELETE the task index${count===null?"":` (${count} task(s))`} \u2014 ${tasksPath}`),console.log(` \u2022 DELETE the whole settings file \u2014 ${statePath}`);for(let line of stateSummary(statePath))console.log(line);console.log(" \u2022 DELETE the pre-Rove task/UI indexes too, so migration cannot restore reset state")}if(console.log(" \u2022 NOT touch your git worktrees under ~/.rove/worktrees/ or existing repo-local roots"),!hard)console.log(" (your task list, settings & worktrees are kept \u2014 add --hard to also delete the task index and settings file)");if(!yes){if(!process.stdin.isTTY){console.log(`
6
6
  re-run with --yes to proceed (no interactive terminal for a y/N prompt) \u2014 nothing was changed`),process.exitCode=2;return}if(!await confirmTty(hard?`
7
7
  Stop runtimes and DELETE the task index + settings file? [y/N] `:`
8
8
  Stop runtimes? [y/N] `)){console.log("aborted \u2014 nothing changed");return}}console.log("");let daemon=await stopDaemonProcess(daemonSocket,defaultDaemonPidPath());console.log(daemon.method==="absent"?" daemon: was not running (cleared any stale socket/pidfile)":` daemon: stopped via ${daemon.method}${daemon.pid?` (pid ${daemon.pid})`:""}`);let ptyHost=await stopDaemonProcess(defaultPtyHostSocketPath(),defaultPtyHostPidPath());if(console.log(ptyHost.method==="absent"?" pty host: was not running (cleared any stale socket/pidfile)":` pty host: stopped via ${ptyHost.method}${ptyHost.pid?` (pid ${ptyHost.pid})`:""}`),ptyHost.method!=="graceful")clearFrozenSessions(defaultPtyFreezeDir()),console.log(` frozen sessions: cleared (${ptyHost.method} stop skips the host's own wipe)`);let legacyTmux=await stopLegacyTmux();if(legacyTmux.status==="failed"){console.error(` legacy tmux: cleanup failed \u2014 ${legacyTmux.error??"unknown error"}`),process.exitCode=1;return}if(console.log(legacyTmux.status==="absent"?" legacy tmux: no pre-v0.8 sessions found":` legacy tmux: stopped ${legacyTmux.sessions} session(s) after signalling ${legacyTmux.signalledGroups} pane group(s)`),hard)await removeStateFile(tasksPath,"task index"),await removeStateFile(legacyTasksPath,"legacy task index"),await removeStateFile(statePath,"UI state"),await removeStateFile(legacyStatePath,"legacy UI state");else stampResetGate();console.log(`
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{DEFAULT_TERMINAL_COLORS}from"./chunk-4250pw6r.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE,tightenDirPermissionsSync,tightenFilePermissionsSync}from"./chunk-yt15y085.js";import{defaultPtyFreezeDir}from"./chunk-npwzmmv9.js";import{randomUUID}from"crypto";import{mkdirSync,readFileSync,readdirSync,renameSync,rmSync,statSync,writeFileSync}from"fs";import{join}from"path";import{StringDecoder}from"string_decoder";var DEFAULT_MODES={applicationCursorKeys:!1,applicationKeypad:!1,origin:!1,wraparound:!0,reverseWraparound:!1,cursorBlink:!1,cursorVisible:!0,insertMode:!1,sendFocus:!1,bracketedPaste:!1,synchronizedOutput:!1,altScreen:!1,mouseProtocol:"none",mouseEncoding:"default"},MOUSE_PROTOCOLS={9:"x10",1000:"vt200",1002:"drag",1003:"any"},MOUSE_ENCODINGS={1006:"sgr",1016:"sgr-pixels"};function freshModeTrack(modes={...DEFAULT_MODES}){return{modes,carry:""}}function normalizeTerminalModes(raw){let modes={...DEFAULT_MODES};if(typeof raw!=="object"||raw===null)return modes;let record=raw;for(let key of Object.keys(DEFAULT_MODES))if(typeof record[key]==="boolean"&&typeof modes[key]==="boolean")modes[key]=record[key];if(Object.values(MOUSE_PROTOCOLS).includes(record.mouseProtocol))modes.mouseProtocol=record.mouseProtocol;if(Object.values(MOUSE_ENCODINGS).includes(record.mouseEncoding))modes.mouseEncoding=record.mouseEncoding;return modes}function scanTerminalModes(track,chunk){let text=track.carry+chunk;track.carry="";let replies=[],i=text.indexOf("\x1B");while(i!==-1){if(i+1>=text.length){track.carry="\x1B";break}let next=text.charCodeAt(i+1);if(next===91){let end=csiEnd(text,i+2);if(end===-1){if(text.length-i<=64)track.carry=text.slice(i);break}if(end>=0)applyCsi(track.modes,text.slice(i+2,end),text[end],replies);i=text.indexOf("\x1B",end>=0?end+1:i+2);continue}if(next===61)track.modes.applicationKeypad=!0;else if(next===62)track.modes.applicationKeypad=!1;else if(next===99)track.modes={...DEFAULT_MODES};i=text.indexOf("\x1B",i+1)}return replies}function terminalModePreamble(modes){let set=[],reset=[];if(modes.applicationCursorKeys)set.push(1);if(modes.origin)set.push(6);if(!modes.wraparound)reset.push(7);if(modes.cursorBlink)set.push(12);if(!modes.cursorVisible)reset.push(25);if(modes.reverseWraparound)set.push(45);for(let[mode,protocol]of Object.entries(MOUSE_PROTOCOLS))if(modes.mouseProtocol===protocol)set.push(+mode);for(let[mode,encoding]of Object.entries(MOUSE_ENCODINGS))if(modes.mouseEncoding===encoding)set.push(+mode);if(modes.sendFocus)set.push(1004);if(modes.bracketedPaste)set.push(2004);let out=modes.altScreen?"\x1B[?1049h":"";if(set.length>0)out+=`\x1B[?${set.join(";")}h`;if(reset.length>0)out+=`\x1B[?${reset.join(";")}l`;if(modes.applicationKeypad)out+="\x1B=";if(modes.insertMode)out+="\x1B[4h";return out}function csiEnd(text,from){for(let j=from;j<text.length;j++){let c=text.charCodeAt(j);if(c>=64&&c<=126)return j;if(c<32||c>63)return-2}return-1}function applyCsi(modes,body,final,replies){let start=0,prefix="",first=body.charCodeAt(0);if(first>=60&&first<=63)prefix=body[0],start=1;let end=body.length;while(end>start&&body.charCodeAt(end-1)<=47)end--;let intermediates=body.slice(end),params=body.slice(start,end).split(";").map((param)=>Number.parseInt(param.split(":")[0]??"",10)||0);if(intermediates===""&&(final==="h"||final==="l")){let on=final==="h";if(prefix==="?")for(let mode of params)setPrivateMode(modes,mode,on);else if(prefix===""&&params.includes(4))modes.insertMode=on}else if(intermediates==="$"&&final==="p"&&(prefix==="?"||prefix==="")){let mode=params[0]??0,value=prefix==="?"?privateModeValue(modes,mode):ansiModeValue(modes,mode);replies.push(`\x1B[${prefix}${mode};${value}$y`)}else if(intermediates==="!"&&final==="p"&&prefix==="")softReset(modes);else if(intermediates===""&&final==="c"&&prefix===""&&(params[0]??0)===0)replies.push("\x1B[?1;2c")}function setPrivateMode(modes,mode,on){if(mode in MOUSE_PROTOCOLS){modes.mouseProtocol=on?MOUSE_PROTOCOLS[mode]:"none";return}if(mode in MOUSE_ENCODINGS){modes.mouseEncoding=on?MOUSE_ENCODINGS[mode]:"default";return}switch(mode){case 1:modes.applicationCursorKeys=on;break;case 6:modes.origin=on;break;case 7:modes.wraparound=on;break;case 12:modes.cursorBlink=on;break;case 25:modes.cursorVisible=on;break;case 45:modes.reverseWraparound=on;break;case 66:modes.applicationKeypad=on;break;case 1004:modes.sendFocus=on;break;case 47:case 1047:case 1049:modes.altScreen=on;break;case 2004:modes.bracketedPaste=on;break;case 2026:modes.synchronizedOutput=on;break}}function softReset(modes){Object.assign(modes,{applicationCursorKeys:!1,applicationKeypad:!1,origin:!1,wraparound:!0,reverseWraparound:!1,cursorVisible:!0,insertMode:!1,sendFocus:!1,bracketedPaste:!1,synchronizedOutput:!1})}var NOT_RECOGNIZED=0,SET=1,RESET=2,PERMANENTLY_SET=3,PERMANENTLY_RESET=4,flag=(on)=>on?SET:RESET;function privateModeValue(modes,mode){if(mode in MOUSE_PROTOCOLS)return flag(modes.mouseProtocol===MOUSE_PROTOCOLS[mode]);if(mode in MOUSE_ENCODINGS)return flag(modes.mouseEncoding===MOUSE_ENCODINGS[mode]);switch(mode){case 1:return flag(modes.applicationCursorKeys);case 6:return flag(modes.origin);case 7:return flag(modes.wraparound);case 8:return PERMANENTLY_SET;case 12:return flag(modes.cursorBlink);case 25:return flag(modes.cursorVisible);case 45:return flag(modes.reverseWraparound);case 66:return flag(modes.applicationKeypad);case 67:case 1005:case 1015:return PERMANENTLY_RESET;case 1004:return flag(modes.sendFocus);case 1048:return SET;case 47:case 1047:case 1049:return flag(modes.altScreen);case 2004:return flag(modes.bracketedPaste);case 2026:return flag(modes.synchronizedOutput);default:return NOT_RECOGNIZED}}function ansiModeValue(modes,mode){switch(mode){case 2:return PERMANENTLY_RESET;case 4:return flag(modes.insertMode);case 12:return PERMANENTLY_SET;case 20:return RESET;default:return NOT_RECOGNIZED}}var FREEZE_VERSION=1;function freezeSession(session,now=new Date){return{v:FREEZE_VERSION,key:session.key,cwd:session.cwd,command:[...session.command],cols:session.cols,rows:session.rows,title:session.title,totalBytes:session.totalBytes,exit:session.exit,ringB64:Buffer.concat(session.chunks).toString("base64"),...session.ringModes?{ringModes:session.ringModes.modes}:{},updatedAt:now.toISOString()}}function thawRing(record,cap){let ring;try{ring=Buffer.from(record.ringB64,"base64")}catch{return null}let cut=Math.max(0,ring.byteLength-cap),trimmed=ring.subarray(cut),ringModes=freshModeTrack(normalizeTerminalModes(record.ringModes));if(cut>0)scanTerminalModes(ringModes,ring.subarray(0,cut).toString("latin1"));return{chunks:trimmed.byteLength>0?[trimmed]:[],bytes:trimmed.byteLength,ringModes}}function thawSession(record,cap){let ring=thawRing(record,cap);if(!ring)return null;let modes=freshModeTrack({...ring.ringModes.modes});for(let chunk of ring.chunks)scanTerminalModes(modes,chunk.toString("latin1"));return{key:record.key,generation:randomUUID(),cwd:record.cwd,proc:null,alive:!1,chunks:[...ring.chunks],bytes:ring.bytes,totalBytes:Math.max(record.totalBytes,ring.bytes),cols:record.cols,rows:record.rows,command:record.command,title:record.title,titleCarry:"",titleDecoder:new StringDecoder("utf8"),colorQueryCarry:"",defaultColors:DEFAULT_TERMINAL_COLORS,modes,ringModes:ring.ringModes,sinks:new Map,emulatorSinks:new Set,parked:!1,parkedScreenBytes:0,exit:record.exit,restored:!0,lastFreezeAtMs:0}}function recordFile(dir,key){return join(dir,`${encodeURIComponent(key)}.json`)}function parseRecord(raw){try{let parsed=JSON.parse(raw);if(parsed?.v!==FREEZE_VERSION)return null;if(typeof parsed.key!=="string"||parsed.key.length===0)return null;if(parsed.key.startsWith("::"))return null;if(typeof parsed.cwd!=="string"||!Array.isArray(parsed.command))return null;if(typeof parsed.ringB64!=="string"||typeof parsed.totalBytes!=="number")return null;return parsed}catch{return null}}var FREEZE_TTL_MS=1209600000,FREEZE_RESTORE_MAX_BYTES=67108864;function updatedAtMs(record){let t=Date.parse(record.updatedAt);return Number.isFinite(t)?t:0}function loadFrozenSessions(dir=defaultPtyFreezeDir(),now=Date.now(),report){let names;try{names=readdirSync(dir)}catch{return[]}let entries=[];for(let name of names){if(!name.endsWith(".json"))continue;try{let st=statSync(join(dir,name));entries.push({name,size:st.size,mtimeMs:st.mtimeMs})}catch{}}entries.sort((a,b)=>b.mtimeMs-a.mtimeMs);let kept=[],stale=[],bytesRead=0,deferred=0,unreadable=0;for(let entry of entries){if(now-entry.mtimeMs>FREEZE_TTL_MS){stale.push(entry.name);continue}if(bytesRead+entry.size>FREEZE_RESTORE_MAX_BYTES&&kept.length>0){deferred++;continue}let record=null;try{record=parseRecord(readFileSync(join(dir,entry.name),"utf8"))}catch{}if(bytesRead+=entry.size,!record){unreadable++;continue}if(now-updatedAtMs(record)>FREEZE_TTL_MS)stale.push(entry.name);else kept.push(record)}for(let name of stale)try{rmSync(join(dir,name),{force:!0})}catch{}return kept.sort((a,b)=>updatedAtMs(b)-updatedAtMs(a)),report?.({restored:kept.length,bytesRead,deferred,expired:stale.length,unreadable}),kept}function tightenExistingPermissions(dir){tightenDirPermissionsSync(dir);let names;try{names=readdirSync(dir)}catch{return}for(let name of names)if(name.endsWith(".json"))tightenFilePermissionsSync(join(dir,name))}function fileFreezeSink(dir=defaultPtyFreezeDir()){return tightenExistingPermissions(dir),{save(record){try{mkdirSync(dir,{recursive:!0,mode:OWNER_ONLY_DIR_MODE});let target=recordFile(dir,record.key),staging=`${target}.${process.pid}.tmp`;writeFileSync(staging,JSON.stringify(record),{encoding:"utf8",mode:OWNER_ONLY_FILE_MODE}),renameSync(staging,target)}catch{}},drop(key){try{rmSync(recordFile(dir,key),{force:!0})}catch{}}}}function clearFrozenSessions(dir=defaultPtyFreezeDir()){try{rmSync(dir,{recursive:!0,force:!0})}catch{}}
3
+ export{freshModeTrack,scanTerminalModes,terminalModePreamble,freezeSession,thawSession,FREEZE_TTL_MS,FREEZE_RESTORE_MAX_BYTES,loadFrozenSessions,fileFreezeSink,clearFrozenSessions};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";var SEARCH_TIMEOUT_MS=5000,CLI_NAME=ROVE_PRODUCT_NAME,FIRST_PARTY=[{ref:"Sma1lboy/rove-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/rove-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/rove-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/rove-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/rove-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/rove-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}];async function fetchTopic(topic,query){let q=encodeURIComponent(`topic:${topic}${query?` ${query}`:""}`),ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),SEARCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/search/repositories?q=${q}&sort=stars&order=desc&per_page=50`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json"}});if(!res.ok)return null;let body=await res.json();if(!Array.isArray(body.items))return null;return body.items.filter((r)=>typeof r.full_name==="string").map((r)=>({ref:r.full_name,desc:r.description??"",stars:r.stargazers_count}))}catch{return null}finally{clearTimeout(timer)}}async function fetchMarketplace(query){let topicResults=await Promise.all([fetchTopic("rove-plugin",query)]),lower=query?.toLowerCase(),seeds=FIRST_PARTY.filter((s)=>!lower||`${s.ref} ${s.desc}`.toLowerCase().includes(lower)).map((s)=>({...s,firstParty:!0}));return{entries:dedupeEntries([...seeds,...topicResults.flatMap((result)=>result??[])]),offline:topicResults.every((result)=>result===null)}}async function searchMarketplace(query){let{entries,offline}=await fetchMarketplace(query);if(offline)console.error("(GitHub search unreachable \u2014 showing first-party plugins only)");if(entries.length===0){console.log(query?`no plugins match \`${query}\``:"no plugins found");return}let width=Math.min(48,Math.max(...entries.map((e)=>e.ref.length))+2);for(let e of entries){let stars=e.stars!==void 0?`\u2605${e.stars}`:e.firstParty?"first-party":"";console.log(`${e.ref.padEnd(width)}${stars.padEnd(12)}${e.desc}`)}console.log(`
3
+ install: ${CLI_NAME} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.run/plugins`)}function dedupeEntries(entries){let seen=new Set;return entries.filter((entry)=>{let key=entry.ref.toLowerCase();if(seen.has(key))return!1;return seen.add(key),!0})}
4
+ export{fetchMarketplace,searchMarketplace};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{discoverMachine}from"./chunk-ww4fbx8h.js";import{RemoteOrchestrator}from"./chunk-kavsx69v.js";import{startTunnel}from"./chunk-7txq91d9.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-bs7v83x0.js";import"./chunk-nh4wvyz3.js";import"./chunk-k6nxyxyh.js";import"./chunk-h4n8ffqy.js";import"./chunk-6xppe9bj.js";import"./chunk-wtqxv2rv.js";import"./chunk-pz907kve.js";import"./chunk-xy8be792.js";import"./chunk-4y1fdz34.js";import"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import{createStateCell}from"./chunk-nhakrm1f.js";import{KobeDaemonClient}from"./chunk-qagek3wg.js";import"./chunk-544bwsss.js";import"./chunk-hqbmzz4t.js";import{logClient,logClientError}from"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";class MachineHub{local;slots=new Map;machinesAcc=createStateCell([],"machines.status");mergedAcc=createStateCell([],"machines.tasks");localUnsubscribe=null;disposed=!1;constructor(local){this.local=local}machinesSignal(){return this.machinesAcc}tasksSignal(){if(this.slots.size===0)return this.local.tasksSignal();return this.mergedAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}attach(){let entries=dedupeMachines(listMachines());if(entries.length===0)return;for(let entry of entries)this.slots.set(entry.alias,{entry,tasks:[]});this.publishStatuses(),this.localUnsubscribe=this.local.tasksSignal().subscribe(()=>this.republishTasks()),this.republishTasks();for(let entry of entries)this.connect(entry)}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}if(found.ok)updateMachine(entry.alias,{sockets});let tunnel=startTunnel({alias:entry.alias,config:entry,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new KobeDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{await orchestrator.init()}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()});slot.unsubscribe=()=>{stopTasks(),stopConnection()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.kobeVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}publishStatuses(){this.machinesAcc.set([...this.slots.values()].map((slot)=>({alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})))}republishTasks(){let merged=this.local.tasksSignal().get().map((task)=>stampOrigin(task,"local","local"));for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.mergedAcc.set(merged)}dispose(){this.disposed=!0,this.localUnsubscribe?.();for(let slot of this.slots.values())slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop();this.slots.clear()}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}export{classifyHandshakeFailure,MachineHub};
2
+ import{RemoteOrchestrator}from"./chunk-ss8c3b25.js";import{discoverMachine}from"./chunk-wtb8cycx.js";import"./chunk-atn06ncf.js";import"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import{startTunnel}from"./chunk-9jsm6h5y.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-9aydqazr.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-xy8be792.js";import"./chunk-7cce0st1.js";import"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{createStateCell}from"./chunk-nhakrm1f.js";import{RoveDaemonClient}from"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import{logClient,logClientError}from"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";class MachineHub{local;slots=new Map;machinesAcc=createStateCell([],"machines.status");mergedAcc=createStateCell([],"machines.tasks");localUnsubscribe=null;disposed=!1;constructor(local){this.local=local}machinesSignal(){return this.machinesAcc}tasksSignal(){if(this.slots.size===0)return this.local.tasksSignal();return this.mergedAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}attach(){let entries=dedupeMachines(listMachines());if(entries.length===0)return;for(let entry of entries)this.slots.set(entry.alias,{entry,tasks:[]});this.publishStatuses(),this.localUnsubscribe=this.local.tasksSignal().subscribe(()=>this.republishTasks()),this.republishTasks();for(let entry of entries)this.connect(entry)}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}if(found.ok)updateMachine(entry.alias,{sockets});let tunnel=startTunnel({alias:entry.alias,config:entry,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new RoveDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{await orchestrator.init()}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()});slot.unsubscribe=()=>{stopTasks(),stopConnection()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.roveVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}publishStatuses(){this.machinesAcc.set([...this.slots.values()].map((slot)=>({alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})))}republishTasks(){let merged=this.local.tasksSignal().get().map((task)=>stampOrigin(task,"local","local"));for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.mergedAcc.set(merged)}dispose(){this.disposed=!0,this.localUnsubscribe?.();for(let slot of this.slots.values())slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop();this.slots.clear()}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}export{classifyHandshakeFailure,MachineHub};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{ensureForwards}from"./chunk-9jsm6h5y.js";import{dedupeMachines,listMachines,localDaemonSocketPath}from"./chunk-9aydqazr.js";import{ApiError}from"./chunk-f7zjggfv.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{RoveDaemonClient}from"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";function remoteTaskUnsupported(taskId,machineId){return new ApiError(`task ${taskId} lives on machine "${machineId}". Rove can list it, but acting on a remote task is not supported yet.`,"NOT_YET_SUPPORTED_REMOTE",{taskId,machineId,hint:`run the command on ${machineId} itself; remote writes arrive in a later release`,nextCommandArgs:["machine","list"]})}async function machineTasks(entry){let socketPath=localDaemonSocketPath(entry.alias),direct=await tasksOf(socketPath);if(direct)return direct;if(!entry.sockets)return null;return await ensureForwards({alias:entry.alias,config:entry,remoteDaemonSocket:entry.sockets.daemon,remotePtySocket:entry.sockets.pty})?await tasksOf(socketPath):null}async function tasksOf(socketPath){let client=new RoveDaemonClient(socketPath);try{return await client.request("hello",{}),(await client.request("task.list")).tasks??[]}catch{return null}finally{client.close()}}async function mergeTaskList(local){let machines=dedupeMachines(listMachines());if(machines.length===0)return local;let tasks=(local.tasks??[]).map((task)=>({...task,origin:{machineId:"local",hostLabel:"local"}}));for(let entry of machines){let remote=await machineTasks(entry);if(!remote)continue;let hostLabel=entry.alias;for(let task of remote)tasks.push({...task,origin:{machineId:entry.alias,hostLabel}})}return{tasks}}async function assertLocalTask(taskId){if(!taskId)return;let machines=dedupeMachines(listMachines());if(machines.length===0)return;for(let entry of machines){let remote=await machineTasks(entry);if(!remote)continue;if(remote.some((task)=>task.id===taskId))throw remoteTaskUnsupported(taskId,entry.alias)}}export{mergeTaskList,assertLocalTask};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-vdcn6h48.js";import"./chunk-ge30p4s5.js";import"./chunk-nhakrm1f.js";import"./chunk-wqfp8d9w.js";export{tKeys,t,setLocaleLang,localeState,intlLocale,currentLang};
2
+ import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-wqfp8d9w.js";export{tKeys,t,setLocaleLang,localeState,intlLocale,currentLang};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{describeRepoInitSources,missingDependenciesCoda,resolveEngineLaunchInit,resolveRepoInit}from"./chunk-dkgxz9hf.js";import"./chunk-hpay0ax8.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{resolveRepoInit,resolveEngineLaunchInit,missingDependenciesCoda,describeRepoInitSources};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- function reduceActivity(previous,kind,detail){switch(kind){case"session-start":case"session-end":case"turn-interrupted":return"idle";case"turn-start":return"running";case"turn-complete":return previous==="running"||previous==="permission_needed"||previous===void 0?"turn_complete":previous;case"turn-failed":return detail?.failure==="rate_limit"||detail?.failure==="billing"?"rate_limited":"error";case"awaiting-input":return"permission_needed";default:return previous??"idle"}}var DEFAULT_ENGINE_STATE_TTL_MS=600000,STICKY_STATES=new Set(["turn_complete","permission_needed","error","rate_limited","dead"]);function resolveEngineStateTtlMs(){let raw=process.env.KOBE_ENGINE_STATE_TTL_MS;if(raw===void 0)return DEFAULT_ENGINE_STATE_TTL_MS;let n=Number(raw);return Number.isFinite(n)&&n>0?n:DEFAULT_ENGINE_STATE_TTL_MS}function activityStillWorking(live,at,now,staleMs){if(!live)return!1;if(live.unknown)return!0;if(live.completedAt!==void 0&&live.completedAt>=at)return!1;return live.mtimeMs!==void 0&&live.mtimeMs>now-staleMs}
2
+ function reduceActivity(previous,kind,detail){switch(kind){case"session-start":case"session-end":case"turn-interrupted":return"idle";case"turn-start":return"running";case"turn-complete":return previous==="running"||previous==="permission_needed"||previous===void 0?"turn_complete":previous;case"turn-failed":return detail?.failure==="rate_limit"||detail?.failure==="billing"?"rate_limited":"error";case"awaiting-input":return"permission_needed";default:return previous??"idle"}}var DEFAULT_ENGINE_STATE_TTL_MS=600000,STICKY_STATES=new Set(["turn_complete","permission_needed","error","rate_limited","dead"]);function resolveEngineStateTtlMs(){let raw=process.env.ROVE_ENGINE_STATE_TTL_MS;if(raw===void 0)return DEFAULT_ENGINE_STATE_TTL_MS;let n=Number(raw);return Number.isFinite(n)&&n>0?n:DEFAULT_ENGINE_STATE_TTL_MS}function activityStillWorking(live,at,now,staleMs){if(!live)return!1;if(live.unknown)return!0;if(live.completedAt!==void 0&&live.completedAt>=at)return!1;return live.mtimeMs!==void 0&&live.mtimeMs>now-staleMs}
3
3
  export{reduceActivity,STICKY_STATES,resolveEngineStateTtlMs,activityStillWorking};