@sma1lboy/rove 0.9.150 → 0.9.151
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.
- package/dist/cli/chunk-15k6hqzx.js +2 -0
- package/dist/cli/chunk-1cjd7h8p.js +6 -0
- package/dist/cli/chunk-1vhbnf49.js +2 -0
- package/dist/cli/chunk-2cyzv75r.js +3 -0
- package/dist/cli/{chunk-y34fff4t.js → chunk-3zf7mr7r.js} +1 -1
- package/dist/cli/chunk-4d5bph3p.js +2 -0
- package/dist/cli/chunk-4nm1axc3.js +2 -0
- package/dist/cli/{chunk-g1ybdgad.js → chunk-579zz8df.js} +2 -2
- package/dist/cli/{chunk-r2w8qgyd.js → chunk-5mr9j201.js} +3 -3
- package/dist/cli/{chunk-q6579rbz.js → chunk-5wzap7r2.js} +1 -1
- package/dist/cli/chunk-6kz81dkc.js +17 -0
- package/dist/cli/{chunk-f6zsej8e.js → chunk-6sp2ags8.js} +1 -1
- package/dist/cli/chunk-7jkf3tvr.js +3 -0
- package/dist/cli/{chunk-2w4zymkv.js → chunk-7tfqaet5.js} +1 -1
- package/dist/cli/chunk-7zmrn4gn.js +3 -0
- package/dist/cli/{chunk-nm6adny4.js → chunk-86bjqmg1.js} +1 -1
- package/dist/cli/{chunk-k3ksts6g.js → chunk-87y9qjcm.js} +1 -1
- package/dist/cli/chunk-8rxg6hs2.js +2 -0
- package/dist/cli/chunk-95e0ks8n.js +2 -0
- package/dist/cli/chunk-98thhbm5.js +9 -0
- package/dist/cli/{chunk-7j8zpeer.js → chunk-9nbg0nzh.js} +1 -1
- package/dist/cli/chunk-a3a9gdc4.js +3 -0
- package/dist/cli/{chunk-mrwee8sj.js → chunk-aeq5xmtq.js} +1 -1
- package/dist/cli/chunk-akckb9kw.js +3 -0
- package/dist/cli/chunk-ayagydjk.js +2 -0
- package/dist/cli/chunk-cexxmfva.js +2 -0
- package/dist/cli/chunk-d393z1mj.js +4 -0
- package/dist/cli/{chunk-yeytzg1x.js → chunk-d89r6eqm.js} +1 -1
- package/dist/cli/chunk-dmdqnet6.js +3 -0
- package/dist/cli/{chunk-z3va3mt0.js → chunk-e7t4xpr9.js} +21 -19
- package/dist/cli/chunk-e8493db0.js +4 -0
- package/dist/cli/{chunk-7sgtpyr0.js → chunk-emm50f4q.js} +1 -1
- package/dist/cli/{chunk-bjat0fyy.js → chunk-fm4q306m.js} +1 -1
- package/dist/cli/{chunk-nceh1q3d.js → chunk-fpjcrjna.js} +1 -1
- package/dist/cli/chunk-fyf7xgaa.js +2 -0
- package/dist/cli/{chunk-e1g9mvww.js → chunk-g47vt3k5.js} +1 -1
- package/dist/cli/chunk-gtkejmxx.js +3 -0
- package/dist/cli/{chunk-sm1vhrb6.js → chunk-gzf4dfg6.js} +1 -1
- package/dist/cli/chunk-j5r92gh9.js +2 -0
- package/dist/cli/chunk-jfkw009v.js +2 -0
- package/dist/cli/{chunk-k2gfqqmg.js → chunk-jq5vp0f7.js} +1 -1
- package/dist/cli/{chunk-a0rxr20w.js → chunk-jv5nqjnv.js} +1 -1
- package/dist/cli/chunk-jwv06n3d.js +8 -0
- package/dist/cli/{chunk-mfvy10ep.js → chunk-jy6nd23p.js} +1 -1
- package/dist/cli/{chunk-2ffbcsm6.js → chunk-k1sjc72d.js} +4 -4
- package/dist/cli/chunk-k9skkhzs.js +2 -0
- package/dist/cli/chunk-ktmvmskn.js +4 -0
- package/dist/cli/{chunk-fhfqyfpf.js → chunk-m2xasved.js} +2 -2
- package/dist/cli/chunk-m370e00b.js +4 -0
- package/dist/cli/{chunk-2hgt2esq.js → chunk-m4my5wna.js} +2 -2
- package/dist/cli/chunk-m57cv76y.js +3 -0
- package/dist/cli/chunk-n4dmwkfa.js +4 -0
- package/dist/cli/chunk-nw91q4x3.js +2 -0
- package/dist/cli/{chunk-5kkm6tjz.js → chunk-p9vkwnb8.js} +2 -2
- package/dist/cli/{chunk-cjxwzzq7.js → chunk-pmt3agbd.js} +1 -1
- package/dist/cli/{chunk-0h4cfy44.js → chunk-q0f6rhex.js} +2 -2
- package/dist/cli/chunk-q4ry13v3.js +2 -0
- package/dist/cli/chunk-r1p9bwja.js +7 -0
- package/dist/cli/{chunk-hg5x2wr0.js → chunk-r2pztgm6.js} +2 -2
- package/dist/cli/chunk-rf2m6f3h.js +5 -0
- package/dist/cli/{chunk-vapjtyv9.js → chunk-rgh49bm3.js} +1 -1
- package/dist/cli/{chunk-5gn4chrm.js → chunk-rz8247zr.js} +1 -1
- package/dist/cli/chunk-rz8zs7j8.js +3 -0
- package/dist/cli/{chunk-zb56ck5f.js → chunk-s433recg.js} +1 -1
- package/dist/cli/{chunk-71m4ak4t.js → chunk-s8xyh1bt.js} +1 -1
- package/dist/cli/{chunk-ppe5myr0.js → chunk-sexavazm.js} +1 -1
- package/dist/cli/chunk-ssepbf68.js +2 -0
- package/dist/cli/{chunk-6xhtf9jx.js → chunk-t05pnk6y.js} +1 -1
- package/dist/cli/{chunk-1ps9qzp1.js → chunk-tgxe9ae1.js} +2 -2
- package/dist/cli/{chunk-6zwg6me2.js → chunk-tk8p54f7.js} +1 -1
- package/dist/cli/chunk-tz9e598v.js +2 -0
- package/dist/cli/{chunk-jyv82gf0.js → chunk-w7zv47mp.js} +3 -4
- package/dist/cli/{chunk-khp1ga68.js → chunk-wc1kk5c0.js} +1 -1
- package/dist/cli/{chunk-6h9tc9vn.js → chunk-wzyh3fgx.js} +1 -1
- package/dist/cli/{chunk-8x0h6rwa.js → chunk-x39pv7rx.js} +1 -1
- package/dist/cli/{chunk-b24ykek8.js → chunk-x3gch5nw.js} +1 -1
- package/dist/cli/{chunk-db57060b.js → chunk-x8m1vmyd.js} +1 -1
- package/dist/cli/{chunk-jsss3ze7.js → chunk-xe62kmhp.js} +2 -2
- package/dist/cli/{chunk-1gpx52qj.js → chunk-xnr8dga2.js} +2 -2
- package/dist/cli/chunk-xtr7ks02.js +3 -0
- package/dist/cli/{chunk-fbg4fkmg.js → chunk-y5hnrx8d.js} +1 -1
- package/dist/cli/{chunk-13s8rnk5.js → chunk-y9ksfpbp.js} +1 -1
- package/dist/cli/{chunk-p7kztgsd.js → chunk-ybsdy2w8.js} +1 -1
- package/dist/cli/{chunk-1z9ae43v.js → chunk-yfg503fr.js} +1 -1
- package/dist/cli/{chunk-tfdx5ve6.js → chunk-zaxdx0wd.js} +1 -1
- package/dist/cli/index.js +7 -7
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/pty-host-node.mjs +25 -2
- package/dist/cli/rove.js +1 -1
- package/package.json +2 -1
- package/dist/cli/chunk-003tvywc.js +0 -3
- package/dist/cli/chunk-0kn7xxqm.js +0 -6
- package/dist/cli/chunk-0tw42ad1.js +0 -2
- package/dist/cli/chunk-1cqtm24j.js +0 -8
- package/dist/cli/chunk-20pt9yqh.js +0 -4
- package/dist/cli/chunk-2jxdzw4r.js +0 -3
- package/dist/cli/chunk-2pqqvse3.js +0 -2
- package/dist/cli/chunk-2t62vct7.js +0 -2
- package/dist/cli/chunk-4d7bbh87.js +0 -2
- package/dist/cli/chunk-5b6940vk.js +0 -2
- package/dist/cli/chunk-5hhvrvgm.js +0 -8
- package/dist/cli/chunk-7nhdvr5v.js +0 -4
- package/dist/cli/chunk-84aks78e.js +0 -3
- package/dist/cli/chunk-99devyxr.js +0 -2
- package/dist/cli/chunk-awsawfrm.js +0 -2
- package/dist/cli/chunk-bzz4ta7g.js +0 -17
- package/dist/cli/chunk-dk3pvrw6.js +0 -2
- package/dist/cli/chunk-fyjj9ast.js +0 -2
- package/dist/cli/chunk-gjf604bb.js +0 -3
- package/dist/cli/chunk-gm3vj0fv.js +0 -5
- package/dist/cli/chunk-h79zfebh.js +0 -7
- package/dist/cli/chunk-h9xpeqn6.js +0 -2
- package/dist/cli/chunk-hpj8xjxb.js +0 -2
- package/dist/cli/chunk-k5k0ecka.js +0 -4
- package/dist/cli/chunk-mfqjdpd8.js +0 -2
- package/dist/cli/chunk-ncsgawg7.js +0 -2
- package/dist/cli/chunk-qtke4x42.js +0 -3
- package/dist/cli/chunk-r26g5ree.js +0 -2
- package/dist/cli/chunk-vwjec3m6.js +0 -3
- package/dist/cli/chunk-vws0j65e.js +0 -4
- package/dist/cli/chunk-vzvy1s1d.js +0 -2
- package/dist/cli/chunk-w5xy83ze.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{API_VERBS,RETIRED_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb}from"./chunk-5mr9j201.js";import"./chunk-9nbg0nzh.js";import"./chunk-1rkb0j1j.js";import"./chunk-aq912vvw.js";import"./chunk-d393z1mj.js";import"./chunk-d89r6eqm.js";import"./chunk-qkehg2c1.js";import"./chunk-0vmrteyg.js";import"./chunk-gtkejmxx.js";import"./chunk-t05pnk6y.js";import"./chunk-y5hnrx8d.js";import"./chunk-xnr8dga2.js";import"./chunk-hape5vwj.js";import"./chunk-7zmrn4gn.js";import"./chunk-1kktfmtg.js";import"./chunk-e8493db0.js";import"./chunk-gzf4dfg6.js";import"./chunk-jvxh93nz.js";import"./chunk-7q67dz4c.js";import"./chunk-1cjd7h8p.js";import"./chunk-b99tf0jr.js";import"./chunk-s8xyh1bt.js";import"./chunk-zaxdx0wd.js";import"./chunk-sexavazm.js";import"./chunk-sdyzxayr.js";import"./chunk-0sm2k04y.js";import"./chunk-5bn91n19.js";import"./chunk-pdh5w4ht.js";import"./chunk-4wwx51m5.js";import"./chunk-79gqh5p2.js";import"./chunk-3ztek08w.js";import"./chunk-kwe61yx7.js";import"./chunk-x3gch5nw.js";import"./chunk-e7t4xpr9.js";import"./chunk-n4dmwkfa.js";import"./chunk-w7zv47mp.js";import"./chunk-gwcneg6c.js";import"./chunk-m370e00b.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-87y9qjcm.js";import"./chunk-m57cv76y.js";import"./chunk-dmdqnet6.js";import"./chunk-xy8be792.js";import"./chunk-a3a9gdc4.js";import"./chunk-2brn8e1y.js";import"./chunk-9c1e5z6a.js";import"./chunk-6dn6h640.js";import"./chunk-h82kzdsn.js";import"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-grh6dvfv.js";import"./chunk-pw6yfj10.js";import"./chunk-rxvbm4vt.js";import"./chunk-x760j10f.js";import"./chunk-3bfm4hrs.js";import"./chunk-wqfp8d9w.js";export{findVerb,VERB_GROUPS,VERB_ALIASES,VERBS,RETIRED_VERBS,API_VERBS};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{closeTab,engineTabArgv,initialTabs,terminalTabsKey}from"./chunk-fbg4fkmg.js";import{ComposerBusyError,awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,sessionHasEngine,writeHostedPromptIfClear}from"./chunk-1gpx52qj.js";import{engineLaunchArgv}from"./chunk-sm1vhrb6.js";import{engineEntry}from"./chunk-z3va3mt0.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-gjf604bb.js";import{existsSync}from"fs";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function hasLiveEngineTab(snapshot,taskId,sessions,engineAlive){let alive=aliveKeysOf(sessions),counts=(key)=>alive.has(key)&&engineAlive?.get(key)!==!1;if(counts(`${taskId}::tab-1`))return!0;return(snapshot?.tabs??[]).some((t)=>t.kind==="engine"&&counts(`${taskId}::${t.id}`))}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}class ApiError extends Error{code;data;constructor(message,code,data){super(message);this.code=code;this.data=data}}var DAEMON_CODE_PREFIX=/^([A-Z][A-Z0-9_]{2,}): /;function splitDaemonCode(message){let match=DAEMON_CODE_PREFIX.exec(message);if(!match?.[1])return null;return{code:match[1],rest:message.slice(match[0].length)}}function helpStep(verbName){return{hint:"run the verb's --help for its exact flag contract, then retry",nextCommandArgs:["api",verbName,"--help"]}}var VERB_GROUP_IDS=["discover","read","create","drive","edit","issues","workitems","routine","lifecycle","worktree","feedback"];var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,writePrompt=writeHostedPromptIfClear,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid;if(!await sessionHasEngine(pid,target.engineBin,opts?.snapshot))throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let deliveryOpts={screenManifest:resolveComposerManifest(opts?.vendor)},tabId=existingKey.split("::")[1]??"tab-1",outcome;try{outcome=await deliverToKey(rpc,existingKey,prompt,deliveryOpts)}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let tabId=launch.key.split("::")[1]??"tab-1",outcome;try{outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs,screenManifest:resolveComposerManifest(opts?.vendor)})}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let tabId=launch.key.split("::")[1]??"tab-1",outcome;try{outcome=await writePrompt(rpc,launch.key,prompt,{screenManifest:resolveComposerManifest(opts?.vendor)})}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!existsSync(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!existsSync(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!existsSync(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}function resolveComposerManifest(vendor){return vendor?engineEntry(vendor).screenManifest:void 0}async function deferOrThrow(error,sink,taskId,tabId,prompt){if(sink){let deferred;try{deferred=await sink.defer({taskId,tabId,prompt,layer:error.layer})}catch{throw composerBusyApiError(error,taskId,prompt)}if(deferred.kind==="occupied")throw new ApiError(`task ${taskId} tab ${tabId} already has a deferred prompt`,"DEFERRED_PROMPT_PENDING",{taskId,tabId,existingId:deferred.id,hint:"a prompt is already held for this tab \u2014 deliver it with `deferred-release --id`, or drop it with `deferred-dismiss --id`, then send yours again (`deferred-list` shows the text and its expiry)",nextCommandArgs:["api","deferred-release","--id",deferred.id]});return{session:`${taskId}::${tabId}`,pane:`${taskId}::${tabId}`,started:!1,engineReady:!1,delivered:!1,deferred:{id:deferred.id,layer:error.layer,...deferred.expiresAt!==void 0?{expiresAt:deferred.expiresAt}:{}}}}throw composerBusyApiError(error,taskId,prompt)}function composerBusyApiError(error,taskId,prompt){let layerText=error.layer==="recent-human-write"?"user was typing recently":"composer has text";return new ApiError(`task ${taskId}'s composer is busy (${layerText})`,"COMPOSER_BUSY",{layer:error.layer,hint:"wait a moment and retry, or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","send","--task-id",taskId,"--prompt",prompt]})}var killTaskSessions=killHostedSessions;
|
|
2
|
+
import{closeTab,engineTabArgv,initialTabs,terminalTabsKey}from"./chunk-y5hnrx8d.js";import{ComposerBusyError,awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,sessionHasEngine,writeHostedPromptIfClear}from"./chunk-xnr8dga2.js";import{engineLaunchArgv}from"./chunk-gzf4dfg6.js";import{engineEntry}from"./chunk-e7t4xpr9.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-m57cv76y.js";import{existsSync}from"fs";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function hasLiveEngineTab(snapshot,taskId,sessions,engineAlive){let alive=aliveKeysOf(sessions),counts=(key)=>alive.has(key)&&engineAlive?.get(key)!==!1;if(counts(`${taskId}::tab-1`))return!0;return(snapshot?.tabs??[]).some((t)=>t.kind==="engine"&&counts(`${taskId}::${t.id}`))}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}class ApiError extends Error{code;data;constructor(message,code,data){super(message);this.code=code;this.data=data}}var DAEMON_CODE_PREFIX=/^([A-Z][A-Z0-9_]{2,}): /;function splitDaemonCode(message){let match=DAEMON_CODE_PREFIX.exec(message);if(!match?.[1])return null;return{code:match[1],rest:message.slice(match[0].length)}}function helpStep(verbName){return{hint:"run the verb's --help for its exact flag contract, then retry",nextCommandArgs:["api",verbName,"--help"]}}var VERB_GROUP_IDS=["discover","read","create","drive","edit","issues","workitems","routine","lifecycle","worktree","feedback"];var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,writePrompt=writeHostedPromptIfClear,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid;if(!await sessionHasEngine(pid,target.engineBin,opts?.snapshot))throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let deliveryOpts={screenManifest:resolveComposerManifest(opts?.vendor)},tabId=existingKey.split("::")[1]??"tab-1",outcome;try{outcome=await deliverToKey(rpc,existingKey,prompt,deliveryOpts)}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let tabId=launch.key.split("::")[1]??"tab-1",outcome;try{outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs,screenManifest:resolveComposerManifest(opts?.vendor)})}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let tabId=launch.key.split("::")[1]??"tab-1",outcome;try{outcome=await writePrompt(rpc,launch.key,prompt,{screenManifest:resolveComposerManifest(opts?.vendor)})}catch(err){if(err instanceof ComposerBusyError)return deferOrThrow(err,opts?.defer,target.id,tabId,prompt);throw err}return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!existsSync(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!existsSync(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!existsSync(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}function resolveComposerManifest(vendor){return vendor?engineEntry(vendor).screenManifest:void 0}async function deferOrThrow(error,sink,taskId,tabId,prompt){if(sink){let deferred;try{deferred=await sink.defer({taskId,tabId,prompt,layer:error.layer})}catch{throw composerBusyApiError(error,taskId,prompt)}if(deferred.kind==="occupied")throw new ApiError(`task ${taskId} tab ${tabId} already has a deferred prompt`,"DEFERRED_PROMPT_PENDING",{taskId,tabId,existingId:deferred.id,hint:"a prompt is already held for this tab \u2014 deliver it with `deferred-release --id`, or drop it with `deferred-dismiss --id`, then send yours again (`deferred-list` shows the text and its expiry)",nextCommandArgs:["api","deferred-release","--id",deferred.id]});return{session:`${taskId}::${tabId}`,pane:`${taskId}::${tabId}`,started:!1,engineReady:!1,delivered:!1,deferred:{id:deferred.id,layer:error.layer,...deferred.expiresAt!==void 0?{expiresAt:deferred.expiresAt}:{}}}}throw composerBusyApiError(error,taskId,prompt)}function composerBusyApiError(error,taskId,prompt){let layerText=error.layer==="recent-human-write"?"user was typing recently":"composer has text";return new ApiError(`task ${taskId}'s composer is busy (${layerText})`,"COMPOSER_BUSY",{layer:error.layer,hint:"wait a moment and retry, or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","send","--task-id",taskId,"--prompt",prompt]})}var killTaskSessions=killHostedSessions;
|
|
3
3
|
export{ApiError,splitDaemonCode,helpStep,VERB_GROUP_IDS,taskEngineArgv,readTabsSnapshot,closeTabsSnapshot,unregisteredTabIds,joinTaskTabs,hasLiveEngineTab,publishCliTabSnapshot,markCliTabSession,mintCliTab,restoredTabLaunch,isTaskKey,findEngineKey,taskKeys,openPtyHost,ensurePtyHost,listSessions,listSessionsOrNull,deliverToKey,ENGINE_START_PROBE_MS,ENGINE_START_POLL_MS,ENGINE_NOT_OBSERVED_REASON,outcomeFields,deliverHostedPrompt,resolveComposerManifest,deferOrThrow,killTaskSessions};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{NPX_MISSING_EXIT,bundledSkillDir,kobeSkillPaths,kobeSkillState,npxSkillsCommand,runNpxSkillsInstall}from"./chunk-
|
|
2
|
+
import{NPX_MISSING_EXIT,bundledSkillDir,kobeSkillPaths,kobeSkillState,npxSkillsCommand,runNpxSkillsInstall}from"./chunk-579zz8df.js";import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import"./chunk-87y9qjcm.js";import"./chunk-m57cv76y.js";import"./chunk-a3a9gdc4.js";import"./chunk-9c1e5z6a.js";import"./chunk-6dn6h640.js";import{activeCliName}from"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-3bfm4hrs.js";import{__require}from"./chunk-wqfp8d9w.js";import{existsSync,readFileSync}from"fs";import{join}from"path";var CLI_NAME=activeCliName(),SKILL_VERBS=SUBCOMMAND_VERBS.skill;function skillUsage(){return[`usage: ${CLI_NAME} skill <verb>`,"","verbs:"," install [--global|-g | --project|-p] [--agent NAME]\u2026 Install the Rove agent skill (wraps `npx skills add`)"," status Show whether the skill is installed"," command [--global|-g | --project|-p] [--agent NAME]\u2026 Print the underlying npx command without running it",` print Print the bundled SKILL.md (also: \`${CLI_NAME} --skill\`)`,"",`The skill teaches a coding agent how to drive \`${CLI_NAME} api\`. Installs are`,"global (user-level) by default; --global/-g says so explicitly, --project/-p","installs into the current project instead. With no --agent, the agent-skills","CLI detects your installed agents and asks; repeat --agent to name them","(e.g. --agent claude-code --agent codex)."].join(`
|
|
3
3
|
`)}function parseInstallFlags(rest){let global=!0,agents=[];for(let i=0;i<rest.length;i++){let arg=rest[i];if(arg==="--project"||arg==="-p")global=!1;else if(arg==="--global"||arg==="-g")global=!0;else if(arg==="--agent"){let v=rest[i+1];if(!v||v.startsWith("--"))process.stderr.write(`${CLI_NAME} skill: --agent requires a value
|
|
4
4
|
`),process.exit(2);agents.push(v),i++}else if(arg.startsWith("--agent="))agents.push(arg.slice(8));else process.stderr.write(`${CLI_NAME} skill: unknown flag "${arg}"
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ ${skillUsage()}
|
|
|
11
11
|
|
|
12
12
|
${skillUsage()}
|
|
13
13
|
`),process.exit(2);if(verb==="print"){let bundled2=bundledSkillDir(),path=bundled2?join(bundled2,"SKILL.md"):kobeSkillPaths().find((p)=>existsSync(p));if(!path)process.stderr.write(`${CLI_NAME} skill: no SKILL.md found (not bundled, not installed) \u2014 run \`${CLI_NAME} skill install\`
|
|
14
|
-
`),process.exit(1);process.stdout.write(readFileSync(path,"utf8"));return}if(verb==="status"){let{isRovePluginEnabled}=await import("./chunk-
|
|
14
|
+
`),process.exit(1);process.stdout.write(readFileSync(path,"utf8"));return}if(verb==="status"){let{isRovePluginEnabled}=await import("./chunk-ktmvmskn.js"),state=kobeSkillState(),paths=kobeSkillPaths(),pluginNote=isRovePluginEnabled()?` note: the Rove Claude Code plugin is enabled \u2014 for Claude Code the skill ships
|
|
15
15
|
inside the plugin and versions with it (staleness prompts are suppressed).
|
|
16
16
|
`:"",head=!state.installed?"\u2717 not installed":state.stale?`\u26A0 out of date (installed ${state.installedVersion===null?"unstamped":`v${state.installedVersion}`}, this Rove wants v${state.currentVersion})`:`\u2713 installed (v${state.installedVersion})`;process.stdout.write([`${CLI_NAME} skill: ${head}`,...state.legacyCopies.map((copy)=>` \u26A0 stale duplicate: ${copy.path}${copy.version===null?"":` (v${copy.version})`} \u2014 remove it; agents load both`),` looked in: ${paths.join(`
|
|
17
17
|
`)}`,state.installed&&!state.stale?"":` \u2192 run \`${CLI_NAME} skill install\` to install / refresh`,""].join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{ulid}from"./chunk-qkehg2c1.js";import{acquireWithRetry,mergeTasksWithDisk,readDiskIndex,recoverIndexFromDisk
|
|
2
|
+
import{ulid}from"./chunk-qkehg2c1.js";import{acquireWithRetry,mergeTasksWithDisk,readDiskIndex,recoverIndexFromDisk}from"./chunk-dmdqnet6.js";import{DEFAULT_TASK_VENDOR,toTaskId}from"./chunk-xy8be792.js";import{release}from"./chunk-a3a9gdc4.js";import{LEGACY_KOBE_STATE_DIR_BASENAME,ROVE_STATE_DIR_BASENAME}from"./chunk-cb2fpajx.js";import{readRoveHomeDirEnv}from"./chunk-3bfm4hrs.js";import{mkdir,open,rename,unlink}from"fs/promises";import{homedir}from"os";import{dirname,join}from"path";var CURRENT_VERSION=3;class TaskIndexStore{homeDir;roveDir;path;legacyPath;lockPath;cache={version:CURRENT_VERSION,tasks:[]};loaded=!1;listeners=new Set;saveChain=Promise.resolve();dirtyIds=new Set;removedIds=new Map;constructor(options={}){this.homeDir=options.homeDir??readRoveHomeDirEnv()??homedir(),this.roveDir=join(this.homeDir,ROVE_STATE_DIR_BASENAME),this.path=join(this.roveDir,"tasks.json"),this.legacyPath=join(this.homeDir,LEGACY_KOBE_STATE_DIR_BASENAME,"tasks.json"),this.lockPath=`${this.path}.lock`}subscribe(listener){if(this.listeners.add(listener),this.loaded)try{listener(this.cache.tasks.slice())}catch(err){console.error("[rove TaskIndexStore] listener threw on subscribe:",err)}return()=>{this.listeners.delete(listener)}}get filePath(){return this.path}get stateDir(){return this.roveDir}async load(){return this.dirtyIds.clear(),this.removedIds.clear(),this.cache=await recoverIndexFromDisk(this.path,this.legacyPath),this.loaded=!0,this.notifyListeners(),this.snapshot()}async save(){this.assertLoaded();let next=this.saveChain.then(()=>this.doSave());return this.saveChain=next.catch(()=>{}),next}async saveOrRollback(id,undo){try{await this.save()}catch(err){if(undo())this.dirtyIds.delete(id),this.notifyListeners();throw err}}async doSave(){await mkdir(dirname(this.path),{recursive:!0});let dirty=new Set(this.dirtyIds),removed=new Map(this.removedIds),lockToken=await acquireWithRetry(this.lockPath),cacheChanged=!1;try{let disk=await readDiskIndex(this.path,this.legacyPath),merged=mergeTasksWithDisk(this.cache.tasks,disk.tasks,dirty,removed,disk.removed),payload={version:CURRENT_VERSION,tasks:merged.tasks,...merged.removed.length>0?{removed:merged.removed}:{}},json=`${JSON.stringify(payload)}
|
|
3
3
|
`,tmpPath=`${this.path}.${process.pid}.${ulid()}.tmp`;try{let handle=await open(tmpPath,"w",384);try{await handle.writeFile(json,"utf8"),await handle.sync()}finally{await handle.close()}await rename(tmpPath,this.path)}catch(err){throw await unlink(tmpPath).catch(()=>{}),err}for(let id of dirty)this.dirtyIds.delete(id);for(let id of removed.keys())this.removedIds.delete(id);let present=new Set(this.cache.tasks.map((t)=>t.id));for(let task of merged.tasks){if(present.has(task.id))continue;this.cache.tasks.push(task),cacheChanged=!0}let tombstoned=new Set(merged.removed.map((t)=>t.id));if(tombstoned.size>0)for(let i=this.cache.tasks.length-1;i>=0;i--){let entry=this.cache.tasks[i];if(!entry||!tombstoned.has(entry.id))continue;this.cache.tasks.splice(i,1),cacheChanged=!0}}finally{await release(this.lockPath,lockToken).catch((err)=>{console.error("[rove TaskIndexStore] index lock release failed:",err)})}if(cacheChanged)this.notifyListeners()}get(id){return this.assertLoaded(),this.cache.tasks.find((t)=>t.id===id)}list(){return this.assertLoaded(),this.cache.tasks.slice()}async create(partial){this.assertLoaded();let now=new Date().toISOString(),task={vendor:partial.vendor??DEFAULT_TASK_VENDOR,...partial,id:toTaskId(ulid()),createdAt:now,updatedAt:now};return this.cache.tasks.push(task),this.dirtyIds.add(task.id),await this.saveOrRollback(task.id,()=>{let at=this.cache.tasks.indexOf(task);if(at<0)return!1;return this.cache.tasks.splice(at,1),!0}),this.notifyListeners(),task}async update(id,patch){this.assertLoaded();let idx=this.cache.tasks.findIndex((t)=>t.id===id);if(idx<0)throw Error(`task not found: ${id}`);let existing=this.cache.tasks[idx];if(!existing)throw Error(`task not found: ${id}`);let{id:_id,createdAt:_createdAt,...mutable}=patch,next={...existing,...mutable,id:existing.id,createdAt:existing.createdAt,updatedAt:new Date().toISOString()};return this.cache.tasks[idx]=next,this.dirtyIds.add(String(id)),await this.saveOrRollback(String(id),()=>{let at=this.cache.tasks.indexOf(next);if(at<0)return!1;return this.cache.tasks[at]=existing,!0}),this.notifyListeners(),next}touchRecency(id){this.assertLoaded();let idx=this.cache.tasks.findIndex((t)=>t.id===id);if(idx<0)return;let existing=this.cache.tasks[idx];if(!existing)return;this.cache.tasks[idx]={...existing,updatedAt:new Date().toISOString()},this.dirtyIds.add(String(id)),this.notifyListeners()}async move(id,delta,withinIds){this.assertLoaded();let task=this.cache.tasks.find((t)=>t.id===id);if(!task)throw Error(`task not found: ${id}`);let ids=withinIds?.length?withinIds:this.cache.tasks.map((t)=>t.id),pos=ids.indexOf(String(id));if(pos<0)throw Error(`task not movable in current group: ${id}`);let targetId=ids[pos+delta];if(!targetId)return task;let fromIdx=this.cache.tasks.findIndex((t)=>t.id===id),toIdx=this.cache.tasks.findIndex((t)=>t.id===targetId);if(fromIdx<0||toIdx<0||fromIdx===toIdx)return task;let[moved]=this.cache.tasks.splice(fromIdx,1);if(!moved)return task;let adjustedToIdx=fromIdx<toIdx?toIdx-1:toIdx,insertAt=delta>0?adjustedToIdx+1:adjustedToIdx,next={...moved,updatedAt:new Date().toISOString()};return this.cache.tasks.splice(insertAt,0,next),this.dirtyIds.add(String(id)),await this.saveOrRollback(String(id),()=>{let at=this.cache.tasks.indexOf(next);if(at<0)return!1;return this.cache.tasks.splice(at,1),this.cache.tasks.splice(Math.min(fromIdx,this.cache.tasks.length),0,moved),!0}),this.notifyListeners(),next}async remove(id){this.assertLoaded();let idx=this.cache.tasks.findIndex((t)=>t.id===id);if(idx<0)return!1;return this.cache.tasks.splice(idx,1),this.dirtyIds.delete(String(id)),this.removedIds.set(String(id),new Date().toISOString()),await this.save(),this.notifyListeners(),!0}async _unlinkForTests(){try{await unlink(this.path)}catch(err){if(err.code!=="ENOENT")throw err}this.cache={version:CURRENT_VERSION,tasks:[]},this.loaded=!1,this.dirtyIds.clear(),this.removedIds.clear()}assertLoaded(){if(!this.loaded)throw Error("TaskIndexStore: call load() before any other method")}snapshot(){return{version:CURRENT_VERSION,tasks:this.cache.tasks.slice()}}notifyListeners(){if(this.listeners.size===0)return;let snapshot=this.cache.tasks.slice();for(let listener of this.listeners)try{listener(snapshot)}catch(err){console.error("[rove TaskIndexStore] listener threw on notify:",err)}}}
|
|
4
4
|
export{TaskIndexStore};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{releaseBodyLines,runShellUpdater}from"./chunk-jq5vp0f7.js";import{$jsx,$jsxs,bootPaneHost,pageCloseBindings,require_react_production,useBindings,useRenderer,useT,useTheme}from"./chunk-rz8247zr.js";import"./chunk-764bsyb0.js";import"./chunk-mjvq39gf.js";import"./chunk-6xppe9bj.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-gtkejmxx.js";import"./chunk-s8xyh1bt.js";import"./chunk-zaxdx0wd.js";import"./chunk-sexavazm.js";import"./chunk-sdyzxayr.js";import"./chunk-0sm2k04y.js";import"./chunk-5bn91n19.js";import"./chunk-pdh5w4ht.js";import"./chunk-4wwx51m5.js";import"./chunk-79gqh5p2.js";import"./chunk-3ztek08w.js";import"./chunk-kwe61yx7.js";import"./chunk-m57cv76y.js";import"./chunk-xy8be792.js";import"./chunk-a3a9gdc4.js";import"./chunk-2brn8e1y.js";import"./chunk-6dn6h640.js";import"./chunk-cb2fpajx.js";import"./chunk-grh6dvfv.js";import"./chunk-pw6yfj10.js";import"./chunk-x760j10f.js";import"./chunk-3bfm4hrs.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:"q / esc"})]}),$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:{backgroundColor:theme.background,foregroundColor:theme.borderActive}},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,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
2
|
+
/*!
|
|
3
3
|
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
4
4
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
5
|
*
|
|
@@ -253,6 +253,5 @@ ${codeblock}`,options);this.line=line,this.column=column,this.codeblock=codebloc
|
|
|
253
253
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
254
254
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
255
255
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
256
|
-
*/var PLUGIN_PLATFORMS=["macos","linux","windows"];class ManifestError extends Error{}function fail(message){throw new ManifestError(`rove-plugin.toml: ${message}`)}function asString(value,field){if(typeof value!=="string"||value.length===0)fail(`\`${field}\` must be a non-empty string`);return value}function asSettingDefault(value,field){if(value===void 0||value===!1)return;if(value===!0)return"1";if(typeof value==="number"&&Number.isFinite(value))return String(value);return asString(value,field)}var TIMEOUT_MIN_MS=100,TIMEOUT_MAX_MS=600000;function asTimeoutMs(value,field){if(value===void 0)return;if(typeof value!=="number"||!Number.isInteger(value)||value<TIMEOUT_MIN_MS||value>TIMEOUT_MAX_MS)fail(`\`${field}\` must be a whole number of milliseconds between ${TIMEOUT_MIN_MS} and ${TIMEOUT_MAX_MS}`);return value}function asCommand(value,field){if(!Array.isArray(value)||value.length===0||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings (argv form)`);return value}function asPlatforms(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>PLUGIN_PLATFORMS.includes(v)))fail(`\`${field}\` must be an array drawn from ${PLUGIN_PLATFORMS.join(", ")}`);return value}function asTableArray(value,field){if(value===void 0)return[];if(!Array.isArray(value)||!value.every((v)=>typeof v==="object"&&v!==null&&!Array.isArray(v)))fail(`\`[[${field}]]\` must be an array of tables`);return value}function asStringArray(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings`);return value}var SETTING_KEY_RE=/^[A-Za-z_][A-Za-z0-9_]*$/,RESERVED_SETTING_KEYS=["PATH","HOME","SHELL","IFS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","NODE_OPTIONS","BUN_INSPECT","PYTHONPATH","PYTHONSTARTUP","PERL5OPT","PERL5LIB","RUBYOPT","BASH_ENV","ENV","GIT_SSH_COMMAND","GIT_SSH","GIT_EXTERNAL_DIFF","GIT_PAGER","PAGER","EDITOR","VISUAL"];function settingKeyRejection(key){if(!SETTING_KEY_RE.test(key))return`\`${key}\` is not a valid env var name (${SETTING_KEY_RE.source})`;if(RESERVED_SETTING_KEYS.includes(key))return`\`${key}\` is reserved; it steers how the plugin's own process runs`;return null}var PLUGIN_MANIFEST_FILENAME="rove-plugin.toml",LEGACY_PLUGIN_MANIFEST_FILENAME="kobe-plugin.toml",PLUGIN_MANIFEST_FILENAMES=[PLUGIN_MANIFEST_FILENAME,LEGACY_PLUGIN_MANIFEST_FILENAME],RESERVED_ENGINE_IDS=["claude","codex","copilot","kimi","gemini","opencode","cursor","grok","droid","amp"];function pluginManifestPath(root){for(let filename of PLUGIN_MANIFEST_FILENAMES){let path=join(root,filename);if(existsSync(path))return path}return null}function readPluginManifest(root){let path=pluginManifestPath(root);if(!path)throw new ManifestError(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);return parsePluginManifest(readFileSync(path,"utf8"),basename(path))}var PLUGIN_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._:-]*$/,LOCAL_ID_RE=/^[A-Za-z0-9][A-Za-z0-9_:-]*$/;function qualifiedActionId(pluginId,actionId){return`${pluginId}.${actionId}`}function currentPluginPlatform(platform=process.platform){if(platform==="darwin")return"macos";if(platform==="linux")return"linux";if(platform==="win32")return"windows";return}function supportsPlatform(item,manifest,platform){let declared=item.platforms??manifest.platforms;if(!declared)return!0;return platform!==void 0&&declared.includes(platform)}function parsePluginManifest(text,filename=PLUGIN_MANIFEST_FILENAME){try{return parseCanonicalPluginManifest(text)}catch(err){if(filename!==PLUGIN_MANIFEST_FILENAME&&err instanceof ManifestError)throw new ManifestError(err.message.replace(/^rove-plugin\.toml:/,`${filename}:`));throw err}}function parseCanonicalPluginManifest(text){let raw;try{raw=parse(text)}catch(err){fail(`invalid TOML \u2014 ${err instanceof Error?err.message:String(err)}`)}let warnings=[],id=asString(raw.id,"id");if(!PLUGIN_ID_RE.test(id))fail(`plugin id \`${id}\` may use ASCII letters, digits, dot, colon, underscore, hyphen`);let name=asString(raw.name,"name"),version=asString(raw.version,"version"),rawMinVersion=raw.min_rove_version??raw.min_kobe_version,minKobeVersion=asString(rawMinVersion,"min_rove_version"),description=raw.description===void 0?void 0:asString(raw.description,"description"),platforms=asPlatforms(raw.platforms,"platforms");if(!platforms)warnings.push("no top-level `platforms` declared; assuming the plugin runs everywhere");if(raw.min_rove_version!==void 0&&raw.min_kobe_version!==void 0&&raw.min_rove_version!==raw.min_kobe_version)warnings.push("both `min_rove_version` and legacy `min_kobe_version` are set; using `min_rove_version`");let build=asTableArray(raw.build,"build").map((t,i)=>({command:asCommand(t.command,`build[${i}].command`),platforms:asPlatforms(t.platforms,`build[${i}].platforms`)})),startup=asTableArray(raw.startup,"startup").map((t,i)=>({command:asCommand(t.command,`startup[${i}].command`),platforms:asPlatforms(t.platforms,`startup[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`startup[${i}].timeout_ms`)})),shutdown=asTableArray(raw.shutdown,"shutdown").map((t,i)=>({command:asCommand(t.command,`shutdown[${i}].command`),platforms:asPlatforms(t.platforms,`shutdown[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`shutdown[${i}].timeout_ms`)})),actions=asTableArray(raw.actions,"actions").map((t,i)=>{let actionId=asString(t.id,`actions[${i}].id`);if(t.timeout_ms!==void 0)warnings.push(`actions[${i}] declares \`timeout_ms\`; actions are user-invoked and are never killed on a deadline`);if(!LOCAL_ID_RE.test(actionId))fail(`action id \`${actionId}\` may not contain dots`);return{id:actionId,title:asString(t.title,`actions[${i}].title`),command:asCommand(t.command,`actions[${i}].command`),platforms:asPlatforms(t.platforms,`actions[${i}].platforms`)}}),seen=new Set;for(let a of actions){if(seen.has(a.id))fail(`duplicate action id \`${a.id}\``);seen.add(a.id)}let panes=asTableArray(raw.panes,"panes").map((t,i)=>{let paneId=asString(t.id,`panes[${i}].id`);if(!LOCAL_ID_RE.test(paneId))fail(`pane id \`${paneId}\` may not contain dots`);if(t.timeout_ms!==void 0)warnings.push(`panes[${i}] declares \`timeout_ms\`; a pane is a terminal the user closes, not a bounded hook`);if(t.placement!==void 0&&t.placement!=="tab"&&t.placement!=="split")warnings.push(`pane \`${paneId}\` placement \`${String(t.placement)}\` is not supported yet; opening as a split`);return{id:paneId,title:asString(t.title,`panes[${i}].title`),placement:t.placement==="tab"?"tab":"split",command:asCommand(t.command,`panes[${i}].command`),platforms:asPlatforms(t.platforms,`panes[${i}].platforms`)}}),paneSeen=new Set;for(let p of panes){if(paneSeen.has(p.id))fail(`duplicate pane id \`${p.id}\``);paneSeen.add(p.id)}let events=asTableArray(raw.events,"events").flatMap((t,i)=>{let on=asString(t.on,`events[${i}].on`),hook={on,command:asCommand(t.command,`events[${i}].command`),platforms:asPlatforms(t.platforms,`events[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`events[${i}].timeout_ms`)};if(!PLUGIN_EVENT_NAMES.includes(on))warnings.push(`unknown event \`${on}\`; this hook will never fire on this Rove version`);return[hook]}),settings=asTableArray(raw.settings,"settings").map((t,i)=>{let type=asString(t.type,`settings[${i}].type`);if(type!=="string"&&type!=="number"&&type!=="boolean"&&type!=="enum"&&type!=="secret")fail(`settings[${i}].type must be string | number | boolean | enum | secret`);let options=t.options===void 0?void 0:Array.isArray(t.options)&&t.options.every((o)=>typeof o==="string"&&o.length>0)?t.options:fail(`settings[${i}].options must be an array of strings`);if(type==="enum"&&(!options||options.length===0))fail(`settings[${i}] enum needs \`options\``);let settingDefault=asSettingDefault(t.default,`settings[${i}].default`),key=asString(t.key,`settings[${i}].key`),rejection=settingKeyRejection(key);if(rejection)fail(`settings[${i}].key ${rejection}`);return{key,label:asString(t.label,`settings[${i}].label`),type,...options?{options}:{},...settingDefault===void 0?{}:{default:settingDefault}}}),fileHandlers=asTableArray(raw.file_handlers,"file_handlers").map((t,i)=>{let pattern=asString(t.pattern,`file_handlers[${i}].pattern`);try{new RegExp(pattern)}catch{fail(`file_handlers[${i}].pattern is not a valid regex`)}let action=asString(t.action,`file_handlers[${i}].action`);if(!actions.some((a)=>a.id===action))fail(`file_handlers[${i}] names unknown action \`${action}\``);return{pattern,action}}),engines=asTableArray(raw.engines,"engines").map((t,i)=>{let engineId=asString(t.id,`engines[${i}].id`);if(!LOCAL_ID_RE.test(engineId))fail(`engine id \`${engineId}\` may not contain dots`);if(RESERVED_ENGINE_IDS.includes(engineId))fail(`engine id \`${engineId}\` shadows a built-in or shipped engine`);let rules=asTableArray(t.rules,`engines[${i}].rules`).map((r,j)=>{let state=asString(r.state,`engines[${i}].rules[${j}].state`);if(state!=="working"&&state!=="blocked"&&state!=="idle")fail(`engines[${i}].rules[${j}].state must be working | blocked | idle`);let lineRegex=asStringArray(r.line_regex,`engines[${i}].rules[${j}].line_regex`);for(let re of lineRegex??[])try{new RegExp(re)}catch{fail(`engines[${i}].rules[${j}].line_regex \`${re}\` is not a valid regex`)}let all=asStringArray(r.all,`engines[${i}].rules[${j}].all`),any=asStringArray(r.any,`engines[${i}].rules[${j}].any`);if(!all&&!any&&!lineRegex)fail(`engines[${i}].rules[${j}] needs at least one of all/any/line_regex`);return{state,...typeof r.bottom_lines==="number"?{bottomLines:r.bottom_lines}:{},...all?{all}:{},...any?{any}:{},...lineRegex?{lineRegex}:{}}}),identityRaw=t.identity,identity;if(identityRaw!==void 0){if(typeof identityRaw!=="object"||identityRaw===null||Array.isArray(identityRaw))fail(`engines[${i}].identity must be a table`);let idt=identityRaw,shortName=((key)=>idt[key]===void 0?void 0:asString(idt[key],`engines[${i}].identity.${key}`))("short_name");identity={...shortName!==void 0?{shortName}:{}}}let firstMessageDelivery;if(t.first_message_delivery!==void 0){let raw2=asString(t.first_message_delivery,`engines[${i}].first_message_delivery`);if(raw2!=="argv"&&raw2!=="paste")fail(`engines[${i}].first_message_delivery must be argv | paste`);firstMessageDelivery=raw2}return{id:engineId,name:asString(t.name,`engines[${i}].name`),command:asCommand(t.command,`engines[${i}].command`),...t.process_names===void 0?{}:{processNames:asCommand(t.process_names,`engines[${i}].process_names`)},rules,...identity?{identity}:{},...firstMessageDelivery?{firstMessageDelivery}:{}}}),engineSeen=new Set;for(let e of engines){if(engineSeen.has(e.id))fail(`duplicate engine id \`${e.id}\``);engineSeen.add(e.id)}return{manifest:{id,name,version,minKobeVersion,description,platforms,build,startup,shutdown,actions,events,panes,settings,fileHandlers,engines},warnings}}import{existsSync as existsSync2}from"fs";import{homedir}from"os";import{join as join2}from"path";function stateRoot(homeDir){let home=homeDir??readRoveHomeDirEnv()??homedir(),canonical=join2(home,ROVE_STATE_DIR_BASENAME);if(existsSync2(join2(canonical,"plugins.json")))return canonical;let legacy=join2(home,COMPAT_STATE_DIR_BASENAME);return existsSync2(join2(legacy,"plugins.json"))?legacy:canonical}function pluginRegistryPath(homeDir){return join2(stateRoot(homeDir),"plugins.json")}function pluginsRootDir(homeDir){return join2(stateRoot(homeDir),"plugins")}function legacyPluginsRootDir(homeDir){let home=homeDir??readRoveHomeDirEnv()??homedir();return join2(home,COMPAT_STATE_DIR_BASENAME,"plugins")}function pluginDataDir(id,homeDir){return join2(pluginsRootDir(homeDir),id)}function pluginCheckoutDir(id,homeDir){return join2(pluginDataDir(id,homeDir),"checkout")}function pluginConfigDir(id,homeDir){return join2(pluginDataDir(id,homeDir),"config")}function pluginStateDir(id,homeDir){return join2(pluginDataDir(id,homeDir),"state")}function pluginLogPath(id,homeDir){return join2(pluginDataDir(id,homeDir),"log.jsonl")}function pluginsOutdatedCachePath(homeDir){return join2(stateRoot(homeDir),"plugins-outdated.json")}import{mkdirSync,readFileSync as readFileSync2,writeFileSync}from"fs";import{dirname,join as join3,relative}from"path";var EMPTY={plugins:[]};function loadPluginRegistry(homeDir){let text;try{text=readFileSync2(pluginRegistryPath(homeDir),"utf8")}catch{return EMPTY}try{let raw=JSON.parse(text);if(!Array.isArray(raw.plugins))return EMPTY;return{plugins:raw.plugins.filter(isEntry).map((entry)=>withCanonicalRoot(entry,homeDir))}}catch{return EMPTY}}function withCanonicalRoot(entry,homeDir){if(entry.source.kind!=="github")return entry;let legacy=legacyPluginsRootDir(homeDir),canonical=pluginsRootDir(homeDir);if(legacy===canonical)return entry;let inside=relative(legacy,entry.root);if(inside===""||inside.startsWith("..")||inside.startsWith("/"))return entry;return{...entry,root:join3(canonical,inside)}}function isEntry(v){if(typeof v!=="object"||v===null)return!1;let e=v,source=e.source;return typeof e.id==="string"&&typeof e.root==="string"&&typeof e.enabled==="boolean"&&typeof e.version==="string"&&typeof e.installedAt==="number"&&typeof source==="object"&&source!==null&&(source.kind==="link"||source.kind==="github"&&typeof source.spec==="string")}function savePluginRegistry(registry,homeDir){let path=pluginRegistryPath(homeDir);mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(registry,null,2)}
|
|
257
|
-
|
|
258
|
-
export{PLUGIN_MANIFEST_FILENAMES,pluginManifestPath,readPluginManifest,qualifiedActionId,currentPluginPlatform,supportsPlatform,parsePluginManifest,pluginRegistryPath,pluginsRootDir,pluginDataDir,pluginCheckoutDir,pluginConfigDir,pluginStateDir,pluginLogPath,pluginsOutdatedCachePath,loadPluginRegistry,savePluginRegistry,upsertPluginEntry,removePluginEntry};
|
|
256
|
+
*/
|
|
257
|
+
export{TomlError,parse};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{SUBCOMMAND_VERBS,TOP_LEVEL_SUBCOMMANDS}from"./chunk-s76r56rj.js";import{activeCliName}from"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-3bfm4hrs.js";import{__require}from"./chunk-wqfp8d9w.js";async function collectSubVerbs(){let{API_VERBS}=await import("./chunk-
|
|
2
|
+
import{SUBCOMMAND_VERBS,TOP_LEVEL_SUBCOMMANDS}from"./chunk-s76r56rj.js";import{activeCliName}from"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-3bfm4hrs.js";import{__require}from"./chunk-wqfp8d9w.js";async function collectSubVerbs(){let{API_VERBS}=await import("./chunk-ssepbf68.js"),merged={...SUBCOMMAND_VERBS,api:API_VERBS};return Object.keys(merged).sort().map((command)=>[command,merged[command]??[]])}function completionUsage(cliName){return[`Usage: ${cliName} completions <bash|zsh|fish>`,"",`Generate a shell completion script for ${cliName} and print it to stdout.`,"","Install:",` zsh source <(${cliName} completions zsh) # one-off, or in ~/.zshrc after compinit`," # or the fpath way:",` # ${cliName} completions zsh > ~/.zsh/completions/_${cliName}`," # fpath=(~/.zsh/completions $fpath) # in ~/.zshrc, BEFORE compinit"," # rm -f ~/.zcompdump && exec zsh # rebuild the completion cache",` bash ${cliName} completions bash > ~/.bash_completion.d/${cliName} # source it from ~/.bashrc`,` fish ${cliName} completions fish > ~/.config/fish/completions/${cliName}.fish`,""].join(`
|
|
3
3
|
`)}function generateBashCompletions(cliName,subVerbs){let subcommands=TOP_LEVEL_SUBCOMMANDS.join(" "),fn=`_${cliName}`;return[`# ${cliName} bash completions`,`# Source: ${cliName} completions bash`,"",`${fn}() {`," local cur prev"," COMPREPLY=()",' cur="${COMP_WORDS[COMP_CWORD]}"',' prev="${COMP_WORDS[COMP_CWORD-1]}"'," if [[ ${COMP_CWORD} -eq 1 ]]; then",` COMPREPLY=( $(compgen -W "${subcommands}" -- "\${cur}") )`," return"," fi"," if [[ ${COMP_CWORD} -eq 2 ]]; then",' case "${prev}" in',...subVerbs.map(([command,verbs])=>` ${command}) COMPREPLY=( $(compgen -W "${verbs.join(" ")}" -- "\${cur}") ) ;;`)," esac"," fi","}",`complete -F ${fn} ${cliName}`,""].join(`
|
|
4
4
|
`)}function generateZshCompletions(cliName,subVerbs){let subcommandsList=TOP_LEVEL_SUBCOMMANDS.map((s)=>`"${s}"`).join(" "),fn=`_${cliName}`;return[`#compdef ${cliName}`,`# ${cliName} zsh completions`,`# Source: ${cliName} completions zsh`,"",`${fn}() {`," local -a subcommands verbs",` subcommands=(${subcommandsList})`,""," if (( CURRENT == 2 )); then"," _describe -t commands 'subcommand' subcommands"," return"," fi",""," verbs=()",' case "${words[2]}" in',...subVerbs.map(([command,verbs])=>` ${command}) verbs=(${verbs.map((v)=>`"${v}"`).join(" ")}) ;;`)," esac"," if (( CURRENT == 3 && ${#verbs} > 0 )); then"," _describe -t verbs 'verb' verbs"," fi","}","","# Autoloaded from $fpath -> run as the completion function;","# sourced directly -> register with compdef instead.",`if [ "\${funcstack[1]}" = "${fn}" ]; then`,` ${fn} "$@"`,"elif (( $+functions[compdef] )); then",` compdef ${fn} ${cliName}`,"fi",""].join(`
|
|
5
5
|
`)}function generateFishCompletions(cliName,subVerbs){let lines=[...TOP_LEVEL_SUBCOMMANDS.map((s)=>`complete -c ${cliName} -f -n __fish_use_subcommand -a ${s}`),...subVerbs.map(([command,verbs])=>`complete -c ${cliName} -f -n "__fish_seen_subcommand_from ${command}" -a "${verbs.join(" ")}"`)];return`# ${cliName} fish completions
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{API_SCHEMA_VERSION,API_VERBS,RETIRED_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-
|
|
2
|
+
import{API_SCHEMA_VERSION,API_VERBS,RETIRED_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-5mr9j201.js";import{ensurePluginEnginesLoaded}from"./chunk-9nbg0nzh.js";import{openDaemonSession}from"./chunk-1rkb0j1j.js";import"./chunk-aq912vvw.js";import"./chunk-d393z1mj.js";import"./chunk-d89r6eqm.js";import"./chunk-qkehg2c1.js";import"./chunk-0vmrteyg.js";import"./chunk-gtkejmxx.js";import{ApiError,splitDaemonCode}from"./chunk-t05pnk6y.js";import"./chunk-y5hnrx8d.js";import"./chunk-xnr8dga2.js";import"./chunk-hape5vwj.js";import"./chunk-7zmrn4gn.js";import"./chunk-1kktfmtg.js";import"./chunk-e8493db0.js";import"./chunk-gzf4dfg6.js";import"./chunk-jvxh93nz.js";import"./chunk-7q67dz4c.js";import"./chunk-1cjd7h8p.js";import"./chunk-b99tf0jr.js";import"./chunk-s8xyh1bt.js";import"./chunk-zaxdx0wd.js";import"./chunk-sexavazm.js";import"./chunk-sdyzxayr.js";import"./chunk-0sm2k04y.js";import"./chunk-5bn91n19.js";import"./chunk-pdh5w4ht.js";import"./chunk-4wwx51m5.js";import"./chunk-79gqh5p2.js";import"./chunk-3ztek08w.js";import"./chunk-kwe61yx7.js";import"./chunk-x3gch5nw.js";import"./chunk-e7t4xpr9.js";import"./chunk-n4dmwkfa.js";import"./chunk-w7zv47mp.js";import"./chunk-gwcneg6c.js";import"./chunk-m370e00b.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-87y9qjcm.js";import"./chunk-m57cv76y.js";import"./chunk-dmdqnet6.js";import"./chunk-xy8be792.js";import"./chunk-a3a9gdc4.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-9c1e5z6a.js";import"./chunk-6dn6h640.js";import"./chunk-h82kzdsn.js";import"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-grh6dvfv.js";import"./chunk-pw6yfj10.js";import"./chunk-rxvbm4vt.js";import"./chunk-x760j10f.js";import"./chunk-3bfm4hrs.js";import"./chunk-wqfp8d9w.js";function emit(value,pretty){let warning=takeIdentityWarning(),payload=warning&&value&&typeof value==="object"&&!Array.isArray(value)?{...value,identityWarning:warning}:value,text=pretty?JSON.stringify(payload,null,2):JSON.stringify(payload);process.stdout.write(`${text}
|
|
3
3
|
`)}function fail(message,code,exitCode=1,data){process.stderr.write(`${JSON.stringify({error:{message,code,...data}})}
|
|
4
4
|
`),process.exit(exitCode)}function makeContext(verb,flags,client,runtime){return{args:new VerbArgs(verb,flags),client,runtime}}var SCHEMA_STEP={hint:"list every valid verb + flag as JSON, then retry with a real verb",nextCommandArgs:["api","schema"]};function unknownVerbError(verbName){let retired=RETIRED_VERBS[verbName];if(retired)return new ApiError(`unknown verb: ${verbName} (removed)`,"UNKNOWN_VERB",{hint:retired.hint,nextCommandArgs:[...retired.nextCommandArgs]});return new ApiError(`unknown verb: ${verbName}`,"BAD_VERB",SCHEMA_STEP)}function toApiError(err){if(err instanceof ApiError)return err;let message=errorMessage(err);if(/task not found/i.test(message))return new ApiError(message,"TASK_NOT_FOUND",{hint:"that task id does not exist (deleted or mistyped) \u2014 list live tasks and retry with a real id",nextCommandArgs:["api","list"]});if(/unknown daemon request:/i.test(message))return versionSkewError(message);let coded=splitDaemonCode(message);if(coded)return new ApiError(coded.rest,coded.code);return new ApiError(message,"RPC_ERROR")}function versionSkewError(message){return new ApiError(message,"DAEMON_VERSION_SKEW",{hint:"the running daemon is a different build than this CLI, so it does not serve this verb \u2014 restart the daemon to pick up this build, then retry (if the verb is gone for good, `rove api schema` lists what this daemon actually serves)",nextCommandArgs:["daemon","restart"]})}async function invokeVerb(verbName,argv,deps){let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);let booleanFlags=new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name)),parsed=parseFlags(argv,booleanFlags);validateAgainstSpec(verb,parsed.flags);try{return await verb.handler(makeContext(verb,parsed.flags,deps.client,deps.runtime??defaultApiRuntime))}catch(err){throw toApiError(err)}}async function runApiSubcommand(argv){let[verbName,...rest]=argv;if(!verbName||verbName==="--help"||verbName==="-h"||verbName==="help"){if(!verbName)fail(apiUsage(),"MISSING_VERB",2);process.stdout.write(`${apiUsage()}
|
|
5
5
|
`);return}ensurePluginEnginesLoaded();let verb=findVerb(verbName);if(!verb){let err=unknownVerbError(verbName);fail(`${err.message}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{interactiveEngineCommand,listPresetIds}from"./chunk-
|
|
2
|
+
import{interactiveEngineCommand,listPresetIds}from"./chunk-gzf4dfg6.js";import{engineEntry}from"./chunk-e7t4xpr9.js";import{installedEngineIds}from"./chunk-n4dmwkfa.js";import{spawnSync}from"child_process";import{statSync}from"fs";import path from"path";function whichOnPath(bin){let bunWhich=globalThis.Bun?.which;if(bunWhich)return bunWhich(bin);let out=spawnSync(process.platform==="win32"?"where":"which",[bin],{encoding:"utf8"});if(out.status!==0)return null;return out.stdout.split(`
|
|
3
3
|
`).map((l)=>l.trim()).find(Boolean)??null}var defaultDeps={which:whichOnPath,command:(vendor)=>interactiveEngineCommand(vendor)};function probeLaunchBinary(argv,which){let bin=argv[0]?.trim();if(!bin)return{found:!1,error:"no launch command"};if(bin.includes(path.sep)||bin.startsWith(".")){try{if(statSync(bin).isFile())return{found:!0,path:bin}}catch{}return{found:!1,error:`not found at ${bin}`}}let found=which(bin);return found?{found:!0,path:found}:{found:!1,error:"not found on PATH"}}async function detectEngineStatus(vendor,over={}){let deps={...defaultDeps,...over},detector=engineEntry(vendor).detectAccount;if(!detector)return{vendor,binary:probeLaunchBinary(deps.command(vendor),deps.which),account:null};let status=await detector(deps.accountDeps),binary=status.binary.found?status.binary:probeLaunchBinary(deps.command(vendor),deps.which);return{vendor,binary,account:status.account,accountError:status.accountError}}function detectEngineStatuses(vendors,over={}){return Promise.all(vendors.map((v)=>detectEngineStatus(v,over)))}function describeAccount(account){if(account===null)return"login not detectable";switch(account.kind){case"oauth":return"email"in account?`logged in (${account.email}${account.organization?`, ${account.organization}`:""})`:"logged in";case"chatgpt":return`logged in (${account.email}${account.plan?`, ${account.plan}`:""})`;case"apikey":return"API key";case"token":return`token (${account.source})`;default:return"no account"}}function engineUsable(status){return status.binary.found&&status.account?.kind!=="none"}async function probeableEngineIds(){return[...new Set([...listPresetIds(),...await installedEngineIds()])]}function summarizeEngines(statuses){let usable=[],signedOut=[];for(let status of statuses)if(engineUsable(status))usable.push(status.vendor);else if(status.binary.found)signedOut.push(status.vendor);return{usable,signedOut}}
|
|
4
4
|
export{detectEngineStatuses,describeAccount,probeableEngineIds,summarizeEngines};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{engineEntry,identifiableEngineIds}from"./chunk-
|
|
2
|
+
import{engineEntry,identifiableEngineIds}from"./chunk-e7t4xpr9.js";import{basename}from"path";var WRAPPERS=new Set(["node","bun","npx","deno","sh","zsh","bash","env","script"]);function binaryName(token){return basename(token).replace(/\.(exe|js|mjs|cjs)$/,"")}function executableNameFromArgv(argv){for(let token of argv.slice(0,8)){if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))continue;let name=binaryName(token);if(WRAPPERS.has(name))continue;return name||null}return null}function vendorFromArgv(commandLine){let name=executableNameFromArgv(commandLine.trim().split(/\s+/));if(!name)return null;return identifiableEngineIds().find((v)=>{let entry=engineEntry(v);return entry.defaultCommand[0]===name||entry.processNames?.includes(name)===!0})??null}function parsePsSnapshot(text){let rows=[];for(let line of text.split(`
|
|
3
3
|
`)){let m=/^\s*(\d+)\s+(\d+)\s+(\S.*)$/.exec(line);if(m)rows.push({pid:Number(m[1]),ppid:Number(m[2]),args:m[3]})}return rows}function childrenIndex(rows){let kids=new Map;for(let row of rows){let list=kids.get(row.ppid);if(list)list.push(row);else kids.set(row.ppid,[row])}return kids}function hasAncestor(rows,pid,ancestorPid){let parents=new Map(rows.map((r)=>[r.pid,r.ppid])),cur=pid;for(let hops=0;hops<=rows.length;hops++){if(cur===ancestorPid)return!0;let next=parents.get(cur);if(next===void 0||next<=1)return!1;cur=next}return!1}function foregroundEngineIn(rows,rootPid){let kids=childrenIndex(rows),queue=[...kids.get(rootPid)??[]];while(queue.length>0){let row=queue.shift();if(!row)break;let vendor=vendorFromArgv(row.args);if(vendor)return{vendor,argv:row.args,pid:row.pid};queue.push(...kids.get(row.pid)??[])}return null}function engineProcessIn(rows,rootPid,extraLaunch){if(foregroundEngineIn(rows,rootPid))return!0;let expected=extraLaunch?executableNameFromArgv(typeof extraLaunch==="string"?[extraLaunch]:extraLaunch):null;if(!expected)return!1;let kids=childrenIndex(rows),queue=[...kids.get(rootPid)??[]];while(queue.length>0){let row=queue.shift();if(!row)break;if(executableNameFromArgv(row.args.trim().split(/\s+/))===expected)return!0;queue.push(...kids.get(row.pid)??[])}return!1}var psSnapshot=async()=>{let proc=Bun.spawn(["ps","-A","-o","pid=,ppid=,args="],{stdout:"pipe",stderr:"ignore"});return await new Response(proc.stdout).text()};async function foregroundEngine(rootPid,snapshot=psSnapshot){try{return foregroundEngineIn(parsePsSnapshot(await snapshot()),rootPid)}catch{return null}}
|
|
4
4
|
export{vendorFromArgv,parsePsSnapshot,hasAncestor,foregroundEngineIn,engineProcessIn,psSnapshot,foregroundEngine};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{stampResetGate}from"./chunk-
|
|
2
|
+
import{stampResetGate}from"./chunk-jy6nd23p.js";import{stopLegacyTmux}from"./chunk-dqndd97s.js";import"./chunk-gtkejmxx.js";import{stopDaemonProcess}from"./chunk-pdh5w4ht.js";import"./chunk-4wwx51m5.js";import"./chunk-79gqh5p2.js";import"./chunk-3ztek08w.js";import"./chunk-kwe61yx7.js";import"./chunk-m57cv76y.js";import"./chunk-a3a9gdc4.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{kvStatePath,legacyKobeKvStatePath,legacyKobeStateDir,roveStateDir}from"./chunk-6dn6h640.js";import{activeCliName}from"./chunk-ef11h2am.js";import"./chunk-8ddjfc2v.js";import"./chunk-cb2fpajx.js";import"./chunk-grh6dvfv.js";import"./chunk-pw6yfj10.js";import{defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-x760j10f.js";import"./chunk-3bfm4hrs.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";import{unlink}from"fs/promises";import{join}from"path";import{createInterface}from"readline";var CLI_NAME=activeCliName();function printUsage(out){out.write([`Usage: ${CLI_NAME} reset [--hard] [--yes]`,"","Recover a wedged install: stop the daemon, Hosted PTY host, and any pre-v0.8 tmux sessions.","This ends background terminal and engine sessions; the next launch starts fresh.","Never touches your git worktrees.","","Options:"," --hard Also wipe the task index + UI state"," -y, --yes Skip the interactive confirmation"," -h, --help Print this help",""].join(`
|
|
3
3
|
`))}function taskCount(path){try{let parsed=JSON.parse(readFileSync(path,"utf8"));return Array.isArray(parsed.tasks)?parsed.tasks.length:null}catch{return null}}async function confirmTty(prompt){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(prompt,resolve));return/^y(es)?$/i.test(answer.trim())}finally{readline.close()}}async function removeStateFile(path,label){try{await unlink(path),console.log(` removed ${label} (${path})`)}catch(err){if(err.code==="ENOENT")console.log(` ${label}: already absent`);else throw Error(`failed to remove ${label} (${path}): ${errorMessage(err)}`)}}async function runResetSubcommand(argv){if(argv.some((arg)=>arg==="--help"||arg==="-h"||arg==="help")){printUsage(process.stdout);return}let known=new Set(["--hard","--yes","-y"]),unknown=argv.find((arg)=>!known.has(arg));if(unknown!==void 0)process.stderr.write(`${CLI_NAME} reset: unknown argument "${unknown}"
|
|
4
4
|
|
|
5
5
|
`),printUsage(process.stderr),process.exit(2);let hard=argv.includes("--hard"),yes=argv.includes("--yes")||argv.includes("-y"),daemonSocket=defaultDaemonSocketPath(),tasksPath=join(roveStateDir(),"tasks.json"),legacyTasksPath=join(legacyKobeStateDir(),"tasks.json"),statePath=kvStatePath(),legacyStatePath=legacyKobeKvStatePath();if(console.log(`${CLI_NAME} reset will:`),console.log(" \u2022 stop the Rove daemon (graceful \u2192 SIGTERM \u2192 SIGKILL)"),console.log(` \u2022 remove its socket + pidfile (${daemonSocket})`),console.log(" \u2022 stop the standalone Hosted PTY host and all background terminal/engine sessions"),console.log(" \u2022 stop any pre-v0.8 tmux sessions after SIGTERM-ing their pane process groups"),hard){let count=taskCount(tasksPath)??taskCount(legacyTasksPath);console.log(` \u2022 DELETE the task index${count===null?"":` (${count} task(s))`} \u2014 ${tasksPath}`),console.log(` \u2022 DELETE the UI state \u2014 ${statePath}`),console.log(" \u2022 DELETE the pre-Rove task/UI indexes too, so migration cannot restore reset state")}if(console.log(" \u2022 NOT touch your git worktrees under ~/.rove/worktrees/, ~/.kobe/worktrees/, or repo-local roots"),!hard)console.log(" (your task list & worktrees are kept \u2014 add --hard to also wipe task and UI state)");if(!yes){if(!process.stdin.isTTY){console.log(`
|
|
@@ -4,8 +4,8 @@ import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import{expandTilde}from"./chun
|
|
|
4
4
|
|
|
5
5
|
`),printUsage(),process.exit(2)}function listThemes(){let lines=[];lines.push("bundled:");for(let name of[...BUNDLED_NAMES].sort())lines.push(` ${name} [built-in]`);let dir=userThemesDir(),userFiles=[];try{userFiles=readdirSync(dir).filter((f)=>f.endsWith(".json")).sort()}catch{}if(lines.push(""),lines.push(`user (${dir}):`),userFiles.length===0)lines.push(" (none)");else for(let f of userFiles){let name=f.slice(0,-5),path=join(dir,f),overridesBundled=BUNDLED_NAMES.includes(name)?" (overrides built-in)":"";lines.push(` ${name}${overridesBundled} ${path}`)}process.stdout.write(`${lines.join(`
|
|
6
6
|
`)}
|
|
7
|
-
`)}async function readSource(source){if(/^https?:\/\//i.test(source)){let res;try{res=await fetch(source)}catch(err){fail(`failed to fetch ${source}: ${errorMessage(err)}`)}if(!res.ok)fail(`failed to fetch ${source}: HTTP ${res.status} ${res.statusText}`);let text2=await res.text(),cleanPath=source.split(/[?#]/)[0]??source,file2=basename(cleanPath)||"theme.json",defaultName2=file2.endsWith(".json")?file2.slice(0,-5):file2;return{text:text2,defaultName:defaultName2}}let abs=resolve(process.cwd(),expandTilde(source)),text;try{text=readFileSync(abs,"utf8")}catch(err){fail(`failed to read ${abs}: ${errorMessage(err)}`)}let file=basename(abs),defaultName=file.endsWith(".json")?file.slice(0,-5):file;return{text,defaultName}}function parseAddArgs(args){let source=null,name,force=!1;for(let i=0;i<args.length;i+=1){let a=args[i];if(a==="--force"||a==="-f"){force=!0;continue}if(a==="--name"||a==="-n"){let next=args[i+1];if(next===void 0)failUsage("--name requires a value");name=next,i+=1;continue}if(a.startsWith("--name=")){name=a.slice(7);continue}if(a.startsWith("--"))failUsage(`unknown flag: ${a}`);if(source===null){source=a;continue}failUsage(`unexpected positional argument: ${a}`)}if(source===null)failUsage("missing <source> (URL or path to theme JSON)");return{source,opts:{name,force}}}async function addTheme(args){let{source,opts}=parseAddArgs(args),{text,defaultName}=await readSource(source),parsed;try{parsed=JSON.parse(text)}catch(err){fail(`source is not valid JSON: ${errorMessage(err)}`)}let result=validateTheme(parsed);if(!result.ok)fail(`source is not a valid Rove theme: ${result.reason}`);let name=opts.name??defaultName
|
|
7
|
+
`)}async function readSource(source){if(/^https?:\/\//i.test(source)){let res;try{res=await fetch(source)}catch(err){fail(`failed to fetch ${source}: ${errorMessage(err)}`)}if(!res.ok)fail(`failed to fetch ${source}: HTTP ${res.status} ${res.statusText}`);let text2=await res.text(),cleanPath=source.split(/[?#]/)[0]??source,file2=basename(cleanPath)||"theme.json",defaultName2=file2.endsWith(".json")?file2.slice(0,-5):file2;return{text:text2,defaultName:defaultName2}}let abs=resolve(process.cwd(),expandTilde(source)),text;try{text=readFileSync(abs,"utf8")}catch(err){fail(`failed to read ${abs}: ${errorMessage(err)}`)}let file=basename(abs),defaultName=file.endsWith(".json")?file.slice(0,-5):file;return{text,defaultName}}function parseAddArgs(args){let source=null,name,force=!1;for(let i=0;i<args.length;i+=1){let a=args[i];if(a==="--force"||a==="-f"){force=!0;continue}if(a==="--name"||a==="-n"){let next=args[i+1];if(next===void 0)failUsage("--name requires a value");name=next,i+=1;continue}if(a.startsWith("--name=")){name=a.slice(7);continue}if(a.startsWith("--"))failUsage(`unknown flag: ${a}`);if(source===null){source=a;continue}failUsage(`unexpected positional argument: ${a}`)}if(source===null)failUsage("missing <source> (URL or path to theme JSON)");return{source,opts:{name,force}}}async function addTheme(args){let{source,opts}=parseAddArgs(args),{text,defaultName}=await readSource(source),parsed;try{parsed=JSON.parse(text)}catch(err){fail(`source is not valid JSON: ${errorMessage(err)}`)}let result=validateTheme(parsed);if(!result.ok)fail(`source is not a valid Rove theme: ${result.reason}`);let name=requireThemeName(opts.name??defaultName),dir=userThemesDir();mkdirSync(dir,{recursive:!0});let dest=join(dir,`${name}.json`);if(existsSync(dest)&&!opts.force)fail(`${dest} already exists (pass --force to overwrite)`);writeFileSync(dest,`${JSON.stringify(result.theme,null,2)}
|
|
8
8
|
`,"utf8"),process.stdout.write(`installed theme "${name}" -> ${dest}
|
|
9
|
-
`)}function
|
|
9
|
+
`)}function requireThemeName(name){if(!name||!/^[a-zA-Z0-9._-]+$/.test(name)||name==="."||name==="..")fail(`invalid theme name "${name}" (use letters, digits, '.', '_', '-')`);return name}function removeTheme(args){if(!args[0])failUsage("missing <name>");if(args.length>1)failUsage(`unexpected extra arguments after "${args[0]}"`);let name=requireThemeName(args[0]);if(BUNDLED_NAMES.includes(name))fail(`"${name}" is a built-in theme and cannot be removed`);let dest=join(userThemesDir(),`${name}.json`);if(!existsSync(dest))fail(`no user theme named "${name}" (looked for ${dest})`);unlinkSync(dest),process.stdout.write(`removed theme "${name}" (${dest})
|
|
10
10
|
`)}function printUsage(out=process.stderr){out.write([`Usage: ${CLI_NAME} theme <command> [args]`,"","Commands:"," list List bundled and user-installed themes"," add <source> [--name <name>] Install a theme from a URL or local path"," Pass --force to overwrite an existing user theme"," remove <name> Remove a user-installed theme","",`User themes live under: ${userThemesDir()}`,"Schema: https://raw.githubusercontent.com/sma1lboy/rove/main/packages/kobe/src/tui/context/theme/theme.schema.json",""].join(`
|
|
11
11
|
`))}async function runThemeSubcommand(args){let[action,...rest]=args;if(!action||action==="--help"||action==="-h"||action==="help"){if(printUsage(action?process.stdout:process.stderr),!action)process.exit(2);return}let verb=THEME_VERB_ALIASES[action]??action;if(!SUBCOMMAND_VERBS.theme.includes(verb))failUsage(`unknown action "${action}" (try ${SUBCOMMAND_VERBS.theme.map((v)=>`"${v}"`).join(", ")})`);if(verb==="list"){if(rest.length>0)failUsage(`"${action}" takes no arguments`);listThemes();return}if(verb==="add"){await addTheme(rest);return}if(verb==="remove"){removeTheme(rest);return}failUsage(`unknown action "${action}"`)}export{runThemeSubcommand};
|