@sma1lboy/rove 0.9.158 → 0.9.159
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-xayk93mt.js → chunk-0f377y88.js} +1 -1
- package/dist/cli/chunk-1w8nmx4v.js +2 -0
- package/dist/cli/{chunk-43h1dzea.js → chunk-4wrby8xt.js} +1 -1
- package/dist/cli/{chunk-pzpaf3w7.js → chunk-7fy242v4.js} +1 -1
- package/dist/cli/{chunk-qch6g9za.js → chunk-9m0tb44t.js} +1 -1
- package/dist/cli/{chunk-nss70xwr.js → chunk-9wn8m2rt.js} +1 -1
- package/dist/cli/{chunk-nt3s6fdf.js → chunk-bc93p4fx.js} +1 -1
- package/dist/cli/{chunk-37y5pcwh.js → chunk-ckqjhfss.js} +1 -1
- package/dist/cli/{chunk-p93wwzrv.js → chunk-cpmbj0zg.js} +1 -1
- package/dist/cli/{chunk-8d7ckf5a.js → chunk-dqxzpetd.js} +1 -1
- package/dist/cli/{chunk-h6h9rzs4.js → chunk-dxcwhdsx.js} +1 -1
- package/dist/cli/{chunk-vfq69a8b.js → chunk-e5f9rdj2.js} +1 -1
- package/dist/cli/{chunk-s7ceva0p.js → chunk-es4985my.js} +1 -1
- package/dist/cli/{chunk-ybcacmqv.js → chunk-g8r9zv1x.js} +1 -1
- package/dist/cli/{chunk-nk0qrs4y.js → chunk-gf5y2jft.js} +2 -2
- package/dist/cli/{chunk-n7n12868.js → chunk-hfdxy3qe.js} +2 -2
- package/dist/cli/{chunk-tg1dytxg.js → chunk-kkc2vejt.js} +1 -1
- package/dist/cli/{chunk-kv86anbp.js → chunk-m4zadw45.js} +1 -1
- package/dist/cli/{chunk-pedc66hv.js → chunk-mmfwyc7j.js} +2 -2
- package/dist/cli/{chunk-3xfhns47.js → chunk-mxz4jmb8.js} +1 -1
- package/dist/cli/{chunk-gxs1g9v8.js → chunk-nsayx0vv.js} +2 -2
- package/dist/cli/{chunk-2f4bjgnm.js → chunk-pny0ne6r.js} +1 -1
- package/dist/cli/{chunk-0b0v9t2e.js → chunk-pz92vzcv.js} +6 -6
- package/dist/cli/{chunk-we0gedwp.js → chunk-qq5z2ev8.js} +1 -1
- package/dist/cli/{chunk-exggdhpt.js → chunk-s53jjqyf.js} +1 -1
- package/dist/cli/{chunk-5rag9cyg.js → chunk-s6fcwzyg.js} +1 -1
- package/dist/cli/{chunk-m003t3jb.js → chunk-svndhd3d.js} +1 -1
- package/dist/cli/chunk-tb6b5zx4.js +3 -0
- package/dist/cli/{chunk-fd2zhddn.js → chunk-w06vgba4.js} +1 -1
- package/dist/cli/{chunk-bnqjzkqs.js → chunk-w3gzwzfk.js} +1 -1
- package/dist/cli/{chunk-xhczp1ew.js → chunk-w6s06z4a.js} +2 -2
- package/dist/cli/chunk-wk7f8ns5.js +7 -0
- package/dist/cli/{chunk-mhzv94cg.js → chunk-wt8dc57p.js} +4 -4
- package/dist/cli/{chunk-6dhk21ce.js → chunk-wy1rbq5h.js} +1 -1
- package/dist/cli/{chunk-ptjc5mtc.js → chunk-xxmyqw1v.js} +1 -1
- package/dist/cli/{chunk-fm5s7njg.js → chunk-ynknvkrw.js} +1 -1
- package/dist/cli/{chunk-y1nm1p2m.js → chunk-yxnqzamz.js} +1 -1
- package/dist/cli/{chunk-yqvrr5kt.js → chunk-yzwv7g1r.js} +1 -1
- package/dist/cli/{chunk-4rm0yrp8.js → chunk-zvhrhn88.js} +3 -3
- package/dist/cli/index.js +3 -3
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/rove.js +1 -1
- package/dist/skills/rove/references/api-flags.md +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-ngnrz33z.js +0 -3
- package/dist/cli/chunk-nvpd0bgq.js +0 -7
- package/dist/cli/chunk-nx7ahbsg.js +0 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-
|
|
2
|
+
import{deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,deriveTitleFromSession,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,tearDownTaskSessionAdapter}from"./chunk-qq5z2ev8.js";import{resolvePluginBinPath}from"./chunk-e17gszac.js";import{Orchestrator}from"./chunk-wbt845s6.js";import{GH_PR_VIEW_FIELDS,classifyGhFailure,mapGhPrView,nextPrPoll,samePrStatus}from"./chunk-vj2vdx3w.js";import"./chunk-t7xhb2jx.js";import{GitWorktreeManager,parseDirtyPaths}from"./chunk-hj08heah.js";import{auditDeletionBranchKept,auditDeletionResidue,auditDeletionSalvaged,auditWorktreeResidue,auditWorktreeSalvaged,parseAheadBehind,startDaemonServer}from"./chunk-zvhrhn88.js";import"./chunk-39x1ztey.js";import"./chunk-41ahvk51.js";import"./chunk-rz8zs7j8.js";import"./chunk-caqpt09m.js";import{parsePorcelain}from"./chunk-xqw5d5rv.js";import"./chunk-h4n8ffqy.js";import{DEFAULT_BASE_REF_CANDIDATES,readHeadSha,readRefSha,resolveGitDirs}from"./chunk-vyb5a2rh.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{affectsActivityState,isEngineActivityKind}from"./chunk-3e5n28t6.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-r05r01nv.js";import"./chunk-6pt23vas.js";import"./chunk-r2pztgm6.js";import"./chunk-38272eqv.js";import"./chunk-5f80ggc3.js";import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import{TaskIndexStore}from"./chunk-c43g3qcb.js";import"./chunk-qkehg2c1.js";import{CURRENT_VERSION,checkLatestVersion}from"./chunk-kkc2vejt.js";import{autoStatusEnabled,deliveryGuard}from"./chunk-wt8dc57p.js";import{execHostForWorktreePath}from"./chunk-ds9qf1w1.js";import"./chunk-bkba9c4n.js";import"./chunk-g2advs8t.js";import"./chunk-wdhcrcre.js";import{GENERIC_PROTOCOL,engineProtocolKey,getEngineProtocol,protocolEntry,resolveCommandProtocol}from"./chunk-xxmyqw1v.js";import"./chunk-7q67dz4c.js";import{installDaemonCrashHandlers}from"./chunk-1cjd7h8p.js";import"./chunk-b99tf0jr.js";import"./chunk-t27t2x9b.js";import"./chunk-hape5vwj.js";import{engineDisplayName,kobeApiInvocation}from"./chunk-de751t37.js";import"./chunk-ynknvkrw.js";import"./chunk-w06vgba4.js";import"./chunk-sdyzxayr.js";import"./chunk-zqfbyq0a.js";import"./chunk-jvxh93nz.js";import{connectOrStartDaemon}from"./chunk-4502n1bk.js";import{stopDaemonProcess}from"./chunk-nm0pq5r6.js";import{readPidFile}from"./chunk-mqqnk8w7.js";import{KobeDaemonClient}from"./chunk-0wnfq5sx.js";import"./chunk-7j5372wb.js";import"./chunk-mnqxgvyb.js";import{foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-hfdxy3qe.js";import{createEngineTurnDetector,engineEntry,engineTitleTurnHint,vendorsWithQuotaProbe}from"./chunk-4gjr08g0.js";import{availableEngineIds}from"./chunk-sfv15era.js";import"./chunk-w7zv47mp.js";import{spawnCapture}from"./chunk-gwcneg6c.js";import"./chunk-25hxhtdr.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import{backfillSavedReposFromProjects,getCustomEngineIds,getPersistedString,getRemoteRepoConfig,getSavedRepos,setPersistedString}from"./chunk-kt1ppyje.js";import"./chunk-5v893waj.js";import"./chunk-axfn4f28.js";import{DEFAULT_TASK_VENDOR,isTaskStatus}from"./chunk-xy8be792.js";import{isProcessAlive,releaseSync}from"./chunk-a3a9gdc4.js";import"./chunk-2brn8e1y.js";import"./chunk-3wj69b0a.js";import"./chunk-ch9b1d5y.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-bq3fyc0p.js";import{activeCliName}from"./chunk-p7s4xwgx.js";import{migrateRoveDaemonStateLayout}from"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-k2ckx8zw.js";import{rotateLogIfNeeded}from"./chunk-pw6yfj10.js";import"./chunk-nyv7a76k.js";import"./chunk-rxvbm4vt.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-mcdv19rs.js";import{readRoveHomeDirEnv}from"./chunk-r3k9rbwm.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(`
|
|
6
|
-
`).find((l)=>l.startsWith("branch "))?.slice(7).trim().replace(/^refs\/heads\//,"")||null}function readRefSymbolic(dirs,ref){for(let dir of[dirs.gitDir,dirs.commonDir])try{let target=readFileSync(join(dir,ref),"utf8").trim().match(/^ref:\s*(.+)$/)?.[1]?.trim();if(target)return target}catch{}return null}function ladderFromFiles(worktreePath){let dirs=resolveGitDirs(worktreePath);if(!dirs)return;let originHead=readRefSymbolic(dirs,"refs/remotes/origin/HEAD")?.replace(/^refs\/remotes\//,""),baseCheckout=readRefSymbolic({gitDir:dirs.commonDir,commonDir:dirs.commonDir},"HEAD")?.replace(/^refs\/heads\//,""),names=[],head=readHeadSha(dirs),parts=[`HEAD=${head}`];for(let guess of[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]]){if(names.includes(guess))continue;let sha=readRefSha(dirs,guess);if(sha===null)continue;names.push(guess),parts.push(`${guess}=${sha}`)}return{names,fingerprint:head===null?null:parts.join(",")}}async function ladderFromGit(worktreePath,signal){let head=await git2(worktreePath,["symbolic-ref","--short","refs/remotes/origin/HEAD"],signal),originHead=head.status===0?head.stdout.trim():"",baseCheckout=await baseCheckoutBranchFromGit(worktreePath,signal),names=[],candidates=[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]];for(let guess of candidates){if(names.includes(guess))continue;if(await refExists(worktreePath,guess,signal))names.push(guess)}return{names,fingerprint:null}}async function resolveBaseRefCached(worktreePath,recordedBaseRef,signal,now=Date.now()){if(recordedBaseRef){let dirs=resolveGitDirs(worktreePath);if(dirs&&readRefSha(dirs,recordedBaseRef)!==null)return recordedBaseRef;if(await refExists(worktreePath,recordedBaseRef,signal))return recordedBaseRef}let hit=cache.get(worktreePath);if(hit&&now-hit.at<BASE_REF_TTL_MS)return hit.ref;let ladder=ladderFromFiles(worktreePath)??await ladderFromGit(worktreePath,signal);if(hit&&ladder.fingerprint!==null&&hit.fingerprint===ladder.fingerprint)return cache.set(worktreePath,{...hit,at:now}),hit.ref;let ref=null;for(let candidate of ladder.names)if(await sharesHistory(worktreePath,candidate,signal)){ref=candidate;break}return cache.set(worktreePath,{ref,at:now,fingerprint:ladder.fingerprint}),ref}var cache2=new Map;function readShas(worktreePath,baseRef){let dirs=resolveGitDirs(worktreePath);if(!dirs)return null;let head=readHeadSha(dirs),base=readRefSha(dirs,baseRef);return head&&base?{head,base}:null}async function driftCached(worktreePath,baseRef,compute){let shas=readShas(worktreePath,baseRef),hit=shas?cache2.get(worktreePath):void 0;if(shas&&hit&&hit.head===shas.head&&hit.base===shas.base)return hit.value;let value=await compute();if(shas&&value!==null)cache2.set(worktreePath,{...shas,value});return value}import{statSync}from"fs";function judgeWorktree(signals,nowMs){if(signals.dirty)return{verdict:"active",reason:"dirty"};if(signals.prState==="open")return{verdict:"active",reason:"prOpen"};if(signals.prState==="merged")return{verdict:"merged",reason:"prMerged"};if(signals.aheadOfDefault===0)return{verdict:"merged",reason:"inMain"};if(signals.prState==="closed")return{verdict:"stale",reason:"prClosed"};if(signals.lastActivityMs>0&&nowMs-signals.lastActivityMs>1209600000)return{verdict:"stale",reason:"idle"};return{verdict:"fresh",reason:"fresh"}}function parseGhPrList(stdout){let entries;try{entries=JSON.parse(stdout)}catch{return null}if(!Array.isArray(entries))return null;let rank={open:3,merged:2,closed:1},map=new Map;for(let entry of entries){let branch=entry?.headRefName,rawState=entry?.state;if(typeof branch!=="string"||typeof rawState!=="string")continue;let state=rawState.toLowerCase();if(state!=="open"&&state!=="merged"&&state!=="closed")continue;let cur=map.get(branch);if(!cur||rank[state]>rank[cur])map.set(branch,state)}return map}var TIMEOUT_MS=4000,manager=new GitWorktreeManager;function createdAt(path){try{let stat=statSync(path);return stat.birthtimeMs||stat.mtimeMs}catch{return 0}}async function run(path,argv){return execHostForWorktreePath(path).run(argv,{cwd:path,signal:AbortSignal.timeout(TIMEOUT_MS)})}async function branchOnRemote(path,branch){try{let out=await run(path,["git","ls-remote","--exit-code","--heads","origin",branch]);return out.exitCode===0?!0:out.exitCode===2?!1:null}catch{return null}}async function defaultRef(repo){try{let out=await run(repo,["git","symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(out.exitCode===0&&out.stdout.trim())return out.stdout.trim()}catch{}for(let guess of["origin/main","origin/master"])try{if((await run(repo,["git","rev-parse","--verify","--quiet",guess])).exitCode===0)return guess}catch{}return null}async function prStates(repo){try{let origin=await run(repo,["git","remote","get-url","origin"]);if(origin.exitCode!==0||!origin.stdout.includes("github.com"))return null;let out=await run(repo,["gh","pr","list","--state","all","--limit","200","--json","headRefName,state"]);return out.exitCode===0?parseGhPrList(out.stdout):null}catch{return null}}async function ahead(path,ref){if(!ref)return null;try{let out=await run(path,["git","rev-list","--count",`${ref}..HEAD`]),value=Number.parseInt(out.stdout.trim(),10);return out.exitCode===0&&!Number.isNaN(value)?value:null}catch{return null}}async function listWorktreeProjectsAdapter(network){let repos=getSavedRepos().filter((repo)=>!getRemoteRepoConfig(repo)),now=Date.now();return Promise.all(repos.map(async(repo)=>{let[worktrees,states,ref]=await Promise.all([manager.listAll(repo),network?prStates(repo):null,defaultRef(repo)]),rows=await Promise.all(worktrees.map(async(worktree)=>{let[remote,aheadBy]=await Promise.all([network?branchOnRemote(worktree.path,worktree.branch):null,ahead(worktree.path,ref)]),judgement=judgeWorktree({dirty:worktree.dirty===!0,prState:states?.get(worktree.branch)??null,aheadOfDefault:aheadBy,lastActivityMs:worktree.lastActivityMs},now);return{...worktree,repo,createdAtMs:createdAt(worktree.path),branchOnRemote:remote,verdict:judgement.verdict,verdictReason:judgement.reason}}));return{repo,worktrees:rows}}))}async function listUnreadableWorktreesAdapter(repo){return manager.listUnreadableWorktrees(repo)}async function removeWorktreeAdapter(path,force){let residue=null;return await manager.remove(path,{force,onSalvage:(record)=>{if(record)auditWorktreeSalvaged(path,record.ref,record.commit,record.uncaptured)},onResidue:(r)=>{residue={path:r.path,reason:r.reason},auditWorktreeResidue(r.path,r.reason)}}),residue}function resolveProtocolUpgradeAndLearnPreset(task,evidence){let preset=protocolWriteBackFromLiveSession(task,evidence,getCustomEngineIds());if(preset)setPersistedString(engineProtocolKey(preset.id),preset.protocol);return protocolUpgradeFromLiveSession(task,evidence)}var daemonRuntime={currentVersion:CURRENT_VERSION,defaultTaskVendor:DEFAULT_TASK_VENDOR,placeholderTaskTitle:PLACEHOLDER_TASK_TITLE,isTaskStatus,isEngineActivityKind,affectsActivityState,async foregroundEngines(pids){let rows=parsePsSnapshot(await psSnapshot()),out=new Map;for(let pid of pids){let found=foregroundEngineIn(rows,pid);out.set(pid,found?{vendor:found.vendor,pid:found.pid}:null)}return out},titleTurnHint:engineTitleTurnHint,resolveProtocolUpgrade:resolveProtocolUpgradeAndLearnPreset,readEngineTurns:async(vendor,transcriptPath)=>await engineEntry(vendor).readTurns?.(transcriptPath)??[],checkLatestVersion,latestTranscriptMtime,deriveTitleFromSession,createEngineTurnDetector,async runWorktreeStatus(worktreePath,signal,baseRef){let result=await spawnCapture("git",["status","--porcelain=v1"],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});if(result.status!==0)throw Error("git status failed");let counts=parsePorcelain(result.stdout),base=await resolveBaseRefCached(worktreePath,baseRef,signal);if(!base)return counts;let drift=await driftCached(worktreePath,base,async()=>{let out=await spawnCapture("git",["rev-list","--left-right","--count",`${base}...HEAD`],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});return out.status===0?parseAheadBehind(out.stdout):null});return drift===null?counts:{...counts,...drift}},maybeAutoStart:(orch,taskId)=>maybeAutoStart(orch,taskId),listWorktreeProjects:listWorktreeProjectsAdapter,listUnreadableWorktrees:listUnreadableWorktreesAdapter,removeWorktree:removeWorktreeAdapter,async syncWorktreeWithBase(worktreePath,recordedBaseRef){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),SYNC_TIMEOUT_MS);try{let baseRef=await resolveBaseRefCached(worktreePath,recordedBaseRef,controller.signal);if(!baseRef)throw Error("no base ref resolves for this worktree");return await syncWorktreeWithBase(worktreePath,baseRef,controller.signal)}finally{clearTimeout(timer)}},availableEngineIds,engineDisplayName,kobeApiInvocation,engineEntry,ensureTaskSession:ensureTaskSessionAdapter,startTaskSessionWithPrompt:startTaskSessionWithPromptAdapter,tearDownTaskSession:tearDownTaskSessionAdapter,async readEngineContextUsage(vendor,sessionId){let read=engineEntry(vendor).history.readUsageSnapshot;if(!read)return null;let snapshot=await read(sessionId);if(snapshot?.context_tokens===void 0)return null;return{contextTokens:snapshot.context_tokens,...snapshot.context_window_tokens===void 0?{}:{contextWindowTokens:snapshot.context_window_tokens},...snapshot.context_tokens_approximate?{approximate:!0}:{},...snapshot.input_tokens===void 0?{}:{inputTokens:snapshot.input_tokens},...snapshot.output_tokens===void 0?{}:{outputTokens:snapshot.output_tokens},...snapshot.cache_read_input_tokens===void 0?{}:{cacheReadTokens:snapshot.cache_read_input_tokens},...snapshot.cache_creation_input_tokens===void 0?{}:{cacheCreationTokens:snapshot.cache_creation_input_tokens}}},quotaUsage:(vendor)=>engineEntry(vendor).quotaUsage?.()??Promise.resolve(null),vendorsWithQuotaProbe,deliverPromptToLiveEngine:deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailed:deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailed:deliverPromptToLiveEngineTabDetailedAdapter,composerGateEnabled,getPersistedString,setPersistedString,getSavedRepos:()=>[...getSavedRepos()],prStatus:{viewFields:GH_PR_VIEW_FIELDS,mapView:(view,at)=>mapGhPrView(view,at),sameStatus:samePrStatus,nextPoll:(outcome,failures,now,config,random)=>nextPrPoll(outcome,failures,now,config,random),classify:classifyGhFailure}};import{homedir}from"os";async function createKobeCore(options={}){let homeDir=options.homeDir??readRoveHomeDirEnv()??homedir(),store=new TaskIndexStore({homeDir});await store.load();let worktrees=new GitWorktreeManager,orchestrator=new Orchestrator({store,worktrees,onSalvage:(taskId,salvage)=>auditDeletionSalvaged(String(taskId),salvage.ref,salvage.commit,store.get(taskId)?.repo,salvage.uncaptured),onWorktreeResidue:(taskId,residue)=>auditDeletionResidue(String(taskId),residue.path,residue.reason),onBranchKept:(taskId,kept)=>auditDeletionBranchKept(String(taskId),kept.branch,kept.reason),tearDownSession:(taskId)=>tearDownTaskSessionAdapter(String(taskId))}),backfilled=backfillSavedReposFromProjects(store.list().filter((task)=>task.kind==="main").map((task)=>task.repo));if(backfilled.length>0)console.error(`[rove] added ${backfilled.length} existing project(s) to the new-task picker`);return{homeDir,orchestrator,store,worktrees,async close(){orchestrator.dispose()}}}import{existsSync,readFileSync as readFileSync2,readdirSync,statSync as statSync2,unlinkSync}from"fs";import{join as join2}from"path";var TMP_MAX_AGE_MS=300000;function sweepIndexLeftovers(stateDir,now=Date.now()){let tmp=[],tmpBytes=0,entries;try{entries=readdirSync(stateDir)}catch{return{tmp,tmpBytes,lock:!1}}for(let name of entries){if(!name.startsWith("tasks.json.")||!name.endsWith(".tmp"))continue;let path=join2(stateDir,name);try{let stat=statSync2(path);if(now-stat.mtimeMs<TMP_MAX_AGE_MS)continue;unlinkSync(path),tmp.push(path),tmpBytes+=stat.size}catch{}}return{tmp,tmpBytes,lock:clearStaleLock(join2(stateDir,"tasks.json.lock"))}}function clearStaleLock(lockPath){let holder;try{holder=readFileSync2(lockPath,"utf8").trim()}catch{return!1}let pid=Number.parseInt(holder,10);if(Number.isFinite(pid)&&pid>0&&isProcessAlive(pid))return!1;return releaseSync(lockPath,holder),!existsSync(lockPath)}var CLI_NAME=activeCliName();function printDaemonUsage(out){out.write([`Usage: ${CLI_NAME} daemon <command>`,"","Commands:"," status Print the running daemon's status JSON (default)"," start Run the daemon in the foreground (this process becomes it)"," stop Ask the running daemon to shut down"," restart Stop the daemon (graceful \u2192 SIGTERM \u2192 SIGKILL) and respawn it",""].join(`
|
|
6
|
+
`).find((l)=>l.startsWith("branch "))?.slice(7).trim().replace(/^refs\/heads\//,"")||null}function readRefSymbolic(dirs,ref){for(let dir of[dirs.gitDir,dirs.commonDir])try{let target=readFileSync(join(dir,ref),"utf8").trim().match(/^ref:\s*(.+)$/)?.[1]?.trim();if(target)return target}catch{}return null}function ladderFromFiles(worktreePath){let dirs=resolveGitDirs(worktreePath);if(!dirs)return;let originHead=readRefSymbolic(dirs,"refs/remotes/origin/HEAD")?.replace(/^refs\/remotes\//,""),baseCheckout=readRefSymbolic({gitDir:dirs.commonDir,commonDir:dirs.commonDir},"HEAD")?.replace(/^refs\/heads\//,""),names=[],head=readHeadSha(dirs),parts=[`HEAD=${head}`];for(let guess of[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]]){if(names.includes(guess))continue;let sha=readRefSha(dirs,guess);if(sha===null)continue;names.push(guess),parts.push(`${guess}=${sha}`)}return{names,fingerprint:head===null?null:parts.join(",")}}async function ladderFromGit(worktreePath,signal){let head=await git2(worktreePath,["symbolic-ref","--short","refs/remotes/origin/HEAD"],signal),originHead=head.status===0?head.stdout.trim():"",baseCheckout=await baseCheckoutBranchFromGit(worktreePath,signal),names=[],candidates=[...originHead?[originHead]:[],...DEFAULT_BASE_REF_CANDIDATES,...baseCheckout?[baseCheckout]:[]];for(let guess of candidates){if(names.includes(guess))continue;if(await refExists(worktreePath,guess,signal))names.push(guess)}return{names,fingerprint:null}}async function resolveBaseRefCached(worktreePath,recordedBaseRef,signal,now=Date.now()){if(recordedBaseRef){let dirs=resolveGitDirs(worktreePath);if(dirs&&readRefSha(dirs,recordedBaseRef)!==null)return recordedBaseRef;if(await refExists(worktreePath,recordedBaseRef,signal))return recordedBaseRef}let hit=cache.get(worktreePath);if(hit&&now-hit.at<BASE_REF_TTL_MS)return hit.ref;let ladder=ladderFromFiles(worktreePath)??await ladderFromGit(worktreePath,signal);if(hit&&ladder.fingerprint!==null&&hit.fingerprint===ladder.fingerprint)return cache.set(worktreePath,{...hit,at:now}),hit.ref;let ref=null;for(let candidate of ladder.names)if(await sharesHistory(worktreePath,candidate,signal)){ref=candidate;break}return cache.set(worktreePath,{ref,at:now,fingerprint:ladder.fingerprint}),ref}var cache2=new Map;function readShas(worktreePath,baseRef){let dirs=resolveGitDirs(worktreePath);if(!dirs)return null;let head=readHeadSha(dirs),base=readRefSha(dirs,baseRef);return head&&base?{head,base}:null}async function driftCached(worktreePath,baseRef,compute){let shas=readShas(worktreePath,baseRef),hit=shas?cache2.get(worktreePath):void 0;if(shas&&hit&&hit.head===shas.head&&hit.base===shas.base)return hit.value;let value=await compute();if(shas&&value!==null)cache2.set(worktreePath,{...shas,value});return value}import{statSync}from"fs";function judgeWorktree(signals,nowMs){if(signals.dirty)return{verdict:"active",reason:"dirty"};if(signals.prState==="open")return{verdict:"active",reason:"prOpen"};if(signals.prState==="merged")return{verdict:"merged",reason:"prMerged"};if(signals.aheadOfDefault===0)return{verdict:"merged",reason:"inMain"};if(signals.prState==="closed")return{verdict:"stale",reason:"prClosed"};if(signals.lastActivityMs>0&&nowMs-signals.lastActivityMs>1209600000)return{verdict:"stale",reason:"idle"};return{verdict:"fresh",reason:"fresh"}}function parseGhPrList(stdout){let entries;try{entries=JSON.parse(stdout)}catch{return null}if(!Array.isArray(entries))return null;let rank={open:3,merged:2,closed:1},map=new Map;for(let entry of entries){let branch=entry?.headRefName,rawState=entry?.state;if(typeof branch!=="string"||typeof rawState!=="string")continue;let state=rawState.toLowerCase();if(state!=="open"&&state!=="merged"&&state!=="closed")continue;let cur=map.get(branch);if(!cur||rank[state]>rank[cur])map.set(branch,state)}return map}var TIMEOUT_MS=4000,manager=new GitWorktreeManager;function createdAt(path){try{let stat=statSync(path);return stat.birthtimeMs||stat.mtimeMs}catch{return 0}}async function run(path,argv){return execHostForWorktreePath(path).run(argv,{cwd:path,signal:AbortSignal.timeout(TIMEOUT_MS)})}async function branchOnRemote(path,branch){try{let out=await run(path,["git","ls-remote","--exit-code","--heads","origin",branch]);return out.exitCode===0?!0:out.exitCode===2?!1:null}catch{return null}}async function defaultRef(repo){try{let out=await run(repo,["git","symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(out.exitCode===0&&out.stdout.trim())return out.stdout.trim()}catch{}for(let guess of["origin/main","origin/master"])try{if((await run(repo,["git","rev-parse","--verify","--quiet",guess])).exitCode===0)return guess}catch{}return null}async function prStates(repo){try{let origin=await run(repo,["git","remote","get-url","origin"]);if(origin.exitCode!==0||!origin.stdout.includes("github.com"))return null;let out=await run(repo,["gh","pr","list","--state","all","--limit","200","--json","headRefName,state"]);return out.exitCode===0?parseGhPrList(out.stdout):null}catch{return null}}async function ahead(path,ref){if(!ref)return null;try{let out=await run(path,["git","rev-list","--count",`${ref}..HEAD`]),value=Number.parseInt(out.stdout.trim(),10);return out.exitCode===0&&!Number.isNaN(value)?value:null}catch{return null}}async function listWorktreeProjectsAdapter(network){let repos=getSavedRepos().filter((repo)=>!getRemoteRepoConfig(repo)),now=Date.now();return Promise.all(repos.map(async(repo)=>{let[worktrees,states,ref]=await Promise.all([manager.listAll(repo),network?prStates(repo):null,defaultRef(repo)]),rows=await Promise.all(worktrees.map(async(worktree)=>{let[remote,aheadBy]=await Promise.all([network?branchOnRemote(worktree.path,worktree.branch):null,ahead(worktree.path,ref)]),judgement=judgeWorktree({dirty:worktree.dirty===!0,prState:states?.get(worktree.branch)??null,aheadOfDefault:aheadBy,lastActivityMs:worktree.lastActivityMs},now);return{...worktree,repo,createdAtMs:createdAt(worktree.path),branchOnRemote:remote,verdict:judgement.verdict,verdictReason:judgement.reason}}));return{repo,worktrees:rows}}))}async function listUnreadableWorktreesAdapter(repo){return manager.listUnreadableWorktrees(repo)}async function removeWorktreeAdapter(path,force){let residue=null;return await manager.remove(path,{force,onSalvage:(record)=>{if(record)auditWorktreeSalvaged(path,record.ref,record.commit,record.uncaptured)},onResidue:(r)=>{residue={path:r.path,reason:r.reason},auditWorktreeResidue(r.path,r.reason)}}),residue}function resolveProtocolUpgradeAndLearnPreset(task,evidence){let preset=protocolWriteBackFromLiveSession(task,evidence,getCustomEngineIds());if(preset)setPersistedString(engineProtocolKey(preset.id),preset.protocol);return protocolUpgradeFromLiveSession(task,evidence)}var daemonRuntime={currentVersion:CURRENT_VERSION,defaultTaskVendor:DEFAULT_TASK_VENDOR,placeholderTaskTitle:PLACEHOLDER_TASK_TITLE,isTaskStatus,isEngineActivityKind,affectsActivityState,async foregroundEngines(pids){let rows=parsePsSnapshot(await psSnapshot()),out=new Map;for(let pid of pids){let found=foregroundEngineIn(rows,pid);out.set(pid,found?{vendor:found.vendor,pid:found.pid}:null)}return out},titleTurnHint:engineTitleTurnHint,resolveProtocolUpgrade:resolveProtocolUpgradeAndLearnPreset,readEngineTurns:async(vendor,transcriptPath)=>await engineEntry(vendor).readTurns?.(transcriptPath)??[],checkLatestVersion,latestTranscriptMtime,deriveTitleFromSession,createEngineTurnDetector,async runWorktreeStatus(worktreePath,signal,baseRef){let result=await spawnCapture("git",["status","--porcelain=v1"],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});if(result.status!==0)throw Error("git status failed");let counts=parsePorcelain(result.stdout),base=await resolveBaseRefCached(worktreePath,baseRef,signal);if(!base)return counts;let drift=await driftCached(worktreePath,base,async()=>{let out=await spawnCapture("git",["rev-list","--left-right","--count",`${base}...HEAD`],{cwd:worktreePath,env:readOnlyGitProcessEnv(),signal});return out.status===0?parseAheadBehind(out.stdout):null});return drift===null?counts:{...counts,...drift}},maybeAutoStart:(orch,taskId)=>maybeAutoStart(orch,taskId),listWorktreeProjects:listWorktreeProjectsAdapter,listUnreadableWorktrees:listUnreadableWorktreesAdapter,removeWorktree:removeWorktreeAdapter,async syncWorktreeWithBase(worktreePath,recordedBaseRef){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),SYNC_TIMEOUT_MS);try{let baseRef=await resolveBaseRefCached(worktreePath,recordedBaseRef,controller.signal);if(!baseRef)throw Error("no base ref resolves for this worktree");return await syncWorktreeWithBase(worktreePath,baseRef,controller.signal)}finally{clearTimeout(timer)}},availableEngineIds,engineDisplayName,kobeApiInvocation,engineEntry,ensureTaskSession:ensureTaskSessionAdapter,startTaskSessionWithPrompt:startTaskSessionWithPromptAdapter,tearDownTaskSession:tearDownTaskSessionAdapter,async readEngineContextUsage(vendor,sessionId){let read=engineEntry(vendor).history.readUsageSnapshot;if(!read)return null;let snapshot=await read(sessionId);if(snapshot?.context_tokens===void 0)return null;return{contextTokens:snapshot.context_tokens,...snapshot.context_window_tokens===void 0?{}:{contextWindowTokens:snapshot.context_window_tokens},...snapshot.context_tokens_approximate?{approximate:!0}:{},...snapshot.input_tokens===void 0?{}:{inputTokens:snapshot.input_tokens},...snapshot.output_tokens===void 0?{}:{outputTokens:snapshot.output_tokens},...snapshot.cache_read_input_tokens===void 0?{}:{cacheReadTokens:snapshot.cache_read_input_tokens},...snapshot.cache_creation_input_tokens===void 0?{}:{cacheCreationTokens:snapshot.cache_creation_input_tokens}}},quotaUsage:(vendor)=>engineEntry(vendor).quotaUsage?.()??Promise.resolve(null),vendorsWithQuotaProbe,deliverPromptToLiveEngine:deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailed:deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailed:deliverPromptToLiveEngineTabDetailedAdapter,deliveryGuard,getPersistedString,setPersistedString,getSavedRepos:()=>[...getSavedRepos()],prStatus:{viewFields:GH_PR_VIEW_FIELDS,mapView:(view,at)=>mapGhPrView(view,at),sameStatus:samePrStatus,nextPoll:(outcome,failures,now,config,random)=>nextPrPoll(outcome,failures,now,config,random),classify:classifyGhFailure}};import{homedir}from"os";async function createKobeCore(options={}){let homeDir=options.homeDir??readRoveHomeDirEnv()??homedir(),store=new TaskIndexStore({homeDir});await store.load();let worktrees=new GitWorktreeManager,orchestrator=new Orchestrator({store,worktrees,onSalvage:(taskId,salvage)=>auditDeletionSalvaged(String(taskId),salvage.ref,salvage.commit,store.get(taskId)?.repo,salvage.uncaptured),onWorktreeResidue:(taskId,residue)=>auditDeletionResidue(String(taskId),residue.path,residue.reason),onBranchKept:(taskId,kept)=>auditDeletionBranchKept(String(taskId),kept.branch,kept.reason),tearDownSession:(taskId)=>tearDownTaskSessionAdapter(String(taskId))}),backfilled=backfillSavedReposFromProjects(store.list().filter((task)=>task.kind==="main").map((task)=>task.repo));if(backfilled.length>0)console.error(`[rove] added ${backfilled.length} existing project(s) to the new-task picker`);return{homeDir,orchestrator,store,worktrees,async close(){orchestrator.dispose()}}}import{existsSync,readFileSync as readFileSync2,readdirSync,statSync as statSync2,unlinkSync}from"fs";import{join as join2}from"path";var TMP_MAX_AGE_MS=300000;function sweepIndexLeftovers(stateDir,now=Date.now()){let tmp=[],tmpBytes=0,entries;try{entries=readdirSync(stateDir)}catch{return{tmp,tmpBytes,lock:!1}}for(let name of entries){if(!name.startsWith("tasks.json.")||!name.endsWith(".tmp"))continue;let path=join2(stateDir,name);try{let stat=statSync2(path);if(now-stat.mtimeMs<TMP_MAX_AGE_MS)continue;unlinkSync(path),tmp.push(path),tmpBytes+=stat.size}catch{}}return{tmp,tmpBytes,lock:clearStaleLock(join2(stateDir,"tasks.json.lock"))}}function clearStaleLock(lockPath){let holder;try{holder=readFileSync2(lockPath,"utf8").trim()}catch{return!1}let pid=Number.parseInt(holder,10);if(Number.isFinite(pid)&&pid>0&&isProcessAlive(pid))return!1;return releaseSync(lockPath,holder),!existsSync(lockPath)}var CLI_NAME=activeCliName();function printDaemonUsage(out){out.write([`Usage: ${CLI_NAME} daemon <command>`,"","Commands:"," status Print the running daemon's status JSON (default)"," start Run the daemon in the foreground (this process becomes it)"," stop Ask the running daemon to shut down"," restart Stop the daemon (graceful \u2192 SIGTERM \u2192 SIGKILL) and respawn it",""].join(`
|
|
7
7
|
`))}async function runDaemonSubcommand(argv){let[command="status"]=argv,socketPath=defaultDaemonSocketPath(),pidPath=defaultDaemonPidPath();if(command==="--help"||command==="-h"||command==="help"){printDaemonUsage(process.stdout);return}if(!SUBCOMMAND_VERBS.daemon.includes(command))process.stderr.write(`${CLI_NAME} daemon: unknown command "${command}"
|
|
8
8
|
|
|
9
9
|
`),printDaemonUsage(process.stderr),process.exit(2);if(command==="status"){let client=new KobeDaemonClient(socketPath);try{let status=await client.request("daemon.status");console.log(JSON.stringify(status,null,2))}catch{let pid=await readPidFile(pidPath);if(pid)console.log(`${CLI_NAME} daemon: no daemon socket at ${socketPath} (stale pidfile pid=${pid})`);else console.log(`${CLI_NAME} daemon: no daemon running at ${socketPath}`);process.exitCode=1}finally{client.close()}return}if(command==="stop"){let client=new KobeDaemonClient(socketPath);try{await client.request("daemon.stop"),console.log(`${CLI_NAME} daemon: stop requested`)}catch{console.log(`${CLI_NAME} daemon: no daemon running at ${socketPath}`)}finally{client.close()}return}if(command==="restart"){await stopDaemonProcess(socketPath,pidPath),(await connectOrStartDaemon()).close(),console.log(`${CLI_NAME} daemon: restarted, listening on ${socketPath}`);return}rotateLogIfNeeded(defaultDaemonLogPath()),installDaemonCrashHandlers();let core,server=await startDaemonServer(async()=>{let migration=migrateRoveDaemonStateLayout();for(let warning of migration.warnings)console.error(`[rove] daemon state migration will retry: ${warning}`);core=await createKobeCore();let swept=sweepIndexLeftovers(core.store.stateDir);if(swept.lock||swept.tmp.length>0)console.error(`[rove] swept crash leftovers in ${core.store.stateDir}: ${swept.tmp.length} orphaned staging file(s) (${swept.tmpBytes} bytes)${swept.lock?", stale task-index lockfile":""}`);return core.orchestrator},{runtime:daemonRuntime,socketPath,pidPath,plugins:{binPath:resolvePluginBinPath()},onStop:async()=>{await core?.close()}});console.log(`${CLI_NAME} daemon: listening on ${server.socketPath}`);let shutdown=async()=>{await server.close(),process.exit(0)};process.once("SIGINT",()=>void shutdown()),process.once("SIGTERM",()=>void shutdown())}export{runDaemonSubcommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import{engineEntry,identifiableEngineIds}from"./chunk-4gjr08g0.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
|
-
`)){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
|
|
4
|
-
export{vendorFromArgv,parsePsSnapshot,hasAncestor,foregroundEngineIn,engineProcessIn,psSnapshot,foregroundEngine};
|
|
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 PS_PROBE_TIMEOUT_MS=5000;class PsProbeUnavailableError extends Error{constructor(reason){super(`process probe unavailable: ${reason}`);this.name="PsProbeUnavailableError"}}var bunPsSpawn=()=>{let proc=Bun.spawn(["ps","-A","-o","pid=,ppid=,args="],{stdout:"pipe",stderr:"ignore"});return{text:new Response(proc.stdout).text(),kill:()=>proc.kill()}};async function psSnapshotWith(spawn,timeoutMs=PS_PROBE_TIMEOUT_MS){let proc=spawn(),timer;try{return await Promise.race([proc.text,new Promise((_resolve,reject)=>{timer=setTimeout(()=>{try{proc.kill()}catch{}reject(new PsProbeUnavailableError(`ps did not answer within ${timeoutMs}ms`))},timeoutMs)})])}finally{if(timer)clearTimeout(timer)}}var psSnapshot=()=>psSnapshotWith(bunPsSpawn);async function foregroundEngine(rootPid,snapshot=psSnapshot){try{return foregroundEngineIn(parsePsSnapshot(await snapshot()),rootPid)}catch{return null}}
|
|
4
|
+
export{vendorFromArgv,parsePsSnapshot,hasAncestor,foregroundEngineIn,engineProcessIn,PS_PROBE_TIMEOUT_MS,PsProbeUnavailableError,psSnapshotWith,psSnapshot,foregroundEngine};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{isDev}from"./chunk-ch9b1d5y.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.
|
|
2
|
+
import{isDev}from"./chunk-ch9b1d5y.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.159",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.KOBE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
|
|
3
3
|
export{package_default,CURRENT_VERSION,PACKAGE_NAME,repoSlug,UPDATE_SCRIPT_URL,UPDATE_COMMAND,owningNpmPrefix,recommendedGlobalInstallCommand,BREAKING_VERSIONS,breakingVersionsCrossed,RELEASE_CHANNELS,DEFAULT_RELEASE_CHANNEL,channelOf,isNewerSemver,compareSemver,checkLatestVersion,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,releasePageUrl};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-
|
|
2
|
+
import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-wk7f8ns5.js";import{ensurePluginEnginesLoaded}from"./chunk-ntt7gy5a.js";import{openDaemonSession}from"./chunk-1aqmmea7.js";import"./chunk-dxcwhdsx.js";import"./chunk-3e5n28t6.js";import"./chunk-r05r01nv.js";import"./chunk-6pt23vas.js";import"./chunk-r2pztgm6.js";import"./chunk-38272eqv.js";import"./chunk-5f80ggc3.js";import"./chunk-qkehg2c1.js";import"./chunk-kkc2vejt.js";import"./chunk-msr1xtay.js";import{ApiError,splitDaemonCode}from"./chunk-tb6b5zx4.js";import"./chunk-9m0tb44t.js";import"./chunk-wt8dc57p.js";import"./chunk-ds9qf1w1.js";import"./chunk-bkba9c4n.js";import"./chunk-g2advs8t.js";import"./chunk-wdhcrcre.js";import"./chunk-xxmyqw1v.js";import"./chunk-7q67dz4c.js";import"./chunk-1cjd7h8p.js";import"./chunk-b99tf0jr.js";import"./chunk-t27t2x9b.js";import"./chunk-hape5vwj.js";import"./chunk-de751t37.js";import"./chunk-ynknvkrw.js";import"./chunk-9wn8m2rt.js";import"./chunk-w06vgba4.js";import"./chunk-sdyzxayr.js";import"./chunk-zqfbyq0a.js";import"./chunk-jvxh93nz.js";import"./chunk-4502n1bk.js";import"./chunk-nm0pq5r6.js";import"./chunk-mqqnk8w7.js";import"./chunk-0wnfq5sx.js";import"./chunk-7j5372wb.js";import"./chunk-mnqxgvyb.js";import"./chunk-hfdxy3qe.js";import"./chunk-4gjr08g0.js";import"./chunk-sfv15era.js";import"./chunk-w7zv47mp.js";import"./chunk-gwcneg6c.js";import"./chunk-25hxhtdr.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import"./chunk-kt1ppyje.js";import"./chunk-5v893waj.js";import"./chunk-axfn4f28.js";import"./chunk-xy8be792.js";import"./chunk-a3a9gdc4.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-3wj69b0a.js";import"./chunk-ch9b1d5y.js";import"./chunk-bq3fyc0p.js";import"./chunk-p7s4xwgx.js";import"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-k2ckx8zw.js";import"./chunk-pw6yfj10.js";import"./chunk-rxvbm4vt.js";import"./chunk-mcdv19rs.js";import"./chunk-r3k9rbwm.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 USAGE_ERROR_CODES=new Set(["BAD_VERB","UNKNOWN_VERB","BAD_FLAG","MISSING_FLAG","MISSING_VERB","BAD_DAEMON"]);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,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{checkOnboardingEnv,noEngineAction}from"./chunk-
|
|
2
|
+
import{checkOnboardingEnv,noEngineAction}from"./chunk-g8r9zv1x.js";import{isNpxMissing,markSkillHintSeen,npxSkillsArgv,npxSkillsCommand}from"./chunk-g90z5s39.js";import{LAST_RUN_VERSION_KEY}from"./chunk-es4985my.js";import{t}from"./chunk-9wn8m2rt.js";import{getPersistedBool,loadStateFile,setPersistedBool}from"./chunk-5v893waj.js";import{activeCliName}from"./chunk-p7s4xwgx.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{appendFileSync,existsSync,mkdirSync,readFileSync,writeFileSync}from"fs";import{homedir}from"os";import{basename,join}from"path";var ONBOARDED_KEY="onboarded",PRIMER_KEY="onboardedPrimer";function detectShell(env=process.env){let shell=basename(env.SHELL??"");return shell==="zsh"||shell==="bash"||shell==="fish"?shell:null}function installCompletions(shell,home=homedir(),cli=activeCliName()){let rcMarker=`${cli} completions`;if(shell==="fish"){let dir=join(home,".config","fish","completions"),path=join(dir,`${cli}.fish`);return mkdirSync(dir,{recursive:!0}),writeFileSync(path,`${cli} completions fish | source
|
|
3
3
|
`),path}let rc=join(home,shell==="zsh"?".zshrc":".bashrc");if(!(existsSync(rc)?readFileSync(rc,"utf8"):"").includes(rcMarker)){let line=`
|
|
4
4
|
# ${cli} completions
|
|
5
5
|
command -v ${cli} >/dev/null && source <(${cli} completions ${shell})
|
|
6
6
|
`;appendFileSync(rc,line)}return rc}function isOnboarded(){return getPersistedBool(ONBOARDED_KEY,!1)}function markOnboarded(){setPersistedBool(ONBOARDED_KEY,!0)}function isPrimerDone(){return getPersistedBool(PRIMER_KEY,!1)}function markPrimerDone(){setPersistedBool(PRIMER_KEY,!0)}function backfillPrimerForExistingUsers(){if(typeof loadStateFile()[LAST_RUN_VERSION_KEY]!=="string")return!1;return markPrimerDone(),!0}function envReadyForTasks(env){return env.engines.anyUsable&&env.git.found}function applyOnboardingChoices(choices,shell,env){let cli=activeCliName(),completionsHelp=`${cli} completions --help`,skillInstall=`${cli} skill install`,out=(line)=>process.stdout.write(`${line}
|
|
7
|
-
`);if(shell!==null)if(choices.completions)out(t("onboarding.appliedCompletions",{path:installCompletions(shell)}));else out(t("onboarding.skippedCompletions",{command:completionsHelp}));if(choices.skill){if(isNpxMissing())out(t("onboarding.skillNeedsNode",{command:skillInstall}));else if(out(t("onboarding.installingSkill",{command:npxSkillsCommand()})),spawnSync("npx",npxSkillsArgv(),{stdio:"inherit"}).status!==0)out(t("onboarding.skillFailed",{command:skillInstall}))}else out(t("onboarding.skippedSkill",{command:skillInstall})),markSkillHintSeen();out(""),out(env.git.line);for(let line of env.engines.lines)out(line);if(out(""),envReadyForTasks(env))out(t("onboarding.ready")),out(t("onboarding.readyHint",{command:cli}));else{if(out(t("onboarding.notReadyHeader")),!env.engines.anyUsable)out(` \u2192 ${noEngineAction(env.engines.signedOut)}`);if(!env.git.found)out(` \u2192 ${t("doctor.fix.gitAction")}`)}}async function maybeRunOnboarding(){if(!process.stdout.isTTY||!process.stdin.isTTY)return!1;let seen=isOnboarded();if(seen&&(isPrimerDone()||backfillPrimerForExistingUsers()))return!1;markOnboarded();let shell=detectShell(),env=await checkOnboardingEnv(),{runOnboardingWizard}=await import("./chunk-
|
|
7
|
+
`);if(shell!==null)if(choices.completions)out(t("onboarding.appliedCompletions",{path:installCompletions(shell)}));else out(t("onboarding.skippedCompletions",{command:completionsHelp}));if(choices.skill){if(isNpxMissing())out(t("onboarding.skillNeedsNode",{command:skillInstall}));else if(out(t("onboarding.installingSkill",{command:npxSkillsCommand()})),spawnSync("npx",npxSkillsArgv(),{stdio:"inherit"}).status!==0)out(t("onboarding.skillFailed",{command:skillInstall}))}else out(t("onboarding.skippedSkill",{command:skillInstall})),markSkillHintSeen();out(""),out(env.git.line);for(let line of env.engines.lines)out(line);if(out(""),envReadyForTasks(env))out(t("onboarding.ready")),out(t("onboarding.readyHint",{command:cli}));else{if(out(t("onboarding.notReadyHeader")),!env.engines.anyUsable)out(` \u2192 ${noEngineAction(env.engines.signedOut)}`);if(!env.git.found)out(` \u2192 ${t("doctor.fix.gitAction")}`)}}async function maybeRunOnboarding(){if(!process.stdout.isTTY||!process.stdin.isTTY)return!1;let seen=isOnboarded();if(seen&&(isPrimerDone()||backfillPrimerForExistingUsers()))return!1;markOnboarded();let shell=detectShell(),env=await checkOnboardingEnv(),{runOnboardingWizard}=await import("./chunk-dqxzpetd.js"),choices=await runOnboardingWizard(shell,env,seen?"primer":"full");return markPrimerDone(),applyOnboardingChoices(choices,shell,env),!0}
|
|
8
8
|
export{detectShell,installCompletions,envReadyForTasks,applyOnboardingChoices,maybeRunOnboarding};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{SUBCOMMAND_VERBS,TOP_LEVEL_SUBCOMMANDS}from"./chunk-s76r56rj.js";import{activeCliName}from"./chunk-p7s4xwgx.js";import"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-r3k9rbwm.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-p7s4xwgx.js";import"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-r3k9rbwm.js";import{__require}from"./chunk-wqfp8d9w.js";async function collectSubVerbs(){let{API_VERBS}=await import("./chunk-e5f9rdj2.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{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-
|
|
2
|
+
import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-kkc2vejt.js";import"./chunk-ch9b1d5y.js";import{activeCliName}from"./chunk-p7s4xwgx.js";import"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-r3k9rbwm.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:"sh",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
|
|
|
@@ -9,7 +9,7 @@ import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNEL
|
|
|
9
9
|
`)}io.stdout.write(`
|
|
10
10
|
install one with: ${CLI_NAME} update <version>
|
|
11
11
|
`)}async function warnBreakingCrossings(target,channel,io){if(BREAKING_VERSIONS.length===0)return;let resolved=target??(await checkLatestVersion({force:!0,channel}))?.latest;if(!resolved)return;let crossed=breakingVersionsCrossed(CURRENT_VERSION,resolved);if(crossed.length===0)return;io.stderr.write([`warning: ${CURRENT_VERSION} -> ${resolved} crosses breaking version(s): ${crossed.join(", ")}.`,`After this update, Rove will refuse to start until you run \`${CLI_NAME} reset\``,"(worktrees are never touched; add --hard only to also wipe the task index).",""].join(`
|
|
12
|
-
`))}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-
|
|
12
|
+
`))}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-0f377y88.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
13
|
`),switching)io.stdout.write(`switching channel: ${channelOf()} -> ${channel}
|
|
14
14
|
`);if(io.stdout.write(`running: ${plan.display}
|
|
15
15
|
`),parsed.dryRun)return;await warnBreakingCrossings(parsed.version,channel,io);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{writeOutdatedCache}from"./chunk-n4nntq73.js";import{PluginCliError,installPlugin}from"./chunk-
|
|
2
|
+
import{writeOutdatedCache}from"./chunk-n4nntq73.js";import{PluginCliError,installPlugin}from"./chunk-svndhd3d.js";import{loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginDataDir,pluginStateDir,removePluginEntry,savePluginRegistry}from"./chunk-38272eqv.js";import"./chunk-kkc2vejt.js";import"./chunk-mnqxgvyb.js";import"./chunk-w7zv47mp.js";import"./chunk-ch9b1d5y.js";import{activeCliName}from"./chunk-p7s4xwgx.js";import"./chunk-4pmd0mxp.js";import"./chunk-g56kvet6.js";import"./chunk-r3k9rbwm.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};
|