@sma1lboy/rove 0.9.246 → 0.9.247

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 (74) hide show
  1. package/dist/cli/chunk-09y7gspe.js +4 -0
  2. package/dist/cli/{chunk-1wt1esef.js → chunk-0b5mec1c.js} +1 -1
  3. package/dist/cli/{chunk-g2kb61q5.js → chunk-1kprhx82.js} +2 -2
  4. package/dist/cli/{chunk-xx166cdv.js → chunk-1s93zcnx.js} +1 -1
  5. package/dist/cli/{chunk-9x980fd4.js → chunk-2md5j9ws.js} +1 -1
  6. package/dist/cli/{chunk-xnsk57ta.js → chunk-466djpa8.js} +1 -1
  7. package/dist/cli/{chunk-9nm43nw4.js → chunk-4a2veqfk.js} +1 -1
  8. package/dist/cli/{chunk-cgt8wmd7.js → chunk-4fgpzkaq.js} +1 -1
  9. package/dist/cli/{chunk-c5rb17k9.js → chunk-4hm0smvv.js} +1 -1
  10. package/dist/cli/{chunk-skf7y627.js → chunk-4nt1gnwq.js} +1 -0
  11. package/dist/cli/{chunk-jj460xsw.js → chunk-4qytyfmt.js} +1 -1
  12. package/dist/cli/{chunk-qdfxk8pt.js → chunk-4r3s1z14.js} +1 -1
  13. package/dist/cli/{chunk-xvdk2b8e.js → chunk-5c57gz48.js} +1 -1
  14. package/dist/cli/{chunk-9m5g6t5k.js → chunk-5zw9xngg.js} +1 -1
  15. package/dist/cli/chunk-60fy3ckp.js +3 -0
  16. package/dist/cli/{chunk-g8eh5jd4.js → chunk-6eb945nc.js} +1 -1
  17. package/dist/cli/{chunk-4ayqnz4j.js → chunk-73x2hszy.js} +1 -1
  18. package/dist/cli/{chunk-qdmzsx2z.js → chunk-7axwr3a5.js} +1 -1
  19. package/dist/cli/{chunk-8manew0x.js → chunk-7j6escfh.js} +24 -23
  20. package/dist/cli/{chunk-6nk7h22s.js → chunk-8p579jct.js} +1 -1
  21. package/dist/cli/{chunk-1zxheb0c.js → chunk-8vbcj8xx.js} +1 -1
  22. package/dist/cli/{chunk-tkbdgh2k.js → chunk-9sk0w5be.js} +1 -1
  23. package/dist/cli/{chunk-7za7dj9z.js → chunk-a10bkevn.js} +1 -1
  24. package/dist/cli/{chunk-84h387qb.js → chunk-a5vhekme.js} +1 -1
  25. package/dist/cli/chunk-c1j22psa.js +3 -0
  26. package/dist/cli/{chunk-wpvxfzb9.js → chunk-c9js0wd7.js} +1 -1
  27. package/dist/cli/chunk-ctkf2m9h.js +9 -0
  28. package/dist/cli/{chunk-gpan2g7d.js → chunk-ctmbj2y3.js} +1 -1
  29. package/dist/cli/{chunk-33dt8jkh.js → chunk-dbs8p34d.js} +2 -2
  30. package/dist/cli/{chunk-gxdfyn42.js → chunk-dqvy3kxk.js} +1 -1
  31. package/dist/cli/{chunk-zh6fadgw.js → chunk-e5k2j2x8.js} +1 -1
  32. package/dist/cli/{chunk-efq3j5v8.js → chunk-f3gedc7r.js} +1 -1
  33. package/dist/cli/{chunk-taf0014q.js → chunk-g655yb7d.js} +4 -2
  34. package/dist/cli/{chunk-1brfxbvg.js → chunk-grr2fn38.js} +1 -1
  35. package/dist/cli/{chunk-k5py2g4y.js → chunk-h29wy8y3.js} +1 -1
  36. package/dist/cli/{chunk-nem2x959.js → chunk-h86p4zzr.js} +1 -1
  37. package/dist/cli/{chunk-ca3bfxd9.js → chunk-hkbdrwtg.js} +1 -1
  38. package/dist/cli/{chunk-qgck9n3y.js → chunk-hv77tgmh.js} +1 -1
  39. package/dist/cli/{chunk-8ztzk7tg.js → chunk-j8evwrp3.js} +1 -1
  40. package/dist/cli/chunk-jxyvk9c0.js +3 -0
  41. package/dist/cli/{chunk-66cew8sb.js → chunk-kjhhwhs4.js} +1 -1
  42. package/dist/cli/{chunk-74v6dm9n.js → chunk-kme8knh8.js} +1 -1
  43. package/dist/cli/{chunk-6c5hh9zq.js → chunk-knpr38z6.js} +1 -1
  44. package/dist/cli/chunk-m9q1whep.js +3 -0
  45. package/dist/cli/{chunk-kxpfm6mb.js → chunk-ntkfhrbw.js} +3 -3
  46. package/dist/cli/{chunk-j3783bf2.js → chunk-pa6teq2c.js} +1 -1
  47. package/dist/cli/{chunk-aq04rqv7.js → chunk-pmszj74t.js} +1 -1
  48. package/dist/cli/{chunk-fcfh9xsq.js → chunk-qqz6nxfe.js} +2 -2
  49. package/dist/cli/{chunk-2whnrjrr.js → chunk-ry54qsbg.js} +3 -3
  50. package/dist/cli/{chunk-ybw6wah4.js → chunk-s9d6vjmc.js} +1 -1
  51. package/dist/cli/{chunk-2zrphhdf.js → chunk-szx3wehf.js} +1 -1
  52. package/dist/cli/{chunk-9xq1r084.js → chunk-t45c781p.js} +1 -1
  53. package/dist/cli/{chunk-rn1kwc71.js → chunk-t64hwtzt.js} +2 -2
  54. package/dist/cli/{chunk-q4qxhh4d.js → chunk-tnghx1kw.js} +1 -1
  55. package/dist/cli/chunk-vq6q30tg.js +8 -0
  56. package/dist/cli/{chunk-ncxfyfb5.js → chunk-vrzb7s42.js} +1 -1
  57. package/dist/cli/{chunk-3yd0ty84.js → chunk-wam8sr6a.js} +1 -1
  58. package/dist/cli/{chunk-pb4cc1vy.js → chunk-wd2k83dv.js} +3 -3
  59. package/dist/cli/{chunk-0xrdy726.js → chunk-wh734g12.js} +1 -1
  60. package/dist/cli/{chunk-dgt1yq74.js → chunk-wvwkmj3t.js} +1 -1
  61. package/dist/cli/{chunk-e3g79zpp.js → chunk-xt92ptzx.js} +1 -1
  62. package/dist/cli/index.js +7 -5
  63. package/dist/cli/pty-host-node.mjs +10 -1
  64. package/dist/cli/rove-run.js +1 -1
  65. package/dist/cli/rove.js +2 -2
  66. package/dist/skills/rove/SKILL.md +3 -3
  67. package/dist/skills/rove/references/api-flags.md +2 -2
  68. package/package.json +2 -2
  69. package/dist/cli/chunk-q0av0rvg.js +0 -9
  70. package/dist/cli/chunk-t3682s5j.js +0 -3
  71. package/dist/cli/chunk-t6zw81pp.js +0 -8
  72. package/dist/cli/chunk-x1d1mq5c.js +0 -3
  73. package/dist/cli/chunk-xnn96zvb.js +0 -3
  74. package/dist/cli/chunk-yexx8nec.js +0 -3
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{buildEngineSessionLaunch,trustEngineWorktree}from"./chunk-zh6fadgw.js";import{engineForkArgv,engineResumeArgv,withPinnedSessionId}from"./chunk-qdfxk8pt.js";import{engineEntry,engineStatusPrefixes,isEnginePlaceholderTitle,stripEngineStatusPrefix}from"./chunk-gpan2g7d.js";import{tildify}from"./chunk-ag3txfg2.js";import{t}from"./chunk-dgt1yq74.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";function engineTabArgv(tab,base,live,fallbackVendor){if(tab.forkFrom&&!tab.spawned&&!live){let forked=tab.vendor?engineForkArgv(base,tab.vendor,tab.forkFrom,tab.sessionId??null):null;if(forked)return forked}if(!tab.sessionId)return base;let vendor=tab.vendor??fallbackVendor;if(tab.spawned&&!live)return engineResumeArgv(base,vendor,tab.sessionId)??base;return withPinnedSessionId(base,vendor,()=>tab.sessionId).argv}function engineTabSpawnFor(state,tab,base,opts){let{live,shell,prompt}=opts,firstEngine=state.tabs.find((t2)=>t2.kind==="engine"),fresh=!tab.spawned&&!live,tabPrompt=fresh?tab.initialPrompt?.trim():void 0,wantsPrompt=!!prompt&&tab.id===firstEngine?.id&&fresh,isFreshFirstEngine=tab.id===firstEngine?.id&&fresh,promptIntent=tabPrompt?{kind:"explicit",prompt:tabPrompt}:wantsPrompt?{kind:"new-task",prompt}:isFreshFirstEngine?{kind:"repo-init"}:{kind:"none"},ref=tab.ptyTask;trustEngineWorktree(tab.vendor??opts.task.vendor,ref?.worktree??opts.worktreePath);let launch=buildEngineSessionLaunch({task:ref?{...opts.task,id:ref.id,kind:"task"}:opts.task,worktreePath:ref?.worktree??opts.worktreePath,shell,argv:engineTabArgv(tab,base,live,opts.task.vendor),promptIntent,protocolGates:opts.protocolGates,inlineImages:opts.inlineImages,tabId:ref?"tab-1":tab.id});return{command:launch.command,...launch.firstMessage?{firstMessage:launch.firstMessage,engineBin:base[0]}:{}}}function tabExitAction(tab,deadOnAttach,resumeTried){if(tab.kind==="engine"&&deadOnAttach&&!!tab.sessionId&&tab.spawned&&!resumeTried)return"resume";return"close"}import*as fs from"fs";import*as os from"os";function pathLeaf(p){return p.slice(lastSeparator(p)+1)}function lastSeparator(p){return pathSyntax(p).sep==="\\"||process.platform==="win32"&&!p.startsWith("/")?Math.max(p.lastIndexOf("/"),p.lastIndexOf("\\")):p.lastIndexOf("/")}function expandHome(p){if(p==="~")return os.homedir();if(p.startsWith("~/")||process.platform==="win32"&&p.startsWith("~\\"))return os.homedir()+p.slice(1);return p}function stripTrailingSlash(p){let root=pathSyntax(p).parse(p).root,end=p.length;while(end>root.length&&lastSeparator(p.slice(0,end))===end-1)end--;return p.slice(0,end)}function splitPathForDirSuggest(value){if(!value)return{base:"",filter:""};let expanded=expandHome(value==="~"?"~/":value),lastSlash=lastSeparator(expanded);if(lastSlash===-1)return{base:"",filter:expanded};return{base:expanded.slice(0,lastSlash+1),filter:expanded.slice(lastSlash+1)}}function listSubdirs(base){if(!base)return[];try{let entries=fs.readdirSync(base,{withFileTypes:!0}),out=[];for(let e of entries)if(e.isDirectory())out.push(e.name);return out.sort((a,b)=>a.localeCompare(b))}catch{return[]}}function filterSubdirs(all,filter){let f=filter.toLowerCase(),visible=f.startsWith(".")?all:all.filter((n)=>!n.startsWith("."));if(!f)return visible;return visible.filter((n)=>n.toLowerCase().startsWith(f))}function joinDrill(typedValue,baseExpanded,name){let out=`${baseExpanded+name}/`;if(typedValue.startsWith("~")){let short=tildify(out);if(short.startsWith("~"))return short==="~"?"~/":`${short}/`}return out}function joinPicked(typedValue,baseExpanded,name){let out=baseExpanded+name;if(typedValue.startsWith("~"))return tildify(out);return out}function depth(node){return node.kind==="leaf"?0:1+Math.max(...node.children.map(depth))}function siblingCount(root,id,orientation){let find=(node)=>{if(node.kind==="leaf")return null;if(node.orientation===orientation&&node.children.some((c)=>c.kind==="leaf"&&c.id===id))return node.children.length;for(let child of node.children){let n=find(child);if(n!==null)return n}return null};return find(root)??1}function splitFits(state,orientation,activeSize){let extent=orientation==="row"?activeSize.cols:activeSize.rows,min=orientation==="row"?20:6,n=siblingCount(state.root,state.activeLeafId,orientation);return Math.floor(extent*n/(n+1))-1>=min}function initialSplit(content){return{root:{kind:"leaf",id:"leaf-1",content},activeLeafId:"leaf-1",nextOrdinal:2}}function leaves(node){return node.kind==="leaf"?[node]:node.children.flatMap(leaves)}function splitActive(state,orientation,content,activeSize){if(activeSize&&!splitFits(state,orientation,activeSize))return state;let leaf={kind:"leaf",id:`leaf-${state.nextOrdinal}`,content},insert=(node)=>{if(node.kind==="leaf"){if(node.id!==state.activeLeafId)return node;return{kind:"group",orientation,children:[node,leaf]}}if(node.orientation===orientation){let i=node.children.findIndex((c)=>c.kind==="leaf"&&c.id===state.activeLeafId);if(i>=0){let children=[...node.children.slice(0,i+1),leaf,...node.children.slice(i+1)];return{...node,children}}}return{...node,children:node.children.map(insert)}},root=insert(state.root);if(!activeSize&&depth(root)>4)return state;return{root,activeLeafId:leaf.id,nextOrdinal:state.nextOrdinal+1}}function removeLeaf(state,id){let all=leaves(state.root);if(all.length<=1)return null;let prune=(node)=>{if(node.kind==="leaf")return node.id===id?null:node;let children=node.children.map(prune).filter((c)=>c!==null);if(children.length===0)return null;if(children.length===1)return children[0];return{...node,children}},root=prune(state.root);if(root===null)return null;if(leaves(root).length===all.length)return state;let order=all.map((l)=>l.id),removedIdx=order.indexOf(id),fallback=order[removedIdx>0?removedIdx-1:removedIdx+1],activeLeafId=state.activeLeafId===id?fallback:state.activeLeafId;return{...state,root,activeLeafId}}function renameLeaf(state,id,title){let trimmed=title.trim(),next=trimmed.length>0?trimmed:null,walk=(node)=>node.kind==="leaf"?node.id===id?{...node,title:next}:node:{...node,children:node.children.map(walk)};if(!leaves(state.root).some((l)=>l.id===id))return state;return{...state,root:walk(state.root)}}function cycleLeaf(state,delta){let order=leaves(state.root).map((l)=>l.id);if(order.length<=1)return state;let i=order.indexOf(state.activeLeafId),next=order[(i+delta+order.length)%order.length];return{...state,activeLeafId:next}}function hasEngineLeaf(tree){return!tree||leaves(tree.root).some((l)=>l.id==="leaf-1")}function isTabSplit(tree){return tree?leaves(tree.root).length>1:!1}function collapseSplit(next){let ls=leaves(next.root);return ls.length===1&&ls[0]?.id==="leaf-1"?null:next}function splitLeafPtyKey(tabKey,leafId){return leafId==="leaf-1"?tabKey:`${tabKey}::${leafId}`}var SHELL_LEAF_NAME="shell";function splitLeafNames(leafList,tabCommand,engineTitle,liveTitles){let basename=(argv)=>{let head=(argv??tabCommand)[0]??"",name=pathLeaf(head);return name.length>0?name:"?"},seen=new Map,out=new Map;for(let leaf of leafList){if(leaf.title){out.set(leaf.id,leaf.title);continue}let name=leaf.content===null?engineTitle||liveTitles?.get(leaf.id)||basename(leaf.content):liveTitles?.get(leaf.id)||SHELL_LEAF_NAME,n=(seen.get(name)??0)+1;seen.set(name,n),out.set(leaf.id,n===1?name:`${name} ${n}`)}return out}function meaningfulAutoTitle(autoTitle){let trimmed=(autoTitle??"").trim();if(trimmed.length<3)return null;if(/^[\d\s\p{P}\p{S}]+$/u.test(trimmed))return null;return trimmed}function stableRecordedTitle(raw,vendor){let recorded=raw?.trim();if(!recorded)return null;let cleaned=stripEngineStatusPrefix(recorded,vendor);if(cleaned===recorded&&isEngineDecoration(recorded,vendor))return null;if(isEnginePlaceholderTitle(cleaned,vendor))return null;return cleaned||null}function isEngineDecoration(text,vendor){let glyphs=new Set(engineStatusPrefixes(vendor));return[...text].every((ch)=>ch.trim().length===0||glyphs.has(ch))}function tabTitleStable(tab,taskVendor,liveVendor,liveTitle){if(liveVendor===null&&tab.kind==="engine")return tabTitle({...tab,kind:"command",lastTitle:null},taskVendor);let vendor=liveVendor??tab.liveVendor??(tab.kind==="engine"?tab.vendor??taskVendor:void 0)??void 0,source=liveTitle?.trim()||tab.lastTitle,named=vendor?stableRecordedTitle(source,vendor):source??null;if(!vendor||engineEntry(vendor).terminalTitle?.ownsStatus!==!0)return tabTitle({...tab,...vendor?{kind:"engine",vendor}:{},lastTitle:named},taskVendor);return tabTitle({...tab,kind:"engine",vendor,lastTitle:named},taskVendor)}function titleVendor(tab,taskVendor){return tab.liveVendor??(tab.kind==="engine"?tab.vendor:void 0)??taskVendor}function tabTitle(tab,taskVendor,liveName){if(tab.title)return tab.title;let ls=tab.splitTree?leaves(tab.splitTree.root):[];if(ls.length>1)return t("terminal.tab.groupTitle",{n:tab.ordinal});let sole=ls.length===1?ls[0]:void 0;if(sole&&sole.id!=="leaf-1")return sole.title??`${liveName??SHELL_LEAF_NAME} ${tab.ordinal}`;let vendor=titleVendor(tab,taskVendor);if(liveName&&!isEnginePlaceholderTitle(liveName,vendor))return`${liveName} ${tab.ordinal}`;if(tab.lastTitle&&!isEnginePlaceholderTitle(tab.lastTitle,vendor))return`${tab.lastTitle} ${tab.ordinal}`;let auto=meaningfulAutoTitle(tab.autoTitle);if(auto)return auto;return`${tab.kind==="engine"?engineEntry(tab.vendor??taskVendor).defaultCommand[0]??SHELL_LEAF_NAME:SHELL_LEAF_NAME} ${tab.ordinal}`}function visibleNativeStatus(tab,taskVendor,vendor,liveName){if(!vendor||!liveName)return!1;if(engineEntry(vendor).terminalTitle?.ownsStatus!==!0)return!1;return tabTitle(tab,taskVendor,liveName)===`${liveName} ${tab.ordinal}`}function initialTabs(){return{tabs:[{kind:"engine",id:"tab-1",title:null,ordinal:1}],activeId:"tab-1",nextOrdinal:2}}function reopenHintFor(closed){if(closed?.kind==="command")return{kind:"command"};if(closed?.kind==="engine"&&closed.vendor)return{kind:"engine",vendor:closed.vendor};return{kind:"engine"}}function reopenTabs(state,shell){let ordinal=state.nextOrdinal,id=`tab-${ordinal}`,next=state.nextOrdinal+1;if(state.reopenAs?.kind==="command")return{tabs:[{kind:"command",id,title:null,ordinal,command:[shell]}],activeId:id,nextOrdinal:next};let vendor=state.reopenAs?.kind==="engine"?state.reopenAs.vendor:void 0;return{tabs:[{kind:"engine",id,title:null,ordinal,...vendor?{vendor}:{}}],activeId:id,nextOrdinal:next}}function initialShellTabs(shell){return{tabs:[{kind:"command",id:"tab-1",title:null,ordinal:1,command:[shell]}],activeId:"tab-1",nextOrdinal:2}}function rehydrateTabs(persisted,shell,opts={}){let tabs=persisted.tabs.map((t2)=>t2.kind==="command"?{...t2,command:shell,purpose:void 0}:t2);if(tabs.length===0)return opts.allowEmpty?persisted:initialTabs();let activeId=tabs.some((t2)=>t2.id===persisted.activeId)?persisted.activeId:tabs[0].id,maxOrdinal=tabs.reduce((max,t2)=>Math.max(max,t2.ordinal),0);return{tabs,activeId,nextOrdinal:Math.max(persisted.nextOrdinal,maxOrdinal+1)}}function recycleTabs(state,prev){let ordinal=state.nextOrdinal,id=`tab-${ordinal}`,pinned=prev.kind==="engine"?prev:void 0;return{tabs:[{kind:"engine",id,ordinal,title:prev.title,autoTitle:prev.autoTitle,...pinned?.vendor?{vendor:pinned.vendor}:{},...pinned?.engineCommand?{engineCommand:pinned.engineCommand}:{}}],activeId:id,nextOrdinal:ordinal+1}}var SHELL_SAFE_ARG=/^[A-Za-z0-9@%+=:,./_-]+$/;function shellCommandLine(argv){return argv.map((a)=>SHELL_SAFE_ARG.test(a)?a:`'${a.replaceAll("'","'\\''")}'`).join(" ")}function shellIdentityInput(taskId,tabId){let task=shellCommandLine([taskId]),tab=shellCommandLine([tabId]);return` export ROVE_TASK_ID=${task} ROVE_TAB_ID=${tab} && clear\r`}function insertAfterActive(state,tab){let i=state.tabs.findIndex((t2)=>t2.id===state.activeId);return{tabs:[...state.tabs.slice(0,i+1),tab,...state.tabs.slice(i+1)],activeId:tab.id,nextOrdinal:state.nextOrdinal+1}}function addTab(state,vendor){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"engine",id:`tab-${ordinal}`,title:null,ordinal,vendor})}function openCommandTab(state,command,label){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"command",id:`tab-${ordinal}`,title:label,ordinal,command})}function findEditorTab(state){return state.tabs.find((tab)=>tab.kind==="command"&&tab.purpose==="editor")}function openEditorTab(state,command,label){let existing=findEditorTab(state);if(!existing){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"command",id:`tab-${ordinal}`,title:label,ordinal,command,purpose:"editor"})}let tabs=state.tabs.map((tab)=>tab.id===existing.id?{...existing,title:label,command,splitTree:null}:tab);return{...state,tabs,activeId:existing.id}}function findContentTab(state){return state.tabs.find((tab)=>tab.kind==="content")}function openContentTab(state,relPath,label,base){let existing=findContentTab(state);if(!existing){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"content",id:`tab-${ordinal}`,title:label,ordinal,relPath,base})}let tabs=state.tabs.map((tab)=>tab.id===existing.id?{...existing,title:label,relPath,base}:tab);return{...state,tabs,activeId:existing.id}}function closeTab(state,id,opts={}){if(state.tabs.length<=1&&!opts.allowEmpty)return{state,closedId:null};let i=state.tabs.findIndex((t2)=>t2.id===id);if(i<0)return{state,closedId:null};let tabs=state.tabs.filter((t2)=>t2.id!==id);if(state.activeId!==id)return{state:{...state,tabs},closedId:id};if(tabs.length===0)return{state:{...state,tabs,activeId:id,reopenAs:reopenHintFor(state.tabs[i])},closedId:id};let next=tabs[Math.max(0,i-1)];return{state:{...state,tabs,activeId:(next??tabs[0]).id},closedId:id}}function closeActiveTab(state){return closeTab(state,state.activeId)}function renameActiveTab(state,title){return setTabTitle(state,state.activeId,title)}function setTabTitle(state,id,title){let trimmed=title.trim(),next=trimmed.length>0?trimmed:null,current=state.tabs.find((t2)=>t2.id===id);if(!current||(current.title??null)===next)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,title:next}:t2);return{...state,tabs}}function setTabSessionId(state,id,sessionId){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,sessionId}:t2);return{...state,tabs}}function setTabForkFrom(state,id,sourceSessionId){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,forkFrom:sourceSessionId}:t2);return{...state,tabs}}function setTabEngineCommand(state,id,command){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,engineCommand:command}:t2);return{...state,tabs}}function setTabInitialPrompt(state,id,prompt){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,initialPrompt:prompt}:t2);return{...state,tabs}}function setTabLastTitle(state,id,lastTitle){if(lastTitle.length===0)return state;let current=state.tabs.find((t2)=>t2.id===id);if(!current||current.lastTitle===lastTitle)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,lastTitle}:t2);return{...state,tabs}}function setTabLiveVendor(state,id,liveVendor){let current=state.tabs.find((t2)=>t2.id===id);if(!current||(current.liveVendor??null)===liveVendor)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,liveVendor}:t2);return{...state,tabs}}function setTabAutoTitle(state,id,autoTitle){let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,autoTitle}:t2);return{...state,tabs}}function setTabSpawned(state,id,spawned){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"&&!t2.spawned!==!spawned?{...t2,spawned}:t2);return{...state,tabs}}function cycleTab(state,delta){let n=state.tabs.length;if(n<=1)return state;let i=state.tabs.findIndex((t2)=>t2.id===state.activeId),next=state.tabs[(i+delta+n)%n];return{...state,activeId:next.id}}function gotoTab(state,index){let target=state.tabs[index];return target&&target.id!==state.activeId?{...state,activeId:target.id}:state}function moveTab(state,id,delta){let i=state.tabs.findIndex((t2)=>t2.id===id),j=i+delta;if(i<0||j<0||j>=state.tabs.length)return state;let tabs=[...state.tabs],a=tabs[i];return tabs[i]=tabs[j],tabs[j]=a,{...state,tabs}}function selectTab(state,id){if(state.activeId===id||!state.tabs.some((t2)=>t2.id===id))return state;return{...state,activeId:id}}function setTabSplit(state,id,tree){if(!state.tabs.some((t2)=>t2.id===id))return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,splitTree:tree}:t2);return{...state,tabs}}function tabPtyKey(taskId,tabId){return`${taskId}::${tabId}`}function tabPtyKeyFor(taskId,tab){if(tab.kind==="engine"&&tab.ptyTask)return tabPtyKey(tab.ptyTask.id,"tab-1");return tabPtyKey(taskId,tab.id)}function tabCwdFor(tab,taskWorktree){if(tab.kind==="engine"&&tab.ptyTask)return tab.ptyTask.worktree;return taskWorktree}function terminalTabsKey(taskId){return`terminalTabs.${taskId}`}function forgetTaskTabsSnapshot(kv,taskId){let key=terminalTabsKey(taskId);if(kv.store[key]===void 0)return;kv.set(key,void 0)}function sweepOrphanTabsSnapshots(kv,liveTaskIds){let live=new Set(liveTaskIds),swept=0;for(let key of Object.keys(kv.store)){if(!key.startsWith("terminalTabs."))continue;let taskId=key.slice(13);if(live.has(taskId))continue;kv.set(key,void 0),swept++}return swept}
3
- export{pathLeaf,expandHome,stripTrailingSlash,splitPathForDirSuggest,listSubdirs,filterSubdirs,joinDrill,joinPicked,initialSplit,leaves,splitActive,removeLeaf,renameLeaf,cycleLeaf,hasEngineLeaf,isTabSplit,collapseSplit,splitLeafPtyKey,splitLeafNames,tabTitleStable,tabTitle,visibleNativeStatus,initialTabs,reopenTabs,initialShellTabs,rehydrateTabs,recycleTabs,engineTabArgv,engineTabSpawnFor,tabExitAction,shellIdentityInput,addTab,openCommandTab,findEditorTab,openEditorTab,openContentTab,closeTab,closeActiveTab,renameActiveTab,setTabTitle,setTabSessionId,setTabForkFrom,setTabEngineCommand,setTabInitialPrompt,setTabLastTitle,setTabLiveVendor,setTabAutoTitle,setTabSpawned,cycleTab,gotoTab,moveTab,selectTab,setTabSplit,tabPtyKey,tabPtyKeyFor,tabCwdFor,terminalTabsKey,forgetTaskTabsSnapshot,sweepOrphanTabsSnapshots};
2
+ import{buildEngineSessionLaunch,trustEngineWorktree}from"./chunk-e5k2j2x8.js";import{engineForkArgv,engineResumeArgv,withPinnedSessionId}from"./chunk-4r3s1z14.js";import{engineEntry,engineStatusPrefixes,isEnginePlaceholderTitle,stripEngineStatusPrefix}from"./chunk-ctmbj2y3.js";import{tildify}from"./chunk-ag3txfg2.js";import{t}from"./chunk-wvwkmj3t.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";function engineTabArgv(tab,base,live,fallbackVendor){if(tab.forkFrom&&!tab.spawned&&!live){let forked=tab.vendor?engineForkArgv(base,tab.vendor,tab.forkFrom,tab.sessionId??null):null;if(forked)return forked}if(!tab.sessionId)return base;let vendor=tab.vendor??fallbackVendor;if(tab.spawned&&!live)return engineResumeArgv(base,vendor,tab.sessionId)??base;return withPinnedSessionId(base,vendor,()=>tab.sessionId).argv}function engineTabSpawnFor(state,tab,base,opts){let{live,shell,prompt}=opts,firstEngine=state.tabs.find((t2)=>t2.kind==="engine"),fresh=!tab.spawned&&!live,tabPrompt=fresh?tab.initialPrompt?.trim():void 0,wantsPrompt=!!prompt&&tab.id===firstEngine?.id&&fresh,isFreshFirstEngine=tab.id===firstEngine?.id&&fresh,promptIntent=tabPrompt?{kind:"explicit",prompt:tabPrompt}:wantsPrompt?{kind:"new-task",prompt}:isFreshFirstEngine?{kind:"repo-init"}:{kind:"none"},ref=tab.ptyTask;trustEngineWorktree(tab.vendor??opts.task.vendor,ref?.worktree??opts.worktreePath);let launch=buildEngineSessionLaunch({task:ref?{...opts.task,id:ref.id,kind:"task"}:opts.task,worktreePath:ref?.worktree??opts.worktreePath,shell,argv:engineTabArgv(tab,base,live,opts.task.vendor),promptIntent,protocolGates:opts.protocolGates,inlineImages:opts.inlineImages,tabId:ref?"tab-1":tab.id});return{command:launch.command,...launch.firstMessage?{firstMessage:launch.firstMessage,engineBin:base[0]}:{}}}function tabExitAction(tab,deadOnAttach,resumeTried){if(tab.kind==="engine"&&deadOnAttach&&!!tab.sessionId&&tab.spawned&&!resumeTried)return"resume";return"close"}import*as fs from"fs";import*as os from"os";function pathLeaf(p){return p.slice(lastSeparator(p)+1)}function lastSeparator(p){return pathSyntax(p).sep==="\\"||process.platform==="win32"&&!p.startsWith("/")?Math.max(p.lastIndexOf("/"),p.lastIndexOf("\\")):p.lastIndexOf("/")}function expandHome(p){if(p==="~")return os.homedir();if(p.startsWith("~/")||process.platform==="win32"&&p.startsWith("~\\"))return os.homedir()+p.slice(1);return p}function stripTrailingSlash(p){let root=pathSyntax(p).parse(p).root,end=p.length;while(end>root.length&&lastSeparator(p.slice(0,end))===end-1)end--;return p.slice(0,end)}function splitPathForDirSuggest(value){if(!value)return{base:"",filter:""};let expanded=expandHome(value==="~"?"~/":value),lastSlash=lastSeparator(expanded);if(lastSlash===-1)return{base:"",filter:expanded};return{base:expanded.slice(0,lastSlash+1),filter:expanded.slice(lastSlash+1)}}function listSubdirs(base){if(!base)return[];try{let entries=fs.readdirSync(base,{withFileTypes:!0}),out=[];for(let e of entries)if(e.isDirectory())out.push(e.name);return out.sort((a,b)=>a.localeCompare(b))}catch{return[]}}function filterSubdirs(all,filter){let f=filter.toLowerCase(),visible=f.startsWith(".")?all:all.filter((n)=>!n.startsWith("."));if(!f)return visible;return visible.filter((n)=>n.toLowerCase().startsWith(f))}function joinDrill(typedValue,baseExpanded,name){let out=`${baseExpanded+name}/`;if(typedValue.startsWith("~")){let short=tildify(out);if(short.startsWith("~"))return short==="~"?"~/":`${short}/`}return out}function joinPicked(typedValue,baseExpanded,name){let out=baseExpanded+name;if(typedValue.startsWith("~"))return tildify(out);return out}function depth(node){return node.kind==="leaf"?0:1+Math.max(...node.children.map(depth))}function siblingCount(root,id,orientation){let find=(node)=>{if(node.kind==="leaf")return null;if(node.orientation===orientation&&node.children.some((c)=>c.kind==="leaf"&&c.id===id))return node.children.length;for(let child of node.children){let n=find(child);if(n!==null)return n}return null};return find(root)??1}function splitFits(state,orientation,activeSize){let extent=orientation==="row"?activeSize.cols:activeSize.rows,min=orientation==="row"?20:6,n=siblingCount(state.root,state.activeLeafId,orientation);return Math.floor(extent*n/(n+1))-1>=min}function initialSplit(content){return{root:{kind:"leaf",id:"leaf-1",content},activeLeafId:"leaf-1",nextOrdinal:2}}function leaves(node){return node.kind==="leaf"?[node]:node.children.flatMap(leaves)}function splitActive(state,orientation,content,activeSize){if(activeSize&&!splitFits(state,orientation,activeSize))return state;let leaf={kind:"leaf",id:`leaf-${state.nextOrdinal}`,content},insert=(node)=>{if(node.kind==="leaf"){if(node.id!==state.activeLeafId)return node;return{kind:"group",orientation,children:[node,leaf]}}if(node.orientation===orientation){let i=node.children.findIndex((c)=>c.kind==="leaf"&&c.id===state.activeLeafId);if(i>=0){let children=[...node.children.slice(0,i+1),leaf,...node.children.slice(i+1)];return{...node,children}}}return{...node,children:node.children.map(insert)}},root=insert(state.root);if(!activeSize&&depth(root)>4)return state;return{root,activeLeafId:leaf.id,nextOrdinal:state.nextOrdinal+1}}function removeLeaf(state,id){let all=leaves(state.root);if(all.length<=1)return null;let prune=(node)=>{if(node.kind==="leaf")return node.id===id?null:node;let children=node.children.map(prune).filter((c)=>c!==null);if(children.length===0)return null;if(children.length===1)return children[0];return{...node,children}},root=prune(state.root);if(root===null)return null;if(leaves(root).length===all.length)return state;let order=all.map((l)=>l.id),removedIdx=order.indexOf(id),fallback=order[removedIdx>0?removedIdx-1:removedIdx+1],activeLeafId=state.activeLeafId===id?fallback:state.activeLeafId;return{...state,root,activeLeafId}}function renameLeaf(state,id,title){let trimmed=title.trim(),next=trimmed.length>0?trimmed:null,walk=(node)=>node.kind==="leaf"?node.id===id?{...node,title:next}:node:{...node,children:node.children.map(walk)};if(!leaves(state.root).some((l)=>l.id===id))return state;return{...state,root:walk(state.root)}}function cycleLeaf(state,delta){let order=leaves(state.root).map((l)=>l.id);if(order.length<=1)return state;let i=order.indexOf(state.activeLeafId),next=order[(i+delta+order.length)%order.length];return{...state,activeLeafId:next}}function hasEngineLeaf(tree){return!tree||leaves(tree.root).some((l)=>l.id==="leaf-1")}function isTabSplit(tree){return tree?leaves(tree.root).length>1:!1}function collapseSplit(next){let ls=leaves(next.root);return ls.length===1&&ls[0]?.id==="leaf-1"?null:next}function splitLeafPtyKey(tabKey,leafId){return leafId==="leaf-1"?tabKey:`${tabKey}::${leafId}`}var SHELL_LEAF_NAME="shell";function splitLeafNames(leafList,tabCommand,engineTitle,liveTitles){let basename=(argv)=>{let head=(argv??tabCommand)[0]??"",name=pathLeaf(head);return name.length>0?name:"?"},seen=new Map,out=new Map;for(let leaf of leafList){if(leaf.title){out.set(leaf.id,leaf.title);continue}let name=leaf.content===null?engineTitle||liveTitles?.get(leaf.id)||basename(leaf.content):liveTitles?.get(leaf.id)||SHELL_LEAF_NAME,n=(seen.get(name)??0)+1;seen.set(name,n),out.set(leaf.id,n===1?name:`${name} ${n}`)}return out}function meaningfulAutoTitle(autoTitle){let trimmed=(autoTitle??"").trim();if(trimmed.length<3)return null;if(/^[\d\s\p{P}\p{S}]+$/u.test(trimmed))return null;return trimmed}function stableRecordedTitle(raw,vendor){let recorded=raw?.trim();if(!recorded)return null;let cleaned=stripEngineStatusPrefix(recorded,vendor);if(cleaned===recorded&&isEngineDecoration(recorded,vendor))return null;if(isEnginePlaceholderTitle(cleaned,vendor))return null;return cleaned||null}function isEngineDecoration(text,vendor){let glyphs=new Set(engineStatusPrefixes(vendor));return[...text].every((ch)=>ch.trim().length===0||glyphs.has(ch))}function tabTitleStable(tab,taskVendor,liveVendor,liveTitle){if(liveVendor===null&&tab.kind==="engine")return tabTitle({...tab,kind:"command",lastTitle:null},taskVendor);let vendor=liveVendor??tab.liveVendor??(tab.kind==="engine"?tab.vendor??taskVendor:void 0)??void 0,source=liveTitle?.trim()||tab.lastTitle,named=vendor?stableRecordedTitle(source,vendor):source??null;if(!vendor||engineEntry(vendor).terminalTitle?.ownsStatus!==!0)return tabTitle({...tab,...vendor?{kind:"engine",vendor}:{},lastTitle:named},taskVendor);return tabTitle({...tab,kind:"engine",vendor,lastTitle:named},taskVendor)}function titleVendor(tab,taskVendor){return tab.liveVendor??(tab.kind==="engine"?tab.vendor:void 0)??taskVendor}function tabTitle(tab,taskVendor,liveName){if(tab.title)return tab.title;let ls=tab.splitTree?leaves(tab.splitTree.root):[];if(ls.length>1)return t("terminal.tab.groupTitle",{n:tab.ordinal});let sole=ls.length===1?ls[0]:void 0;if(sole&&sole.id!=="leaf-1")return sole.title??`${liveName??SHELL_LEAF_NAME} ${tab.ordinal}`;let vendor=titleVendor(tab,taskVendor);if(liveName&&!isEnginePlaceholderTitle(liveName,vendor))return`${liveName} ${tab.ordinal}`;if(tab.lastTitle&&!isEnginePlaceholderTitle(tab.lastTitle,vendor))return`${tab.lastTitle} ${tab.ordinal}`;let auto=meaningfulAutoTitle(tab.autoTitle);if(auto)return auto;return`${tab.kind==="engine"?engineEntry(tab.vendor??taskVendor).defaultCommand[0]??SHELL_LEAF_NAME:SHELL_LEAF_NAME} ${tab.ordinal}`}function visibleNativeStatus(tab,taskVendor,vendor,liveName){if(!vendor||!liveName)return!1;if(engineEntry(vendor).terminalTitle?.ownsStatus!==!0)return!1;return tabTitle(tab,taskVendor,liveName)===`${liveName} ${tab.ordinal}`}function initialTabs(){return{tabs:[{kind:"engine",id:"tab-1",title:null,ordinal:1}],activeId:"tab-1",nextOrdinal:2}}function reopenHintFor(closed){if(closed?.kind==="command")return{kind:"command"};if(closed?.kind==="engine"&&closed.vendor)return{kind:"engine",vendor:closed.vendor};return{kind:"engine"}}function reopenTabs(state,shell){let ordinal=state.nextOrdinal,id=`tab-${ordinal}`,next=state.nextOrdinal+1;if(state.reopenAs?.kind==="command")return{tabs:[{kind:"command",id,title:null,ordinal,command:[shell]}],activeId:id,nextOrdinal:next};let vendor=state.reopenAs?.kind==="engine"?state.reopenAs.vendor:void 0;return{tabs:[{kind:"engine",id,title:null,ordinal,...vendor?{vendor}:{}}],activeId:id,nextOrdinal:next}}function initialShellTabs(shell){return{tabs:[{kind:"command",id:"tab-1",title:null,ordinal:1,command:[shell]}],activeId:"tab-1",nextOrdinal:2}}function rehydrateTabs(persisted,shell,opts={}){let tabs=persisted.tabs.map((t2)=>t2.kind==="command"?{...t2,command:shell,purpose:void 0}:t2);if(tabs.length===0)return opts.allowEmpty?persisted:initialTabs();let activeId=tabs.some((t2)=>t2.id===persisted.activeId)?persisted.activeId:tabs[0].id,maxOrdinal=tabs.reduce((max,t2)=>Math.max(max,t2.ordinal),0);return{tabs,activeId,nextOrdinal:Math.max(persisted.nextOrdinal,maxOrdinal+1)}}function recycleTabs(state,prev){let ordinal=state.nextOrdinal,id=`tab-${ordinal}`,pinned=prev.kind==="engine"?prev:void 0;return{tabs:[{kind:"engine",id,ordinal,title:prev.title,autoTitle:prev.autoTitle,...pinned?.vendor?{vendor:pinned.vendor}:{},...pinned?.engineCommand?{engineCommand:pinned.engineCommand}:{}}],activeId:id,nextOrdinal:ordinal+1}}var SHELL_SAFE_ARG=/^[A-Za-z0-9@%+=:,./_-]+$/;function shellCommandLine(argv){return argv.map((a)=>SHELL_SAFE_ARG.test(a)?a:`'${a.replaceAll("'","'\\''")}'`).join(" ")}function shellIdentityInput(taskId,tabId){let task=shellCommandLine([taskId]),tab=shellCommandLine([tabId]);return` export ROVE_TASK_ID=${task} ROVE_TAB_ID=${tab} && clear\r`}function insertAfterActive(state,tab){let i=state.tabs.findIndex((t2)=>t2.id===state.activeId);return{tabs:[...state.tabs.slice(0,i+1),tab,...state.tabs.slice(i+1)],activeId:tab.id,nextOrdinal:state.nextOrdinal+1}}function addTab(state,vendor){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"engine",id:`tab-${ordinal}`,title:null,ordinal,vendor})}function openCommandTab(state,command,label){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"command",id:`tab-${ordinal}`,title:label,ordinal,command})}function findEditorTab(state){return state.tabs.find((tab)=>tab.kind==="command"&&tab.purpose==="editor")}function openEditorTab(state,command,label){let existing=findEditorTab(state);if(!existing){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"command",id:`tab-${ordinal}`,title:label,ordinal,command,purpose:"editor"})}let tabs=state.tabs.map((tab)=>tab.id===existing.id?{...existing,title:label,command,splitTree:null}:tab);return{...state,tabs,activeId:existing.id}}function findContentTab(state){return state.tabs.find((tab)=>tab.kind==="content")}function openContentTab(state,relPath,label,base){let existing=findContentTab(state);if(!existing){let ordinal=state.nextOrdinal;return insertAfterActive(state,{kind:"content",id:`tab-${ordinal}`,title:label,ordinal,relPath,base})}let tabs=state.tabs.map((tab)=>tab.id===existing.id?{...existing,title:label,relPath,base}:tab);return{...state,tabs,activeId:existing.id}}function closeTab(state,id,opts={}){if(state.tabs.length<=1&&!opts.allowEmpty)return{state,closedId:null};let i=state.tabs.findIndex((t2)=>t2.id===id);if(i<0)return{state,closedId:null};let tabs=state.tabs.filter((t2)=>t2.id!==id);if(state.activeId!==id)return{state:{...state,tabs},closedId:id};if(tabs.length===0)return{state:{...state,tabs,activeId:id,reopenAs:reopenHintFor(state.tabs[i])},closedId:id};let next=tabs[Math.max(0,i-1)];return{state:{...state,tabs,activeId:(next??tabs[0]).id},closedId:id}}function closeActiveTab(state){return closeTab(state,state.activeId)}function renameActiveTab(state,title){return setTabTitle(state,state.activeId,title)}function setTabTitle(state,id,title){let trimmed=title.trim(),next=trimmed.length>0?trimmed:null,current=state.tabs.find((t2)=>t2.id===id);if(!current||(current.title??null)===next)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,title:next}:t2);return{...state,tabs}}function setTabSessionId(state,id,sessionId){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,sessionId}:t2);return{...state,tabs}}function setTabForkFrom(state,id,sourceSessionId){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,forkFrom:sourceSessionId}:t2);return{...state,tabs}}function setTabEngineCommand(state,id,command){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,engineCommand:command}:t2);return{...state,tabs}}function setTabInitialPrompt(state,id,prompt){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"?{...t2,initialPrompt:prompt}:t2);return{...state,tabs}}function setTabLastTitle(state,id,lastTitle){if(lastTitle.length===0)return state;let current=state.tabs.find((t2)=>t2.id===id);if(!current||current.lastTitle===lastTitle)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,lastTitle}:t2);return{...state,tabs}}function setTabLiveVendor(state,id,liveVendor){let current=state.tabs.find((t2)=>t2.id===id);if(!current||(current.liveVendor??null)===liveVendor)return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,liveVendor}:t2);return{...state,tabs}}function setTabAutoTitle(state,id,autoTitle){let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,autoTitle}:t2);return{...state,tabs}}function setTabSpawned(state,id,spawned){let tabs=state.tabs.map((t2)=>t2.id===id&&t2.kind==="engine"&&!t2.spawned!==!spawned?{...t2,spawned}:t2);return{...state,tabs}}function cycleTab(state,delta){let n=state.tabs.length;if(n<=1)return state;let i=state.tabs.findIndex((t2)=>t2.id===state.activeId),next=state.tabs[(i+delta+n)%n];return{...state,activeId:next.id}}function gotoTab(state,index){let target=state.tabs[index];return target&&target.id!==state.activeId?{...state,activeId:target.id}:state}function moveTab(state,id,delta){let i=state.tabs.findIndex((t2)=>t2.id===id),j=i+delta;if(i<0||j<0||j>=state.tabs.length)return state;let tabs=[...state.tabs],a=tabs[i];return tabs[i]=tabs[j],tabs[j]=a,{...state,tabs}}function selectTab(state,id){if(state.activeId===id||!state.tabs.some((t2)=>t2.id===id))return state;return{...state,activeId:id}}function setTabSplit(state,id,tree){if(!state.tabs.some((t2)=>t2.id===id))return state;let tabs=state.tabs.map((t2)=>t2.id===id?{...t2,splitTree:tree}:t2);return{...state,tabs}}function tabPtyKey(taskId,tabId){return`${taskId}::${tabId}`}function tabPtyKeyFor(taskId,tab){if(tab.kind==="engine"&&tab.ptyTask)return tabPtyKey(tab.ptyTask.id,"tab-1");return tabPtyKey(taskId,tab.id)}function tabCwdFor(tab,taskWorktree){if(tab.kind==="engine"&&tab.ptyTask)return tab.ptyTask.worktree;return taskWorktree}function terminalTabsKey(taskId){return`terminalTabs.${taskId}`}function forgetTaskTabsSnapshot(kv,taskId){let key=terminalTabsKey(taskId);if(kv.store[key]===void 0)return;kv.set(key,void 0)}function sweepOrphanTabsSnapshots(kv,liveTaskIds){let live=new Set(liveTaskIds),swept=0;for(let key of Object.keys(kv.store)){if(!key.startsWith("terminalTabs."))continue;let taskId=key.slice(13);if(live.has(taskId))continue;kv.set(key,void 0),swept++}return swept}
3
+ export{terminalTabsKey,forgetTaskTabsSnapshot,sweepOrphanTabsSnapshots,pathLeaf,expandHome,stripTrailingSlash,splitPathForDirSuggest,listSubdirs,filterSubdirs,joinDrill,joinPicked,initialSplit,leaves,splitActive,removeLeaf,renameLeaf,cycleLeaf,hasEngineLeaf,isTabSplit,collapseSplit,splitLeafPtyKey,splitLeafNames,tabTitleStable,tabTitle,visibleNativeStatus,initialTabs,reopenTabs,initialShellTabs,rehydrateTabs,recycleTabs,engineTabArgv,engineTabSpawnFor,tabExitAction,shellIdentityInput,addTab,openCommandTab,findEditorTab,openEditorTab,openContentTab,closeTab,closeActiveTab,renameActiveTab,setTabTitle,setTabSessionId,setTabForkFrom,setTabEngineCommand,setTabInitialPrompt,setTabLastTitle,setTabLiveVendor,setTabAutoTitle,setTabSpawned,cycleTab,gotoTab,moveTab,selectTab,setTabSplit,tabPtyKey,tabPtyKeyFor,tabCwdFor};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{publishRoveTerminalTitle}from"./chunk-3aqhytyy.js";import{ensureGlobalRoveHooks}from"./chunk-t6zw81pp.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-rqyaf0dw.js";import"./chunk-gpan2g7d.js";import"./chunk-k4374n9t.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-2brn8e1y.js";import"./chunk-yexx8nec.js";import"./chunk-znjcesdr.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import{takeWelcome}from"./chunk-cgt8wmd7.js";import{LAST_RUN_VERSION_KEY,enforceResetGate}from"./chunk-66cew8sb.js";import"./chunk-6ms5chc3.js";import"./chunk-e1x88j3k.js";import{CURRENT_VERSION,compareSemver}from"./chunk-6nk7h22s.js";import{maybeHintSkillInstall}from"./chunk-33dt8jkh.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import{loadStateFile,patchStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-dgt1yq74.js";import"./chunk-x1d1mq5c.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";var WHATS_NEW_SEEN_KEY="app.whatsNewSeenVersion";function whatsNewFromVersion(state,current=CURRENT_VERSION){let stamped=state[WHATS_NEW_SEEN_KEY]??state[LAST_RUN_VERSION_KEY];if(typeof stamped!=="string"||stamped.length===0)return null;return compareSemver(current,stamped)>0?stamped:null}function takeWhatsNew(){let from=whatsNewFromVersion(loadStateFile());try{patchStateFile({[WHATS_NEW_SEEN_KEY]:CURRENT_VERSION})}catch{}return from}async function startTui(){let whatsNewFrom=takeWhatsNew(),welcome=takeWelcome();enforceResetGate(),publishRoveTerminalTitle(),await maybeHintSkillInstall(),await ensureGlobalRoveHooks();let{loadPluginEngines}=await import("./chunk-sb2ardv3.js");loadPluginEngines();let{startWorkspaceHost}=await import("./chunk-8manew0x.js");await startWorkspaceHost({whatsNewFrom,welcome})}export{startTui};
2
+ import{publishRoveTerminalTitle}from"./chunk-3aqhytyy.js";import{ensureGlobalRoveHooks}from"./chunk-vq6q30tg.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-rqyaf0dw.js";import"./chunk-ctmbj2y3.js";import"./chunk-k4374n9t.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-2brn8e1y.js";import"./chunk-60fy3ckp.js";import"./chunk-znjcesdr.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import{takeWelcome}from"./chunk-4fgpzkaq.js";import{LAST_RUN_VERSION_KEY,enforceResetGate}from"./chunk-kjhhwhs4.js";import"./chunk-6ms5chc3.js";import"./chunk-e1x88j3k.js";import{CURRENT_VERSION,compareSemver}from"./chunk-8p579jct.js";import{maybeHintSkillInstall}from"./chunk-dbs8p34d.js";import"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import{loadStateFile,patchStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-wvwkmj3t.js";import"./chunk-jxyvk9c0.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";var WHATS_NEW_SEEN_KEY="app.whatsNewSeenVersion";function whatsNewFromVersion(state,current=CURRENT_VERSION){let stamped=state[WHATS_NEW_SEEN_KEY]??state[LAST_RUN_VERSION_KEY];if(typeof stamped!=="string"||stamped.length===0)return null;return compareSemver(current,stamped)>0?stamped:null}function takeWhatsNew(){let from=whatsNewFromVersion(loadStateFile());try{patchStateFile({[WHATS_NEW_SEEN_KEY]:CURRENT_VERSION})}catch{}return from}async function startTui(){let whatsNewFrom=takeWhatsNew(),welcome=takeWelcome();enforceResetGate(),publishRoveTerminalTitle(),await maybeHintSkillInstall(),await ensureGlobalRoveHooks();let{loadPluginEngines}=await import("./chunk-sb2ardv3.js");loadPluginEngines();let{startWorkspaceHost}=await import("./chunk-7j6escfh.js");await startWorkspaceHost({whatsNewFrom,welcome})}export{startTui};
@@ -0,0 +1,8 @@
1
+ // @bun
2
+ import{isEngineActivityKind}from"./chunk-17e2tgyg.js";import{loadPluginRegistry,readPluginManifest}from"./chunk-rqyaf0dw.js";import{activityHookAdapters}from"./chunk-ctmbj2y3.js";import{flagValue}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-96cjpssp.js";import{getPersistedString,setPersistedString}from"./chunk-h9cg0j3a.js";import{readRoveEnv}from"./chunk-nc46gddg.js";import{join,resolve}from"path";var STDIN_READ_TIMEOUT_MS=500;async function readTextWithTimeout(read,timeoutMs=STDIN_READ_TIMEOUT_MS){let raceTimer;try{return await Promise.race([read(),new Promise((resolve2)=>{raceTimer=setTimeout(()=>resolve2(""),timeoutMs)})])}finally{if(raceTimer!==void 0)clearTimeout(raceTimer)}}async function readStdinText(){let bun=globalThis.Bun;if(bun)return bun.stdin.text();if(process.stdin.isTTY)return"";let chunks=[];try{for await(let chunk of process.stdin)chunks.push(chunk)}finally{process.stdin.destroy()}return Buffer.concat(chunks).toString("utf8")}async function readStdinPayload(){try{let text=await readTextWithTimeout(readStdinText);if(!text.trim())return{};let parsed=JSON.parse(text);return parsed&&typeof parsed==="object"&&!Array.isArray(parsed)?parsed:{}}catch{return{}}}async function runHookSubcommand(argv){let[verb,...rest]=argv;if(verb==="setup"){await runHookSetup(rest);return}if(verb==="cleanup"){await runHookCleanup();return}try{if(!verb||!isEngineActivityKind(verb))return;let payload=await readStdinPayload(),payloadFlag=flagValue(rest,"--payload");if(payloadFlag)try{let extra=JSON.parse(payloadFlag);if(extra&&typeof extra==="object"&&!Array.isArray(extra))Object.assign(payload,extra)}catch{}let taskId=flagValue(rest,"--task-id"),envTaskId=process.env.ROVE_TASK_ID,envTabId=process.env.ROVE_TAB_ID,engine=flagValue(rest,"--engine"),adapters=activityHookAdapters().filter((a)=>!engine||a.vendor===engine);if(!taskId&&adapters.some((a)=>a.isUnattendedSession?.(process.env)===!0))return;let cwd=typeof payload.cwd==="string"&&payload.cwd?payload.cwd:void 0;for(let adapter of adapters){if(cwd)break;cwd=adapter.cwdFromPayload?.(payload)}cwd||=process.cwd();let detail;for(let adapter of adapters)if(detail=adapter.activityDetailFromPayload(verb,payload),detail)break;let session;for(let adapter of adapters)if(session=adapter.sessionFromPayload(payload),session)break;let client=await connectIfRunning();if(!client)return;try{let effectiveTaskId=taskId??envTaskId;await client.request("engine.reportEvent",{...effectiveTaskId?{taskId:effectiveTaskId}:{cwd},kind:verb,...engine?{engine}:{},...envTabId?{tabId:envTabId}:{},...detail?{detail}:{},...session?{sessionId:session.sessionId}:{},...session?.transcriptPath?{transcriptPath:session.transcriptPath}:{}})}finally{client.close()}}catch(err){if(readRoveEnv("HOOK_DEBUG"))console.error(`[rove hook] ${verb} failed:`,err instanceof Error?err.message:String(err))}}var SYNC_SETTING_KEY="externalWorktreeSync";function worktreeSyncAdapters(){return activityHookAdapters().filter((a)=>a.supportsWorktreeSync())}function globalSettingsPath(){return worktreeSyncAdapters()[0]?.globalSettingsPath()}function persistedSyncPath(stored){if(!stored||stored==="off")return;if(stored==="global")return globalSettingsPath();if(stored.startsWith("repo:"))return join(resolve(stored.slice(5)),".claude","settings.json");return stored}async function ensureGlobalRoveHooks(opts={}){try{let toolEvents=pluginsWantToolEvents();for(let a of activityHookAdapters()){let external=await a.externallyManagedHooks?.();if(external){if(external.notice)process.stderr.write(`
3
+ ${external.notice}
4
+ `);continue}let enginePath=a.globalSettingsPath();if(!enginePath)continue;await a.installActivityHooks(enginePath,{toolEvents,quiet:opts.quiet}),await a.removeWorktreeWatchHook(enginePath)}await cleanupWorktreeSyncHook()}catch{}}function pluginsWantToolEvents(){try{for(let entry of loadPluginRegistry().plugins){if(!entry.enabled)continue;try{if(readPluginManifest(entry.root).manifest.events.some((e)=>e.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function cleanupWorktreeSyncHook(){let adapters=worktreeSyncAdapters();if(adapters.length===0)return;let stored=getPersistedString(SYNC_SETTING_KEY),paths=new Set;for(let adapter of adapters){let file=adapter.globalSettingsPath();if(file)paths.add(file)}let prev=persistedSyncPath(stored);if(prev)paths.add(prev);for(let a of adapters)for(let p of paths)await a.removeWorktreeSyncHook(p);if(stored!=="off")setPersistedString(SYNC_SETTING_KEY,"off")}async function runHookCleanup(){let claude=activityHookAdapters().find((a)=>a.vendor==="claude"),path=claude?.globalSettingsPath();if(!claude||!path){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
5
+ `);return}await claude.removeActivityHooks(path),await claude.removeWorktreeWatchHook(path),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${path}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
6
+ `))}async function runHookSetup(_argv){await cleanupWorktreeSyncHook(),process.stdout.write(["rove hook setup is deprecated and now a no-op (cleanup only).","","The old external-worktree sync used a global WorktreeCreate hook, which is","a VCS provider hook \u2014 its presence broke `claude --worktree` / EnterWorktree","in every repo. Any hook Rove previously installed has been removed.","","Sync is now automatic: a `claude --worktree` (or any session) started in a","worktree under a repo Rove already tracks is adopted as a task on launch.","To adopt existing worktrees on demand, use the New Task dialog or `rove adopt`.",""].join(`
7
+ `))}
8
+ export{readTextWithTimeout,readStdinText,runHookSubcommand,ensureGlobalRoveHooks};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CURRENT_VERSION,repoSlug}from"./chunk-6nk7h22s.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
2
+ import{CURRENT_VERSION,repoSlug}from"./chunk-8p579jct.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
3
3
  query($owner: String!, $name: String!) {
4
4
  repository(owner: $owner, name: $name) {
5
5
  id
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{engineEntry,identifiableEngineIds}from"./chunk-gpan2g7d.js";import{recordSpawn}from"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-7q43tysm.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import{__require}from"./chunk-wqfp8d9w.js";import{basename}from"path";var WRAPPERS=new Set(["node","bun","npx","deno","sh","zsh","bash","env","script"]);function binaryName(token){return basename(token).replace(/\.(exe|js|mjs|cjs)$/,"")}function executableNameFromArgv(argv){for(let token of argv.slice(0,8)){if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))continue;let name=binaryName(token);if(WRAPPERS.has(name))continue;return name||null}return null}function vendorFromArgv(commandLine){let name=executableNameFromArgv(commandLine.trim().split(/\s+/));if(!name)return null;return identifiableEngineIds().find((v)=>{let entry=engineEntry(v);return entry.defaultCommand[0]===name||entry.processNames?.includes(name)===!0})??null}function parsePsSnapshot(text){let rows=[];for(let line of text.split(`
2
+ import{engineEntry,identifiableEngineIds}from"./chunk-ctmbj2y3.js";import{recordSpawn}from"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-7q43tysm.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import{__require}from"./chunk-wqfp8d9w.js";import{basename}from"path";var WRAPPERS=new Set(["node","bun","npx","deno","sh","zsh","bash","env","script"]);function binaryName(token){return basename(token).replace(/\.(exe|js|mjs|cjs)$/,"")}function executableNameFromArgv(argv){for(let token of argv.slice(0,8)){if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))continue;let name=binaryName(token);if(WRAPPERS.has(name))continue;return name||null}return null}function vendorFromArgv(commandLine){let name=executableNameFromArgv(commandLine.trim().split(/\s+/));if(!name)return null;return identifiableEngineIds().find((v)=>{let entry=engineEntry(v);return entry.defaultCommand[0]===name||entry.processNames?.includes(name)===!0})??null}function parsePsSnapshot(text){let rows=[];for(let line of text.split(`
3
3
  `)){let m=/^\s*(\d+)\s+(\d+)\s+(\S.*)$/.exec(line);if(m)rows.push({pid:Number(m[1]),ppid:Number(m[2]),args:m[3]})}return rows}function childrenIndex(rows){let kids=new Map;for(let row of rows){let list=kids.get(row.ppid);if(list)list.push(row);else kids.set(row.ppid,[row])}return kids}function hasAncestor(rows,pid,ancestorPid){let parents=new Map(rows.map((r)=>[r.pid,r.ppid])),cur=pid;for(let hops=0;hops<=rows.length;hops++){if(cur===ancestorPid)return!0;let next=parents.get(cur);if(next===void 0||next<=1)return!1;cur=next}return!1}function customEngineBinaries(){let state=loadStateFile(),ids=state.customEngineIds,out=new Map;if(!Array.isArray(ids))return out;for(let id of ids){if(typeof id!=="string"||id.trim().length===0)continue;let command=state[`engineCommand.${id}`],argv=typeof command==="string"&&command.trim().length>0?command.trim().split(/\s+/):[id],name=executableNameFromArgv(argv);if(name)out.set(name,id)}return out}function findDescendant(rows,rootPid,pick){let kids=childrenIndex(rows),queue=[...kids.get(rootPid)??[]],visited=new Set;while(queue.length>0){let row=queue.shift();if(!row)break;if(visited.has(row.pid))continue;visited.add(row.pid);let hit=pick(row);if(hit!==null)return hit;queue.push(...kids.get(row.pid)??[])}return null}function walkDescendants(rows,rootPid,identify){return findDescendant(rows,rootPid,(row)=>{let vendor=identify(row.args);return vendor?{vendor,argv:row.args,pid:row.pid}:null})}function foregroundEngineIn(rows,rootPid){let builtin=walkDescendants(rows,rootPid,vendorFromArgv);if(builtin)return builtin;let custom=customEngineBinaries();if(custom.size===0)return null;return walkDescendants(rows,rootPid,(args)=>custom.get(executableNameFromArgv(args.trim().split(/\s+/))??"")??null)}function engineProcessIn(rows,rootPid,extraLaunch){if(foregroundEngineIn(rows,rootPid))return!0;let expected=extraLaunch?executableNameFromArgv(typeof extraLaunch==="string"?[extraLaunch]:extraLaunch):null;if(!expected)return!1;return findDescendant(rows,rootPid,(row)=>executableNameFromArgv(row.args.trim().split(/\s+/))===expected?!0:null)===!0}var PS_PROBE_TIMEOUT_MS=5000,bunPsSpawn=()=>{recordSpawn("engine.foregroundWalk",["ps","-A","-o","pid=,ppid=,args="]);let proc=Bun.spawn(["ps","-A","-o","pid=,ppid=,args="],{stdout:"pipe",stderr:"ignore"});return{text:new Response(proc.stdout).text(),kill:()=>proc.kill()}};async function psSnapshotWith(spawn,timeoutMs=PS_PROBE_TIMEOUT_MS){let proc=spawn(),timer;try{let text=await Promise.race([proc.text,new Promise((_resolve,reject)=>{timer=setTimeout(()=>{try{proc.kill()}catch{}reject(new PsProbeUnavailableError(`ps did not answer within ${timeoutMs}ms`))},timeoutMs)})]);if(parsePsSnapshot(text).length===0)throw new PsProbeUnavailableError("ps returned no usable rows");return text}finally{if(timer)clearTimeout(timer)}}var psSnapshot=async(anchors)=>{if(process.platform!=="win32")return psSnapshotWith(bunPsSpawn);let{defaultWinProcessProbe,winProcessSnapshot}=await import("./chunk-kxaqge09.js");return winProcessSnapshot(anchors??[],defaultWinProcessProbe())};async function foregroundEngine(rootPid,snapshot=psSnapshot){try{return foregroundEngineIn(parsePsSnapshot(await snapshot([rootPid])),rootPid)}catch{return null}}
4
4
  export{vendorFromArgv,parsePsSnapshot,hasAncestor,foregroundEngineIn,engineProcessIn,PS_PROBE_TIMEOUT_MS,psSnapshotWith,psSnapshot,foregroundEngine};
@@ -1,16 +1,16 @@
1
1
  // @bun
2
- import{updaterShell,updaterShellFailureHint}from"./chunk-aq04rqv7.js";import"./chunk-vjvkkrzc.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-6nk7h22s.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";var CLI_NAME=ROVE_PRODUCT_NAME;function updatePlan(target){let shell=target===void 0?UPDATE_COMMAND:`${UPDATE_COMMAND} -s -- ${target}`;return{command:updaterShell(),args:["-c",shell],display:shell}}var VERSION_SHAPE=/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;function isReleaseChannel(value){return RELEASE_CHANNELS.includes(value)}function parseUpdateArgs(args){let dryRun=!1,list=!1,version,channel;for(let i=0;i<args.length;i+=1){let arg=args[i];if(arg===void 0)continue;if(arg==="--help"||arg==="-h"||arg==="help")return{help:!0,dryRun,list,version,channel};if(arg==="dry-run"||arg==="--dry-run"){dryRun=!0;continue}if(arg==="list"||arg==="--list"){list=!0;continue}if(arg==="--channel"||arg.startsWith("--channel=")){let value=(arg.startsWith("--channel=")?arg.slice(10):void 0)??args[++i];if(value===void 0||!isReleaseChannel(value))process.stderr.write(`${CLI_NAME} update: --channel expects one of ${RELEASE_CHANNELS.join(", ")}${value===void 0?"":` (got "${value}")`}
2
+ import{updaterShell,updaterShellFailureHint}from"./chunk-pmszj74t.js";import"./chunk-vjvkkrzc.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-8p579jct.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";var CLI_NAME=ROVE_PRODUCT_NAME;function updatePlan(target){let shell=target===void 0?UPDATE_COMMAND:`${UPDATE_COMMAND} -s -- ${target}`;return{command:updaterShell(),args:["-c",shell],display:shell}}var VERSION_SHAPE=/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;function isReleaseChannel(value){return RELEASE_CHANNELS.includes(value)}function parseUpdateArgs(args){let dryRun=!1,list=!1,version,channel;for(let i=0;i<args.length;i+=1){let arg=args[i];if(arg===void 0)continue;if(arg==="--help"||arg==="-h"||arg==="help")return{help:!0,dryRun,list,version,channel};if(arg==="dry-run"||arg==="--dry-run"){dryRun=!0;continue}if(arg==="list"||arg==="--list"){list=!0;continue}if(arg==="--channel"||arg.startsWith("--channel=")){let value=(arg.startsWith("--channel=")?arg.slice(10):void 0)??args[++i];if(value===void 0||!isReleaseChannel(value))process.stderr.write(`${CLI_NAME} update: --channel expects one of ${RELEASE_CHANNELS.join(", ")}${value===void 0?"":` (got "${value}")`}
3
3
 
4
4
  `),printUsage(process.stderr),process.exit(2);channel=value;continue}if(channel===void 0&&isReleaseChannel(arg)){channel=arg;continue}if(version===void 0&&VERSION_SHAPE.test(arg)){version=arg;continue}process.stderr.write(`${CLI_NAME} update: unknown argument "${arg}"
5
5
 
6
6
  `),printUsage(process.stderr),process.exit(2)}return{help:!1,dryRun,list,version,channel}}function printUsage(out){out.write([`Usage: ${CLI_NAME} update [version|channel|list|dry-run]`,"","Runs Rove's GitHub-hosted update script. With [version] (e.g.","0.7.90) the script installs that exact release instead of the","head of your channel.","","Verbs (--flag spellings also accepted):"," list Browse recent versions \u2014 a TUI page with release notes"," when interactive, plain text when piped"," dry-run Print the command without running it","","Flags:"," --channel <name> Install from this channel instead of yours. The"," bare name works too: `update nightly`","","Channels:"," latest Stable releases (default)"," nightly Automated nightly cut from main \u2014 newer, less baked","",`You are on: ${channelOf()}`,"","Switching channels is just installing from the other one; there is","no stored setting. Update checks follow the build you are running.","","Default command:",` ${UPDATE_COMMAND}`,"","Script URL:",` ${UPDATE_SCRIPT_URL}`,"","Manual fallback:",` ${recommendedGlobalInstallCommand()}`,"","Examples:",` ${CLI_NAME} update`,` ${CLI_NAME} update 0.7.90`,` ${CLI_NAME} update nightly`,` ${CLI_NAME} update --channel latest`,` ${CLI_NAME} update list`,` ${CLI_NAME} update dry-run`,""].join(`
7
- `))}async function printVersionList(io){let releases=await fetchReleaseSummaries(20);if(releases.length===0)io.stderr.write(`${CLI_NAME} update: could not fetch the release list (offline or rate-limited)
7
+ `))}async function printVersionList(io){let releases=await fetchReleaseSummaries(20);if(releases.length===0)io.stderr.write(`${CLI_NAME} update: could not fetch the release list (offline or rate-limited). Check your connection, then retry ${CLI_NAME} update list.
8
8
  `),io.exit(1);for(let release of releases){let markers=[release.version===CURRENT_VERSION?"(current)":"",BREAKING_VERSIONS.includes(release.version)?`(breaking \u2014 needs \`${CLI_NAME} reset\`)`:""].filter(Boolean).join(" ");io.stdout.write(`${release.version}${markers?` ${markers}`:""}
9
9
  `)}io.stdout.write(`
10
10
  install one with: ${CLI_NAME} update <version>
11
11
  `)}async function warnBreakingCrossings(target,channel,io){if(BREAKING_VERSIONS.length===0)return;let resolved=target??(await checkLatestVersion({force:!0,channel}))?.latest;if(!resolved)return;let crossed=breakingVersionsCrossed(CURRENT_VERSION,resolved);if(crossed.length===0)return;io.stderr.write([`warning: ${CURRENT_VERSION} -> ${resolved} crosses breaking version(s): ${crossed.join(", ")}.`,`After this update, Rove will refuse to start until you run \`${CLI_NAME} reset\``,"(worktrees are never touched; add --hard only to also wipe the task index).",""].join(`
12
12
  `))}var FOLLOW_UP_NOTE=["",`${CLI_NAME}: installed. Two background processes are still running the old build:`,` daemon \u2192 \`${CLI_NAME} daemon restart\` (safe; never touches live sessions)`,` pty host \u2192 only \`${CLI_NAME} reset\` replaces it, and that ends every live`," terminal and engine session \u2014 do it when you can afford to.",`Run \`${CLI_NAME} doctor\` to see which of the two is actually stale.`,""].join(`
13
- `);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code))},parsed=parseUpdateArgs(args);if(parsed.help){printUsage(io.stdout);return}if(parsed.list){if(deps===void 0&&process.stdout.isTTY){let{startVersionsHost}=await import("./chunk-0xrdy726.js");await startVersionsHost();return}await printVersionList(io);return}let channel=parsed.channel??channelOf(),target=parsed.version??(channel===DEFAULT_RELEASE_CHANNEL?void 0:channel),plan=updatePlan(target),switching=parsed.channel!==void 0&&parsed.channel!==channelOf();if(io.stdout.write(`${CLI_NAME} ${CURRENT_VERSION} -> ${target??channel}
13
+ `);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code))},parsed=parseUpdateArgs(args);if(parsed.help){printUsage(io.stdout);return}if(parsed.list){if(deps===void 0&&process.stdout.isTTY){let{startVersionsHost}=await import("./chunk-wh734g12.js");await startVersionsHost();return}await printVersionList(io);return}let channel=parsed.channel??channelOf(),target=parsed.version??(channel===DEFAULT_RELEASE_CHANNEL?void 0:channel),plan=updatePlan(target),switching=parsed.channel!==void 0&&parsed.channel!==channelOf();if(io.stdout.write(`${CLI_NAME} ${CURRENT_VERSION} -> ${target??channel}
14
14
  `),switching)io.stdout.write(`switching channel: ${channelOf()} -> ${channel}
15
15
  `);if(io.stdout.write(`running: ${plan.display}
16
16
  `),await warnBreakingCrossings(parsed.version,channel,io),parsed.dryRun)return;let result=io.spawn(plan.command,plan.args,{stdio:"inherit"});if(result.error){io.stderr.write(`${CLI_NAME} update: failed to run ${plan.command}: ${result.error.message}
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{$jsx,$jsxs,ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useRenderer,useT,useTheme}from"./chunk-2whnrjrr.js";import"./chunk-7za7dj9z.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-764bsyb0.js";import"./chunk-aq04rqv7.js";import"./chunk-atn06ncf.js";import"./chunk-k5py2g4y.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-6nk7h22s.js";import"./chunk-40dgv828.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-dgt1yq74.js";import"./chunk-x1d1mq5c.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:`${UPDATE_COMMAND} -s -- ${selected.version}`})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
2
+ import{$jsx,$jsxs,ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useRenderer,useT,useTheme}from"./chunk-ry54qsbg.js";import"./chunk-a10bkevn.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-764bsyb0.js";import"./chunk-pmszj74t.js";import"./chunk-atn06ncf.js";import"./chunk-h29wy8y3.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-8p579jct.js";import"./chunk-40dgv828.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-wvwkmj3t.js";import"./chunk-jxyvk9c0.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:`${UPDATE_COMMAND} -s -- ${selected.version}`})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-x1d1mq5c.js";import{createStateCell}from"./chunk-nhakrm1f.js";function lookup(catalog,key){let node=catalog;for(let part of key.split("."))if(node&&typeof node==="object"&&part in node)node=node[part];else return;return typeof node==="string"?node:void 0}function interpolate(template,params){if(!params)return template;return template.replace(/\{(\w+)\}/g,(whole,name)=>(name in params)?String(params[name]):whole)}function lookupKeys(catalog,group,key){return catalog.keys[group]?.[key]}var langState=createStateCell(DEFAULT_LOCALE);function setLocaleLang(lang){if(CATALOGS[lang])langState.set(lang)}function currentLang(){return langState.get()}function intlLocale(){return LOCALES.find((locale)=>locale.id===langState.get())?.intl??"en-US"}function localeState(){return langState}function t(key,params){let lang=langState.get(),resolved=lookup(CATALOGS[lang],key)??lookup(CATALOGS.en,key)??key;return interpolate(resolved,params)}function tKeys(group,key){let lang=langState.get();return lookupKeys(CATALOGS[lang],group,key)??lookupKeys(CATALOGS.en,group,key)??key}
2
+ import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-jxyvk9c0.js";import{createStateCell}from"./chunk-nhakrm1f.js";function lookup(catalog,key){let node=catalog;for(let part of key.split("."))if(node&&typeof node==="object"&&part in node)node=node[part];else return;return typeof node==="string"?node:void 0}function interpolate(template,params){if(!params)return template;return template.replace(/\{(\w+)\}/g,(whole,name)=>(name in params)?String(params[name]):whole)}function lookupKeys(catalog,group,key){return catalog.keys[group]?.[key]}var langState=createStateCell(DEFAULT_LOCALE);function setLocaleLang(lang){if(CATALOGS[lang])langState.set(lang)}function currentLang(){return langState.get()}function intlLocale(){return LOCALES.find((locale)=>locale.id===langState.get())?.intl??"en-US"}function localeState(){return langState}function t(key,params){let lang=langState.get(),resolved=lookup(CATALOGS[lang],key)??lookup(CATALOGS.en,key)??key;return interpolate(resolved,params)}function tKeys(group,key){let lang=langState.get();return lookupKeys(CATALOGS[lang],group,key)??lookupKeys(CATALOGS.en,group,key)??key}
3
3
  export{setLocaleLang,currentLang,intlLocale,localeState,t,tKeys};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{deriveTitleFromPrompt}from"./chunk-cbc1h345.js";import{TaskDeletingError}from"./chunk-4xns5j33.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedEngine,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,killHostedSessions,listHostedSessions,openHostedSessionHost,pastePromptWhenEngineUp,trustEngineWorktree}from"./chunk-zh6fadgw.js";import{engineLaunchArgv,protocolEntry}from"./chunk-qdfxk8pt.js";import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";var MAX_SESSIONS_SCANNED=8;function titleFromMessages(messages){let firstUser=messages.find((m)=>m.role==="user");if(!firstUser)return"";let text=firstUser.blocks.filter((b)=>b.type==="text").map((b)=>b.text).join(" "),title=deriveTitleFromPrompt(text);return title.length>0?Buffer.from(title,"utf8").toString("utf8"):title}async function deriveTitleFromSession(worktree,vendor=DEFAULT_TASK_VENDOR){if(!worktree)return"";let{history}=protocolEntry(vendor),ids=await history.listSessionIdsForWorktree(worktree);for(let sessionId of ids.slice(0,MAX_SESSIONS_SCANNED)){let title=titleFromMessages(await history.readHistory(sessionId));if(title)return title}return""}async function deriveTitleFromSessionId(vendor,sessionId){if(!sessionId)return"";try{return titleFromMessages(await protocolEntry(vendor).history.readHistory(sessionId))}catch{return""}}async function getTask(link,taskId){let{task}=await link.request("task.get",{taskId});return task}async function ensureTaskWorktree(link,taskId){let task=await getTask(link,taskId);if(task.deletion)throw new TaskDeletingError(taskId);if(task.worktreePath)return{task,worktreePath:task.worktreePath};let{worktreePath}=await link.request("task.ensureWorktree",{taskId});if(!worktreePath)throw Error(`task ${taskId} has no worktree`);return{task,worktreePath}}async function ensureTaskSessionAdapter(link,taskId){let{task,worktreePath}=await ensureTaskWorktree(link,taskId),launch=taskEngineLaunch(task,worktreePath,{kind:"repo-init"}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)throw Error(`failed to start hosted engine session for ${taskId}`);if(launch.firstMessage){let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0];await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs}).catch(()=>!1)}}finally{host.close()}return{session:launch.key,worktreePath}}async function startTaskSessionWithPromptAdapter(link,taskId,prompt){let{task,worktreePath}=await ensureTaskWorktree(link,taskId);await link.request("task.observeLanguage",{taskId,text:prompt}).catch(()=>{});let launch=taskEngineLaunch(task,worktreePath,{kind:"new-task",prompt}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)return{started:!1,error:"hosted session did not open"};let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0],wait={initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs};if(launch.firstMessage){if(await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}if(await awaitEngineProcess(host.rpc,launch.key,engineBin,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}finally{host.close()}}async function startFailureReason(rpc,key){let tail=await hostedSessionFailureLine(rpc,key),base="engine process never started";return tail?`engine process never started; last session output: ${tail}`:"engine process never started"}function taskEngineLaunch(task,worktreePath,promptIntent){return trustEngineWorktree(task.vendor,worktreePath),buildEngineSessionLaunch({task:{id:task.id,kind:task.kind,vendor:task.vendor,repo:task.repo},worktreePath,shell:resolveLoginShell({fallback:"/bin/zsh"}),argv:engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model}),promptIntent})}async function deliverPromptToLiveEngineAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return!1;try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0]);if(!key)return!1;let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return!1;return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})!==null}catch{return!1}finally{host.close()}}function tabIdFromHostedKey(key){return key.split("::")[1]??"tab-1"}async function deliverPromptToLiveEngineDetailedAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0]);if(!key)return{outcome:"no-session"};let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:tabIdFromHostedKey(key)};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:tabIdFromHostedKey(key)}}catch{return{outcome:"no-session"}}finally{host.close()}}async function deliverPromptToLiveEngineTabDetailedAdapter(target,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let key=`${target.id}::${target.tabId}`,sessions;try{sessions=await listHostedSessions(host.rpc)}catch{return{outcome:"no-session"}}let session=sessions.find((candidate)=>candidate.alive&&candidate.key===key);if(!session)return{outcome:"no-session"};let engineArgv=engineLaunchArgv({command:target.command,vendor:target.vendor}),presence=await enginePresence(session.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:target.tabId};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:target.tabId}}finally{host.close()}}async function tearDownTaskSessionAdapter(taskId){let host=await openHostedSessionHost();if(!host)return;try{await killHostedSessions(host.rpc,hostedTaskKeys(await listHostedSessions(host.rpc),taskId),{wait:!0})}catch{}finally{host.close()}}
2
+ import{deriveTitleFromPrompt}from"./chunk-cbc1h345.js";import{TaskDeletingError}from"./chunk-4xns5j33.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedEngine,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,killHostedSessions,listHostedSessions,openHostedSessionHost,pastePromptWhenEngineUp,trustEngineWorktree}from"./chunk-e5k2j2x8.js";import{engineLaunchArgv,protocolEntry}from"./chunk-4r3s1z14.js";import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";var MAX_SESSIONS_SCANNED=8;function titleFromMessages(messages){let firstUser=messages.find((m)=>m.role==="user");if(!firstUser)return"";let text=firstUser.blocks.filter((b)=>b.type==="text").map((b)=>b.text).join(" "),title=deriveTitleFromPrompt(text);return title.length>0?Buffer.from(title,"utf8").toString("utf8"):title}async function deriveTitleFromSession(worktree,vendor=DEFAULT_TASK_VENDOR){if(!worktree)return"";let{history}=protocolEntry(vendor),ids=await history.listSessionIdsForWorktree(worktree);for(let sessionId of ids.slice(0,MAX_SESSIONS_SCANNED)){let title=titleFromMessages(await history.readHistory(sessionId));if(title)return title}return""}async function deriveTitleFromSessionId(vendor,sessionId){if(!sessionId)return"";try{return titleFromMessages(await protocolEntry(vendor).history.readHistory(sessionId))}catch{return""}}async function getTask(link,taskId){let{task}=await link.request("task.get",{taskId});return task}async function ensureTaskWorktree(link,taskId){let task=await getTask(link,taskId);if(task.deletion)throw new TaskDeletingError(taskId);if(task.worktreePath)return{task,worktreePath:task.worktreePath};let{worktreePath}=await link.request("task.ensureWorktree",{taskId});if(!worktreePath)throw Error(`task ${taskId} has no worktree`);return{task,worktreePath}}async function ensureTaskSessionAdapter(link,taskId){let{task,worktreePath}=await ensureTaskWorktree(link,taskId),launch=taskEngineLaunch(task,worktreePath,{kind:"repo-init"}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)throw Error(`failed to start hosted engine session for ${taskId}`);if(launch.firstMessage){let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0];await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs}).catch(()=>!1)}}finally{host.close()}return{session:launch.key,worktreePath}}async function startTaskSessionWithPromptAdapter(link,taskId,prompt){let{task,worktreePath}=await ensureTaskWorktree(link,taskId);await link.request("task.observeLanguage",{taskId,text:prompt}).catch(()=>{});let launch=taskEngineLaunch(task,worktreePath,{kind:"new-task",prompt}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)return{started:!1,error:"hosted session did not open"};let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0],wait={initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs};if(launch.firstMessage){if(await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}if(await awaitEngineProcess(host.rpc,launch.key,engineBin,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}finally{host.close()}}async function startFailureReason(rpc,key){let tail=await hostedSessionFailureLine(rpc,key),base="engine process never started";return tail?`engine process never started; last session output: ${tail}`:"engine process never started"}function taskEngineLaunch(task,worktreePath,promptIntent){return trustEngineWorktree(task.vendor,worktreePath),buildEngineSessionLaunch({task:{id:task.id,kind:task.kind,vendor:task.vendor,repo:task.repo},worktreePath,shell:resolveLoginShell({fallback:"/bin/zsh"}),argv:engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model}),promptIntent})}async function deliverPromptToLiveEngineAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return!1;try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0]);if(!key)return!1;let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return!1;return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})!==null}catch{return!1}finally{host.close()}}function tabIdFromHostedKey(key){return key.split("::")[1]??"tab-1"}async function deliverPromptToLiveEngineDetailedAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0]);if(!key)return{outcome:"no-session"};let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:tabIdFromHostedKey(key)};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:tabIdFromHostedKey(key)}}catch{return{outcome:"no-session"}}finally{host.close()}}async function deliverPromptToLiveEngineTabDetailedAdapter(target,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let key=`${target.id}::${target.tabId}`,sessions;try{sessions=await listHostedSessions(host.rpc)}catch{return{outcome:"no-session"}}let session=sessions.find((candidate)=>candidate.alive&&candidate.key===key);if(!session)return{outcome:"no-session"};let engineArgv=engineLaunchArgv({command:target.command,vendor:target.vendor}),presence=await enginePresence(session.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:target.tabId};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:target.tabId}}finally{host.close()}}async function tearDownTaskSessionAdapter(taskId){let host=await openHostedSessionHost();if(!host)return;try{await killHostedSessions(host.rpc,hostedTaskKeys(await listHostedSessions(host.rpc),taskId),{wait:!0})}catch{}finally{host.close()}}
3
3
  export{deriveTitleFromSession,deriveTitleFromSessionId,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,tearDownTaskSessionAdapter};
package/dist/cli/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{matchPathGlob}from"./chunk-kg11c1py.js";import{switchFlag}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import{expandTilde}from"./chunk-ag3txfg2.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{CURRENT_VERSION}from"./chunk-6nk7h22s.js";import{rejectionReason}from"./chunk-3342qzve.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.ROVE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}`;let raw=errorMessage(err);return`${subject}: ${summarizeCliGitError(raw,opts.cwd)??raw}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-g2kb61q5.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-vej49hnt.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-easxds8p.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-1zxheb0c.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-pb4cc1vy.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-skf7y627.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-wpvxfzb9.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-ca3bfxd9.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-p83wf4zw.js");await runMachineSubcommand(args)}],["weixin",async(args)=>{let{runChannelCli}=await import("./chunk-1wt1esef.js");await runChannelCli("weixin",args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-c5rb17k9.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-p18ehv9y.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-fcfh9xsq.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-tkbdgh2k.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-kxpfm6mb.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-taf0014q.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-8ztzk7tg.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-pe6wnsww.js"),{GitWorktreeManager}=await import("./chunk-9q1m5qz0.js"),{Orchestrator}=await import("./chunk-8pna13mr.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-ng12dprz.js"),{projectRejection}=await import("./chunk-2vgc5cyj.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${ROVE_PRODUCT_NAME}: "${arg}" is not a directory (resolved to ${dir}).
4
- `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-ktzbg4jg.js");writeLastActiveTaskId(String(task.id))}});let{publishRoveTerminalTitle}=await import("./chunk-t8v9rpdx.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-84h387qb.js");await launchTui()}function topLevelUsage(cliName=ROVE_PRODUCT_NAME){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|remove|list)"," weixin <verb> Talk to Rove from WeChat (login|logout|status|allow|deny)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"].join(`
3
+ import{matchPathGlob}from"./chunk-kg11c1py.js";import{failureHint}from"./chunk-09y7gspe.js";import{switchFlag}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import{expandTilde}from"./chunk-ag3txfg2.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{CURRENT_VERSION}from"./chunk-8p579jct.js";import{rejectionReason}from"./chunk-3342qzve.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-wvwkmj3t.js";import"./chunk-jxyvk9c0.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import{pathSyntax}from"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.ROVE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}
4
+ ${failureHint(err,opts.cliName)}`;let raw=errorMessage(err),git=summarizeCliGitError(raw,opts.cwd);return`${subject}: ${git??`${raw}
5
+ ${failureHint(err,opts.cliName)}`}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-1kprhx82.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-vej49hnt.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-easxds8p.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-8vbcj8xx.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-wd2k83dv.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-4nt1gnwq.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-c9js0wd7.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-hkbdrwtg.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-p83wf4zw.js");await runMachineSubcommand(args)}],["weixin",async(args)=>{let{runChannelCli}=await import("./chunk-0b5mec1c.js");await runChannelCli("weixin",args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-4hm0smvv.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-p18ehv9y.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-qqz6nxfe.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-9sk0w5be.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-ntkfhrbw.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-g655yb7d.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-j8evwrp3.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-pe6wnsww.js"),{GitWorktreeManager}=await import("./chunk-9q1m5qz0.js"),{Orchestrator}=await import("./chunk-8pna13mr.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-ng12dprz.js"),{projectRejection}=await import("./chunk-2vgc5cyj.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${ROVE_PRODUCT_NAME}: "${arg}" is not a directory (resolved to ${dir}).
6
+ `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-ktzbg4jg.js");writeLastActiveTaskId(String(task.id))}});let{publishRoveTerminalTitle}=await import("./chunk-t8v9rpdx.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-a5vhekme.js");await launchTui()}function topLevelUsage(cliName=ROVE_PRODUCT_NAME){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|remove|list)"," weixin <verb> Talk to Rove from WeChat (login|logout|status|allow|deny)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"].join(`
5
7
  `)}var CLI_NAME=ROVE_PRODUCT_NAME,ADD_USAGE=[`Usage: ${CLI_NAME} add [path]`,` ${CLI_NAME} add --remote --host <host> --user <user> --path <basePath> [--port N] [--key [path] | --password]`,"","Save a repo for the new-task picker. With --remote, register an SSH-backed","project whose worktrees live on <host>; engine launch over SSH is pending.",""].join(`
6
8
  `);async function runAddSubcommand(rest){let arg=rest[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(ADD_USAGE);return}if(arg==="--remote"){let{runAddRemote}=await import("./chunk-53cyns0f.js");await runAddRemote(rest.slice(1));return}if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} add: unknown flag "${arg}"
7
9
 
8
10
  ${ADD_USAGE}`),process.exit(2);let target=resolve2(process.cwd(),expandTilde(arg&&arg.length>0?arg:".")),{addSavedRepo}=await import("./chunk-ng12dprz.js"),result=addSavedRepo(target);if(result.rejected)process.stderr.write(`${CLI_NAME} add: "${arg&&arg.length>0?arg:"."}" cannot be a project \u2014 ${rejectionReason(result.rejected)} (resolved to ${result.path}).
9
- `),process.exit(1);if(result.added)console.log(`added ${result.path} (${result.total} saved repo${result.total===1?"":"s"} total)`);else console.log(`already saved: ${result.path}`);await ensureProjectMainTask(result.path),await adoptAllWorktrees(result.path)}async function ensureProjectMainTask(repo){try{await withDaemonOrLocal({daemon:(client)=>client.request("task.ensureMain",{repo}),local:(orch)=>orch.ensureMainTask(repo)})}catch(err){console.error(`(skipped project main-task setup: ${errorMessage(err)})`)}}var PURGE_FLAG="--purge-credentials",REMOVE_USAGE=[`Usage: ${CLI_NAME} remove [path] [--purge-credentials]`,"","Forget a saved project (drop it from the new-task picker). Non-destructive:","the repo's files, worktrees, branches and tasks all stay on disk. A remote","(ssh://) project also has its stored connection config dropped.",""," path defaults to the current directory. Pass an exact saved entry (e.g. a"," remote `ssh://user@host` key) to remove it verbatim. Run with no match to"," print the current saved projects.",""," --purge-credentials also delete the remote project's SSH password from"," the OS keychain. Off by default: forgetting a project"," should not silently destroy a stored secret.",""].join(`
11
+ `),process.exit(1);if(result.added)console.log(`added ${result.path} (${result.total} saved repo${result.total===1?"":"s"} total)`);else console.log(`already saved: ${result.path}`);await ensureProjectMainTask(result.path),await adoptAllWorktrees(result.path)}async function ensureProjectMainTask(repo){try{await withDaemonOrLocal({daemon:(client)=>client.request("task.ensureMain",{repo}),local:(orch)=>orch.ensureMainTask(repo)})}catch(err){console.error(`(skipped project main-task setup: ${errorMessage(err)}). Run ${CLI_NAME} doctor, then retry ${CLI_NAME} add.`)}}var PURGE_FLAG="--purge-credentials",REMOVE_USAGE=[`Usage: ${CLI_NAME} remove [path] [--purge-credentials]`,"","Forget a saved project (drop it from the new-task picker). Non-destructive:","the repo's files, worktrees, branches and tasks all stay on disk. A remote","(ssh://) project also has its stored connection config dropped.",""," path defaults to the current directory. Pass an exact saved entry (e.g. a"," remote `ssh://user@host` key) to remove it verbatim. Run with no match to"," print the current saved projects.",""," --purge-credentials also delete the remote project's SSH password from"," the OS keychain. Off by default: forgetting a project"," should not silently destroy a stored secret.",""].join(`
10
12
  `);async function runRemoveSubcommand(rest){let purgeCredentials=switchFlag(rest,PURGE_FLAG),arg=rest.filter((a)=>a!==PURGE_FLAG&&!a.startsWith(`${PURGE_FLAG}=`))[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(REMOVE_USAGE);return}if(purgeCredentials===void 0)process.stderr.write(`${CLI_NAME} remove: ${PURGE_FLAG} takes true or false
11
13
 
12
14
  ${REMOVE_USAGE}`),process.exit(2);if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} remove: unknown flag "${arg}"
@@ -15,7 +17,7 @@ ${REMOVE_USAGE}`),process.exit(2);let{getRemoteRepoConfig,getSavedRepos,resolveR
15
17
 
16
18
  Saved projects:
17
19
  `);for(let p of saved)process.stderr.write(` ${p}
18
- `);process.exit(1)}let auth=getRemoteRepoConfig(target)?.auth,keychainRef=auth?.kind==="password"?auth.keychainRef:null;await withDaemonOrLocal({daemon:(client)=>client.request("project.forget",{repo:target}),local:(orch)=>orch.forgetProject(target)});let remaining=getSavedRepos().length;if(console.log(`removed ${target} (${remaining} saved repo${remaining===1?"":"s"} left)`),keychainRef)await reportCredentialExit(keychainRef,purgeCredentials)}async function reportCredentialExit(ref,purge){let{deleteKeychainPassword,isKeychainSupported}=await import("./chunk-fvmee0tr.js");if(!purge){console.log(`note: its SSH password is still in the OS keychain (${ref.service}/${ref.account}).`),console.log(` re-run with ${PURGE_FLAG} to delete it.`);return}if(!isKeychainSupported()){console.error("--purge-credentials: the OS keychain is only wired for macOS; nothing deleted.");return}if(deleteKeychainPassword(ref))console.log(`purged the keychain password (${ref.service}/${ref.account})`);else console.error(`--purge-credentials: no keychain item found for ${ref.service}/${ref.account}`)}async function adoptAllWorktrees(repo){let orch=await openLocalOrchestrator(),candidates;try{candidates=await orch.discoverAdoptableWorktrees(repo)}catch(err){console.error(`(skipped worktree scan: ${errorMessage(err)})`);return}if(candidates.length===0)return;console.log(`scanning ${repo}: ${candidates.length} unlinked worktree(s) \u2192 importing`),await adoptWorktreesInto(orch,repo,candidates,coerceVendorId(void 0))}async function adoptWorktreesInto(orch,repo,list,vendor){for(let w of list){let adopted=await withDaemonOrLocal({daemon:async(client)=>(await client.request("worktree.adopt",{repo,worktreePath:w.path,branch:w.branch,vendor})).task,local:async()=>orch.adoptWorktree({repo,worktreePath:w.path,branch:w.branch,vendor})});console.log(` adopted ${w.branch} \u2192 task ${adopted.id} (${adopted.title})`)}}var ADOPT_USAGE=[`Usage: ${CLI_NAME} adopt [glob] [--repo <path>] [--vendor <v>] [--yes]`,"",`Import existing git worktrees in a repo as ${CLI_NAME} tasks.`,"No glob \u2192 dry-run listing. With a glob \u2192 list matches; --yes adopts them.","","Options:"," --repo <path> Repo to scan (default: current directory)"," --vendor <v> Engine vendor for adopted tasks"," -y, --yes Actually adopt the matched worktrees"," -h, --help Print this help",""].join(`
20
+ `);process.exit(1)}let auth=getRemoteRepoConfig(target)?.auth,keychainRef=auth?.kind==="password"?auth.keychainRef:null;await withDaemonOrLocal({daemon:(client)=>client.request("project.forget",{repo:target}),local:(orch)=>orch.forgetProject(target)});let remaining=getSavedRepos().length;if(console.log(`removed ${target} (${remaining} saved repo${remaining===1?"":"s"} left)`),keychainRef)await reportCredentialExit(keychainRef,purgeCredentials)}async function reportCredentialExit(ref,purge){let{deleteKeychainPassword,isKeychainSupported}=await import("./chunk-fvmee0tr.js");if(!purge){console.log(`note: its SSH password is still in the OS keychain (${ref.service}/${ref.account}).`),console.log(` re-run with ${PURGE_FLAG} to delete it.`);return}if(!isKeychainSupported()){console.error("--purge-credentials: the OS keychain is only wired for macOS; nothing deleted.");return}if(deleteKeychainPassword(ref))console.log(`purged the keychain password (${ref.service}/${ref.account})`);else console.error(`--purge-credentials: no keychain item found for ${ref.service}/${ref.account}`)}async function adoptAllWorktrees(repo){let orch=await openLocalOrchestrator(),candidates;try{candidates=await orch.discoverAdoptableWorktrees(repo)}catch(err){console.error(`(skipped worktree scan: ${errorMessage(err)}). Run git worktree list in the repository, then retry ${CLI_NAME} add.`);return}if(candidates.length===0)return;console.log(`scanning ${repo}: ${candidates.length} unlinked worktree(s) \u2192 importing`),await adoptWorktreesInto(orch,repo,candidates,coerceVendorId(void 0))}async function adoptWorktreesInto(orch,repo,list,vendor){for(let w of list){let adopted=await withDaemonOrLocal({daemon:async(client)=>(await client.request("worktree.adopt",{repo,worktreePath:w.path,branch:w.branch,vendor})).task,local:async()=>orch.adoptWorktree({repo,worktreePath:w.path,branch:w.branch,vendor})});console.log(` adopted ${w.branch} \u2192 task ${adopted.id} (${adopted.title})`)}}var ADOPT_USAGE=[`Usage: ${CLI_NAME} adopt [glob] [--repo <path>] [--vendor <v>] [--yes]`,"",`Import existing git worktrees in a repo as ${CLI_NAME} tasks.`,"No glob \u2192 dry-run listing. With a glob \u2192 list matches; --yes adopts them.","","Options:"," --repo <path> Repo to scan (default: current directory)"," --vendor <v> Engine vendor for adopted tasks"," -y, --yes Actually adopt the matched worktrees"," -h, --help Print this help",""].join(`
19
21
  `);function adoptUsageError(message){process.stderr.write(`${CLI_NAME} adopt: ${message}
20
22
 
21
23
  ${ADOPT_USAGE}
@@ -24,4 +26,4 @@ ${ADOPT_USAGE}
24
26
  pass a path glob to adopt, e.g. ${CLI_NAME} adopt '${repo}/*' --yes`);return}let matched=worktrees.filter(isMatch);if(matched.length===0){console.log(`
25
27
  no worktrees match glob ${JSON.stringify(glob)}`);return}if(!yes){console.log(`
26
28
  ${matched.length} worktree(s) match \u2014 re-run with --yes to adopt them`);return}await adoptWorktreesInto(orch,repo,matched,vendor),console.log(`done \u2014 adopted ${matched.length} worktree(s)`)}function printTopLevelUsage(out){out.write(`${topLevelUsage()}
27
- `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-gxdfyn42.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-kxpfm6mb.js");await runSkillSubcommand(["print"]);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishRoveTerminalTitle}=await import("./chunk-t8v9rpdx.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-84h387qb.js");await launchTui()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
29
+ `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-dqvy3kxk.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-ntkfhrbw.js");await runSkillSubcommand(["print"]);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishRoveTerminalTitle}=await import("./chunk-t8v9rpdx.js");publishRoveTerminalTitle();let{launchTui}=await import("./chunk-a5vhekme.js");await launchTui()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
@@ -2837,9 +2837,13 @@ function dispatchPtyRequest(req, client, deps) {
2837
2837
  switch (req.name) {
2838
2838
  case "hello":
2839
2839
  return { protocolVersion: DAEMON_PROTOCOL_VERSION, ptyHost: true, pid: process.pid };
2840
+ case "pty.openChecked":
2840
2841
  case "pty.open": {
2841
2842
  const payload = objectPayload(req.payload);
2842
- return ptys.open(requireString(payload, "key"), {
2843
+ if (req.name === "pty.openChecked" && requireString(payload, "admissionToken") !== admissionToken(ptys)) {
2844
+ return { kind: "changed" };
2845
+ }
2846
+ const open = ptys.open(requireString(payload, "key"), {
2843
2847
  cwd: requireString(payload, "cwd"),
2844
2848
  command: Array.isArray(payload.command) ? payload.command.filter((c) => typeof c === "string") : undefined,
2845
2849
  shell: typeof payload.shell === "string" ? payload.shell : undefined,
@@ -2847,6 +2851,7 @@ function dispatchPtyRequest(req, client, deps) {
2847
2851
  rows: typeof payload.rows === "number" ? payload.rows : undefined,
2848
2852
  defaultColors: parseTerminalDefaultColors(payload.defaultColors) ?? undefined
2849
2853
  }, client, (frame) => deps.writeFrame(client, frame), typeof payload.sinceOffset === "number" ? payload.sinceOffset : undefined, typeof payload.sincePid === "number" ? payload.sincePid : undefined, payload.answersQueries === true);
2854
+ return req.name === "pty.openChecked" ? { kind: "opened", open } : open;
2850
2855
  }
2851
2856
  case "pty.write": {
2852
2857
  const payload = objectPayload(req.payload);
@@ -2894,6 +2899,7 @@ function dispatchPtyRequest(req, client, deps) {
2894
2899
  pid: process.pid,
2895
2900
  rssBytes: process.memoryUsage().rss,
2896
2901
  sessions: ptys.list(),
2902
+ admissionToken: admissionToken(ptys),
2897
2903
  stats: ptys.stats(),
2898
2904
  ...deps.version ? { version: deps.version } : {}
2899
2905
  };
@@ -2921,6 +2927,9 @@ function dispatchPtyRequest(req, client, deps) {
2921
2927
  throw new Error(`unknown pty-host request: ${req.name}`);
2922
2928
  }
2923
2929
  }
2930
+ function admissionToken(ptys) {
2931
+ return JSON.stringify(ptys.list().map((s) => [s.key, s.generation, s.pid, s.alive]));
2932
+ }
2924
2933
 
2925
2934
  // ../rove-daemon/src/daemon/socket-guard.ts
2926
2935
  async function listenOnUnixSocket(server, socketPath) {
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{migrateRoveClientStateLayout}from"./chunk-tdhk4dz8.js";import{updateStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import{kvStatePath}from"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var RENAMED_KEY_PREFIXES=[{from:"autoEffort.",to:"autoRouting."}],NOTHING={moved:0,superseded:0};function legacyRename(key){for(let{from,to}of RENAMED_KEY_PREFIXES)if(key.startsWith(from))return`${to}${key.slice(from.length)}`;return}function isStateObject(text){try{let parsed=JSON.parse(text);return typeof parsed==="object"&&parsed!==null&&!Array.isArray(parsed)}catch{return!1}}function migrateRenamedStateKeys(){let text;try{text=readFileSync(kvStatePath(),"utf8")}catch{return NOTHING}if(!RENAMED_KEY_PREFIXES.some(({from})=>text.includes(`"${from}`)))return NOTHING;if(!isStateObject(text))return NOTHING;let moved=0,superseded=0;try{updateStateFile((state)=>{for(let[key,value]of Object.entries(state)){let renamed=legacyRename(key);if(renamed===void 0)continue;if(renamed in state)superseded+=1;else state[renamed]=value,moved+=1;delete state[key]}return moved+superseded>0})}catch{return NOTHING}return{moved,superseded}}function prepareCliStateLayout(env=process.env){let result=migrateRoveClientStateLayout(env);for(let warning of result.warnings)console.error(`[rove] state migration will retry: ${warning}`);migrateRenamedStateKeys()}prepareCliStateLayout();await import("./index.js");
3
+ import{migrateRoveClientStateLayout}from"./chunk-tdhk4dz8.js";import{updateStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import{kvStatePath}from"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var RENAMED_KEY_PREFIXES=[{from:"autoEffort.",to:"autoRouting."}],NOTHING={moved:0,superseded:0};function legacyRename(key){for(let{from,to}of RENAMED_KEY_PREFIXES)if(key.startsWith(from))return`${to}${key.slice(from.length)}`;return}function isStateObject(text){try{let parsed=JSON.parse(text);return typeof parsed==="object"&&parsed!==null&&!Array.isArray(parsed)}catch{return!1}}function migrateRenamedStateKeys(){let text;try{text=readFileSync(kvStatePath(),"utf8")}catch{return NOTHING}if(!RENAMED_KEY_PREFIXES.some(({from})=>text.includes(`"${from}`)))return NOTHING;if(!isStateObject(text))return NOTHING;let moved=0,superseded=0;try{updateStateFile((state)=>{for(let[key,value]of Object.entries(state)){let renamed=legacyRename(key);if(renamed===void 0)continue;if(renamed in state)superseded+=1;else state[renamed]=value,moved+=1;delete state[key]}return moved+superseded>0})}catch{return NOTHING}return{moved,superseded}}function prepareCliStateLayout(env=process.env){let result=migrateRoveClientStateLayout(env);for(let warning of result.warnings)console.error(`[rove] state migration will retry: ${warning}. Check the source/destination permissions, then relaunch Rove.`);migrateRenamedStateKeys()}prepareCliStateLayout();await import("./index.js");
package/dist/cli/rove.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import{join as n}from"node:path";import{createInterface as a}from"node:readline/promises";import{pathToFileURL as ss}from"node:url";import{spawnSync as Q}from"node:child_process";import{constants as d,accessSync as R}from"node:fs";import{homedir as I}from"node:os";import{basename as U,delimiter as o,dirname as _,join as k}from"node:path";import{fileURLToPath as T}from"node:url";var H={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.246",description:"Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.20","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-weixin":"0.0.7",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var q="rove";var i=q;var z="ROVE_BUN",e="ROVE_NO_BUN_BOOTSTRAP",F="ROVE_SKIP_BUN_CHECK",$=H.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",L=(s)=>{try{return R(s,d.X_OK),!0}catch{return!1}},B=(s)=>s==="win32"?"bun.exe":"bun",f=(s)=>{let t=Q(s,["--version"],{encoding:"utf8",timeout:5000});if(t.error||t.status!==0)return null;return t.stdout?.split(`
2
+ import{join as n}from"node:path";import{createInterface as a}from"node:readline/promises";import{pathToFileURL as ss}from"node:url";import{spawnSync as Q}from"node:child_process";import{constants as d,accessSync as R}from"node:fs";import{homedir as I}from"node:os";import{basename as U,delimiter as o,dirname as _,join as k}from"node:path";import{fileURLToPath as T}from"node:url";var H={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.247",description:"Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.20","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-weixin":"0.0.8",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var q="rove";var i=q;var z="ROVE_BUN",e="ROVE_NO_BUN_BOOTSTRAP",F="ROVE_SKIP_BUN_CHECK",$=H.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",L=(s)=>{try{return R(s,d.X_OK),!0}catch{return!1}},B=(s)=>s==="win32"?"bun.exe":"bun",f=(s)=>{let t=Q(s,["--version"],{encoding:"utf8",timeout:5000});if(t.error||t.status!==0)return null;return t.stdout?.split(`
3
3
  `)[0]?.trim()??""};function J(s){return s.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function X(s,t=$){let c=J(s),b=J(t);if(!c||!b)return!0;let W=c.split(".").map(Number),g=b.split(".").map(Number);for(let x=0;x<3;x++){let y=W[x]??0,r=g[x]??0;if(y!==r)return y>r}return!0}function Y(s=process.env){return s[F]==="1"}function A(s={}){let t=s.env??process.env,c=s.platform??process.platform,b=s.home??t.HOME??t.USERPROFILE??I(),W=B(c),g=[],x=t[z]?.trim();if(x)g.push(x);for(let G of(t.PATH??t.Path??"").split(o))if(G)g.push(k(G,W));let y=t.BUN_INSTALL?.trim();if(y)g.push(k(y,"bin",W));if(b)g.push(k(b,".bun","bin",W));let r=s.launcherDir;if(r)g.push(k(r,"..","..","node_modules","bun","bin",W)),g.push(k(r,"..","..","..","bun","bin",W));return g}function N(s={}){let t=s.isExecutable??L;return A(s).find((c)=>t(c))??null}function Z(s={}){let t=s.isExecutable??L,c=s.bunVersionOf??f;if(Y(s.env??process.env))return{bun:N(s),stale:null,unusable:null};let b=null,W=null;for(let g of A(s)){if(!t(g))continue;let x=c(g);if(x===null){W??=g;continue}if(X(x))return{bun:g,stale:b,unusable:W};b??={path:g,version:J(x)??x}}return{bun:null,stale:b,unusable:W}}function h(s){return _(T(s))}function C(s){return U(T(s)).replace(/\.[cm]?[jt]s$/,"")}function u(s=process.platform){return s==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(s=i,t=process.platform){let c=t==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${s}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${c}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${z}=/path/to/bun`,""].join(`
4
4
  `)}function j(s,t,c=i){return[`${c}: this machine's Bun is too old for Rove — found ${t} at ${s}, need ${$} or newer.`,"","Rove's terminals are built on Bun's PTY API. An older Bun ignores it silently,","so every terminal and engine tab would open empty and stay empty.","","Upgrade Bun, then run this command again:"," bun upgrade # Bun installed itself (~/.bun)"," brew upgrade bun # Homebrew"," npm install -g bun@latest # npm-managed Bun","",`Have a newer Bun elsewhere? Point Rove at it: ${z}=/path/to/bun`,`Run on this one anyway (unsupported, terminals will be blank): ${F}=1`,""].join(`
5
5
  `)}function v(s,t=i){return[`${t}: the Bun at ${s} could not be run — \`${s} --version\` failed or never returned.`,"","Rove skipped it rather than starting through it, which would hang or fail","with a message from that binary instead of this one.","","Reinstall Bun, then run this command again:"," curl -fsSL https://bun.sh/install | bash","",`Have a working Bun elsewhere? Point Rove at it: ${z}=/path/to/bun`,""].join(`
6
- `)}function w(s=process.env,t=process.stdin,c=process.stdout){if(s[e]==="1")return!1;if(s.CI==="true"||s.CI==="1")return!1;return Boolean(t.isTTY&&c.isTTY)}function M(s={},t=Q){let c=s.platform??process.platform,[b,...W]=u(c);if(!b)return null;let g=t(b,W,{stdio:"inherit"});if(g.error||g.status!==0)return null;return Z(s).bun}function l(s){if(typeof s.status==="number")return s.status;if(s.signal)return 128+(Object.hasOwn(K,s.signal)?K[s.signal]:0);return 1}var K={SIGINT:2,SIGQUIT:3,SIGKILL:9,SIGTERM:15};function S(s,t,c,b=Q){let W=b(s,[t,...c],{stdio:"inherit"});if(W.error)return process.stderr.write(`rove: could not start Bun at ${s}: ${W.error.message}
6
+ `)}function w(s=process.env,t=process.stdin,c=process.stdout){if(s[e]==="1")return!1;if(s.CI==="true"||s.CI==="1")return!1;return Boolean(t.isTTY&&c.isTTY)}function M(s={},t=Q){let c=s.platform??process.platform,[b,...W]=u(c);if(!b)return null;let g=t(b,W,{stdio:"inherit"});if(g.error||g.status!==0)return null;return Z(s).bun}function l(s){if(typeof s.status==="number")return s.status;if(s.signal)return 128+(Object.hasOwn(K,s.signal)?K[s.signal]:0);return 1}var K={SIGINT:2,SIGQUIT:3,SIGKILL:9,SIGTERM:15};function S(s,t,c,b=Q){let W=b(s,[t,...c],{stdio:"inherit"});if(W.error)return process.stderr.write(`rove: could not start Bun at ${s}: ${W.error.message}. Check that this path is executable, or reinstall Bun from https://bun.sh.
7
7
  `),1;return l(W)}var E=h(import.meta.url),p=C(import.meta.url),m=n(E,`${p}-run.js`);async function ts(s){let t=a({input:process.stdin,output:process.stdout});try{let c=(await t.question(s)).trim().toLowerCase();return c===""||c==="y"||c==="yes"}finally{t.close()}}async function cs(){let s={launcherDir:E},t=Z(s);if(t.bun||!w())return t;let c=t.stale?`${p}: Bun ${t.stale.version} is too old for Rove (needs ${$}+). Install the latest Bun now? [Y/n] `:`${p}: Rove runs on the Bun runtime, and none is installed. Install Bun now? [Y/n] `;if(!await ts(c))return t;return{bun:M(s),stale:t.stale,unusable:t.unusable}}var O=globalThis.Bun;if(O){let s=O.version;if(s&&!Y()&&!X(s))process.stderr.write(j(process.execPath,s,p)),process.exit(1);await import(ss(m).href)}else{let{bun:s,stale:t,unusable:c}=await cs();if(!s){let b=t?j(t.path,t.version,p):c?v(c,p):D(p);process.stderr.write(b),process.exit(1)}process.exit(S(s,m,process.argv.slice(2)))}
@@ -3,7 +3,7 @@ name: rove
3
3
  description: Use when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell. Also the ONLY channel for messaging another agent session on this machine — `rove api send`, never a peer/MCP side channel.
4
4
  ---
5
5
 
6
- <!-- rove-skill-version: 57 — bump in lockstep with ROVE_SKILL_VERSION (src/lib/skill-install.ts). -->
6
+ <!-- rove-skill-version: 58 — bump in lockstep with ROVE_SKILL_VERSION (src/lib/skill-install.ts). -->
7
7
 
8
8
  # Rove shell control
9
9
 
@@ -281,8 +281,8 @@ collect --group <groupId> | --task-ids <csv> | --repo
281
281
  Names that have actually been guessed wrong here: `add --vendor` is
282
282
  `--command`; `read-output --task` is `--task-id`; per-field verbs
283
283
  (`set-<field>`, `rename`, `pin`) are all `update --<field>`; `dispatch --text` is
284
- `--prompt` (`--text` belongs to `note`); `issue-list` has no `--state` at all
285
- — filter its JSON yourself.
284
+ `--prompt` (`--text` belongs to `note`); `issue-list --state` is `--status`
285
+ (a comma list, beside `--search`).
286
286
 
287
287
  **[`references/api-flags.md`](references/api-flags.md) is every verb and flag.**
288
288
  Find your section by what you were ASKED, not by Rove's noun for it:
@@ -37,7 +37,7 @@ Four flag names that have actually been guessed wrong here, and what they are:
37
37
  | `add --vendor` | `add --command` (engine id or full command line) |
38
38
  | `read-output --task` | `read-output --task-id` |
39
39
  | `dispatch --text` | `dispatch --prompt` (`--text` belongs to `note`) |
40
- | `issue-list --state` | none — `issue-list` takes only `--repo`; filter the JSON yourself |
40
+ | `issue-list --state` | `issue-list --status` (comma list: `open,doing`) |
41
41
 
42
42
  `--count`/`--agents` require `--prompt`. `--branch` is single-task only.
43
43
  `--tab new` is the only placement that accepts `send --command`.
@@ -223,7 +223,7 @@ adopt --repo(REQ) --worktree(REQ) --branch --command --title
223
223
 
224
224
  <!-- generated:begin issues -->
225
225
  ```text
226
- issue-list --repo(REQ)
226
+ issue-list --repo(REQ) --status <S1,S2> --search
227
227
  issue-create --repo(REQ) --title(REQ) --body
228
228
  issue-update --repo(REQ) --id(REQ) --title --body --task --status{open|doing|hold|done}
229
229
  issue-delete --repo(REQ) --id(REQ)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/rove",
4
- "version": "0.9.246",
4
+ "version": "0.9.247",
5
5
  "description": "Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",
6
6
  "keywords": [
7
7
  "terminal",
@@ -88,7 +88,7 @@
88
88
  "@vitest/coverage-v8": "2.1.9",
89
89
  "knip": "^6.14.2",
90
90
  "react-devtools-core": "^7.0.1",
91
- "rove-weixin": "0.0.7",
91
+ "rove-weixin": "0.0.8",
92
92
  "typescript": "5.8.2",
93
93
  "vitest": "2.1.9"
94
94
  },