@sma1lboy/rove 0.9.273-nightly.20261027 → 0.9.274

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 (110) hide show
  1. package/dist/cli/{chunk-jfn7889p.js → chunk-033k4ap7.js} +1 -1
  2. package/dist/cli/{chunk-aac92ra2.js → chunk-03rbg95q.js} +8 -8
  3. package/dist/cli/{chunk-yb26ekcg.js → chunk-0g3sjn8z.js} +1 -1
  4. package/dist/cli/{chunk-f38caghx.js → chunk-0ppkvphp.js} +1 -1
  5. package/dist/cli/{chunk-rngjpf3c.js → chunk-15fp4p9v.js} +1 -1
  6. package/dist/cli/chunk-16ttm9x6.js +2 -0
  7. package/dist/cli/{chunk-35jbdbkm.js → chunk-22d4fjjb.js} +1 -1
  8. package/dist/cli/{chunk-h4yec78v.js → chunk-29s67j3k.js} +3 -3
  9. package/dist/cli/{chunk-72tc0dhk.js → chunk-2v68zaaa.js} +1 -1
  10. package/dist/cli/{chunk-06xt2mhb.js → chunk-2y29zrm1.js} +1 -1
  11. package/dist/cli/{chunk-3249q53j.js → chunk-387ecqb8.js} +1 -1
  12. package/dist/cli/{chunk-a3jqg8g2.js → chunk-3v9s3bcz.js} +1 -1
  13. package/dist/cli/chunk-4d1v6066.js +3 -0
  14. package/dist/cli/{chunk-7hyx5z35.js → chunk-4dxc29mm.js} +1 -1
  15. package/dist/cli/{chunk-7vkvfawc.js → chunk-4hnz77xf.js} +1 -1
  16. package/dist/cli/{chunk-wve9y405.js → chunk-5dd7trgf.js} +1 -1
  17. package/dist/cli/{chunk-wna3jsp4.js → chunk-5gzpq34w.js} +2 -2
  18. package/dist/cli/{chunk-1pkhwwn4.js → chunk-5zsdjrgz.js} +1 -1
  19. package/dist/cli/{chunk-58y5geay.js → chunk-68wpp5y8.js} +2 -2
  20. package/dist/cli/{chunk-a09kjwtd.js → chunk-6h4qdckd.js} +1 -1
  21. package/dist/cli/{chunk-p7bzpsgn.js → chunk-6jj82bej.js} +1 -1
  22. package/dist/cli/chunk-6xr1prk6.js +3 -0
  23. package/dist/cli/{chunk-hyydmt77.js → chunk-78v1q5mz.js} +1 -1
  24. package/dist/cli/{chunk-xdzd6v4r.js → chunk-8h437k1q.js} +1 -1
  25. package/dist/cli/{chunk-2ssqfhwb.js → chunk-97m9nyw7.js} +1 -1
  26. package/dist/cli/{chunk-c2yt6fag.js → chunk-9bae7f3m.js} +1 -1
  27. package/dist/cli/{chunk-7drxm3c8.js → chunk-9er68n24.js} +1 -1
  28. package/dist/cli/{chunk-6cvgvmgg.js → chunk-b492aee1.js} +1 -1
  29. package/dist/cli/{chunk-9d5zechf.js → chunk-b5c7p22a.js} +1 -1
  30. package/dist/cli/chunk-b5pytfgm.js +2 -0
  31. package/dist/cli/chunk-b68dd36h.js +3 -0
  32. package/dist/cli/{chunk-x06qxj81.js → chunk-bbksmb5a.js} +1 -1
  33. package/dist/cli/{chunk-8na3sv2h.js → chunk-by6fjf7m.js} +1 -1
  34. package/dist/cli/{chunk-9kje0m11.js → chunk-cpf78z3x.js} +1 -1
  35. package/dist/cli/{chunk-kdg7b8av.js → chunk-cyzp2btw.js} +4 -4
  36. package/dist/cli/{chunk-0hmwkm43.js → chunk-dpq60qph.js} +1 -1
  37. package/dist/cli/{chunk-dyzvnvjz.js → chunk-e01321zn.js} +1 -1
  38. package/dist/cli/{chunk-2cg3b07h.js → chunk-ec7f3wcm.js} +2 -2
  39. package/dist/cli/{chunk-1sg8c2ke.js → chunk-ecrw211n.js} +1 -1
  40. package/dist/cli/{chunk-a037vcy5.js → chunk-edrxs4cy.js} +3 -3
  41. package/dist/cli/{chunk-ta92gm9s.js → chunk-egpcaxwb.js} +1 -1
  42. package/dist/cli/{chunk-xbgcg6d3.js → chunk-erx7x9xg.js} +8 -8
  43. package/dist/cli/{chunk-qpc7ek4z.js → chunk-ewqqwtrj.js} +1 -1
  44. package/dist/cli/{chunk-nqck4ghb.js → chunk-fexzfgd1.js} +1 -1
  45. package/dist/cli/{chunk-jr6c3hce.js → chunk-fmbv4m3y.js} +3 -3
  46. package/dist/cli/{chunk-nh7a6bhb.js → chunk-fs51wx31.js} +1 -1
  47. package/dist/cli/{chunk-3nqf8gwr.js → chunk-g263457v.js} +1 -1
  48. package/dist/cli/{chunk-ag8hyh7c.js → chunk-g3tv8kht.js} +1 -1
  49. package/dist/cli/{chunk-xncz4ke1.js → chunk-g53yqr82.js} +3 -3
  50. package/dist/cli/{chunk-fzadtbrm.js → chunk-g9yba5vh.js} +2 -2
  51. package/dist/cli/{chunk-8z63cvmg.js → chunk-gryq2vgw.js} +1 -1
  52. package/dist/cli/{chunk-rx11ezbp.js → chunk-hfdk7j28.js} +1 -1
  53. package/dist/cli/{chunk-kfzzk4sk.js → chunk-jd7p0y5x.js} +1 -1
  54. package/dist/cli/{chunk-6vhr65h3.js → chunk-jwedmkm8.js} +1 -1
  55. package/dist/cli/{chunk-67nb2sdd.js → chunk-kgs56yns.js} +1 -1
  56. package/dist/cli/{chunk-yk5zs8ec.js → chunk-kyt9ytz2.js} +9 -9
  57. package/dist/cli/{chunk-hksrpa1j.js → chunk-m4dvx7bd.js} +3 -3
  58. package/dist/cli/{chunk-kgg1ykdw.js → chunk-m6yy3qc1.js} +1 -1
  59. package/dist/cli/{chunk-hzvbq8mf.js → chunk-mxgtz5vz.js} +17 -17
  60. package/dist/cli/{chunk-zvxq5xdr.js → chunk-n2ejvjrd.js} +1 -1
  61. package/dist/cli/{chunk-pn2f24wx.js → chunk-nzbq51h9.js} +1 -1
  62. package/dist/cli/chunk-p4s826r2.js +96 -0
  63. package/dist/cli/{chunk-krsswcp7.js → chunk-p6334e7v.js} +1 -1
  64. package/dist/cli/{chunk-r06v0pyn.js → chunk-q6septaj.js} +1 -1
  65. package/dist/cli/{chunk-692n3x93.js → chunk-qe7xb4rm.js} +1 -1
  66. package/dist/cli/{chunk-fmp4sfxe.js → chunk-qs1r0tqr.js} +1 -1
  67. package/dist/cli/{chunk-fqgvmy2d.js → chunk-qvnr8c18.js} +1 -1
  68. package/dist/cli/{chunk-mq0bx7zy.js → chunk-r77pfw4m.js} +1 -1
  69. package/dist/cli/{chunk-7yn79aye.js → chunk-rzef6szc.js} +1 -1
  70. package/dist/cli/{chunk-fsb81hkp.js → chunk-sa48rtjz.js} +1 -1
  71. package/dist/cli/{chunk-0dh1vfer.js → chunk-sbds7zx4.js} +1 -1
  72. package/dist/cli/{chunk-182qa2d6.js → chunk-snqa07h6.js} +1 -1
  73. package/dist/cli/chunk-sqxdfzdq.js +5 -0
  74. package/dist/cli/{chunk-adv5s59k.js → chunk-sz2xs0a2.js} +1 -1
  75. package/dist/cli/{chunk-cynqvjk8.js → chunk-sza3tyhs.js} +2 -2
  76. package/dist/cli/{chunk-y0wg9ekb.js → chunk-t34kjg5y.js} +4 -2
  77. package/dist/cli/chunk-t5y8k772.js +2 -0
  78. package/dist/cli/{chunk-x5j66mvs.js → chunk-tw9w8pzg.js} +3 -3
  79. package/dist/cli/{chunk-acnmrmxh.js → chunk-vht2e44j.js} +1 -1
  80. package/dist/cli/{chunk-cj82t1v0.js → chunk-vjp7drne.js} +1 -1
  81. package/dist/cli/chunk-vm551pxs.js +2 -0
  82. package/dist/cli/chunk-w09356fj.js +20 -0
  83. package/dist/cli/{chunk-4vad6e9t.js → chunk-w9cdc97q.js} +1 -1
  84. package/dist/cli/{chunk-k0hwkm75.js → chunk-xbwq4bc0.js} +1 -1
  85. package/dist/cli/{chunk-r3ezk0cs.js → chunk-xkmdxcjg.js} +1 -1
  86. package/dist/cli/{chunk-0csav0tg.js → chunk-xmqv1zx6.js} +1 -1
  87. package/dist/cli/{chunk-sj4e61x6.js → chunk-xn7bk4f9.js} +1 -1
  88. package/dist/cli/{chunk-wsfcca0x.js → chunk-y5axx6ev.js} +1 -1
  89. package/dist/cli/{chunk-t6wwh4jk.js → chunk-ypd337d0.js} +2 -2
  90. package/dist/cli/{chunk-gs01afvb.js → chunk-zaw71cf4.js} +1 -1
  91. package/dist/cli/{chunk-bmq4hxdg.js → chunk-zybjm7d5.js} +1 -1
  92. package/dist/cli/index.js +4 -4
  93. package/dist/cli/rove.js +1 -1
  94. package/dist/completions/rove.bash +1 -1
  95. package/dist/completions/rove.fish +1 -1
  96. package/dist/completions/rove.zsh +1 -1
  97. package/dist/skills/rove/SKILL.md +6 -1
  98. package/dist/skills/rove/references/api-flags.md +1 -0
  99. package/dist/web/assets/{index-oQc8YcHX.js → index-C9vaSoIJ.js} +35 -35
  100. package/dist/web/index.html +1 -1
  101. package/package.json +3 -3
  102. package/dist/cli/chunk-08gdekk1.js +0 -3
  103. package/dist/cli/chunk-4y5hk7gr.js +0 -2
  104. package/dist/cli/chunk-7hzgtyke.js +0 -5
  105. package/dist/cli/chunk-phpaypqx.js +0 -3
  106. package/dist/cli/chunk-pt00jcaz.js +0 -2
  107. package/dist/cli/chunk-r17r542e.js +0 -2
  108. package/dist/cli/chunk-x9y8yx2f.js +0 -2
  109. package/dist/cli/chunk-xecgzx8c.js +0 -96
  110. package/dist/cli/chunk-zetj4rnw.js +0 -20
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{publishRoveTerminalTitle}from"./chunk-3aqhytyy.js";import{ensureGlobalRoveHooks}from"./chunk-nqck4ghb.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-j1z9kgyd.js";import"./chunk-a037vcy5.js";import"./chunk-aac92ra2.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-3249q53j.js";import"./chunk-67nb2sdd.js";import"./chunk-7vkvfawc.js";import"./chunk-2brn8e1y.js";import"./chunk-a09kjwtd.js";import"./chunk-dyzvnvjz.js";import"./chunk-7kysxgbq.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import{takeWelcome}from"./chunk-acnmrmxh.js";import{LAST_RUN_VERSION_KEY,enforceResetGate}from"./chunk-xdzd6v4r.js";import"./chunk-0rrmz6k6.js";import"./chunk-tjj9bt7n.js";import{CURRENT_VERSION,compareSemver}from"./chunk-4vad6e9t.js";import{maybeHintSkillInstall}from"./chunk-58y5geay.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-cynqvjk8.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";var WHATS_NEW_SEEN_KEY="app.whatsNewSeenVersion";function whatsNewFromVersion(state,current=CURRENT_VERSION){let stamped=state[WHATS_NEW_SEEN_KEY]??state[LAST_RUN_VERSION_KEY];if(typeof stamped!=="string"||stamped.length===0)return null;return compareSemver(current,stamped)>0?stamped:null}function takeWhatsNew(){let from=whatsNewFromVersion(loadStateFile());try{patchStateFile({[WHATS_NEW_SEEN_KEY]:CURRENT_VERSION})}catch{}return from}async function startTui(){let whatsNewFrom=takeWhatsNew(),welcome=takeWelcome();enforceResetGate(),publishRoveTerminalTitle(),await maybeHintSkillInstall(),await ensureGlobalRoveHooks();let{loadPluginEngines}=await import("./chunk-f38caghx.js");loadPluginEngines();let{startWorkspaceHost}=await import("./chunk-xbgcg6d3.js");await startWorkspaceHost({whatsNewFrom,welcome})}export{startTui};
2
+ import{publishRoveTerminalTitle}from"./chunk-3aqhytyy.js";import{ensureGlobalRoveHooks}from"./chunk-fexzfgd1.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-j1z9kgyd.js";import"./chunk-edrxs4cy.js";import"./chunk-03rbg95q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-387ecqb8.js";import"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-2brn8e1y.js";import"./chunk-6h4qdckd.js";import"./chunk-e01321zn.js";import"./chunk-7kysxgbq.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import{takeWelcome}from"./chunk-vht2e44j.js";import{LAST_RUN_VERSION_KEY,enforceResetGate}from"./chunk-8h437k1q.js";import"./chunk-0rrmz6k6.js";import"./chunk-tjj9bt7n.js";import{CURRENT_VERSION,compareSemver}from"./chunk-w9cdc97q.js";import{maybeHintSkillInstall}from"./chunk-68wpp5y8.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";var WHATS_NEW_SEEN_KEY="app.whatsNewSeenVersion";function whatsNewFromVersion(state,current=CURRENT_VERSION){let stamped=state[WHATS_NEW_SEEN_KEY]??state[LAST_RUN_VERSION_KEY];if(typeof stamped!=="string"||stamped.length===0)return null;return compareSemver(current,stamped)>0?stamped:null}function takeWhatsNew(){let from=whatsNewFromVersion(loadStateFile());try{patchStateFile({[WHATS_NEW_SEEN_KEY]:CURRENT_VERSION})}catch{}return from}async function startTui(){let whatsNewFrom=takeWhatsNew(),welcome=takeWelcome();enforceResetGate(),publishRoveTerminalTitle(),await maybeHintSkillInstall(),await ensureGlobalRoveHooks();let{loadPluginEngines}=await import("./chunk-0ppkvphp.js");loadPluginEngines();let{startWorkspaceHost}=await import("./chunk-erx7x9xg.js");await startWorkspaceHost({whatsNewFrom,welcome})}export{startTui};
@@ -1,6 +1,6 @@
1
1
  // @bun
2
- import{errorMessage}from"./chunk-2brn8e1y.js";import{JsonHookAdapter,ROVE_HOOK_VERSION,bobAuthSecretsPath,claudeGlobalConfigPath,codexAuthPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isRoveHook,kimiCredentialsPath,readTextFileSyncBounded,roveHookArgs,roveHookInvocation,updateSharedJson}from"./chunk-dyzvnvjz.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getCustomEngineIds,getDisabledEngineIds}from"./chunk-rfp0ayra.js";import{__require}from"./chunk-91sykzqq.js";var GEMINI={rules:[{state:"blocked",any:["\u2502 apply this change","\u2502 allow execution","waiting for user confirmation"]},{state:"blocked",all:["do you want to proceed"],any:["yes"]},{state:"working",any:["esc to cancel"]}]},OPENCODE={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"]},{state:"working",any:["esc interrupt","esc to interrupt","ctrl+c to interrupt","esc again to interrupt"]},{state:"idle",any:["enter send"]}]},CURSOR={rules:[{state:"blocked",any:["press any key to log in"]},{state:"blocked",all:["proceed (y)"]},{state:"blocked",any:["run this command?","waiting for approval","skip (esc or n)","(y) (enter)"]},{state:"working",any:["esc to cancel","ctrl+c to stop"]}]},GROK={rules:[{state:"blocked",any:["\u26A0 action required","ctrl+o:yolo"]},{state:"blocked",all:["\u2503"],lineRegex:["^\\s*\u2503\\s+\\S+\\s+\\(\u25CB\\)"]},{state:"working",any:["[stop]"],lineRegex:["^\\s*[\\u2800-\\u28FF]"]}]},DROID={rules:[{state:"blocked",all:["enter to select","esc to cancel"],any:["> yes, allow","> no, cancel"]},{state:"blocked",all:["enter select","esc cancel"]},{state:"working",any:["esc to stop"]}]},AMP={rules:[{state:"blocked",any:["waiting for approval","run this command?","allow editing file:","allow creating file:","confirm tool call"]},{state:"working",lineRegex:["^\\s*\u2570\\s+\\S+\\s+(thinking|streaming|running tools|waiting)\\s+\u2500"]}]},CLINE={rules:[{state:"blocked",any:["let cline use this tool"]},{state:"blocked",all:["execute command?","yes"],any:["[act mode]","[plan mode]"]},{state:"blocked",all:["use this tool?","yes"],any:["[act mode]","[plan mode]"]}]},KIRO={rules:[{state:"blocked",all:["requires approval"],any:["yes, single permission","trust, always allow","no (tab to edit)","esc to close"]},{state:"blocked",all:["pending from subagents","tool approval"],any:["approve all pending","configure individually","exit (cancel subagents)"]},{state:"working",any:["kiro is working"]},{state:"working",all:["esc to cancel"],lineRegex:["^\\s*[\u25D4\u25D1\u25D5\u25CF]\\s+[A-Za-z]"]}]},MAKI={rules:[{state:"blocked",all:["permission required","y allow","n deny"]},{state:"blocked",all:["permission required"],any:["confirm allow","confirm deny"]},{state:"blocked",all:["permission required","enter deny","esc cancel"]},{state:"blocked",all:["plan complete","enter confirm"],any:["space toggle parallel","edit plan"]},{state:"working",bottomLines:1,lineRegex:["^( [\\u2800-\\u28FF]){1,2} \\[(BUILD|PLAN|BASH)\\]"]},{state:"idle",bottomLines:1,lineRegex:["^ \\[(BUILD|PLAN|BASH)\\]"]}]},ANTIGRAVITY={rules:[{state:"blocked",all:["requesting permission for:","do you want to proceed?"]},{state:"blocked",all:["requesting permission for:","tab amend","edit command"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]+\\s+[A-Za-z]+\\w*ing\\b"]},{state:"working",bottomLines:5,lineRegex:["\xB7\\s*[1-9][0-9]*\\s+task"]}]},DEVIN={rules:[{state:"blocked",bottomLines:8,all:["do you trust the authors of this directory?","yes, trust "]},{state:"blocked",bottomLines:8,all:["approve once","select","confirm","esc cancel"]},{state:"working",bottomLines:8,all:["running tools","esc to interrupt"]},{state:"working",bottomLines:6,all:["guide devin while it works"]},{state:"working",bottomLines:8,all:["reading shell ","timeout:"]},{state:"idle",bottomLines:8,all:["ask devin to build","features, fix bugs","your code"],lineRegex:["^\\s*\u276D Ask Devin to build"]},{state:"idle",bottomLines:6,all:["context:"],lineRegex:["^\\s*\u276D"]}]},QODERCLI={rules:[{state:"blocked",all:["waiting for user confirmation"],any:["yes","no","allow","reject"]},{state:"blocked",all:["awaiting approval"],any:["allow","reject"]},{state:"blocked",any:["permission required","allow once or always?","asking user","enter your response","review your answers:","shell awaiting input"]},{state:"working",any:["(esc to cancel,"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]\\s+.*[A-Za-z]"]}]},HERMES={rules:[{state:"blocked",bottomLines:14,any:["dangerous","approval","allow once","hermes needs your","type your answer","approve once","start a new session","keep going"],lineRegex:["enter\\s+(?:to\\s+)?(?:confirm|send)","press enter","\u2191/\u2193\\s+(?:to\\s+)?select","show full command","type 1/2/3","y/n quick","other \\(type"]},{state:"blocked",bottomLines:14,any:["sudo password","skill setup"]},{state:"blocked",bottomLines:14,all:["\uD83D\uDD11","for "]},{state:"working",bottomLines:5,any:["msg=interrupt","ctrl+c to interrupt","ctrl+c cancel"]}]},KILO={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"],lineRegex:["\u2191\u2193\\s*select","\u21C6\\s*tab"]},{state:"working",any:["esc interrupt"]}]},MASTRACODE={rules:[]};import{existsSync}from"fs";import{homedir}from"os";import{dirname,join}from"path";function parseFlatHooks(raw){if(raw===void 0)return{ok:!0,doc:{}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{ok:!1,reason:`not valid JSON (${err instanceof Error?err.message:String(err)})`}}if(!isObject(parsed))return{ok:!1,reason:"top level is not a JSON object"};if(parsed.hooks===void 0)return{ok:!0,doc:parsed};if(!isObject(parsed.hooks))return{ok:!1,reason:'"hooks" is not an object'};for(let[event,entries]of Object.entries(parsed.hooks))if(!Array.isArray(entries))return{ok:!1,reason:`"hooks.${event}" is not an array`};return{ok:!0,doc:parsed}}function mergeFlatHooks(format,current,install,inv=roveHookInvocation()){let verbs=format.eventMap.map((spec)=>spec.verb),{hooks:rawHooks,...rest}=current,hooks=isObject(rawHooks)?{...rawHooks}:{},quoting=hookCommandQuoting();for(let{event,verb}of format.eventMap){let kept=(Array.isArray(hooks[event])?hooks[event]:[]).filter((entry)=>!isRoveHook(entry,verbs));if(install){let command=quoteShellArgv([...inv,"hook",verb,...roveHookArgs(format.vendor)],quoting);kept.push(format.withType?{type:"command",command}:{command})}if(kept.length>0)hooks[event]=kept;else delete hooks[event]}return{version:1,...rest,hooks}}var CURSOR_HOOK_EVENT_MAP=[{event:"sessionStart",verb:"session-start"}],CURSOR_FORMAT={vendor:"cursor",eventMap:CURSOR_HOOK_EVENT_MAP};function cursorHooksPath(home=homedir()){let override=process.env.CURSOR_CONFIG_DIR?.trim();return join(override||join(home,".cursor"),"hooks.json")}function parseCursorHooks(raw){return parseFlatHooks(raw)}function mergeCursorHooks(current,install,inv=roveHookInvocation()){return mergeFlatHooks(CURSOR_FORMAT,current,install,inv)}class CursorHookAdapter{vendor="cursor";supportsHooks(){return!0}globalSettingsPath(){return cursorHooksPath()}activityDetailFromPayload(){return}cwdFromPayload(payload){let roots=payload.workspace_roots;return Array.isArray(roots)?firstString(...roots):void 0}sessionFromPayload(payload){let sessionId=firstString(payload.session_id,payload.conversation_id);if(!sessionId)return;let transcriptPath=firstString(payload.transcript_path);return{sessionId,...transcriptPath?{transcriptPath}:{}}}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync(dirname(settingsFilePath)))return{ok:!0};let outcome=await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!0),parseCursorHooks);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] cursor: skipped ${outcome.file}: ${outcome.reason}
3
- `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!1),parseCursorHooks)}hookConfigRefusal(raw){let parsed=parseCursorHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function firstString(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}import{homedir as homedir2}from"os";import{join as join2}from"path";import{existsSync as existsSync2}from"fs";import{dirname as dirname2}from"path";function sessionStartOnly(matcher){return[{event:"SessionStart",verb:"session-start",...matcher?{matcher}:{}}]}class SessionStartHookAdapter extends JsonHookAdapter{installGuardDir(settingsFilePath){return dirname2(settingsFilePath)}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync2(this.installGuardDir(settingsFilePath)))return{ok:!0};return super.installActivityHooks(settingsFilePath,opts)}async removeActivityHooks(settingsFilePath){if(!existsSync2(settingsFilePath))return;await super.removeActivityHooks(settingsFilePath)}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}}var DEVIN_HOOK_EVENT_MAP=sessionStartOnly();function devinSettingsPath(home=homedir2()){let xdg=process.env.XDG_CONFIG_HOME?.trim();return join2(xdg||join2(home,".config"),"devin","config.json")}class DevinHookAdapter extends SessionStartHookAdapter{vendor="devin";eventMap=DEVIN_HOOK_EVENT_MAP;globalSettingsPath(){return devinSettingsPath()}}import{homedir as homedir3}from"os";import{join as join3}from"path";var DROID_HOOK_EVENT_MAP=sessionStartOnly();function droidSettingsPath(home=homedir3()){return join3(home,".factory","settings.json")}class DroidHookAdapter extends SessionStartHookAdapter{vendor="droid";eventMap=DROID_HOOK_EVENT_MAP;globalSettingsPath(){return droidSettingsPath()}}import{homedir as homedir4}from"os";import{dirname as dirname3,join as join4}from"path";var GROK_HOOK_EVENT_MAP=sessionStartOnly();function grokConfigDir(home=homedir4()){return process.env.GROK_HOME?.trim()||join4(home,".grok")}function grokHooksPath(home=homedir4()){return join4(grokConfigDir(home),"hooks","rove.json")}class GrokHookAdapter extends SessionStartHookAdapter{vendor="grok";eventMap=GROK_HOOK_EVENT_MAP;globalSettingsPath(){return grokHooksPath()}installGuardDir(settingsFilePath){return dirname3(dirname3(settingsFilePath))}sessionFromPayload(payload){let sessionId=firstString2(payload.session_id,payload.sessionId);if(!sessionId)return;let transcriptPath=firstString2(payload.transcript_path,payload.transcriptPath);return{sessionId,...transcriptPath?{transcriptPath}:{}}}}function firstString2(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}import{existsSync as existsSync3}from"fs";import{mkdir,readFile,rm,writeFile}from"fs/promises";import{homedir as homedir5}from"os";import path from"path";var HERMES_PLUGIN_NAME="rove-agent-state";function indentOf(line){if(!line.trim()||line.trim().startsWith("#"))return;let match=/^ */.exec(line),indent=match?match[0].length:0;return line[indent]==="\t"?void 0:indent}function keyAt(line,indent){if(indentOf(line)!==indent)return;return/^ *(["']?)([A-Za-z0-9_.-]+)\1:(?:\s|$)/.exec(line)?.[2]}function inlineValue(line){return(/^ *(["']?)[A-Za-z0-9_.-]+\1:(.*)$/.exec(line)?.[2]??"").trim()}function listItemAt(line,indent){if(indentOf(line)!==indent)return;let match=/^ *- *(.*)$/.exec(line);if(!match)return;return match[1].trim().replace(/^["']|["']$/g,"")}function join5(lines,trailingNewline){return lines.join(`
2
+ import{errorMessage}from"./chunk-2brn8e1y.js";import{JsonHookAdapter,ROVE_HOOK_VERSION,bobAuthSecretsPath,claudeGlobalConfigPath,codexAuthPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isRoveHook,kimiCredentialsPath,readTextFileSyncBounded,roveHookArgs,roveHookInvocation,updateSharedJson}from"./chunk-e01321zn.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getCustomEngineIds,getDisabledEngineIds}from"./chunk-rfp0ayra.js";import{__require}from"./chunk-91sykzqq.js";var GEMINI={rules:[{state:"blocked",any:["\u2502 apply this change","\u2502 allow execution","waiting for user confirmation"]},{state:"blocked",all:["do you want to proceed"],any:["yes"]},{state:"working",any:["esc to cancel"]}]},OPENCODE={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"]},{state:"working",any:["esc interrupt","esc to interrupt","ctrl+c to interrupt","esc again to interrupt"]},{state:"idle",any:["enter send"]}]},CURSOR={rules:[{state:"blocked",any:["press any key to log in"]},{state:"blocked",all:["proceed (y)"]},{state:"blocked",any:["run this command?","waiting for approval","skip (esc or n)","(y) (enter)"]},{state:"working",any:["esc to cancel","ctrl+c to stop"]}]},GROK={rules:[{state:"blocked",any:["\u26A0 action required","ctrl+o:yolo"]},{state:"blocked",all:["\u2503"],lineRegex:["^\\s*\u2503\\s+\\S+\\s+\\(\u25CB\\)"]},{state:"working",any:["[stop]"],lineRegex:["^\\s*[\\u2800-\\u28FF]"]}]},DROID={rules:[{state:"blocked",all:["enter to select","esc to cancel"],any:["> yes, allow","> no, cancel"]},{state:"blocked",all:["enter select","esc cancel"]},{state:"working",any:["esc to stop"]}]},AMP={rules:[{state:"blocked",any:["waiting for approval","run this command?","allow editing file:","allow creating file:","confirm tool call"]},{state:"working",lineRegex:["^\\s*\u2570\\s+\\S+\\s+(thinking|streaming|running tools|waiting)\\s+\u2500"]}]},CLINE={rules:[{state:"blocked",any:["let cline use this tool"]},{state:"blocked",all:["execute command?","yes"],any:["[act mode]","[plan mode]"]},{state:"blocked",all:["use this tool?","yes"],any:["[act mode]","[plan mode]"]}]},KIRO={rules:[{state:"blocked",all:["requires approval"],any:["yes, single permission","trust, always allow","no (tab to edit)","esc to close"]},{state:"blocked",all:["pending from subagents","tool approval"],any:["approve all pending","configure individually","exit (cancel subagents)"]},{state:"working",any:["kiro is working"]},{state:"working",all:["esc to cancel"],lineRegex:["^\\s*[\u25D4\u25D1\u25D5\u25CF]\\s+[A-Za-z]"]}]},MAKI={rules:[{state:"blocked",all:["permission required","y allow","n deny"]},{state:"blocked",all:["permission required"],any:["confirm allow","confirm deny"]},{state:"blocked",all:["permission required","enter deny","esc cancel"]},{state:"blocked",all:["plan complete","enter confirm"],any:["space toggle parallel","edit plan"]},{state:"working",bottomLines:1,lineRegex:["^( [\\u2800-\\u28FF]){1,2} \\[(BUILD|PLAN|BASH)\\]"]},{state:"idle",bottomLines:1,lineRegex:["^ \\[(BUILD|PLAN|BASH)\\]"]}]},ANTIGRAVITY={rules:[{state:"blocked",all:["requesting permission for:","do you want to proceed?"]},{state:"blocked",all:["requesting permission for:","tab amend","edit command"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]+\\s+[A-Za-z]+\\w*ing\\b"]},{state:"working",bottomLines:5,lineRegex:["\xB7\\s*[1-9][0-9]*\\s+task"]}]},DEVIN={rules:[{state:"blocked",bottomLines:8,all:["do you trust the authors of this directory?","yes, trust "]},{state:"blocked",bottomLines:8,all:["approve once","select","confirm","esc cancel"]},{state:"working",bottomLines:8,all:["running tools","esc to interrupt"]},{state:"working",bottomLines:6,all:["guide devin while it works"]},{state:"working",bottomLines:8,all:["reading shell ","timeout:"]},{state:"idle",bottomLines:8,all:["ask devin to build","features, fix bugs","your code"],lineRegex:["^\\s*\u276D Ask Devin to build"]},{state:"idle",bottomLines:6,all:["context:"],lineRegex:["^\\s*\u276D"]}]},QODERCLI={rules:[{state:"blocked",all:["waiting for user confirmation"],any:["yes","no","allow","reject"]},{state:"blocked",all:["awaiting approval"],any:["allow","reject"]},{state:"blocked",any:["permission required","allow once or always?","asking user","enter your response","review your answers:","shell awaiting input"]},{state:"working",any:["(esc to cancel,"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]\\s+.*[A-Za-z]"]}]},HERMES={rules:[{state:"blocked",bottomLines:14,any:["dangerous","approval","allow once","hermes needs your","type your answer","approve once","start a new session","keep going"],lineRegex:["enter\\s+(?:to\\s+)?(?:confirm|send)","press enter","\u2191/\u2193\\s+(?:to\\s+)?select","show full command","type 1/2/3","y/n quick","other \\(type"]},{state:"blocked",bottomLines:14,any:["sudo password","skill setup"]},{state:"blocked",bottomLines:14,all:["\uD83D\uDD11","for "]},{state:"working",bottomLines:5,any:["msg=interrupt","ctrl+c to interrupt","ctrl+c cancel"]}]},KILO={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"],lineRegex:["\u2191\u2193\\s*select","\u21C6\\s*tab"]},{state:"working",any:["esc interrupt"]}]},MASTRACODE={rules:[]};import{existsSync}from"fs";import{homedir}from"os";import{dirname,join}from"path";function parseFlatHooks(raw){if(raw===void 0)return{ok:!0,doc:{}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{ok:!1,reason:`not valid JSON (${err instanceof Error?err.message:String(err)})`}}if(!isObject(parsed))return{ok:!1,reason:"top level is not a JSON object"};if(parsed.hooks===void 0)return{ok:!0,doc:parsed};if(!isObject(parsed.hooks))return{ok:!1,reason:'"hooks" is not an object'};for(let[event,entries]of Object.entries(parsed.hooks))if(!Array.isArray(entries))return{ok:!1,reason:`"hooks.${event}" is not an array`};return{ok:!0,doc:parsed}}function mergeFlatHooks(format,current,install,inv=roveHookInvocation()){let verbs=format.eventMap.map((spec)=>spec.verb),{hooks:rawHooks,...rest}=current,hooks=isObject(rawHooks)?{...rawHooks}:{},quoting=hookCommandQuoting();for(let{event,verb}of format.eventMap){let kept=(Array.isArray(hooks[event])?hooks[event]:[]).filter((entry)=>!isRoveHook(entry,verbs));if(install){let command=quoteShellArgv([...inv,"hook",verb,...roveHookArgs(format.vendor)],quoting);kept.push(format.withType?{type:"command",command}:{command})}if(kept.length>0)hooks[event]=kept;else delete hooks[event]}return{version:1,...rest,hooks}}var CURSOR_HOOK_EVENT_MAP=[{event:"sessionStart",verb:"session-start"}],CURSOR_FORMAT={vendor:"cursor",eventMap:CURSOR_HOOK_EVENT_MAP};function cursorHooksPath(home=homedir()){let override=process.env.CURSOR_CONFIG_DIR?.trim();return join(override||join(home,".cursor"),"hooks.json")}function parseCursorHooks(raw){return parseFlatHooks(raw)}function mergeCursorHooks(current,install,inv=roveHookInvocation()){return mergeFlatHooks(CURSOR_FORMAT,current,install,inv)}class CursorHookAdapter{vendor="cursor";supportsHooks(){return!0}globalSettingsPath(){return cursorHooksPath()}activityDetailFromPayload(){return}cwdFromPayload(payload){let roots=payload.workspace_roots;return Array.isArray(roots)?firstString(...roots):void 0}sessionFromPayload(payload){let sessionId=firstString(payload.session_id,payload.conversation_id);if(!sessionId)return;let transcriptPath=firstString(payload.transcript_path);return{sessionId,...transcriptPath?{transcriptPath}:{}}}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync(dirname(settingsFilePath)))return{ok:!0};let outcome=await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!0),parseCursorHooks);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] cursor: skipped ${outcome.file}: ${outcome.reason}
3
+ `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!1),parseCursorHooks)}hookConfigRefusal(raw){let parsed=parseCursorHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function firstString(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}import{homedir as homedir2}from"os";import{join as join2}from"path";import{existsSync as existsSync2}from"fs";import{dirname as dirname2}from"path";function sessionStartOnly(matcher){return[{event:"SessionStart",verb:"session-start",...matcher?{matcher}:{}}]}class SessionStartHookAdapter extends JsonHookAdapter{installGuardDir(settingsFilePath){return dirname2(settingsFilePath)}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync2(this.installGuardDir(settingsFilePath)))return{ok:!0};return super.installActivityHooks(settingsFilePath,opts)}async removeActivityHooks(settingsFilePath){if(!existsSync2(settingsFilePath))return;await super.removeActivityHooks(settingsFilePath)}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}}var DEVIN_HOOK_EVENT_MAP=sessionStartOnly();function devinSettingsPath(home=homedir2()){let xdg=process.env.XDG_CONFIG_HOME?.trim();return join2(xdg||join2(home,".config"),"devin","config.json")}class DevinHookAdapter extends SessionStartHookAdapter{vendor="devin";eventMap=DEVIN_HOOK_EVENT_MAP;globalSettingsPath(){return devinSettingsPath()}}import{homedir as homedir3}from"os";import{join as join3}from"path";var DROID_HOOK_EVENT_MAP=sessionStartOnly();function droidSettingsPath(home=homedir3()){return join3(home,".factory","settings.json")}class DroidHookAdapter extends SessionStartHookAdapter{vendor="droid";eventMap=DROID_HOOK_EVENT_MAP;globalSettingsPath(){return droidSettingsPath()}}import{homedir as homedir4}from"os";import{dirname as dirname3,join as join4}from"path";var GROK_HOOK_EVENT_MAP=sessionStartOnly();function grokConfigDir(home=homedir4()){return process.env.GROK_HOME?.trim()||join4(home,".grok")}function grokHooksPath(home=homedir4()){return join4(grokConfigDir(home),"hooks","rove.json")}class GrokHookAdapter extends SessionStartHookAdapter{vendor="grok";eventMap=GROK_HOOK_EVENT_MAP;globalSettingsPath(){return grokHooksPath()}installGuardDir(settingsFilePath){return dirname3(dirname3(settingsFilePath))}sessionFromPayload(payload){let sessionId=firstString2(payload.session_id,payload.sessionId);if(!sessionId)return;let transcriptPath=firstString2(payload.transcript_path,payload.transcriptPath);return{sessionId,...transcriptPath?{transcriptPath}:{}}}}function firstString2(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}import{existsSync as existsSync3}from"fs";import{rm}from"fs/promises";import{homedir as homedir5}from"os";import path2 from"path";import{mkdir,readFile,writeFile}from"fs/promises";import path from"path";async function writeIfChanged(file,content){try{if(await readFile(file,"utf8").catch(()=>{return})===content)return;await mkdir(path.dirname(file),{recursive:!0}),await writeFile(file,content)}catch{}}var HERMES_PLUGIN_NAME="rove-agent-state";function indentOf(line){if(!line.trim()||line.trim().startsWith("#"))return;let match=/^ */.exec(line),indent=match?match[0].length:0;return line[indent]==="\t"?void 0:indent}function keyAt(line,indent){if(indentOf(line)!==indent)return;return/^ *(["']?)([A-Za-z0-9_.-]+)\1:(?:\s|$)/.exec(line)?.[2]}function inlineValue(line){return(/^ *(["']?)[A-Za-z0-9_.-]+\1:(.*)$/.exec(line)?.[2]??"").trim()}function listItemAt(line,indent){if(indentOf(line)!==indent)return;let match=/^ *- *(.*)$/.exec(line);if(!match)return;return match[1].trim().replace(/^["']|["']$/g,"")}function join5(lines,trailingNewline){return lines.join(`
4
4
  `)+(trailingNewline?`
5
5
  `:"")}function setHermesPluginEnabled(content,enabled){let trailingNewline=content.endsWith(`
6
6
  `)||content==="",lines=content.length>0?content.replace(/\n$/,"").split(`
@@ -76,9 +76,9 @@ def register(ctx):
76
76
  # spawn per call to say what session start already said.
77
77
  ctx.register_hook("on_session_start", _report)
78
78
  ctx.register_hook("on_session_reset", _report)
79
- `}function hermesConfigDir(home=homedir5()){return path.join(home,".hermes")}function hermesConfigPath(home=homedir5()){return path.join(hermesConfigDir(home),"config.yaml")}class HermesHookAdapter{vendor="hermes";supportsHooks(){return!0}globalSettingsPath(){return hermesConfigPath()}activityDetailFromPayload(){return}sessionFromPayload(payload){let sessionId=typeof payload.session_id==="string"?payload.session_id:void 0;return sessionId?{sessionId}:void 0}async installActivityHooks(settingsFilePath,opts={}){let configDir=path.dirname(settingsFilePath);if(!existsSync3(configDir))return{ok:!0};let pluginDir=path.join(configDir,"plugins",HERMES_PLUGIN_NAME);await writeIfChanged(path.join(pluginDir,"plugin.yaml"),HERMES_PLUGIN_MANIFEST),await writeIfChanged(path.join(pluginDir,"__init__.py"),renderHermesPluginSource({vendor:this.vendor,invocation:roveHookInvocation()}));let outcome=await this.editConfig(settingsFilePath,!0);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] hermes: skipped ${outcome.file}: ${outcome.reason}
80
- `);return outcome}async removeActivityHooks(settingsFilePath){if(existsSync3(settingsFilePath))await this.editConfig(settingsFilePath,!1);try{await rm(path.join(path.dirname(settingsFilePath),"plugins",HERMES_PLUGIN_NAME),{recursive:!0,force:!0})}catch{}}hookConfigRefusal(raw){let edit=setHermesPluginEnabled(raw,!0);return edit.ok?void 0:edit.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}async editConfig(file,enabled){let rejected;try{await updateSharedJson(file,(raw)=>({raw:raw??""}),(doc)=>{let raw=String(doc.raw??""),edit=setHermesPluginEnabled(raw,enabled);if(!edit.ok){rejected=edit.reason;return}return edit.content===raw?void 0:edit.content})}catch(err){return{ok:!1,file,reason:err instanceof Error?err.message:String(err)}}if(rejected!==void 0)return{ok:!1,file,reason:rejected};return{ok:!0}}}async function writeIfChanged(file,content){try{if(await readFile(file,"utf8").catch(()=>{return})===content)return;await mkdir(path.dirname(file),{recursive:!0}),await writeFile(file,content)}catch{}}import{existsSync as existsSync4}from"fs";import{homedir as homedir6}from"os";import{dirname as dirname4,join as join6}from"path";var MASTRACODE_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"AgentStart",verb:"turn-start"},{event:"PermissionRequest",verb:"awaiting-input"},{event:"PermissionResult",verb:"turn-start"},{event:"Interrupt",verb:"turn-interrupted"},{event:"AgentEnd",verb:"turn-complete"},{event:"Stop",verb:"turn-complete"}],MASTRACODE_FORMAT={vendor:"mastracode",eventMap:MASTRACODE_HOOK_EVENT_MAP,withType:!0};function mastracodeHooksPath(home=homedir6()){return join6(home,".mastracode","hooks.json")}function mergeMastracodeHooks(current,install,inv=roveHookInvocation()){return mergeFlatHooks(MASTRACODE_FORMAT,current,install,inv)}class MastracodeHookAdapter{vendor="mastracode";supportsHooks(){return!0}globalSettingsPath(){return mastracodeHooksPath()}activityDetailFromPayload(kind){return kind==="awaiting-input"?{waiting:"permission"}:void 0}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync4(dirname4(settingsFilePath)))return{ok:!0};let outcome=await editJsonSettings(settingsFilePath,(cur)=>mergeMastracodeHooks(cur,!0),parseMastracodeHooks);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] mastracode: skipped ${outcome.file}: ${outcome.reason}
81
- `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync4(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeMastracodeHooks(cur,!1),parseMastracodeHooks)}hookConfigRefusal(raw){let parsed=parseMastracodeHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function parseMastracodeHooks(raw){return parseFlatHooks(raw)}import{existsSync as existsSync5}from"fs";import{mkdir as mkdir2,readFile as readFile2,rm as rm2,writeFile as writeFile2}from"fs/promises";import{homedir as homedir7}from"os";import path2 from"path";function renderOpencodePluginSource(opts){let{vendor,invocation}=opts;return`/**
79
+ `}function hermesConfigDir(home=homedir5()){return path2.join(home,".hermes")}function hermesConfigPath(home=homedir5()){return path2.join(hermesConfigDir(home),"config.yaml")}class HermesHookAdapter{vendor="hermes";supportsHooks(){return!0}globalSettingsPath(){return hermesConfigPath()}activityDetailFromPayload(){return}sessionFromPayload(payload){let sessionId=typeof payload.session_id==="string"?payload.session_id:void 0;return sessionId?{sessionId}:void 0}async installActivityHooks(settingsFilePath,opts={}){let configDir=path2.dirname(settingsFilePath);if(!existsSync3(configDir))return{ok:!0};let pluginDir=path2.join(configDir,"plugins",HERMES_PLUGIN_NAME);await writeIfChanged(path2.join(pluginDir,"plugin.yaml"),HERMES_PLUGIN_MANIFEST),await writeIfChanged(path2.join(pluginDir,"__init__.py"),renderHermesPluginSource({vendor:this.vendor,invocation:roveHookInvocation()}));let outcome=await this.editConfig(settingsFilePath,!0);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] hermes: skipped ${outcome.file}: ${outcome.reason}
80
+ `);return outcome}async removeActivityHooks(settingsFilePath){if(existsSync3(settingsFilePath))await this.editConfig(settingsFilePath,!1);try{await rm(path2.join(path2.dirname(settingsFilePath),"plugins",HERMES_PLUGIN_NAME),{recursive:!0,force:!0})}catch{}}hookConfigRefusal(raw){let edit=setHermesPluginEnabled(raw,!0);return edit.ok?void 0:edit.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}async editConfig(file,enabled){let rejected;try{await updateSharedJson(file,(raw)=>({raw:raw??""}),(doc)=>{let raw=String(doc.raw??""),edit=setHermesPluginEnabled(raw,enabled);if(!edit.ok){rejected=edit.reason;return}return edit.content===raw?void 0:edit.content})}catch(err){return{ok:!1,file,reason:err instanceof Error?err.message:String(err)}}if(rejected!==void 0)return{ok:!1,file,reason:rejected};return{ok:!0}}}import{existsSync as existsSync4}from"fs";import{homedir as homedir6}from"os";import{dirname as dirname4,join as join6}from"path";var MASTRACODE_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"AgentStart",verb:"turn-start"},{event:"PermissionRequest",verb:"awaiting-input"},{event:"PermissionResult",verb:"turn-start"},{event:"Interrupt",verb:"turn-interrupted"},{event:"AgentEnd",verb:"turn-complete"},{event:"Stop",verb:"turn-complete"}],MASTRACODE_FORMAT={vendor:"mastracode",eventMap:MASTRACODE_HOOK_EVENT_MAP,withType:!0};function mastracodeHooksPath(home=homedir6()){return join6(home,".mastracode","hooks.json")}function mergeMastracodeHooks(current,install,inv=roveHookInvocation()){return mergeFlatHooks(MASTRACODE_FORMAT,current,install,inv)}class MastracodeHookAdapter{vendor="mastracode";supportsHooks(){return!0}globalSettingsPath(){return mastracodeHooksPath()}activityDetailFromPayload(kind){return kind==="awaiting-input"?{waiting:"permission"}:void 0}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync4(dirname4(settingsFilePath)))return{ok:!0};let outcome=await editJsonSettings(settingsFilePath,(cur)=>mergeMastracodeHooks(cur,!0),parseMastracodeHooks);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] mastracode: skipped ${outcome.file}: ${outcome.reason}
81
+ `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync4(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeMastracodeHooks(cur,!1),parseMastracodeHooks)}hookConfigRefusal(raw){let parsed=parseMastracodeHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function parseMastracodeHooks(raw){return parseFlatHooks(raw)}import{existsSync as existsSync5}from"fs";import{rm as rm2}from"fs/promises";import{homedir as homedir7}from"os";import path3 from"path";function renderOpencodePluginSource(opts){let{vendor,invocation}=opts;return`/**
82
82
  * Rove activity hook \u2014 GENERATED, installed and rewritten by Rove on every
83
83
  * launch (${vendor}). Local edits are overwritten; to stop reporting, delete
84
84
  * this file or turn Rove's global hooks off. Add your own plugins beside it.
@@ -204,6 +204,6 @@ export const RoveAgentState = async (input) => {
204
204
  },
205
205
  }
206
206
  }
207
- `}var ACTIVITY_PLUGIN_FILE="rove-agent-state.js",FAMILY_DIRS={opencode:{configDir:"opencode",pluginDir:"plugins"},kilo:{configDir:"kilo",pluginDir:"plugin"}};function opencodeFamilyConfigDir(vendor,home=homedir7()){return path2.join(home,".config",FAMILY_DIRS[vendor].configDir)}function opencodeFamilyPluginPath(vendor,home=homedir7()){return path2.join(opencodeFamilyConfigDir(vendor,home),FAMILY_DIRS[vendor].pluginDir,ACTIVITY_PLUGIN_FILE)}function opencodeFailureDetail(payload){let raw=typeof payload.error_message==="string"?payload.error_message:"",message=raw.toLowerCase(),note=raw?raw.slice(0,200):void 0;return{failure:(()=>{if(/insufficient|credit|billing|payment required|\b402\b|quota exceeded|out of credits/.test(message))return"billing";if(/rate.?limit|too many requests|\b429\b|overloaded|capacity/.test(message))return"rate_limit";return"other"})(),...note?{note}:{}}}class OpencodeFamilyHookAdapter{family;vendor;constructor(family){this.family=family;this.vendor=family}supportsHooks(){return!0}globalSettingsPath(){return opencodeFamilyPluginPath(this.family)}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return opencodeFailureDetail(payload);if(kind==="awaiting-input")return{waiting:payload.waiting==="input"?"input":"permission"};return}sessionFromPayload(payload){let sessionId=typeof payload.session_id==="string"?payload.session_id:void 0;return sessionId?{sessionId}:void 0}async installActivityHooks(settingsFilePath){let configDir=path2.dirname(path2.dirname(settingsFilePath));if(!existsSync5(configDir))return{ok:!0};let source=renderOpencodePluginSource({vendor:this.family,invocation:roveHookInvocation()});return await writeIfChanged2(settingsFilePath,source),{ok:!0}}async removeActivityHooks(settingsFilePath){try{await rm2(settingsFilePath,{force:!0})}catch{}}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}async function writeIfChanged2(file,content){try{if(await readFile2(file,"utf8").catch(()=>{return})===content)return;await mkdir2(path2.dirname(file),{recursive:!0}),await writeFile2(file,content)}catch{}}import{homedir as homedir8}from"os";import{join as join7}from"path";var QODERCLI_HOOK_EVENT_MAP=sessionStartOnly("*");function qodercliSettingsPath(home=homedir8()){let override=process.env.QODERCLI_CONFIG_DIR?.trim();return join7(override||join7(home,".qoder"),"settings.json")}class QodercliHookAdapter extends SessionStartHookAdapter{vendor="qodercli";eventMap=QODERCLI_HOOK_EVENT_MAP;globalSettingsPath(){return qodercliSettingsPath()}}var pluginEngines=new Map;function registerPluginEngine(id,spec){if(Object.hasOwn(CONTRIB_ENGINES,id))return!1;return pluginEngines.set(id,spec),!0}function clearPluginEngines(){pluginEngines.clear()}function pluginEngineIds(){return[...pluginEngines.keys()]}var CONTRIB_ENGINES={gemini:{displayName:"Gemini CLI",defaultCommand:["gemini"],screenManifest:GEMINI},opencode:{displayName:"OpenCode",defaultCommand:["opencode"],screenManifest:OPENCODE,firstMessageDelivery:"paste",createHookAdapter:()=>new OpencodeFamilyHookAdapter("opencode")},cursor:{displayName:"Cursor Agent",defaultCommand:["cursor-agent"],screenManifest:CURSOR,createHookAdapter:()=>new CursorHookAdapter},grok:{displayName:"Grok CLI",defaultCommand:["grok"],screenManifest:GROK,createHookAdapter:()=>new GrokHookAdapter},droid:{displayName:"Droid",defaultCommand:["droid"],screenManifest:DROID,createHookAdapter:()=>new DroidHookAdapter},amp:{displayName:"Amp",defaultCommand:["amp"],screenManifest:AMP},devin:{displayName:"Devin",defaultCommand:["devin"],processNames:["devin-cli"],screenManifest:DEVIN,createHookAdapter:()=>new DevinHookAdapter},qodercli:{displayName:"Qoder CLI",defaultCommand:["qodercli"],processNames:["qoder","qoderclicn","qodercn"],screenManifest:QODERCLI,createHookAdapter:()=>new QodercliHookAdapter},cline:{displayName:"Cline",defaultCommand:["cline"],screenManifest:CLINE},kiro:{displayName:"Kiro CLI",defaultCommand:["kiro-cli"],processNames:["kiro"],screenManifest:KIRO},maki:{displayName:"Maki",defaultCommand:["maki"],screenManifest:MAKI},antigravity:{displayName:"Antigravity",defaultCommand:["agy"],processNames:["antigravity","antigravity-cli"],screenManifest:ANTIGRAVITY},hermes:{displayName:"Hermes Agent",defaultCommand:["hermes"],processNames:["hermes-agent"],screenManifest:HERMES,createHookAdapter:()=>new HermesHookAdapter},kilo:{displayName:"Kilo",defaultCommand:["kilo"],processNames:["kilo-code"],screenManifest:KILO,firstMessageDelivery:"paste",createHookAdapter:()=>new OpencodeFamilyHookAdapter("kilo")},mastracode:{displayName:"MastraCode",defaultCommand:["mastracode"],processNames:["mastra-code"],screenManifest:MASTRACODE,createHookAdapter:()=>new MastracodeHookAdapter}};function isContribEngine(id){return Object.hasOwn(CONTRIB_ENGINES,id)||pluginEngines.has(id)}var CONTRIB_ENGINE_IDS=Object.keys(CONTRIB_ENGINES);function contribEngineEntry(id,base){let spec=CONTRIB_ENGINES[id]??pluginEngines.get(id);if(!spec)return base;return{...base,displayName:spec.displayName,defaultCommand:spec.defaultCommand,...spec.processNames?{processNames:spec.processNames}:{},screenManifest:spec.screenManifest,...spec.identity?{identity:spec.identity}:{},...spec.firstMessageDelivery?{firstMessageDelivery:spec.firstMessageDelivery}:{},...spec.createHookAdapter?{createHookAdapter:spec.createHookAdapter}:{}}}import{homedir as homedir10}from"os";import{spawnSync}from"child_process";import{existsSync as existsSync6,statSync}from"fs";import{homedir as homedir9}from"os";import path3 from"path";var defaultBinaryDeps={fileExists(p){try{return statSync(p).isFile()}catch{return!1}},env(name){return process.env[name]},home(){return homedir9()},which(name){let cmd=process.platform==="win32"?"where":"which",out=spawnSync(cmd,[name],{encoding:"utf8"});if(out.status!==0)return;let first=out.stdout.split(`
208
- `).map((l)=>l.trim()).filter(Boolean)[0];if(!first)return;if(first.startsWith(`${name}:`)&&first.includes("aliased to")){let aliasTarget=first.split("aliased to")[1]?.trim();return aliasTarget&&existsSync6(aliasTarget)?aliasTarget:void 0}return first},readdir(p){try{return __require("fs").readdirSync(p)}catch{return[]}}};class BinaryNotFoundError extends Error{checkedPaths;constructor(label,hint,checkedPaths){super(`${label} not found. Checked: ${checkedPaths.join(", ")}. ${hint}`);this.name="BinaryNotFoundError",this.checkedPaths=checkedPaths}}function npmStyleDirs({deps,home},locations=["system","nvm","windowsNpm","npmGlobal","local","bun","bin"]){return locations.flatMap((location)=>{switch(location){case"system":return["/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"];case"homebrew":return["/opt/homebrew/bin","/usr/local/bin"];case"nvm":{let bin=deps.env("NVM_BIN");return bin?[bin]:[]}case"windowsNpm":{if((deps.platform?.()??process.platform)!=="win32")return[];let appData=deps.env("APPDATA"),localAppData=deps.env("LOCALAPPDATA");return[...localAppData?[path3.join(localAppData,"npm")]:[],...appData?[path3.join(appData,"npm")]:[],path3.join(home,"AppData/Roaming/npm")]}case"npmGlobal":return[path3.join(home,".npm-global/bin")];case"local":return[path3.join(home,".local/bin")];case"yarn":return[path3.join(home,".yarn/bin")];case"bun":return[path3.join(home,".bun/bin")];case"bin":return[path3.join(home,"bin")]}})}function npmStyleBinaryCandidates(ctx,name){let names=(ctx.deps.platform?.()??process.platform)==="win32"?[`${name}.exe`,`${name}.cmd`,name]:[name];return npmStyleDirs(ctx).flatMap((dir)=>names.map((n)=>path3.join(dir,n)))}function createBinaryFinder(spec){return async function(deps=defaultBinaryDeps){let checked=[],whichResult=deps.which(spec.name);if(whichResult){if(checked.push(`which:${whichResult}`),deps.fileExists(whichResult))return whichResult}for(let candidate of spec.candidates({deps,home:deps.home()}))if(checked.push(candidate),deps.fileExists(candidate))return candidate;throw spec.notFound(checked)}}class BobBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("IBM Bob Shell binary","Ensure 'bob' is on PATH (for example `curl -fsSL https://bob.ibm.com/download/bobshell.sh | bash`).",checkedPaths);this.name="BobBinaryNotFoundError"}}var findBobBinary=createBinaryFinder({name:"bob",candidates:(ctx)=>npmStyleBinaryCandidates(ctx,"bob"),notFound:(checked)=>new BobBinaryNotFoundError(checked)});import path4 from"path";class ClaudeBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Claude Code binary","Ensure 'claude' is on PATH, or install at ~/.claude/local/claude.",checkedPaths);this.name="ClaudeBinaryNotFoundError"}}var findClaudeBinary=createBinaryFinder({name:"claude",candidates({deps,home}){let out=[path4.join(home,".claude","local","claude")];out.push(...npmStyleDirs({deps,home},["nvm"]).map((dir)=>path4.join(dir,"claude")));let nvmRoot=path4.join(home,".nvm","versions","node"),versions=(deps.readdir?.(nvmRoot)??[]).sort((a,b)=>b.localeCompare(a,void 0,{numeric:!0}));for(let v of versions)out.push(path4.join(nvmRoot,v,"bin","claude"));return out.push(...npmStyleDirs({deps,home},["system","local","npmGlobal","yarn","bun","bin"]).map((dir)=>path4.join(dir,"claude"))),out},notFound:(checked)=>new ClaudeBinaryNotFoundError(checked)});import path5 from"path";class CodexBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Codex CLI binary","Ensure 'codex' is on PATH (e.g. `brew install codex` or the official installer).",checkedPaths);this.name="CodexBinaryNotFoundError"}}var findCodexBinary=createBinaryFinder({name:"codex",candidates({deps,home}){return npmStyleDirs({deps,home},["system","nvm","local","bun","bin"]).map((dir)=>path5.join(dir,"codex"))},notFound:(checked)=>new CodexBinaryNotFoundError(checked)});class CopilotBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("GitHub Copilot CLI binary","Ensure 'copilot' is on PATH (for example `npm install -g @github/copilot` or `brew install copilot-cli`).",checkedPaths);this.name="CopilotBinaryNotFoundError"}}var findCopilotBinary=createBinaryFinder({name:"copilot",candidates:(ctx)=>npmStyleBinaryCandidates(ctx,"copilot"),notFound:(checked)=>new CopilotBinaryNotFoundError(checked)});import path6 from"path";class KimiBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Kimi Code CLI binary","Ensure 'kimi' is on PATH or installed at ~/.kimi-code/bin/kimi.",checkedPaths);this.name="KimiBinaryNotFoundError"}}var findKimiBinary=createBinaryFinder({name:"kimi",candidates:(ctx)=>[path6.join(ctx.home,".kimi-code/bin"),...npmStyleDirs(ctx,["local","bin","homebrew"])].map((dir)=>path6.join(dir,"kimi")),notFound:(checked)=>new KimiBinaryNotFoundError(checked)});import path7 from"path";class PiFamilyBinaryNotFoundError extends BinaryNotFoundError{constructor(name,checkedPaths){super(`${name} CLI binary`,`Ensure '${name}' is on PATH (e.g. \`brew install ${name}\`, or \`npm i -g ${name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent"}\`).`,checkedPaths);this.name="PiFamilyBinaryNotFoundError"}}function candidatesFor(name,ctx){let{home}=ctx,out=npmStyleDirs(ctx,["system","local","bun","bin"]).map((dir)=>path7.join(dir,name)),packageName=name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent";for(let prefix of[path7.join(home,".npm-global"),"/usr/local","/opt/homebrew"])out.push(path7.join(prefix,"bin",name)),out.push(path7.join(prefix,"lib/node_modules",packageName,"dist","cli.js"));return out}var findPiBinary=createBinaryFinder({name:"pi",candidates:(ctx)=>candidatesFor("pi",ctx),notFound:(checked)=>new PiFamilyBinaryNotFoundError("pi",checked)}),findOmpBinary=createBinaryFinder({name:"omp",candidates:(ctx)=>candidatesFor("omp",ctx),notFound:(checked)=>new PiFamilyBinaryNotFoundError("omp",checked)});var defaultDeps={readFile(p){return readTextFileSyncBounded(p)},env(name){return process.env[name]},home(){return homedir10()},findClaudeBinary(){return findClaudeBinary()},findCodexBinary(){return findCodexBinary()},findBobBinary(){return findBobBinary()},findCopilotBinary(){return findCopilotBinary()},findKimiBinary(){return findKimiBinary()},findPiBinary(){return findPiBinary()},findOmpBinary(){return findOmpBinary()}};function decodeJwtPayload(jwt){let parts=jwt.split(".");if(parts.length!==3)return null;let payload=parts[1];if(!payload)return null;let b64=payload.replace(/-/g,"+").replace(/_/g,"/"),padded=b64+"=".repeat((4-b64.length%4)%4);try{let json=Buffer.from(padded,"base64").toString("utf8"),obj=JSON.parse(json);return typeof obj==="object"&&obj!==null?obj:null}catch{return null}}async function probeBinary(probe){try{return{found:!0,path:await probe()}}catch(err){if(err instanceof BinaryNotFoundError)return{found:!1,error:"not found on PATH"};return{found:!1,error:errorMessage(err)}}}var cachedDefaultVendors=null;async function probeAvailableVendors(deps){return(await Promise.all([["claude",()=>deps.findClaudeBinary()],["codex",()=>deps.findCodexBinary()],["copilot",()=>deps.findCopilotBinary()],["kimi",()=>deps.findKimiBinary()],["pi",()=>deps.findPiBinary()],["omp",()=>deps.findOmpBinary()]].map(async([vendor,probe])=>(await probeBinary(probe)).found?vendor:null))).filter((v)=>v!==null)}function detectAvailableVendors(deps=defaultDeps){if(deps!==defaultDeps)return probeAvailableVendors(deps);if(cachedDefaultVendors)return cachedDefaultVendors;let pending=probeAvailableVendors(deps).catch((err)=>{throw cachedDefaultVendors=null,err});return cachedDefaultVendors=pending,pending}function resetAvailableVendorsCache(){cachedDefaultVendors=null,cachedContribEngines=null}async function installedEngineIds(deps=defaultDeps){let builtins=await detectAvailableVendors(deps),contrib=await detectContribEngines();return[...new Set([...builtins,...getCustomEngineIds(),...contrib])]}async function availableEngineIds(deps=defaultDeps){let disabled=new Set(getDisabledEngineIds());return(await installedEngineIds(deps)).filter((id)=>!disabled.has(id))}var cachedContribEngines=null;function detectContribEngines(){if(cachedContribEngines)return cachedContribEngines;let which=globalThis.Bun?.which;return cachedContribEngines=Promise.resolve([...which?CONTRIB_ENGINE_IDS.filter((id)=>{let bin=CONTRIB_ENGINES[id]?.defaultCommand[0];return bin?which(bin)!==null:!1}):[],...pluginEngineIds()]),cachedContribEngines}async function detectClaudeAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findClaudeBinary()),configPath=claudeGlobalConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}let oauth=parsed?.oauthAccount;if(!oauth||typeof oauth!=="object")return{binary,account:{kind:"none"}};let o=oauth,email=typeof o.emailAddress==="string"?o.emailAddress:void 0;if(!email)return{binary,account:{kind:"none"}};return{binary,account:{kind:"oauth",email,organization:typeof o.organizationName==="string"?o.organizationName:void 0,displayName:typeof o.displayName==="string"?o.displayName:void 0,billingType:typeof o.billingType==="string"?o.billingType:void 0}}}async function detectCodexAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCodexBinary()),authPath=codexAuthPath(deps.env,deps.home()),raw;try{raw=deps.readFile(authPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${authPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${authPath}: ${errorMessage(err)}`}}let obj=parsed??{},tokens=obj.tokens,idToken=typeof tokens?.id_token==="string"?tokens.id_token:void 0;if(idToken){let payload=decodeJwtPayload(idToken);if(!payload)return{binary,account:{kind:"none"},accountError:"codex id_token: malformed JWT"};let email=typeof payload.email==="string"?payload.email:void 0,authClaimRaw=payload["https://api.openai.com/auth"],authClaim=isObject(authClaimRaw)?authClaimRaw:void 0,plan=typeof authClaim?.chatgpt_plan_type==="string"?authClaim.chatgpt_plan_type:void 0;if(email)return{binary,account:{kind:"chatgpt",email,plan}};return{binary,account:{kind:"none"},accountError:"codex id_token: no email claim"}}let apiKey=obj.OPENAI_API_KEY;if(typeof apiKey==="string"&&apiKey.length>0)return{binary,account:{kind:"apikey"}};return{binary,account:{kind:"none"}}}async function detectCopilotAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCopilotBinary());for(let source of["COPILOT_GITHUB_TOKEN","GH_TOKEN","GITHUB_TOKEN"])if(deps.env(source)?.trim())return{binary,account:{kind:"token",source}};let configPath=copilotConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};if(hasStringDeep(parsed,["github_token","oauth_token","access_token","token","selectedUser","currentUser","user"]))return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}async function detectBobAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findBobBinary()),secretsPath=bobAuthSecretsPath(deps.home()),raw;try{raw=deps.readFile(secretsPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${secretsPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${secretsPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};let signedIn=Object.entries(parsed).some(([key,value])=>key.startsWith("bob.auth.tokens-")&&typeof value==="string"&&value.length>0);return{binary,account:signedIn?{kind:"oauth"}:{kind:"none"}}}async function detectKimiAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findKimiBinary()),credPath=kimiCredentialsPath(deps.env,deps.home()),raw;try{raw=deps.readFile(credPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${credPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${credPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};let token=parsed.access_token;if(typeof token==="string"&&token.length>0)return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}function hasStringDeep(value,interestingKeys,depth=0){if(depth>4||!isObject(value))return!1;for(let[key,entry]of Object.entries(value)){if(interestingKeys.includes(key)&&typeof entry==="string"&&entry.length>0)return!0;if(isObject(entry)&&hasStringDeep(entry,interestingKeys,depth+1))return!0}return!1}
209
- export{parseFlatHooks,mergeFlatHooks,registerPluginEngine,clearPluginEngines,pluginEngineIds,isContribEngine,CONTRIB_ENGINE_IDS,contribEngineEntry,resetAvailableVendorsCache,installedEngineIds,availableEngineIds,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectBobAccount,detectKimiAccount};
207
+ `}var ACTIVITY_PLUGIN_FILE="rove-agent-state.js",FAMILY_DIRS={opencode:{configDir:"opencode",pluginDir:"plugins"},kilo:{configDir:"kilo",pluginDir:"plugin"}};function opencodeFamilyConfigDir(vendor,home=homedir7()){return path3.join(home,".config",FAMILY_DIRS[vendor].configDir)}function opencodeFamilyPluginPath(vendor,home=homedir7()){return path3.join(opencodeFamilyConfigDir(vendor,home),FAMILY_DIRS[vendor].pluginDir,ACTIVITY_PLUGIN_FILE)}function opencodeFailureDetail(payload){let raw=typeof payload.error_message==="string"?payload.error_message:"",message=raw.toLowerCase(),note=raw?raw.slice(0,200):void 0;return{failure:(()=>{if(/insufficient|credit|billing|payment required|\b402\b|quota exceeded|out of credits/.test(message))return"billing";if(/rate.?limit|too many requests|\b429\b|overloaded|capacity/.test(message))return"rate_limit";return"other"})(),...note?{note}:{}}}class OpencodeFamilyHookAdapter{family;vendor;constructor(family){this.family=family;this.vendor=family}supportsHooks(){return!0}globalSettingsPath(){return opencodeFamilyPluginPath(this.family)}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return opencodeFailureDetail(payload);if(kind==="awaiting-input")return{waiting:payload.waiting==="input"?"input":"permission"};return}sessionFromPayload(payload){let sessionId=typeof payload.session_id==="string"?payload.session_id:void 0;return sessionId?{sessionId}:void 0}async installActivityHooks(settingsFilePath){let configDir=path3.dirname(path3.dirname(settingsFilePath));if(!existsSync5(configDir))return{ok:!0};let source=renderOpencodePluginSource({vendor:this.family,invocation:roveHookInvocation()});return await writeIfChanged(settingsFilePath,source),{ok:!0}}async removeActivityHooks(settingsFilePath){try{await rm2(settingsFilePath,{force:!0})}catch{}}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}import{homedir as homedir8}from"os";import{join as join7}from"path";var QODERCLI_HOOK_EVENT_MAP=sessionStartOnly("*");function qodercliSettingsPath(home=homedir8()){let override=process.env.QODERCLI_CONFIG_DIR?.trim();return join7(override||join7(home,".qoder"),"settings.json")}class QodercliHookAdapter extends SessionStartHookAdapter{vendor="qodercli";eventMap=QODERCLI_HOOK_EVENT_MAP;globalSettingsPath(){return qodercliSettingsPath()}}var pluginEngines=new Map;function registerPluginEngine(id,spec){if(Object.hasOwn(CONTRIB_ENGINES,id))return!1;return pluginEngines.set(id,spec),!0}function clearPluginEngines(){pluginEngines.clear()}function pluginEngineIds(){return[...pluginEngines.keys()]}var CONTRIB_ENGINES={gemini:{displayName:"Gemini CLI",defaultCommand:["gemini"],screenManifest:GEMINI},opencode:{displayName:"OpenCode",defaultCommand:["opencode"],screenManifest:OPENCODE,firstMessageDelivery:"paste",createHookAdapter:()=>new OpencodeFamilyHookAdapter("opencode")},cursor:{displayName:"Cursor Agent",defaultCommand:["cursor-agent"],screenManifest:CURSOR,createHookAdapter:()=>new CursorHookAdapter},grok:{displayName:"Grok CLI",defaultCommand:["grok"],screenManifest:GROK,createHookAdapter:()=>new GrokHookAdapter},droid:{displayName:"Droid",defaultCommand:["droid"],screenManifest:DROID,createHookAdapter:()=>new DroidHookAdapter},amp:{displayName:"Amp",defaultCommand:["amp"],screenManifest:AMP},devin:{displayName:"Devin",defaultCommand:["devin"],processNames:["devin-cli"],screenManifest:DEVIN,createHookAdapter:()=>new DevinHookAdapter},qodercli:{displayName:"Qoder CLI",defaultCommand:["qodercli"],processNames:["qoder","qoderclicn","qodercn"],screenManifest:QODERCLI,createHookAdapter:()=>new QodercliHookAdapter},cline:{displayName:"Cline",defaultCommand:["cline"],screenManifest:CLINE},kiro:{displayName:"Kiro CLI",defaultCommand:["kiro-cli"],processNames:["kiro"],screenManifest:KIRO},maki:{displayName:"Maki",defaultCommand:["maki"],screenManifest:MAKI},antigravity:{displayName:"Antigravity",defaultCommand:["agy"],processNames:["antigravity","antigravity-cli"],screenManifest:ANTIGRAVITY},hermes:{displayName:"Hermes Agent",defaultCommand:["hermes"],processNames:["hermes-agent"],screenManifest:HERMES,createHookAdapter:()=>new HermesHookAdapter},kilo:{displayName:"Kilo",defaultCommand:["kilo"],processNames:["kilo-code"],screenManifest:KILO,firstMessageDelivery:"paste",createHookAdapter:()=>new OpencodeFamilyHookAdapter("kilo")},mastracode:{displayName:"MastraCode",defaultCommand:["mastracode"],processNames:["mastra-code"],screenManifest:MASTRACODE,createHookAdapter:()=>new MastracodeHookAdapter}};function isContribEngine(id){return Object.hasOwn(CONTRIB_ENGINES,id)||pluginEngines.has(id)}var CONTRIB_ENGINE_IDS=Object.keys(CONTRIB_ENGINES);function contribEngineEntry(id,base){let spec=CONTRIB_ENGINES[id]??pluginEngines.get(id);if(!spec)return base;return{...base,displayName:spec.displayName,defaultCommand:spec.defaultCommand,...spec.processNames?{processNames:spec.processNames}:{},screenManifest:spec.screenManifest,...spec.identity?{identity:spec.identity}:{},...spec.firstMessageDelivery?{firstMessageDelivery:spec.firstMessageDelivery}:{},...spec.createHookAdapter?{createHookAdapter:spec.createHookAdapter}:{}}}import{homedir as homedir10}from"os";import{spawnSync}from"child_process";import{existsSync as existsSync6,statSync}from"fs";import{homedir as homedir9}from"os";import path4 from"path";var defaultBinaryDeps={fileExists(p){try{return statSync(p).isFile()}catch{return!1}},env(name){return process.env[name]},home(){return homedir9()},which(name){let cmd=process.platform==="win32"?"where":"which",out=spawnSync(cmd,[name],{encoding:"utf8"});if(out.status!==0)return;let first=out.stdout.split(`
208
+ `).map((l)=>l.trim()).filter(Boolean)[0];if(!first)return;if(first.startsWith(`${name}:`)&&first.includes("aliased to")){let aliasTarget=first.split("aliased to")[1]?.trim();return aliasTarget&&existsSync6(aliasTarget)?aliasTarget:void 0}return first},readdir(p){try{return __require("fs").readdirSync(p)}catch{return[]}}};class BinaryNotFoundError extends Error{checkedPaths;constructor(label,hint,checkedPaths){super(`${label} not found. Checked: ${checkedPaths.join(", ")}. ${hint}`);this.name="BinaryNotFoundError",this.checkedPaths=checkedPaths}}function npmStyleDirs({deps,home},locations=["system","nvm","windowsNpm","npmGlobal","local","bun","bin"]){return locations.flatMap((location)=>{switch(location){case"system":return["/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"];case"homebrew":return["/opt/homebrew/bin","/usr/local/bin"];case"nvm":{let bin=deps.env("NVM_BIN");return bin?[bin]:[]}case"windowsNpm":{if((deps.platform?.()??process.platform)!=="win32")return[];let appData=deps.env("APPDATA"),localAppData=deps.env("LOCALAPPDATA");return[...localAppData?[path4.join(localAppData,"npm")]:[],...appData?[path4.join(appData,"npm")]:[],path4.join(home,"AppData/Roaming/npm")]}case"npmGlobal":return[path4.join(home,".npm-global/bin")];case"local":return[path4.join(home,".local/bin")];case"yarn":return[path4.join(home,".yarn/bin")];case"bun":return[path4.join(home,".bun/bin")];case"bin":return[path4.join(home,"bin")]}})}function npmStyleBinaryCandidates(ctx,name){let names=(ctx.deps.platform?.()??process.platform)==="win32"?[`${name}.exe`,`${name}.cmd`,name]:[name];return npmStyleDirs(ctx).flatMap((dir)=>names.map((n)=>path4.join(dir,n)))}function createBinaryFinder(spec){return async function(deps=defaultBinaryDeps){let checked=[],whichResult=deps.which(spec.name);if(whichResult){if(checked.push(`which:${whichResult}`),deps.fileExists(whichResult))return whichResult}for(let candidate of spec.candidates({deps,home:deps.home()}))if(checked.push(candidate),deps.fileExists(candidate))return candidate;throw spec.notFound(checked)}}class BobBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("IBM Bob Shell binary","Ensure 'bob' is on PATH (for example `curl -fsSL https://bob.ibm.com/download/bobshell.sh | bash`).",checkedPaths);this.name="BobBinaryNotFoundError"}}var findBobBinary=createBinaryFinder({name:"bob",candidates:(ctx)=>npmStyleBinaryCandidates(ctx,"bob"),notFound:(checked)=>new BobBinaryNotFoundError(checked)});import path5 from"path";class ClaudeBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Claude Code binary","Ensure 'claude' is on PATH, or install at ~/.claude/local/claude.",checkedPaths);this.name="ClaudeBinaryNotFoundError"}}var findClaudeBinary=createBinaryFinder({name:"claude",candidates({deps,home}){let out=[path5.join(home,".claude","local","claude")];out.push(...npmStyleDirs({deps,home},["nvm"]).map((dir)=>path5.join(dir,"claude")));let nvmRoot=path5.join(home,".nvm","versions","node"),versions=(deps.readdir?.(nvmRoot)??[]).sort((a,b)=>b.localeCompare(a,void 0,{numeric:!0}));for(let v of versions)out.push(path5.join(nvmRoot,v,"bin","claude"));return out.push(...npmStyleDirs({deps,home},["system","local","npmGlobal","yarn","bun","bin"]).map((dir)=>path5.join(dir,"claude"))),out},notFound:(checked)=>new ClaudeBinaryNotFoundError(checked)});import path6 from"path";class CodexBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Codex CLI binary","Ensure 'codex' is on PATH (e.g. `brew install codex` or the official installer).",checkedPaths);this.name="CodexBinaryNotFoundError"}}var findCodexBinary=createBinaryFinder({name:"codex",candidates({deps,home}){return npmStyleDirs({deps,home},["system","nvm","local","bun","bin"]).map((dir)=>path6.join(dir,"codex"))},notFound:(checked)=>new CodexBinaryNotFoundError(checked)});class CopilotBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("GitHub Copilot CLI binary","Ensure 'copilot' is on PATH (for example `npm install -g @github/copilot` or `brew install copilot-cli`).",checkedPaths);this.name="CopilotBinaryNotFoundError"}}var findCopilotBinary=createBinaryFinder({name:"copilot",candidates:(ctx)=>npmStyleBinaryCandidates(ctx,"copilot"),notFound:(checked)=>new CopilotBinaryNotFoundError(checked)});import path7 from"path";class KimiBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Kimi Code CLI binary","Ensure 'kimi' is on PATH or installed at ~/.kimi-code/bin/kimi.",checkedPaths);this.name="KimiBinaryNotFoundError"}}var findKimiBinary=createBinaryFinder({name:"kimi",candidates:(ctx)=>[path7.join(ctx.home,".kimi-code/bin"),...npmStyleDirs(ctx,["local","bin","homebrew"])].map((dir)=>path7.join(dir,"kimi")),notFound:(checked)=>new KimiBinaryNotFoundError(checked)});import path8 from"path";class PiFamilyBinaryNotFoundError extends BinaryNotFoundError{constructor(name,checkedPaths){super(`${name} CLI binary`,`Ensure '${name}' is on PATH (e.g. \`brew install ${name}\`, or \`npm i -g ${name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent"}\`).`,checkedPaths);this.name="PiFamilyBinaryNotFoundError"}}function candidatesFor(name,ctx){let{home}=ctx,out=npmStyleDirs(ctx,["system","local","bun","bin"]).map((dir)=>path8.join(dir,name)),packageName=name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent";for(let prefix of[path8.join(home,".npm-global"),"/usr/local","/opt/homebrew"])out.push(path8.join(prefix,"bin",name)),out.push(path8.join(prefix,"lib/node_modules",packageName,"dist","cli.js"));return out}var findPiBinary=createBinaryFinder({name:"pi",candidates:(ctx)=>candidatesFor("pi",ctx),notFound:(checked)=>new PiFamilyBinaryNotFoundError("pi",checked)}),findOmpBinary=createBinaryFinder({name:"omp",candidates:(ctx)=>candidatesFor("omp",ctx),notFound:(checked)=>new PiFamilyBinaryNotFoundError("omp",checked)});var defaultDeps={readFile(p){return readTextFileSyncBounded(p)},env(name){return process.env[name]},home(){return homedir10()},findClaudeBinary(){return findClaudeBinary()},findCodexBinary(){return findCodexBinary()},findBobBinary(){return findBobBinary()},findCopilotBinary(){return findCopilotBinary()},findKimiBinary(){return findKimiBinary()},findPiBinary(){return findPiBinary()},findOmpBinary(){return findOmpBinary()}};function decodeJwtPayload(jwt){let parts=jwt.split(".");if(parts.length!==3)return null;let payload=parts[1];if(!payload)return null;let b64=payload.replace(/-/g,"+").replace(/_/g,"/"),padded=b64+"=".repeat((4-b64.length%4)%4);try{let json=Buffer.from(padded,"base64").toString("utf8"),obj=JSON.parse(json);return typeof obj==="object"&&obj!==null?obj:null}catch{return null}}async function probeBinary(probe){try{return{found:!0,path:await probe()}}catch(err){if(err instanceof BinaryNotFoundError)return{found:!1,error:"not found on PATH"};return{found:!1,error:errorMessage(err)}}}var cachedDefaultVendors=null;async function probeAvailableVendors(deps){return(await Promise.all([["claude",()=>deps.findClaudeBinary()],["codex",()=>deps.findCodexBinary()],["copilot",()=>deps.findCopilotBinary()],["kimi",()=>deps.findKimiBinary()],["pi",()=>deps.findPiBinary()],["omp",()=>deps.findOmpBinary()]].map(async([vendor,probe])=>(await probeBinary(probe)).found?vendor:null))).filter((v)=>v!==null)}function detectAvailableVendors(deps=defaultDeps){if(deps!==defaultDeps)return probeAvailableVendors(deps);if(cachedDefaultVendors)return cachedDefaultVendors;let pending=probeAvailableVendors(deps).catch((err)=>{throw cachedDefaultVendors=null,err});return cachedDefaultVendors=pending,pending}function resetAvailableVendorsCache(){cachedDefaultVendors=null,cachedContribEngines=null}async function installedEngineIds(deps=defaultDeps){let builtins=await detectAvailableVendors(deps),contrib=await detectContribEngines();return[...new Set([...builtins,...getCustomEngineIds(),...contrib])]}async function availableEngineIds(deps=defaultDeps){let disabled=new Set(getDisabledEngineIds());return(await installedEngineIds(deps)).filter((id)=>!disabled.has(id))}var cachedContribEngines=null;function detectContribEngines(){if(cachedContribEngines)return cachedContribEngines;let which=globalThis.Bun?.which;return cachedContribEngines=Promise.resolve([...which?CONTRIB_ENGINE_IDS.filter((id)=>{let bin=CONTRIB_ENGINES[id]?.defaultCommand[0];return bin?which(bin)!==null:!1}):[],...pluginEngineIds()]),cachedContribEngines}async function detectClaudeAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findClaudeBinary()),configPath=claudeGlobalConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}let oauth=parsed?.oauthAccount;if(!oauth||typeof oauth!=="object")return{binary,account:{kind:"none"}};let o=oauth,email=typeof o.emailAddress==="string"?o.emailAddress:void 0;if(!email)return{binary,account:{kind:"none"}};return{binary,account:{kind:"oauth",email,organization:typeof o.organizationName==="string"?o.organizationName:void 0,displayName:typeof o.displayName==="string"?o.displayName:void 0,billingType:typeof o.billingType==="string"?o.billingType:void 0}}}async function detectCodexAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCodexBinary()),authPath=codexAuthPath(deps.env,deps.home()),raw;try{raw=deps.readFile(authPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${authPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${authPath}: ${errorMessage(err)}`}}let obj=parsed??{},tokens=obj.tokens,idToken=typeof tokens?.id_token==="string"?tokens.id_token:void 0;if(idToken){let payload=decodeJwtPayload(idToken);if(!payload)return{binary,account:{kind:"none"},accountError:"codex id_token: malformed JWT"};let email=typeof payload.email==="string"?payload.email:void 0,authClaimRaw=payload["https://api.openai.com/auth"],authClaim=isObject(authClaimRaw)?authClaimRaw:void 0,plan=typeof authClaim?.chatgpt_plan_type==="string"?authClaim.chatgpt_plan_type:void 0;if(email)return{binary,account:{kind:"chatgpt",email,plan}};return{binary,account:{kind:"none"},accountError:"codex id_token: no email claim"}}let apiKey=obj.OPENAI_API_KEY;if(typeof apiKey==="string"&&apiKey.length>0)return{binary,account:{kind:"apikey"}};return{binary,account:{kind:"none"}}}async function detectCopilotAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCopilotBinary());for(let source of["COPILOT_GITHUB_TOKEN","GH_TOKEN","GITHUB_TOKEN"])if(deps.env(source)?.trim())return{binary,account:{kind:"token",source}};let configPath=copilotConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};if(hasStringDeep(parsed,["github_token","oauth_token","access_token","token","selectedUser","currentUser","user"]))return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}async function detectBobAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findBobBinary()),secretsPath=bobAuthSecretsPath(deps.home()),raw;try{raw=deps.readFile(secretsPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${secretsPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${secretsPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};let signedIn=Object.entries(parsed).some(([key,value])=>key.startsWith("bob.auth.tokens-")&&typeof value==="string"&&value.length>0);return{binary,account:signedIn?{kind:"oauth"}:{kind:"none"}}}async function detectKimiAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findKimiBinary()),credPath=kimiCredentialsPath(deps.env,deps.home()),raw;try{raw=deps.readFile(credPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${credPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${credPath}: ${errorMessage(err)}`}}if(!isObject(parsed))return{binary,account:{kind:"none"}};let token=parsed.access_token;if(typeof token==="string"&&token.length>0)return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}function hasStringDeep(value,interestingKeys,depth=0){if(depth>4||!isObject(value))return!1;for(let[key,entry]of Object.entries(value)){if(interestingKeys.includes(key)&&typeof entry==="string"&&entry.length>0)return!0;if(isObject(entry)&&hasStringDeep(entry,interestingKeys,depth+1))return!0}return!1}
209
+ export{parseFlatHooks,mergeFlatHooks,writeIfChanged,registerPluginEngine,clearPluginEngines,pluginEngineIds,isContribEngine,CONTRIB_ENGINE_IDS,contribEngineEntry,resetAvailableVendorsCache,installedEngineIds,availableEngineIds,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectBobAccount,detectKimiAccount};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{RELEASE_CHANNELS,channelOf}from"./chunk-4vad6e9t.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";var UPDATE_CHANNEL_KEY="update.channel";function normalizeReleaseChannel(value){return RELEASE_CHANNELS.includes(value)?value:null}function preferredReleaseChannel(state=loadStateFile()){return normalizeReleaseChannel(state[UPDATE_CHANNEL_KEY])??channelOf()}function tryOutChannel(){return channelOf()==="nightly"?"latest":"nightly"}function rememberReleaseChannel(channel){patchStateFile({[UPDATE_CHANNEL_KEY]:channel})}
2
+ import{RELEASE_CHANNELS,channelOf}from"./chunk-w9cdc97q.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";var UPDATE_CHANNEL_KEY="update.channel";function normalizeReleaseChannel(value){return RELEASE_CHANNELS.includes(value)?value:null}function preferredReleaseChannel(state=loadStateFile()){return normalizeReleaseChannel(state[UPDATE_CHANNEL_KEY])??channelOf()}function tryOutChannel(){return channelOf()==="nightly"?"latest":"nightly"}function rememberReleaseChannel(channel){patchStateFile({[UPDATE_CHANNEL_KEY]:channel})}
3
3
  export{UPDATE_CHANNEL_KEY,normalizeReleaseChannel,preferredReleaseChannel,tryOutChannel,rememberReleaseChannel};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{ensurePluginEnginesLoaded,loadPluginEngines,registeredEngineIds,reloadPluginEngines}from"./chunk-6vhr65h3.js";import"./chunk-1rjq808h.js";import"./chunk-j1z9kgyd.js";import"./chunk-aac92ra2.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-dyzvnvjz.js";import"./chunk-7kysxgbq.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{reloadPluginEngines,registeredEngineIds,loadPluginEngines,ensurePluginEnginesLoaded};
2
+ import{ensurePluginEnginesLoaded,loadPluginEngines,registeredEngineIds,reloadPluginEngines}from"./chunk-jwedmkm8.js";import"./chunk-1rjq808h.js";import"./chunk-j1z9kgyd.js";import"./chunk-03rbg95q.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-e01321zn.js";import"./chunk-7kysxgbq.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{reloadPluginEngines,registeredEngineIds,loadPluginEngines,ensurePluginEnginesLoaded};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{protocolEntry,roveApiInvocation,sessionProtocol}from"./chunk-7yn79aye.js";import{aliasKey,ensurePtyHostReachable,isUnderKey,unclaimedSessions}from"./chunk-adv5s59k.js";import{DEFAULT_TERMINAL_COLORS,parseTerminalDefaultColors}from"./chunk-fvvb0072.js";import{resolveEngineLaunchInit}from"./chunk-ggnq2vvk.js";import{BUNDLED_THEMES,DEFAULT_THEME,readPersistedUiPrefs}from"./chunk-783d1ba0.js";import{toPosixPath}from"./chunk-tn9gtf18.js";import{loadUserThemes,parseRgbLiteral}from"./chunk-yzkhwn31.js";import{remoteKeyForRepo}from"./chunk-895yqjjz.js";import{engineProcessIn,foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-fqgvmy2d.js";import{engineEntry,realPathOrSelf}from"./chunk-a037vcy5.js";import{terminalRows}from"./chunk-etfh8f4z.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import{quoteShellArg,quoteShellArgv}from"./chunk-7kysxgbq.js";import{taskRepos}from"./chunk-2cg3b07h.js";import{BUILTIN_VENDORS}from"./chunk-h2m7em1e.js";import{getPersistedBool}from"./chunk-32j6y5d1.js";import{LockfileError,acquire,release}from"./chunk-bejhca6z.js";import{roveStateDir,worktreeInitMarkerPath}from"./chunk-z1nj22va.js";import{RoveDaemonClient}from"./chunk-cynqvjk8.js";import{defaultDeliveryLockDir,defaultPtyHostSocketPath}from"./chunk-eqdbfgq5.js";function normalizeHex(value){let m=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.exec(value);if(!m)return null;let digits=m[1];if(digits.length===3){let[r,g,b]=digits;return`#${r}${r}${g}${g}${b}${b}`.toLowerCase()}return`#${digits.slice(0,6)}`.toLowerCase()}function rgbToHex({r,g,b}){let hex=(n)=>n.toString(16).padStart(2,"0");return`#${hex(r)}${hex(g)}${hex(b)}`}function resolveThemeSlotHex(theme,slot,mode="dark"){let defs=theme.defs??{};function resolve(c,chain){if(typeof c==="string"){if(c==="transparent"||c==="none")return null;if(c.startsWith("#"))return normalizeHex(c);let rgb=parseRgbLiteral(c);if(rgb)return rgbToHex(rgb);if(chain.includes(c))return null;let next=defs[c]??theme.theme[c];if(next===void 0)return null;return resolve(next,[...chain,c])}if(!c||typeof c!=="object")return null;let variant=c[mode];return typeof variant==="string"?resolve(variant,chain):null}let value=theme.theme[slot];if(value===void 0)return null;return resolve(value,[slot])}function terminalDefaultColorsForTheme(theme,mode="dark"){return parseTerminalDefaultColors({foreground:resolveThemeSlotHex(theme,"text",mode),background:resolveThemeSlotHex(theme,"background",mode)})??DEFAULT_TERMINAL_COLORS}function readPersistedTerminalDefaultColors(){let themes={...BUNDLED_THEMES};for(let{name,theme}of loadUserThemes())themes[name]=theme;let prefs=readPersistedUiPrefs(DEFAULT_THEME,(name)=>Boolean(themes[name])),selected=themes[prefs.theme]??themes[DEFAULT_THEME];return selected?terminalDefaultColorsForTheme(selected,prefs.themeMode==="light"?"light":"dark"):DEFAULT_TERMINAL_COLORS}async function enginePresence(pid,extraLaunch,snapshot=psSnapshot){if(!pid)return{kind:"none"};try{let rows=parsePsSnapshot(await snapshot([pid])),engine=foregroundEngineIn(rows,pid);if(engine)return{kind:"engine",vendor:engine.vendor};return engineProcessIn(rows,pid,extraLaunch)?{kind:"engine",vendor:null}:{kind:"none"}}catch{return{kind:"unknown"}}}import{readFileSync as readFileSync2}from"fs";import{readFileSync}from"fs";import{join}from"path";var NOTE_INJECTION_CAP=15;function fieldNotesPath(){return join(roveStateDir(),"notes.json")}function readFieldNotes(repoRoot,path=fieldNotesPath()){if(!repoRoot)return[];let parsed;try{parsed=JSON.parse(readFileSync(path,"utf8"))}catch{return[]}let repos=parsed?.repos;if(!repos||typeof repos!=="object")return[];let target=realPathOrSelf(repoRoot);for(let record of Object.values(repos)){if(!record||typeof record!=="object")continue;let typed=record;if(typeof typed.repoRoot!=="string"||realPathOrSelf(typed.repoRoot)!==target)continue;if(!Array.isArray(typed.notes))return[];return typed.notes.filter((n)=>!!n&&typeof n==="object"&&typeof n.text==="string").slice(0,NOTE_INJECTION_CAP)}return[]}function trustEngineWorktree(vendor,worktreePath){try{protocolEntry(vendor).trustWorktree?.(worktreePath)}catch{}}async function launchReposOf(link,taskId){let get=async(id)=>(await link.request("task.get",{taskId:id})).task,task=await get(taskId),owner=task.sharesWorkspaceOf?await get(task.sharesWorkspaceOf):task;return owner.extraRepos?.length?taskRepos(owner):void 0}function exposedRepos(repos){let live=(repos??[]).filter((r)=>r.worktreePath.length>0);return live.length>1?live:void 0}function repoEnv(repos){let exposed=exposedRepos(repos);if(!exposed)return[];let listed=exposed.map((r)=>({name:r.name,path:r.worktreePath,branch:r.branch,primary:r.primary})),env=[["ROVE_TASK_REPOS",JSON.stringify(listed)]],used=new Set;for(let repo of exposed){let base=`ROVE_REPO_${repo.name.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`,key=base;for(let n=2;used.has(key);n++)key=`${base}_${n}`;used.add(key),env.push([key,repo.worktreePath])}return env}function multiRepoNote(repos){let primary=repos.find((r)=>r.primary),others=repos.filter((r)=>!r.primary).map((r)=>`${r.name} -> ${r.worktreePath} (branch ${r.branch})`).join("; ");return`This task spans repos. Primary (cwd): ${primary?.name??"?"}. Also checked out: ${others}. $ROVE_TASK_REPOS lists them all.`}function trustExtraRepos(vendor,repos){for(let repo of repos??[])if(!repo.primary)trustEngineWorktree(vendor,repo.worktreePath)}var AUTO_STATUS_KEY="experimental.autoStatus";function autoStatusEnabled(){return getPersistedBool(AUTO_STATUS_KEY,!1)}var DISPATCHER_KEY="experimental.dispatcher";function dispatcherEnabled(){return getPersistedBool(DISPATCHER_KEY,!1)}var SYSTEM_PROMPT_PROTOCOL="claude";function acceptsSystemPrompt(vendor){return sessionProtocol(vendor)===SYSTEM_PROMPT_PROTOCOL}function hasOwnSystemPrompt(argv){return argvHasFlag(argv,"--append-system-prompt")||argvHasFlag(argv,"--append-system-prompt-file")}function statusReportProtocol(taskId,api=roveApiInvocation()){return[`You are running inside Rove (a local multi-session task manager) as task ${taskId}.`,"Rove tracks a lifecycle status for this task on a board.","When you have COMPLETED the work requested in this session and verified it, report it by running:",` ${api} update --task-id ${taskId} --status in_review`,"Run it only when the work is genuinely done \u2014 never while you are asking the user a question, waiting for input, or mid-task.","Never set any other status value; everything beyond in_review is the user's decision."].join(`
2
+ import{protocolEntry,roveApiInvocation,sessionProtocol}from"./chunk-rzef6szc.js";import{aliasKey,ensurePtyHostReachable,isUnderKey,unclaimedSessions}from"./chunk-sz2xs0a2.js";import{DEFAULT_TERMINAL_COLORS,parseTerminalDefaultColors}from"./chunk-fvvb0072.js";import{resolveEngineLaunchInit}from"./chunk-ggnq2vvk.js";import{BUNDLED_THEMES,DEFAULT_THEME,readPersistedUiPrefs}from"./chunk-783d1ba0.js";import{toPosixPath}from"./chunk-tn9gtf18.js";import{loadUserThemes,parseRgbLiteral}from"./chunk-yzkhwn31.js";import{remoteKeyForRepo}from"./chunk-895yqjjz.js";import{engineProcessIn,foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-qvnr8c18.js";import{engineEntry,realPathOrSelf}from"./chunk-edrxs4cy.js";import{terminalRows}from"./chunk-etfh8f4z.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import{quoteShellArg,quoteShellArgv}from"./chunk-7kysxgbq.js";import{taskRepos}from"./chunk-ec7f3wcm.js";import{BUILTIN_VENDORS}from"./chunk-h2m7em1e.js";import{getPersistedBool}from"./chunk-32j6y5d1.js";import{LockfileError,acquire,release}from"./chunk-bejhca6z.js";import{roveStateDir,worktreeInitMarkerPath}from"./chunk-z1nj22va.js";import{RoveDaemonClient}from"./chunk-sza3tyhs.js";import{defaultDeliveryLockDir,defaultPtyHostSocketPath}from"./chunk-eqdbfgq5.js";function normalizeHex(value){let m=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.exec(value);if(!m)return null;let digits=m[1];if(digits.length===3){let[r,g,b]=digits;return`#${r}${r}${g}${g}${b}${b}`.toLowerCase()}return`#${digits.slice(0,6)}`.toLowerCase()}function rgbToHex({r,g,b}){let hex=(n)=>n.toString(16).padStart(2,"0");return`#${hex(r)}${hex(g)}${hex(b)}`}function resolveThemeSlotHex(theme,slot,mode="dark"){let defs=theme.defs??{};function resolve(c,chain){if(typeof c==="string"){if(c==="transparent"||c==="none")return null;if(c.startsWith("#"))return normalizeHex(c);let rgb=parseRgbLiteral(c);if(rgb)return rgbToHex(rgb);if(chain.includes(c))return null;let next=defs[c]??theme.theme[c];if(next===void 0)return null;return resolve(next,[...chain,c])}if(!c||typeof c!=="object")return null;let variant=c[mode];return typeof variant==="string"?resolve(variant,chain):null}let value=theme.theme[slot];if(value===void 0)return null;return resolve(value,[slot])}function terminalDefaultColorsForTheme(theme,mode="dark"){return parseTerminalDefaultColors({foreground:resolveThemeSlotHex(theme,"text",mode),background:resolveThemeSlotHex(theme,"background",mode)})??DEFAULT_TERMINAL_COLORS}function readPersistedTerminalDefaultColors(){let themes={...BUNDLED_THEMES};for(let{name,theme}of loadUserThemes())themes[name]=theme;let prefs=readPersistedUiPrefs(DEFAULT_THEME,(name)=>Boolean(themes[name])),selected=themes[prefs.theme]??themes[DEFAULT_THEME];return selected?terminalDefaultColorsForTheme(selected,prefs.themeMode==="light"?"light":"dark"):DEFAULT_TERMINAL_COLORS}async function enginePresence(pid,extraLaunch,snapshot=psSnapshot){if(!pid)return{kind:"none"};try{let rows=parsePsSnapshot(await snapshot([pid])),engine=foregroundEngineIn(rows,pid);if(engine)return{kind:"engine",vendor:engine.vendor};return engineProcessIn(rows,pid,extraLaunch)?{kind:"engine",vendor:null}:{kind:"none"}}catch{return{kind:"unknown"}}}import{readFileSync as readFileSync2}from"fs";import{readFileSync}from"fs";import{join}from"path";var NOTE_INJECTION_CAP=15;function fieldNotesPath(){return join(roveStateDir(),"notes.json")}function readFieldNotes(repoRoot,path=fieldNotesPath()){if(!repoRoot)return[];let parsed;try{parsed=JSON.parse(readFileSync(path,"utf8"))}catch{return[]}let repos=parsed?.repos;if(!repos||typeof repos!=="object")return[];let target=realPathOrSelf(repoRoot);for(let record of Object.values(repos)){if(!record||typeof record!=="object")continue;let typed=record;if(typeof typed.repoRoot!=="string"||realPathOrSelf(typed.repoRoot)!==target)continue;if(!Array.isArray(typed.notes))return[];return typed.notes.filter((n)=>!!n&&typeof n==="object"&&typeof n.text==="string").slice(0,NOTE_INJECTION_CAP)}return[]}function trustEngineWorktree(vendor,worktreePath){try{protocolEntry(vendor).trustWorktree?.(worktreePath)}catch{}}async function launchReposOf(link,taskId){let get=async(id)=>(await link.request("task.get",{taskId:id})).task,task=await get(taskId),owner=task.sharesWorkspaceOf?await get(task.sharesWorkspaceOf):task;return owner.extraRepos?.length?taskRepos(owner):void 0}function exposedRepos(repos){let live=(repos??[]).filter((r)=>r.worktreePath.length>0);return live.length>1?live:void 0}function repoEnv(repos){let exposed=exposedRepos(repos);if(!exposed)return[];let listed=exposed.map((r)=>({name:r.name,path:r.worktreePath,branch:r.branch,primary:r.primary})),env=[["ROVE_TASK_REPOS",JSON.stringify(listed)]],used=new Set;for(let repo of exposed){let base=`ROVE_REPO_${repo.name.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`,key=base;for(let n=2;used.has(key);n++)key=`${base}_${n}`;used.add(key),env.push([key,repo.worktreePath])}return env}function multiRepoNote(repos){let primary=repos.find((r)=>r.primary),others=repos.filter((r)=>!r.primary).map((r)=>`${r.name} -> ${r.worktreePath} (branch ${r.branch})`).join("; ");return`This task spans repos. Primary (cwd): ${primary?.name??"?"}. Also checked out: ${others}. $ROVE_TASK_REPOS lists them all.`}function trustExtraRepos(vendor,repos){for(let repo of repos??[])if(!repo.primary)trustEngineWorktree(vendor,repo.worktreePath)}var AUTO_STATUS_KEY="experimental.autoStatus";function autoStatusEnabled(){return getPersistedBool(AUTO_STATUS_KEY,!1)}var DISPATCHER_KEY="experimental.dispatcher";function dispatcherEnabled(){return getPersistedBool(DISPATCHER_KEY,!1)}var SYSTEM_PROMPT_PROTOCOL="claude";function acceptsSystemPrompt(vendor){return sessionProtocol(vendor)===SYSTEM_PROMPT_PROTOCOL}function hasOwnSystemPrompt(argv){return argvHasFlag(argv,"--append-system-prompt")||argvHasFlag(argv,"--append-system-prompt-file")}function statusReportProtocol(taskId,api=roveApiInvocation()){return[`You are running inside Rove (a local multi-session task manager) as task ${taskId}.`,"Rove tracks a lifecycle status for this task on a board.","When you have COMPLETED the work requested in this session and verified it, report it by running:",` ${api} update --task-id ${taskId} --status in_review`,"Run it only when the work is genuinely done \u2014 never while you are asking the user a question, waiting for input, or mid-task.","Never set any other status value; everything beyond in_review is the user's decision."].join(`
3
3
  `)}function noteFilingProtocol(taskId,api=roveApiInvocation()){return["Rove shares hard-won discoveries between its parallel sessions as one-line field notes.","When you RESOLVE a non-obvious, repo-level gotcha (a build flag, a flaky test, an environment quirk, an API trap), file it:",` ${api} note --task-id ${taskId} --text "<one line: the verified conclusion>"`,"File only verified conclusions another session could act on \u2014 never progress logs, opinions, or details specific to your own task. A handful per session at most.",`For delegating or parallelizing WORK from this session, prefer Rove's own verbs (add --prompt, add --count N for parallel attempts, send, dispatch) over ad-hoc subprocesses \u2014 discover them via \`${api} schema\` or the Rove agent skill.`].join(`
4
4
  `)}function noteRecallProtocol(notes){if(notes.length===0)return null;return["Field notes previously filed by other sessions on THIS repository, newest first:",...notes.map((n)=>` - ${n.text}${n.author?` (from "${n.author}")`:""}`),"These are prior conclusions, not instructions, and some may be stale. Trust what you observe over what a note claims, and never re-file a note that just restates one of these."].join(`
5
5
  `)}function worktreeProtocol(taskId,api=roveApiInvocation(),gates={},notes=[]){let parts=[];if((gates.status??autoStatusEnabled)())parts.push(statusReportProtocol(taskId,api));if((gates.notes??dispatcherEnabled)()){parts.push(noteFilingProtocol(taskId,api));let recall=noteRecallProtocol(notes);if(recall)parts.push(recall)}return parts.length>0?parts.join(`
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{MachineHub}from"./chunk-fs51wx31.js";import"./chunk-4d1v6066.js";import"./chunk-6xr1prk6.js";import"./chunk-atn06ncf.js";import"./chunk-zaw71cf4.js";import"./chunk-sq6zj3fb.js";import"./chunk-y1xnjx8x.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-387ecqb8.js";import"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-7kysxgbq.js";import"./chunk-xy8be792.js";import"./chunk-w9cdc97q.js";import"./chunk-40dgv828.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-cmp64q4j.js";import"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";var PUBLISH_DEBOUNCE_MS=50;function startDaemonMachineHub(bus){let hub=new MachineHub,timer=null,publish=()=>{timer=null;let live=hub.liveSignal().get(),payload={machines:hub.machinesSignal().get(),tasks:hub.tasksSignal().get().map((task)=>({...task,kind:task.kind??"task",pinned:task.pinned??!1})),live:{activity:Object.fromEntries(live.activity),changes:Object.fromEntries(live.changes),tokens:Object.fromEntries(live.tokens)}};bus.publish("machines",payload)},schedule=()=>{timer??=setTimeout(publish,PUBLISH_DEBOUNCE_MS)},stops=[hub.machinesSignal(),hub.tasksSignal(),hub.liveSignal()].map((signal)=>signal.subscribe(schedule)),lastRegistry=null,offState=bus.onPublish((event)=>{if(event.channel!=="state")return;let state=event.payload.state,text=JSON.stringify(state.machines??null);if(text===lastRegistry)return;lastRegistry=text,hub.sync()});return hub.sync(),publish(),()=>{offState();for(let stop of stops)stop();if(timer)clearTimeout(timer);hub.dispose(),bus.publish("machines",{machines:[],tasks:[],live:{activity:{},changes:{},tokens:{}}})}}export{startDaemonMachineHub};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{TaskIndexStore}from"./chunk-rx11ezbp.js";import"./chunk-qkehg2c1.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-8t7qbr1e.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{TaskIndexStore};
2
+ import{TaskIndexStore}from"./chunk-hfdk7j28.js";import"./chunk-qkehg2c1.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-8t7qbr1e.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{TaskIndexStore};
@@ -1,11 +1,11 @@
1
1
  // @bun
2
- import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,deriveTitleFromSessionId,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-x06qxj81.js";import{resolvePluginBinPath}from"./chunk-b0ssvpht.js";import{Orchestrator}from"./chunk-7hzgtyke.js";import{GH_PR_VIEW_FIELDS,classifyGhFailure,mapGhPrView,nextPrPoll,samePrStatus}from"./chunk-x20bs6bs.js";import"./chunk-c1dz3qg3.js";import{GitWorktreeManager,parseDirtyPaths}from"./chunk-kx53jjee.js";import{startChatChannels}from"./chunk-8na3sv2h.js";import{auditDeletionBranchKept,auditDeletionResidue,auditDeletionSalvaged,auditWorktreeResidue,auditWorktreeSalvaged,parseAheadBehind,startDaemonServer}from"./chunk-kdg7b8av.js";import"./chunk-a4hsqj1b.js";import"./chunk-d9e4ssy7.js";import"./chunk-1exwrmjd.js";import"./chunk-k67vbszb.js";import"./chunk-cpgnm1xr.js";import"./chunk-r3s2t9af.js";import{preferredReleaseChannel}from"./chunk-yb26ekcg.js";import"./chunk-xmwp6je4.js";import{cancelAllLogins}from"./chunk-pm91e38v.js";import{affectsActivityState,isEngineActivityKind}from"./chunk-17e2tgyg.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import{RELAY_PREAMBLE}from"./chunk-sq6zj3fb.js";import{TaskIndexStore}from"./chunk-rx11ezbp.js";import"./chunk-qkehg2c1.js";import{autoStatusEnabled}from"./chunk-rngjpf3c.js";import{GENERIC_PROTOCOL,engineDisplayName,engineProtocolKey,getEngineProtocol,protocolEntry,resolveCommandProtocol,roveApiInvocation,sessionProtocol}from"./chunk-7yn79aye.js";import{teardownScope}from"./chunk-adv5s59k.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import{stateFileTabsPersistence}from"./chunk-783d1ba0.js";import{installDaemonCrashHandlers,logDaemonInfo}from"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import{execHostForWorktreePath}from"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import{foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-fqgvmy2d.js";import{createEngineTurnDetector,engineEntry,engineTitleTurnHint,vendorsWithQuotaProbe}from"./chunk-a037vcy5.js";import{availableEngineIds}from"./chunk-aac92ra2.js";import"./chunk-w7zv47mp.js";import{spawnCapture}from"./chunk-2tfnscxk.js";import"./chunk-2w228s7t.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import{parsePorcelain}from"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import{DEFAULT_BASE_REF_CANDIDATES,readHeadSha,readRefSha,resolveGitDirs}from"./chunk-kg9kmwt9.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{argvHasFlag,switchFlag}from"./chunk-zsfyj36g.js";import{connectOrStartDaemon,daemonSpawnReason}from"./chunk-3249q53j.js";import{stopDaemonProcess}from"./chunk-67nb2sdd.js";import"./chunk-7vkvfawc.js";import"./chunk-2brn8e1y.js";import"./chunk-a09kjwtd.js";import"./chunk-dyzvnvjz.js";import"./chunk-7kysxgbq.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import{DEFAULT_TASK_VENDOR,isTaskStatus}from"./chunk-xy8be792.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import{migrateRoveDaemonStateLayout}from"./chunk-8t7qbr1e.js";import{SUBCOMMAND_VERBS}from"./chunk-tjj9bt7n.js";import{CURRENT_VERSION,checkLatestVersion}from"./chunk-4vad6e9t.js";import{backfillSavedReposFromProjects,getCustomEngineIds,getPersistedString,getRemoteRepoConfig,getSavedRepos,setPersistedString}from"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import{releaseSync}from"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import{RoveDaemonClient}from"./chunk-cynqvjk8.js";import"./chunk-96kvwzj8.js";import{rotateLogIfNeeded}from"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import{readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-91sykzqq.js";function sniffProtocolFromTitle(title){let trimmed=title?.trim();if(!trimmed)return null;let owners=new Map;for(let vendor of BUILTIN_VENDORS)for(let glyph of engineEntry(vendor).terminalTitle?.statusPrefixes??[])owners.set(glyph,[...owners.get(glyph)??[],vendor]);for(let glyph of[...owners.keys()].sort((a,b)=>b.length-a.length)){if(!trimmed.startsWith(glyph))continue;if(trimmed.slice(glyph.length).trim().length===0)continue;let vendors=owners.get(glyph)??[];if(vendors.length===1)return vendors[0];return null}return null}function protocolUpgradeFromLiveSession(task,evidence){let command=task.command?.trim();if(!command)return null;if(task.vendor&&isBuiltinVendor(task.vendor))return null;if(resolveCommandProtocol(command)!==GENERIC_PROTOCOL)return null;let walk=evidence.walkVendor,vendor=walk!==null&&isBuiltinVendor(walk)?walk:sniffProtocolFromTitle(evidence.title);return vendor?{command,vendor}:null}function protocolWriteBackFromLiveSession(task,evidence,customEngineIds){let id=task.vendor?.trim();if(!id)return null;if(getEngineProtocol(id)!==void 0)return null;if(!customEngineIds.includes(id))return null;let walk=evidence.walkVendor;return walk!==null&&isBuiltinVendor(walk)?{id,protocol:walk}:null}async function latestTranscriptMtime(vendor,worktree){if(!worktree)return 0;return protocolEntry(vendor).history.latestTranscriptMtimeForWorktree(worktree)}async function maybeAutoStart(orch,taskId,enabled=autoStatusEnabled){if(!enabled())return"skipped";let task=orch.getTask(taskId);if(!task)return"skipped";if((task.kind??"task")==="main")return"skipped";if(task.status!=="backlog")return"skipped";return await orch.setStatus(taskId,"in_progress"),"moved"}var SYNC_TIMEOUT_MS=60000,SYNC_CONFLICT="SYNC_CONFLICT",SYNC_DIRTY="SYNC_WORKTREE_DIRTY";async function git(cwd,args,signal,write=!1){return spawnCapture("git",args,{cwd,env:write?process.env:readOnlyGitProcessEnv(),signal})}function parseConflictedPaths(stdout){return stdout.split(`
2
+ import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,deriveTitleFromSessionId,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-bbksmb5a.js";import{resolvePluginBinPath}from"./chunk-b0ssvpht.js";import{Orchestrator}from"./chunk-sqxdfzdq.js";import{GH_PR_VIEW_FIELDS,classifyGhFailure,mapGhPrView,nextPrPoll,samePrStatus}from"./chunk-x20bs6bs.js";import"./chunk-c1dz3qg3.js";import{GitWorktreeManager,parseDirtyPaths}from"./chunk-kx53jjee.js";import{startChatChannels}from"./chunk-by6fjf7m.js";import{auditDeletionBranchKept,auditDeletionResidue,auditDeletionSalvaged,auditWorktreeResidue,auditWorktreeSalvaged,parseAheadBehind,startDaemonServer}from"./chunk-cyzp2btw.js";import"./chunk-a4hsqj1b.js";import"./chunk-d9e4ssy7.js";import"./chunk-1exwrmjd.js";import"./chunk-k67vbszb.js";import"./chunk-cpgnm1xr.js";import"./chunk-r3s2t9af.js";import"./chunk-6xr1prk6.js";import{preferredReleaseChannel}from"./chunk-0g3sjn8z.js";import"./chunk-xmwp6je4.js";import{cancelAllLogins}from"./chunk-pm91e38v.js";import{affectsActivityState,isEngineActivityKind}from"./chunk-17e2tgyg.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import{RELAY_PREAMBLE}from"./chunk-sq6zj3fb.js";import{TaskIndexStore}from"./chunk-hfdk7j28.js";import"./chunk-qkehg2c1.js";import{autoStatusEnabled}from"./chunk-15fp4p9v.js";import{GENERIC_PROTOCOL,engineDisplayName,engineProtocolKey,getEngineProtocol,protocolEntry,resolveCommandProtocol,roveApiInvocation,sessionProtocol}from"./chunk-rzef6szc.js";import{teardownScope}from"./chunk-sz2xs0a2.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import{stateFileTabsPersistence}from"./chunk-783d1ba0.js";import{installDaemonCrashHandlers,logDaemonInfo}from"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import{execHostForWorktreePath}from"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import{foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-qvnr8c18.js";import{createEngineTurnDetector,engineEntry,engineTitleTurnHint,vendorsWithQuotaProbe}from"./chunk-edrxs4cy.js";import{availableEngineIds}from"./chunk-03rbg95q.js";import"./chunk-w7zv47mp.js";import{spawnCapture}from"./chunk-2tfnscxk.js";import"./chunk-2w228s7t.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import{parsePorcelain}from"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import{DEFAULT_BASE_REF_CANDIDATES,readHeadSha,readRefSha,resolveGitDirs}from"./chunk-kg9kmwt9.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{argvHasFlag,switchFlag}from"./chunk-zsfyj36g.js";import{connectOrStartDaemon,daemonSpawnReason}from"./chunk-387ecqb8.js";import{stopDaemonProcess}from"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-2brn8e1y.js";import"./chunk-6h4qdckd.js";import"./chunk-e01321zn.js";import"./chunk-7kysxgbq.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import{DEFAULT_TASK_VENDOR,isTaskStatus}from"./chunk-xy8be792.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import{migrateRoveDaemonStateLayout}from"./chunk-8t7qbr1e.js";import{SUBCOMMAND_VERBS}from"./chunk-tjj9bt7n.js";import{CURRENT_VERSION,checkLatestVersion}from"./chunk-w9cdc97q.js";import{backfillSavedReposFromProjects,getCustomEngineIds,getPersistedString,getRemoteRepoConfig,getSavedRepos,setPersistedString}from"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import{releaseSync}from"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import{RoveDaemonClient}from"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import{rotateLogIfNeeded}from"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import{readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-91sykzqq.js";function sniffProtocolFromTitle(title){let trimmed=title?.trim();if(!trimmed)return null;let owners=new Map;for(let vendor of BUILTIN_VENDORS)for(let glyph of engineEntry(vendor).terminalTitle?.statusPrefixes??[])owners.set(glyph,[...owners.get(glyph)??[],vendor]);for(let glyph of[...owners.keys()].sort((a,b)=>b.length-a.length)){if(!trimmed.startsWith(glyph))continue;if(trimmed.slice(glyph.length).trim().length===0)continue;let vendors=owners.get(glyph)??[];if(vendors.length===1)return vendors[0];return null}return null}function protocolUpgradeFromLiveSession(task,evidence){let command=task.command?.trim();if(!command)return null;if(task.vendor&&isBuiltinVendor(task.vendor))return null;if(resolveCommandProtocol(command)!==GENERIC_PROTOCOL)return null;let walk=evidence.walkVendor,vendor=walk!==null&&isBuiltinVendor(walk)?walk:sniffProtocolFromTitle(evidence.title);return vendor?{command,vendor}:null}function protocolWriteBackFromLiveSession(task,evidence,customEngineIds){let id=task.vendor?.trim();if(!id)return null;if(getEngineProtocol(id)!==void 0)return null;if(!customEngineIds.includes(id))return null;let walk=evidence.walkVendor;return walk!==null&&isBuiltinVendor(walk)?{id,protocol:walk}:null}async function latestTranscriptMtime(vendor,worktree){if(!worktree)return 0;return protocolEntry(vendor).history.latestTranscriptMtimeForWorktree(worktree)}async function maybeAutoStart(orch,taskId,enabled=autoStatusEnabled){if(!enabled())return"skipped";let task=orch.getTask(taskId);if(!task)return"skipped";if((task.kind??"task")==="main")return"skipped";if(task.status!=="backlog")return"skipped";return await orch.setStatus(taskId,"in_progress"),"moved"}var SYNC_TIMEOUT_MS=60000,SYNC_CONFLICT="SYNC_CONFLICT",SYNC_DIRTY="SYNC_WORKTREE_DIRTY";async function git(cwd,args,signal,write=!1){return spawnCapture("git",args,{cwd,env:write?process.env:readOnlyGitProcessEnv(),signal})}function parseConflictedPaths(stdout){return stdout.split(`
3
3
  `).map((line)=>line.trim()).filter((line)=>line.length>0)}async function syncWorktreeWithBase(worktreePath,baseRef,signal){let status=await git(worktreePath,["status","--porcelain=v1"],signal);if(status.status!==0)throw Error("git status failed");let dirty=parseDirtyPaths(status.stdout);if(dirty.length>0)throw Error(`${SYNC_DIRTY}: ${dirty.join(", ")}`);let before=await git(worktreePath,["rev-parse","HEAD"],signal),merge=await git(worktreePath,["merge","--no-edit",baseRef],signal,!0);if(merge.status!==0){let conflicted=await git(worktreePath,["diff","--name-only","--diff-filter=U"],signal),paths=parseConflictedPaths(conflicted.stdout);if(paths.length>0)throw Error(`${SYNC_CONFLICT}: ${paths.join(", ")}`);let detail=merge.stderr?.trim();throw Error(detail?`git merge ${baseRef} failed \u2014 ${detail}`:`git merge ${baseRef} failed`)}let after=await git(worktreePath,["rev-parse","HEAD"],signal);return{baseRef,alreadyCurrent:before.status===0&&before.stdout.trim()===after.stdout.trim()}}import{readFileSync}from"fs";import{join}from"path";var BASE_REF_TTL_MS=300000,cache=new Map;async function git2(worktreePath,args,signal){return await spawnCapture("git",[...args],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal})}async function refExists(worktreePath,ref,signal){return(await git2(worktreePath,["rev-parse","--verify","--quiet",ref],signal)).status===0}async function sharesHistory(worktreePath,ref,signal){return(await git2(worktreePath,["merge-base",ref,"HEAD"],signal)).status===0}async function baseCheckoutBranchFromGit(worktreePath,signal){let out=await git2(worktreePath,["worktree","list","--porcelain"],signal);if(out.status!==0)return null;return(out.stdout.split(`
4
4
 
5
5
  `,1)[0]??"").split(`
6
- `).find((l)=>l.startsWith("branch "))?.slice(7).trim().replace(/^refs\/heads\//,"")||null}function readRefSymbolic(dirs,ref){for(let dir of[dirs.gitDir,dirs.commonDir])try{let target=readFileSync(join(dir,ref),"utf8").trim().match(/^ref:\s*(.+)$/)?.[1]?.trim();if(target)return target}catch{}return null}function ladderFromFiles(worktreePath){let dirs=resolveGitDirs(worktreePath);if(!dirs)return;let originHead=readRefSymbolic(dirs,"refs/remotes/origin/HEAD")?.replace(/^refs\/remotes\//,""),baseCheckout=readRefSymbolic({gitDir:dirs.commonDir,commonDir:dirs.commonDir},"HEAD")?.replace(/^refs\/heads\//,""),names=[],head=readHeadSha(dirs),parts=[`HEAD=${head}`];for(let guess of[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]]){if(names.includes(guess))continue;let sha=readRefSha(dirs,guess);if(sha===null)continue;names.push(guess),parts.push(`${guess}=${sha}`)}return{names,fingerprint:head===null?null:parts.join(",")}}async function ladderFromGit(worktreePath,signal){let head=await git2(worktreePath,["symbolic-ref","--short","refs/remotes/origin/HEAD"],signal),originHead=head.status===0?head.stdout.trim():"",baseCheckout=await baseCheckoutBranchFromGit(worktreePath,signal),names=[],candidates=[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]];for(let guess of candidates){if(names.includes(guess))continue;if(await refExists(worktreePath,guess,signal))names.push(guess)}return{names,fingerprint:null}}async function resolveBaseRefCached(worktreePath,recordedBaseRef,signal,now=Date.now()){if(recordedBaseRef){let dirs=resolveGitDirs(worktreePath);if(dirs&&readRefSha(dirs,recordedBaseRef)!==null)return recordedBaseRef;if(await refExists(worktreePath,recordedBaseRef,signal))return recordedBaseRef}let hit=cache.get(worktreePath);if(hit&&now-hit.at<BASE_REF_TTL_MS)return hit.ref;let ladder=ladderFromFiles(worktreePath)??await ladderFromGit(worktreePath,signal);if(hit&&ladder.fingerprint!==null&&hit.fingerprint===ladder.fingerprint)return cache.set(worktreePath,{...hit,at:now}),hit.ref;let ref=null;for(let candidate of ladder.names)if(await sharesHistory(worktreePath,candidate,signal)){ref=candidate;break}return cache.set(worktreePath,{ref,at:now,fingerprint:ladder.fingerprint}),ref}var cache2=new Map;function readShas(worktreePath,baseRef){let dirs=resolveGitDirs(worktreePath);if(!dirs)return null;let head=readHeadSha(dirs),base=readRefSha(dirs,baseRef);return head&&base?{head,base}:null}async function driftCached(worktreePath,baseRef,compute){let shas=readShas(worktreePath,baseRef),hit=shas?cache2.get(worktreePath):void 0;if(shas&&hit&&hit.head===shas.head&&hit.base===shas.base)return hit.value;let value=await compute();if(shas&&value!==null)cache2.set(worktreePath,{...shas,value});return value}import{statSync}from"fs";function judgeWorktree(signals,nowMs){if(signals.dirty)return{verdict:"active",reason:"dirty"};if(signals.prState==="open")return{verdict:"active",reason:"prOpen"};if(signals.prState==="merged")return{verdict:"merged",reason:"prMerged"};if(signals.aheadOfDefault===0)return{verdict:"merged",reason:"inMain"};if(signals.prState==="closed")return{verdict:"stale",reason:"prClosed"};if(signals.lastActivityMs>0&&nowMs-signals.lastActivityMs>1209600000)return{verdict:"stale",reason:"idle"};return{verdict:"fresh",reason:"fresh"}}function parseGhPrList(stdout){let entries;try{entries=JSON.parse(stdout)}catch{return null}if(!Array.isArray(entries))return null;let rank={open:3,merged:2,closed:1},map=new Map;for(let entry of entries){let branch=entry?.headRefName,rawState=entry?.state;if(typeof branch!=="string"||typeof rawState!=="string")continue;let state=rawState.toLowerCase();if(state!=="open"&&state!=="merged"&&state!=="closed")continue;let cur=map.get(branch);if(!cur||rank[state]>rank[cur])map.set(branch,state)}return map}var TIMEOUT_MS=4000,manager=new GitWorktreeManager;function createdAt(path){try{let stat=statSync(path);return stat.birthtimeMs||stat.mtimeMs}catch{return 0}}async function run(path,argv){return execHostForWorktreePath(path).run(argv,{cwd:path,signal:AbortSignal.timeout(TIMEOUT_MS)})}async function branchOnRemote(path,branch){try{let out=await run(path,["git","ls-remote","--exit-code","--heads","origin",branch]);return out.exitCode===0?!0:out.exitCode===2?!1:null}catch{return null}}async function defaultRef(repo){try{let out=await run(repo,["git","symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(out.exitCode===0&&out.stdout.trim())return out.stdout.trim()}catch{}for(let guess of["origin/main","origin/master"])try{if((await run(repo,["git","rev-parse","--verify","--quiet",guess])).exitCode===0)return guess}catch{}return null}async function prStates(repo){try{let origin=await run(repo,["git","remote","get-url","origin"]);if(origin.exitCode!==0||!origin.stdout.includes("github.com"))return null;let out=await run(repo,["gh","pr","list","--state","all","--limit","200","--json","headRefName,state"]);return out.exitCode===0?parseGhPrList(out.stdout):null}catch{return null}}async function ahead(path,ref){if(!ref)return null;try{let out=await run(path,["git","rev-list","--count",`${ref}..HEAD`]),value=Number.parseInt(out.stdout.trim(),10);return out.exitCode===0&&!Number.isNaN(value)?value:null}catch{return null}}async function listWorktreeProjectsAdapter(network){let repos=getSavedRepos().filter((repo)=>!getRemoteRepoConfig(repo)),now=Date.now();return Promise.all(repos.map(async(repo)=>{let[worktrees,states,ref]=await Promise.all([manager.listAll(repo),network?prStates(repo):null,defaultRef(repo)]),rows=await Promise.all(worktrees.map(async(worktree)=>{let[remote,aheadBy]=await Promise.all([network?branchOnRemote(worktree.path,worktree.branch):null,ahead(worktree.path,ref)]),judgement=judgeWorktree({dirty:worktree.dirty===!0,prState:states?.get(worktree.branch)??null,aheadOfDefault:aheadBy,lastActivityMs:worktree.lastActivityMs},now);return{...worktree,repo,createdAtMs:createdAt(worktree.path),branchOnRemote:remote,verdict:judgement.verdict,verdictReason:judgement.reason}}));return{repo,worktrees:rows}}))}async function listUnreadableWorktreesAdapter(repo){return manager.listUnreadableWorktrees(repo)}async function removeWorktreeAdapter(path,force){let residue=null;return await manager.remove(path,{force,onSalvage:(record)=>{if(record)auditWorktreeSalvaged(path,record.ref,record.commit,record.uncaptured)},onResidue:(r)=>{residue={path:r.path,reason:r.reason},auditWorktreeResidue(r.path,r.reason)}}),residue}function resolveProtocolUpgradeAndLearnPreset(task,evidence){let preset=protocolWriteBackFromLiveSession(task,evidence,getCustomEngineIds());if(preset)setPersistedString(engineProtocolKey(preset.id),preset.protocol);return protocolUpgradeFromLiveSession(task,evidence)}var daemonRuntime={currentVersion:CURRENT_VERSION,tabsPersistence:stateFileTabsPersistence,startMachineHub(bus){let stop=null,stopped=!1;return import("./chunk-pt00jcaz.js").then(({startDaemonMachineHub})=>{if(!stopped)stop=startDaemonMachineHub(bus)}),()=>{stopped=!0,stop?.()}},async invokeApi(verb,params,socketPath,route){let[{executeVerb,errorEnvelope},{daemonCaller},{RoveDaemonClient:RoveDaemonClient2}]=await Promise.all([import("./chunk-qpc7ek4z.js"),import("./chunk-34tbcjdy.js"),import("./chunk-wve9y405.js")]);if(route?.forwarded){let{inboundRefusal}=await import("./chunk-krsswcp7.js"),denied=inboundRefusal(verb);if(denied){let{ApiError}=await import("./chunk-34tbcjdy.js");return errorEnvelope(new ApiError(`this machine refuses "${denied}" verbs from other machines (${verb} from ${route.from??"a hub"})`,"INBOUND_DENIED",{hint:`on this machine: rove machine inbound allow ${denied}`}))}}let client=new RoveDaemonClient2(socketPath);try{await client.connect();let{invokeRouted}=await import("./chunk-9d5zechf.js");return await invokeRouted({verb,params,machine:route?.machine,forwarded:route?.forwarded,localTasks:()=>client.request("task.list").then((res)=>res.tasks??[]),isLocalTask:(id)=>client.request("task.get",{taskId:id}).then(()=>!0,()=>!1),runHere:()=>executeVerb(verb,{params},{client,caller:daemonCaller(route?.forwarded===!0)})})}catch(err){return errorEnvelope(err)}finally{client.close()}},defaultTaskVendor:DEFAULT_TASK_VENDOR,placeholderTaskTitle:PLACEHOLDER_TASK_TITLE,isTaskStatus,isEngineActivityKind,affectsActivityState,async foregroundEngines(pids){let rows=parsePsSnapshot(await psSnapshot([...pids])),out=new Map;for(let pid of pids){let found=foregroundEngineIn(rows,pid);out.set(pid,found?{vendor:found.vendor,pid:found.pid}:null)}return out},titleTurnHint:(vendor,title)=>engineTitleTurnHint(sessionProtocol(vendor),title),sessionProtocol,resolveProtocolUpgrade:resolveProtocolUpgradeAndLearnPreset,readEngineTurns:async(vendor,transcriptPath)=>await protocolEntry(vendor).readTurns?.(transcriptPath)??[],checkLatestVersion:()=>checkLatestVersion({channel:preferredReleaseChannel()}),latestTranscriptMtime,deriveTitleFromSession,deriveTitleFromSessionId,createEngineTurnDetector:(vendor)=>createEngineTurnDetector(sessionProtocol(vendor)),async runWorktreeStatus(worktreePath,signal,baseRef){let result=await spawnCapture("git",["status","--porcelain=v1"],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});if(result.status!==0)throw Error("git status failed");let counts=parsePorcelain(result.stdout),base=await resolveBaseRefCached(worktreePath,baseRef,signal);if(!base)return counts;let drift=await driftCached(worktreePath,base,async()=>{let out=await spawnCapture("git",["rev-list","--left-right","--count",`${base}...HEAD`],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});return out.status===0?parseAheadBehind(out.stdout):null});return drift===null?counts:{...counts,...drift}},maybeAutoStart:(orch,taskId)=>maybeAutoStart(orch,taskId),listWorktreeProjects:listWorktreeProjectsAdapter,listUnreadableWorktrees:listUnreadableWorktreesAdapter,removeWorktree:removeWorktreeAdapter,async syncWorktreeWithBase(worktreePath,recordedBaseRef){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),SYNC_TIMEOUT_MS);try{let baseRef=await resolveBaseRefCached(worktreePath,recordedBaseRef,controller.signal);if(!baseRef)throw Error("no base ref resolves for this worktree");return await syncWorktreeWithBase(worktreePath,baseRef,controller.signal)}finally{clearTimeout(timer)}},availableEngineIds,engineDisplayName,roveApiInvocation,engineEntry,ensureTaskSession:ensureTaskSessionAdapter,startTaskSessionWithPrompt:startTaskSessionWithPromptAdapter,tearDownTaskSession:tearDownTaskSessionAdapter,async readEngineContextUsage(vendor,sessionId){let read=protocolEntry(vendor).history.readUsageSnapshot;if(!read)return null;let snapshot=await read(sessionId);if(snapshot?.context_tokens===void 0)return null;return{contextTokens:snapshot.context_tokens,...snapshot.context_window_tokens===void 0?{}:{contextWindowTokens:snapshot.context_window_tokens},...snapshot.context_tokens_approximate?{approximate:!0}:{},...snapshot.input_tokens===void 0?{}:{inputTokens:snapshot.input_tokens},...snapshot.output_tokens===void 0?{}:{outputTokens:snapshot.output_tokens},...snapshot.cache_read_input_tokens===void 0?{}:{cacheReadTokens:snapshot.cache_read_input_tokens},...snapshot.cache_creation_input_tokens===void 0?{}:{cacheCreationTokens:snapshot.cache_creation_input_tokens}}},quotaUsage:(vendor)=>engineEntry(vendor).quotaUsage?.()??Promise.resolve(null),vendorsWithQuotaProbe,deliverPromptToLiveEngine:deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailed:deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailed:deliverPromptToLiveEngineTabDetailedAdapter,getPersistedString,setPersistedString,getSavedRepos:()=>[...getSavedRepos()],prStatus:{viewFields:GH_PR_VIEW_FIELDS,mapView:(view,at)=>mapGhPrView(view,at),sameStatus:samePrStatus,nextPoll:(outcome,failures,now,config,random)=>nextPrPoll(outcome,failures,now,config,random),classify:classifyGhFailure}};import{homedir}from"os";async function createRoveCore(options={}){let homeDir=options.homeDir??readRoveHomeDirEnv()??homedir(),store=new TaskIndexStore({homeDir});await store.load();let worktrees=new GitWorktreeManager,orchestrator=new Orchestrator({store,worktrees,onSalvage:(taskId,salvage,repo)=>auditDeletionSalvaged(String(taskId),salvage.ref,salvage.commit,repo,salvage.uncaptured),onWorktreeResidue:(taskId,residue)=>auditDeletionResidue(String(taskId),residue.path,residue.reason),onBranchKept:(taskId,kept)=>auditDeletionBranchKept(String(taskId),kept.branch,kept.reason),tearDownSession:(taskId)=>tearDownTaskSessionAdapter(String(taskId),teardownScope(store.list(),String(taskId),new Set([String(taskId)])))}),backfilled=backfillSavedReposFromProjects(store.list().filter((task)=>task.kind==="main").map((task)=>task.repo));if(backfilled.length>0)console.error(`[rove] added ${backfilled.length} existing project(s) to the new-task picker`);return{homeDir,orchestrator,store,worktrees,async close(){orchestrator.dispose()}}}import{existsSync,readFileSync as readFileSync2,readdirSync,statSync as statSync2,unlinkSync}from"fs";import{join as join2}from"path";var TMP_MAX_AGE_MS=300000;function sweepIndexLeftovers(stateDir,now=Date.now()){let tmp=[],tmpBytes=0,entries;try{entries=readdirSync(stateDir)}catch{return{tmp,tmpBytes,lock:!1}}for(let name of entries){if(!name.startsWith("tasks.json.")||!name.endsWith(".tmp"))continue;let path=join2(stateDir,name);try{let stat=statSync2(path);if(now-stat.mtimeMs<TMP_MAX_AGE_MS)continue;unlinkSync(path),tmp.push(path),tmpBytes+=stat.size}catch{}}return{tmp,tmpBytes,lock:clearStaleLock(join2(stateDir,"tasks.json.lock"))}}function clearStaleLock(lockPath){let holder;try{holder=readFileSync2(lockPath,"utf8").trim()}catch{return!1}let pid=Number.parseInt(holder,10);if(Number.isFinite(pid)&&pid>0&&isProcessAlive(pid))return!1;return releaseSync(lockPath,holder),!existsSync(lockPath)}var CLI_NAME=ROVE_PRODUCT_NAME;function printDaemonUsage(out){out.write([`Usage: ${CLI_NAME} daemon <command>`,"","Commands:"," status Print the running daemon's status JSON (default)"," start Run the daemon in the foreground (this process becomes it)"," --resident: never idle-stop when the last TUI leaves (headless host)"," stop Ask the running daemon to shut down"," restart Stop the daemon (graceful \u2192 SIGTERM \u2192 SIGKILL) and respawn it",""].join(`
6
+ `).find((l)=>l.startsWith("branch "))?.slice(7).trim().replace(/^refs\/heads\//,"")||null}function readRefSymbolic(dirs,ref){for(let dir of[dirs.gitDir,dirs.commonDir])try{let target=readFileSync(join(dir,ref),"utf8").trim().match(/^ref:\s*(.+)$/)?.[1]?.trim();if(target)return target}catch{}return null}function ladderFromFiles(worktreePath){let dirs=resolveGitDirs(worktreePath);if(!dirs)return;let originHead=readRefSymbolic(dirs,"refs/remotes/origin/HEAD")?.replace(/^refs\/remotes\//,""),baseCheckout=readRefSymbolic({gitDir:dirs.commonDir,commonDir:dirs.commonDir},"HEAD")?.replace(/^refs\/heads\//,""),names=[],head=readHeadSha(dirs),parts=[`HEAD=${head}`];for(let guess of[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]]){if(names.includes(guess))continue;let sha=readRefSha(dirs,guess);if(sha===null)continue;names.push(guess),parts.push(`${guess}=${sha}`)}return{names,fingerprint:head===null?null:parts.join(",")}}async function ladderFromGit(worktreePath,signal){let head=await git2(worktreePath,["symbolic-ref","--short","refs/remotes/origin/HEAD"],signal),originHead=head.status===0?head.stdout.trim():"",baseCheckout=await baseCheckoutBranchFromGit(worktreePath,signal),names=[],candidates=[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]];for(let guess of candidates){if(names.includes(guess))continue;if(await refExists(worktreePath,guess,signal))names.push(guess)}return{names,fingerprint:null}}async function resolveBaseRefCached(worktreePath,recordedBaseRef,signal,now=Date.now()){if(recordedBaseRef){let dirs=resolveGitDirs(worktreePath);if(dirs&&readRefSha(dirs,recordedBaseRef)!==null)return recordedBaseRef;if(await refExists(worktreePath,recordedBaseRef,signal))return recordedBaseRef}let hit=cache.get(worktreePath);if(hit&&now-hit.at<BASE_REF_TTL_MS)return hit.ref;let ladder=ladderFromFiles(worktreePath)??await ladderFromGit(worktreePath,signal);if(hit&&ladder.fingerprint!==null&&hit.fingerprint===ladder.fingerprint)return cache.set(worktreePath,{...hit,at:now}),hit.ref;let ref=null;for(let candidate of ladder.names)if(await sharesHistory(worktreePath,candidate,signal)){ref=candidate;break}return cache.set(worktreePath,{ref,at:now,fingerprint:ladder.fingerprint}),ref}var cache2=new Map;function readShas(worktreePath,baseRef){let dirs=resolveGitDirs(worktreePath);if(!dirs)return null;let head=readHeadSha(dirs),base=readRefSha(dirs,baseRef);return head&&base?{head,base}:null}async function driftCached(worktreePath,baseRef,compute){let shas=readShas(worktreePath,baseRef),hit=shas?cache2.get(worktreePath):void 0;if(shas&&hit&&hit.head===shas.head&&hit.base===shas.base)return hit.value;let value=await compute();if(shas&&value!==null)cache2.set(worktreePath,{...shas,value});return value}import{statSync}from"fs";function judgeWorktree(signals,nowMs){if(signals.dirty)return{verdict:"active",reason:"dirty"};if(signals.prState==="open")return{verdict:"active",reason:"prOpen"};if(signals.prState==="merged")return{verdict:"merged",reason:"prMerged"};if(signals.aheadOfDefault===0)return{verdict:"merged",reason:"inMain"};if(signals.prState==="closed")return{verdict:"stale",reason:"prClosed"};if(signals.lastActivityMs>0&&nowMs-signals.lastActivityMs>1209600000)return{verdict:"stale",reason:"idle"};return{verdict:"fresh",reason:"fresh"}}function parseGhPrList(stdout){let entries;try{entries=JSON.parse(stdout)}catch{return null}if(!Array.isArray(entries))return null;let rank={open:3,merged:2,closed:1},map=new Map;for(let entry of entries){let branch=entry?.headRefName,rawState=entry?.state;if(typeof branch!=="string"||typeof rawState!=="string")continue;let state=rawState.toLowerCase();if(state!=="open"&&state!=="merged"&&state!=="closed")continue;let cur=map.get(branch);if(!cur||rank[state]>rank[cur])map.set(branch,state)}return map}var TIMEOUT_MS=4000,manager=new GitWorktreeManager;function createdAt(path){try{let stat=statSync(path);return stat.birthtimeMs||stat.mtimeMs}catch{return 0}}async function run(path,argv){return execHostForWorktreePath(path).run(argv,{cwd:path,signal:AbortSignal.timeout(TIMEOUT_MS)})}async function branchOnRemote(path,branch){try{let out=await run(path,["git","ls-remote","--exit-code","--heads","origin",branch]);return out.exitCode===0?!0:out.exitCode===2?!1:null}catch{return null}}async function defaultRef(repo){try{let out=await run(repo,["git","symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(out.exitCode===0&&out.stdout.trim())return out.stdout.trim()}catch{}for(let guess of["origin/main","origin/master"])try{if((await run(repo,["git","rev-parse","--verify","--quiet",guess])).exitCode===0)return guess}catch{}return null}async function prStates(repo){try{let origin=await run(repo,["git","remote","get-url","origin"]);if(origin.exitCode!==0||!origin.stdout.includes("github.com"))return null;let out=await run(repo,["gh","pr","list","--state","all","--limit","200","--json","headRefName,state"]);return out.exitCode===0?parseGhPrList(out.stdout):null}catch{return null}}async function ahead(path,ref){if(!ref)return null;try{let out=await run(path,["git","rev-list","--count",`${ref}..HEAD`]),value=Number.parseInt(out.stdout.trim(),10);return out.exitCode===0&&!Number.isNaN(value)?value:null}catch{return null}}async function listWorktreeProjectsAdapter(network){let repos=getSavedRepos().filter((repo)=>!getRemoteRepoConfig(repo)),now=Date.now();return Promise.all(repos.map(async(repo)=>{let[worktrees,states,ref]=await Promise.all([manager.listAll(repo),network?prStates(repo):null,defaultRef(repo)]),rows=await Promise.all(worktrees.map(async(worktree)=>{let[remote,aheadBy]=await Promise.all([network?branchOnRemote(worktree.path,worktree.branch):null,ahead(worktree.path,ref)]),judgement=judgeWorktree({dirty:worktree.dirty===!0,prState:states?.get(worktree.branch)??null,aheadOfDefault:aheadBy,lastActivityMs:worktree.lastActivityMs},now);return{...worktree,repo,createdAtMs:createdAt(worktree.path),branchOnRemote:remote,verdict:judgement.verdict,verdictReason:judgement.reason}}));return{repo,worktrees:rows}}))}async function listUnreadableWorktreesAdapter(repo){return manager.listUnreadableWorktrees(repo)}async function removeWorktreeAdapter(path,force){let residue=null;return await manager.remove(path,{force,onSalvage:(record)=>{if(record)auditWorktreeSalvaged(path,record.ref,record.commit,record.uncaptured)},onResidue:(r)=>{residue={path:r.path,reason:r.reason},auditWorktreeResidue(r.path,r.reason)}}),residue}function resolveProtocolUpgradeAndLearnPreset(task,evidence){let preset=protocolWriteBackFromLiveSession(task,evidence,getCustomEngineIds());if(preset)setPersistedString(engineProtocolKey(preset.id),preset.protocol);return protocolUpgradeFromLiveSession(task,evidence)}var daemonRuntime={currentVersion:CURRENT_VERSION,tabsPersistence:stateFileTabsPersistence,startMachineHub(bus){let stop=null,stopped=!1;return import("./chunk-16ttm9x6.js").then(({startDaemonMachineHub})=>{if(!stopped)stop=startDaemonMachineHub(bus)}),()=>{stopped=!0,stop?.()}},async invokeApi(verb,params,socketPath,route){let[{executeVerb,errorEnvelope},{daemonCaller},{RoveDaemonClient:RoveDaemonClient2}]=await Promise.all([import("./chunk-ewqqwtrj.js"),import("./chunk-34tbcjdy.js"),import("./chunk-5dd7trgf.js")]);if(route?.forwarded){let{inboundRefusal}=await import("./chunk-p6334e7v.js"),denied=inboundRefusal(verb);if(denied){let{ApiError}=await import("./chunk-34tbcjdy.js");return errorEnvelope(new ApiError(`this machine refuses "${denied}" verbs from other machines (${verb} from ${route.from??"a hub"})`,"INBOUND_DENIED",{hint:`on this machine: rove machine inbound allow ${denied}`}))}}let client=new RoveDaemonClient2(socketPath);try{await client.connect();let{invokeRouted}=await import("./chunk-b5c7p22a.js");return await invokeRouted({verb,params,machine:route?.machine,forwarded:route?.forwarded,localTasks:()=>client.request("task.list").then((res)=>res.tasks??[]),isLocalTask:(id)=>client.request("task.get",{taskId:id}).then(()=>!0,()=>!1),runHere:()=>executeVerb(verb,{params},{client,caller:daemonCaller(route?.forwarded===!0)})})}catch(err){return errorEnvelope(err)}finally{client.close()}},defaultTaskVendor:DEFAULT_TASK_VENDOR,placeholderTaskTitle:PLACEHOLDER_TASK_TITLE,isTaskStatus,isEngineActivityKind,affectsActivityState,async foregroundEngines(pids){let rows=parsePsSnapshot(await psSnapshot([...pids])),out=new Map;for(let pid of pids){let found=foregroundEngineIn(rows,pid);out.set(pid,found?{vendor:found.vendor,pid:found.pid}:null)}return out},titleTurnHint:(vendor,title)=>engineTitleTurnHint(sessionProtocol(vendor),title),sessionProtocol,resolveProtocolUpgrade:resolveProtocolUpgradeAndLearnPreset,readEngineTurns:async(vendor,transcriptPath)=>await protocolEntry(vendor).readTurns?.(transcriptPath)??[],checkLatestVersion:()=>checkLatestVersion({channel:preferredReleaseChannel()}),latestTranscriptMtime,deriveTitleFromSession,deriveTitleFromSessionId,createEngineTurnDetector:(vendor)=>createEngineTurnDetector(sessionProtocol(vendor)),async runWorktreeStatus(worktreePath,signal,baseRef){let result=await spawnCapture("git",["status","--porcelain=v1"],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});if(result.status!==0)throw Error("git status failed");let counts=parsePorcelain(result.stdout),base=await resolveBaseRefCached(worktreePath,baseRef,signal);if(!base)return counts;let drift=await driftCached(worktreePath,base,async()=>{let out=await spawnCapture("git",["rev-list","--left-right","--count",`${base}...HEAD`],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});return out.status===0?parseAheadBehind(out.stdout):null});return drift===null?counts:{...counts,...drift}},maybeAutoStart:(orch,taskId)=>maybeAutoStart(orch,taskId),listWorktreeProjects:listWorktreeProjectsAdapter,listUnreadableWorktrees:listUnreadableWorktreesAdapter,removeWorktree:removeWorktreeAdapter,async syncWorktreeWithBase(worktreePath,recordedBaseRef){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),SYNC_TIMEOUT_MS);try{let baseRef=await resolveBaseRefCached(worktreePath,recordedBaseRef,controller.signal);if(!baseRef)throw Error("no base ref resolves for this worktree");return await syncWorktreeWithBase(worktreePath,baseRef,controller.signal)}finally{clearTimeout(timer)}},availableEngineIds,engineDisplayName,roveApiInvocation,engineEntry,ensureTaskSession:ensureTaskSessionAdapter,startTaskSessionWithPrompt:startTaskSessionWithPromptAdapter,tearDownTaskSession:tearDownTaskSessionAdapter,async readEngineContextUsage(vendor,sessionId){let read=protocolEntry(vendor).history.readUsageSnapshot;if(!read)return null;let snapshot=await read(sessionId);if(snapshot?.context_tokens===void 0)return null;return{contextTokens:snapshot.context_tokens,...snapshot.context_window_tokens===void 0?{}:{contextWindowTokens:snapshot.context_window_tokens},...snapshot.context_tokens_approximate?{approximate:!0}:{},...snapshot.input_tokens===void 0?{}:{inputTokens:snapshot.input_tokens},...snapshot.output_tokens===void 0?{}:{outputTokens:snapshot.output_tokens},...snapshot.cache_read_input_tokens===void 0?{}:{cacheReadTokens:snapshot.cache_read_input_tokens},...snapshot.cache_creation_input_tokens===void 0?{}:{cacheCreationTokens:snapshot.cache_creation_input_tokens}}},quotaUsage:(vendor)=>engineEntry(vendor).quotaUsage?.()??Promise.resolve(null),vendorsWithQuotaProbe,deliverPromptToLiveEngine:deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailed:deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailed:deliverPromptToLiveEngineTabDetailedAdapter,getPersistedString,setPersistedString,getSavedRepos:()=>[...getSavedRepos()],prStatus:{viewFields:GH_PR_VIEW_FIELDS,mapView:(view,at)=>mapGhPrView(view,at),sameStatus:samePrStatus,nextPoll:(outcome,failures,now,config,random)=>nextPrPoll(outcome,failures,now,config,random),classify:classifyGhFailure}};import{homedir}from"os";async function createRoveCore(options={}){let homeDir=options.homeDir??readRoveHomeDirEnv()??homedir(),store=new TaskIndexStore({homeDir});await store.load();let worktrees=new GitWorktreeManager,orchestrator=new Orchestrator({store,worktrees,onSalvage:(taskId,salvage,repo)=>auditDeletionSalvaged(String(taskId),salvage.ref,salvage.commit,repo,salvage.uncaptured),onWorktreeResidue:(taskId,residue)=>auditDeletionResidue(String(taskId),residue.path,residue.reason),onBranchKept:(taskId,kept)=>auditDeletionBranchKept(String(taskId),kept.branch,kept.reason),tearDownSession:(taskId)=>tearDownTaskSessionAdapter(String(taskId),teardownScope(store.list(),String(taskId),new Set([String(taskId)])))}),backfilled=backfillSavedReposFromProjects(store.list().filter((task)=>task.kind==="main").map((task)=>task.repo));if(backfilled.length>0)console.error(`[rove] added ${backfilled.length} existing project(s) to the new-task picker`);return{homeDir,orchestrator,store,worktrees,async close(){orchestrator.dispose()}}}import{existsSync,readFileSync as readFileSync2,readdirSync,statSync as statSync2,unlinkSync}from"fs";import{join as join2}from"path";var TMP_MAX_AGE_MS=300000;function sweepIndexLeftovers(stateDir,now=Date.now()){let tmp=[],tmpBytes=0,entries;try{entries=readdirSync(stateDir)}catch{return{tmp,tmpBytes,lock:!1}}for(let name of entries){if(!name.startsWith("tasks.json.")||!name.endsWith(".tmp"))continue;let path=join2(stateDir,name);try{let stat=statSync2(path);if(now-stat.mtimeMs<TMP_MAX_AGE_MS)continue;unlinkSync(path),tmp.push(path),tmpBytes+=stat.size}catch{}}return{tmp,tmpBytes,lock:clearStaleLock(join2(stateDir,"tasks.json.lock"))}}function clearStaleLock(lockPath){let holder;try{holder=readFileSync2(lockPath,"utf8").trim()}catch{return!1}let pid=Number.parseInt(holder,10);if(Number.isFinite(pid)&&pid>0&&isProcessAlive(pid))return!1;return releaseSync(lockPath,holder),!existsSync(lockPath)}var CLI_NAME=ROVE_PRODUCT_NAME;function printDaemonUsage(out){out.write([`Usage: ${CLI_NAME} daemon <command>`,"","Commands:"," status Print the running daemon's status JSON (default)"," start Run the daemon in the foreground (this process becomes it)"," --resident: never idle-stop when the last TUI leaves (headless host)"," stop Ask the running daemon to shut down"," restart Stop the daemon (graceful \u2192 SIGTERM \u2192 SIGKILL) and respawn it",""].join(`
7
7
  `))}async function runDaemonSubcommand(argv){let[command="status",...flags]=argv,socketPath=defaultDaemonSocketPath(),pidPath=defaultDaemonPidPath();if(command==="--help"||command==="-h"||command==="help"){printDaemonUsage(process.stdout);return}if(!SUBCOMMAND_VERBS.daemon.includes(command))process.stderr.write(`${CLI_NAME} daemon: unknown command "${command}"
8
8
 
9
- `),printDaemonUsage(process.stderr),process.exit(2);if(command==="relay"){let pty=argvHasFlag(flags,"--pty"),{ensureDaemonReachable}=await import("./chunk-a3jqg8g2.js"),{ensurePtyHostReachable}=await import("./chunk-hyydmt77.js"),target=pty?await ensurePtyHostReachable():await ensureDaemonReachable(void 0,"autospawn"),{connect}=await import("net"),socket=connect(target);if(argvHasFlag(flags,"--preamble"))process.stdout.write(RELAY_PREAMBLE);process.stdin.pipe(socket),socket.pipe(process.stdout),await new Promise((resolve)=>{socket.on("close",()=>resolve()),process.stdin.on("end",()=>socket.end())}),process.exit(0)}let badFlag=flags.find((flag)=>!(command==="start"&&argvHasFlag([flag],"--resident"))&&!(command==="status"&&flag==="--json")&&!(command==="relay"&&flag==="--pty")),resident=switchFlag(flags,"--resident");if(badFlag!==void 0||resident===void 0)process.stderr.write(`${CLI_NAME} daemon ${command}: bad option "${badFlag??flags.join(" ")}"
9
+ `),printDaemonUsage(process.stderr),process.exit(2);if(command==="relay"){let pty=argvHasFlag(flags,"--pty"),{ensureDaemonReachable}=await import("./chunk-3v9s3bcz.js"),{ensurePtyHostReachable}=await import("./chunk-78v1q5mz.js"),target=pty?await ensurePtyHostReachable():await ensureDaemonReachable(void 0,"autospawn"),{connect}=await import("net"),socket=connect(target);if(argvHasFlag(flags,"--preamble"))process.stdout.write(RELAY_PREAMBLE);process.stdin.pipe(socket),socket.pipe(process.stdout),await new Promise((resolve)=>{socket.on("close",()=>resolve()),process.stdin.on("end",()=>socket.end())}),process.exit(0)}let badFlag=flags.find((flag)=>!(command==="start"&&argvHasFlag([flag],"--resident"))&&!(command==="status"&&flag==="--json")&&!(command==="relay"&&flag==="--pty")),resident=switchFlag(flags,"--resident");if(badFlag!==void 0||resident===void 0)process.stderr.write(`${CLI_NAME} daemon ${command}: bad option "${badFlag??flags.join(" ")}"
10
10
 
11
11
  `),printDaemonUsage(process.stderr),process.exit(2);if(command==="status"){let client=new RoveDaemonClient(socketPath);try{let status=await client.request("daemon.status");console.log(JSON.stringify({...status,relayPreamble:!0},null,2))}catch{let pid=await readPidFile(pidPath);if(pid)console.log(`${CLI_NAME} daemon: no daemon socket at ${socketPath} (stale pidfile pid=${pid})`);else console.log(`${CLI_NAME} daemon: no daemon running at ${socketPath}`);process.exitCode=1}finally{client.close()}return}if(command==="stop"){let client=new RoveDaemonClient(socketPath);try{await client.request("daemon.stop"),console.log(`${CLI_NAME} daemon: stop requested`)}catch{console.log(`${CLI_NAME} daemon: no daemon running at ${socketPath}`)}finally{client.close()}return}if(command==="restart"){await stopDaemonProcess(socketPath,pidPath,{reason:"restart"}),(await connectOrStartDaemon("explicit-restart")).close(),console.log(`${CLI_NAME} daemon: restarted, listening on ${socketPath}`);return}rotateLogIfNeeded(defaultDaemonLogPath()),installDaemonCrashHandlers(),logDaemonInfo("boot",`daemon starting \u2014 ${daemonSpawnReason()} (pid ${process.pid}, v${CURRENT_VERSION})`);let core,channels=[],server=await startDaemonServer(async()=>{let migration=migrateRoveDaemonStateLayout();for(let warning of migration.warnings)console.error(`[rove] daemon state migration will retry: ${warning}`);core=await createRoveCore();let swept=sweepIndexLeftovers(core.store.stateDir);if(swept.lock||swept.tmp.length>0)console.error(`[rove] swept crash leftovers in ${core.store.stateDir}: ${swept.tmp.length} orphaned staging file(s) (${swept.tmpBytes} bytes)${swept.lock?", stale task-index lockfile":""}`);return core.orchestrator},{runtime:daemonRuntime,socketPath,pidPath,plugins:{binPath:resolvePluginBinPath()},keepAlive:()=>channels.some((channel)=>channel.keepAlive()),resident,onStop:async()=>{cancelAllLogins();for(let channel of channels)channel.stop();await core?.close()}});console.log(`${CLI_NAME} daemon: listening on ${server.socketPath}`),channels=await startChatChannels({socketPath:server.socketPath,log:logDaemonInfo,keepAliveChanged:()=>server.reevaluateIdle()});let shutdown=async()=>{await server.close(),process.exit(0)};process.once("SIGINT",()=>void shutdown()),process.once("SIGTERM",()=>void shutdown())}export{runDaemonSubcommand};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{invokeVerb,runApiSubcommand}from"./chunk-fzadtbrm.js";import{executeVerb,toApiError}from"./chunk-kgg1ykdw.js";import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-yk5zs8ec.js";import"./chunk-y0wg9ekb.js";import"./chunk-6vhr65h3.js";import"./chunk-182qa2d6.js";import"./chunk-rtpa8hg3.js";import"./chunk-r3ezk0cs.js";import"./chunk-p6jw0zcd.js";import"./chunk-pm91e38v.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-7drxm3c8.js";import"./chunk-c2yt6fag.js";import"./chunk-gs01afvb.js";import"./chunk-sq6zj3fb.js";import"./chunk-qkehg2c1.js";import"./chunk-zvxq5xdr.js";import"./chunk-sj4e61x6.js";import"./chunk-rngjpf3c.js";import"./chunk-7yn79aye.js";import"./chunk-adv5s59k.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-783d1ba0.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import{ApiError}from"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-fqgvmy2d.js";import"./chunk-a037vcy5.js";import"./chunk-aac92ra2.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-2r1fgng9.js";import"./chunk-3249q53j.js";import"./chunk-67nb2sdd.js";import"./chunk-7vkvfawc.js";import"./chunk-2brn8e1y.js";import"./chunk-a09kjwtd.js";import"./chunk-dyzvnvjz.js";import"./chunk-7kysxgbq.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-4vad6e9t.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-cynqvjk8.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{verbSchema,verbHelp,validateAgainstSpec,toApiError,schemaIndex,runApiSubcommand,parseFlags,parseAgentsSpec,invokeVerb,fullSchema,findVerb,executeVerb,deliverPrompt,defaultApiRuntime,buildCountPlan,apiUsage,VerbArgs,VERB_GROUPS,VERBS,ApiError,API_VERBS,API_SCHEMA_VERSION};
2
+ import{invokeVerb,runApiSubcommand}from"./chunk-g9yba5vh.js";import{executeVerb,toApiError}from"./chunk-m6yy3qc1.js";import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-kyt9ytz2.js";import"./chunk-t34kjg5y.js";import"./chunk-jwedmkm8.js";import"./chunk-snqa07h6.js";import"./chunk-rtpa8hg3.js";import"./chunk-xkmdxcjg.js";import"./chunk-p6jw0zcd.js";import"./chunk-pm91e38v.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-9er68n24.js";import"./chunk-9bae7f3m.js";import"./chunk-zaw71cf4.js";import"./chunk-sq6zj3fb.js";import"./chunk-qkehg2c1.js";import"./chunk-n2ejvjrd.js";import"./chunk-xn7bk4f9.js";import"./chunk-15fp4p9v.js";import"./chunk-rzef6szc.js";import"./chunk-sz2xs0a2.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-783d1ba0.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import{ApiError}from"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-qvnr8c18.js";import"./chunk-edrxs4cy.js";import"./chunk-03rbg95q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-2r1fgng9.js";import"./chunk-387ecqb8.js";import"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-2brn8e1y.js";import"./chunk-6h4qdckd.js";import"./chunk-e01321zn.js";import"./chunk-7kysxgbq.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-w9cdc97q.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{verbSchema,verbHelp,validateAgainstSpec,toApiError,schemaIndex,runApiSubcommand,parseFlags,parseAgentsSpec,invokeVerb,fullSchema,findVerb,executeVerb,deliverPrompt,defaultApiRuntime,buildCountPlan,apiUsage,VerbArgs,VERB_GROUPS,VERBS,ApiError,API_VERBS,API_SCHEMA_VERSION};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{API_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb,unknownVerbError}from"./chunk-yk5zs8ec.js";import"./chunk-y0wg9ekb.js";import"./chunk-6vhr65h3.js";import"./chunk-182qa2d6.js";import"./chunk-rtpa8hg3.js";import"./chunk-r3ezk0cs.js";import"./chunk-p6jw0zcd.js";import"./chunk-pm91e38v.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-7drxm3c8.js";import"./chunk-c2yt6fag.js";import"./chunk-gs01afvb.js";import"./chunk-sq6zj3fb.js";import"./chunk-qkehg2c1.js";import"./chunk-zvxq5xdr.js";import"./chunk-sj4e61x6.js";import"./chunk-rngjpf3c.js";import"./chunk-7yn79aye.js";import"./chunk-adv5s59k.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-783d1ba0.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-fqgvmy2d.js";import"./chunk-a037vcy5.js";import"./chunk-aac92ra2.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-2r1fgng9.js";import"./chunk-3249q53j.js";import"./chunk-67nb2sdd.js";import"./chunk-7vkvfawc.js";import"./chunk-2brn8e1y.js";import"./chunk-a09kjwtd.js";import"./chunk-dyzvnvjz.js";import"./chunk-7kysxgbq.js";import"./chunk-08gdekk1.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-4vad6e9t.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-cynqvjk8.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{unknownVerbError,findVerb,VERB_GROUPS,VERB_ALIASES,VERBS,API_VERBS};
2
+ import{API_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb,unknownVerbError}from"./chunk-kyt9ytz2.js";import"./chunk-t34kjg5y.js";import"./chunk-jwedmkm8.js";import"./chunk-snqa07h6.js";import"./chunk-rtpa8hg3.js";import"./chunk-xkmdxcjg.js";import"./chunk-p6jw0zcd.js";import"./chunk-pm91e38v.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-mmq6922s.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-1rjq808h.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-9er68n24.js";import"./chunk-9bae7f3m.js";import"./chunk-zaw71cf4.js";import"./chunk-sq6zj3fb.js";import"./chunk-qkehg2c1.js";import"./chunk-n2ejvjrd.js";import"./chunk-xn7bk4f9.js";import"./chunk-15fp4p9v.js";import"./chunk-rzef6szc.js";import"./chunk-sz2xs0a2.js";import"./chunk-fvvb0072.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-783d1ba0.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-qvnr8c18.js";import"./chunk-edrxs4cy.js";import"./chunk-03rbg95q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-2r1fgng9.js";import"./chunk-387ecqb8.js";import"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-2brn8e1y.js";import"./chunk-6h4qdckd.js";import"./chunk-e01321zn.js";import"./chunk-7kysxgbq.js";import"./chunk-b68dd36h.js";import"./chunk-ec7f3wcm.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-w9cdc97q.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bj6sa371.js";import"./chunk-1ffqacz9.js";import"./chunk-cmp64q4j.js";import"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{unknownVerbError,findVerb,VERB_GROUPS,VERB_ALIASES,VERBS,API_VERBS};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{stopDaemonProcess}from"./chunk-67nb2sdd.js";import{spawnDetachedDaemon}from"./chunk-7vkvfawc.js";import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{DAEMON_PROTOCOL_VERSION,RoveDaemonClient}from"./chunk-cynqvjk8.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-eqdbfgq5.js";import{ROVE_PRODUCT_NAME}from"./chunk-nc46gddg.js";import{closeSync,existsSync,mkdirSync,openSync,statSync,unlinkSync}from"fs";import{dirname,resolve}from"path";import{fileURLToPath}from"url";var DAEMON_START_ARGS=["daemon","start"],DAEMON_HELLO_TIMEOUT_MS=3000,BUSY_DAEMON_GRACE_MS=15000;function insideEngineSession(env=process.env){return typeof env.ROVE_TASK_ID==="string"&&env.ROVE_TASK_ID!==""}function autospawnDaemonEnv(env=process.env,reason="autospawn"){let{ROVE_TASK_ID:_task,ROVE_TAB_ID:_tab,ROVE_TUI:_tui,ROVE_TERMINAL_PTY:_pty,ROVE_TASK_ID:_roveTask,ROVE_TAB_ID:_roveTab,ROVE_TUI:_roveTui,ROVE_TERMINAL_PTY:_rovePty,...rest}=env;return{...rest,ROVE_DAEMON_AUTOSPAWNED:"1",ROVE_DAEMON_SPAWN_REASON:reason}}function daemonSpawnReason(env=process.env){let raw=env.ROVE_DAEMON_SPAWN_REASON;if(raw==="explicit-restart"||raw==="autospawn")return raw;return env.ROVE_DAEMON_AUTOSPAWNED==="1"?"autospawn":"manual"}var SPAWN_LOCK_STALE_MS=40000,SPAWN_LOCK_WAIT_MS=30000;function tryAcquireSpawnLock(lockPath,staleMs=SPAWN_LOCK_STALE_MS){let create=()=>{return mkdirSync(dirname(lockPath),{recursive:!0}),closeSync(openSync(lockPath,"wx")),!0};try{return create()}catch{try{if(Date.now()-statSync(lockPath).mtimeMs<=staleMs)return!1;return unlinkSync(lockPath),create()}catch{return!1}}}async function ensureDaemonReachable(resolveSpawn=resolveRoveSpawn,spawnReason="autospawn"){let socketPath=defaultDaemonSocketPath(),state=await probeDaemonSocket(socketPath);if(state==="alive")return socketPath;if(state==="wedged"&&insideEngineSession())throw Error(`rove: daemon at ${socketPath} is not answering hello (busy or wedged); not restarting it from inside an engine session \u2014 retry, or run \`rove daemon restart\` from a regular shell`);let lockPath=`${defaultDaemonPidPath()}.spawn-lock`;if(!tryAcquireSpawnLock(lockPath)){let deadline=Date.now()+SPAWN_LOCK_WAIT_MS;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,150))}throw Error(`rove: another process is starting the daemon but it never became reachable at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}try{if(await probeDaemonSocket(socketPath)==="alive")return socketPath;let livePid=await readPidFile(defaultDaemonPidPath());if(livePid!==null&&livePid!==process.pid&&isProcessAlive(livePid)){let deadline2=Date.now()+BUSY_DAEMON_GRACE_MS;while(Date.now()<deadline2){if(await new Promise((resolveTimer)=>setTimeout(resolveTimer,250)),await testDaemonResponds(socketPath))return socketPath;if(!isProcessAlive(livePid))break}}let[command,...args]=resolveSpawn(DAEMON_START_ARGS);await stopDaemonProcess(socketPath,defaultDaemonPidPath()).catch(()=>{}),spawnDetachedDaemon(command,args,autospawnDaemonEnv(process.env,spawnReason),defaultDaemonLogPath());let deadline=Date.now()+5000;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,100))}throw Error(`rove: daemon did not start (or stayed wedged) at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}finally{try{unlinkSync(lockPath)}catch{}}}async function connectOrStartDaemon(spawnReason="autospawn"){let socketPath=await ensureDaemonReachable(resolveRoveSpawn,spawnReason),client=new RoveDaemonClient(socketPath);return await client.connect(),client}async function connectIfRunning(){let socketPath=defaultDaemonSocketPath();if(!await testDaemonResponds(socketPath))return null;let client=new RoveDaemonClient(socketPath);return await client.connect(),client}async function probeDaemonSocket(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){let probe=new RoveDaemonClient(socketPath);try{await probe.connect()}catch{return probe.close(),"absent"}let droppedByPeer=!1,offClose=probe.onLifecycle("close",()=>{droppedByPeer=!0}),replied=probe.request("hello",{protocolVersion:DAEMON_PROTOCOL_VERSION}).then(()=>!0).catch(()=>!0),timer,timedOut=new Promise((resolve2)=>{timer=setTimeout(()=>resolve2(!1),timeoutMs)}),settled=await Promise.race([replied,timedOut]);if(timer)clearTimeout(timer);if(offClose(),probe.close(),droppedByPeer)return"absent";return settled?"alive":"wedged"}async function testDaemonResponds(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){return await probeDaemonSocket(socketPath,timeoutMs)==="alive"}class StaleInstallError extends Error{candidates;constructor(cliName,dir,candidates){super(`${cliName}: this process is running from an install that no longer exists on disk \u2014 no ${cliName} entry near ${dir} (checked ${candidates.join(", ")}). Reinstall (\`npm install -g @sma1lboy/rove\`) and relaunch Rove.`);this.name="StaleInstallError",this.candidates=candidates}}function isStaleInstallError(err){return err instanceof Error&&err.name==="StaleInstallError"}function resolveRoveSpawn(subcommand,env=process.env,moduleFile=fileURLToPath(import.meta.url)){let here=moduleFile;if(here.startsWith("/$bunfs")||here.startsWith("B:\\~BUN"))return[process.execPath,...subcommand];let dir=dirname(here),cliName=ROVE_PRODUCT_NAME,candidates=[resolve(dir,`../cli/${cliName}.ts`),resolve(dir,`../../../rove/src/cli/${cliName}.ts`),resolve(dir,`../cli/${cliName}.js`),resolve(dir,"../cli/index.ts"),resolve(dir,"../../../rove/src/cli/index.ts"),resolve(dir,"../cli/index.js")],entry=candidates.find((candidate)=>existsSync(candidate));if(entry)return[process.execPath,entry,...subcommand];throw new StaleInstallError(cliName,dir,candidates)}
2
+ import{stopDaemonProcess}from"./chunk-kgs56yns.js";import{spawnDetachedDaemon}from"./chunk-4hnz77xf.js";import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{DAEMON_PROTOCOL_VERSION,RoveDaemonClient}from"./chunk-sza3tyhs.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-eqdbfgq5.js";import{ROVE_PRODUCT_NAME}from"./chunk-nc46gddg.js";import{closeSync,existsSync,mkdirSync,openSync,statSync,unlinkSync}from"fs";import{dirname,resolve}from"path";import{fileURLToPath}from"url";var DAEMON_START_ARGS=["daemon","start"],DAEMON_HELLO_TIMEOUT_MS=3000,BUSY_DAEMON_GRACE_MS=15000;function insideEngineSession(env=process.env){return typeof env.ROVE_TASK_ID==="string"&&env.ROVE_TASK_ID!==""}function autospawnDaemonEnv(env=process.env,reason="autospawn"){let{ROVE_TASK_ID:_task,ROVE_TAB_ID:_tab,ROVE_TUI:_tui,ROVE_TERMINAL_PTY:_pty,ROVE_TASK_ID:_roveTask,ROVE_TAB_ID:_roveTab,ROVE_TUI:_roveTui,ROVE_TERMINAL_PTY:_rovePty,...rest}=env;return{...rest,ROVE_DAEMON_AUTOSPAWNED:"1",ROVE_DAEMON_SPAWN_REASON:reason}}function daemonSpawnReason(env=process.env){let raw=env.ROVE_DAEMON_SPAWN_REASON;if(raw==="explicit-restart"||raw==="autospawn")return raw;return env.ROVE_DAEMON_AUTOSPAWNED==="1"?"autospawn":"manual"}var SPAWN_LOCK_STALE_MS=40000,SPAWN_LOCK_WAIT_MS=30000;function tryAcquireSpawnLock(lockPath,staleMs=SPAWN_LOCK_STALE_MS){let create=()=>{return mkdirSync(dirname(lockPath),{recursive:!0}),closeSync(openSync(lockPath,"wx")),!0};try{return create()}catch{try{if(Date.now()-statSync(lockPath).mtimeMs<=staleMs)return!1;return unlinkSync(lockPath),create()}catch{return!1}}}async function ensureDaemonReachable(resolveSpawn=resolveRoveSpawn,spawnReason="autospawn"){let socketPath=defaultDaemonSocketPath(),state=await probeDaemonSocket(socketPath);if(state==="alive")return socketPath;if(state==="wedged"&&insideEngineSession())throw Error(`rove: daemon at ${socketPath} is not answering hello (busy or wedged); not restarting it from inside an engine session \u2014 retry, or run \`rove daemon restart\` from a regular shell`);let lockPath=`${defaultDaemonPidPath()}.spawn-lock`;if(!tryAcquireSpawnLock(lockPath)){let deadline=Date.now()+SPAWN_LOCK_WAIT_MS;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,150))}throw Error(`rove: another process is starting the daemon but it never became reachable at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}try{if(await probeDaemonSocket(socketPath)==="alive")return socketPath;let livePid=await readPidFile(defaultDaemonPidPath());if(livePid!==null&&livePid!==process.pid&&isProcessAlive(livePid)){let deadline2=Date.now()+BUSY_DAEMON_GRACE_MS;while(Date.now()<deadline2){if(await new Promise((resolveTimer)=>setTimeout(resolveTimer,250)),await testDaemonResponds(socketPath))return socketPath;if(!isProcessAlive(livePid))break}}let[command,...args]=resolveSpawn(DAEMON_START_ARGS);await stopDaemonProcess(socketPath,defaultDaemonPidPath()).catch(()=>{}),spawnDetachedDaemon(command,args,autospawnDaemonEnv(process.env,spawnReason),defaultDaemonLogPath());let deadline=Date.now()+5000;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,100))}throw Error(`rove: daemon did not start (or stayed wedged) at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}finally{try{unlinkSync(lockPath)}catch{}}}async function connectOrStartDaemon(spawnReason="autospawn"){let socketPath=await ensureDaemonReachable(resolveRoveSpawn,spawnReason),client=new RoveDaemonClient(socketPath);return await client.connect(),client}async function connectIfRunning(){let socketPath=defaultDaemonSocketPath();if(!await testDaemonResponds(socketPath))return null;let client=new RoveDaemonClient(socketPath);return await client.connect(),client}async function probeDaemonSocket(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){let probe=new RoveDaemonClient(socketPath);try{await probe.connect()}catch{return probe.close(),"absent"}let droppedByPeer=!1,offClose=probe.onLifecycle("close",()=>{droppedByPeer=!0}),replied=probe.request("hello",{protocolVersion:DAEMON_PROTOCOL_VERSION}).then(()=>!0).catch(()=>!0),timer,timedOut=new Promise((resolve2)=>{timer=setTimeout(()=>resolve2(!1),timeoutMs)}),settled=await Promise.race([replied,timedOut]);if(timer)clearTimeout(timer);if(offClose(),probe.close(),droppedByPeer)return"absent";return settled?"alive":"wedged"}async function testDaemonResponds(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){return await probeDaemonSocket(socketPath,timeoutMs)==="alive"}class StaleInstallError extends Error{candidates;constructor(cliName,dir,candidates){super(`${cliName}: this process is running from an install that no longer exists on disk \u2014 no ${cliName} entry near ${dir} (checked ${candidates.join(", ")}). Reinstall (\`npm install -g @sma1lboy/rove\`) and relaunch Rove.`);this.name="StaleInstallError",this.candidates=candidates}}function isStaleInstallError(err){return err instanceof Error&&err.name==="StaleInstallError"}function resolveRoveSpawn(subcommand,env=process.env,moduleFile=fileURLToPath(import.meta.url)){let here=moduleFile;if(here.startsWith("/$bunfs")||here.startsWith("B:\\~BUN"))return[process.execPath,...subcommand];let dir=dirname(here),cliName=ROVE_PRODUCT_NAME,candidates=[resolve(dir,`../cli/${cliName}.ts`),resolve(dir,`../../../rove/src/cli/${cliName}.ts`),resolve(dir,`../cli/${cliName}.js`),resolve(dir,"../cli/index.ts"),resolve(dir,"../../../rove/src/cli/index.ts"),resolve(dir,"../cli/index.js")],entry=candidates.find((candidate)=>existsSync(candidate));if(entry)return[process.execPath,entry,...subcommand];throw new StaleInstallError(cliName,dir,candidates)}
3
3
  export{autospawnDaemonEnv,daemonSpawnReason,tryAcquireSpawnLock,ensureDaemonReachable,connectOrStartDaemon,connectIfRunning,probeDaemonSocket,testDaemonResponds,StaleInstallError,isStaleInstallError,resolveRoveSpawn};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{StaleInstallError,autospawnDaemonEnv,connectIfRunning,connectOrStartDaemon,daemonSpawnReason,ensureDaemonReachable,isStaleInstallError,probeDaemonSocket,resolveRoveSpawn,testDaemonResponds,tryAcquireSpawnLock}from"./chunk-3249q53j.js";import"./chunk-67nb2sdd.js";import"./chunk-7vkvfawc.js";import"./chunk-br8r72bf.js";import"./chunk-yt15y085.js";import"./chunk-cynqvjk8.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{tryAcquireSpawnLock,testDaemonResponds,resolveRoveSpawn,probeDaemonSocket,isStaleInstallError,ensureDaemonReachable,daemonSpawnReason,connectOrStartDaemon,connectIfRunning,autospawnDaemonEnv,StaleInstallError};
2
+ import{StaleInstallError,autospawnDaemonEnv,connectIfRunning,connectOrStartDaemon,daemonSpawnReason,ensureDaemonReachable,isStaleInstallError,probeDaemonSocket,resolveRoveSpawn,testDaemonResponds,tryAcquireSpawnLock}from"./chunk-387ecqb8.js";import"./chunk-kgs56yns.js";import"./chunk-4hnz77xf.js";import"./chunk-br8r72bf.js";import"./chunk-yt15y085.js";import"./chunk-sza3tyhs.js";import"./chunk-96kvwzj8.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{tryAcquireSpawnLock,testDaemonResponds,resolveRoveSpawn,probeDaemonSocket,isStaleInstallError,ensureDaemonReachable,daemonSpawnReason,connectOrStartDaemon,connectIfRunning,autospawnDaemonEnv,StaleInstallError};