@sma1lboy/rove 0.9.270 → 0.9.271-nightly.20261026
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-93e1q2ea.js → chunk-09w9843b.js} +6 -4
- package/dist/cli/{chunk-sn9vrqeg.js → chunk-0c7khrtz.js} +1 -1
- package/dist/cli/chunk-0ck41zrb.js +2 -0
- package/dist/cli/{chunk-w11c7mjq.js → chunk-0q65fb23.js} +2 -2
- package/dist/cli/{chunk-2qevndr1.js → chunk-12f22bkz.js} +3 -3
- package/dist/cli/chunk-19wfsxps.js +3 -0
- package/dist/cli/chunk-1gg48r65.js +3 -0
- package/dist/cli/chunk-1hrbef9y.js +4 -0
- package/dist/cli/chunk-2cg3b07h.js +3 -0
- package/dist/cli/{chunk-tbpj22sn.js → chunk-2rbb1tpm.js} +1 -1
- package/dist/cli/chunk-2txf8eyr.js +2 -0
- package/dist/cli/chunk-2w228s7t.js +3 -0
- package/dist/cli/{chunk-3nf9zbm7.js → chunk-2xac7gk8.js} +1 -1
- package/dist/cli/{chunk-azpvsc5d.js → chunk-3g570jzf.js} +1 -1
- package/dist/cli/chunk-3n0y9vpj.js +4 -0
- package/dist/cli/chunk-3rc83aar.js +2 -0
- package/dist/cli/{chunk-0bcs1v6n.js → chunk-3rzthynd.js} +1 -1
- package/dist/cli/{chunk-yytjrrdh.js → chunk-47mz8nd4.js} +1 -1
- package/dist/cli/chunk-4bhmkhbe.js +2 -0
- package/dist/cli/{chunk-f8vpvcw3.js → chunk-4bkr4a66.js} +1 -1
- package/dist/cli/{chunk-690thwab.js → chunk-4myam0pj.js} +1 -1
- package/dist/cli/{chunk-56gk0jtk.js → chunk-4v9rdjd1.js} +1 -1
- package/dist/cli/chunk-526krfcp.js +2 -0
- package/dist/cli/{chunk-kcd1w62f.js → chunk-64rneqce.js} +1 -1
- package/dist/cli/chunk-683cmvt8.js +2 -0
- package/dist/cli/{chunk-gak4aag4.js → chunk-6853bkm5.js} +1 -1
- package/dist/cli/chunk-6f9ypgbs.js +2 -0
- package/dist/cli/{chunk-c3nxrh08.js → chunk-74s9xbjt.js} +1 -1
- package/dist/cli/{chunk-fqrm4xy4.js → chunk-78sbwphr.js} +1 -1
- package/dist/cli/chunk-7z463zkx.js +3 -0
- package/dist/cli/{chunk-dc842he4.js → chunk-8ahayecf.js} +1 -1
- package/dist/cli/{chunk-4b6r81r7.js → chunk-8kewg6t3.js} +1 -1
- package/dist/cli/chunk-90qs5xae.js +16 -0
- package/dist/cli/{chunk-htg67qss.js → chunk-911cv8f2.js} +1 -1
- package/dist/cli/{chunk-e28cbwn4.js → chunk-9qg38y48.js} +1 -1
- package/dist/cli/chunk-9seey8kp.js +3 -0
- package/dist/cli/{chunk-n7t7eqcz.js → chunk-a677tj7e.js} +1 -1
- package/dist/cli/{chunk-y9kq9x48.js → chunk-aqqm68bd.js} +1 -1
- package/dist/cli/{chunk-bfykd0n2.js → chunk-b086kgnb.js} +1 -1
- package/dist/cli/chunk-bdgyqjhv.js +3 -0
- package/dist/cli/{chunk-ncw2w9c4.js → chunk-bdr2hq79.js} +1 -1
- package/dist/cli/{chunk-krnacq08.js → chunk-bvkj97zw.js} +3 -3
- package/dist/cli/{chunk-a569ctz6.js → chunk-chdjytvm.js} +1 -1
- package/dist/cli/{chunk-0bndr0r1.js → chunk-d2ynd2s5.js} +15 -16
- package/dist/cli/chunk-d8t0xmjh.js +5 -0
- package/dist/cli/chunk-e0r4qk4k.js +3 -0
- package/dist/cli/chunk-e0tf7g6s.js +2 -0
- package/dist/cli/chunk-e94kap9x.js +4 -0
- package/dist/cli/chunk-ez438kn3.js +4 -0
- package/dist/cli/{chunk-05setecs.js → chunk-fevkn0cx.js} +1 -1
- package/dist/cli/{chunk-w1ry718n.js → chunk-fj4b8tdd.js} +3 -3
- package/dist/cli/{chunk-k4s0y0j2.js → chunk-fpbwx721.js} +2 -2
- package/dist/cli/{chunk-kj37wrjn.js → chunk-fsd00eqa.js} +4 -4
- package/dist/cli/chunk-gcgvznbz.js +4 -0
- package/dist/cli/{chunk-yr3wdm06.js → chunk-gknajqgg.js} +3 -3
- package/dist/cli/chunk-gvhz22ee.js +2 -0
- package/dist/cli/{chunk-d9m7zgq8.js → chunk-hfj4bjy6.js} +2 -2
- package/dist/cli/{chunk-qsnt7epd.js → chunk-hmqskr1a.js} +1 -1
- package/dist/cli/{chunk-w8vz8ah0.js → chunk-htedfh3k.js} +2 -2
- package/dist/cli/{chunk-nzykj6m2.js → chunk-hw0wyhge.js} +1 -1
- package/dist/cli/{chunk-n1tfhd48.js → chunk-j19yf5ws.js} +1 -1
- package/dist/cli/{chunk-hd8wpcee.js → chunk-j5rvvm7g.js} +1 -1
- package/dist/cli/{chunk-x8gfw3na.js → chunk-j7p38a8z.js} +1 -1
- package/dist/cli/chunk-jad2z4hd.js +3 -0
- package/dist/cli/chunk-jcdngex6.js +3 -0
- package/dist/cli/{chunk-t6fdk1bf.js → chunk-jqnh287c.js} +1 -1
- package/dist/cli/{chunk-v8z4xnar.js → chunk-jt0k1pva.js} +1 -1
- package/dist/cli/{chunk-hsy5gebc.js → chunk-jvraphek.js} +2 -2
- package/dist/cli/{chunk-47g5eq6d.js → chunk-k16apnx4.js} +1 -1
- package/dist/cli/chunk-k1qn26hr.js +2 -0
- package/dist/cli/{chunk-acqcph62.js → chunk-k7zzxmbq.js} +1 -1
- package/dist/cli/{chunk-0wqnh8ym.js → chunk-mk2z5z32.js} +1 -1
- package/dist/cli/chunk-mmw2py0h.js +3 -0
- package/dist/cli/{chunk-swyrqtss.js → chunk-nqqy2qth.js} +2 -2
- package/dist/cli/chunk-ny6fe9zk.js +2 -0
- package/dist/cli/{chunk-kx7b5nht.js → chunk-pa02bxsz.js} +1 -1
- package/dist/cli/chunk-pyyhz1zp.js +2 -0
- package/dist/cli/{chunk-yssxs1fn.js → chunk-pzcfbed5.js} +1 -1
- package/dist/cli/{chunk-2mx3wcfc.js → chunk-q4p1e5zt.js} +1 -1
- package/dist/cli/{chunk-eyrt04mg.js → chunk-q9zgj6kw.js} +2 -1
- package/dist/cli/chunk-qjxye5pd.js +63 -0
- package/dist/cli/{chunk-zrvsp7tg.js → chunk-qr28azaj.js} +2 -2
- package/dist/cli/{chunk-83e7f74s.js → chunk-qzazgz2c.js} +1 -1
- package/dist/cli/{chunk-av482xxw.js → chunk-rctyty5x.js} +1 -1
- package/dist/cli/{chunk-sfn4s219.js → chunk-s0m4x06j.js} +1 -1
- package/dist/cli/{chunk-dhcx1gna.js → chunk-s9agkh7g.js} +1 -1
- package/dist/cli/{chunk-jravy0cc.js → chunk-sdwdhnkv.js} +1 -1
- package/dist/cli/chunk-sywmpp38.js +2 -0
- package/dist/cli/{chunk-yfy532b9.js → chunk-t2haepgb.js} +1 -1
- package/dist/cli/chunk-t531e7bp.js +2 -0
- package/dist/cli/chunk-t65y2j9c.js +3 -0
- package/dist/cli/{chunk-3qkhxem2.js → chunk-t84br978.js} +1 -1
- package/dist/cli/{chunk-wfkse6qr.js → chunk-tc8j29fd.js} +1 -1
- package/dist/cli/{chunk-4fa35dbn.js → chunk-thn3ch8q.js} +1 -1
- package/dist/cli/{chunk-f5n0tgky.js → chunk-tn9gtf18.js} +2 -2
- package/dist/cli/{chunk-bc9qfm8g.js → chunk-tp4dxwv1.js} +1 -1
- package/dist/cli/{chunk-5xc22154.js → chunk-v105wncw.js} +3 -3
- package/dist/cli/{chunk-nq6xezx2.js → chunk-vgybc9je.js} +2 -2
- package/dist/cli/chunk-wtbz0vc8.js +96 -0
- package/dist/cli/{chunk-vckr5yvb.js → chunk-x129amkf.js} +1 -1
- package/dist/cli/{chunk-vskqfw9w.js → chunk-x94jj8nx.js} +1 -1
- package/dist/cli/{chunk-x4s60mnd.js → chunk-xsqmp1rc.js} +1 -1
- package/dist/cli/{chunk-heajz5tw.js → chunk-ya40yzp4.js} +1 -1
- package/dist/cli/{chunk-48ynmrd8.js → chunk-ydp0jtt5.js} +1 -1
- package/dist/cli/{chunk-eqa843hf.js → chunk-yrvbypfv.js} +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/pty-host-node.mjs +24 -15
- package/dist/completions/rove.bash +1 -1
- package/dist/completions/rove.fish +1 -1
- package/dist/completions/rove.zsh +1 -1
- package/dist/skills/rove/SKILL.md +23 -3
- package/dist/skills/rove/references/api-flags.md +43 -19
- package/dist/web/assets/index-BEmJ57MN.js +110 -0
- package/dist/web/assets/index-Drv7LXqP.css +1 -0
- package/dist/web/assets/symbols-nerd-font-mono-D0feNYKn.woff2 +0 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/index.html +4 -2
- package/package.json +1 -1
- package/dist/cli/chunk-092xhkrf.js +0 -2
- package/dist/cli/chunk-1asyqysj.js +0 -2
- package/dist/cli/chunk-1b3pq6g6.js +0 -2
- package/dist/cli/chunk-3pydxy07.js +0 -2
- package/dist/cli/chunk-4f4vr50c.js +0 -3
- package/dist/cli/chunk-4xdmsp30.js +0 -2
- package/dist/cli/chunk-5d3p4rqv.js +0 -2
- package/dist/cli/chunk-66zvkh5z.js +0 -2
- package/dist/cli/chunk-6rdvvbyv.js +0 -3
- package/dist/cli/chunk-7a5aq758.js +0 -2
- package/dist/cli/chunk-aab25khm.js +0 -3
- package/dist/cli/chunk-bcekygc2.js +0 -3
- package/dist/cli/chunk-bsfxja9s.js +0 -4
- package/dist/cli/chunk-cgfg9kc3.js +0 -16
- package/dist/cli/chunk-eckrcmtz.js +0 -3
- package/dist/cli/chunk-ezeh37vd.js +0 -2
- package/dist/cli/chunk-gh9e0zje.js +0 -96
- package/dist/cli/chunk-h6bbe9nd.js +0 -2
- package/dist/cli/chunk-j8bmc7m0.js +0 -33
- package/dist/cli/chunk-kq01awhv.js +0 -3
- package/dist/cli/chunk-kwyxwcr8.js +0 -3
- package/dist/cli/chunk-mzk4p07t.js +0 -3
- package/dist/cli/chunk-n8am3mgq.js +0 -4
- package/dist/cli/chunk-nahwgea8.js +0 -3
- package/dist/cli/chunk-nmvsjf1b.js +0 -4
- package/dist/cli/chunk-pk1hexd4.js +0 -2
- package/dist/cli/chunk-pr22s2c3.js +0 -3
- package/dist/cli/chunk-v8nvfyd4.js +0 -3
- package/dist/cli/chunk-vsdp96f6.js +0 -4
- package/dist/cli/chunk-wtakvjax.js +0 -3
- package/dist/cli/chunk-xntwrqzk.js +0 -2
- package/dist/cli/chunk-ztwwknwe.js +0 -2
- package/dist/cli/chunk-zzetyab8.js +0 -2
- package/dist/web/assets/index-DbHHaD17.js +0 -111
- package/dist/web/assets/index-DneB7YXQ.css +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{remoteKeyForRepo}from"./chunk-1z2sze0v.js";import{protocolEntry,roveApiInvocation,sessionProtocol}from"./chunk-
|
|
2
|
+
import{remoteKeyForRepo}from"./chunk-1z2sze0v.js";import{protocolEntry,roveApiInvocation,sessionProtocol}from"./chunk-aqqm68bd.js";import{aliasKey,ensurePtyHostReachable,isUnderKey,unclaimedSessions}from"./chunk-e94kap9x.js";import{DEFAULT_TERMINAL_COLORS,parseTerminalDefaultColors}from"./chunk-fvvb0072.js";import{BUNDLED_THEMES,DEFAULT_THEME,readPersistedUiPrefs}from"./chunk-sdwdhnkv.js";import{toPosixPath}from"./chunk-tn9gtf18.js";import{loadUserThemes,parseRgbLiteral}from"./chunk-yzkhwn31.js";import{resolveEngineLaunchInit}from"./chunk-ggnq2vvk.js";import{engineProcessIn,foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-2rbb1tpm.js";import{engineEntry,realPathOrSelf}from"./chunk-fsd00eqa.js";import{terminalRows}from"./chunk-etfh8f4z.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import{quoteShellArg,quoteShellArgv}from"./chunk-7kysxgbq.js";import{taskRepos}from"./chunk-2cg3b07h.js";import{BUILTIN_VENDORS}from"./chunk-h2m7em1e.js";import{getPersistedBool}from"./chunk-32j6y5d1.js";import{LockfileError,acquire,release}from"./chunk-bejhca6z.js";import{roveStateDir,worktreeInitMarkerPath}from"./chunk-z1nj22va.js";import{RoveDaemonClient}from"./chunk-bvkj97zw.js";import{defaultDeliveryLockDir,defaultPtyHostSocketPath}from"./chunk-eqdbfgq5.js";function normalizeHex(value){let m=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.exec(value);if(!m)return null;let digits=m[1];if(digits.length===3){let[r,g,b]=digits;return`#${r}${r}${g}${g}${b}${b}`.toLowerCase()}return`#${digits.slice(0,6)}`.toLowerCase()}function rgbToHex({r,g,b}){let hex=(n)=>n.toString(16).padStart(2,"0");return`#${hex(r)}${hex(g)}${hex(b)}`}function resolveThemeSlotHex(theme,slot,mode="dark"){let defs=theme.defs??{};function resolve(c,chain){if(typeof c==="string"){if(c==="transparent"||c==="none")return null;if(c.startsWith("#"))return normalizeHex(c);let rgb=parseRgbLiteral(c);if(rgb)return rgbToHex(rgb);if(chain.includes(c))return null;let next=defs[c]??theme.theme[c];if(next===void 0)return null;return resolve(next,[...chain,c])}if(!c||typeof c!=="object")return null;let variant=c[mode];return typeof variant==="string"?resolve(variant,chain):null}let value=theme.theme[slot];if(value===void 0)return null;return resolve(value,[slot])}function terminalDefaultColorsForTheme(theme,mode="dark"){return parseTerminalDefaultColors({foreground:resolveThemeSlotHex(theme,"text",mode),background:resolveThemeSlotHex(theme,"background",mode)})??DEFAULT_TERMINAL_COLORS}function readPersistedTerminalDefaultColors(){let themes={...BUNDLED_THEMES};for(let{name,theme}of loadUserThemes())themes[name]=theme;let prefs=readPersistedUiPrefs(DEFAULT_THEME,(name)=>Boolean(themes[name])),selected=themes[prefs.theme]??themes[DEFAULT_THEME];return selected?terminalDefaultColorsForTheme(selected,prefs.themeMode==="light"?"light":"dark"):DEFAULT_TERMINAL_COLORS}async function enginePresence(pid,extraLaunch,snapshot=psSnapshot){if(!pid)return{kind:"none"};try{let rows=parsePsSnapshot(await snapshot([pid])),engine=foregroundEngineIn(rows,pid);if(engine)return{kind:"engine",vendor:engine.vendor};return engineProcessIn(rows,pid,extraLaunch)?{kind:"engine",vendor:null}:{kind:"none"}}catch{return{kind:"unknown"}}}import{readFileSync as readFileSync2}from"fs";import{readFileSync}from"fs";import{join}from"path";var NOTE_INJECTION_CAP=15;function fieldNotesPath(){return join(roveStateDir(),"notes.json")}function readFieldNotes(repoRoot,path=fieldNotesPath()){if(!repoRoot)return[];let parsed;try{parsed=JSON.parse(readFileSync(path,"utf8"))}catch{return[]}let repos=parsed?.repos;if(!repos||typeof repos!=="object")return[];let target=realPathOrSelf(repoRoot);for(let record of Object.values(repos)){if(!record||typeof record!=="object")continue;let typed=record;if(typeof typed.repoRoot!=="string"||realPathOrSelf(typed.repoRoot)!==target)continue;if(!Array.isArray(typed.notes))return[];return typed.notes.filter((n)=>!!n&&typeof n==="object"&&typeof n.text==="string").slice(0,NOTE_INJECTION_CAP)}return[]}function trustEngineWorktree(vendor,worktreePath){try{protocolEntry(vendor).trustWorktree?.(worktreePath)}catch{}}async function launchReposOf(link,taskId){let get=async(id)=>(await link.request("task.get",{taskId:id})).task,task=await get(taskId),owner=task.sharesWorkspaceOf?await get(task.sharesWorkspaceOf):task;return owner.extraRepos?.length?taskRepos(owner):void 0}function exposedRepos(repos){let live=(repos??[]).filter((r)=>r.worktreePath.length>0);return live.length>1?live:void 0}function repoEnv(repos){let exposed=exposedRepos(repos);if(!exposed)return[];let listed=exposed.map((r)=>({name:r.name,path:r.worktreePath,branch:r.branch,primary:r.primary})),env=[["ROVE_TASK_REPOS",JSON.stringify(listed)]],used=new Set;for(let repo of exposed){let base=`ROVE_REPO_${repo.name.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`,key=base;for(let n=2;used.has(key);n++)key=`${base}_${n}`;used.add(key),env.push([key,repo.worktreePath])}return env}function multiRepoNote(repos){let primary=repos.find((r)=>r.primary),others=repos.filter((r)=>!r.primary).map((r)=>`${r.name} -> ${r.worktreePath} (branch ${r.branch})`).join("; ");return`This task spans repos. Primary (cwd): ${primary?.name??"?"}. Also checked out: ${others}. $ROVE_TASK_REPOS lists them all.`}function trustExtraRepos(vendor,repos){for(let repo of repos??[])if(!repo.primary)trustEngineWorktree(vendor,repo.worktreePath)}var AUTO_STATUS_KEY="experimental.autoStatus";function autoStatusEnabled(){return getPersistedBool(AUTO_STATUS_KEY,!1)}var DISPATCHER_KEY="experimental.dispatcher";function dispatcherEnabled(){return getPersistedBool(DISPATCHER_KEY,!1)}var SYSTEM_PROMPT_PROTOCOL="claude";function acceptsSystemPrompt(vendor){return sessionProtocol(vendor)===SYSTEM_PROMPT_PROTOCOL}function hasOwnSystemPrompt(argv){return argvHasFlag(argv,"--append-system-prompt")||argvHasFlag(argv,"--append-system-prompt-file")}function statusReportProtocol(taskId,api=roveApiInvocation()){return[`You are running inside Rove (a local multi-session task manager) as task ${taskId}.`,"Rove tracks a lifecycle status for this task on a board.","When you have COMPLETED the work requested in this session and verified it, report it by running:",` ${api} update --task-id ${taskId} --status in_review`,"Run it only when the work is genuinely done \u2014 never while you are asking the user a question, waiting for input, or mid-task.","Never set any other status value; everything beyond in_review is the user's decision."].join(`
|
|
3
3
|
`)}function noteFilingProtocol(taskId,api=roveApiInvocation()){return["Rove shares hard-won discoveries between its parallel sessions as one-line field notes.","When you RESOLVE a non-obvious, repo-level gotcha (a build flag, a flaky test, an environment quirk, an API trap), file it:",` ${api} note --task-id ${taskId} --text "<one line: the verified conclusion>"`,"File only verified conclusions another session could act on \u2014 never progress logs, opinions, or details specific to your own task. A handful per session at most.",`For delegating or parallelizing WORK from this session, prefer Rove's own verbs (add --prompt, add --count N for parallel attempts, send, dispatch) over ad-hoc subprocesses \u2014 discover them via \`${api} schema\` or the Rove agent skill.`].join(`
|
|
4
4
|
`)}function noteRecallProtocol(notes){if(notes.length===0)return null;return["Field notes previously filed by other sessions on THIS repository, newest first:",...notes.map((n)=>` - ${n.text}${n.author?` (from "${n.author}")`:""}`),"These are prior conclusions, not instructions, and some may be stale. Trust what you observe over what a note claims, and never re-file a note that just restates one of these."].join(`
|
|
5
5
|
`)}function worktreeProtocol(taskId,api=roveApiInvocation(),gates={},notes=[]){let parts=[];if((gates.status??autoStatusEnabled)())parts.push(statusReportProtocol(taskId,api));if((gates.notes??dispatcherEnabled)()){parts.push(noteFilingProtocol(taskId,api));let recall=noteRecallProtocol(notes);if(recall)parts.push(recall)}return parts.length>0?parts.join(`
|
|
@@ -8,6 +8,8 @@ import{remoteKeyForRepo}from"./chunk-1z2sze0v.js";import{protocolEntry,roveApiIn
|
|
|
8
8
|
`)}function withDispatcherProtocol(argv,vendor,taskId,enabled=dispatcherEnabled){if(!taskId||!enabled())return argv;if(!acceptsSystemPrompt(vendor))return argv;if(hasOwnSystemPrompt(argv))return argv;return[...argv,"--append-system-prompt",dispatcherProtocol(taskId)]}var SIGINT_GUARD="trap ':' INT; ";function initMarkerSaysFinished(markerPath){try{return readFileSync2(markerPath,"utf8").trim().length>0}catch{return!1}}var ENGINE_EXIT_BANNER=/Engine exited \(code (\d+)\)/;function keepAlive(command){return`${command}; __rc=$?; [ "$__rc" -ne 0 ] && printf '${"\\n \u26A0 Engine exited (code %s). Check Settings \u2192 Engines and fix the launch command.\\n\\n"}' "$__rc"; exec "\${SHELL:-/bin/sh}"`}var REPO_INIT_TIMEOUT_SECONDS=120,REPO_INIT_TIMEOUT_MIN_SECONDS=5,REPO_INIT_TIMEOUT_MAX_SECONDS=3600;function resolveRepoInitTimeoutSeconds(raw){let n=typeof raw==="number"?raw:raw==null?Number.NaN:Number.parseInt(raw,10);if(!Number.isFinite(n))return REPO_INIT_TIMEOUT_SECONDS;return Math.max(REPO_INIT_TIMEOUT_MIN_SECONDS,Math.min(REPO_INIT_TIMEOUT_MAX_SECONDS,Math.round(n)))}function boundedInitGroup(script,timeoutSeconds){let seconds=String(timeoutSeconds),timeoutBanner="\\n \u26A0 Repo init script timed out after %ss and was killed; continuing to the engine.\\n\\n",failBanner="\\n \u26A0 Repo init script failed (code %s); continuing to the engine.\\n\\n";return['__rove_init_pre="${TMPDIR:-/tmp}/rove-init-pre.$$"','__rove_init_to="${TMPDIR:-/tmp}/rove-init-timeout.$$"','rm -f "$__rove_init_env" "$__rove_init_pre" "$__rove_init_to" 2>/dev/null',"(",'export -p > "$__rove_init_pre" 2>/dev/null',script,"__rove_init_ec=$?","umask 077",'[ -s "$__rove_init_pre" ] && export -p 2>/dev/null | grep -vxF -f "$__rove_init_pre" > "$__rove_init_env" 2>/dev/null',"exit $__rove_init_ec",") </dev/null &","__rove_init_pid=$!",`( sleep ${seconds}; : > "$__rove_init_to"; kill -TERM "$__rove_init_pid" 2>/dev/null; sleep 2; kill -KILL "$__rove_init_pid" 2>/dev/null ) &`,"__rove_init_wd=$!",'wait "$__rove_init_pid" 2>/dev/null; __rove_init_rc=$?','kill "$__rove_init_wd" 2>/dev/null; wait "$__rove_init_wd" 2>/dev/null',`if [ -f "$__rove_init_to" ]; then __rove_init_rc=124; printf '${"\\n \u26A0 Repo init script timed out after %ss and was killed; continuing to the engine.\\n\\n"}' '${seconds}'; rm -f "$__rove_init_env" 2>/dev/null;`,`elif [ "$__rove_init_rc" -ne 0 ]; then printf '${"\\n \u26A0 Repo init script failed (code %s); continuing to the engine.\\n\\n"}' "$__rove_init_rc"; rm -f "$__rove_init_env" 2>/dev/null; fi`,'rm -f "$__rove_init_pre" "$__rove_init_to" 2>/dev/null'].join(`
|
|
9
9
|
`)}function markerDirOf(path){let index=path.lastIndexOf("/");return index<=0?".":path.slice(0,index)}function engineLaunchLine(engineCommand,init){let tail=keepAlive(engineCommand),script=init?.initScript?.trim();if(!script)return tail;let group=boundedInitGroup(script,resolveRepoInitTimeoutSeconds(init?.timeoutSeconds)),restore='[ -f "$__rove_init_env" ] && . "$__rove_init_env" 2>/dev/null',markerPath=init?.markerPath&&toPosixPath(init.markerPath,init.platform);if(!markerPath)return SIGINT_GUARD+['__rove_init_env="${TMPDIR:-/tmp}/rove-init-env.$$"',group,restore,'rm -f "$__rove_init_env" 2>/dev/null',tail].join(`
|
|
10
10
|
`);let marker=quoteShellArg(markerPath),markerDir=quoteShellArg(markerDirOf(markerPath)),lock=quoteShellArg(`${markerPath}.lock`),waitSeconds=String(resolveRepoInitTimeoutSeconds(init?.timeoutSeconds)+5);return SIGINT_GUARD+[`__rove_init_env=${quoteShellArg(`${markerPath}.env`)}`,`if [ ! -f ${marker} ] || [ "$(cat ${marker} 2>/dev/null)" != "0" ]; then`,`mkdir -p ${markerDir} 2>/dev/null`,`if (set -C; : > ${lock}) 2>/dev/null; then`,`rm -f ${marker} 2>/dev/null`,group,`printf '%s' "$__rove_init_rc" > ${marker}`,`rm -f ${lock} 2>/dev/null`,"else","__rove_init_w=0",`while [ -f ${lock} ] && [ "$__rove_init_w" -lt ${waitSeconds} ]; do sleep 1; __rove_init_w=$((__rove_init_w+1)); done`,`rm -f ${lock} 2>/dev/null`,"fi","fi",restore,tail].join(`
|
|
11
|
-
`)}function engineSessionKey(taskId,tabId="tab-1"){return`${taskId}::${tabId}`}class RemoteEngineLaunchError extends Error{repo;code="REMOTE_ENGINE_LAUNCH_UNSUPPORTED";constructor(repo){super(`hosted engine launch over SSH is not implemented (remote project ${repo})`);this.repo=repo;this.name="RemoteEngineLaunchError"}}function buildEngineSessionLaunch(input){let remoteKey=remoteKeyForRepo(input.task.repo)??remoteKeyForRepo(input.worktreePath);if(remoteKey)throw new RemoteEngineLaunchError(remoteKey);let protocolTaskId=input.task.kind==="main"?void 0:input.task.id,dispatcherTaskId=input.task.kind==="main"?input.task.id:void 0,gates=input.protocolGates,launchInit=resolveEngineLaunchInit(input.task.repo??"",input.worktreePath,input.promptIntent),notes=protocolTaskId?(input.readNotes??readFieldNotes)(input.task.repo??""):[],argv=withDispatcherProtocol(withWorktreeProtocol(input.argv,input.task.vendor,protocolTaskId,{status:gates?.status,notes:gates?.notes},notes),input.task.vendor,dispatcherTaskId,gates?.dispatcher),
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
`)}function engineSessionKey(taskId,tabId="tab-1"){return`${taskId}::${tabId}`}class RemoteEngineLaunchError extends Error{repo;code="REMOTE_ENGINE_LAUNCH_UNSUPPORTED";constructor(repo){super(`hosted engine launch over SSH is not implemented (remote project ${repo})`);this.repo=repo;this.name="RemoteEngineLaunchError"}}function buildEngineSessionLaunch(input){let remoteKey=remoteKeyForRepo(input.task.repo)??remoteKeyForRepo(input.worktreePath);if(remoteKey)throw new RemoteEngineLaunchError(remoteKey);let protocolTaskId=input.task.kind==="main"?void 0:input.task.id,dispatcherTaskId=input.task.kind==="main"?input.task.id:void 0,gates=input.protocolGates,launchInit=resolveEngineLaunchInit(input.task.repo??"",input.worktreePath,input.promptIntent),notes=protocolTaskId?(input.readNotes??readFieldNotes)(input.task.repo??""):[],argv=withDispatcherProtocol(withWorktreeProtocol(input.argv,input.task.vendor,protocolTaskId,{status:gates?.status,notes:gates?.notes},notes),input.task.vendor,dispatcherTaskId,gates?.dispatcher),repos=exposedRepos(input.task.repos);if(repos){let extraDirs=repos.filter((r)=>!r.primary).map((r)=>r.worktreePath);argv=protocolEntry(input.task.vendor).addDirArgv?.(argv,extraDirs)??argv}let delivery=input.firstMessageDelivery??protocolEntry(input.task.vendor).firstMessageDelivery??"argv",firstText=launchInit.firstMessage&&repos?`${multiRepoNote(repos)}
|
|
12
|
+
|
|
13
|
+
${launchInit.firstMessage.text}`:launchInit.firstMessage?.text,pasteFirstMessage=delivery==="paste"?firstText:void 0;if(firstText&&!pasteFirstMessage)argv=[...argv,firstText];let markerPath=launchInit.initScript?worktreeInitMarkerPath(input.worktreePath):void 0,initTimeoutMs=resolveRepoInitTimeoutSeconds(input.initTimeoutSeconds)*1000,script=engineLaunchLine(quoteShellArgv(argv,{bareSafe:!0}),{initScript:launchInit.initScript,markerPath,timeoutSeconds:input.initTimeoutSeconds}),taskId=quoteShellArg(input.task.id),tabId=quoteShellArg(input.tabId??"tab-1"),imageEnv=input.inlineImages?protocolEntry(input.task.vendor).capabilities?.inlineImageEnv:void 0,imageExports=Object.entries(imageEnv??{}).map(([name,value])=>` ${name}=${quoteShellArg(value)}`),repoExports=(repos?repoEnv(repos):[]).map(([name,value])=>` ${name}=${quoteShellArg(value)}`),identity=`export ROVE_TASK_ID=${taskId} ROVE_TAB_ID=${tabId}${imageExports.join("")}${repoExports.join("")}
|
|
14
|
+
`;return{key:engineSessionKey(input.task.id,input.tabId),command:[input.shell,"-ilc",identity+script],...pasteFirstMessage?{firstMessage:pasteFirstMessage}:{},...markerPath?{initMarkerPath:markerPath,initTimeoutMs}:{}}}import{basename}from"path";import path from"path";var DELIVERY_LOCK_TIMEOUT_MS=5000,DELIVERY_LOCK_RETRY_MS=20;function lockFileName(key){return`${key.replace(/[^A-Za-z0-9._-]/g,"_")}.lock`}function deliveryLockPath(key,lockDir=defaultDeliveryLockDir()){return path.join(lockDir,lockFileName(key))}var sleep=(ms)=>new Promise((resolve)=>setTimeout(resolve,ms));async function withDeliveryLock(key,fn,opts={}){let lockPath=deliveryLockPath(key,opts.lockDir??defaultDeliveryLockDir()),deadline=Date.now()+(opts.timeoutMs??DELIVERY_LOCK_TIMEOUT_MS),token=null;for(;;)try{token=await acquire(lockPath);break}catch(err){if(!(err instanceof LockfileError))break;if(Date.now()>=deadline)break;await sleep(DELIVERY_LOCK_RETRY_MS)}try{return await fn()}finally{if(token!==null)await release(lockPath,token).catch(()=>{})}}var PASTE_READY_TIMEOUT_MS=15000,PASTE_READY_POLL_MS=100;function bracketedPasteActive(output){let on=output.lastIndexOf("\x1B[?2004h");if(on===-1)return!1;return on>output.lastIndexOf("\x1B[?2004l")}function encodePaste(prompt,bracketed){return bracketed?`\x1B[200~${prompt}\x1B[201~`:prompt}async function connectHostedSessionClient(socketPath){let client=new RoveDaemonClient(socketPath);try{await client.connect()}catch(error){throw client.close(),error}return{rpc:client,close:()=>client.close()}}async function openHostedSessionHost(){try{return await connectHostedSessionClient(defaultPtyHostSocketPath())}catch{return null}}async function ensureHostedSessionHost(){return connectHostedSessionClient(await ensurePtyHostReachable())}async function listHostedSessionsOrNull(rpc){try{let{sessions}=await rpc.request("pty.list",{});return sessions??[]}catch{return null}}async function listHostedSessions(rpc){return await listHostedSessionsOrNull(rpc)??[]}function isHostedTaskKey(key,taskId){return(key.split("::")[0]??key)===taskId}function hostedTaskKeys(sessions,taskId,scope){return sessions.filter((session)=>isHostedTaskKey(session.key,taskId)&&!scope?.spare.some((base)=>isUnderKey(session.key,base))||(scope?.also.some((base)=>isUnderKey(session.key,base))??!1)).map((session)=>session.key)}async function killHostedSessions(rpc,keys,opts){let payload=opts?.wait===!0?{wait:!0}:{};await Promise.all(keys.map((key)=>rpc.request("pty.kill",{key,...payload}).catch(()=>{})))}function commandHasEngineWord(command,engineBin){for(let part of command)for(let token of part.split(/\s+/)){let bare=token.replace(/^['"]+|['"]+$/g,"");if(bare&&basename(bare)===engineBin)return!0}return!1}function builtinEngineBins(){return BUILTIN_VENDORS.flatMap((vendor)=>{let entry=engineEntry(vendor);return[entry.defaultCommand[0],...entry.processNames??[]]}).filter((bin)=>Boolean(bin))}function sessionArgvNamesEngine(command,engineBin){if(!command||command.length===0)return!1;if(engineBin&&commandHasEngineWord(command,engineBin))return!0;return builtinEngineBins().some((bin)=>commandHasEngineWord(command,bin))}function tabOrder(key){let n=Number(/tab-(\d+)$/.exec(key)?.[1]);return Number.isFinite(n)?n:Number.POSITIVE_INFINITY}function findHostedEngineKey(sessions,taskId,engineBin,scope){if(scope?.alias){let key=aliasKey(scope.alias);if(sessions.some((s)=>s.alive&&s.key===key))return key}let mine=unclaimedSessions(sessions,scope).filter((s)=>s.alive&&isHostedTaskKey(s.key,taskId)).sort((a,b)=>tabOrder(a.key)-tabOrder(b.key)),tab1=mine.find((s)=>s.key===`${taskId}::tab-1`);if(tab1)return tab1.key;if(engineBin){let byCommand=mine.find((s)=>commandHasEngineWord(s.command,engineBin));if(byCommand)return byCommand.key}return mine.find((s)=>sessionArgvNamesEngine(s.command))?.key??null}var SUBMIT_DELAY_MS=150,CONFIRM_TAIL_CHARS=24,CONFIRM_TIMEOUT_MS=2000,CONFIRM_POLL_MS=100;function flatten(text){return text.replace(/\s+/g," ")}async function confirmPromptLanded(rpc,key,prompt,sinceOffset){let tail=flatten(prompt).trim().slice(-CONFIRM_TAIL_CHARS);if(tail.length===0)return!1;let deadline=Date.now()+CONFIRM_TIMEOUT_MS;for(;;){let peek=await rpc.request("pty.peek",{key,sinceOffset});if(!peek.alive)return!1;if(flatten(Buffer.from(peek.data,"base64").toString("utf8")).includes(tail))return!0;if(Date.now()>=deadline)return!1;await new Promise((resolve)=>setTimeout(resolve,CONFIRM_POLL_MS))}}async function writeAndConfirm(rpc,key,prompt,sinceOffset,opts){let ready=await awaitPasteReady(rpc,key,{timeoutMs:opts?.pasteReadyTimeoutMs}),{bytes}=await writeHostedPrompt(rpc,key,prompt,{ready,vendor:opts?.vendor}),confirmed=await confirmPromptLanded(rpc,key,prompt,sinceOffset);return{bytes,ready,confirmed}}async function writeHostedPromptIfLive(rpc,key,prompt,opts){let peek=await rpc.request("pty.peek",{key});if(!peek.alive)return null;return writeAndConfirm(rpc,key,prompt,peek.offset,opts)}async function awaitPasteReady(rpc,key,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),deadline=Date.now()+(opts.timeoutMs??PASTE_READY_TIMEOUT_MS);for(;;){let peek=await rpc.request("pty.peek",{key});if(!peek.alive)return!1;if(bracketedPasteActive(Buffer.from(peek.data,"base64").toString("latin1")))return!0;if(Date.now()>=deadline)return!1;await sleep2(PASTE_READY_POLL_MS)}}async function writeHostedPrompt(rpc,key,prompt,opts){let bracketed=opts?.ready??await awaitPasteReady(rpc,key),capabilities=opts?.vendor?engineEntry(opts.vendor).capabilities:void 0,prepared=capabilities?.preparePromptSubmission?.(prompt),data=encodePaste(prepared??prompt,bracketed);return await withDeliveryLock(key,async()=>{await rpc.request("pty.write",{key,data}),await new Promise((resolve)=>setTimeout(resolve,SUBMIT_DELAY_MS)),await rpc.request("pty.write",{key,data:`${capabilities?.beforePromptSubmit??""}\r`})}),{bytes:Buffer.byteLength(data,"utf8")}}var deliverToHostedKey=writeHostedPromptIfLive;async function ensureHostedEngine(rpc,cwd,launch,defaultColors=readPersistedTerminalDefaultColors()){let result=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors});return await rpc.request("pty.detach",{key:launch.key}).catch(()=>{}),result}var FIRST_MESSAGE_ENGINE_TIMEOUT_MS=20000,FIRST_MESSAGE_POLL_INTERVAL_MS=500,FIRST_MESSAGE_SETTLE_MS=1500;async function awaitEngineProcess(rpc,key,engineBin,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),snapshot=opts.snapshot;if(opts.initMarkerPath){let initDeadline=Date.now()+(opts.initTimeoutMs??REPO_INIT_TIMEOUT_SECONDS*1000);while(Date.now()<initDeadline){let{sessions=[]}=await rpc.request("pty.list",{});if(!sessions.find((s)=>s.key===key)?.alive)return null;if(initMarkerSaysFinished(opts.initMarkerPath))break;await sleep2(opts.intervalMs??FIRST_MESSAGE_POLL_INTERVAL_MS)}}let deadline=Date.now()+(opts.timeoutMs??FIRST_MESSAGE_ENGINE_TIMEOUT_MS);while(Date.now()<deadline){let{sessions=[]}=await rpc.request("pty.list",{}),session=sessions.find((s)=>s.key===key);if(!session?.alive)return null;if(session.pid){let presence=await enginePresence(session.pid,engineBin,snapshot);if(presence.kind==="engine")return{pid:session.pid,vendor:presence.vendor}}await sleep2(opts.intervalMs??FIRST_MESSAGE_POLL_INTERVAL_MS)}return null}async function hostedSessionFailureLine(rpc,key,limit=200){try{let peek=await rpc.request("pty.peek",{key}),lines=terminalRows(Buffer.from(peek.data,"base64").toString("utf8")).map((row)=>row.trim()).filter((row)=>row.length>0),line=lines.findLast((row)=>ENGINE_EXIT_BANNER.test(row))??lines.at(-1);return line===void 0?void 0:line.slice(0,limit)}catch{return}}async function pastePromptWhenEngineUp(rpc,key,engineBin,prompt,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),engine=await awaitEngineProcess(rpc,key,engineBin,opts);if(engine!==null){if(!await awaitPasteReady(rpc,key,{timeoutMs:opts.pasteReadyTimeoutMs,sleep:sleep2}))await sleep2(opts.settleMs??FIRST_MESSAGE_SETTLE_MS);return await writeHostedPromptIfLive(rpc,key,prompt,{...opts,vendor:engine.vendor})}return null}
|
|
15
|
+
export{resolveThemeSlotHex,readPersistedTerminalDefaultColors,withDeliveryLock,enginePresence,trustEngineWorktree,launchReposOf,repoEnv,trustExtraRepos,AUTO_STATUS_KEY,autoStatusEnabled,DISPATCHER_KEY,initMarkerSaysFinished,RemoteEngineLaunchError,buildEngineSessionLaunch,awaitEngineProcess,hostedSessionFailureLine,pastePromptWhenEngineUp,openHostedSessionHost,ensureHostedSessionHost,listHostedSessionsOrNull,listHostedSessions,isHostedTaskKey,hostedTaskKeys,killHostedSessions,sessionArgvNamesEngine,findHostedEngineKey,deliverToHostedKey,ensureHostedEngine};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{PLUGIN_MANIFEST_FILENAMES,currentPluginPlatform,loadPluginRegistry,parsePluginManifest,pluginManifestPath,savePluginRegistry,supportsPlatform,upsertPluginEntry}from"./chunk-
|
|
2
|
+
import{PLUGIN_MANIFEST_FILENAMES,currentPluginPlatform,loadPluginRegistry,parsePluginManifest,pluginManifestPath,savePluginRegistry,supportsPlatform,upsertPluginEntry}from"./chunk-chdjytvm.js";import{pluginCheckoutDir,pluginConfigDir,pluginStateDir,pluginsRootDir}from"./chunk-j1z9kgyd.js";import{CURRENT_VERSION,compareSemver}from"./chunk-1s0ng45a.js";import{spawn}from"child_process";import{cpSync,existsSync,mkdirSync,readFileSync,renameSync,rmSync}from"fs";import{mkdtempSync}from"fs";import{basename,join,resolve}from"path";import{createInterface}from"readline/promises";var GITHUB_SPEC_RE=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;class PluginCliError extends Error{}function fail(message){throw new PluginCliError(message)}function readManifestAt(root){let path=pluginManifestPath(root);if(!path)fail(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);let source=readFileSync(path,"utf8");return{...parsePluginManifest(source,basename(path)),manifestPath:path,manifestSource:source}}function checkVersionGate(parsed){let min=parsed.manifest.minRoveVersion;if(compareSemver(CURRENT_VERSION,min)<0)fail(`plugin requires Rove >= ${min} (this is ${CURRENT_VERSION}); update Rove first`)}function commandLines(parsed){let m=parsed.manifest,lines=[];for(let c of m.build)lines.push(`build: ${c.command.join(" ")}`);for(let c of m.startup)lines.push(`startup: ${c.command.join(" ")}`);for(let a of m.actions)lines.push(`action ${a.id}: ${a.command.join(" ")}`);for(let e of m.events)lines.push(`on ${e.on}: ${e.command.join(" ")}`);return lines}var CAPTURE_TAIL_BYTES=4096;function run(cmd,args,opts){return new Promise((resolve2)=>{let child=spawn(cmd,args,{cwd:opts.cwd,stdio:opts.inherit?["ignore","inherit","inherit"]:["ignore","pipe","pipe"]}),output="",collect=(chunk)=>{output=`${output}${String(chunk)}`.slice(-CAPTURE_TAIL_BYTES)};child.stdout?.on("data",collect),child.stderr?.on("data",collect),child.on("error",(err)=>resolve2({code:null,output:`${output}${err.message}`})),child.on("close",(code)=>resolve2({code,output}))})}function outputTail(output){let trimmed=output.trim();return trimmed?`: ${trimmed.split(`
|
|
3
3
|
`).slice(-3).join(" / ")}`:""}async function git(args,opts){let{code,output}=await run("git",args,opts);if(code!==0)fail(`git ${args[0]} failed${outputTail(output)}`)}async function runBuildCommands(parsed,root,opts){let platform=currentPluginPlatform();for(let[i,step]of parsed.manifest.build.entries()){if(!supportsPlatform(step,parsed.manifest,platform))continue;let[cmd,...args]=step.command;if(opts.inherit)console.log(`build[${i}]: ${step.command.join(" ")}`);let{code,output}=await run(cmd,args,{cwd:root,inherit:opts.inherit});if(code!==0)fail(`build[${i}] failed (exit ${code??"spawn error"}); plugin not registered${outputTail(output)}`)}}function makeStagingDir(){let root=pluginsRootDir();return mkdirSync(root,{recursive:!0}),mkdtempSync(join(root,".staging-"))}function movePluginTree(from,to){try{renameSync(from,to)}catch(err){if(err.code!=="EXDEV")throw err;cpSync(from,to,{recursive:!0,verbatimSymlinks:!0}),rmSync(from,{recursive:!0,force:!0})}}function register(entry){savePluginRegistry(upsertPluginEntry(loadPluginRegistry(),entry)),mkdirSync(pluginConfigDir(entry.id),{recursive:!0,mode:448}),mkdirSync(pluginStateDir(entry.id),{recursive:!0,mode:448})}async function preparePluginInstall(spec,opts={}){let match=spec.match(GITHUB_SPEC_RE);if(!match)fail(`install takes GitHub shorthand (owner/repo[/subdir]), got \`${spec}\``);let[,owner,repo,subdirRaw]=match,subdir=subdirRaw?.replace(/^\//,""),inherit=opts.inherit??!1,tmp=makeStagingDir();try{let url=`https://github.com/${owner}/${repo}.git`;if(inherit)console.log(`cloning ${url}${opts.ref?` @ ${opts.ref}`:""}`);if(opts.ref)await git(["clone","--quiet",url,tmp],{inherit}),await git(["checkout","--quiet",opts.ref],{cwd:tmp,inherit});else await git(["clone","--quiet","--depth","1",url,tmp],{inherit});let rootInClone=subdir?join(tmp,subdir):tmp,parsed=readManifestAt(rootInClone);checkVersionGate(parsed);let id=parsed.manifest.id,existing=loadPluginRegistry().plugins.find((p)=>p.id===id);if(existing?.source.kind==="link")fail(`\`${id}\` is locally linked at ${existing.root}; unlink it first`);if(!supportsPlatform({},parsed.manifest,currentPluginPlatform()))fail(`plugin declares platforms [${parsed.manifest.platforms?.join(", ")}]; this machine is unsupported`);return{preview:{id,name:parsed.manifest.name,version:parsed.manifest.version,description:parsed.manifest.description??null,source:`github.com/${owner}/${repo}${subdir?`/${subdir}`:""}`,commands:commandLines(parsed),warnings:parsed.warnings},commit:async()=>{try{await runBuildCommands(parsed,rootInClone,{inherit});let manifestPath=pluginManifestPath(rootInClone);if(!manifestPath)fail("manifest disappeared during build; aborting");if(manifestPath!==parsed.manifestPath)fail("manifest changed during build; aborting");if(readFileSync(manifestPath,"utf8")!==parsed.manifestSource)fail("manifest changed during build; aborting");let checkout=pluginCheckoutDir(id);return rmSync(checkout,{recursive:!0,force:!0}),mkdirSync(join(checkout,".."),{recursive:!0}),movePluginTree(tmp,checkout),register({id,source:{kind:"github",spec},root:subdir?join(checkout,subdir):checkout,enabled:!0,version:parsed.manifest.version,installedAt:Date.now()}),id}finally{rmSync(tmp,{recursive:!0,force:!0})}},discard:()=>rmSync(tmp,{recursive:!0,force:!0})}}catch(err){throw rmSync(tmp,{recursive:!0,force:!0}),err}}function printPreview(preview){console.log(`
|
|
4
4
|
${preview.name} (${preview.id}) v${preview.version} \u2014 ${preview.description??"no description"}`),console.log(`source: ${preview.source}`);for(let line of preview.commands)console.log(` ${line}`);for(let w of preview.warnings)console.log(` warning: ${w}`);console.log("")}async function confirmOrBail(yes){if(yes)return;if(!process.stdin.isTTY)fail("refusing to install without confirmation in a non-interactive terminal; pass --yes");let rl=createInterface({input:process.stdin,output:process.stdout}),answer=(await rl.question("Install this plugin and run its build commands? [y/N] ")).trim().toLowerCase();if(rl.close(),answer!=="y"&&answer!=="yes")fail("aborted")}async function installPlugin(spec,opts){let prepared=await preparePluginInstall(spec,{ref:opts.ref,inherit:!0});printPreview(prepared.preview);try{await confirmOrBail(opts.yes)}catch(err){throw prepared.discard(),err}let id=await prepared.commit();return console.log(`installed ${id} v${prepared.preview.version}`),id}function linkPlugin(dir){let root=resolve(dir);if(!existsSync(root))fail(`no such directory: ${root}`);let parsed=readManifestAt(root);checkVersionGate(parsed);let id=parsed.manifest.id;if(loadPluginRegistry().plugins.find((p)=>p.id===id)?.source.kind==="github")fail(`\`${id}\` is installed from GitHub; uninstall it before linking a local copy`);for(let w of parsed.warnings)console.log(`warning: ${w}`);if(!supportsPlatform({},parsed.manifest,currentPluginPlatform()))console.log(`warning: declares platforms [${parsed.manifest.platforms?.join(", ")}]; nothing will run on this machine`);register({id,source:{kind:"link"},root,enabled:!0,version:parsed.manifest.version,installedAt:Date.now()}),console.log(`linked ${id} v${parsed.manifest.version} \u2192 ${root}`)}
|
|
5
5
|
export{PluginCliError,preparePluginInstall,installPlugin,linkPlugin};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{API_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb,unknownVerbError}from"./chunk-90qs5xae.js";import"./chunk-qr28azaj.js";import"./chunk-rctyty5x.js";import"./chunk-mmw2py0h.js";import"./chunk-8kewg6t3.js";import"./chunk-p6jw0zcd.js";import"./chunk-ya40yzp4.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-jad2z4hd.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-chdjytvm.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atbwdgg6.js";import"./chunk-atn06ncf.js";import"./chunk-ydp0jtt5.js";import"./chunk-qkehg2c1.js";import"./chunk-9seey8kp.js";import"./chunk-a677tj7e.js";import"./chunk-09w9843b.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-aqqm68bd.js";import"./chunk-e94kap9x.js";import"./chunk-fvvb0072.js";import"./chunk-sdwdhnkv.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-2rbb1tpm.js";import"./chunk-fsd00eqa.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-8ahayecf.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-1s0ng45a.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-47mz8nd4.js";import"./chunk-t65y2j9c.js";import"./chunk-cmp64q4j.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{unknownVerbError,findVerb,VERB_GROUPS,VERB_ALIASES,VERBS,API_VERBS};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{preferredReleaseChannel,rememberReleaseChannel}from"./chunk-xk4sbb8z.js";import{updaterShell,updaterShellFailureHint}from"./chunk-
|
|
2
|
+
import{preferredReleaseChannel,rememberReleaseChannel}from"./chunk-xk4sbb8z.js";import{updaterShell,updaterShellFailureHint}from"./chunk-j7p38a8z.js";import"./chunk-tn9gtf18.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand,updateCommandFor}from"./chunk-1s0ng45a.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{spawnSync}from"child_process";var CLI_NAME=ROVE_PRODUCT_NAME;function updatePlan(target){let shell=updateCommandFor(target);return{command:updaterShell(),args:["-c",shell],display:shell}}var VERSION_SHAPE=/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;function isReleaseChannel(value){return RELEASE_CHANNELS.includes(value)}var CHANNEL_FLAGS={"--nightly":"nightly","--stable":"latest","--latest":"latest",stable:"latest"};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}let flagged=CHANNEL_FLAGS[arg];if(channel===void 0&&flagged!==void 0){channel=flagged;continue}if(channel===void 0&&isReleaseChannel(arg)){channel=arg;continue}if(version===void 0&&VERSION_SHAPE.test(arg)){version=arg;continue}process.stderr.write(`${CLI_NAME} update: unknown argument "${arg}"
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ import{preferredReleaseChannel,rememberReleaseChannel}from"./chunk-xk4sbb8z.js";
|
|
|
10
10
|
install one with: ${CLI_NAME} update <version>
|
|
11
11
|
`)}async function warnBreakingCrossings(target,channel,io){if(BREAKING_VERSIONS.length===0)return;let resolved=target??(await checkLatestVersion({force:!0,channel}))?.latest;if(!resolved)return;let crossed=breakingVersionsCrossed(CURRENT_VERSION,resolved);if(crossed.length===0)return;io.stderr.write([`warning: ${CURRENT_VERSION} -> ${resolved} crosses breaking version(s): ${crossed.join(", ")}.`,`After this update, Rove will refuse to start until you run \`${CLI_NAME} reset\``,"(worktrees are never touched; add --hard only to also wipe the task index).",""].join(`
|
|
12
12
|
`))}var FOLLOW_UP_NOTE=["",`${CLI_NAME}: installed. Two background processes are still running the old build:`,` daemon \u2192 \`${CLI_NAME} daemon restart\` (safe; never touches live sessions)`,` pty host \u2192 only \`${CLI_NAME} reset\` replaces it, and that ends every live`," terminal and engine session \u2014 do it when you can afford to.",`Run \`${CLI_NAME} doctor\` to see which of the two is actually stale.`,""].join(`
|
|
13
|
-
`);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code)),channel:deps?.channel??{get:()=>preferredReleaseChannel(),remember:rememberReleaseChannel}},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-
|
|
13
|
+
`);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code)),channel:deps?.channel??{get:()=>preferredReleaseChannel(),remember:rememberReleaseChannel}},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-b086kgnb.js");await startVersionsHost();return}await printVersionList(io);return}let channel=parsed.channel??io.channel.get(),target=parsed.version??(channel===DEFAULT_RELEASE_CHANNEL?void 0:channel),plan=updatePlan(target),switching=parsed.version===void 0&&channel!==channelOf();if(io.stdout.write(`${CLI_NAME} ${CURRENT_VERSION} -> ${target??channel}
|
|
14
14
|
`),switching)io.stdout.write(`switching channel: ${channelOf()} -> ${channel}
|
|
15
15
|
`);if(io.stdout.write(`running: ${plan.display}
|
|
16
16
|
`),await warnBreakingCrossings(parsed.version,channel,io),parsed.dryRun)return;let result=io.spawn(plan.command,plan.args,{stdio:"inherit"});if(result.error){io.stderr.write(`${CLI_NAME} update: failed to run ${plan.command}: ${result.error.message}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{defaultFixRuntime}from"./chunk-
|
|
2
|
+
import{defaultFixRuntime}from"./chunk-jt0k1pva.js";import{INBOUND_CLASSES,deniedClasses,setInbound}from"./chunk-mk2z5z32.js";import{addMachine,defaultMachineAlias,discoverMachine,duplicateAliasOf,getMachine,isValidMachineAlias,isWindowsMachine,learnedFrom,listMachines,machineSocketDir,machineSshArgs,parseSshTarget,readMachines,remoteRove,removeMachine,sanitizeAlias,setMachineIdentity,sshServerIsWindows,sshTargetOf,updateMachine,windowsAuthorizeKeySteps}from"./chunk-s4nrmbqh.js";import"./chunk-90qs5xae.js";import"./chunk-qr28azaj.js";import"./chunk-rctyty5x.js";import"./chunk-mmw2py0h.js";import"./chunk-8kewg6t3.js";import"./chunk-p6jw0zcd.js";import"./chunk-ya40yzp4.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-jad2z4hd.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-chdjytvm.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atbwdgg6.js";import"./chunk-atn06ncf.js";import{primaryCheckouts,repoIdOf,repoIdentity,setPrimaryCheckout}from"./chunk-ydp0jtt5.js";import"./chunk-qkehg2c1.js";import"./chunk-9seey8kp.js";import"./chunk-a677tj7e.js";import"./chunk-09w9843b.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-aqqm68bd.js";import"./chunk-e94kap9x.js";import"./chunk-fvvb0072.js";import"./chunk-sdwdhnkv.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import{shQuote}from"./chunk-y1xnjx8x.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-2rbb1tpm.js";import"./chunk-fsd00eqa.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-8ahayecf.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import{CURRENT_VERSION}from"./chunk-1s0ng45a.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import{loadStateFile}from"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import{homeDir}from"./chunk-z1nj22va.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-47mz8nd4.js";import"./chunk-t65y2j9c.js";import"./chunk-cmp64q4j.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-91sykzqq.js";import{spawn}from"child_process";import{appendFileSync,chmodSync,existsSync,mkdirSync}from"fs";import{homedir}from"os";import{dirname}from"path";function parseSshG(stdout,home=homedir()){let values=new Map;for(let line of stdout.split(`
|
|
3
3
|
`)){let space=line.indexOf(" ");if(space>0)values.set(line.slice(0,space).toLowerCase(),line.slice(space+1).trim())}let hostname=values.get("hostname")??"",port=Number(values.get("port")??"22")||22,files=(key)=>(values.get(key)??"").split(/\s+/).filter((f)=>f&&f!=="none").map((f)=>f.startsWith("~/")?`${home}${f.slice(1)}`:f),alias=values.get("hostkeyalias"),proxy=(key)=>{let v=values.get(key);return v!==void 0&&v!=="none"};return{knownHostsName:alias&&alias!=="none"?alias:port===22?hostname:`[${hostname}]:${port}`,hostname,port,userKnownHosts:files("userknownhostsfile"),globalKnownHosts:files("globalknownhostsfile"),proxied:proxy("proxyjump")||proxy("proxycommand")}}async function checkHostKey(config){let target=sshTargetOf(config),resolved=await run(["ssh","-G",...config.port?["-p",String(config.port)]:[],target]);if(resolved.code!==0)return{state:"skipped",reason:"ssh -G failed"};let destination=parseSshG(resolved.stdout);if(!destination.hostname)return{state:"skipped",reason:"ssh -G named no host"};if(destination.proxied)return{state:"skipped",reason:"reached through a proxy"};for(let file of[...destination.userKnownHosts,...destination.globalKnownHosts]){if(!existsSync(file))continue;if((await run(["ssh-keygen","-F",destination.knownHostsName,"-f",file])).code===0)return{state:"known"}}let keys=(await run(["ssh-keyscan","-T","5","-p",String(destination.port),destination.hostname])).stdout.split(`
|
|
4
4
|
`).filter((line)=>line.trim()&&!line.startsWith("#"));if(keys.length===0)return{state:"skipped",reason:"the host offered no key"};let named=keys.map((line)=>line.replace(/^\S+/,destination.knownHostsName)),fingerprints=(await run(["ssh-keygen","-l","-f","-"],`${named.join(`
|
|
5
5
|
`)}
|
|
@@ -39,12 +39,12 @@ ${MACHINE_USAGE}
|
|
|
39
39
|
`),process.exit(1)}function flagValue(argv,name){for(let i=0;i<argv.length;i++){let arg=argv[i];if(arg===void 0)continue;if(arg.startsWith(`--${name}=`))return arg.slice(name.length+3);if(arg!==`--${name}`)continue;let value=argv[i+1];if(value===void 0||value.startsWith("--"))usageError(`--${name} needs a value`);return value}return}async function runMachineSubcommand(argv){let[verb,...rest]=argv;if(!verb||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${MACHINE_USAGE}
|
|
40
40
|
`);return}if(verb==="list")return list();if(verb==="add")return await add(rest);if(verb==="doctor")return await doctor(rest);if(verb==="remove")return remove(rest);if(verb==="tunnel")return tunnel(rest);if(verb==="inbound")return inbound(rest);if(verb==="primary")return machinePrimary(rest,usageError);usageError(`unknown verb "${verb}"`)}async function add(argv){let target=positionalOf(argv);if(!target)usageError("add needs an ssh target, e.g. `machine add narwhal`");let parsed=parseSshTarget(target);if(!parsed)usageError(`"${target}" is not a valid ssh target ([user@]host[:port])`);let portFlag=flagValue(argv,"port"),port=portFlag?Number(portFlag):parsed.port;if(port!==void 0&&(!Number.isInteger(port)||port<1||port>65535))usageError("--port must be 1-65535");let identity=flagValue(argv,"identity"),requested=flagValue(argv,"alias");if(requested&&!isValidMachineAlias(requested))usageError(`--alias must be letters/digits/._- and cannot be "local" (got "${requested}")`);let probeAlias=requested??sanitizeAlias(parsed.host),config={host:parsed.host,...parsed.user?{user:parsed.user}:{},...port?{port}:{},auth:identity?{kind:"key",keyPath:identity}:{kind:"key"}};await confirmHostKey(config),process.stderr.write(`${CLI_NAME} machine: contacting ${sshTargetOf(config)}\u2026
|
|
41
41
|
`);let established=await establishMachine(probeAlias,config,setupRuntime(argv));if(!established.ok)fail("nothing was saved");let{found,config:settled}=established,alias=requested??defaultMachineAlias({typedHost:parsed.host,typedUser:parsed.user,port,remoteHostname:found.status.hostname});if(!isValidMachineAlias(alias))fail(`could not derive a usable alias from "${found.status.hostname}" \u2014 pass --alias`);let identityTriple={hostname:found.status.hostname,homeDir:found.status.homeDir,daemonPid:found.status.daemonPid},duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identityTriple),learned=learnedFrom(found),sockets=learned.sockets;if(found.roveBin)process.stderr.write(`${CLI_NAME} machine: rove is not on ${alias}'s non-interactive PATH; using ${found.roveBin}
|
|
42
|
-
`);addMachine(alias,{...settled,...learned,identity:identityTriple}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-
|
|
42
|
+
`);addMachine(alias,{...settled,...learned,identity:identityTriple}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-j19yf5ws.js"),up=await ensureForwards({alias,config:{...settled,...learned},remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(process.stdout.write(`${CLI_NAME} machine: ${alias} \u2192 ${sshTargetOf(settled)} (rove ${found.status.roveVersion||"?"} on ${found.status.hostname||"?"})
|
|
43
43
|
`),!up)process.stderr.write(`${CLI_NAME} machine: registered, but could not forward ${alias}'s socket yet \u2014 it will show as offline until the connection comes up
|
|
44
44
|
`);if(duplicate)process.stdout.write(`${CLI_NAME} machine: ${alias} is the same machine as ${duplicate} (hostname/homeDir/pid match) \u2014 the sidebar shows one row
|
|
45
45
|
`)}function setupRuntime(argv){let yes=argv.includes("--yes"),fixRuntime=defaultFixRuntime();return{confirm:fixRuntime.confirm,exec:fixRuntime.exec,out:(line)=>process.stderr.write(`${line}
|
|
46
46
|
`),ask:!yes,planOnly:!yes&&process.stdin.isTTY!==!0}}async function doctor(argv){let alias=positionalOf(argv),entries=listMachines().filter((m)=>!alias||m.alias===alias);if(alias&&entries.length===0)fail(`no machine named "${alias}" (see \`${CLI_NAME} machine list\`)`);if(entries.length===0){process.stdout.write(`No machines registered. Add one with \`${CLI_NAME} machine add <ssh-target>\`.
|
|
47
|
-
`);return}let rt=setupRuntime(argv),{ensureForwards}=await import("./chunk-
|
|
47
|
+
`);return}let rt=setupRuntime(argv),{ensureForwards}=await import("./chunk-j19yf5ws.js"),failed=0;for(let{alias:name,...config}of entries){process.stderr.write(`${CLI_NAME} machine: checking ${name} (${sshTargetOf(config)})\u2026
|
|
48
48
|
`);let established=await establishMachine(name,config,rt);if(!established.ok){failed++,process.stdout.write(`${name} \u2717 ${established.failure.code}
|
|
49
49
|
`);continue}let{found}=established,learned=learnedFrom(found),sockets=learned.sockets,settled={...established.config,...learned};updateMachine(name,settled);let up=await ensureForwards({alias:name,config:settled,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty}),version=found.status.roveVersion||"?",skew=version!==CURRENT_VERSION?` (this machine runs ${CURRENT_VERSION})`:"";process.stdout.write(`${name} ${up?"\u2713":"\u2717 socket not forwarded"} rove ${version}${skew} on ${found.status.hostname||"?"}
|
|
50
50
|
`);for(let note of await doctorNotes(name,settled,found))process.stdout.write(` ${note}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{PTY_STOP_REFUSED,RoveDaemonClient}from"./chunk-bvkj97zw.js";import{unlink}from"fs/promises";async function stopDaemonProcess(socketPath,pidPath,opts={}){let oldPid=await readPidFile(pidPath),targetPid=oldPid!==null&&oldPid!==process.pid?oldPid:null,wasAlive=targetPid!==null&&isProcessAlive(targetPid),method=wasAlive?"graceful":"absent",client=new RoveDaemonClient(socketPath),refusal=client.request("daemon.stop",{reason:opts.reason??"stop",...opts.force?{force:!0}:{}}).then(()=>!1,(err)=>err instanceof Error&&err.name===PTY_STOP_REFUSED),{promise:stopTimeout,resolve:timedOut}=Promise.withResolvers();setTimeout(()=>timedOut(!1),2000);let refused=await Promise.race([refusal,stopTimeout]);if(client.close(),refused)return{pid:oldPid,method:"refused"};if(wasAlive&&targetPid!==null){let deadline=Date.now()+5000,escalated=!1;while(Date.now()<deadline){try{process.kill(targetPid,0)}catch{break}if(!escalated&&Date.now()-(deadline-5000)>2000){try{process.kill(targetPid,"SIGTERM")}catch{}method="sigterm",escalated=!0}await new Promise((resolve)=>setTimeout(resolve,50))}try{process.kill(targetPid,0),process.kill(targetPid,"SIGKILL"),method="sigkill",await new Promise((resolve)=>setTimeout(resolve,100))}catch{}}let survivor=await readPidFile(pidPath);if(survivor!==null&&survivor!==process.pid&&isProcessAlive(survivor))return{pid:oldPid,method};return await unlink(socketPath).catch(()=>{}),await unlink(pidPath).catch(()=>{}),{pid:oldPid,method}}
|
|
3
|
+
export{stopDaemonProcess};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{stampOrigin}from"./chunk-tc8j29fd.js";import{createStateCell}from"./chunk-cmp64q4j.js";var NO_LIVE={activity:new Map,changes:new Map,tokens:new Map};function decodeMachines(payload){let p=payload;if(!p||!Array.isArray(p.machines)||!Array.isArray(p.tasks)||!p.live||typeof p.live!=="object")return null;let map=(value)=>new Map(value&&typeof value==="object"?Object.entries(value):[]);return{machines:p.machines,tasks:p.tasks,live:{activity:map(p.live.activity),changes:map(p.live.changes),tokens:map(p.live.tokens)}}}class MachineFeed{local;machinesAcc=createStateCell([],"machines.status");remoteTasksAcc=createStateCell(null,"machines.remoteTasks");tasksAcc;merged=null;liveAcc=createStateCell(NO_LIVE,"machines.live");stops;constructor(local){this.local=local;this.tasksAcc=this.mergedTasks();let raw=local.rawChannelSignal("machines"),take=()=>{let next=decodeMachines(raw.get());if(!next)return;this.machinesAcc.set(next.machines),this.liveAcc.set(next.live),this.remoteTasksAcc.set(next.machines.length===0?null:next.tasks)};this.stops=[raw.subscribe(take)],take()}machinesSignal(){return this.machinesAcc}tasksSignal(){return this.tasksAcc}liveSignal(){return this.liveAcc}mergedTasks(){let localTasks=this.local.tasksSignal(),get=()=>{let local=localTasks.get(),remote=this.remoteTasksAcc.get();if(remote===null)return local;if(this.merged?.local!==local||this.merged.remote!==remote){let value=[...local.map((task)=>stampOrigin(task,"local","local")),...remote];this.merged={local,remote,value}}return this.merged.value},state=get;return state.get=get,state.subscribe=(listener)=>{let stopLocal=localTasks.subscribe(listener),stopRemote=this.remoteTasksAcc.subscribe(listener);return()=>{stopLocal(),stopRemote()}},state}dispose(){for(let stop of this.stops)stop()}}
|
|
3
|
+
export{decodeMachines,MachineFeed};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{CLAUDE_HOOK_EVENT_MAP,claudeSettingsPath}from"./chunk-8ahayecf.js";import{hasRoveActivityHooks}from"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import{isObject}from"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import{installedSkillDirs}from"./chunk-fpbwx721.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";import{readFileSync}from"fs";import{homedir}from"os";var PLUGIN_NAME="rove";function readSettings(path){try{let parsed=JSON.parse(readFileSync(path,"utf8"));return isObject(parsed)?parsed:null}catch{return null}}function isRovePluginEnabled(settingsFilePath=claudeSettingsPath()){let settings=readSettings(settingsFilePath);if(!settings||!isObject(settings.enabledPlugins))return!1;return Object.entries(settings.enabledPlugins).some(([key,on])=>on===!0&&key.split("@")[0]===PLUGIN_NAME)}function detectLegacyInstalls(opts={}){let settingsFilePath=opts.settingsFilePath??claudeSettingsPath(),home=opts.home??homedir(),settings=readSettings(settingsFilePath),legacyHooks=settings!==null&&(hasRoveActivityHooks(settings,CLAUDE_HOOK_EVENT_MAP)||settingsHasWorktreeWatch(settings)),legacySkillDirs=installedSkillDirs(home);return{legacyHooks,legacySkillDirs}}function settingsHasWorktreeWatch(settings){let hooks=isObject(settings.hooks)?settings.hooks:{};return Object.values(hooks).some((groups)=>Array.isArray(groups)&&groups.some((g)=>isObject(g)&&Array.isArray(g.hooks)&&g.hooks.some((h)=>isObject(h)&&typeof h.command==="string"&&h.command.includes("worktree-created")&&!h.command.includes("CLAUDE_PLUGIN_ROOT"))))}function migrationHint(findings,cliName){if(!findings.legacyHooks&&findings.legacySkillDirs.length===0)return null;let lines=[`${cliName}: the Rove Claude Code plugin is enabled, but legacy installs remain:`];if(findings.legacyHooks)lines.push(" \u2022 ~/.claude/settings.json still has the settings-managed Rove hooks (every event fires TWICE).",` Run \`${cliName} hook cleanup\` to remove them (only Rove's own entries are touched).`);for(let dir of findings.legacySkillDirs)lines.push(` \u2022 legacy skill copy at ${dir} (the plugin bundles the skill \u2014 two copies double-register).`," Remove that directory to keep the plugin's copy only.");return lines.push(" Reading this inside a session? Just ask your agent to run the cleanup for you."),`${lines.join(`
|
|
3
|
+
`)}
|
|
4
|
+
`}export{migrationHint,isRovePluginEnabled,detectLegacyInstalls};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{pathSyntax}from"./chunk-pn5ygqn6.js";function childrenOf(tasks,id){return tasks.filter((task)=>task.parentTaskId===id)}function workspaceOwnerId(task){return task.sharesWorkspaceOf??task.id}function isSharedChild(task){return task.sharesWorkspaceOf!==void 0}function lineageRootId(tasks,id){let byId=new Map(tasks.map((task)=>[task.id,task])),seen=new Set,current=id;for(;;){seen.add(current);let up=byId.get(current)?.parentTaskId;if(!up||seen.has(up)||!byId.has(up))return current;current=up}}function subtreeIds(tasks,id){let out=[],seen=new Set,visit=(current)=>{if(seen.has(current))return;seen.add(current);for(let child of childrenOf(tasks,current))visit(child.id);out.push(current)};return visit(id),out}function taskCwd(task){let root=task.worktreePath??"";if(!root||!task.cwdSubpath)return root;return pathSyntax(root).join(root,task.cwdSubpath)}var MULTI_REPO_CAP=8,REPO_NAME_RE=/^[A-Za-z0-9_][A-Za-z0-9._-]*$/;function repoNameOf(repoPath){return pathSyntax(repoPath).basename(repoPath).replace(/[^A-Za-z0-9._-]/g,"-").replace(/^[.-]+/,"")||"repo"}function uniqueRepoName(name,taken){if(!taken.has(name))return name;for(let n=2;;n++)if(!taken.has(`${name}-${n}`))return`${name}-${n}`}function taskRepos(task,tasks){let extras=(task.sharesWorkspaceOf&&tasks?.find((t)=>t.id===task.sharesWorkspaceOf)||task).extraRepos??[];return[{name:uniqueRepoName(repoNameOf(task.repo),new Set(extras.map((e)=>e.name))),repo:task.repo,branch:task.branch,worktreePath:task.worktreePath??"",...task.baseRef?{baseRef:task.baseRef}:{},...task.prStatus?{prStatus:task.prStatus}:{},primary:!0},...extras.map((e)=>({name:e.name,repo:e.repo,branch:e.branch,worktreePath:e.worktreePath,...e.baseRef?{baseRef:e.baseRef}:{},...e.prStatus?{prStatus:e.prStatus}:{},primary:!1}))]}function taskWorktreePaths(task,tasks){return taskRepos(task,tasks).map((r)=>r.worktreePath).filter((p)=>p.length>0)}function prRank(pr){if(pr.checkState==="failing")return 0;if(pr.checkState==="pending")return 1;return pr.lifecycle==="merged"?3:2}function rollupPr(task){let worst;for(let pr of[task.prStatus,...(task.extraRepos??[]).map((e)=>e.prStatus)])if(pr&&(!worst||prRank(pr)<prRank(worst)))worst=pr;return worst}function pickRepos(task,only){let all=taskRepos(task);if(!only)return all;let picked=all.filter((r)=>r.name===only);if(picked.length===0)throw Error(`UNKNOWN_REPO: no repo named '${only}' in this task (repos: ${all.map((r)=>r.name).join(", ")})`);return picked}
|
|
3
|
+
export{childrenOf,workspaceOwnerId,isSharedChild,lineageRootId,subtreeIds,taskCwd,MULTI_REPO_CAP,REPO_NAME_RE,repoNameOf,uniqueRepoName,taskRepos,taskWorktreePaths,rollupPr,pickRepos};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{engineEntry,identifiableEngineIds}from"./chunk-
|
|
2
|
+
import{engineEntry,identifiableEngineIds}from"./chunk-fsd00eqa.js";import{recordSpawn}from"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-32j6y5d1.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import{__require}from"./chunk-91sykzqq.js";import{basename}from"path";var WRAPPERS=new Set(["node","bun","npx","deno","sh","zsh","bash","env","script"]);function binaryName(token){return basename(token).replace(/\.(exe|js|mjs|cjs)$/,"")}function executableNameFromArgv(argv){for(let token of argv.slice(0,8)){if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(token))continue;let name=binaryName(token);if(WRAPPERS.has(name))continue;return name||null}return null}function vendorFromArgv(commandLine){let name=executableNameFromArgv(commandLine.trim().split(/\s+/));if(!name)return null;return identifiableEngineIds().find((v)=>{let entry=engineEntry(v);return entry.defaultCommand[0]===name||entry.processNames?.includes(name)===!0})??null}function parsePsSnapshot(text){let rows=[];for(let line of text.split(`
|
|
3
3
|
`)){let m=/^\s*(\d+)\s+(\d+)\s+(\S.*)$/.exec(line);if(m)rows.push({pid:Number(m[1]),ppid:Number(m[2]),args:m[3]})}return rows}function childrenIndex(rows){let kids=new Map;for(let row of rows){let list=kids.get(row.ppid);if(list)list.push(row);else kids.set(row.ppid,[row])}return kids}function hasAncestor(rows,pid,ancestorPid){let parents=new Map(rows.map((r)=>[r.pid,r.ppid])),cur=pid;for(let hops=0;hops<=rows.length;hops++){if(cur===ancestorPid)return!0;let next=parents.get(cur);if(next===void 0||next<=1)return!1;cur=next}return!1}function customEngineBinaries(){let state=loadStateFile(),ids=state.customEngineIds,out=new Map;if(!Array.isArray(ids))return out;for(let id of ids){if(typeof id!=="string"||id.trim().length===0)continue;let command=state[`engineCommand.${id}`],argv=typeof command==="string"&&command.trim().length>0?command.trim().split(/\s+/):[id],name=executableNameFromArgv(argv);if(name)out.set(name,id)}return out}function findDescendant(rows,rootPid,pick){let kids=childrenIndex(rows),queue=[...kids.get(rootPid)??[]],visited=new Set;while(queue.length>0){let row=queue.shift();if(!row)break;if(visited.has(row.pid))continue;visited.add(row.pid);let hit=pick(row);if(hit!==null)return hit;queue.push(...kids.get(row.pid)??[])}return null}function walkDescendants(rows,rootPid,identify){return findDescendant(rows,rootPid,(row)=>{let vendor=identify(row.args);return vendor?{vendor,argv:row.args,pid:row.pid}:null})}function foregroundEngineIn(rows,rootPid){let builtin=walkDescendants(rows,rootPid,vendorFromArgv);if(builtin)return builtin;let custom=customEngineBinaries();if(custom.size===0)return null;return walkDescendants(rows,rootPid,(args)=>custom.get(executableNameFromArgv(args.trim().split(/\s+/))??"")??null)}function engineProcessIn(rows,rootPid,extraLaunch){if(foregroundEngineIn(rows,rootPid))return!0;let expected=extraLaunch?executableNameFromArgv(typeof extraLaunch==="string"?[extraLaunch]:extraLaunch):null;if(!expected)return!1;return findDescendant(rows,rootPid,(row)=>executableNameFromArgv(row.args.trim().split(/\s+/))===expected?!0:null)===!0}var PS_PROBE_TIMEOUT_MS=5000,bunPsSpawn=()=>{recordSpawn("engine.foregroundWalk",["ps","-A","-o","pid=,ppid=,args="]);let proc=Bun.spawn(["ps","-A","-o","pid=,ppid=,args="],{stdout:"pipe",stderr:"ignore"});return{text:new Response(proc.stdout).text(),kill:()=>proc.kill()}};async function psSnapshotWith(spawn,timeoutMs=PS_PROBE_TIMEOUT_MS){let proc=spawn(),timer;try{let text=await Promise.race([proc.text,new Promise((_resolve,reject)=>{timer=setTimeout(()=>{try{proc.kill()}catch{}reject(new PsProbeUnavailableError(`ps did not answer within ${timeoutMs}ms`))},timeoutMs)})]);if(parsePsSnapshot(text).length===0)throw new PsProbeUnavailableError("ps returned no usable rows");return text}finally{if(timer)clearTimeout(timer)}}var psSnapshot=async(anchors)=>{if(process.platform!=="win32")return psSnapshotWith(bunPsSpawn);let{defaultWinProcessProbe,winProcessSnapshot}=await import("./chunk-14f459aa.js");return winProcessSnapshot(anchors??[],defaultWinProcessProbe())};async function foregroundEngine(rootPid,snapshot=psSnapshot){try{return foregroundEngineIn(parsePsSnapshot(await snapshot([rootPid])),rootPid)}catch{return null}}
|
|
4
4
|
export{vendorFromArgv,parsePsSnapshot,hasAncestor,foregroundEngineIn,engineProcessIn,PS_PROBE_TIMEOUT_MS,psSnapshotWith,psSnapshot,foregroundEngine};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{openDaemonSession,resolveActiveTaskId}from"./chunk-ya40yzp4.js";import"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-br8r72bf.js";import"./chunk-yt15y085.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{resolveActiveTaskId,openDaemonSession};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{stripTerminalControls,terminalRows}from"./chunk-etfh8f4z.js";import{OWNER_ONLY_FILE_MODE}from"./chunk-yt15y085.js";import{defaultPtyExitsPath}from"./chunk-eqdbfgq5.js";import{randomUUID}from"crypto";import{mkdirSync,readFileSync,renameSync,writeFileSync}from"fs";import{dirname}from"path";var MAX_RECORDS=50,TAIL_LINES=40,TAIL_LINE_CHARS=500;function plainTail(raw){let lines=terminalRows(raw,TAIL_LINE_CHARS);while(lines.length>0&&(lines[lines.length-1]??"").trim()==="")lines.pop();return lines.slice(-TAIL_LINES)}function engineExitCodeFromTail(tail){for(let i=tail.length-1;i>=0;i--){let m=ENGINE_EXIT_BANNER.exec(tail[i]??"");if(m?.[1])return Number.parseInt(m[1],10)}return null}var WRAPPER_BANNER_ROW=/^\s*(?:\u26A0\s*)?Engine exited \(code (\d+)\)\. Check Settings/;function wrapperBannerCodeFromTail(tail){for(let i=tail.length-1;i>=0;i--){let m=WRAPPER_BANNER_ROW.exec(tail[i]??"");if(m?.[1])return Number.parseInt(m[1],10)}return null}var ENGINE_EXIT_BANNER=/Engine exited \(code (\d+)\)/;function healTails(records){let out={};for(let[key,record]of Object.entries(records)){let tail=record?.tail;out[key]=Array.isArray(tail)?{...record,tail:tail.map((line)=>stripTerminalControls(String(line)))}:record}return out}function compareByExitAtDesc(a,b){if(a.at===b.at)return 0;return a.at<b.at?1:-1}function readPtyExitStore(path=defaultPtyExitsPath()){let read=(status,records={})=>({records,status,readable:status==="ok"||status==="absent"}),raw;try{raw=readFileSync(path,"utf8")}catch(err){return read(err.code==="ENOENT"?"absent":"unreadable")}try{let parsed=JSON.parse(raw);if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed))return read("unparsable");return read("ok",healTails(parsed))}catch{return read("unparsable")}}function readPtyExitRecords(path=defaultPtyExitsPath()){return readPtyExitStore(path).records}function recordPtyExit(info,path=defaultPtyExitsPath()){if(info.key.startsWith("::"))return;if(info.exit.code===0&&info.exit.signal===null)return;let tail=plainTail(info.tail);writeRecord(info.key,{key:info.key,pid:info.pid,code:info.exit.code??engineExitCodeFromTail(tail),signal:info.exit.signal,at:info.exit.at,tail,layer:"pty"},path)}function recordEngineExit(info,path=defaultPtyExitsPath()){if(info.key.startsWith("::"))return;let tail=plainTail(info.tail);writeRecord(`${info.key}#engine`,{key:info.key,pid:info.pid,code:engineExitCodeFromTail(tail),signal:null,at:info.at,tail,layer:"engine",...info.vendor?{vendor:info.vendor}:{},...info.atApproximate?{atApproximate:!0}:{},parentAlive:!0},path)}function writeRecord(storeKey,record,path){let store=readPtyExitStore(path);if(store.status==="unreadable")throw Error(`pty-exits store is unreadable (${path}) \u2014 refusing to overwrite it`);let records=store.records;records[storeKey]=record;let newest=Object.entries(records).sort(([,a],[,b])=>compareByExitAtDesc(a,b)).slice(0,MAX_RECORDS);mkdirSync(dirname(path),{recursive:!0});let tmp=`${path}.tmp-${process.pid}-${randomUUID()}`;writeFileSync(tmp,JSON.stringify(Object.fromEntries(newest),null,2),{encoding:"utf8",mode:OWNER_ONLY_FILE_MODE}),renameSync(tmp,path)}
|
|
3
|
+
export{plainTail,engineExitCodeFromTail,wrapperBannerCodeFromTail,ENGINE_EXIT_BANNER,compareByExitAtDesc,readPtyExitStore,readPtyExitRecords,recordPtyExit,recordEngineExit};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{StaleInstallError,autospawnDaemonEnv,connectIfRunning,connectOrStartDaemon,daemonSpawnReason,ensureDaemonReachable,isStaleInstallError,probeDaemonSocket,resolveRoveSpawn,testDaemonResponds,tryAcquireSpawnLock}from"./chunk-
|
|
2
|
+
import{StaleInstallError,autospawnDaemonEnv,connectIfRunning,connectOrStartDaemon,daemonSpawnReason,ensureDaemonReachable,isStaleInstallError,probeDaemonSocket,resolveRoveSpawn,testDaemonResponds,tryAcquireSpawnLock}from"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-br8r72bf.js";import"./chunk-yt15y085.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{tryAcquireSpawnLock,testDaemonResponds,resolveRoveSpawn,probeDaemonSocket,isStaleInstallError,ensureDaemonReachable,daemonSpawnReason,connectOrStartDaemon,connectIfRunning,autospawnDaemonEnv,StaleInstallError};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{GitWorktreeManager}from"./chunk-
|
|
2
|
+
import{GitWorktreeManager}from"./chunk-pa02bxsz.js";import"./chunk-jad2z4hd.js";import"./chunk-gq36nzg8.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y1xnjx8x.js";import"./chunk-catrr0z3.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-2brn8e1y.js";import"./chunk-7kysxgbq.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{GitWorktreeManager};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{readlinkSync}from"fs";function parseLsofCwd(output){for(let line of output.split(`
|
|
3
|
+
`))if(line.startsWith("n")&&line.length>1)return line.slice(1);return null}var lsofCwd=async(pid)=>{let proc=Bun.spawn(["lsof","-a","-p",String(pid),"-d","cwd","-Fn"],{stdout:"pipe",stderr:"ignore"});return await new Response(proc.stdout).text()};async function processCwd(pid,lsof=lsofCwd){if(!Number.isInteger(pid)||pid<=0)return null;try{return readlinkSync(`/proc/${pid}/cwd`)}catch{}try{return parseLsofCwd(await lsof(pid))}catch{return null}}
|
|
4
|
+
export{processCwd};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{INBOUND_CLASSES,INBOUND_KEY,deniedClasses,inboundClassOf,inboundRefusal,setInbound}from"./chunk-mk2z5z32.js";import"./chunk-90qs5xae.js";import"./chunk-qr28azaj.js";import"./chunk-rctyty5x.js";import"./chunk-mmw2py0h.js";import"./chunk-8kewg6t3.js";import"./chunk-p6jw0zcd.js";import"./chunk-ya40yzp4.js";import"./chunk-17e2tgyg.js";import"./chunk-q9zgj6kw.js";import"./chunk-jad2z4hd.js";import"./chunk-7z463zkx.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-chdjytvm.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-atbwdgg6.js";import"./chunk-atn06ncf.js";import"./chunk-ydp0jtt5.js";import"./chunk-qkehg2c1.js";import"./chunk-9seey8kp.js";import"./chunk-a677tj7e.js";import"./chunk-09w9843b.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-aqqm68bd.js";import"./chunk-e94kap9x.js";import"./chunk-fvvb0072.js";import"./chunk-sdwdhnkv.js";import"./chunk-rxqdw6s5.js";import"./chunk-tn9gtf18.js";import"./chunk-yzkhwn31.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-2rbb1tpm.js";import"./chunk-fsd00eqa.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-zsfyj36g.js";import"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-8ahayecf.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-1s0ng45a.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-47mz8nd4.js";import"./chunk-t65y2j9c.js";import"./chunk-cmp64q4j.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{setInbound,inboundRefusal,inboundClassOf,deniedClasses,INBOUND_KEY,INBOUND_CLASSES};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{ConnectTimeoutError,RoveDaemonClient,RpcTimeoutError}from"./chunk-
|
|
2
|
+
import{ConnectTimeoutError,RoveDaemonClient,RpcTimeoutError}from"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{RpcTimeoutError,RoveDaemonClient,ConnectTimeoutError};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-
|
|
2
|
+
import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-t65y2j9c.js";import{createStateCell}from"./chunk-cmp64q4j.js";function lookup(catalog,key){let node=catalog;for(let part of key.split("."))if(node&&typeof node==="object"&&part in node)node=node[part];else return;return typeof node==="string"?node:void 0}function interpolate(template,params){if(!params)return template;return template.replace(/\{(\w+)\}/g,(whole,name)=>(name in params)?String(params[name]):whole)}function lookupKeys(catalog,group,key){return catalog.keys[group]?.[key]}var langState=createStateCell(DEFAULT_LOCALE);function setLocaleLang(lang){if(CATALOGS[lang])langState.set(lang)}function currentLang(){return langState.get()}function intlLocale(){return LOCALES.find((locale)=>locale.id===langState.get())?.intl??"en-US"}function localeState(){return langState}var pluginNamespaces=new Set;function registerMessages(namespace,messages){let en=CATALOGS.en,zh=CATALOGS.zh;if(namespace in en&&!pluginNamespaces.has(namespace))throw Error(`i18n namespace "${namespace}" belongs to the host`);if(pluginNamespaces.add(namespace),en[namespace]=messages.en,messages.zh)zh[namespace]=messages.zh;else delete zh[namespace]}function t(key,params){let lang=langState.get(),resolved=lookup(CATALOGS[lang],key)??lookup(CATALOGS.en,key)??key;return interpolate(resolved,params)}function tKeys(group,key){let lang=langState.get();return lookupKeys(CATALOGS[lang],group,key)??lookupKeys(CATALOGS.en,group,key)??key}
|
|
3
3
|
export{setLocaleLang,currentLang,intlLocale,localeState,registerMessages,t,tKeys};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{ensureGlobalRoveHooks,readStdinText,readTextWithTimeout,runHookSubcommand}from"./chunk-4v9rdjd1.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-chdjytvm.js";import"./chunk-j1z9kgyd.js";import"./chunk-fsd00eqa.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-zsfyj36g.js";import"./chunk-s0m4x06j.js";import"./chunk-19wfsxps.js";import"./chunk-6853bkm5.js";import"./chunk-2brn8e1y.js";import"./chunk-8ahayecf.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{runHookSubcommand,readTextWithTimeout,readStdinText,ensureGlobalRoveHooks};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{t}from"./chunk-
|
|
2
|
+
import{t}from"./chunk-47mz8nd4.js";function failureHint(error,cliName="rove"){let details=typeof error==="object"&&error!==null?error:null,hint=details&&"hint"in details&&typeof details.hint==="string"?details.hint:null,args=details&&"nextCommandArgs"in details?details.nextCommandArgs:null,command=Array.isArray(args)&&args.length>0&&args.every((arg)=>typeof arg==="string")?[cliName,...args].map((arg)=>/^[\w./:@=-]+$/.test(arg)?arg:`'${arg.replaceAll("'","'\\''")}'`).join(" "):null;return[hint,command].filter(Boolean).join(`
|
|
3
3
|
`)||t("common.failureHint",{command:`${cliName} doctor`})}
|
|
4
4
|
export{failureHint};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Orchestrator}from"./chunk-
|
|
2
|
+
import{Orchestrator}from"./chunk-d8t0xmjh.js";import"./chunk-t84br978.js";import"./chunk-pa02bxsz.js";import"./chunk-c1dz3qg3.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-q9zgj6kw.js";import"./chunk-jad2z4hd.js";import"./chunk-gq36nzg8.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y1xnjx8x.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-2tfnscxk.js";import"./chunk-h8t4xg1p.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-2brn8e1y.js";import"./chunk-7kysxgbq.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-cmp64q4j.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{PLACEHOLDER_TASK_TITLE,Orchestrator};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{isEngineActivityKind}from"./chunk-17e2tgyg.js";import{loadPluginRegistry,readPluginManifest}from"./chunk-
|
|
2
|
+
import{isEngineActivityKind}from"./chunk-17e2tgyg.js";import{loadPluginRegistry,readPluginManifest}from"./chunk-chdjytvm.js";import{activityHookAdapters}from"./chunk-fsd00eqa.js";import{flagValue}from"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-s0m4x06j.js";import{getPersistedString,setPersistedString}from"./chunk-rfp0ayra.js";import{readRoveEnv}from"./chunk-nc46gddg.js";import{join,resolve}from"path";var STDIN_READ_TIMEOUT_MS=500;async function readTextWithTimeout(read,timeoutMs=STDIN_READ_TIMEOUT_MS){let raceTimer;try{return await Promise.race([read(),new Promise((resolve2)=>{raceTimer=setTimeout(()=>resolve2(""),timeoutMs)})])}finally{if(raceTimer!==void 0)clearTimeout(raceTimer)}}async function readStdinText(isComplete){let bun=globalThis.Bun;if(bun)return bun.stdin.text();if(process.stdin.isTTY)return"";let chunks=[];try{for await(let chunk of process.stdin)if(chunks.push(chunk),isComplete?.(Buffer.concat(chunks).toString("utf8")))break}finally{process.stdin.destroy()}return Buffer.concat(chunks).toString("utf8")}function isCompleteJson(text){try{return JSON.parse(text),!0}catch{return!1}}async function readStdinPayload(){try{let text=await readTextWithTimeout(()=>readStdinText(isCompleteJson));if(!text.trim())return{};let parsed=JSON.parse(text);return parsed&&typeof parsed==="object"&&!Array.isArray(parsed)?parsed:{}}catch{return{}}}async function runHookSubcommand(argv){let[verb,...rest]=argv;if(verb==="setup"){await runHookSetup(rest);return}if(verb==="cleanup"){await runHookCleanup();return}try{if(!verb||!isEngineActivityKind(verb))return;let payload=await readStdinPayload(),payloadFlag=flagValue(rest,"--payload");if(payloadFlag)try{let extra=JSON.parse(payloadFlag);if(extra&&typeof extra==="object"&&!Array.isArray(extra))Object.assign(payload,extra)}catch{}let taskId=flagValue(rest,"--task-id"),envTaskId=process.env.ROVE_TASK_ID,envTabId=process.env.ROVE_TAB_ID,engine=flagValue(rest,"--engine"),adapters=activityHookAdapters().filter((a)=>!engine||a.vendor===engine);if(!taskId&&adapters.some((a)=>a.isUnattendedSession?.(process.env)===!0))return;let cwd=typeof payload.cwd==="string"&&payload.cwd?payload.cwd:void 0;for(let adapter of adapters){if(cwd)break;cwd=adapter.cwdFromPayload?.(payload)}cwd||=process.cwd();let detail;for(let adapter of adapters)if(detail=adapter.activityDetailFromPayload(verb,payload),detail)break;let session;for(let adapter of adapters)if(session=adapter.sessionFromPayload(payload),session)break;let client=await connectIfRunning();if(!client)return;try{let effectiveTaskId=taskId??envTaskId;await client.request("engine.reportEvent",{...effectiveTaskId?{taskId:effectiveTaskId}:{cwd},kind:verb,...engine?{engine}:{},...envTabId?{tabId:envTabId}:{},...detail?{detail}:{},...session?{sessionId:session.sessionId}:{},...session?.transcriptPath?{transcriptPath:session.transcriptPath}:{}})}finally{client.close()}}catch(err){if(readRoveEnv("HOOK_DEBUG"))console.error(`[rove hook] ${verb} failed:`,err instanceof Error?err.message:String(err))}}var SYNC_SETTING_KEY="externalWorktreeSync";function worktreeSyncAdapters(){return activityHookAdapters().filter((a)=>a.supportsWorktreeSync())}function globalSettingsPath(){return worktreeSyncAdapters()[0]?.globalSettingsPath()}function persistedSyncPath(stored){if(!stored||stored==="off")return;if(stored==="global")return globalSettingsPath();if(stored.startsWith("repo:"))return join(resolve(stored.slice(5)),".claude","settings.json");return stored}async function ensureGlobalRoveHooks(opts={}){try{let toolEvents=pluginsWantToolEvents();for(let a of activityHookAdapters()){let external=await a.externallyManagedHooks?.();if(external){if(external.notice)process.stderr.write(`
|
|
3
3
|
${external.notice}
|
|
4
4
|
`);continue}let enginePath=a.globalSettingsPath();if(!enginePath)continue;await a.installActivityHooks(enginePath,{toolEvents,quiet:opts.quiet}),await a.removeWorktreeWatchHook(enginePath)}await cleanupWorktreeSyncHook()}catch{}}function pluginsWantToolEvents(){try{for(let entry of loadPluginRegistry().plugins){if(!entry.enabled)continue;try{if(readPluginManifest(entry.root).manifest.events.some((e)=>e.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function cleanupWorktreeSyncHook(){let adapters=worktreeSyncAdapters();if(adapters.length===0)return;let stored=getPersistedString(SYNC_SETTING_KEY),paths=new Set;for(let adapter of adapters){let file=adapter.globalSettingsPath();if(file)paths.add(file)}let prev=persistedSyncPath(stored);if(prev)paths.add(prev);for(let a of adapters)for(let p of paths)await a.removeWorktreeSyncHook(p);if(stored!=="off")setPersistedString(SYNC_SETTING_KEY,"off")}async function runHookCleanup(){let claude=activityHookAdapters().find((a)=>a.vendor==="claude"),path=claude?.globalSettingsPath();if(!claude||!path){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
|
|
5
5
|
`);return}await claude.removeActivityHooks(path),await claude.removeWorktreeWatchHook(path),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${path}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{ensurePluginEnginesLoaded,loadPluginEngines,registeredEngineIds,reloadPluginEngines}from"./chunk-rctyty5x.js";import"./chunk-chdjytvm.js";import"./chunk-j1z9kgyd.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{reloadPluginEngines,registeredEngineIds,loadPluginEngines,ensurePluginEnginesLoaded};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{machineTasks}from"./chunk-
|
|
2
|
+
import{machineTasks}from"./chunk-pzcfbed5.js";import"./chunk-s9agkh7g.js";import"./chunk-sq6zj3fb.js";import{dedupeMachines,listMachines}from"./chunk-s4nrmbqh.js";import"./chunk-ydp0jtt5.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-2brn8e1y.js";import"./chunk-7kysxgbq.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-bvkj97zw.js";import"./chunk-f2bqrzsy.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";async function mergeTaskList(local){let machines=dedupeMachines(listMachines());if(machines.length===0)return local;let tasks=(local.tasks??[]).map((task)=>({...task,origin:{machineId:"local",hostLabel:"local"}}));for(let entry of machines){let remote=await machineTasks(entry);if(!remote)continue;let hostLabel=entry.alias;for(let task of remote)tasks.push({...task,origin:{machineId:entry.alias,hostLabel}})}return{tasks}}export{mergeTaskList};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{PS_PROBE_TIMEOUT_MS,engineProcessIn,foregroundEngine,foregroundEngineIn,hasAncestor,parsePsSnapshot,psSnapshot,psSnapshotWith,vendorFromArgv}from"./chunk-2rbb1tpm.js";import"./chunk-fsd00eqa.js";import"./chunk-thn3ch8q.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-2brn8e1y.js";import"./chunk-8ahayecf.js";import"./chunk-yrvbypfv.js";import"./chunk-7kysxgbq.js";import"./chunk-e0r4qk4k.js";import"./chunk-2cg3b07h.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import"./chunk-91sykzqq.js";export{vendorFromArgv,psSnapshotWith,psSnapshot,parsePsSnapshot,hasAncestor,foregroundEngineIn,foregroundEngine,engineProcessIn,PsProbeUnavailableError,PS_PROBE_TIMEOUT_MS};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{RoveDaemonClient}from"./chunk-
|
|
2
|
+
import{RoveDaemonClient}from"./chunk-bvkj97zw.js";import{defaultDaemonSocketPath,defaultPtyHostSocketPath}from"./chunk-eqdbfgq5.js";import{spawn}from"child_process";import{existsSync}from"fs";import{join}from"path";var LAUNCH_CMD_ENV="ROVE_LAUNCH_CMD",LAUNCH_LOG_ENV="ROVE_LAUNCH_LOG",WIN_DETACHED_LAUNCHER_PS=`
|
|
3
3
|
$ErrorActionPreference = 'Stop'
|
|
4
4
|
$cmd = $env:${LAUNCH_CMD_ENV}
|
|
5
5
|
$log = $env:${LAUNCH_LOG_ENV}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{ENGINE_EXIT_BANNER,compareByExitAtDesc,engineExitCodeFromTail,plainTail,readPtyExitRecords,readPtyExitStore,recordEngineExit,recordPtyExit,wrapperBannerCodeFromTail}from"./chunk-2w228s7t.js";import"./chunk-etfh8f4z.js";import"./chunk-yt15y085.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{wrapperBannerCodeFromTail,recordPtyExit,recordEngineExit,readPtyExitStore,readPtyExitRecords,plainTail,engineExitCodeFromTail,compareByExitAtDesc,ENGINE_EXIT_BANNER};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{detectShell,installCompletions,recordWelcomeChoices,runPendingWelcomeInstalls,settleWelcomeInstall}from"./chunk-
|
|
2
|
+
import{detectShell,installCompletions,recordWelcomeChoices,runPendingWelcomeInstalls,settleWelcomeInstall}from"./chunk-k16apnx4.js";import"./chunk-059cbe7h.js";import"./chunk-0rrmz6k6.js";import"./chunk-tjj9bt7n.js";import"./chunk-1s0ng45a.js";import"./chunk-fpbwx721.js";import"./chunk-rfp0ayra.js";import"./chunk-40dgv828.js";import"./chunk-7mwvvj46.js";import"./chunk-32j6y5d1.js";import"./chunk-bejhca6z.js";import"./chunk-br8r72bf.js";import"./chunk-z1nj22va.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-47mz8nd4.js";import"./chunk-t65y2j9c.js";import"./chunk-cmp64q4j.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{settleWelcomeInstall,runPendingWelcomeInstalls,recordWelcomeChoices,installCompletions,detectShell};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{__require}from"./chunk-91sykzqq.js";var CHANNEL_LOADERS={weixin:async()=>(await import("./chunk-
|
|
2
|
+
import{__require}from"./chunk-91sykzqq.js";var CHANNEL_LOADERS={weixin:async()=>(await import("./chunk-bdr2hq79.js")).default};async function runChannelCli(id,argv){let load=CHANNEL_LOADERS[id];if(!load)throw Error(`no chat channel "${id}"`);await(await load()).runCli(argv)}async function startChatChannels(ctx){let started=[];for(let[id,load]of Object.entries(CHANNEL_LOADERS))try{let channel=(await load()).createChannel();await channel.start(ctx),started.push(channel)}catch(err){ctx.log("channel",`${id} did not start: ${err instanceof Error?err.message:String(err)}`)}return started}
|
|
3
3
|
export{runChannelCli,startChatChannels};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{managedWorktreeRootsFor,readWorktreeBaseOverride}from"./chunk-gq36nzg8.js";import{pathIdentity,pathSyntax,pathWithin,samePath}from"./chunk-pn5ygqn6.js";import{existsSync}from"fs";import path from"path";function ownerFirst(a,b){let rank=(t)=>t.sharesWorkspaceOf?1:0;return rank(a)-rank(b)||(a.id<b.id?-1:a.id>b.id?1:0)}function resolvePtyOwner(tasks,taskId,tabId){if(!tabId)return taskId;return tasks.find((t)=>t.ptyAlias?.taskId===taskId&&t.ptyAlias.tabId===tabId)?.id??taskId}function crossesRepoBoundary(wt,cwd){let syntax=pathSyntax(cwd);for(let dir=cwd;!samePath(dir,wt);dir=syntax.dirname(dir)){if(existsSync(syntax.join(dir,".git")))return!0;if(samePath(dir,syntax.dirname(dir)))break}return!1}function worktreesOf(t){return[t.worktreePath,...(t.extraRepos??[]).map((x)=>x.worktreePath)].filter((p)=>!!p)}function matchTaskByCwd(tasks,cwd){let target=pathIdentity(cwd),best,bestWt="";for(let t of tasks)for(let worktree of worktreesOf(t)){let wt=pathIdentity(worktree);if(pathWithin(wt,target)===null)continue;if(!best||wt.length>bestWt.length||wt.length===bestWt.length&&ownerFirst(t,best)<0)best=t,bestWt=wt}if(best&&crossesRepoBoundary(bestWt,target))return;return best?.id}function tasksAtWorktreePath(tasks,worktreePath){let target=pathIdentity(worktreePath);return tasks.filter((t)=>worktreesOf(t).some((wt)=>pathIdentity(wt)===target)).sort(ownerFirst).map((t)=>t.id)}function findAdoptableWorktree(tasks,cwd){let target=pathIdentity(cwd),repos=new Set,known=new Set;for(let t of tasks){if(t.repo&&path.isAbsolute(t.repo))repos.add(pathIdentity(t.repo));for(let wt of worktreesOf(t))known.add(pathIdentity(wt))}for(let repo of repos)for(let root of managedWorktreeRootsFor(repo,readWorktreeBaseOverride(repo)).map(pathIdentity)){let prefix=root.endsWith("/")?root:`${root}/`,rest=pathWithin(root,target);if(!rest)continue;let name=rest.split("/")[0];if(!name)continue;let worktreePath=`${prefix}${name}`;if(known.has(worktreePath))return;return{repo,worktreePath}}return}var DISPATCH_PROMPT_HEAD_CHARS=160;var SETTLED=new Set(["done","failed"]);function next(status,state){if(state==="error"||state==="dead")return"failed";if(state==="running"&&(status==="delivered"||status==="asking"))return"working";if(state==="permission_needed"&&(status==="delivered"||status==="working"))return"asking";if((state==="turn_complete"||state==="idle")&&(status==="working"||status==="asking"))return"done";return}class DispatchLedger{bus;rows=[];seq=1;rev=0;expiry=null;off;now;constructor(bus,now){this.bus=bus;this.now=now??Date.now,this.off=bus.onPublish((event)=>{if(event.channel==="engine-state")this.take(event.payload)})}list(){return{rows:this.rows,rev:this.rev}}record(input){let at=this.now(),row={id:`x-${this.seq++}`,kind:input.kind,from:input.from,...input.routine?{routine:input.routine}:{},to:input.to,promptHead:input.promptHead.replace(/\s+/g," ").trim().slice(0,160),at,status:input.delivered?"delivered":"failed",statusAt:at,...input.reason?{reason:input.reason}:{},...input.deliveryId?{deliveryId:input.deliveryId}:{}};return this.rows=[...this.rows,row],this.publish(),row}close(){this.off(),this.clearExpiry()}take(payload){let p=payload;if(typeof p.taskId!=="string"||typeof p.state!=="string")return;let tabId=typeof p.tabId==="string"&&p.tabId?p.tabId:null,at=typeof p.at==="number"?p.at:this.now(),changed=!1;if(this.rows=this.rows.map((row)=>{if(SETTLED.has(row.status)||row.to.taskId!==p.taskId||at<row.at)return row;if(row.to.tabId!==null&&tabId!==null&&row.to.tabId!==tabId)return row;let status=next(row.status,p.state);if(!status)return row;return changed=!0,{...row,to:row.to.tabId===null&&tabId!==null?{...row.to,tabId}:row.to,status,statusAt:at,...status==="failed"?{reason:p.state}:{}}}),changed)this.publish()}publish(){this.rows=prune(this.rows,this.now()),this.rev+=1,this.bus.publish("dispatch.snapshot",this.list()),this.scheduleExpiry()}scheduleExpiry(){this.clearExpiry();let open=this.rows.filter((r)=>!SETTLED.has(r.status));if(open.length===0)return;let due=Math.min(...open.map((r)=>r.statusAt))+21600000;this.expiry=setTimeout(()=>{if(this.expiry=null,prune(this.rows,this.now()).length!==this.rows.length)this.publish();else this.scheduleExpiry()},Math.max(0,due-this.now())),this.expiry.unref?.()}clearExpiry(){if(this.expiry)clearTimeout(this.expiry);this.expiry=null}}function prune(rows,now){let open=rows.filter((r)=>!SETTLED.has(r.status)&&now-r.statusAt<21600000).slice(-100),settled=rows.filter((r)=>SETTLED.has(r.status)).slice(-40),keep=new Set([...open,...settled]);return rows.filter((r)=>keep.has(r))}function ownEngineTabs(tabs){return tabs.filter((tab)=>tab.kind==="engine"&&tab.ptyTask===void 0)}function canonicalEngineTab(tabs){let own=ownEngineTabs(tabs);return own.find((tab)=>tab.id==="tab-1")??own[0]}
|
|
3
|
+
export{DISPATCH_PROMPT_HEAD_CHARS,DispatchLedger,resolvePtyOwner,matchTaskByCwd,tasksAtWorktreePath,findAdoptableWorktree,ownEngineTabs,canonicalEngineTab};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{JsonHookAdapter,editJsonSettings,removeRoveHooks,vendorConfigHome}from"./chunk-
|
|
2
|
+
import{JsonHookAdapter,editJsonSettings,removeRoveHooks,vendorConfigHome}from"./chunk-yrvbypfv.js";import{isObject}from"./chunk-7ghwdjdc.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{__require}from"./chunk-91sykzqq.js";import{join}from"path";var CLAUDE_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"StopFailure",verb:"turn-failed"},{event:"Notification",matcher:"permission_prompt",verb:"awaiting-input"},{event:"Notification",matcher:"elicitation_dialog",verb:"awaiting-input"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"},{event:"PostToolUseFailure",verb:"tool-failed"}],ROVE_HOOK_EVENTS=[...new Set(CLAUDE_HOOK_EVENT_MAP.map((e)=>e.event))];function failureFromErrorType(errorType){if(typeof errorType!=="string")return"other";if(errorType==="rate_limit"||errorType==="overloaded")return"rate_limit";if(errorType==="billing_error")return"billing";return"other"}function claudeSettingsPath(){return join(vendorConfigHome("claude"),"settings.json")}var WORKTREE_SYNC_VERB="worktree-created";function mergeWorktreeSyncHook(current,command){let{hooks:rawHooks,...restSettings}=current,{WorktreeCreate,...otherHooks}=isObject(rawHooks)?rawHooks:{},prior=Array.isArray(WorktreeCreate)?WorktreeCreate:[],kept=removeRoveHooks(prior,[WORKTREE_SYNC_VERB]);if(command!==null)kept.push({hooks:[{type:"command",command}]});let nextHooks={...otherHooks};if(kept.length>0)nextHooks.WorktreeCreate=kept;return Object.keys(nextHooks).length>0?{...restSettings,hooks:nextHooks}:{...restSettings}}class ClaudeHookAdapter extends JsonHookAdapter{vendor="claude";eventMap=CLAUDE_HOOK_EVENT_MAP;globalSettingsPath(){return claudeSettingsPath()}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return{failure:failureFromErrorType(payload.error_type)};if(kind==="awaiting-input")return{waiting:payload.notification_type==="elicitation_dialog"?"input":"permission"};if(kind==="tool-pre"||kind==="tool-post"||kind==="tool-failed")return{tool:{...typeof payload.tool_name==="string"?{name:payload.tool_name}:{},...typeof payload.tool_use_id==="string"?{id:payload.tool_use_id}:{}}};if(kind==="pre-compact"||kind==="post-compact")return{compact:{trigger:payload.trigger==="manual"?"manual":"auto"}};if(kind==="subagent-start"||kind==="subagent-stop")return{subagent:{...typeof payload.agent_type==="string"?{type:payload.agent_type}:{},...typeof payload.agent_id==="string"?{id:payload.agent_id}:{}}};return}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}isUnattendedSession(env){return env.CLAUDE_CODE_SESSION_ATTENDED==="0"}async externallyManagedHooks(){let{isRovePluginEnabled,detectLegacyInstalls,migrationHint}=await import("./chunk-1hrbef9y.js");if(!isRovePluginEnabled())return;let notice=migrationHint(detectLegacyInstalls(),ROVE_PRODUCT_NAME);return notice?{notice}:{}}supportsWorktreeSync(){return!0}async removeWorktreeSyncHook(settingsFilePath){await editJsonSettings(settingsFilePath,(cur)=>mergeWorktreeSyncHook(cur,null))}}
|
|
3
3
|
export{CLAUDE_HOOK_EVENT_MAP,claudeSettingsPath,ClaudeHookAdapter};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{interactiveEngineCommand,listPresetIds}from"./chunk-
|
|
2
|
+
import{interactiveEngineCommand,listPresetIds}from"./chunk-aqqm68bd.js";import{engineEntry}from"./chunk-fsd00eqa.js";import{installedEngineIds}from"./chunk-thn3ch8q.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{detectEngineStatus,detectEngineStatuses,describeAccount,probeableEngineIds,summarizeEngines};
|