@sma1lboy/rove 0.9.177 → 0.9.179

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 (53) hide show
  1. package/dist/cli/{chunk-rmn9d90r.js → chunk-0vrv03qn.js} +1 -1
  2. package/dist/cli/{chunk-67jyf8x5.js → chunk-0xgd6as7.js} +1 -1
  3. package/dist/cli/{chunk-bdgwqx8f.js → chunk-1ngaph89.js} +1 -1
  4. package/dist/cli/{chunk-mwzmw8q4.js → chunk-1vpsb31h.js} +1 -1
  5. package/dist/cli/{chunk-ea9t4hh5.js → chunk-2ragcjyb.js} +1 -1
  6. package/dist/cli/{chunk-r0hekyyy.js → chunk-3dexjt11.js} +1 -1
  7. package/dist/cli/{chunk-wvb1f6pt.js → chunk-3p5yjwjs.js} +1 -1
  8. package/dist/cli/{chunk-gs4nhjah.js → chunk-4kweezsh.js} +2 -2
  9. package/dist/cli/{chunk-d7fk35g9.js → chunk-615s6xjd.js} +1 -1
  10. package/dist/cli/{chunk-dj5qqh6n.js → chunk-6f18r6vf.js} +1 -1
  11. package/dist/cli/{chunk-fg75vvv7.js → chunk-8cdrt8zx.js} +1 -1
  12. package/dist/cli/{chunk-ge7bva0a.js → chunk-8qx3959c.js} +1 -1
  13. package/dist/cli/{chunk-d608mvsf.js → chunk-8znc46fw.js} +1 -1
  14. package/dist/cli/{chunk-garjd34w.js → chunk-9d4tfysz.js} +1 -1
  15. package/dist/cli/{chunk-ajtxh7kg.js → chunk-ac0yv0v4.js} +1 -1
  16. package/dist/cli/{chunk-0c3pff95.js → chunk-bg16r4yh.js} +1 -1
  17. package/dist/cli/{chunk-94eb11hz.js → chunk-br6dggaa.js} +1 -1
  18. package/dist/cli/{chunk-ksfqd3sm.js → chunk-cnre6fbm.js} +1 -1
  19. package/dist/cli/chunk-d4fvkzp3.js +2 -0
  20. package/dist/cli/{chunk-d9y4wvpj.js → chunk-d8nmt9zt.js} +1 -1
  21. package/dist/cli/{chunk-364q4ak8.js → chunk-frdr9bjy.js} +1 -1
  22. package/dist/cli/{chunk-1ajvv66w.js → chunk-gpt8mj16.js} +1 -1
  23. package/dist/cli/{chunk-s72y2s88.js → chunk-gsy8xfh6.js} +1 -1
  24. package/dist/cli/chunk-hses07jj.js +8 -0
  25. package/dist/cli/{chunk-r2qn2k6r.js → chunk-k0xgtzm2.js} +1 -1
  26. package/dist/cli/{chunk-7w2vcjst.js → chunk-kweffk7w.js} +1 -1
  27. package/dist/cli/{chunk-xrqaqj84.js → chunk-ne34zknk.js} +1 -1
  28. package/dist/cli/{chunk-b3xxh6v9.js → chunk-nnmpben9.js} +2 -2
  29. package/dist/cli/{chunk-n3b6yr9e.js → chunk-nnscywzf.js} +1 -1
  30. package/dist/cli/{chunk-71g9dn38.js → chunk-nqkcrhpp.js} +1 -1
  31. package/dist/cli/{chunk-eg8ns7p3.js → chunk-pspw5k9e.js} +3 -3
  32. package/dist/cli/{chunk-8mn798a6.js → chunk-q8v9zad9.js} +1 -1
  33. package/dist/cli/{chunk-8zn7pdc2.js → chunk-r2r5krab.js} +1 -1
  34. package/dist/cli/{chunk-77m8h1x8.js → chunk-rwkbxtpe.js} +1 -1
  35. package/dist/cli/{chunk-8p120gdr.js → chunk-s0gqxhk7.js} +1 -1
  36. package/dist/cli/{chunk-ndvccptj.js → chunk-t0bfjapm.js} +3 -3
  37. package/dist/cli/chunk-te8g5azg.js +39 -0
  38. package/dist/cli/{chunk-5rta19wp.js → chunk-v5dmc2r6.js} +1 -1
  39. package/dist/cli/{chunk-s9h4m4k2.js → chunk-wdzhfbye.js} +1 -1
  40. package/dist/cli/{chunk-chfbbmf9.js → chunk-wz421xna.js} +1 -1
  41. package/dist/cli/{chunk-7r17j4te.js → chunk-xr30vfgt.js} +1 -1
  42. package/dist/cli/{chunk-9gezfdvn.js → chunk-xswrw836.js} +1 -1
  43. package/dist/cli/{chunk-6xwg11k1.js → chunk-y9bgn622.js} +1 -1
  44. package/dist/cli/{chunk-pz5y8f3r.js → chunk-z5x3cd7j.js} +1 -1
  45. package/dist/cli/{chunk-y8dn3rez.js → chunk-zkj59kkd.js} +1 -1
  46. package/dist/cli/{chunk-w2d429hk.js → chunk-zx7fkp8y.js} +1 -1
  47. package/dist/cli/index.js +3 -3
  48. package/dist/cli/kobe.js +1 -1
  49. package/dist/cli/rove.js +1 -1
  50. package/package.json +1 -1
  51. package/dist/cli/chunk-fbc5d1fq.js +0 -3
  52. package/dist/cli/chunk-khsq49yp.js +0 -2
  53. package/dist/cli/chunk-qqxw72nh.js +0 -8
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{buildEngineSessionLaunch,trustEngineWorktree}from"./chunk-364q4ak8.js";import{engineForkArgv,engineResumeArgv,withPinnedSessionId}from"./chunk-7r17j4te.js";import{t}from"./chunk-fa7s3d1e.js";import{tildify}from"./chunk-fczqwtmq.js";import{engineEntry,engineStatusPrefixes,isEnginePlaceholderTitle,stripEngineStatusPrefix}from"./chunk-80hf0bbr.js";import{pathSyntax}from"./chunk-f10n6063.js";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,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}}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,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"}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} KOBE_TASK_ID=${task} ROVE_TAB_ID=${tab} KOBE_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 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}
2
+ import{buildEngineSessionLaunch,trustEngineWorktree}from"./chunk-frdr9bjy.js";import{engineForkArgv,engineResumeArgv,withPinnedSessionId}from"./chunk-xr30vfgt.js";import{t}from"./chunk-fa7s3d1e.js";import{tildify}from"./chunk-fczqwtmq.js";import{engineEntry,engineStatusPrefixes,isEnginePlaceholderTitle,stripEngineStatusPrefix}from"./chunk-80hf0bbr.js";import{pathSyntax}from"./chunk-f10n6063.js";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,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}}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,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"}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} KOBE_TASK_ID=${task} ROVE_TAB_ID=${tab} KOBE_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 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
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,moveTab,selectTab,setTabSplit,tabPtyKey,tabPtyKeyFor,tabCwdFor,terminalTabsKey,forgetTaskTabsSnapshot,sweepOrphanTabsSnapshots};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{deriveTitleFromPrompt}from"./chunk-xb9b93ts.js";import{TaskDeletingError}from"./chunk-g7baby60.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,ensureHostedEngine,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,killHostedSessions,listHostedSessions,openHostedSessionHost,pastePromptWhenEngineUp,sessionHasEngine,trustEngineWorktree}from"./chunk-364q4ak8.js";import{engineLaunchArgv,protocolEntry}from"./chunk-7r17j4te.js";import{resolveLoginShell}from"./chunk-b99tf0jr.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})[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})[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}),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;if(!await sessionHasEngine(sessions.find((s)=>s.key===key)?.pid,engineArgv))return!1;return await deliverToHostedKey(host.rpc,key,prompt)!==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"};if(!await sessionHasEngine(sessions.find((s)=>s.key===key)?.pid,engineArgv))return{outcome:"no-engine",tabId:tabIdFromHostedKey(key)};return await deliverToHostedKey(host.rpc,key,prompt)===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});if(!await sessionHasEngine(session.pid,engineArgv))return{outcome:"no-engine",tabId:target.tabId};return await deliverToHostedKey(host.rpc,key,prompt)===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))}catch{}finally{host.close()}}
2
+ import{deriveTitleFromPrompt}from"./chunk-xb9b93ts.js";import{TaskDeletingError}from"./chunk-g7baby60.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,ensureHostedEngine,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,killHostedSessions,listHostedSessions,openHostedSessionHost,pastePromptWhenEngineUp,sessionHasEngine,trustEngineWorktree}from"./chunk-frdr9bjy.js";import{engineLaunchArgv,protocolEntry}from"./chunk-xr30vfgt.js";import{resolveLoginShell}from"./chunk-b99tf0jr.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})[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})[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}),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;if(!await sessionHasEngine(sessions.find((s)=>s.key===key)?.pid,engineArgv))return!1;return await deliverToHostedKey(host.rpc,key,prompt)!==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"};if(!await sessionHasEngine(sessions.find((s)=>s.key===key)?.pid,engineArgv))return{outcome:"no-engine",tabId:tabIdFromHostedKey(key)};return await deliverToHostedKey(host.rpc,key,prompt)===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});if(!await sessionHasEngine(session.pid,engineArgv))return{outcome:"no-engine",tabId:target.tabId};return await deliverToHostedKey(host.rpc,key,prompt)===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))}catch{}finally{host.close()}}
3
3
  export{deriveTitleFromSession,deriveTitleFromSessionId,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,tearDownTaskSessionAdapter};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Orchestrator}from"./chunk-534se0f6.js";import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-67jyf8x5.js";import{GH_PR_VIEW_FIELDS,classifyGhFailure,mapGhPrView,nextPrPoll,samePrStatus}from"./chunk-hfpmeck1.js";import"./chunk-2kb4z64z.js";import{resolvePluginBinPath}from"./chunk-7nndmapz.js";import{GitWorktreeManager,parseDirtyPaths}from"./chunk-esgxxnwn.js";import{auditDeletionBranchKept,auditDeletionResidue,auditDeletionSalvaged,auditWorktreeResidue,auditWorktreeSalvaged,parseAheadBehind,startDaemonServer}from"./chunk-ea9t4hh5.js";import"./chunk-px6axbd9.js";import"./chunk-rz8zs7j8.js";import"./chunk-xsrcwcjc.js";import"./chunk-jpdf97cx.js";import{TaskIndexStore}from"./chunk-xjnd1hwr.js";import"./chunk-a74pa16c.js";import"./chunk-bkm7vxr5.js";import{parsePorcelain}from"./chunk-xqw5d5rv.js";import"./chunk-h4n8ffqy.js";import{DEFAULT_BASE_REF_CANDIDATES,readHeadSha,readRefSha,resolveGitDirs}from"./chunk-vyb5a2rh.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-xb9b93ts.js";import{affectsActivityState,isEngineActivityKind}from"./chunk-3e5n28t6.js";import"./chunk-g7baby60.js";import"./chunk-r2pztgm6.js";import"./chunk-g2e1dmxh.js";import"./chunk-63wmhbqs.js";import"./chunk-qkehg2c1.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import{CURRENT_VERSION,checkLatestVersion}from"./chunk-n3b6yr9e.js";import{autoStatusEnabled}from"./chunk-364q4ak8.js";import{execHostForWorktreePath}from"./chunk-jg61s3ce.js";import"./chunk-bkba9c4n.js";import"./chunk-g2advs8t.js";import"./chunk-s72y2s88.js";import{GENERIC_PROTOCOL,engineProtocolKey,getEngineProtocol,protocolEntry,resolveCommandProtocol,sessionProtocol}from"./chunk-7r17j4te.js";import{installDaemonCrashHandlers,logDaemonInfo}from"./chunk-rcyasw34.js";import"./chunk-7q67dz4c.js";import"./chunk-92d2t5sk.js";import"./chunk-hape5vwj.js";import{engineDisplayName,kobeApiInvocation}from"./chunk-km4hx6kc.js";import"./chunk-6tvs0r4z.js";import"./chunk-z7c6nap0.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-b99tf0jr.js";import"./chunk-w25b7xxz.js";import"./chunk-jvxh93nz.js";import{connectOrStartDaemon,daemonSpawnReason}from"./chunk-fbc5d1fq.js";import{stopDaemonProcess}from"./chunk-y13681dw.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import{foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-pz5y8f3r.js";import{createEngineTurnDetector,engineEntry,engineTitleTurnHint,vendorsWithQuotaProbe}from"./chunk-80hf0bbr.js";import{spawnCapture}from"./chunk-khj0apc7.js";import{availableEngineIds}from"./chunk-5zh5fcpe.js";import"./chunk-w7zv47mp.js";import"./chunk-v61s3fps.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-r9gfh1zz.js";import{DEFAULT_TASK_VENDOR,isTaskStatus}from"./chunk-xy8be792.js";import{backfillSavedReposFromProjects,getCustomEngineIds,getPersistedString,getRemoteRepoConfig,getSavedRepos,setPersistedString}from"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import{releaseSync}from"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import{isProcessAlive,readPidFile}from"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import{migrateRoveDaemonStateLayout}from"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-pxk2c2vj.js";import"./chunk-0q6h4vt4.js";import{rotateLogIfNeeded}from"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-8cjr5ypt.js";import{readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";function sniffProtocolFromTitle(title){let trimmed=title?.trim();if(!trimmed)return null;let owners=new Map;for(let vendor of BUILTIN_VENDORS)for(let glyph of engineEntry(vendor).terminalTitle?.statusPrefixes??[])owners.set(glyph,[...owners.get(glyph)??[],vendor]);for(let glyph of[...owners.keys()].sort((a,b)=>b.length-a.length)){if(!trimmed.startsWith(glyph))continue;if(trimmed.slice(glyph.length).trim().length===0)continue;let vendors=owners.get(glyph)??[];if(vendors.length===1)return vendors[0];return null}return null}function protocolUpgradeFromLiveSession(task,evidence){let command=task.command?.trim();if(!command)return null;if(task.vendor&&isBuiltinVendor(task.vendor))return null;if(resolveCommandProtocol(command)!==GENERIC_PROTOCOL)return null;let walk=evidence.walkVendor,vendor=walk!==null&&isBuiltinVendor(walk)?walk:sniffProtocolFromTitle(evidence.title);return vendor?{command,vendor}:null}function protocolWriteBackFromLiveSession(task,evidence,customEngineIds){let id=task.vendor?.trim();if(!id)return null;if(getEngineProtocol(id)!==void 0)return null;if(!customEngineIds.includes(id))return null;let walk=evidence.walkVendor;return walk!==null&&isBuiltinVendor(walk)?{id,protocol:walk}:null}async function latestTranscriptMtime(vendor,worktree){if(!worktree)return 0;return protocolEntry(vendor).history.latestTranscriptMtimeForWorktree(worktree)}async function maybeAutoStart(orch,taskId,enabled=autoStatusEnabled){if(!enabled())return"skipped";let task=orch.getTask(taskId);if(!task)return"skipped";if((task.kind??"task")==="main")return"skipped";if(task.status!=="backlog")return"skipped";return await orch.setStatus(taskId,"in_progress"),"moved"}var SYNC_TIMEOUT_MS=60000,SYNC_CONFLICT="SYNC_CONFLICT",SYNC_DIRTY="SYNC_WORKTREE_DIRTY";async function git(cwd,args,signal,write=!1){return spawnCapture("git",args,{cwd,env:write?process.env:readOnlyGitProcessEnv(),signal})}function parseConflictedPaths(stdout){return stdout.split(`
2
+ import{Orchestrator}from"./chunk-534se0f6.js";import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-0xgd6as7.js";import{GH_PR_VIEW_FIELDS,classifyGhFailure,mapGhPrView,nextPrPoll,samePrStatus}from"./chunk-hfpmeck1.js";import"./chunk-2kb4z64z.js";import{resolvePluginBinPath}from"./chunk-7nndmapz.js";import{GitWorktreeManager,parseDirtyPaths}from"./chunk-esgxxnwn.js";import{auditDeletionBranchKept,auditDeletionResidue,auditDeletionSalvaged,auditWorktreeResidue,auditWorktreeSalvaged,parseAheadBehind,startDaemonServer}from"./chunk-2ragcjyb.js";import"./chunk-px6axbd9.js";import"./chunk-rz8zs7j8.js";import"./chunk-xsrcwcjc.js";import"./chunk-jpdf97cx.js";import{TaskIndexStore}from"./chunk-xjnd1hwr.js";import"./chunk-a74pa16c.js";import"./chunk-bkm7vxr5.js";import{parsePorcelain}from"./chunk-xqw5d5rv.js";import"./chunk-h4n8ffqy.js";import{DEFAULT_BASE_REF_CANDIDATES,readHeadSha,readRefSha,resolveGitDirs}from"./chunk-vyb5a2rh.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-xb9b93ts.js";import{affectsActivityState,isEngineActivityKind}from"./chunk-3e5n28t6.js";import"./chunk-g7baby60.js";import"./chunk-r2pztgm6.js";import"./chunk-g2e1dmxh.js";import"./chunk-63wmhbqs.js";import"./chunk-qkehg2c1.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import{CURRENT_VERSION,checkLatestVersion}from"./chunk-nnscywzf.js";import{autoStatusEnabled}from"./chunk-frdr9bjy.js";import{execHostForWorktreePath}from"./chunk-jg61s3ce.js";import"./chunk-bkba9c4n.js";import"./chunk-g2advs8t.js";import"./chunk-gsy8xfh6.js";import{GENERIC_PROTOCOL,engineProtocolKey,getEngineProtocol,protocolEntry,resolveCommandProtocol,sessionProtocol}from"./chunk-xr30vfgt.js";import{installDaemonCrashHandlers,logDaemonInfo}from"./chunk-rcyasw34.js";import"./chunk-7q67dz4c.js";import"./chunk-92d2t5sk.js";import"./chunk-hape5vwj.js";import{engineDisplayName,kobeApiInvocation}from"./chunk-km4hx6kc.js";import"./chunk-6tvs0r4z.js";import"./chunk-z7c6nap0.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-b99tf0jr.js";import"./chunk-w25b7xxz.js";import"./chunk-jvxh93nz.js";import{connectOrStartDaemon,daemonSpawnReason}from"./chunk-te8g5azg.js";import{stopDaemonProcess}from"./chunk-y13681dw.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import{foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-z5x3cd7j.js";import{createEngineTurnDetector,engineEntry,engineTitleTurnHint,vendorsWithQuotaProbe}from"./chunk-80hf0bbr.js";import{spawnCapture}from"./chunk-khj0apc7.js";import{availableEngineIds}from"./chunk-5zh5fcpe.js";import"./chunk-w7zv47mp.js";import"./chunk-v61s3fps.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-r9gfh1zz.js";import{DEFAULT_TASK_VENDOR,isTaskStatus}from"./chunk-xy8be792.js";import{backfillSavedReposFromProjects,getCustomEngineIds,getPersistedString,getRemoteRepoConfig,getSavedRepos,setPersistedString}from"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import{releaseSync}from"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import{isProcessAlive,readPidFile}from"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import{migrateRoveDaemonStateLayout}from"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-pxk2c2vj.js";import"./chunk-0q6h4vt4.js";import{rotateLogIfNeeded}from"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-8cjr5ypt.js";import{readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";function sniffProtocolFromTitle(title){let trimmed=title?.trim();if(!trimmed)return null;let owners=new Map;for(let vendor of BUILTIN_VENDORS)for(let glyph of engineEntry(vendor).terminalTitle?.statusPrefixes??[])owners.set(glyph,[...owners.get(glyph)??[],vendor]);for(let glyph of[...owners.keys()].sort((a,b)=>b.length-a.length)){if(!trimmed.startsWith(glyph))continue;if(trimmed.slice(glyph.length).trim().length===0)continue;let vendors=owners.get(glyph)??[];if(vendors.length===1)return vendors[0];return null}return null}function protocolUpgradeFromLiveSession(task,evidence){let command=task.command?.trim();if(!command)return null;if(task.vendor&&isBuiltinVendor(task.vendor))return null;if(resolveCommandProtocol(command)!==GENERIC_PROTOCOL)return null;let walk=evidence.walkVendor,vendor=walk!==null&&isBuiltinVendor(walk)?walk:sniffProtocolFromTitle(evidence.title);return vendor?{command,vendor}:null}function protocolWriteBackFromLiveSession(task,evidence,customEngineIds){let id=task.vendor?.trim();if(!id)return null;if(getEngineProtocol(id)!==void 0)return null;if(!customEngineIds.includes(id))return null;let walk=evidence.walkVendor;return walk!==null&&isBuiltinVendor(walk)?{id,protocol:walk}:null}async function latestTranscriptMtime(vendor,worktree){if(!worktree)return 0;return protocolEntry(vendor).history.latestTranscriptMtimeForWorktree(worktree)}async function maybeAutoStart(orch,taskId,enabled=autoStatusEnabled){if(!enabled())return"skipped";let task=orch.getTask(taskId);if(!task)return"skipped";if((task.kind??"task")==="main")return"skipped";if(task.status!=="backlog")return"skipped";return await orch.setStatus(taskId,"in_progress"),"moved"}var SYNC_TIMEOUT_MS=60000,SYNC_CONFLICT="SYNC_CONFLICT",SYNC_DIRTY="SYNC_WORKTREE_DIRTY";async function git(cwd,args,signal,write=!1){return spawnCapture("git",args,{cwd,env:write?process.env:readOnlyGitProcessEnv(),signal})}function parseConflictedPaths(stdout){return stdout.split(`
3
3
  `).map((line)=>line.trim()).filter((line)=>line.length>0)}async function syncWorktreeWithBase(worktreePath,baseRef,signal){let status=await git(worktreePath,["status","--porcelain=v1"],signal);if(status.status!==0)throw Error("git status failed");let dirty=parseDirtyPaths(status.stdout);if(dirty.length>0)throw Error(`${SYNC_DIRTY}: ${dirty.join(", ")}`);let before=await git(worktreePath,["rev-parse","HEAD"],signal),merge=await git(worktreePath,["merge","--no-edit",baseRef],signal,!0);if(merge.status!==0){let conflicted=await git(worktreePath,["diff","--name-only","--diff-filter=U"],signal),paths=parseConflictedPaths(conflicted.stdout);if(paths.length>0)throw Error(`${SYNC_CONFLICT}: ${paths.join(", ")}`);let detail=merge.stderr?.trim();throw Error(detail?`git merge ${baseRef} failed \u2014 ${detail}`:`git merge ${baseRef} failed`)}let after=await git(worktreePath,["rev-parse","HEAD"],signal);return{baseRef,alreadyCurrent:before.status===0&&before.stdout.trim()===after.stdout.trim()}}import{readFileSync}from"fs";import{join}from"path";var BASE_REF_TTL_MS=300000,cache=new Map;async function git2(worktreePath,args,signal){return await spawnCapture("git",[...args],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal})}async function refExists(worktreePath,ref,signal){return(await git2(worktreePath,["rev-parse","--verify","--quiet",ref],signal)).status===0}async function sharesHistory(worktreePath,ref,signal){return(await git2(worktreePath,["merge-base",ref,"HEAD"],signal)).status===0}async function baseCheckoutBranchFromGit(worktreePath,signal){let out=await git2(worktreePath,["worktree","list","--porcelain"],signal);if(out.status!==0)return null;return(out.stdout.split(`
4
4
 
5
5
  `,1)[0]??"").split(`
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CURRENT_VERSION,repoSlug}from"./chunk-n3b6yr9e.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
2
+ import{CURRENT_VERSION,repoSlug}from"./chunk-nnscywzf.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,5 +1,5 @@
1
1
  // @bun
2
- import{IssuesStore,countCronBetween,defaultIssuesStorePath,isValidCron,latestCronAtOrBefore,nextCronAfter,resolveRepoRoot,tightenInstalledPluginPermissions}from"./chunk-px6axbd9.js";import{ClientWriter,LineReceiver,linkLegacyRuntimePath,objectPayload,optionalActivityDetail,optionalBoolean,optionalNumber,optionalString,optionalVendor,requireNumber,requireString}from"./chunk-rz8zs7j8.js";import{serialized,writeJsonAtomic,writeTextAtomic}from"./chunk-xsrcwcjc.js";import{buildPluginEnv}from"./chunk-jpdf97cx.js";import{ENGINE_EXIT_BANNER,engineExitCodeFromTail,plainTail,readPtyExitRecords,readPtyExitStore,recordEngineExit}from"./chunk-a74pa16c.js";import{parsePorcelainRows}from"./chunk-h4n8ffqy.js";import{worktreeFingerprint}from"./chunk-vyb5a2rh.js";import{STICKY_STATES,activityStillWorking,reduceActivity,resolveEngineStateTtlMs}from"./chunk-r2pztgm6.js";import{currentPluginPlatform,loadPluginRegistry,pluginConfigDir,pluginLogPath,pluginManifestPath,pluginRegistryPath,pluginStateDir,readPluginManifest,supportsPlatform}from"./chunk-g2e1dmxh.js";import{managedWorktreeRootsFor,readWorktreeBaseOverride}from"./chunk-63wmhbqs.js";import{ptyHostHasLiveSessions,sweepPtyHostSessions}from"./chunk-s72y2s88.js";import{logDaemonError,logDaemonInfo}from"./chunk-rcyasw34.js";import{resolveLoginShell}from"./chunk-b99tf0jr.js";import{probeDaemonSocket}from"./chunk-fbc5d1fq.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import{CHANNEL_NAMES,DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,attentionInboxItemKey,automationRunNeedsAttention,displayTaskTitle,frameToLine,isAttentionInboxState,isProtocolCompatible,normalizeChannelFilter,parseDaemonStopReason,serializeTask}from"./chunk-re5ke4fz.js";import{decodeCapturedChunks,maybeStartScheduledRun}from"./chunk-khj0apc7.js";import{defaultKeybindingsPath,defaultUiPrefsStatePath}from"./chunk-q5jhy3t8.js";import{createSocketOwnershipGuard,isProcessAlive,listenOnUnixSocket}from"./chunk-t915by6w.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE,ensureOwnerOnlyStateDir}from"./chunk-9prawccj.js";import{rotateLogIfNeeded}from"./chunk-pw6yfj10.js";import{pathIdentity,pathSyntax,pathWithin,samePath}from"./chunk-f10n6063.js";import{defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyExitsPath,defaultPtyHostSocketPath,legacyDaemonPidPath,legacyDaemonSocketPath,resolveDaemonHomeDir}from"./chunk-8cjr5ypt.js";import{ROVE_STATE_DIR_BASENAME,readRoveEnv,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{mkdir,unlink as unlink2}from"fs/promises";import{createServer}from"net";import{dirname as dirname2}from"path";import{statSync}from"fs";var WATCHED_FIELDS=["title","branch","worktreePath","status","pinned","vendor","command","modelEffort","linkedWorkItem","scratch"];function same(a,b){if(a===b)return!0;if(a==null||b==null)return a==null&&b==null;if(typeof a==="object"||typeof b==="object")return JSON.stringify(a)===JSON.stringify(b);return!1}function samePr(a,b){let strip=(v)=>{if(v==null||typeof v!=="object"||Array.isArray(v))return v;let{lastCheckedAt:_a,lastError:_b,...rest}=v;return rest};return same(strip(a),strip(b))}function diffTask(prev,next){let fields=[],from={},to={};for(let field of WATCHED_FIELDS){let a=prev[field],b=next[field];if(same(a,b))continue;if(fields.push(field),a!==void 0)from[field]=a;if(b!==void 0)to[field]=b}let prChanged=!samePr(prev.prStatus,next.prStatus);if(fields.length===0&&!prChanged)return null;return{fields,from,to,prChanged,worktreeCreated:next.kind==="task"&&!prev.worktreePath&&!!next.worktreePath}}function bornWithWorktree(task){return task.kind==="task"&&!!task.worktreePath}function lifecycleEventFor(kind,detail){switch(kind){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return detail?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}var AGENT_EVENT_BY_STATE={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"};function taskContext(task){if(!task)return;let{id,title,repo,branch,worktreePath,vendor,status}=task;return{id,title,repo,branch,worktreePath,vendor,status}}class PluginEventReducer{tasks;agentState=new Map;now;constructor(now=Date.now){this.now=now}contextFor(taskId){return taskContext(this.tasks?.get(taskId))}reduce(event){switch(event.channel){case"task.snapshot":return this.reduceTasks(event.payload.tasks);case"engine-state":return this.reduceEngine(event.payload);default:return[]}}reduceTasks(tasks){let next=new Map(tasks.map((t)=>[t.id,t])),prev=this.tasks;if(this.tasks=next,!prev)return[];let at=this.now(),out=[];for(let[id,task]of next){let before=prev.get(id);if(!before){if(out.push({event:"task.created",taskId:id,task:taskContext(task),at}),bornWithWorktree(task))out.push({event:"worktree.created",taskId:id,task:taskContext(task),at});continue}let diff=diffTask(before,task);if(!diff)continue;let ctx=taskContext(task);if(diff.fields.length>0)out.push({event:"task.changed",taskId:id,task:ctx,detail:{fields:diff.fields,from:diff.from,to:diff.to},at});if(diff.prChanged)out.push({event:"task.pr-changed",taskId:id,task:ctx,detail:{...before.prStatus!==void 0?{from:before.prStatus}:{},...task.prStatus!==void 0?{to:task.prStatus}:{}},at});if(diff.worktreeCreated)out.push({event:"worktree.created",taskId:id,task:ctx,at})}for(let[id,task]of prev)if(!next.has(id))out.push({event:"task.deleted",taskId:id,task:taskContext(task),at});return out}reduceEngine(payload){let key=`${payload.taskId}\x00${payload.tabId??""}`,prev=this.agentState.get(key);if(this.agentState.set(key,payload.state),prev===payload.state)return[];let event=AGENT_EVENT_BY_STATE[payload.state];if(!event)return[];return[{event,taskId:payload.taskId,task:taskContext(this.tasks?.get(payload.taskId)),...payload.tabId?{tabId:payload.tabId}:{},at:this.now()}]}}import{spawn}from"child_process";import{appendFileSync,mkdirSync}from"fs";var OUTPUT_CAP=8192,PLUGIN_LOG_CAP_BYTES=4194304,SHUTDOWN_GRACE_MS=3000,HOOK_TIMEOUT_MS=30000,HOOK_SLOW_MS=2000;function hookTimeoutMs(spec,kind){return spec.timeoutMs??(kind==="shutdown"?SHUTDOWN_GRACE_MS:HOOK_TIMEOUT_MS)}function appendRecord(pluginId,homeDir,record){try{let logPath=pluginLogPath(pluginId,homeDir);rotateLogIfNeeded(logPath,PLUGIN_LOG_CAP_BYTES),appendFileSync(logPath,`${JSON.stringify(record)}
2
+ import{IssuesStore,countCronBetween,defaultIssuesStorePath,isValidCron,latestCronAtOrBefore,nextCronAfter,resolveRepoRoot,tightenInstalledPluginPermissions}from"./chunk-px6axbd9.js";import{ClientWriter,LineReceiver,linkLegacyRuntimePath,objectPayload,optionalActivityDetail,optionalBoolean,optionalNumber,optionalString,optionalVendor,requireNumber,requireString}from"./chunk-rz8zs7j8.js";import{serialized,writeJsonAtomic,writeTextAtomic}from"./chunk-xsrcwcjc.js";import{buildPluginEnv}from"./chunk-jpdf97cx.js";import{ENGINE_EXIT_BANNER,engineExitCodeFromTail,plainTail,readPtyExitRecords,readPtyExitStore,recordEngineExit}from"./chunk-a74pa16c.js";import{parsePorcelainRows}from"./chunk-h4n8ffqy.js";import{worktreeFingerprint}from"./chunk-vyb5a2rh.js";import{STICKY_STATES,activityStillWorking,reduceActivity,resolveEngineStateTtlMs}from"./chunk-r2pztgm6.js";import{currentPluginPlatform,loadPluginRegistry,pluginConfigDir,pluginLogPath,pluginManifestPath,pluginRegistryPath,pluginStateDir,readPluginManifest,supportsPlatform}from"./chunk-g2e1dmxh.js";import{managedWorktreeRootsFor,readWorktreeBaseOverride}from"./chunk-63wmhbqs.js";import{ptyHostHasLiveSessions,sweepPtyHostSessions}from"./chunk-gsy8xfh6.js";import{logDaemonError,logDaemonInfo}from"./chunk-rcyasw34.js";import{resolveLoginShell}from"./chunk-b99tf0jr.js";import{probeDaemonSocket}from"./chunk-te8g5azg.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import{CHANNEL_NAMES,DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,attentionInboxItemKey,automationRunNeedsAttention,displayTaskTitle,frameToLine,isAttentionInboxState,isProtocolCompatible,normalizeChannelFilter,parseDaemonStopReason,serializeTask}from"./chunk-re5ke4fz.js";import{decodeCapturedChunks,maybeStartScheduledRun}from"./chunk-khj0apc7.js";import{defaultKeybindingsPath,defaultUiPrefsStatePath}from"./chunk-q5jhy3t8.js";import{createSocketOwnershipGuard,isProcessAlive,listenOnUnixSocket}from"./chunk-t915by6w.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE,ensureOwnerOnlyStateDir}from"./chunk-9prawccj.js";import{rotateLogIfNeeded}from"./chunk-pw6yfj10.js";import{pathIdentity,pathSyntax,pathWithin,samePath}from"./chunk-f10n6063.js";import{defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyExitsPath,defaultPtyHostSocketPath,legacyDaemonPidPath,legacyDaemonSocketPath,resolveDaemonHomeDir}from"./chunk-8cjr5ypt.js";import{ROVE_STATE_DIR_BASENAME,readRoveEnv,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{mkdir,unlink as unlink2}from"fs/promises";import{createServer}from"net";import{dirname as dirname2}from"path";import{statSync}from"fs";var WATCHED_FIELDS=["title","branch","worktreePath","status","pinned","vendor","command","modelEffort","linkedWorkItem","scratch"];function same(a,b){if(a===b)return!0;if(a==null||b==null)return a==null&&b==null;if(typeof a==="object"||typeof b==="object")return JSON.stringify(a)===JSON.stringify(b);return!1}function samePr(a,b){let strip=(v)=>{if(v==null||typeof v!=="object"||Array.isArray(v))return v;let{lastCheckedAt:_a,lastError:_b,...rest}=v;return rest};return same(strip(a),strip(b))}function diffTask(prev,next){let fields=[],from={},to={};for(let field of WATCHED_FIELDS){let a=prev[field],b=next[field];if(same(a,b))continue;if(fields.push(field),a!==void 0)from[field]=a;if(b!==void 0)to[field]=b}let prChanged=!samePr(prev.prStatus,next.prStatus);if(fields.length===0&&!prChanged)return null;return{fields,from,to,prChanged,worktreeCreated:next.kind==="task"&&!prev.worktreePath&&!!next.worktreePath}}function bornWithWorktree(task){return task.kind==="task"&&!!task.worktreePath}function lifecycleEventFor(kind,detail){switch(kind){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return detail?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}var AGENT_EVENT_BY_STATE={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"};function taskContext(task){if(!task)return;let{id,title,repo,branch,worktreePath,vendor,status}=task;return{id,title,repo,branch,worktreePath,vendor,status}}class PluginEventReducer{tasks;agentState=new Map;now;constructor(now=Date.now){this.now=now}contextFor(taskId){return taskContext(this.tasks?.get(taskId))}reduce(event){switch(event.channel){case"task.snapshot":return this.reduceTasks(event.payload.tasks);case"engine-state":return this.reduceEngine(event.payload);default:return[]}}reduceTasks(tasks){let next=new Map(tasks.map((t)=>[t.id,t])),prev=this.tasks;if(this.tasks=next,!prev)return[];let at=this.now(),out=[];for(let[id,task]of next){let before=prev.get(id);if(!before){if(out.push({event:"task.created",taskId:id,task:taskContext(task),at}),bornWithWorktree(task))out.push({event:"worktree.created",taskId:id,task:taskContext(task),at});continue}let diff=diffTask(before,task);if(!diff)continue;let ctx=taskContext(task);if(diff.fields.length>0)out.push({event:"task.changed",taskId:id,task:ctx,detail:{fields:diff.fields,from:diff.from,to:diff.to},at});if(diff.prChanged)out.push({event:"task.pr-changed",taskId:id,task:ctx,detail:{...before.prStatus!==void 0?{from:before.prStatus}:{},...task.prStatus!==void 0?{to:task.prStatus}:{}},at});if(diff.worktreeCreated)out.push({event:"worktree.created",taskId:id,task:ctx,at})}for(let[id,task]of prev)if(!next.has(id))out.push({event:"task.deleted",taskId:id,task:taskContext(task),at});return out}reduceEngine(payload){let key=`${payload.taskId}\x00${payload.tabId??""}`,prev=this.agentState.get(key);if(this.agentState.set(key,payload.state),prev===payload.state)return[];let event=AGENT_EVENT_BY_STATE[payload.state];if(!event)return[];return[{event,taskId:payload.taskId,task:taskContext(this.tasks?.get(payload.taskId)),...payload.tabId?{tabId:payload.tabId}:{},at:this.now()}]}}import{spawn}from"child_process";import{appendFileSync,mkdirSync}from"fs";var OUTPUT_CAP=8192,PLUGIN_LOG_CAP_BYTES=4194304,SHUTDOWN_GRACE_MS=3000,HOOK_TIMEOUT_MS=30000,HOOK_SLOW_MS=2000;function hookTimeoutMs(spec,kind){return spec.timeoutMs??(kind==="shutdown"?SHUTDOWN_GRACE_MS:HOOK_TIMEOUT_MS)}function appendRecord(pluginId,homeDir,record){try{let logPath=pluginLogPath(pluginId,homeDir);rotateLogIfNeeded(logPath,PLUGIN_LOG_CAP_BYTES),appendFileSync(logPath,`${JSON.stringify(record)}
3
3
  `,{mode:OWNER_ONLY_FILE_MODE})}catch{}}async function runPluginHook(opts){let{pluginId,spec,kind,label,homeDir}=opts,timeoutMs=hookTimeoutMs(spec,kind),startedAt=Date.now();try{mkdirSync(pluginConfigDir(pluginId,homeDir),{recursive:!0,mode:OWNER_ONLY_DIR_MODE}),mkdirSync(pluginStateDir(pluginId,homeDir),{recursive:!0,mode:OWNER_ONLY_DIR_MODE})}catch(err){appendRecord(pluginId,homeDir,{at:startedAt,kind,label,command:spec.command,exitCode:null,durationMs:Date.now()-startedAt,spawnError:String(err)}),opts.log?.(`plugin ${pluginId} ${label}: ${String(err)}`);return}let exitCode=null,stdout="",stderr="",spawnError,timedOut=!1;if(await new Promise((resolve)=>{let[cmd,...args]=spec.command,child=spawn(cmd,args,{cwd:opts.pluginRoot,env:buildPluginEnv({homeDir,socketPath:opts.socketPath,binPath:opts.binPath,pluginId,pluginRoot:opts.pluginRoot,extra:opts.extraEnv}),stdio:["ignore","pipe","pipe"],detached:!0}),kill=()=>{try{if(child.pid)process.kill(-child.pid,"SIGKILL");else child.kill("SIGKILL")}catch{child.kill("SIGKILL")}},deadline=setTimeout(()=>{timedOut=!0,kill()},timeoutMs);deadline.unref?.();let slow=setTimeout(()=>{appendRecord(pluginId,homeDir,{at:startedAt,kind,label,command:spec.command,phase:"running",runningMs:Date.now()-startedAt,timeoutMs})},Math.min(HOOK_SLOW_MS,Math.floor(timeoutMs/2)));slow.unref?.(),opts.inFlight?.add(kill);let finish=()=>{clearTimeout(deadline),clearTimeout(slow),opts.inFlight?.delete(kill),resolve()};child.stdout.on("data",(chunk)=>{if(stdout.length<OUTPUT_CAP)stdout+=chunk.toString().slice(0,OUTPUT_CAP-stdout.length)}),child.stderr.on("data",(chunk)=>{if(stderr.length<OUTPUT_CAP)stderr+=chunk.toString().slice(0,OUTPUT_CAP-stderr.length)}),child.on("error",(err)=>{spawnError=String(err),finish()}),child.on("close",(code)=>{exitCode=code,finish()})}),appendRecord(pluginId,homeDir,{at:startedAt,kind,label,command:spec.command,exitCode,durationMs:Date.now()-startedAt,...timedOut?{timedOut:!0,timeoutMs}:{},...stdout?{stdout}:{},...stderr?{stderr}:{},...spawnError?{spawnError}:{}}),timedOut)opts.log?.(`plugin ${pluginId} ${label}: killed after ${timeoutMs}ms (hook did not exit)`);else if(spawnError||exitCode!==null&&exitCode!==0)opts.log?.(`plugin ${pluginId} ${label}: ${spawnError??`exit ${exitCode}`}`)}var RELOAD_DEBOUNCE_MS=150,REGISTRY_POLL_MS=200;function fileStamp(path){if(!path)return"absent";try{let s=statSync(path,{bigint:!0});return`${s.mtimeNs}:${s.size}:${s.ino}`}catch{return"absent"}}function startPluginHost(bus,opts){let host=new PluginHost(opts);bus.onPublish((event)=>host.handleChannel(event));for(let event of bus.snapshot())host.handleChannel(event);return host.start(),host}function maybeStartPluginHost(bus,options,socketPath,log){if(!options.plugins)return null;return startPluginHost(bus,{homeDir:options.homeDir,socketPath,binPath:options.plugins.binPath,log})}class PluginHost{opts;reducer=new PluginEventReducer;plugins=[];enabledIds=new Set;manifestStamps=new Map;pollTimer;registryStamp="";reloadTimer;inFlight=new Set;stopped=!1;constructor(opts){this.opts=opts}start(){this.watchRegistry(),this.plugins=this.loadPlugins();for(let plugin of this.plugins)for(let[i,hook]of plugin.manifest.startup.entries()){if(!supportsPlatform(hook,plugin.manifest,currentPluginPlatform()))continue;this.run(plugin,hook,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${i}]`)}}async stop(){if(this.stopped)return;if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);if(this.pollTimer)clearInterval(this.pollTimer);for(let kill of[...this.inFlight])kill();let runs=[];for(let plugin of this.plugins)for(let[i,hook]of plugin.manifest.shutdown.entries()){if(!supportsPlatform(hook,plugin.manifest,currentPluginPlatform()))continue;runs.push(this.run(plugin,hook,"shutdown",{ROVE_PLUGIN_EVENT:"shutdown"},`shutdown[${i}]`))}await Promise.allSettled(runs)}handleChannel(event){if(this.stopped)return;try{for(let derived of this.reducer.reduce(event))this.dispatch(derived)}catch(err){this.opts.log?.(`plugin event reduce failed on ${event.channel} \u2014 ${String(err)}`)}}handleUiReport(report){if(this.stopped)return;try{this.dispatch({event:report.kind,...report.taskId?{taskId:report.taskId,task:this.reducer.contextFor(report.taskId)}:{},...report.detail?{detail:report.detail}:{},at:Date.now()})}catch(err){this.opts.log?.(`plugin ui-report dispatch failed for ${report.kind} \u2014 ${String(err)}`)}}handleEngineReport(report){if(this.stopped)return;let event=lifecycleEventFor(report.kind,report.detail);if(!event)return;try{this.dispatch({event,taskId:report.taskId,task:this.reducer.contextFor(report.taskId),...report.vendor?{vendor:report.vendor}:{},...report.tabId?{tabId:report.tabId}:{},...report.sessionId?{sessionId:report.sessionId}:{},...report.detail?{detail:report.detail}:{},at:Date.now()})}catch(err){this.opts.log?.(`plugin engine-report dispatch failed for ${event} \u2014 ${String(err)}`)}}dispatchTo(plugin,event){let platform=currentPluginPlatform();try{for(let hook of plugin.manifest.events){if(hook.on!==event.event)continue;if(!supportsPlatform(hook,plugin.manifest,platform))continue;this.run(plugin,hook,"event",{ROVE_PLUGIN_EVENT:event.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify(event)},hook.on)}}catch(err){this.opts.log?.(`plugin ${plugin.manifest.id}: ${event.event} dispatch failed \u2014 ${String(err)}`)}}dispatch(event){let platform=currentPluginPlatform();for(let plugin of this.plugins)try{for(let hook of plugin.manifest.events){if(hook.on!==event.event)continue;if(!supportsPlatform(hook,plugin.manifest,platform))continue;this.run(plugin,hook,"event",{ROVE_PLUGIN_EVENT:event.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify(event),...event.taskId?{ROVE_PLUGIN_TASK_ID:event.taskId}:{},...event.task?.title?{ROVE_PLUGIN_TASK_TITLE:event.task.title}:{}},hook.on)}}catch(err){this.opts.log?.(`plugin ${plugin.manifest.id}: ${event.event} dispatch failed \u2014 ${String(err)}`)}}loadPlugins(){let registry=loadPluginRegistry(this.opts.homeDir),platform=currentPluginPlatform(),out=[],enabled=new Set,stamps=new Map;for(let entry of registry.plugins){if(!entry.enabled)continue;enabled.add(entry.id),stamps.set(entry.root,fileStamp(pluginManifestPath(entry.root)));let manifest;try{manifest=readPluginManifest(entry.root).manifest}catch(err){this.opts.log?.(`plugin ${entry.id}: manifest unreadable, skipping \u2014 ${String(err)}`);continue}if(!supportsPlatform({},manifest,platform))continue;out.push({manifest,root:entry.root})}return this.enabledIds=enabled,this.manifestStamps=stamps,out}sourcesChanged(){let stamp=fileStamp(pluginRegistryPath(this.opts.homeDir));if(stamp!==this.registryStamp)return this.registryStamp=stamp,!0;for(let[root,was]of this.manifestStamps)if(fileStamp(pluginManifestPath(root))!==was)return!0;return!1}watchRegistry(){this.registryStamp=fileStamp(pluginRegistryPath(this.opts.homeDir)),this.pollTimer=setInterval(()=>{if(!this.sourcesChanged())return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;try{let loadedBefore=new Map(this.plugins.map((p)=>[p.manifest.id,p])),enabledBefore=this.enabledIds;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`);let at=Date.now();for(let plugin of this.plugins)if(!enabledBefore.has(plugin.manifest.id))this.dispatchTo(plugin,{event:"plugin.enabled",detail:{pluginId:plugin.manifest.id},at});for(let[id,plugin]of loadedBefore)if(!this.enabledIds.has(id))this.dispatchTo(plugin,{event:"plugin.disabled",detail:{pluginId:id},at})}catch(err){this.opts.log?.(`plugin registry reload failed \u2014 ${String(err)}`)}},RELOAD_DEBOUNCE_MS)},REGISTRY_POLL_MS),this.pollTimer.unref?.()}run(plugin,spec,kind,extraEnv,label){return runPluginHook({pluginId:plugin.manifest.id,pluginRoot:plugin.root,spec,kind,label,extraEnv,homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,log:this.opts.log,inFlight:this.inFlight}).catch((err)=>{this.opts.log?.(`plugin ${plugin.manifest.id} ${label}: ${String(err)}`)})}}function replacementKey(frame){if(frame.type!=="event")return null;switch(frame.name){case"task.snapshot":case"active-task":case"update":case"attention.inbox":case"ui-prefs":case"worktree.changes":case"transcript.activity":case"usage.snapshot":case"usage.context":return frame.name;default:return null}}function writeFrame(client,frame){client.writer.write(frameToLine(frame),replacementKey(frame))}function broadcast(clients,frame){let channel=frame.type==="event"&&frame.name!=="daemon.stopping"?frame.name:null,replaceKey=replacementKey(frame),line=null;for(let client of clients){if(!client.subscribed&&frame.type==="event")continue;if(channel&&client.channels&&!client.channels.has(channel))continue;line??=frameToLine(frame),client.writer.write(line,replaceKey)}}function handleClientLine(client,line,onRequest){if(line.trim().length===0)return;try{let frame=JSON.parse(line);if(frame.type!=="request")throw Error("daemon only accepts request frames from clients");onRequest(frame,client)}catch(err){writeFrame(client,{type:"response",id:"parse-error",error:{message:err instanceof Error?err.message:String(err)}})}}import{statSync as statSync2}from"fs";import{basename,dirname,join}from"path";var POLL_MS=200;function startFileWatchTrigger(opts){if(opts.debounceMs<=0)return()=>{};let dir=dirname(opts.filePath),names=[...new Set([basename(opts.filePath),...opts.matchBasenames??[]])],timer=null,trigger=()=>{try{opts.onTrigger()}catch(err){opts.onError(err)}},schedule=()=>{if(timer)clearTimeout(timer);timer=setTimeout(()=>{timer=null,trigger()},opts.debounceMs),timer.unref?.()},stampOf=(name)=>{try{let s=statSync2(join(dir,name),{bigint:!0});return`${s.mtimeNs}:${s.size}:${s.ino}`}catch{return"absent"}},stamps=new Map;for(let name of names)stamps.set(name,stampOf(name));let poll=setInterval(()=>{for(let name of names){let stamp=stampOf(name);if(stamp===stamps.get(name))continue;stamps.set(name,stamp),schedule()}},POLL_MS);return poll.unref?.(),()=>{if(clearInterval(poll),timer)clearTimeout(timer),timer=null}}var DEBOUNCE_MS=250,KEY_RE=/^(.+?)::(.+)$/;function startPtyExitWatch(opts){let path=opts.path??defaultPtyExitsPath(opts.homeDir),seen=new Map,baselined=!1,sweep=()=>{let host=opts.plugins();if(!host)return;let{records,readable}=readPtyExitStore(path);if(!readable)return;for(let[storeKey,record]of Object.entries(records)){if(seen.get(storeKey)===record.at)continue;if(seen.set(storeKey,record.at),!baselined)continue;host.handleUiReport({kind:"session.exited",...exitReport(record)}),publishDeath(record)}baselined=!0;for(let key of seen.keys())if(!(key in records))seen.delete(key)},publishDeath=(record)=>{let registry=opts.activity;if(!registry&&!opts.inbox)return;let death=engineDeathOf(record);if(!death)return;let{taskId,tabId,exit,at}=death;registry?.recordEngineDeath(taskId,tabId,exit,at),opts.inbox?.recordEngineDeath(taskId,tabId,{exit},at).catch((err)=>opts.log?.(`pty-exit inbox: ${String(err)}`))},stop=startFileWatchTrigger({filePath:path,debounceMs:DEBOUNCE_MS,onTrigger:sweep,onError:(err)=>opts.log?.(`pty-exit watch: ${String(err)}`)}),initial=readPtyExitStore(path);if(initial.readable){for(let[storeKey,record]of Object.entries(initial.records))seen.set(storeKey,record.at);baselined=!0}return stop}function engineDeathOf(record){let match=KEY_RE.exec(record.key),taskId=match?.[1],tabId=match?.[2];if(!taskId||!tabId)return null;let at=Date.parse(record.at);if(!Number.isFinite(at))return null;let lastLine=lastErrorLine(record.tail);return{taskId,tabId,exit:{code:record.code,signal:record.signal,...lastLine?{lastLine}:{}},at}}function lastErrorLine(tail){let last;for(let i=tail.length-1;i>=0;i--){let line=(tail[i]??"").trim();if(line.length===0)continue;if(ENGINE_EXIT_BANNER.test(line))return line;last??=line}return last}function exitReport(record){let match=KEY_RE.exec(record.key);return{...match?.[1]?{taskId:match[1]}:{},detail:{key:record.key,...match?.[2]?{tabId:match[2]}:{},pid:record.pid,code:record.code,signal:record.signal,exitedAt:record.at,tail:record.tail}}}function createActivityObserverIo(homeDir,runtime,activity){let peek=async(key)=>{let client=new KobeDaemonClient(defaultPtyHostSocketPath(homeDir));try{await client.connect();let result=await client.request("pty.peek",{key});return Buffer.from(result.data??"","base64").toString("utf8")}catch{return""}finally{client.close()}};return{onEngineExit({taskId,tabId,vendor,pid}){let key=`${taskId}::${tabId}`,pending=peek(key).then((tail)=>recordEngineExit({key,vendor,pid,at:new Date().toISOString(),tail},defaultPtyExitsPath(homeDir))).catch((err)=>logDaemonInfo("engine-exit",`record failed for ${key}: ${String(err)}`));return logDaemonInfo("engine-exit",`${vendor} (pid ${pid??"?"}) gone from live session ${key}`),pending},onEngineAbsentAtStart({taskId,tabId}){let key=`${taskId}::${tabId}`,path=defaultPtyExitsPath(homeDir),existing=readPtyExitRecords(path)[`${key}#engine`];if(existing){let death=engineDeathOf(existing);if(death)activity?.recordEngineDeath(death.taskId,death.tabId,death.exit,death.at);return}return peek(key).then((raw)=>{if(engineExitCodeFromTail(plainTail(raw))===null)return;recordEngineExit({key,pid:null,at:new Date().toISOString(),tail:raw,atApproximate:!0},path),logDaemonInfo("engine-exit",`recorded an unwatched death in ${key} (exit time unknown)`)}).catch((err)=>logDaemonInfo("engine-exit",`boot record failed for ${key}: ${String(err)}`))},async listSessions(){let client=new KobeDaemonClient(defaultPtyHostSocketPath(homeDir));try{return await client.connect(),((await client.request("pty.list")).sessions??[]).map((s)=>({key:s.key??"",alive:s.alive===!0,pid:typeof s.pid==="number"?s.pid:null,title:typeof s.title==="string"?s.title:"",totalBytes:typeof s.totalBytes==="number"?s.totalBytes:0}))}catch{return null}finally{client.close()}},foregroundEngines:(pids)=>runtime.foregroundEngines(pids),titleTurnHint:(vendor,title)=>runtime.titleTurnHint(vendor,title)}}var DEFAULT_OBSERVER_POLL_MS=1e4,DEFAULT_SILENCE_MS=30000,DEFAULT_WALK_EVERY_TICKS=6,DEFAULT_UNSUBSCRIBED_EVERY_TICKS=6,DEFAULT_CORRECT_AFTER_MS=20000;function startActivityObserver(activity,io,hasSubscribers,options={}){let pollMs=options.pollMs??DEFAULT_OBSERVER_POLL_MS,silenceMs=options.silenceMs??DEFAULT_SILENCE_MS,walkEvery=Math.max(1,options.walkEveryTicks??DEFAULT_WALK_EVERY_TICKS),unsubscribedEvery=Math.max(1,options.unsubscribedEveryTicks??DEFAULT_UNSUBSCRIBED_EVERY_TICKS),correctAfterMs=options.correctAfterMs??DEFAULT_CORRECT_AFTER_MS,log=options.log??logDaemonInfo,tracks=new Map,tickCount=0,unsubscribedTicks=0,inFlight,stopped=!1,bootWalkDone=!1,applyRest=(track,why)=>{if(activity.observeTab(track.taskId,track.tabId,"rest",{...track.vendor?{vendor:track.vendor}:{},correctHookRunningAfterMs:correctAfterMs})==="corrected-hook-running")log("activity-observe",`idled hook-claimed running for ${track.taskId}/${track.tabId} (${why})`)},tick=async()=>{let effects=[];try{let subscribed=hasSubscribers();if(!subscribed&&unsubscribedTicks++%unsubscribedEvery!==0)return;let walkTick=!subscribed||tickCount%walkEvery===0;tickCount++;let listed=await io.listSessions();if(stopped)return;if(listed===null){for(let[key,track]of tracks)activity.observeTab(track.taskId,track.tabId,"rest",{}),tracks.delete(key);return}let sessions=listed,seen=new Set,now=Date.now(),live=[],newborn=new Set;for(let s of sessions){let parts=s.key.split("::");if(parts.length!==2||!parts[0]||!parts[1])continue;if(seen.add(s.key),!s.alive){let track2=tracks.get(s.key);applyRest(track2??{taskId:parts[0],tabId:parts[1],vendor:void 0},"session exited"),tracks.delete(s.key);continue}let track=tracks.get(s.key);if(!track)track={taskId:parts[0],tabId:parts[1],firstSeenAt:now,lastTotalBytes:s.totalBytes,lastTitle:s.title,lastActivityAt:null,vendor:void 0,enginePid:null},tracks.set(s.key,track),newborn.add(s.key);else if(s.totalBytes!==track.lastTotalBytes||s.title!==track.lastTitle)track.lastTotalBytes=s.totalBytes,track.lastTitle=s.title,track.lastActivityAt=now;live.push(track)}for(let[key,track]of tracks){if(seen.has(key)&&sessions.some((s)=>s.key===key&&s.alive))continue;applyRest(track,"session gone"),tracks.delete(key)}let toWalk=live.filter((t)=>walkTick||newborn.has(`${t.taskId}::${t.tabId}`)||t.vendor===void 0);if(toWalk.length>0){let pidByKey=new Map;for(let s of sessions)if(s.alive&&s.pid!==null)pidByKey.set(s.key,s.pid);try{let pids=toWalk.map((t)=>pidByKey.get(`${t.taskId}::${t.tabId}`)).filter((pid)=>pid!==void 0),verdicts=await io.foregroundEngines(pids);if(stopped)return;let bootWalk=!bootWalkDone;bootWalkDone=!0;for(let track of toWalk){let pid=pidByKey.get(`${track.taskId}::${track.tabId}`);if(pid===void 0||!verdicts.has(pid))continue;let found=verdicts.get(pid)??null;if(found===null&&typeof track.vendor==="string")effects.push(io.onEngineExit?.({taskId:track.taskId,tabId:track.tabId,vendor:track.vendor,pid:track.enginePid}));else if(found===null&&track.vendor===void 0&&bootWalk)effects.push(io.onEngineAbsentAtStart?.({taskId:track.taskId,tabId:track.tabId}));track.vendor=found?.vendor??null,track.enginePid=found?.pid??null}}catch{}}if(stopped)return;for(let track of live){let key=`${track.taskId}::${track.tabId}`,session=sessions.find((s)=>s.key===key);if(!session||track.vendor===void 0)continue;if(effects.push(io.onEngineEvidence?.(track.taskId,track.tabId,{walkVendor:track.vendor,title:session.title})),track.vendor===null){applyRest(track,"no engine in foreground");continue}let silentForMs=now-(track.lastActivityAt??track.firstSeenAt),hint=io.titleTurnHint(track.vendor,session.title),claimWorking=(why)=>{if(activity.observeTab(track.taskId,track.tabId,"working",{vendor:track.vendor??void 0})==="observed-running")log("activity-observe",`seeded running for ${track.taskId}/${track.tabId} (${why})`)};if(hint==="rest")applyRest(track,"engine title at rest");else if(track.lastActivityAt!==null&&now-track.lastActivityAt<silenceMs)claimWorking("live output");else if(hint==="working"&&silentForMs<silenceMs)claimWorking("working title frame");else if(silentForMs>=silenceMs)applyRest(track,`no output for ${Math.round(silentForMs/1000)}s`)}}catch{}finally{await Promise.allSettled(effects)}},schedule=()=>{if(stopped||inFlight)return;inFlight=tick().finally(()=>{inFlight=void 0})};schedule();let timer=setInterval(schedule,pollMs);return timer.unref?.(),async()=>{stopped=!0,clearInterval(timer),await inFlight}}function isThenable(value){return typeof value?.then==="function"}function startTicker(opts){if(opts.tickMs<=0)return async()=>{};let running=null,stopped=!1,tick=()=>{if(stopped||opts.gate&&!opts.gate())return;if(running)return;let result;try{result=opts.run()}catch(err){logDaemonError(opts.name,err);return}if(!isThenable(result))return;running=Promise.resolve(result).then(()=>{return}).catch((err)=>logDaemonError(opts.name,err)).finally(()=>{running=null})};if(opts.immediate)tick();let timer=setInterval(tick,opts.tickMs);return timer.unref?.(),async()=>{try{if(!stopped)stopped=!0,clearInterval(timer),opts.onStop?.()}finally{await running}}}var DEFAULT_AUTO_TITLE_POLL_MS=4000;async function runAutoTitlePass(orch,derive,placeholderTitle,defaultVendor){let renamed=[],snapshot=orch.listTasks();for(let task of snapshot){if(task.title!==placeholderTitle||!task.worktreePath)continue;try{let derived=await derive(task.worktreePath,task.vendor??defaultVendor);if(!derived)continue;let title=withGroupOrdinal(derived,task.id,task.groupId,snapshot),current=orch.getTask(task.id);if(!current||current.title!==placeholderTitle)continue;await orch.setTitle(task.id,title),renamed.push({id:task.id,title})}catch(err){logDaemonError("auto-title-poller",err)}}return renamed}function withGroupOrdinal(title,taskId,groupId,snapshot){if(!groupId)return title;let siblings=snapshot.filter((t)=>t.groupId===groupId);if(siblings.length<2)return title;let ordinal=siblings.findIndex((t)=>t.id===taskId);if(ordinal<0)return title;return`${title} #${ordinal+1}/${siblings.length}`}function startAutoTitlePoller(orch,runtime,intervalMs=DEFAULT_AUTO_TITLE_POLL_MS,hasSubscribers){return startTicker({name:"auto-title-poller",tickMs:intervalMs,...hasSubscribers?{gate:hasSubscribers}:{},run:()=>runAutoTitlePass(orch,runtime.deriveTitleFromSession,runtime.placeholderTaskTitle,runtime.defaultTaskVendor)})}import{realpath}from"fs/promises";function automationTarget(automation){if(automation.target)return automation.target;return automation.persistentSession?{kind:"standing",taskId:automation.sessionTaskId}:{kind:"fresh"}}function readAutomationTarget(value){if(value===null)return null;if(typeof value!=="object"||!value||!("kind"in value)||value.kind!=="existing-tab"||!("taskId"in value)||typeof value.taskId!=="string"||!value.taskId.trim()||!("tabId"in value)||typeof value.tabId!=="string"||!/^tab-[\w-]+$/.test(value.tabId))throw Error("target must be { kind: 'existing-tab', taskId, tabId } or null");return{kind:"existing-tab",taskId:value.taskId.trim(),tabId:value.tabId}}function assertAutomationTargetOptions(value){if(!value.target)return;if(value.vendor||value.baseRef||value.persistentSession)throw Error("an existing-tab target cannot set vendor, baseRef or persistentSession; clear them when binding")}function mergeAutomationTargetOptions(automation,patch){return{target:patch.target===null?void 0:patch.target??automation.target,vendor:patch.vendor===null?void 0:patch.vendor??automation.vendor,baseRef:patch.baseRef===null?void 0:patch.baseRef??automation.baseRef,persistentSession:patch.persistentSession??automation.persistentSession,sessionTaskId:patch.target||patch.sessionTaskId===null?void 0:patch.sessionTaskId??automation.sessionTaskId}}async function assertAutomationTargetTask(value,orch){if(!value.target)return;let task=orch.getTask(value.target.taskId);if(!task||task.deletion||!task.worktreePath)throw Error(`target task unavailable: ${value.target.taskId}`);let[repo,taskRepo]=await Promise.all([realpath(value.repo),realpath(task.repo)]);if(repo!==taskRepo)throw Error(`routine repo must match target task repo: ${task.repo}`)}function resolveStandingTask(orch,automation){let id=automation.sessionTaskId;if(!id)return{task:null,hadStaleLink:!1};let task=orch.getTask(id);if(!task||task.deletion||!task.worktreePath)return{task:null,hadStaleLink:!0};return{task}}async function createRunTask(deps,automation){return await deps.orch.createTask({repo:automation.repo,title:automation.name,...automation.vendor?{vendor:automation.vendor}:{},...automation.baseRef?{baseRef:automation.baseRef}:{},...automation.persistentSession?{routine:{automationId:automation.id}}:{}})}async function spawnWithPrompt(deps,automation,taskId,status){if(deps.canDeliver?.()===!1)return{status:"skipped_cancelled",taskId};let outcome=await deps.runtime.startTaskSessionWithPrompt(deps.link(),taskId,automation.prompt);if(!outcome.started)return{status:"dispatch_failed",taskId,error:outcome.error??"engine session did not start"};return{status,taskId}}async function dispatchAutomation(deps,automation){if(deps.canDeliver?.()===!1)return{status:"skipped_cancelled"};let target=automationTarget(automation);if(target.kind==="existing-tab"){try{await assertAutomationTargetTask(automation,deps.orch)}catch(error){return{status:"skipped_unavailable",taskId:target.taskId,tabId:target.tabId,error:String(error)}}let task2=deps.orch.getTask(target.taskId);if(!task2||task2.deletion||!task2.worktreePath)return{status:"skipped_unavailable",taskId:target.taskId,tabId:target.tabId,error:"target task unavailable"};if(deps.canDeliver?.()===!1)return{status:"skipped_cancelled",taskId:task2.id,tabId:target.tabId};let currentTask=deps.orch.getTask(task2.id);if(!currentTask||currentTask.deletion||!currentTask.worktreePath)return{status:"skipped_unavailable",taskId:task2.id,tabId:target.tabId,error:"target task unavailable"};let result2=await deps.runtime.deliverPromptToLiveEngineTabDetailed({id:task2.id,tabId:target.tabId,vendor:task2.vendor,command:task2.command,worktreePath:task2.worktreePath},automation.prompt);return await liveDeliveryOutcome(deps,automation,task2.id,result2)}if(target.kind==="fresh"){let task2=await createRunTask(deps,automation);return await spawnWithPrompt(deps,automation,task2.id,"dispatched")}let standing=resolveStandingTask(deps.orch,automation);if(standing.task===null){let task2=await createRunTask(deps,automation);return{...await spawnWithPrompt(deps,automation,task2.id,"dispatched"),sessionTaskIdToSet:task2.id,...standing.hadStaleLink?{sessionTaskIdToClear:!0}:{}}}let task=standing.task,result=await deps.runtime.deliverPromptToLiveEngineDetailed({id:task.id,vendor:task.vendor,command:task.command,worktreePath:task.worktreePath},automation.prompt);if(result.outcome==="delivered")return await liveDeliveryOutcome(deps,automation,task.id,result);return await spawnWithPrompt(deps,automation,task.id,"revived")}async function liveDeliveryOutcome(deps,automation,taskId,result){switch(result.outcome){case"delivered":return logDaemonInfo("automation",`delivered ${automation.name} task=${taskId} tab=${result.tabId}`),{status:"dispatched",taskId,tabId:result.tabId};case"no-engine":case"no-session":return{status:"dispatch_failed",taskId,tabId:automation.target?.tabId,error:result.outcome==="no-engine"?"target engine exited; restart it explicitly":"target tab has no live session"}}}import{spawn as spawn2}from"child_process";import{existsSync}from"fs";var MAX_OUTPUT_CHARS=4000,MAX_TIMEOUT_SECONDS=600;function killGroup(child){let pid=child.pid;if(pid===void 0)return;try{process.kill(-pid,"SIGKILL")}catch{try{child.kill("SIGKILL")}catch{}}}function withWatchdog(command,timeoutSeconds){return["set +m 2>/dev/null",`{ sleep ${timeoutSeconds} && { kill -9 -$$ 2>/dev/null || kill -9 $$ ; } ; } >/dev/null 2>&1 </dev/null &`,"__rove_watchdog=$!",`trap 'kill "$__rove_watchdog" 2>/dev/null' EXIT`,command].join(`
4
4
  `)}function tail(chunks){let text=Buffer.concat(chunks.map((c)=>typeof c==="string"?Buffer.from(c):c)).toString("utf8");if(text.length<=MAX_OUTPUT_CHARS)return text;let points=Array.from(text);return points.length<=MAX_OUTPUT_CHARS?text:points.slice(-MAX_OUTPUT_CHARS).join("")}function runAutomationPrecheck(precheck,cwd,shell=resolveLoginShell({fallback:"/bin/sh"})){let startedAt=Date.now(),timeoutMs=Math.min(Math.max(precheck.timeoutSeconds,1),MAX_TIMEOUT_SECONDS)*1000;if(!existsSync(cwd))return Promise.resolve({exitCode:null,timedOut:!1,stdout:"",stderr:`working directory does not exist: ${cwd}`,durationMs:0});return new Promise((resolve)=>{let out=[],err=[],settled=!1,timedOut=!1,finish=(exitCode,timedOut2)=>{if(settled)return;settled=!0,clearTimeout(timer),resolve({exitCode,timedOut:timedOut2,stdout:tail(out),stderr:tail(err),durationMs:Date.now()-startedAt})},timer=setTimeout(()=>{if(timedOut=!0,child)killGroup(child);finish(null,!0)},timeoutMs);timer.unref?.();let child;try{child=spawn2(shell,["-ilc",withWatchdog(precheck.command,timeoutMs/1000+1)],{cwd,stdio:["ignore","pipe","pipe"],detached:process.platform!=="win32"})}catch(spawnError){err.push(spawnError instanceof Error?spawnError.message:String(spawnError)),finish(null,!1);return}child.stdout?.on("data",(chunk)=>out.push(chunk)),child.stderr?.on("data",(chunk)=>err.push(chunk)),child.on("error",(spawnError)=>{if(timedOut){finish(null,!0);return}err.push(spawnError.message),finish(null,!1)}),child.on("close",(code)=>finish(code,timedOut))})}function precheckPassed(result){return result.exitCode===0&&!result.timedOut}function formatPrecheckSkip(result){if(result.timedOut)return`precheck timed out after ${result.durationMs}ms`;if(result.exitCode===null)return`precheck could not run: ${result.stderr.trim()||"unknown error"}`;return`precheck exited ${result.exitCode}`}var DEFAULT_AUTOMATION_TICK_MS=60000;function dueAutomations(automations,nowMs){return automations.filter((a)=>{if(!a.enabled)return!1;let at=Date.parse(a.nextRunAt);return Number.isFinite(at)&&at<=nowMs})}function resolveDueOccurrence(automation,nowMs,tickMs=DEFAULT_AUTOMATION_TICK_MS){let notBefore=Date.parse(automation.createdAt),scheduledFor=latestCronAtOrBefore(automation.schedule,nowMs,Number.isFinite(notBefore)?notBefore:0);if(scheduledFor===null)return null;let graceMs=automation.missedRunGraceMinutes*60000+Math.max(tickMs,0);return{scheduledFor,missed:nowMs-scheduledFor>graceMs}}function runEventFor(status){if(status==="dispatched"||status==="revived")return"automation.dispatched";if(status==="dispatch_failed")return"automation.failed";return"automation.skipped"}function resolveLink(link){return typeof link==="function"?link():link}function emitRunEvent(deps,automation,status,args,extra){deps.plugins?.()?.handleUiReport({kind:runEventFor(status),...extra.taskId?{taskId:extra.taskId}:{},detail:{automationId:automation.id,name:automation.name,repo:automation.repo,status,trigger:args.trigger,scheduledFor:new Date(args.scheduledFor).toISOString(),...extra.tabId?{tabId:extra.tabId}:{},...extra.error?{error:extra.error}:{}}})}async function raiseOrClearInboxEpisode(deps,automation,status,extra){let inbox=deps.inbox;if(!inbox)return;let now=deps.now??Date.now;await(automationRunNeedsAttention(status)?inbox.recordRoutineFailure({automationId:automation.id,name:automation.name,status,...extra.error?{error:extra.error}:{}},extra.taskId??null,now()):inbox.deleteRoutineEpisode?.(automation.id))?.catch((err)=>logDaemonError("automation-inbox",err))}async function recordSkip(deps,automation,status,scheduledFor,error){let now=deps.now??Date.now;await deps.store.recordRun({automationId:automation.id,scheduledFor:new Date(scheduledFor).toISOString(),status,trigger:"scheduled",at:new Date(now()).toISOString(),error}),emitRunEvent(deps,automation,status,{scheduledFor,trigger:"scheduled"},{error})}function droppedOccurrences(automation,scheduledFor){let armedAt=Date.parse(automation.nextRunAt);if(!Number.isFinite(armedAt)||armedAt>=scheduledFor)return null;let count=countCronBetween(automation.schedule,armedAt,scheduledFor);return count>0?{count,firstMs:armedAt}:null}async function runAutomationOnce(deps,automation,args){let now=deps.now??Date.now,record=async(status,extra={})=>{return await deps.store.recordRun({automationId:automation.id,scheduledFor:new Date(args.scheduledFor).toISOString(),status,trigger:args.trigger,at:new Date(now()).toISOString(),...extra}),emitRunEvent(deps,automation,status,args,extra),await raiseOrClearInboxEpisode(deps,automation,status,extra),status},cancelled=()=>deps.stopped?.()===!0||deps.store.get(automation.id)!==automation||args.trigger==="scheduled"&&!automation.enabled;if(cancelled())return await record("skipped_cancelled",{error:"routine disabled, changed, deleted or runner stopped before delivery"});if(args.trigger==="scheduled"&&automation.precheck){let result=await runAutomationPrecheck(automation.precheck,automation.repo);if(!precheckPassed(result))return logDaemonInfo("automation",`skip ${automation.name}: ${formatPrecheckSkip(result)}`),await record("skipped_precheck",{precheckResult:result,error:formatPrecheckSkip(result)})}if(cancelled())return await record("skipped_cancelled",{error:"routine disabled, changed, deleted or runner stopped before delivery"});let outcome;try{outcome=await dispatchAutomation({canDeliver:()=>!cancelled(),orch:deps.orch,runtime:deps.runtime,link:()=>resolveLink(deps.link),...deps.now?{now:deps.now}:{}},automation)}catch(err){let error=err instanceof Error?err.message:String(err);return logDaemonError("automation-dispatch",err),await record("skipped_unavailable",{error})}if(outcome.sessionTaskIdToSet)await deps.store.update(automation.id,{sessionTaskId:outcome.sessionTaskIdToSet}).catch((err)=>logDaemonError("automation-session-link",err));else if(outcome.sessionTaskIdToClear)await deps.store.update(automation.id,{sessionTaskId:null}).catch((err)=>logDaemonError("automation-session-unlink",err));if(outcome.status==="dispatched"||outcome.status==="revived")logDaemonInfo("automation",`${outcome.status} ${automation.name} task=${outcome.taskId}`);return await record(outcome.status,{...outcome.taskId?{taskId:outcome.taskId}:{},...outcome.tabId?{tabId:outcome.tabId}:{},...outcome.error?{error:outcome.error}:{}})}async function sweepAutomations(deps,tickMs=DEFAULT_AUTOMATION_TICK_MS){let now=deps.now??Date.now;for(let automation of dueAutomations(deps.store.list(),now())){if(deps.stopped?.())return;let nowMs=now(),occurrence=resolveDueOccurrence(automation,nowMs,tickMs);if(!occurrence){await deps.store.advanceNextRun(automation.id,nowMs);continue}let dropped=droppedOccurrences(automation,occurrence.scheduledFor),claimed=await deps.store.advanceNextRun(automation.id,occurrence.scheduledFor,automation.nextRunAt);if(!claimed)continue;if(dropped){let first=new Date(dropped.firstMs).toISOString();await recordSkip(deps,automation,"skipped_missed",dropped.firstMs,`${dropped.count} earlier occurrence${dropped.count===1?"":"s"} never ran (from ${first})`).catch((err)=>logDaemonError("automation-dropped",err))}if(occurrence.missed){await recordSkip(deps,automation,"skipped_missed",occurrence.scheduledFor,`missed by more than the ${automation.missedRunGraceMinutes}m grace window`);continue}await runAutomationOnce(deps,claimed,{scheduledFor:occurrence.scheduledFor,trigger:"scheduled"}).catch((err)=>logDaemonError("automation-run",err))}}function startAutomationRunner(deps,tickMs=DEFAULT_AUTOMATION_TICK_MS){let stopped=!1;return startTicker({name:"automation-sweep",tickMs,run:()=>sweepAutomations({...deps,stopped:()=>stopped},tickMs),onStop:()=>{stopped=!0}})}var DEFAULT_CONTEXT_USAGE_TICK_MS=1e4,CONTEXT_USAGE_TIMEOUT_MS=4000,CONTEXT_USAGE_SLOW_RETRY_MS=60000,CONTEXT_USAGE_MIN_INTERVAL_MS=5000;function sameContextUsage(a,b){return a.contextTokens===b.contextTokens&&a.contextWindowTokens===b.contextWindowTokens&&a.approximate===b.approximate&&a.inputTokens===b.inputTokens&&a.outputTokens===b.outputTokens&&a.cacheReadTokens===b.cacheReadTokens&&a.cacheCreationTokens===b.cacheCreationTokens}function contextUsageTargets(states,getVendor){let seen=new Set,targets=[];for(let state of states){if(!state.tabId||!state.sessionId)continue;let vendor=getVendor(state.taskId);if(!vendor)continue;let key=`${state.taskId}::${state.tabId}`;if(seen.has(key))continue;seen.add(key),targets.push({key,vendor,sessionId:state.sessionId})}return targets}class ContextUsageCollector{registry;orch;bus;runtime;options;entries=new Map;stopped=!1;constructor(registry,orch,bus,runtime,options={}){this.registry=registry;this.orch=orch;this.bus=bus;this.runtime=runtime;this.options=options}tick(){if(this.stopped)return;if(this.options.hasSubscribers&&!this.options.hasSubscribers())return;try{let targets=contextUsageTargets(this.registry.currentNonIdle(),(id)=>this.orch.getTask(id)?.vendor),live=new Set(targets.map((t)=>t.key)),pruned=!1;for(let key of[...this.entries.keys()]){if(live.has(key))continue;if(this.entries.get(key)?.value)pruned=!0;this.entries.delete(key)}if(pruned)this.publish();for(let target of targets)this.collect(target)}catch(err){logDaemonError("context-usage",err)}}stop(){this.stopped=!0}collect(target){let entry=this.entries.get(target.key);if(!entry)entry={inFlight:!1,nextAllowedAt:0},this.entries.set(target.key,entry);if(entry.sessionId!==void 0&&entry.sessionId!==target.sessionId){let had=entry.value!==void 0;if(entry.value=void 0,entry.nextAllowedAt=0,entry.sessionId=target.sessionId,had)this.publish()}entry.sessionId=target.sessionId;let cadence=this.options.cadence??{timeoutMs:CONTEXT_USAGE_TIMEOUT_MS,slowRetryMs:CONTEXT_USAGE_SLOW_RETRY_MS,minIntervalMs:CONTEXT_USAGE_MIN_INTERVAL_MS},read=this.options.read??((t)=>this.runtime.readEngineContextUsage(t.vendor,t.sessionId)),startedAt=Date.now();if(entry.inFlight||startedAt<entry.nextAllowedAt)return;entry.inFlight=!0;let controller=new AbortController,timer=setTimeout(()=>controller.abort(),cadence.timeoutMs),held=entry;read(target,controller.signal).then((value)=>{if(controller.signal.aborted||this.stopped)return;if(this.entries.get(target.key)!==held)return;if(!value)return;if(held.value&&sameContextUsage(held.value,value))return;held.value=value,this.publish()}).catch(()=>{}).finally(()=>{clearTimeout(timer);let finishedAt=Date.now();held.nextAllowedAt=controller.signal.aborted?startedAt+cadence.slowRetryMs:finishedAt+Math.max(cadence.minIntervalMs,(finishedAt-startedAt)*5),held.inFlight=!1})}publish(){let context={};for(let[key,entry]of this.entries)if(entry.value)context[key]=entry.value;this.bus.publish("usage.context",{context})}}function startContextUsageCollector(registry,orch,bus,runtime,tickMs=DEFAULT_CONTEXT_USAGE_TICK_MS,hasSubscribers){if(tickMs<=0)return()=>{};let collector=new ContextUsageCollector(registry,orch,bus,runtime,{hasSubscribers});collector.tick();let timer=setInterval(()=>collector.tick(),tickMs);return timer.unref?.(),()=>{clearInterval(timer),collector.stop()}}import{basename as basename2}from"path";var DEFAULT_KEYBINDINGS_DEBOUNCE_MS=200;function startKeybindingsWatcher(bus,options={}){let debounceMs=options.debounceMs??DEFAULT_KEYBINDINGS_DEBOUNCE_MS;if(debounceMs<=0)return()=>{};let filePath=options.path??defaultKeybindingsPath(),baseYaml=basename2(filePath),baseYml=baseYaml.replace(/\.yaml$/,".yml"),rev=0;return bus.publish("keybindings",{rev}),startFileWatchTrigger({filePath,matchBasenames:[baseYaml,baseYml],debounceMs,onTrigger:()=>{try{rev+=1,bus.publish("keybindings",{rev})}catch(err){logDaemonError("keybindings-watcher",err)}},onError:(err)=>logDaemonError("keybindings-watcher",err)})}import{spawn as spawn3}from"child_process";var PR_STATE_RANK={OPEN:2,MERGED:1,CLOSED:1};function pickPr(views){let best,bestRank=-1;for(let view of views){let rank=PR_STATE_RANK[(view.state??"").toUpperCase()]??0;if(rank>bestRank)best=view,bestRank=rank}return best}var DEFAULT_PR_STATUS_POLL_MS=30000,NO_PR_BACKOFF_MS=300000,SETTLED_BACKOFF_MS=600000,PR_FAILURE_BASE_MS=DEFAULT_PR_STATUS_POLL_MS,PR_FAILURE_CAP_MS=900000,NO_REMOTE_BACKOFF_MS=1800000,PR_POLL_JITTER_RATIO=0.2,PR_VIEW_TIMEOUT_MS=1e4,PR_POLL_CONCURRENCY=8;function spawnGh(args,cwd,signal){return new Promise((resolve)=>{let outChunks=[],errChunks=[],settled=!1,finish=(status,spawnError)=>{if(settled)return;settled=!0,resolve({status,stdout:decodeCapturedChunks(outChunks),stderr:decodeCapturedChunks(errChunks),spawnError})},child=spawn3("gh",args.slice(),{cwd,stdio:["ignore","pipe","pipe"],signal,killSignal:"SIGKILL"});child.stdout?.on("data",(chunk)=>{outChunks.push(chunk)}),child.stderr?.on("data",(chunk)=>{errChunks.push(chunk)}),child.on("error",()=>finish(null,!signal.aborted)),child.on("close",(code)=>finish(code,!1))})}function makeGhPrViewRunner(classify,viewFields){return async(worktreePath,branch)=>{let controller=new AbortController,timedOut=!1,timer=setTimeout(()=>{timedOut=!0,controller.abort()},PR_VIEW_TIMEOUT_MS);try{let res=await spawnGh(["pr","list","--head",branch,"--state","all","--json",viewFields],worktreePath,controller.signal);if(res.status===0&&!timedOut)try{let views=JSON.parse(res.stdout),picked=Array.isArray(views)?pickPr(views):void 0;return picked?{kind:"pr",view:picked}:{kind:"empty"}}catch{return classify({parseError:!0})}return classify({spawnError:res.spawnError,timedOut,exitCode:res.status,stderr:res.stderr})}finally{clearTimeout(timer)}}}function isPrPollable(task){if(task.kind==="main")return!1;if(!task.branch||!task.worktreePath)return!1;if(task.repo.startsWith("ssh://")||task.worktreePath.startsWith("ssh://"))return!1;return!0}async function setPrStaleMarker(orch,taskId,error){let prev=orch.getTask(taskId)?.prStatus;if(!prev||prev.lastError===error)return!1;let{lastError:_cleared,...rest}=prev;return await orch.setPRStatus(taskId,error===void 0?rest:{...rest,lastError:error}),!0}async function runPrStatusPass(orch,opts){let tickMs=opts.tickMs??DEFAULT_PR_STATUS_POLL_MS,rand=opts.rand,cfg={tickMs,settledMs:SETTLED_BACKOFF_MS,noPrMs:NO_PR_BACKOFF_MS,noRemoteMs:NO_REMOTE_BACKOFF_MS,failureBaseMs:PR_FAILURE_BASE_MS,failureCapMs:PR_FAILURE_CAP_MS,jitterRatio:PR_POLL_JITTER_RATIO},tasks=orch.listTasks(),live=new Set(tasks.map((task)=>task.id));for(let id of opts.schedule.keys())if(!live.has(id))opts.schedule.delete(id);let due=[];for(let task of tasks){if(!isPrPollable(task)){opts.schedule.delete(task.id);continue}let entry=opts.schedule.get(task.id);if(entry&&opts.now<entry.nextAllowedAt)continue;due.push({task,prevFailures:entry?.failures??0})}let pollOne=async(task,prevFailures)=>{try{let result=await opts.run(task.worktreePath,task.branch);if(result.kind==="error"){logDaemonInfo("pr-status-poller",`gh pr list failed (${result.error}) for task ${task.id} [${task.branch}] \u2014 keeping last PR status, backing off`);let marked=await setPrStaleMarker(orch,task.id,result.error);return opts.schedule.set(task.id,opts.runtime.prStatus.nextPoll({kind:"error",error:result.error},prevFailures,opts.now,cfg,rand)),marked?task.id:void 0}if(result.kind==="empty"){let marked=await setPrStaleMarker(orch,task.id,void 0);return opts.schedule.set(task.id,opts.runtime.prStatus.nextPoll({kind:"empty"},prevFailures,opts.now,cfg,rand)),marked?task.id:void 0}let next=opts.runtime.prStatus.mapView(result.view,opts.at),current=orch.getTask(task.id);if(!current){opts.schedule.delete(task.id);return}let wasStale=current.prStatus?.lastError!==void 0,changedId;if(wasStale||!opts.runtime.prStatus.sameStatus(current.prStatus,next??void 0))await orch.setPRStatus(task.id,next),changedId=task.id;let settled=next?.lifecycle==="merged"||next?.lifecycle==="closed";return opts.schedule.set(task.id,opts.runtime.prStatus.nextPoll({kind:"pr",settled},prevFailures,opts.now,cfg,rand)),changedId}catch(err){logDaemonError("pr-status-poller",err);let marked=await setPrStaleMarker(orch,task.id,"network").catch(()=>!1);return opts.schedule.set(task.id,opts.runtime.prStatus.nextPoll({kind:"error",error:"network"},prevFailures,opts.now,cfg,rand)),marked?task.id:void 0}},slots=Array(due.length),cursor=0,worker=async()=>{for(let i=cursor++;i<due.length;i=cursor++){let item=due[i];if(item)slots[i]=await pollOne(item.task,item.prevFailures)}};return await Promise.all(Array.from({length:Math.min(PR_POLL_CONCURRENCY,due.length)},worker)),slots.filter((id)=>id!==void 0)}function startPrStatusPoller(orch,runtime,intervalMs=DEFAULT_PR_STATUS_POLL_MS,hasSubscribers,run=makeGhPrViewRunner(runtime.prStatus.classify,runtime.prStatus.viewFields),hasWorkingAgent){let schedule=new Map;return startTicker({name:"pr-status-poller",tickMs:intervalMs,...hasSubscribers?{gate:()=>hasSubscribers()||(hasWorkingAgent?.()??!1)}:{},run:()=>runPrStatusPass(orch,{runtime,run,now:Date.now(),at:new Date().toISOString(),schedule,tickMs:intervalMs})})}function quotaResumeContinuePrompt(language){return language==="zh"?"\u4ECE\u4E2D\u65AD\u7684\u5730\u65B9\u7EE7\u7EED\u8FD9\u4E2A\u4EFB\u52A1\u3002\u4E0A\u9762\u7684\u5BF9\u8BDD\u8BB0\u5F55\u91CC\u5DF2\u7ECF\u5B8C\u6210\u7684\u5DE5\u4F5C\u4E0D\u8981\u91CD\u505A\u3002":"Continue the task from where it stopped. The transcript above shows the work already completed \u2014 do not redo it."}var DEFAULT_QUOTA_RESUME_TICK_MS=60000;function dueQuotaResumes(tasks,nowMs){return tasks.filter((task)=>{if(!task.quotaResume||!task.worktreePath)return!1;if(task.deletion)return!1;let at=Date.parse(task.quotaResume.resumeAt);return Number.isFinite(at)&&at<=nowMs})}function exhaustedResetAtMs(usage,nowMs){let candidates=usage.windows.filter((w)=>w.percent>=100&&w.resetsAt!=null&&w.resetsAt>nowMs).map((w)=>w.resetsAt);return candidates.length>0?Math.min(...candidates):null}async function scheduleQuotaResume(orch,runtime,cache,taskId,now=Date.now,plugins){let task=orch.getTask(taskId);if(!task||!task.worktreePath||task.deletion)return;let usage=await cache.get(task.vendor??runtime.defaultTaskVendor,0),resetAtMs=usage?exhaustedResetAtMs(usage,now()):null;if(resetAtMs==null)return;let resumeAt=new Date(resetAtMs).toISOString();await orch.setQuotaResume(taskId,{resumeAt,requestedAt:new Date(now()).toISOString()}),logDaemonInfo("quota-resume",`armed task=${taskId} resumeAt=${resumeAt}`),plugins?.()?.handleUiReport({kind:"quota.exhausted",taskId,detail:{vendor:task.vendor??runtime.defaultTaskVendor,resumeAt}})}async function resumeDueTask(orch,runtime,task,plugins){await orch.setQuotaResume(task.id,null);let delivered=await runtime.deliverPromptToLiveEngine({id:task.id,vendor:task.vendor,command:task.command,worktreePath:task.worktreePath},quotaResumeContinuePrompt(task.observedLanguage));logDaemonInfo("quota-resume",`resume task=${task.id} delivered=${delivered}`),plugins?.()?.handleUiReport({kind:"quota.resumed",taskId:task.id,detail:{delivered}})}function startQuotaResumeRunner(orch,runtime,tickMs=DEFAULT_QUOTA_RESUME_TICK_MS,now=Date.now,plugins){return startTicker({name:"quota-resume",tickMs,run:async()=>{for(let task of dueQuotaResumes(orch.listTasks(),now()))await resumeDueTask(orch,runtime,task,plugins).catch((err)=>logDaemonError("quota-resume",err))}})}var FRESH_POLL_MS=900000,RETRY_BASE_MS=60000,MIN_FETCH_INTERVAL_MS=60000;class QuotaUsageCache{runtime;bus;now;entries=new Map;constructor(runtime,bus,now=Date.now){this.runtime=runtime;this.bus=bus;this.now=now}peek(vendor){return this.entries.get(vendor)?.usage??null}async get(vendor,maxAgeMs){let entry=this.entry(vendor),age=this.now()-(entry.usage?.capturedAt??0);if(entry.usage&&age<=maxAgeMs)return entry.usage;if(entry.inFlight)return entry.inFlight;if(this.now()-entry.attemptedAt<MIN_FETCH_INTERVAL_MS)return entry.usage;return this.fetch(vendor,entry)}async refreshIfDue(vendor){let entry=this.entry(vendor),retryAfter=entry.failures===0?0:Math.min(RETRY_BASE_MS*2**(entry.failures-1),FRESH_POLL_MS),dueAfter=entry.usage?FRESH_POLL_MS:retryAfter;if(this.now()-entry.attemptedAt<dueAfter)return;await this.fetch(vendor,entry)}entry(vendor){let existing=this.entries.get(vendor);if(existing)return existing;let fresh={usage:null,attemptedAt:0,failures:0,inFlight:null};return this.entries.set(vendor,fresh),fresh}fetch(vendor,entry){if(entry.inFlight)return entry.inFlight;return entry.attemptedAt=this.now(),entry.inFlight=this.runtime.quotaUsage(vendor).catch(()=>null).then((usage)=>{if(entry.inFlight=null,usage){entry.failures=0;let changed=JSON.stringify(usage.windows)!==JSON.stringify(entry.usage?.windows);if(entry.usage=usage,changed)this.publish()}else entry.failures+=1;return entry.usage}),entry.inFlight}publish(){let usage={};for(let[vendor,entry]of this.entries)if(entry.usage)usage[vendor]=entry.usage;this.bus.publish("usage.snapshot",{usage})}}function startQuotaUsagePoller(cache,listVendors,hasSubscribers,tickMs=MIN_FETCH_INTERVAL_MS){return startTicker({name:"quota-usage-poller",tickMs,gate:hasSubscribers,immediate:!0,run:()=>{for(let vendor of new Set(listVendors()))cache.refreshIfDue(vendor)}})}function isRemoteRepoKey(value){return value.startsWith("ssh://")}var DEFAULT_TRANSCRIPT_ACTIVITY_TICK_MS=1500,TRANSCRIPT_ACTIVITY_TIMEOUT_MS=4000,TRANSCRIPT_ACTIVITY_SLOW_RETRY_MS=60000,TRANSCRIPT_ACTIVITY_MIN_INTERVAL_MS=1500;function sameTranscriptActivityEntry(a,b){return a.mtimeMs===b.mtimeMs&&a.completionId===b.completionId&&a.completionAt===b.completionAt}async function runTranscriptActivity(worktreePath,vendor,detector,_signal){let{marker,mtimeMs}=await detector.latestActivity(worktreePath);return{mtimeMs:detector.supportsCompletionMarkers()?mtimeMs:0,completionId:marker?.id??null,completionAt:marker?.timestampMs??0}}function trackedWorktrees(tasks,defaultVendor){let map=new Map;for(let task of tasks){if(!task.worktreePath)continue;if(isRemoteRepoKey(task.repo)||isRemoteRepoKey(task.worktreePath))continue;if(map.has(task.worktreePath))continue;map.set(task.worktreePath,task.vendor??defaultVendor)}return map}class TranscriptActivityCollector{orch;bus;options;entries=new Map;stopped=!1;constructor(orch,bus,options){this.orch=orch;this.bus=bus;this.options=options}tick(){if(this.stopped)return;if(this.options.hasSubscribers&&!this.options.hasSubscribers())return;try{let tracked=trackedWorktrees(this.orch.listTasks(),this.options.defaultVendor),pruned=!1;for(let path of this.entries.keys()){if(tracked.has(path))continue;if(this.entries.get(path)?.value)pruned=!0;this.entries.delete(path)}if(pruned)this.publish();for(let[path,vendor]of tracked)this.maybeCollect(path,vendor)}catch(err){logDaemonError("transcript-activity",err)}}stop(){this.stopped=!0}maybeCollect(worktreePath,vendor){let entry=this.entries.get(worktreePath);if(!entry)entry={inFlight:!1,nextAllowedAt:0,vendor,detector:this.createDetector(vendor)},this.entries.set(worktreePath,entry);else if(entry.vendor!==vendor)entry.vendor=vendor,entry.detector=this.createDetector(vendor);let cadence=this.options.cadence??{timeoutMs:TRANSCRIPT_ACTIVITY_TIMEOUT_MS,slowRetryMs:TRANSCRIPT_ACTIVITY_SLOW_RETRY_MS,minIntervalMs:TRANSCRIPT_ACTIVITY_MIN_INTERVAL_MS},run=this.options.run??runTranscriptActivity,current=entry;maybeStartScheduledRun(current,cadence,(signal)=>run(worktreePath,current.vendor,current.detector,signal),(value)=>{if(this.stopped)return;if(this.entries.get(worktreePath)!==current)return;if(current.value&&sameTranscriptActivityEntry(current.value,value))return;current.value=value,this.publish()})}publish(){let activity={};for(let[path,entry]of this.entries)if(entry.value)activity[path]=entry.value;this.bus.publish("transcript.activity",{activity})}createDetector(vendor){return this.options.createDetector?.(vendor)??{latestActivity:async()=>({marker:null,mtimeMs:0}),latestActivityInFile:async()=>null,supportsCompletionMarkers:()=>!1}}}function startTranscriptActivityCollector(orch,runtime,bus,tickMs=DEFAULT_TRANSCRIPT_ACTIVITY_TICK_MS,hasSubscribers){let collector=new TranscriptActivityCollector(orch,bus,{hasSubscribers,createDetector:runtime.createEngineTurnDetector,defaultVendor:runtime.defaultTaskVendor,run:async(path,vendor,detector,signal)=>{let{marker,mtimeMs}=await detector.latestActivity(path);return{mtimeMs:detector.supportsCompletionMarkers()?mtimeMs:await runtime.latestTranscriptMtime(vendor,path),completionId:marker?.id??null,completionAt:marker?.timestampMs??0}}});return startTicker({name:"transcript-activity-collector",tickMs,immediate:!0,run:()=>collector.tick(),onStop:()=>collector.stop()})}import{readFileSync}from"fs";import{basename as basename3}from"path";var DEFAULT_UI_PREFS_DEBOUNCE_MS=200,FOCUS_ACCENT_SLOT_NAMES=["primary","success","info"];function readUiPrefsFromStateFile(statePath){let parsed={};try{let raw=JSON.parse(readFileSync(statePath,"utf8"));if(raw&&typeof raw==="object"&&!Array.isArray(raw))parsed=raw}catch{}let theme=typeof parsed.activeTheme==="string"&&parsed.activeTheme.length>0?parsed.activeTheme:null,transparentBackground=parsed.transparentBackground!==!1,focusAccent=typeof parsed.focusAccent==="string"&&FOCUS_ACCENT_SLOT_NAMES.includes(parsed.focusAccent)?parsed.focusAccent:null,sortMode=parsed.activeSortMode==="recent"?"recent":"default",keysCollapsed=parsed["tasksPane.keysCollapsed"]===!0,projectFilter=typeof parsed["tasksPane.projectFilter"]==="string"&&parsed["tasksPane.projectFilter"].length>0?parsed["tasksPane.projectFilter"]:null,locale=typeof parsed.locale==="string"&&parsed.locale.length>0?parsed.locale:"en";return{theme,transparentBackground,focusAccent,locale,sortMode,keysCollapsed,projectFilter}}function samePrefs(a,b){return a.theme===b.theme&&a.transparentBackground===b.transparentBackground&&a.focusAccent===b.focusAccent&&a.locale===b.locale&&a.sortMode===b.sortMode&&a.keysCollapsed===b.keysCollapsed&&a.projectFilter===b.projectFilter}function startUiPrefsWatcher(bus,options={}){let debounceMs=options.debounceMs??DEFAULT_UI_PREFS_DEBOUNCE_MS;if(debounceMs<=0)return()=>{};let statePath=options.statePath??defaultUiPrefsStatePath(),stateFile=basename3(statePath),last=null,publishIfChanged=()=>{try{let next=readUiPrefsFromStateFile(statePath);if(last&&samePrefs(last,next))return;last=next,bus.publish("ui-prefs",next)}catch(err){logDaemonError("ui-prefs-watcher",err)}},stop=startFileWatchTrigger({filePath:statePath,matchBasenames:[stateFile],debounceMs,onTrigger:publishIfChanged,onError:(err)=>logDaemonError("ui-prefs-watcher",err)});return publishIfChanged(),stop}import{spawn as spawn4}from"child_process";function runGit(worktreePath,args,signal){return new Promise((resolve)=>{let stdout="",settled=!1,finish=(status)=>{if(settled)return;settled=!0,resolve(status===0?stdout:null)},child=spawn4("git",args.slice(),{cwd:worktreePath,stdio:["ignore","pipe","ignore"],env:{...process.env,GIT_OPTIONAL_LOCKS:"0"},signal,killSignal:"SIGKILL"});child.stdout?.on("data",(chunk)=>{stdout+=String(chunk)}),child.on("error",()=>finish(null)),child.on("close",finish)})}async function countDrift(worktreePath,baseRef,signal){return parseAheadBehind(await runGit(worktreePath,["rev-list","--left-right","--count",`${baseRef}...HEAD`],signal))}function parseAheadBehind(stdout){if(stdout===null)return null;let parts=stdout.trim().split(/\s+/);if(parts.length!==2)return null;let behind=Number.parseInt(parts[0]??"",10),ahead=Number.parseInt(parts[1]??"",10);if(!Number.isInteger(behind)||behind<0||!Number.isInteger(ahead)||ahead<0)return null;return{behind,ahead}}function countPorcelain(stdout){let added=0,deleted=0;for(let row of parsePorcelainRows(stdout))if(row.x==="D"||row.y==="D")deleted++;else added++;return{added,deleted}}async function runGitStatus(worktreePath,signal,baseRef){let stdout=await runGit(worktreePath,["status","--porcelain=v1"],signal);if(stdout===null)throw Error("git status failed");let counts=countPorcelain(stdout);if(!baseRef)return counts;let drift=await countDrift(worktreePath,baseRef,signal);return drift===null?counts:{...counts,...drift}}var EMPTY_PATHS=new Set;function isRemoteRepoKey2(value){return value.startsWith("ssh://")}function sameWorktreeChanges(a,b){return a.added===b.added&&a.deleted===b.deleted&&a.behind===b.behind&&a.ahead===b.ahead}var DEFAULT_WORKTREE_CHANGES_TICK_MS=2000,WORKTREE_CHANGES_CONCURRENCY=4,WORKTREE_CHANGES_TIMEOUT_MS=4000,WORKTREE_CHANGES_SLOW_RETRY_MS=60000,WORKTREE_CHANGES_MIN_INTERVAL_MS=1500,WORKTREE_CHANGES_QUIET_INTERVAL_MS=60000;function trackedWorktreePaths(tasks){let paths=new Map;for(let task of tasks){if(!task.worktreePath)continue;if(isRemoteRepoKey2(task.repo)||isRemoteRepoKey2(task.worktreePath))continue;if(paths.get(task.worktreePath)===void 0)paths.set(task.worktreePath,task.baseRef)}return paths}var UNREADABLE=Symbol("worktree-changes-unreadable");class WorktreeChangesCollector{orch;bus;options;entries=new Map;stopped=!1;queued=new Map;active=0;activePaths=new Set;drainHandle;publishTimer;controllers=new Set;constructor(orch,bus,options={}){this.orch=orch;this.bus=bus;this.options=options}tick(){if(this.stopped)return;if(this.options.hasSubscribers&&!this.options.hasSubscribers())return;try{let tasks=this.orch.listTasks(),tracked=trackedWorktreePaths(tasks),pruned=!1;for(let path of this.entries.keys()){if(tracked.has(path))continue;if(this.entries.get(path)?.value)pruned=!0;this.entries.delete(path),this.queued.delete(path)}for(let path of this.queued.keys())if(!tracked.has(path))this.queued.delete(path);if(pruned)this.publish();let busy=this.busyPaths(tasks);for(let[path,baseRef]of tracked)if(!this.entries.get(path)?.inFlight)this.queued.set(path,{baseRef,busy:busy.has(path)});this.drain()}catch(err){logDaemonError("worktree-changes",err)}}stop(){if(this.stopped=!0,this.queued.clear(),this.drainHandle)clearImmediate(this.drainHandle);if(this.publishTimer)clearTimeout(this.publishTimer);for(let controller of this.controllers)controller.abort()}drain(){if(this.stopped||this.options.hasSubscribers?.()===!1)return;let limit=WORKTREE_CHANGES_CONCURRENCY;for(let[path,demand]of this.queued){if(this.active>=limit)break;if(this.activePaths.has(path))continue;this.queued.delete(path);try{this.maybeCollect(path,demand.baseRef,demand.busy)}catch(err){logDaemonError("worktree-changes",err)}}}runFinished(path){if(this.active--,this.activePaths.delete(path),this.stopped||this.drainHandle)return;this.drainHandle=setImmediate(()=>{this.drainHandle=void 0,this.drain()})}busyPaths(tasks){let ids=this.options.activeTaskIds?.();if(!ids)return EMPTY_PATHS;let active=new Set(ids);if(active.size===0)return EMPTY_PATHS;let paths=new Set;for(let task of tasks)if(task.worktreePath&&active.has(task.id))paths.add(task.worktreePath);return paths}maybeCollect(worktreePath,baseRef,busy=!1){let entry=this.entries.get(worktreePath);if(!entry)entry={inFlight:!1,nextAllowedAt:0},this.entries.set(worktreePath,entry);let now=Date.now(),probe=(this.options.probe??worktreeFingerprint)(worktreePath,baseRef),quietUntil=entry.quietUntil??0;if(!busy&&probe!==null&&probe===entry.probe&&now<quietUntil)return;let quietIntervalMs=this.options.quietIntervalMs??WORKTREE_CHANGES_QUIET_INTERVAL_MS,cadence=this.options.cadence??{timeoutMs:WORKTREE_CHANGES_TIMEOUT_MS,slowRetryMs:WORKTREE_CHANGES_SLOW_RETRY_MS,minIntervalMs:WORKTREE_CHANGES_MIN_INTERVAL_MS},run=this.options.run??runGitStatus;maybeStartScheduledRun(entry,cadence,(signal)=>{entry.probe=probe,entry.quietUntil=Date.now()+quietIntervalMs,this.active++,this.activePaths.add(worktreePath);let controller=new AbortController;this.controllers.add(controller);let abort=()=>controller.abort();return signal.addEventListener("abort",abort,{once:!0}),(async()=>{try{return await run(worktreePath,controller.signal,baseRef)}catch{return UNREADABLE}finally{signal.removeEventListener("abort",abort),this.controllers.delete(controller),this.runFinished(worktreePath)}})()},(value)=>{if(this.stopped)return;if(this.entries.get(worktreePath)!==entry)return;if(value===UNREADABLE&&entry.value!==void 0&&entry.value!==UNREADABLE)return;if(entry.value===value)return;if(entry.value&&entry.value!==UNREADABLE&&value!==UNREADABLE&&sameWorktreeChanges(entry.value,value))return;entry.value=value,this.publish()})}publish(){if(this.publishTimer||this.stopped)return;this.publishTimer=setTimeout(()=>{if(this.publishTimer=void 0,!this.stopped)this.publishNow()},this.options.publishDelayMs??10)}publishNow(){let changes={},unreadable=[];for(let[path,entry]of this.entries)if(entry.value===UNREADABLE)unreadable.push(path);else if(entry.value)changes[path]=entry.value;this.bus.publish("worktree.changes",unreadable.length>0?{changes,unreadable}:{changes})}}function startWorktreeChangesCollector(orch,runtime,bus,tickMs=DEFAULT_WORKTREE_CHANGES_TICK_MS,hasSubscribers,activeTaskIds){let collector=new WorktreeChangesCollector(orch,bus,{hasSubscribers,run:runtime.runWorktreeStatus,...activeTaskIds?{activeTaskIds}:{}});return startTicker({name:"worktree-changes-collector",tickMs,immediate:!0,run:()=>collector.tick(),onStop:()=>collector.stop()})}var DEFAULT_UPDATE_POLL_MS=21600000;function createProtocolUpgradeReporter(orch,runtime){return(taskId,tabId,evidence)=>{if(tabId!=="tab-1")return;let task=orch.getTask(taskId);if(!task)return;let upgrade=runtime.resolveProtocolUpgrade?.(task,evidence);if(!upgrade)return;return orch.setCommand(taskId,upgrade.command,upgrade.vendor).then(()=>logDaemonInfo("protocol-sniff",`upgraded task ${taskId} to the ${upgrade.vendor} protocol from its live session`)).catch((err)=>logDaemonError("protocol-sniff",err))}}function startDaemonCollectors(orch,runtime,bus,hasSubscribersFor,options,quotaUsage,automations,activity){let stopActivityObserver=activity?startActivityObserver(activity,{...createActivityObserverIo(options.homeDir,runtime,activity),onEngineEvidence:createProtocolUpgradeReporter(orch,runtime)},()=>hasSubscribersFor("engine-state")):()=>{},checkUpdate=options.checkUpdate??runtime.checkLatestVersion,updatePollMs=options.updatePollMs??DEFAULT_UPDATE_POLL_MS,pollUpdate=()=>{checkUpdate().then((info)=>bus.publish("update",{info})).catch((err)=>logDaemonError("update-poller",err))},updateTimer=null;if(updatePollMs>0)pollUpdate(),updateTimer=setInterval(pollUpdate,updatePollMs),updateTimer.unref?.();let stopAutoTitlePoller=startAutoTitlePoller(orch,runtime,options.autoTitlePollMs??DEFAULT_AUTO_TITLE_POLL_MS,()=>hasSubscribersFor("task.snapshot")),stopUiPrefsWatcher=startUiPrefsWatcher(bus,{statePath:defaultUiPrefsStatePath(options.homeDir),debounceMs:options.uiPrefsDebounceMs??DEFAULT_UI_PREFS_DEBOUNCE_MS}),stopKeybindingsWatcher=startKeybindingsWatcher(bus,{path:defaultKeybindingsPath(options.homeDir),debounceMs:options.keybindingsDebounceMs??DEFAULT_KEYBINDINGS_DEBOUNCE_MS}),stopWorktreeChangesCollector=startWorktreeChangesCollector(orch,runtime,bus,options.worktreeChangesTickMs??DEFAULT_WORKTREE_CHANGES_TICK_MS,()=>hasSubscribersFor("worktree.changes"),activity?()=>activity.currentNonIdle().map((e)=>e.taskId):void 0),stopTranscriptActivityCollector=startTranscriptActivityCollector(orch,runtime,bus,options.transcriptActivityTickMs??DEFAULT_TRANSCRIPT_ACTIVITY_TICK_MS,()=>hasSubscribersFor("transcript.activity")),stopContextUsageCollector=activity?startContextUsageCollector(activity,orch,bus,runtime,options.contextUsageTickMs??DEFAULT_CONTEXT_USAGE_TICK_MS,()=>hasSubscribersFor("usage.context")):()=>{},stopPrStatusPoller=startPrStatusPoller(orch,runtime,options.prStatusPollMs??DEFAULT_PR_STATUS_POLL_MS,()=>hasSubscribersFor("task.snapshot"),void 0,activity?()=>activity.currentNonIdle().some((e)=>e.state!=="idle"):void 0),stopQuotaResumeRunner=startQuotaResumeRunner(orch,runtime,options.quotaResumeTickMs??DEFAULT_QUOTA_RESUME_TICK_MS,void 0,automations?.plugins),stopAutomationRunner=automations?startAutomationRunner({store:automations.store,orch,runtime,link:automations.link,...automations.plugins?{plugins:automations.plugins}:{},...automations.inbox?{inbox:automations.inbox}:{}},options.automationTickMs??DEFAULT_AUTOMATION_TICK_MS):()=>{},stopQuotaUsagePoller=quotaUsage?startQuotaUsagePoller(quotaUsage,()=>runtime.vendorsWithQuotaProbe(),()=>hasSubscribersFor("usage.snapshot"),options.quotaUsageTickMs):()=>{};return async()=>{if(updateTimer)clearInterval(updateTimer);await Promise.allSettled([stopActivityObserver,stopAutoTitlePoller,stopPrStatusPoller,stopQuotaResumeRunner,stopAutomationRunner,stopQuotaUsagePoller,stopUiPrefsWatcher,stopKeybindingsWatcher,stopWorktreeChangesCollector,stopTranscriptActivityCollector,stopContextUsageCollector].map(async(stop)=>stop()))}}var AGENT_TURN_HANDLERS=[{name:"agentTurn.list",handle(payload,ctx){let taskId=optionalString(payload,"taskId"),repo=optionalString(payload,"repoRoot"),since=optionalNumber(payload,"since"),limit=optionalNumber(payload,"limit");return{turns:ctx.agentTurns?.list({...taskId?{taskId}:{},...repo?{repo}:{},...since!==void 0?{since}:{},...limit!==void 0?{limit}:{}})??[]}}}];var ATTENTION_HANDLERS=[{name:"attention.dismissRoutine",async handle(payload,ctx){return await ctx.inbox.deleteRoutineEpisode(requireString(payload,"automationId")),{deleted:!0}}},{name:"attention.dismiss",async handle(payload,ctx){let taskId=requireString(payload,"taskId"),tabId=optionalString(payload,"tabId")??null,at=payload.at===void 0?void 0:requireNumber(payload,"at"),deleted=await ctx.inbox.deleteEpisode(taskId,tabId,at);if(deleted)ctx.plugins?.handleUiReport({kind:"attention.handled",taskId,detail:{how:"dismissed",...tabId?{tabId}:{}}});return{deleted}}},{name:"attention.read",async handle(payload,ctx){let taskId=requireString(payload,"taskId"),tabId=optionalString(payload,"tabId")??null,at=requireNumber(payload,"at"),updated=await ctx.inbox.markRead(taskId,tabId,at);if(updated)ctx.plugins?.handleUiReport({kind:"attention.handled",taskId,detail:{how:"read",...tabId?{tabId}:{}}});return{updated}}}];import{execFile}from"child_process";import{stat}from"fs/promises";import{promisify}from"util";var execFileAsync=promisify(execFile);function isProbeable(repo){return!repo.startsWith("ssh://")}async function isGitWorkTree(repo){try{let{stdout}=await execFileAsync("git",["-C",repo,"rev-parse","--is-inside-work-tree"]);return stdout.trim()==="true"}catch{return!1}}async function assertRoutineRepo(repo){if(!isProbeable(repo))return;if(!(await stat(repo).catch(()=>null))?.isDirectory())throw Error(`repo does not exist: ${repo}`);if(!await isGitWorkTree(repo))throw Error(`not a git repository: ${repo}`)}async function assertRoutineBaseRef(repo,ref){if(!ref||!isProbeable(repo))return;if(!await isGitWorkTree(repo))return;try{await execFileAsync("git",["-C",repo,"rev-parse","--verify","--quiet",`${ref}^{commit}`])}catch{throw Error(`base branch does not resolve in ${repo}: ${ref}`)}}function requireSchedule(payload,key){let schedule=requireString(payload,key);if(!isValidCron(schedule))throw Error(`invalid cron expression: ${schedule}`);return schedule}function readPrecheck(payload){if(!("precheck"in payload))return;let raw=payload.precheck;if(raw===null)return null;if(!raw||typeof raw!=="object")throw Error("precheck must be an object or null");let command=requireString(raw,"command"),timeoutSeconds=optionalNumber(raw,"timeoutSeconds")??120;if(timeoutSeconds<=0)throw Error("precheck.timeoutSeconds must be greater than zero");return{command,timeoutSeconds}}function readGraceMinutes(payload){let value=optionalNumber(payload,"missedRunGraceMinutes");if(value!==void 0&&value<0)throw Error("missedRunGraceMinutes must be zero or more minutes");return value}var AUTOMATION_HANDLERS=[{name:"automation.list",async handle(_payload,ctx){let automations=ctx.automations.list(),lastRunStatus={};for(let automation of automations){let latest=ctx.automations.runsFor(automation.id,1)[0];if(latest)lastRunStatus[automation.id]=latest.status}return{automations,lastRunStatus,keepsDaemonAlive:ctx.automations.hasEnabled()}}},{name:"automation.create",async handle(payload,ctx){let precheck=readPrecheck(payload),repo=requireString(payload,"repo"),baseRef=optionalString(payload,"baseRef"),target="target"in payload?readAutomationTarget(payload.target):void 0;if(!target)await assertRoutineRepo(repo);if(baseRef)await assertRoutineBaseRef(repo,baseRef);let targetOptions={target:target??void 0,vendor:optionalVendor(payload,"vendor"),baseRef,persistentSession:optionalBoolean(payload,"persistentSession")};assertAutomationTargetOptions(targetOptions),await assertAutomationTargetTask({repo,target:target??void 0},ctx.orch);let automation=await ctx.automations.create({name:requireString(payload,"name"),repo,...target?{target}:{},prompt:requireString(payload,"prompt"),schedule:requireSchedule(payload,"schedule"),missedRunGraceMinutes:readGraceMinutes(payload)??60,...optionalVendor(payload,"vendor")?{vendor:optionalVendor(payload,"vendor")}:{},...precheck?{precheck}:{},...baseRef?{baseRef}:{},...optionalBoolean(payload,"persistentSession")===!0?{persistentSession:!0}:{},...optionalBoolean(payload,"enabled")!==void 0?{enabled:optionalBoolean(payload,"enabled")}:{}});return ctx.daemon.reevaluateIdle(),{automation}}},{name:"automation.update",async handle(payload,ctx){let id=requireString(payload,"id"),nextBaseRef="baseRef"in payload?optionalString(payload,"baseRef"):void 0,currentRepo=ctx.automations.get(id)?.repo;if(nextBaseRef&&currentRepo)await assertRoutineBaseRef(currentRepo,nextBaseRef);let patch={...optionalString(payload,"name")!==void 0?{name:optionalString(payload,"name")}:{},...optionalString(payload,"prompt")!==void 0?{prompt:optionalString(payload,"prompt")}:{},...payload.vendor===null?{vendor:null}:optionalVendor(payload,"vendor")!==void 0?{vendor:optionalVendor(payload,"vendor")}:{},..."target"in payload?{target:readAutomationTarget(payload.target)}:{},..."schedule"in payload?{schedule:requireSchedule(payload,"schedule")}:{},...readPrecheck(payload)!==void 0?{precheck:readPrecheck(payload)}:{},..."baseRef"in payload?{baseRef:optionalString(payload,"baseRef")??null}:{},...optionalBoolean(payload,"enabled")!==void 0?{enabled:optionalBoolean(payload,"enabled")}:{},...readGraceMinutes(payload)!==void 0?{missedRunGraceMinutes:readGraceMinutes(payload)}:{},...optionalBoolean(payload,"persistentSession")!==void 0?{persistentSession:optionalBoolean(payload,"persistentSession")}:{}},current=ctx.automations.get(id);if(!current)throw Error(`automation not found: ${id}`);let targetOptions=mergeAutomationTargetOptions(current,patch);if(assertAutomationTargetOptions(targetOptions),patch.target)await assertAutomationTargetTask({repo:current.repo,target:patch.target},ctx.orch);let automation=await ctx.automations.update(id,patch);if(!automation)throw Error(`automation not found: ${id}`);return ctx.daemon.reevaluateIdle(),{automation}}},{name:"automation.delete",async handle(payload,ctx){let id=requireString(payload,"id"),deleted=await ctx.automations.delete(id);if(deleted)await ctx.inbox.deleteRoutineEpisode(id).catch(()=>{}),ctx.daemon.reevaluateIdle();return{deleted}}},{name:"automation.runs",async handle(payload,ctx){let automationId=requireString(payload,"id");if(!ctx.automations.get(automationId))throw Error(`automation not found: ${automationId}`);return{runs:ctx.automations.runsFor(automationId)}}},{name:"automation.runNow",blocking:!0,async handle(payload,ctx){let id=requireString(payload,"id"),automation=ctx.automations.get(id);if(!automation)throw Error(`automation not found: ${id}`);return{status:await runAutomationOnce({store:ctx.automations,orch:ctx.orch,runtime:ctx.runtime,link:ctx.selfLink,...ctx.plugins?{plugins:()=>ctx.plugins??null}:{},inbox:ctx.inbox},automation,{scheduledFor:Date.now(),trigger:"manual"})}}}];async function ingestAgentTurns(store,runtime,orch,input){if(!input.transcriptPath)return{recorded:0,latest:void 0};let task=orch.getTask(input.taskId),vendor=input.vendor??task?.vendor;if(!vendor)return{recorded:0,latest:void 0};let turns=await runtime.readEngineTurns(vendor,input.transcriptPath);if(turns.length===0)return{recorded:0,latest:void 0};let records=turns.map((turn)=>({...turn,taskId:input.taskId,...input.tabId?{tabId:input.tabId}:{},vendor,...task?.repo?{repo:task.repo}:{}})),recorded=await store.record(records),last=records[records.length-1],latest=last?{id:last.id,model:last.model,usage:last.usage,startedAt:last.startedAt,endedAt:last.endedAt}:void 0;return{recorded,latest}}function ingestAgentTurnsBestEffort(store,runtime,orch,input,onDone){if(!store){onDone?.(void 0);return}ingestAgentTurns(store,runtime,orch,input).then(({latest})=>onDone?.(latest)).catch((err)=>{logDaemonError("agent-turns-ingest",err),onDone?.(void 0)})}import{existsSync as existsSync2}from"fs";import path from"path";function crossesRepoBoundary(wt,cwd){let syntax=pathSyntax(cwd);for(let dir=cwd;!samePath(dir,wt);dir=syntax.dirname(dir)){if(existsSync2(syntax.join(dir,".git")))return!0;if(samePath(dir,syntax.dirname(dir)))break}return!1}function matchTaskByCwd(tasks,cwd){let target=pathIdentity(cwd),bestId,bestWt="",bestLen=-1;for(let t of tasks){if(!t.worktreePath)continue;let wt=pathIdentity(t.worktreePath);if(pathWithin(wt,target)!==null&&wt.length>bestLen)bestLen=wt.length,bestWt=wt,bestId=t.id}if(bestId&&crossesRepoBoundary(bestWt,target))return;return bestId}function matchTaskByWorktreePath(tasks,worktreePath){let target=pathIdentity(worktreePath);for(let t of tasks)if(t.worktreePath&&pathIdentity(t.worktreePath)===target)return t.id;return}function findAdoptableWorktree(tasks,cwd){let target=pathIdentity(cwd),repos=new Set,known=new Set;for(let t of tasks){if(t.repo&&path.isAbsolute(t.repo))repos.add(pathIdentity(t.repo));if(t.worktreePath)known.add(pathIdentity(t.worktreePath))}for(let repo of repos)for(let root of managedWorktreeRootsFor(repo,readWorktreeBaseOverride(repo)).map(pathIdentity)){let prefix=root.endsWith("/")?root:`${root}/`,rest=pathWithin(root,target);if(!rest)continue;let name=rest.split("/")[0];if(!name)continue;let worktreePath=`${prefix}${name}`;if(known.has(worktreePath))return;return{repo,worktreePath}}return}var ENGINE_REPORT_HANDLER={name:"engine.reportEvent",async handle(payload,ctx){let kind=requireString(payload,"kind");if(!ctx.runtime.isEngineActivityKind(kind))throw Error(`BAD_EVENT_KIND: unknown engine event kind: ${kind}`);let explicitId=optionalString(payload,"taskId"),cwd=optionalString(payload,"cwd");if(!explicitId&&cwd&&kind==="session-start"){let cand=findAdoptableWorktree(ctx.orch.listTasks(),cwd);if(cand)try{await ctx.orch.adoptWorktree({repo:cand.repo,worktreePath:cand.worktreePath,ifExists:"return"})}catch(err){logDaemonError("worktree-autosync",err)}}let taskId=explicitId??(cwd?matchTaskByCwd(ctx.orch.listTasks(),cwd):void 0);if(!taskId)return{};let detail=optionalActivityDetail(payload),tabId=optionalString(payload,"tabId"),sessionId=optionalString(payload,"sessionId"),transcriptPath=optionalString(payload,"transcriptPath"),session=sessionId?{id:sessionId,transcriptPath}:void 0,isStateKind=ctx.runtime.affectsActivityState(kind),vendor=optionalString(payload,"engine");if(isStateKind){if(ctx.activity.report(taskId,kind,detail,tabId,session,vendor),explicitId)await ctx.inbox.record(taskId,kind,detail,tabId??null).catch((err)=>logDaemonError("attention-inbox-record",err))}if(ctx.engineEvents?.append(taskId,{kind,...tabId?{tabId}:{},...vendor?{vendor}:{},...detail?{detail}:{},at:Date.now()}),kind==="pre-compact"||kind==="post-compact"||kind==="subagent-start"||kind==="subagent-stop")ctx.bus.publish("engine.lifecycle",{taskId,kind,...tabId?{tabId}:{},at:Date.now()});let pluginReport={kind,taskId,...detail?{detail}:{},...vendor?{vendor}:{},...tabId?{tabId}:{},...sessionId?{sessionId}:{}};if(kind!=="turn-complete")ctx.plugins?.handleEngineReport(pluginReport);if(kind==="turn-complete")ingestAgentTurnsBestEffort(ctx.agentTurns,ctx.runtime,ctx.orch,{taskId,...tabId?{tabId}:{},...vendor?{vendor}:{},...transcriptPath?{transcriptPath}:{}},(latest)=>ctx.plugins?.handleEngineReport(latest?{...pluginReport,detail:{...pluginReport.detail??{},turn:latest}}:pluginReport));if(kind==="turn-start"){if(ctx.runtime.maybeAutoStart(ctx.orch,taskId).then((result)=>{if(result==="moved")console.log(`[status-rules] task ${taskId} auto-moved backlog \u2192 in_progress`)}).catch((err)=>logDaemonError("status-rules",err)),ctx.orch.getTask(taskId)?.quotaResume)ctx.orch.setQuotaResume(taskId,null).catch((err)=>logDaemonError("quota-resume",err))}if(kind==="turn-failed"&&detail?.failure==="rate_limit")scheduleQuotaResume(ctx.orch,ctx.runtime,ctx.quotaUsage,taskId,void 0,()=>ctx.plugins??null).catch((err)=>logDaemonError("quota-resume",err));return{}}};function publishIssueSnapshot(ctx,state){if(ctx.daemon.hasSubscribersFor?.("issue.snapshot")===!1)return;ctx.bus.publish("issue.snapshot",state)}var ISSUE_HANDLERS=[{name:"issue.list",async handle(payload,ctx){return ctx.issues.list(requireString(payload,"repoRoot"))}},{name:"issue.repos",async handle(_payload,ctx){return{repos:await ctx.issues.repos()}}},{name:"issue.mutate",async handle(payload,ctx){let repoRoot=requireString(payload,"repoRoot"),op=payload.op,opType=op&&typeof op==="object"?op.type:void 0;if(opType==="link"||opType==="update"){let taskId=op.taskId;if(typeof taskId==="string"&&taskId.length>0&&!ctx.orch.getTask(taskId))throw Error(`task not found: ${taskId}`)}let state=await ctx.issues.mutate(repoRoot,payload.op);return publishIssueSnapshot(ctx,state),ctx.plugins?.handleUiReport({kind:"issue.changed",detail:{repo:repoRoot,...payload.op&&typeof payload.op==="object"?{op:payload.op}:{}}}),state}}];var MAX_FAILING_JOBS=3,MAX_TAIL_LINES=200,RUN_LOG_TIMEOUT_MS=30000;function stringField(value,key){if(typeof value!=="object"||value===null)return"";let field=value[key];return typeof field==="string"?field:""}function runIdFromDetailsUrl(url){return/\/actions\/runs\/(\d+)\b/.exec(url)?.[1]??null}function failingCheckTargets(rollup){let targets=[];for(let entry of rollup){let status=stringField(entry,"status").toUpperCase(),conclusion=stringField(entry,"conclusion").toUpperCase(),contextState=stringField(entry,"state").toUpperCase(),failedAs=null;if(status&&status!=="COMPLETED")failedAs=null;else if(conclusion)failedAs=conclusion==="SUCCESS"||conclusion==="NEUTRAL"||conclusion==="SKIPPED"?null:conclusion;else if(contextState==="FAILURE"||contextState==="ERROR")failedAs=contextState;if(failedAs===null)continue;let url=stringField(entry,"detailsUrl")||stringField(entry,"targetUrl");targets.push({jobName:stringField(entry,"name")||stringField(entry,"context")||"check",conclusion:failedAs,url,runId:runIdFromDetailsUrl(url)})}return targets}function parseFailedRunLog(text,maxLines=MAX_TAIL_LINES){let byJob=new Map;for(let raw of text.split(`
5
5
  `)){let line=raw.replace(/\r$/,"");if(line.length===0)continue;let firstTab=line.indexOf("\t");if(firstTab<=0)continue;let job=line.slice(0,firstTab),secondTab=line.indexOf("\t",firstTab+1),body=(secondTab===-1?line.slice(firstTab+1):line.slice(secondTab+1)).replace(/^\uFEFF/,""),lines=byJob.get(job);if(!lines)lines=[],byJob.set(job,lines);if(lines.push(body),lines.length>maxLines)lines.shift()}return byJob}function joinFailingChecks(targets,logsByJob){return{checks:targets.slice(0,MAX_FAILING_JOBS).map((target)=>({jobName:target.jobName,conclusion:target.conclusion,url:target.url,tail:(logsByJob.get(target.jobName)??[]).join(`
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-94eb11hz.js";import{t}from"./chunk-fa7s3d1e.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function noEngineAction(signedOut){return signedOut.length>0?t("doctor.fix.noEngineLoginAction",{list:signedOut.join(", ")}):t("doctor.fix.noEngineAction")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}async function probeGit(){try{let proc=Bun.spawn(["git","--version"],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),text=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&text)return{line:`git: \u2713 ${text}`,found:!0}}catch{}return{line:"git: \u2717 not found on PATH",found:!1}}function binaryLabel(binary){return binary.found?`\u2713 ${binary.path}`:`\u2717 ${binary.error}`}async function probeEngines(){let statuses=await detectEngineStatuses(await probeableEngineIds()),lines=["engines:"];for(let status of statuses){let account=describeAccount(status.account),name=`${status.vendor.padEnd(7)} `;if(lines.push(` ${name}${binaryLabel(status.binary)}${status.binary.found?` \u2014 ${account}`:""}`),status.accountError)lines.push(` \u26A0 ${status.accountError}`)}let{usable,signedOut}=summarizeEngines(statuses);return{lines,anyUsable:usable.length>0,signedOut}}async function checkOnboardingEnv(){let[git,engines]=await Promise.all([probeGit(),probeEngines()]);return{git,engines}}
2
+ import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-br6dggaa.js";import{t}from"./chunk-fa7s3d1e.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function noEngineAction(signedOut){return signedOut.length>0?t("doctor.fix.noEngineLoginAction",{list:signedOut.join(", ")}):t("doctor.fix.noEngineAction")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}async function probeGit(){try{let proc=Bun.spawn(["git","--version"],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),text=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&text)return{line:`git: \u2713 ${text}`,found:!0}}catch{}return{line:"git: \u2717 not found on PATH",found:!1}}function binaryLabel(binary){return binary.found?`\u2713 ${binary.path}`:`\u2717 ${binary.error}`}async function probeEngines(){let statuses=await detectEngineStatuses(await probeableEngineIds()),lines=["engines:"];for(let status of statuses){let account=describeAccount(status.account),name=`${status.vendor.padEnd(7)} `;if(lines.push(` ${name}${binaryLabel(status.binary)}${status.binary.found?` \u2014 ${account}`:""}`),status.accountError)lines.push(` \u26A0 ${status.accountError}`)}let{usable,signedOut}=summarizeEngines(statuses);return{lines,anyUsable:usable.length>0,signedOut}}async function checkOnboardingEnv(){let[git,engines]=await Promise.all([probeGit(),probeEngines()]);return{git,engines}}
3
3
  export{daemonRestartFix,skillInstallFix,resetManualFix,killOrphansManualFix,engineTabsManualFix,reinstallManualFix,spawnHelperFix,humanOnlyFix,noEngineFix,noEngineAction,applyFixes,defaultFixRuntime,probeGit,probeEngines,checkOnboardingEnv};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{applyOnboardingChoices,detectShell,envReadyForTasks,installCompletions,maybeRunOnboarding}from"./chunk-b3xxh6v9.js";import"./chunk-r0hekyyy.js";import"./chunk-94eb11hz.js";import"./chunk-wvq6kgcp.js";import"./chunk-6xwg11k1.js";import"./chunk-n3b6yr9e.js";import"./chunk-7r17j4te.js";import"./chunk-km4hx6kc.js";import"./chunk-fa7s3d1e.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-jvxh93nz.js";import"./chunk-pz5y8f3r.js";import"./chunk-80hf0bbr.js";import"./chunk-khj0apc7.js";import"./chunk-5zh5fcpe.js";import"./chunk-w7zv47mp.js";import"./chunk-v61s3fps.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-r9gfh1zz.js";import"./chunk-xy8be792.js";import"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-pxk2c2vj.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{maybeRunOnboarding,installCompletions,envReadyForTasks,detectShell,applyOnboardingChoices};
2
+ import{applyOnboardingChoices,detectShell,envReadyForTasks,installCompletions,maybeRunOnboarding}from"./chunk-nnmpben9.js";import"./chunk-3dexjt11.js";import"./chunk-br6dggaa.js";import"./chunk-wvq6kgcp.js";import"./chunk-y9bgn622.js";import"./chunk-nnscywzf.js";import"./chunk-xr30vfgt.js";import"./chunk-km4hx6kc.js";import"./chunk-fa7s3d1e.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-jvxh93nz.js";import"./chunk-z5x3cd7j.js";import"./chunk-80hf0bbr.js";import"./chunk-khj0apc7.js";import"./chunk-5zh5fcpe.js";import"./chunk-w7zv47mp.js";import"./chunk-v61s3fps.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-r9gfh1zz.js";import"./chunk-xy8be792.js";import"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-pxk2c2vj.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{maybeRunOnboarding,installCompletions,envReadyForTasks,detectShell,applyOnboardingChoices};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{updaterShell,updaterShellFailureHint}from"./chunk-r2qn2k6r.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-n3b6yr9e.js";import"./chunk-b99tf0jr.js";import"./chunk-q5jhy3t8.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";var CLI_NAME=activeCliName();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-k0xgtzm2.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-nnscywzf.js";import"./chunk-b99tf0jr.js";import"./chunk-q5jhy3t8.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";var CLI_NAME=activeCliName();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
 
@@ -10,7 +10,7 @@ import{updaterShell,updaterShellFailureHint}from"./chunk-r2qn2k6r.js";import{BRE
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-d7fk35g9.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-615s6xjd.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{releaseBodyLines,runShellUpdater}from"./chunk-ge7bva0a.js";import{$jsx,$jsxs,bootPaneHost,pageCloseBindings,require_react_production,useBindings,useRenderer,useT,useTheme}from"./chunk-y8dn3rez.js";import"./chunk-764bsyb0.js";import"./chunk-r2qn2k6r.js";import"./chunk-xqw5d5rv.js";import"./chunk-h4n8ffqy.js";import"./chunk-6xppe9bj.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-n3b6yr9e.js";import"./chunk-6tvs0r4z.js";import"./chunk-z7c6nap0.js";import"./chunk-fa7s3d1e.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-b99tf0jr.js";import"./chunk-fczqwtmq.js";import"./chunk-fbc5d1fq.js";import"./chunk-y13681dw.js";import"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import"./chunk-xy8be792.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-sb0ns0c7.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.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):[];import_react2.useEffect(()=>{fetchReleaseSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),fetchReleaseNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes]);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"?releaseBodyLines(selectedNotes.body).map((line,i)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:line},`${i}:${line}`)):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};
2
+ import{releaseBodyLines,runShellUpdater}from"./chunk-8qx3959c.js";import{$jsx,$jsxs,bootPaneHost,pageCloseBindings,require_react_production,useBindings,useRenderer,useT,useTheme}from"./chunk-zkj59kkd.js";import"./chunk-764bsyb0.js";import"./chunk-k0xgtzm2.js";import"./chunk-xqw5d5rv.js";import"./chunk-h4n8ffqy.js";import"./chunk-6xppe9bj.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-nnscywzf.js";import"./chunk-6tvs0r4z.js";import"./chunk-z7c6nap0.js";import"./chunk-fa7s3d1e.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-b99tf0jr.js";import"./chunk-fczqwtmq.js";import"./chunk-te8g5azg.js";import"./chunk-y13681dw.js";import"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import"./chunk-xy8be792.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-sb0ns0c7.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.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):[];import_react2.useEffect(()=>{fetchReleaseSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),fetchReleaseNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes]);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"?releaseBodyLines(selectedNotes.body).map((line,i)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:line},`${i}:${line}`)):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};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{writeOutdatedCache}from"./chunk-5ygc7rce.js";import{PluginCliError,installPlugin}from"./chunk-71g9dn38.js";import{loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginDataDir,pluginStateDir,removePluginEntry,savePluginRegistry}from"./chunk-g2e1dmxh.js";import"./chunk-n3b6yr9e.js";import"./chunk-mnqxgvyb.js";import"./chunk-w7zv47mp.js";import"./chunk-q5jhy3t8.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{execFileSync}from"child_process";import{existsSync,mkdirSync,readdirSync,renameSync}from"fs";import{join}from"path";function gitOut(args,cwd){try{return execFileSync("git",args,{cwd,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function checkEntry(entry){let repoSpec=entry.source.spec.split("/").slice(0,2).join("/"),localSha=gitOut(["rev-parse","HEAD"],pluginCheckoutDir(entry.id)),remote=gitOut(["ls-remote",`https://github.com/${repoSpec}.git`,"HEAD"]),remoteSha=remote?remote.split(/\s+/)[0]??null:null;return{id:entry.id,spec:entry.source.spec,version:entry.version,localSha,remoteSha,behind:Boolean(localSha&&remoteSha&&localSha!==remoteSha)}}function listOutdated(){let rows=loadPluginRegistry().plugins.filter((p)=>p.source.kind==="github").map(checkEntry);return writeOutdatedCache(rows.filter((r)=>r.behind).map((r)=>r.id)),rows}function printOutdated(){let rows=listOutdated();if(rows.length===0){console.log("no GitHub-installed plugins.");return}for(let r of rows){let status=r.behind?"update available":r.remoteSha===null?"remote unreachable":r.localSha===null?"local sha unreadable":"up to date";console.log(`${r.id} v${r.version} ${status}`)}}function migrateRenamedPlugin(oldId,newId){for(let dirOf of[pluginConfigDir,pluginStateDir]){let from=dirOf(oldId),to=dirOf(newId);if(!existsSync(from))continue;mkdirSync(to,{recursive:!0});for(let entry of readdirSync(from)){if(existsSync(join(to,entry)))continue;renameSync(join(from,entry),join(to,entry))}}savePluginRegistry(removePluginEntry(loadPluginRegistry(),oldId)),console.log(`renamed ${oldId} \u2192 ${newId}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${pluginDataDir(oldId)}`)}async function updatePlugins(ids,opts){let rows=listOutdated(),targets;if(opts.all){if(targets=rows.filter((r)=>r.behind),targets.length===0){console.log("all plugins up to date.");return}}else{if(ids.length===0)throw new PluginCliError("update takes plugin ids or --all");targets=ids.map((id)=>{let row=rows.find((r)=>r.id===id);if(!row)throw new PluginCliError(`\`${id}\` is not a GitHub-installed plugin; see \`${activeCliName()} plugin list\``);return row})}for(let target of targets){if(!target.behind&&!ids.includes(target.id))continue;console.log(`updating ${target.id} (${target.spec})\u2026`);let installedId=await installPlugin(target.spec,{yes:opts.yes});if(installedId!==target.id)migrateRenamedPlugin(target.id,installedId)}listOutdated()}export{updatePlugins,printOutdated};
2
+ import{writeOutdatedCache}from"./chunk-5ygc7rce.js";import{PluginCliError,installPlugin}from"./chunk-nqkcrhpp.js";import{loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginDataDir,pluginStateDir,removePluginEntry,savePluginRegistry}from"./chunk-g2e1dmxh.js";import"./chunk-nnscywzf.js";import"./chunk-mnqxgvyb.js";import"./chunk-w7zv47mp.js";import"./chunk-q5jhy3t8.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{execFileSync}from"child_process";import{existsSync,mkdirSync,readdirSync,renameSync}from"fs";import{join}from"path";function gitOut(args,cwd){try{return execFileSync("git",args,{cwd,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function checkEntry(entry){let repoSpec=entry.source.spec.split("/").slice(0,2).join("/"),localSha=gitOut(["rev-parse","HEAD"],pluginCheckoutDir(entry.id)),remote=gitOut(["ls-remote",`https://github.com/${repoSpec}.git`,"HEAD"]),remoteSha=remote?remote.split(/\s+/)[0]??null:null;return{id:entry.id,spec:entry.source.spec,version:entry.version,localSha,remoteSha,behind:Boolean(localSha&&remoteSha&&localSha!==remoteSha)}}function listOutdated(){let rows=loadPluginRegistry().plugins.filter((p)=>p.source.kind==="github").map(checkEntry);return writeOutdatedCache(rows.filter((r)=>r.behind).map((r)=>r.id)),rows}function printOutdated(){let rows=listOutdated();if(rows.length===0){console.log("no GitHub-installed plugins.");return}for(let r of rows){let status=r.behind?"update available":r.remoteSha===null?"remote unreachable":r.localSha===null?"local sha unreadable":"up to date";console.log(`${r.id} v${r.version} ${status}`)}}function migrateRenamedPlugin(oldId,newId){for(let dirOf of[pluginConfigDir,pluginStateDir]){let from=dirOf(oldId),to=dirOf(newId);if(!existsSync(from))continue;mkdirSync(to,{recursive:!0});for(let entry of readdirSync(from)){if(existsSync(join(to,entry)))continue;renameSync(join(from,entry),join(to,entry))}}savePluginRegistry(removePluginEntry(loadPluginRegistry(),oldId)),console.log(`renamed ${oldId} \u2192 ${newId}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${pluginDataDir(oldId)}`)}async function updatePlugins(ids,opts){let rows=listOutdated(),targets;if(opts.all){if(targets=rows.filter((r)=>r.behind),targets.length===0){console.log("all plugins up to date.");return}}else{if(ids.length===0)throw new PluginCliError("update takes plugin ids or --all");targets=ids.map((id)=>{let row=rows.find((r)=>r.id===id);if(!row)throw new PluginCliError(`\`${id}\` is not a GitHub-installed plugin; see \`${activeCliName()} plugin list\``);return row})}for(let target of targets){if(!target.behind&&!ids.includes(target.id))continue;console.log(`updating ${target.id} (${target.spec})\u2026`);let installedId=await installPlugin(target.spec,{yes:opts.yes});if(installedId!==target.id)migrateRenamedPlugin(target.id,installedId)}listOutdated()}export{updatePlugins,printOutdated};