@sma1lboy/rove 0.9.267 → 0.9.269
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-awgsda64.js → chunk-05setecs.js} +1 -1
- package/dist/cli/{chunk-zg66t7k9.js → chunk-0hz4nksf.js} +1 -1
- package/dist/cli/{chunk-vd6z4v6p.js → chunk-0wewpk99.js} +1 -1
- package/dist/cli/{chunk-2jzaabcy.js → chunk-0yxwm4g1.js} +3 -3
- package/dist/cli/{chunk-5vetsh77.js → chunk-1ndxmtqf.js} +1 -1
- package/dist/cli/{chunk-a4znycsh.js → chunk-25s2c5yf.js} +1 -1
- package/dist/cli/{chunk-4kdakncb.js → chunk-3jzncprm.js} +1 -1
- package/dist/cli/{chunk-gs6j7y6q.js → chunk-3kgbyr0h.js} +1 -1
- package/dist/cli/{chunk-xex81qeb.js → chunk-3sn0atsa.js} +1 -1
- package/dist/cli/{chunk-4bfwafzg.js → chunk-41yc90sq.js} +1 -1
- package/dist/cli/{chunk-7maf6x1g.js → chunk-426pyw4x.js} +1 -1
- package/dist/cli/{chunk-fcnd49ce.js → chunk-4b6r81r7.js} +1 -1
- package/dist/cli/{chunk-s3cvbp3a.js → chunk-4f4vr50c.js} +1 -1
- package/dist/cli/{chunk-57qny54a.js → chunk-4kmj6ct5.js} +1 -1
- package/dist/cli/{chunk-ke19jzhg.js → chunk-4tt3zaj1.js} +2 -2
- package/dist/cli/{chunk-5r4d0h87.js → chunk-4w6vx3t5.js} +1 -1
- package/dist/cli/{chunk-0t0ykzek.js → chunk-4xdmsp30.js} +1 -1
- package/dist/cli/{chunk-p4fjynez.js → chunk-548fwbx3.js} +1 -1
- package/dist/cli/{chunk-fcqtqpm1.js → chunk-56gk0jtk.js} +1 -1
- package/dist/cli/{chunk-npnbq79j.js → chunk-58j49536.js} +1 -1
- package/dist/cli/{chunk-z7d7gk7p.js → chunk-690thwab.js} +1 -1
- package/dist/cli/chunk-6rdvvbyv.js +3 -0
- package/dist/cli/{chunk-2a19815h.js → chunk-7qkwtkbr.js} +1 -1
- package/dist/cli/chunk-7s2zdhmw.js +20 -0
- package/dist/cli/{chunk-p9t6ye6t.js → chunk-93e1q2ea.js} +1 -1
- package/dist/cli/{chunk-n2j5sk0g.js → chunk-9qy0t3xv.js} +1 -1
- package/dist/cli/{chunk-a0rz9g11.js → chunk-a7a4pn72.js} +1 -1
- package/dist/cli/{chunk-0fejmkz1.js → chunk-adj7j1ta.js} +1 -1
- package/dist/cli/{chunk-qykg15ks.js → chunk-bc9qfm8g.js} +1 -1
- package/dist/cli/{chunk-mvnz68vh.js → chunk-bsfxja9s.js} +1 -1
- package/dist/cli/{chunk-02htajas.js → chunk-c4d1mma0.js} +2 -2
- package/dist/cli/chunk-cpgnm1xr.js +3 -0
- package/dist/cli/{chunk-tst79jmx.js → chunk-dc842he4.js} +1 -1
- package/dist/cli/{chunk-s7mzpdgb.js → chunk-dj742g75.js} +1 -1
- package/dist/cli/{chunk-bm2baazf.js → chunk-ezeh37vd.js} +1 -1
- package/dist/cli/{chunk-nw4p86t1.js → chunk-f8vpvcw3.js} +1 -1
- package/dist/cli/{chunk-1z1tjqyy.js → chunk-g01bct19.js} +1 -1
- package/dist/cli/{chunk-pv2334ak.js → chunk-h26z4573.js} +1 -1
- package/dist/cli/chunk-hnk8rzvz.js +2 -0
- package/dist/cli/chunk-j8bmc7m0.js +33 -0
- package/dist/cli/{chunk-jp8vfwqm.js → chunk-jravy0cc.js} +1 -1
- package/dist/cli/{chunk-f8w52tsz.js → chunk-k4s0y0j2.js} +2 -2
- package/dist/cli/{chunk-y7a8h5xe.js → chunk-k9vmkdt5.js} +1 -1
- package/dist/cli/{chunk-twjt04z3.js → chunk-kc3e07fn.js} +1 -1
- package/dist/cli/{chunk-3gegmpff.js → chunk-kj37wrjn.js} +1 -1
- package/dist/cli/{chunk-axjcmamn.js → chunk-kntxg017.js} +1 -1
- package/dist/cli/{chunk-5m1ef9ez.js → chunk-m2q3dver.js} +2 -2
- package/dist/cli/{chunk-pxdnc5mz.js → chunk-mgweygem.js} +9 -4
- package/dist/cli/{chunk-835qwnnq.js → chunk-mk8r6pcx.js} +1 -1
- package/dist/cli/{chunk-hy0r635n.js → chunk-n7k9ey12.js} +3 -3
- package/dist/cli/{chunk-ra1m0gs4.js → chunk-n7t7eqcz.js} +1 -1
- package/dist/cli/{chunk-6xsc9crp.js → chunk-n8am3mgq.js} +1 -1
- package/dist/cli/{chunk-qeya7dv5.js → chunk-nahwgea8.js} +1 -1
- package/dist/cli/chunk-pr22s2c3.js +3 -0
- package/dist/cli/{chunk-cangy5wn.js → chunk-q49ak80d.js} +1 -1
- package/dist/cli/{chunk-fjvefbnr.js → chunk-rk6tm9zq.js} +4 -4
- package/dist/cli/{chunk-3xrbb1yv.js → chunk-s7189j1a.js} +1 -1
- package/dist/cli/{chunk-gg5f2ayw.js → chunk-stzqewh7.js} +1 -1
- package/dist/cli/{chunk-wd9n7cwz.js → chunk-swyrqtss.js} +1 -1
- package/dist/cli/{chunk-84m0d72d.js → chunk-tbh2rvv7.js} +1 -1
- package/dist/cli/{chunk-ga412sby.js → chunk-tbpj22sn.js} +1 -1
- package/dist/cli/{chunk-bvsjep6w.js → chunk-v8z4xnar.js} +1 -1
- package/dist/cli/chunk-vsdp96f6.js +4 -0
- package/dist/cli/{chunk-wa7jswp3.js → chunk-vskqfw9w.js} +1 -1
- package/dist/cli/{chunk-2geegpp7.js → chunk-wewwz4ky.js} +1 -1
- package/dist/cli/{chunk-hf168gph.js → chunk-wk46aet7.js} +1 -1
- package/dist/cli/{chunk-ak0frbbw.js → chunk-wrmjgk0h.js} +1 -1
- package/dist/cli/{chunk-gytx47yk.js → chunk-wtakvjax.js} +1 -1
- package/dist/cli/{chunk-zy2jdze4.js → chunk-y9khj120.js} +1 -1
- package/dist/cli/{chunk-mj7nfaaf.js → chunk-y9kq9x48.js} +1 -1
- package/dist/cli/{chunk-7ag59vyh.js → chunk-yjmb0arx.js} +1 -1
- package/dist/cli/{chunk-r0etc6vp.js → chunk-yytjrrdh.js} +1 -1
- package/dist/cli/{chunk-xymn760d.js → chunk-zcf25k4x.js} +25 -9
- package/dist/cli/{chunk-s4ghfrr9.js → chunk-zgptbz75.js} +1 -1
- package/dist/cli/{chunk-ghkr7f4t.js → chunk-zrvsp7tg.js} +1 -1
- package/dist/cli/{chunk-ankt6yse.js → chunk-ztwwknwe.js} +1 -1
- package/dist/cli/{chunk-2gc4kqrt.js → chunk-zzetyab8.js} +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/cli/rove.js +1 -1
- package/dist/skills/rove/SKILL.md +1 -1
- package/dist/skills/rove/references/api-flags.md +2 -2
- package/dist/web/assets/{index-BM0Pt6E-.js → index-DbHHaD17.js} +2 -2
- package/dist/web/index.html +1 -1
- package/package.json +3 -3
- package/dist/cli/chunk-85m74thf.js +0 -31
- package/dist/cli/chunk-e7h7w4n0.js +0 -4
- package/dist/cli/chunk-r67c54hn.js +0 -2
- package/dist/cli/chunk-rn08whn3.js +0 -20
- package/dist/cli/chunk-xt543e2h.js +0 -3
- package/dist/cli/chunk-yfvt96ar.js +0 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{INBOUND_CLASSES,INBOUND_KEY,deniedClasses,inboundClassOf,inboundRefusal,setInbound}from"./chunk-
|
|
2
|
+
import{INBOUND_CLASSES,INBOUND_KEY,deniedClasses,inboundClassOf,inboundRefusal,setInbound}from"./chunk-dj742g75.js";import"./chunk-rk6tm9zq.js";import"./chunk-zrvsp7tg.js";import"./chunk-av482xxw.js";import"./chunk-kwyxwcr8.js";import"./chunk-4b6r81r7.js";import"./chunk-p6jw0zcd.js";import"./chunk-heajz5tw.js";import"./chunk-17e2tgyg.js";import"./chunk-eyrt04mg.js";import"./chunk-mzk4p07t.js";import"./chunk-4f4vr50c.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-a569ctz6.js";import"./chunk-pr22s2c3.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-kc3e07fn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-nahwgea8.js";import"./chunk-n7t7eqcz.js";import"./chunk-93e1q2ea.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y9kq9x48.js";import"./chunk-n8am3mgq.js";import"./chunk-fvvb0072.js";import"./chunk-jravy0cc.js";import"./chunk-rxqdw6s5.js";import"./chunk-f5n0tgky.js";import"./chunk-yzkhwn31.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-tbpj22sn.js";import"./chunk-kj37wrjn.js";import"./chunk-4fa35dbn.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-48ynmrd8.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-zsfyj36g.js";import"./chunk-sfn4s219.js";import"./chunk-v8nvfyd4.js";import"./chunk-gak4aag4.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-dc842he4.js";import"./chunk-eqa843hf.js";import"./chunk-kq01awhv.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-548fwbx3.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-yytjrrdh.js";import"./chunk-6rdvvbyv.js";import"./chunk-cmp64q4j.js";import"./chunk-krnacq08.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,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{LAST_RUN_VERSION_KEY}from"./chunk-
|
|
2
|
+
import{LAST_RUN_VERSION_KEY}from"./chunk-41yc90sq.js";import{isShellKind,shippedCompletionsPath}from"./chunk-0rrmz6k6.js";import{isNpxMissing,markSkillHintSeen,npxSkillsArgv,npxSkillsCommand}from"./chunk-k4s0y0j2.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{t}from"./chunk-yytjrrdh.js";import{spawnSync}from"child_process";import{appendFileSync,existsSync,mkdirSync,readFileSync,writeFileSync}from"fs";import{homedir}from"os";import{basename,join}from"path";var WELCOMED_KEY="welcomed",PENDING_SKILL_KEY="welcomePendingSkillInstall";function shouldWelcome(state){if(state[WELCOMED_KEY]===!0)return!1;return typeof state[LAST_RUN_VERSION_KEY]!=="string"}function takeWelcome(){if(!shouldWelcome(loadStateFile()))return null;try{patchStateFile({[WELCOMED_KEY]:!0})}catch{}return{shell:detectShell()}}var PENDING_COMPLETIONS_KEY="welcomePendingCompletions";function detectShell(env=process.env){let shell=basename(env.SHELL??"");return shell==="zsh"||shell==="bash"||shell==="fish"?shell:null}function completionHook(shell,cli,shipped){if(shipped===null)return legacyCompletionHook(shell,cli);return shell==="fish"?`test -f "${shipped}"; and source "${shipped}"`:`[ -f "${shipped}" ] && source "${shipped}"`}function legacyCompletionHook(shell,cli){return shell==="fish"?`${cli} completions fish | source`:`command -v ${cli} >/dev/null && source <(${cli} completions ${shell})`}function shippedScriptFor(shell,cli){let path=shippedCompletionsPath(shell,cli);return existsSync(path)?path:null}function installCompletions(shell,home=homedir(),cli=ROVE_PRODUCT_NAME,shipped=shippedScriptFor(shell,cli)){let hook=completionHook(shell,cli,shipped);if(shell==="fish"){let dir=join(home,".config","fish","completions"),path=join(dir,`${cli}.fish`);return mkdirSync(dir,{recursive:!0}),writeFileSync(path,`${hook}
|
|
3
3
|
`),{path,installed:!0}}let rc=join(home,shell==="zsh"?".zshrc":".bashrc"),existing=existsSync(rc)?readFileSync(rc,"utf8"):"";if(existing.includes(hook))return{path:rc,installed:!1};let legacy=legacyCompletionHook(shell,cli);if(existing.includes(legacy))return writeFileSync(rc,existing.replace(legacy,hook)),{path:rc,installed:!0};if(existing.includes(`${cli} completions`))return{path:rc,installed:!1};return appendFileSync(rc,`
|
|
4
4
|
# ${cli} completions
|
|
5
5
|
${hook}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{readOutdatedCache}from"./chunk-c25vea1q.js";import{hookConfigIssues}from"./chunk-
|
|
2
|
+
import{readOutdatedCache}from"./chunk-c25vea1q.js";import{hookConfigIssues}from"./chunk-vskqfw9w.js";import{tightenPluginPermissions}from"./chunk-vckr5yvb.js";import{DEFAULT_PREFIX_CONFIGURATION}from"./chunk-n1v59qgs.js";import{AUTO_ROUTING_TIERS}from"./chunk-zrvsp7tg.js";import{reloadPluginEngines}from"./chunk-av482xxw.js";import{ENGINE_ACTIVITY_KINDS}from"./chunk-17e2tgyg.js";import{currentPluginPlatform,loadPluginRegistry,parsePluginManifest,pluginManifestPath,qualifiedActionId,readPluginManifest,savePluginRegistry,supportsPlatform}from"./chunk-a569ctz6.js";import{addTab,expandHome,initialTabs,setTabEngineCommand,setTabForkFrom,setTabInitialPrompt}from"./chunk-n7t7eqcz.js";import{engineCanFork,engineDisplayName,engineLaunchArgv,getEngineProtocol,protocolEntry,withPinnedSessionId}from"./chunk-y9kq9x48.js";import{THEME_MODE_PREFERENCES,ensureContrast,inkAtHue,oklchCusp,relativeLuminance,toOklch}from"./chunk-jravy0cc.js";import{readFirstNonEmptyRepoFile}from"./chunk-catrr0z3.js";import{activityHookAdapters,engineEntry}from"./chunk-kj37wrjn.js";import{maybeStartScheduledRun,spawnCapture}from"./chunk-2tfnscxk.js";import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{pluginConfigDir,pluginLogPath}from"./chunk-j1z9kgyd.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{ROVE_HOOK_VERSION}from"./chunk-eqa843hf.js";import{recordSpawn}from"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-32j6y5d1.js";import{promptAttachmentsDir}from"./chunk-z1nj22va.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE}from"./chunk-yt15y085.js";import{t}from"./chunk-yytjrrdh.js";import{LOCALES}from"./chunk-6rdvvbyv.js";import{createStateCell}from"./chunk-cmp64q4j.js";import{readRoveEnv}from"./chunk-nc46gddg.js";var pluginPageErrorState=createStateCell([],"plugin-page-errors");function pluginPageErrors(){return pluginPageErrorState.get()}var WORKING_BORDER_KEY="appearance.workingBorder",WORKING_BORDERS=["flow","still"],DEFAULT_WORKING_BORDER="flow";function normalizeWorkingBorder(raw){return WORKING_BORDERS.includes(raw)?raw:"flow"}function relativeBuckets(absMs){let minutes=Math.floor(absMs/60000),hours=Math.floor(minutes/60);return{minutes,hours,days:Math.floor(hours/24)}}function relativeAge(ms,nowMs=Date.now()){let delta=Math.max(0,nowMs-ms),secs=Math.floor(delta/1000);if(secs<60)return`${secs}s`;let{minutes,hours,days}=relativeBuckets(delta);if(minutes<60)return`${minutes}m`;if(hours<24)return`${hours}h`;return`${days}d`}import{randomBytes}from"crypto";import{existsSync,mkdirSync,writeFileSync}from"fs";import{isAbsolute,join}from"path";var ATTACHMENT_EXTENSION_REGEX=/\.(png|jpe?g|gif|webp|pdf)$/i,PDF_EXTENSION_REGEX=/\.pdf$/i;function removeOuterQuotes(text){if(text.startsWith('"')&&text.endsWith('"')||text.startsWith("'")&&text.endsWith("'"))return text.slice(1,-1);return text}function stripBackslashEscapes(path){let placeholder=`__DOUBLE_BACKSLASH_${randomBytes(8).toString("hex")}__`;return path.replace(/\\\\/g,placeholder).replace(/\\(.)/g,"$1").replaceAll(placeholder,"\\")}function asAttachmentPath(text,exists=existsSync){let cleaned=stripBackslashEscapes(removeOuterQuotes(text.trim()));if(!ATTACHMENT_EXTENSION_REGEX.test(cleaned))return null;if(!isAbsolute(cleaned))return null;return exists(cleaned)?cleaned:null}function asAttachmentPaths(pasted,exists=existsSync){let lines=pasted.split(`
|
|
3
3
|
`).map((l)=>l.trim()).filter((l)=>l.length>0);if(lines.length===0)return null;let paths=[];for(let line of lines){let p=asAttachmentPath(line,exists);if(!p)return null;paths.push(p)}return paths}function attachmentLabel(path,index){return PDF_EXTENSION_REGEX.test(path)?`pdf[${index}]`:`images[${index}]`}function appendAttachmentRefs(prompt,attachments){if(attachments.length===0)return prompt;let refs=attachments.map((p,i)=>`${attachmentLabel(p,i)}: ${p}`).join(`
|
|
4
4
|
`);return`${prompt}
|
|
5
5
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{argvToParams,booleanFlagsOf,callVerb,errorBody,errorEnvelope,executeVerb,paramsToFlags,repeatableFlagsOf,runVerb,successEnvelope,toApiError}from"./chunk-
|
|
2
|
+
import{argvToParams,booleanFlagsOf,callVerb,errorBody,errorEnvelope,executeVerb,paramsToFlags,repeatableFlagsOf,runVerb,successEnvelope,toApiError}from"./chunk-a7a4pn72.js";import"./chunk-rk6tm9zq.js";import"./chunk-zrvsp7tg.js";import"./chunk-av482xxw.js";import"./chunk-kwyxwcr8.js";import"./chunk-4b6r81r7.js";import"./chunk-p6jw0zcd.js";import"./chunk-heajz5tw.js";import"./chunk-17e2tgyg.js";import"./chunk-eyrt04mg.js";import"./chunk-mzk4p07t.js";import"./chunk-4f4vr50c.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-a569ctz6.js";import"./chunk-pr22s2c3.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-kc3e07fn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-nahwgea8.js";import"./chunk-n7t7eqcz.js";import"./chunk-93e1q2ea.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y9kq9x48.js";import"./chunk-n8am3mgq.js";import"./chunk-fvvb0072.js";import"./chunk-jravy0cc.js";import"./chunk-rxqdw6s5.js";import"./chunk-f5n0tgky.js";import"./chunk-yzkhwn31.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-tbpj22sn.js";import"./chunk-kj37wrjn.js";import"./chunk-4fa35dbn.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-48ynmrd8.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-zsfyj36g.js";import"./chunk-sfn4s219.js";import"./chunk-v8nvfyd4.js";import"./chunk-gak4aag4.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-dc842he4.js";import"./chunk-eqa843hf.js";import"./chunk-kq01awhv.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-548fwbx3.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-yytjrrdh.js";import"./chunk-6rdvvbyv.js";import"./chunk-cmp64q4j.js";import"./chunk-krnacq08.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{toApiError,successEnvelope,runVerb,repeatableFlagsOf,paramsToFlags,executeVerb,errorEnvelope,errorBody,callVerb,booleanFlagsOf,argvToParams};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{engineEntry,identifiableEngineIds}from"./chunk-
|
|
2
|
+
import{engineEntry,identifiableEngineIds}from"./chunk-kj37wrjn.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};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{t}from"./chunk-
|
|
2
|
+
import{t}from"./chunk-yytjrrdh.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}
|
|
3
3
|
export{daemonRestartFix,skillInstallFix,resetManualFix,killOrphansManualFix,engineTabsManualFix,reinstallManualFix,spawnHelperFix,humanOnlyFix,noEngineFix,applyFixes,defaultFixRuntime};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{canonPath,normalizeMainRepo,randomDirTaskSuffix,repoWorkingDir,samePrStatus,titleFromRepo}from"./chunk-3qkhxem2.js";import{GitWorktreeManager,defaultExecDeps,git,isDirtyOutput,parseDirtyPaths}from"./chunk-kx7b5nht.js";import{readLastActiveTaskId,writeLastActiveTaskId}from"./chunk-c1dz3qg3.js";import{PLACEHOLDER_TASK_TITLE,isPlaceholderDerivedBranch,sanitizeTaskTitle}from"./chunk-eyrt04mg.js";import{CannotDeleteMainTaskError,DirtyWorktreeError,EmptyBranchDirtyWorktreeError,EmptyBranchError,GitCommandFailedError,IllegalTransitionError,InvalidWorktreeNameError,LandConflictError,MainCheckoutDirtyError,MissingRefError,NotAGitRepoError,NotALinkedRepoError,RemoteParentUnsupportedError,TaskDeletingError,TaskNotFoundError,WorktreeNameTakenError,WorktreeRemoveFailedError,canonicalize,listWorktreeDirNames}from"./chunk-mzk4p07t.js";import{lineageRootId,subtreeIds,taskCwd}from"./chunk-pr22s2c3.js";import{detectLanguage}from"./chunk-hpay0ax8.js";import{resolvePreferredVendor}from"./chunk-h8t4xg1p.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{DEFAULT_TASK_VENDOR,toTaskId}from"./chunk-xy8be792.js";import{addSavedRepo,getSavedRepos,isGitRepo,isRemoteRepoKey,removeSavedRepo,resolveMainRepoRoot,resolveRepoRoot}from"./chunk-rfp0ayra.js";import{projectRejection,rejectionReason}from"./chunk-7mwvvj46.js";import{createStateCell}from"./chunk-cmp64q4j.js";import{pathIdentity,pathWithin,samePath}from"./chunk-pn5ygqn6.js";async function createTaskRow(deps,input){if(!input.repo)throw Error("createTask: repo is required");let repo=(await deps.mainTasks.ensureIfEligible(input.repo,input.projectIntent??"explicit"))?.repo??normalizeMainRepo(input.repo).repo,title=sanitizeTaskTitle(input.title??PLACEHOLDER_TASK_TITLE)||PLACEHOLDER_TASK_TITLE,worktreeName=input.worktreeName?.trim();if(worktreeName)await deps.claimWorktreeName(repo,worktreeName);return await deps.store.create({repo,title,branch:input.branch??"",worktreePath:"",status:"backlog",kind:"task",vendor:input.vendor??DEFAULT_TASK_VENDOR,...input.command?.trim()?{command:input.command.trim()}:{},...input.modelEffort?{modelEffort:input.modelEffort}:{},...input.model?.trim()?{model:input.model.trim()}:{},...input.tier?.trim()?{tier:input.tier.trim()}:{},...input.groupId?{groupId:input.groupId}:{},...input.dispatcher?{dispatcher:input.dispatcher}:{},...input.parentTaskId?{parentTaskId:input.parentTaskId}:{},...input.cwdSubpath?{cwdSubpath:input.cwdSubpath}:{},...input.routine?{routine:input.routine}:{},...input.baseRef?.trim()?{baseRef:input.baseRef.trim()}:{},...worktreeName?{worktreeName}:{}})}async function openDirectoryTaskRow(deps,input){if(!input.dir)throw Error("openDirectoryTask: dir is required");let dir=canonPath(input.dir);return deps.store.create({repo:dir,title:input.scratch?"":`${titleFromRepo(dir)}-${randomDirTaskSuffix()}`,branch:"",worktreePath:dir,status:"backlog",kind:"dir",...input.scratch?{scratch:!0}:{},vendor:input.vendor??resolvePreferredVendor()})}async function adoptScratchRepoRow(deps,id,repo){let task=deps.store.get(id);if(!task||task.kind!=="dir"||task.scratch!==!0)return;let dir=canonPath(repo);await deps.store.update(id,{repo:dir,worktreePath:dir,scratch:!1,title:titleFromRepo(dir)})}function baseRepoCtx(repo,deps){let basePath=deps.remoteBasePath(repo);return{exec:deps.execForRepo(repo),dir:basePath??repo}}async function landGit(exec,dir,args,opts){let r=await exec.run(["git",...args],{cwd:dir,env:opts?.readOnly?READ_ONLY_GIT_ENV:void 0});return{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}}async function isDirty(exec,dir){return isDirtyOutput((await landGit(exec,dir,["status","--porcelain"],{readOnly:!0})).stdout)}async function landPreflight(task,deps=defaultExecDeps){let refuse=(pf,refusal)=>{let refused={...pf,refusal};return{...refused,message:landRefusalError(task,refused).message}},branch=task.branch.trim();if(!branch)throw Error(`landPreflight: task ${task.id} has no branch to land (never materialised)`);let{exec,dir}=baseRepoCtx(task.repo,deps),headOut=await landGit(exec,dir,["symbolic-ref","--short","HEAD"],{readOnly:!0}),landedOn=headOut.stdout.trim();if(headOut.exitCode!==0||!landedOn){let headCommit=await landGit(exec,dir,["rev-parse","--verify","--quiet","HEAD"],{readOnly:!0}),detached=headCommit.exitCode===0&&headCommit.stdout.trim().length>0;return refuse({branch,landedOn:"",baseDir:dir},detached?"DETACHED_HEAD":"UNREADABLE_BASE")}if(landedOn===branch)return refuse({branch,landedOn,baseDir:dir},"SAME_BRANCH");let baseDirty=await isDirty(exec,dir),aheadOut=await landGit(exec,dir,["rev-list","--count",`${landedOn}..${branch}`],{readOnly:!0});if(aheadOut.exitCode!==0){let baseHead=await landGit(exec,dir,["rev-parse","--verify","--quiet","HEAD"],{readOnly:!0});if(baseHead.exitCode!==0||!baseHead.stdout.trim())return refuse({branch,landedOn,baseDirty,baseDir:dir},"UNBORN_BASE");return refuse({branch,landedOn,baseDirty,baseDir:dir},baseDirty?"MAIN_CHECKOUT_DIRTY":"MISSING_REF")}let parsed=Number.parseInt(aheadOut.stdout.trim(),10),base={branch,landedOn,baseDirty,baseDir:dir,...Number.isFinite(parsed)?{ahead:parsed}:{}};if(baseDirty)return refuse(base,"MAIN_CHECKOUT_DIRTY");if(base.ahead!==0)return base;let worktreePath=task.worktreePath.trim();if(worktreePath){let manager=new GitWorktreeManager(deps),dirty=!1;try{dirty=await manager.isDirty(worktreePath)}catch{dirty=!1}if(dirty){let wtExec=deps.execForPath(worktreePath),files=parseDirtyPaths((await landGit(wtExec,worktreePath,["status","--porcelain"],{readOnly:!0})).stdout);return refuse({...base,dirtyFiles:files},"EMPTY_BRANCH_DIRTY_WORKTREE")}}return refuse(base,"EMPTY_BRANCH")}function landRefusalError(task,pf){switch(pf.refusal){case"DETACHED_HEAD":return Error(`landTask: base checkout at ${pf.baseDir} is in detached-HEAD state; check out a branch first`);case"UNREADABLE_BASE":return Error(`landTask: could not read HEAD of the base checkout at ${pf.baseDir} \u2014 is it still a git repo?`);case"UNBORN_BASE":return Error(`landTask: base checkout at ${pf.baseDir} is on '${pf.landedOn}' but has no commits yet, so there is nothing to merge '${pf.branch}' into; make the first commit there (or \`git merge --ff-only ${pf.branch}\`) and land again`);case"SAME_BRANCH":return Error(`landTask: base checkout is already on '${pf.branch}' \u2014 nothing to land onto`);case"MAIN_CHECKOUT_DIRTY":return new MainCheckoutDirtyError(task.repo,pf.baseDir);case"MISSING_REF":return new MissingRefError(pf.branch,pf.landedOn,pf.baseDir);case"EMPTY_BRANCH_DIRTY_WORKTREE":return new EmptyBranchDirtyWorktreeError(pf.branch,pf.landedOn,task.worktreePath.trim(),[...pf.dirtyFiles??[]]);case"EMPTY_BRANCH":return new EmptyBranchError(pf.branch,pf.landedOn)}}async function landTaskWithCleanup(task,opts,deps){if(task.kind==="main")throw Error("landTask: a main task has no branch to land");if(task.kind==="dir")throw Error("landTask: a directory task has no Rove-managed branch to land");let result=await landTask(task,{strategy:opts.strategy}),worktree=opts.removeWorktree===!1?void 0:await removeLandedWorktree(task,opts.callerCwd,deps),branchAnchor=null,branchKept,worktreeGone=!task.worktreePath.trim()||worktree?.removed===!0;if(opts.deleteBranch&&!worktreeGone)branchKept={reason:worktree?.reason??`worktree ${task.worktreePath} was kept, and still has the branch checked out`};else if(opts.deleteBranch){let outcome=await deps.worktrees.deleteBranch(task.repo,result.branch,{force:!0,onAnchor:(record)=>{branchAnchor=record}});if(!outcome.deleted)branchKept={reason:outcome.reason}}return{...result,...worktree?{worktree}:{},...branchAnchor?{branchAnchor}:{},...branchKept?{branchKept}:{}}}async function removeLandedWorktree(task,callerCwd,deps){let worktreePath=task.worktreePath.trim();if(!worktreePath)return{removed:!1,reason:"task has no worktree on disk (never materialised)"};let wt=canonicalize(worktreePath);if(samePath(wt,canonicalize(task.repo)))return{removed:!1,reason:"refusing to remove the base checkout"};if(deps.sharesWorktree?.(task))return{removed:!1,reason:`kept ${worktreePath}: other tasks still run in this directory`};if(callerCwd){if(pathWithin(wt,canonicalize(callerCwd))!==null)return{removed:!1,reason:`refusing to remove the caller's own worktree (${worktreePath}) \u2014 re-run from outside it`}}if(deps.tearDownSession)try{await deps.tearDownSession(task.id)}catch{}let residue;try{await deps.worktrees.remove(worktreePath,{onResidue:(r)=>{residue=r}})}catch(err){return{removed:!1,reason:errText(err)}}try{await deps.clearWorktreePath(task.id)}catch(err){return{removed:!0,reason:`worktree removed, but clearing the task's worktree path failed: ${errText(err)}`,...residue?{residue}:{}}}return{removed:!0,...residue?{residue}:{}}}function errText(err){return err instanceof Error?err.message:String(err)}async function conflictedFiles(exec,dir){return(await landGit(exec,dir,["diff","--name-only","--diff-filter=U"],{readOnly:!0})).stdout.split(`
|
|
3
|
+
`).map((l)=>l.trim()).filter((l)=>l.length>0)}async function landTask(task,input={},deps=defaultExecDeps){let strategy=input.strategy??"merge",preflight=await landPreflight(task,deps);if(preflight.refusal)throw landRefusalError(task,{...preflight,refusal:preflight.refusal});let{branch,landedOn}=preflight,{exec,dir}=baseRepoCtx(task.repo,deps);if(strategy==="squash"){if((await landGit(exec,dir,["merge","--squash",branch])).exitCode!==0){let files=await conflictedFiles(exec,dir);throw await landGit(exec,dir,["merge","--abort"]).catch(()=>{}),await landGit(exec,dir,["reset","--hard","HEAD"]).catch(()=>{}),new LandConflictError(task.id,branch,files)}let commit=await landGit(exec,dir,["commit","--no-edit","-m",`Land ${branch} (squash)`]);if(commit.exitCode!==0){if((await landGit(exec,dir,["diff","--cached","--quiet"],{readOnly:!0})).exitCode===0)throw await landGit(exec,dir,["reset","--hard","HEAD"]).catch(()=>{}),Error(`landTask: '${branch}' has nothing to land onto '${landedOn}' (already merged or empty)`);throw new GitCommandFailedError(`commit (squash-landing '${branch}' onto '${landedOn}')`,commit.stderr,"the squashed merge is left STAGED in the base checkout \u2014 fix the cause and `git commit` it, or `git reset --hard HEAD` to discard")}}else{let before=(await landGit(exec,dir,["rev-parse","HEAD"],{readOnly:!0})).stdout.trim(),merge=await landGit(exec,dir,["merge","--no-ff","-m",`Land ${branch}`,branch]);if(merge.exitCode!==0){let files=await conflictedFiles(exec,dir);if(await landGit(exec,dir,["merge","--abort"]).catch(()=>{}),files.length===0)throw new GitCommandFailedError(`merge --no-ff (landing '${branch}' onto '${landedOn}')`,merge.stderr,"the merge was aborted, so the base checkout is unchanged");throw new LandConflictError(task.id,branch,files)}let after=(await landGit(exec,dir,["rev-parse","HEAD"],{readOnly:!0})).stdout.trim();if(before===after)throw Error(`landTask: '${branch}' has nothing to land onto '${landedOn}' (already merged or empty)`)}let shaOut=await landGit(exec,dir,["rev-parse","--short","HEAD"],{readOnly:!0});return{branch,strategy,landedOn,commit:shaOut.stdout.trim()}}class MainTaskCoordinator{store;forgetWorktree;locks=new Map;constructor(store,forgetWorktree){this.store=store;this.forgetWorktree=forgetWorktree}async ensure(repo){let task=await this.ensureIfEligible(repo,"explicit");if(task)return task;let{repo:normalizedRepo}=normalizeMainRepo(repo),rejected=projectRejection(normalizedRepo,isGitRepo,"explicit")??"notGitRepo";throw Error(`cannot add ${normalizedRepo} as a project: ${rejectionReason(rejected)}`)}async ensureIfEligible(repo,intent="derived"){let{repo:normalizedRepo,key}=normalizeMainRepo(repo),onThisRoot=(task)=>normalizeMainRepo(task.repo).key===key,existing=this.store.list().find((task)=>task.kind==="main"&&onThisRoot(task));if(existing)return existing;if(projectRejection(normalizedRepo,isGitRepo,intent))return null;let inflight=this.locks.get(key);if(inflight)return inflight;let promise=(async()=>{addSavedRepo(normalizedRepo,{intent:"explicit"});let adoptable=this.store.list().find((task)=>task.kind==="dir"&&task.scratch!==!0&&!task.sharesWorkspaceOf&&onThisRoot(task));if(adoptable)return await this.store.update(adoptable.id,this.mainShape(normalizedRepo));return await this.store.create({...this.mainShape(normalizedRepo),status:"backlog",vendor:resolvePreferredVendor(normalizedRepo)})})();this.locks.set(key,promise);try{return await promise}finally{this.locks.delete(key)}}mainShape(normalizedRepo){return{kind:"main",title:titleFromRepo(normalizedRepo),repo:normalizedRepo,branch:"",worktreePath:repoWorkingDir(normalizedRepo)}}async forget(repo){if(!repo)throw Error("forgetProject: repo is required");let key=normalizeMainRepo(repo).key;for(let saved of getSavedRepos())if(normalizeMainRepo(saved).key===key)removeSavedRepo(saved);for(let task of this.store.list()){if(task.kind!=="main")continue;if(normalizeMainRepo(task.repo).key!==key)continue;await this.store.remove(task.id),this.forgetWorktree(task.id);for(let dependent of this.store.list()){if(dependent.parentTaskId!==task.id&&dependent.sharesWorkspaceOf!==task.id)continue;await this.store.update(dependent.id,{...dependent.parentTaskId===task.id?{parentTaskId:void 0}:{},...dependent.sharesWorkspaceOf===task.id?{sharesWorkspaceOf:void 0}:{}})}}}}import{isAbsolute,relative,resolve,sep}from"path";import{lstatSync,readdirSync,realpathSync}from"fs";import{join}from"path";function scanLinkedRepos(workspaceDir){let workspace,names;try{workspace=realpathSync(workspaceDir),names=readdirSync(workspaceDir)}catch{return[]}let out=[];for(let name of names.sort()){let entry=join(workspaceDir,name);try{if(!lstatSync(entry).isSymbolicLink())continue;let target=realpathSync(entry);if(pathWithin(workspace,target)!==null)continue;if(isGitRepo(target)&&samePath(resolveRepoRoot(target),target))out.push({name,path:target})}catch{}}return out}function sharedChildRow(parent,workspace,fields){let command=fields.command?.trim();return{repo:parent.repo,branch:parent.kind==="task"?parent.branch:"",worktreePath:workspace,status:"backlog",kind:parent.kind==="task"?"task":"dir",title:fields.title,vendor:fields.vendor,...command?{command}:{},...fields.dispatcher?{dispatcher:fields.dispatcher}:{},...parent.kind==="task"&&parent.baseRef?{baseRef:parent.baseRef}:{},...parent.cwdSubpath?{cwdSubpath:parent.cwdSubpath}:{},...fields.prompt?{prompt:fields.prompt}:{},parentTaskId:toTaskId(fields.parentTaskId),sharesWorkspaceOf:toTaskId(parent.sharesWorkspaceOf??parent.id)}}async function spawnChildTaskRow(deps,input){let found=deps.store.get(input.parentTaskId);if(!found)throw new TaskNotFoundError(input.parentTaskId);if(found.deletion)throw new TaskDeletingError(String(found.id));if(isRemoteRepoKey(found.repo))throw new RemoteParentUnsupportedError(String(found.id));if(input.isolateIn&&!input.worktree)throw Error("INVALID_SPAWN: isolateIn needs a worktree child");let workspace=found.kind==="task"?await deps.ensureWorktree(found.id):found.worktreePath,parent=deps.store.get(found.id)??found,cwd=taskCwd({worktreePath:workspace,cwdSubpath:parent.cwdSubpath}),links=scanLinkedRepos(cwd),inherit=!input.vendor&&!input.command,common={parentTaskId:lineageRootId(deps.store.list(),parent.id),title:sanitizeTaskTitle(input.title??PLACEHOLDER_TASK_TITLE)||PLACEHOLDER_TASK_TITLE,vendor:input.vendor??parent.vendor,command:input.command??(inherit?parent.command:void 0),dispatcher:input.dispatcher,prompt:input.prompt};if(!input.worktree)return{task:await deps.store.create(sharedChildRow(parent,workspace,common)),parentDirty:await isDirty2(deps,cwd),sharedLinks:links.map((l)=>l.name)};let source=input.isolateIn?requireLink(links,input.isolateIn,cwd):void 0,sourceDir=source?.path??cwd;if(!source&&!isGitRepo(sourceDir))throw new NotAGitRepoError(sourceDir);let top=source?sourceDir:gitOut(sourceDir,["rev-parse","--show-toplevel"]),sub=relative(canonPath(top),canonPath(sourceDir)),cwdSubpath=sub&&!sub.split(sep).includes("..")&&!isAbsolute(sub)?sub:void 0,baseRef=input.baseRef?.trim()||gitOut(sourceDir,["rev-parse","HEAD"]),repo=source||parent.kind==="dir"?resolveMainRepoRoot(sourceDir):parent.repo,parentDirty=await isDirty2(deps,sourceDir),child=await deps.createTask({repo,title:common.title,baseRef,vendor:common.vendor,command:common.command,dispatcher:common.dispatcher,parentTaskId:toTaskId(common.parentTaskId),cwdSubpath,projectIntent:"derived"});try{await deps.ensureWorktree(child.id)}catch(err){let partial=deps.store.get(child.id);if(partial?.worktreePath)await deps.worktrees.remove(partial.worktreePath,{force:!0,deleteBranch:!0,repo:partial.repo,branch:partial.branch}).catch((cleanup)=>console.error(`[rove] spawn rollback failed for ${partial.worktreePath}:`,cleanup));throw await deps.store.remove(child.id),err}if(input.prompt)await deps.store.update(child.id,{prompt:input.prompt});return{task:deps.store.get(child.id)??child,parentDirty,sharedLinks:source?[]:links.map((l)=>l.name)}}function requireLink(links,isolateIn,cwd){let name=isAbsolute(isolateIn)||isolateIn.includes("/")?relative(cwd,resolve(cwd,isolateIn)):isolateIn,link=links.find((l)=>l.name===name);if(!link)throw new NotALinkedRepoError(isolateIn,links.map((l)=>l.name));return link}function gitOut(cwd,args){return git(args,{cwd,readOnly:!0}).stdout.trim()}async function isDirty2(deps,dir){try{return(await deps.worktrees.dirtyPaths(dir)).length>0}catch{return!1}}async function createMigratedChildRow(deps,input){let parent=deps.store.get(input.parentTaskId);if(!parent)throw new TaskNotFoundError(input.parentTaskId);if(parent.deletion)throw new TaskDeletingError(String(parent.id));let inherit=!input.vendor&&!input.command,row=sharedChildRow(parent,parent.worktreePath,{parentTaskId:lineageRootId(deps.store.list(),parent.id),title:sanitizeTaskTitle(input.title)||PLACEHOLDER_TASK_TITLE,vendor:input.vendor??parent.vendor,command:input.command??(inherit?parent.command:void 0)});return await deps.store.create({...row,...input.ptyAlias?{ptyAlias:input.ptyAlias}:{}})}async function setPtyAliasRow(deps,id,alias){let task=deps.store.get(id);if(!task)throw new TaskNotFoundError(id);if(alias===null&&!task.ptyAlias)return;await deps.store.update(id,{ptyAlias:alias??void 0})}function promotableDirTasks(deps){let claimed=new Set(deps.tasks.filter((task)=>task.kind==="main").map((task)=>pathIdentity(task.repo))),seen=new Set,out=[];for(let task of deps.tasks){if(task.kind!=="dir"||task.scratch===!0||task.sharesWorkspaceOf)continue;let path=task.repo,key=pathIdentity(path);if(!path||claimed.has(key)||seen.has(key))continue;if(!deps.isRepoRoot(path))continue;seen.add(key),out.push(task)}return out}function isLeaving(task){return task.deletion?.phase==="queued"||task.deletion?.phase==="running"}class TaskDeletionCoordinator{store;worktrees;forgetTask;onSalvage;onResidue;onBranchKept;pathLocks=new Map;constructor(store,worktrees,forgetTask,onSalvage,onResidue,onBranchKept){this.store=store;this.worktrees=worktrees;this.forgetTask=forgetTask;this.onSalvage=onSalvage;this.onResidue=onResidue;this.onBranchKept=onBranchKept}targets(id,opts){return opts?.cascade?subtreeIds(this.store.list(),String(id)):[String(id)]}async prepare(id,opts){let task=this.store.get(id);if(!task)return!1;if(task.kind==="main")throw new CannotDeleteMainTaskError;if(isLeaving(task))return!0;let keys=this.targets(task.id,opts).flatMap((targetId)=>{let target=this.store.get(targetId);return target?.worktreePath&&target.kind!=="dir"?[canonPath(target.worktreePath)]:[]});return this.withPathLocks([...new Set(keys)].sort(),()=>this.prepareLocked(task.id,opts))}async prepareLocked(id,opts){let task=this.store.get(id);if(!task||isLeaving(task))return task!==void 0;let force=opts?.force===!0,doomed=this.targets(task.id,opts).map((targetId)=>this.store.get(targetId)).filter((t)=>t!==void 0&&t.kind!=="main"&&!isLeaving(t)),leaving=new Set(doomed.map((t)=>String(t.id))),survivors=this.store.list().filter((t)=>!leaving.has(String(t.id))&&!isLeaving(t)),gated=new Set;for(let target of doomed){if(!target.worktreePath||force||target.kind==="dir")continue;let key=canonPath(target.worktreePath);if(gated.has(key)||survivors.some((s)=>s.worktreePath&&canonPath(s.worktreePath)===key))continue;gated.add(key);let dirty=[],ignored=[],probed=!0;try{dirty=await this.worktrees.dirtyPaths(target.worktreePath)}catch{probed=!1}if(probed&&dirty.length===0)ignored=await this.worktrees.ignoredWork(target.worktreePath);if(dirty.length>0||ignored==="unknown"||ignored.length>0)throw new DirtyWorktreeError(target.id,ignored,dirty)}for(let target of doomed)await this.store.update(target.id,{deletion:{phase:"queued",force,deleteBranch:opts?.deleteBranch===!0||target.deleteBranchPending===!0,requestedAt:new Date().toISOString()}});if(await this.transferOwnership(leaving),!opts?.cascade)await this.promoteChildren(task);return!0}async begin(id){let task=this.store.get(id);if(!task||!task.deletion||task.deletion.phase==="error")return!1;if(task.deletion.phase!=="running")await this.store.update(task.id,{deletion:{...task.deletion,phase:"running"}});return!0}async finish(id){let task=this.store.get(id);if(!task?.deletion||task.deletion.phase!=="running")return;let ownsDirectory=Boolean(task.worktreePath)&&task.kind!=="dir";await this.withPathLock(ownsDirectory?canonPath(task.worktreePath):null,async()=>{let key=ownsDirectory?canonPath(task.worktreePath):null,shared=key!==null&&this.store.list().some((t)=>t.id!==task.id&&t.worktreePath&&canonPath(t.worktreePath)===key);try{if(ownsDirectory&&!shared)await this.removeWorktree(task,task.deletion);else if(ownsDirectory&&task.deletion?.deleteBranch)await this.handBranchDeleteOn(task,key)}catch(cause){let failure=new WorktreeRemoveFailedError(task.id,cause);throw await this.store.update(task.id,{deletion:{...task.deletion,phase:"error",error:errorMessage(failure)}}),failure}await this.store.remove(task.id),this.forgetTask(task.id)})}async deleteNow(id,opts){let targets=this.targets(id,opts);if(!await this.prepare(id,opts))return;let failure;for(let target of targets)try{if(await this.begin(target))await this.finish(target)}catch(err){failure??=err}if(failure)throw failure}async removeWorktree(task,deletion){await this.worktrees.remove(task.worktreePath,{force:deletion.force,deleteBranch:deletion.deleteBranch===!0,repo:task.repo,branch:task.branch,onSalvage:(record)=>{if(record)this.onSalvage?.(task.id,record)},onResidue:(residue)=>this.onResidue?.(task.id,residue),onBranchKept:(kept)=>this.onBranchKept?.(task.id,kept)})}async handBranchDeleteOn(leaving,key){let holder=this.store.list().find((t)=>t.id!==leaving.id&&t.worktreePath&&canonPath(t.worktreePath)===key);if(holder&&isLeaving(holder))await this.store.update(holder.id,{deletion:{...holder.deletion,deleteBranch:!0}});else if(holder)await this.store.update(holder.id,{deleteBranchPending:!0});this.onBranchKept?.(leaving.id,{branch:leaving.branch,reason:"another task still uses this branch"})}async transferOwnership(leaving){for(let ownerId of leaving){let remaining=this.store.list().filter((t)=>t.sharesWorkspaceOf===ownerId&&!leaving.has(String(t.id))&&!isLeaving(t)),[heir,...rest]=remaining;if(!heir)continue;await this.store.update(heir.id,{sharesWorkspaceOf:void 0});for(let sharer of rest)await this.store.update(sharer.id,{sharesWorkspaceOf:heir.id})}}async promoteChildren(deleted){for(let child of this.store.list().filter((t)=>t.parentTaskId===deleted.id))await this.store.update(child.id,{parentTaskId:deleted.parentTaskId})}async withPathLocks(keys,fn){let[first,...rest]=keys;if(first===void 0)return fn();return this.withPathLock(first,()=>this.withPathLocks(rest,fn))}async withPathLock(key,fn){if(key===null)return fn();let previous=this.pathLocks.get(key)??Promise.resolve(),release,turn=new Promise((resolve2)=>{release=resolve2}),tail=previous.then(()=>turn);this.pathLocks.set(key,tail),await previous;try{return await fn()}finally{if(release(),this.pathLocks.get(key)===tail)this.pathLocks.delete(key)}}}var TYPE_PREFIXES=new Set(["feat","feature","fix","bugfix","hotfix","chore","docs","doc","refactor","test","tests","ci","build","perf","style","revert","release"]),BRAND_TOKENS=new Set(["rove"]);function inferBranchStyle(names){let typed=new Map,bare=0;for(let raw of new Set(names)){let name=raw.trim();if(!name||name==="HEAD")continue;let slash=name.indexOf("/");if(slash===-1){bare+=1;continue}let prefix=name.slice(0,slash);if(TYPE_PREFIXES.has(prefix))typed.set(prefix,(typed.get(prefix)??0)+1)}let typedTotal=0;for(let n of typed.values())typedTotal+=n;if(typedTotal===0||typedTotal<bare)return{kind:"bare"};let best="",bestN=0;for(let[prefix,n]of typed)if(n>bestN||n===bestN&&(best===""||prefix<best))best=prefix,bestN=n;return{kind:"typed",defaultPrefix:best}}function slugTokens(title){return title.toLowerCase().replace(/[^a-z0-9]+/g,"-").split("-").filter((t)=>t.length>0&&!BRAND_TOKENS.has(t))}function capSlug(tokens){let slug="";for(let token of tokens){let candidate=slug?`${slug}-${token}`:token;if(candidate.length>32)return slug||token.slice(0,32);slug=candidate}return slug}function identitySlug(taskId){return`task-${taskId.slice(-6).toLowerCase()}`}function deriveConventionBranch(title,style,taskId){let tokens=slugTokens(title);if(style.kind==="typed"){let first=tokens[0];return`${first!==void 0&&TYPE_PREFIXES.has(first)?tokens.shift():style.defaultPrefix}/${capSlug(tokens)||identitySlug(taskId)}`}return capSlug(tokens)||identitySlug(taskId)}function uniqueBranchName(base,taken,taskId){let dirs=new Set;for(let name of taken)for(let i=name.indexOf("/");i>0;i=name.indexOf("/",i+1))dirs.add(name.slice(0,i));let isFree=(name)=>!taken.has(name)&&!dirs.has(name),segments=base.split("/"),root=segments.slice(0,-1).some((_,i)=>taken.has(segments.slice(0,i+1).join("/")))?segments.join("-"):base;if(isFree(root))return root;for(let n=2;n<=99;n+=1){let candidate=`${root}-${n}`;if(isFree(candidate))return candidate}return`${root}-${taskId.slice(-6).toLowerCase()}`}class TaskEditor{store;worktrees;constructor(store,worktrees){this.store=store,this.worktrees=worktrees}requireTask(id){let task=this.store.get(id);if(!task)throw new TaskNotFoundError(String(id));return task}async setTitle(id,title){let trimmed=sanitizeTaskTitle(title);if(!trimmed)throw Error("setTitle: title is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.title===trimmed&&task.scratch!==!0)return;await this.store.update(task.id,{title:trimmed,...task.scratch===!0?{scratch:!1}:{}}),await this.followBranchToTitle(task,trimmed)}async followBranchToTitle(taskBefore,newTitle){if(taskBefore.kind==="main"||!taskBefore.worktreePath)return;if(!isPlaceholderDerivedBranch(taskBefore.branch,taskBefore.id))return;try{let names=await this.worktrees.listBranchNames(taskBefore.repo),base=deriveConventionBranch(newTitle,inferBranchStyle(names),taskBefore.id);if(base===taskBefore.branch)return;if(await this.worktrees.branchHasUpstream(taskBefore.worktreePath,taskBefore.branch))return;let taken=new Set(names.filter((n)=>n!==taskBefore.branch)),nextBranch=uniqueBranchName(base,taken,taskBefore.id);await this.setBranch(taskBefore.id,nextBranch)}catch(err){console.error(`[rove] follow-branch-to-title failed for ${taskBefore.id}:`,err)}}async setBranch(id,branch){let trimmed=branch.trim();if(!trimmed)throw Error("setBranch: branch is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.kind==="main")throw Error("setBranch: a main task tracks the repo's own branch; rename it with git directly");if(task.kind==="dir")throw Error("setBranch: a directory task tracks its own checkout; rename branches with git directly");if(task.branch===trimmed)return;if(task.worktreePath)await this.worktrees.renameBranch(task.worktreePath,task.branch,trimmed);if(await this.store.update(task.id,{branch:trimmed}),!task.worktreePath)return;for(let holder of this.store.list()){if(holder.id===task.id||holder.kind!=="task"||holder.branch!==task.branch)continue;if(holder.worktreePath&&samePath(holder.worktreePath,task.worktreePath))await this.store.update(holder.id,{branch:trimmed})}}async observeLanguage(id,text){let observed=detectLanguage(text);if(!observed)return;let task=this.requireTask(id);if(task.observedLanguage===observed)return;await this.store.update(task.id,{observedLanguage:observed})}async setVendor(id,vendor,effort,model){let task=this.requireTask(id),switching=task.vendor!==vendor,effortArg=effort??(switching?"":void 0),modelArg=model??(switching?"":void 0),nextEffort=effortArg?.trim()?effortArg.trim():void 0,effortChanges=effortArg!==void 0&&task.modelEffort!==nextEffort,nextModel=modelArg?.trim()?modelArg.trim():void 0,modelChanges=modelArg!==void 0&&task.model!==nextModel;if(!switching&&!effortChanges&&!modelChanges)return;await this.store.update(task.id,{vendor,...effortArg!==void 0?{modelEffort:nextEffort}:{},...modelArg!==void 0?{model:nextModel}:{}})}async setCommand(id,command,vendor){let trimmed=command.trim();if(!trimmed)throw Error("setCommand: command is required (empty or whitespace-only rejected)");let task=this.requireTask(id),switching=vendor!==void 0&&task.vendor!==vendor;if(task.command===trimmed&&!switching)return;await this.store.update(task.id,{command:trimmed,...switching?{vendor,model:void 0,modelEffort:void 0}:{}})}async setPinned(id,pinned){let task=this.requireTask(id);if(task.kind==="main")return;let next=pinned??!task.pinned;if((task.pinned??!1)===next)return;await this.store.update(task.id,{pinned:next})}async setRequireReport(id,required){let task=this.requireTask(id);if((task.requireReport??!1)===required)return;await this.store.update(task.id,{requireReport:required||void 0})}async moveTask(id,delta){let task=this.requireTask(id);await this.store.move(task.id,delta,this.movePartition(task))}async moveTaskToTop(id){let task=this.requireTask(id);await this.store.moveToFront(task.id,this.movePartition(task))}movePartition(task){let isMain=task.kind==="main";return this.store.list().filter((t)=>isMain?(t.kind??"task")==="main":(t.kind??"task")!=="main"&&samePath(t.repo,task.repo)&&(t.pinned??!1)===(task.pinned??!1)).map((t)=>String(t.id))}async setStatus(id,status){let task=this.requireTask(id);if(task.status===status)return;if(task.status==="done"&&status==="error"||task.status==="error"&&status==="done")throw new IllegalTransitionError(task.status,status,task.id);await this.store.update(task.id,{status})}async setWorkerReport(id,report){let task=this.requireTask(id),next={...task.report,...report,at:new Date().toISOString()};await this.store.update(task.id,{report:next})}async setPRStatus(id,prStatus){let task=this.requireTask(id);if((task.prStatus?.lastError??null)===(prStatus?.lastError??null)&&samePrStatus(task.prStatus,prStatus??void 0))return;await this.store.update(task.id,{prStatus:prStatus??void 0})}async setQuotaResume(id,state){let task=this.requireTask(id);if((task.quotaResume?.resumeAt??null)===(state?.resumeAt??null))return;await this.store.update(task.id,{quotaResume:state??void 0})}async setLinkedWorkItem(id,item){let task=this.requireTask(id);if((task.linkedWorkItem?.url??null)===(item?.url??null))return;await this.store.update(task.id,{linkedWorkItem:item??void 0})}async setPrompt(id,prompt){if(prompt.trim().length===0)throw Error("setPrompt: prompt is required (empty or whitespace-only rejected)");let task=this.requireTask(id);if(task.prompt===prompt)return;await this.store.update(task.id,{prompt})}}import{basename}from"path";var ANIMAL_NAMES=["aardvark","addax","adder","agouti","albatross","alpaca","anaconda","anchovy","anglerfish","anole","anteater","antelope","ape","argali","armadillo","avocet","axolotl","baboon","badger","banteng","barracuda","basilisk","bass","bat","beagle","bear","beaver","bee","beetle","beluga","betta","bison","blackbird","blenny","bluebird","bluegill","boar","bobcat","bonito","bovid","buffalo","bullfrog","bunting","bushbuck","butterfly","buzzard","caiman","camel","canary","capybara","caracal","cardinal","caribou","carp","cassowary","caterpillar","catfish","chameleon","chamois","char","cheetah","chickadee","chimp","chinchilla","chipmunk","chough","cicada","civet","clam","clownfish","cobra","cockatoo","condor","coot","copperhead","coral","cormorant","cougar","coyote","crab","crane","crawfish","crayfish","cricket","crocodile","crow","cuckoo","curlew","cuttlefish","deer","dikdik","dingo","dolphin","donkey","dormouse","dotterel","dove","dragonfly","dromedary","duck","dugong","dunlin","eagle","echidna","eel","egret","eider","eland","elephant","elk","emu","ermine","falcon","fawn","ferret","finch","firefly","flamingo","flounder","fox","frog","gadwall","gannet","gaur","gazelle","gecko","gemsbok","gerbil","gharial","gibbon","gnu","goat","goby","godwit","goldfish","goose","gopher","goral","gorilla","goshawk","grackle","grasshopper","grayling","grebe","grouse","guanaco","guillemot","guineafowl","guppy","halibut","hammerhead","hamster","hare","harrier","hartebeest","hawk","hedgehog","heron","herring","hippo","hornbill","hornet","horse","hummingbird","hyena","ibex","ibis","iguana","impala","indri","jacana","jackal","jaguar","jay","jellyfish","jerboa","junco","kakapo","kangaroo","kestrel","killdeer","kingfisher","kinglet","kite","kiwi","koala","kookaburra","krait","krill","kudu","ladybug","lamprey","langur","lapwing","lark","lemming","lemur","leopard","limpet","lion","lionfish","lizard","llama","lobster","locust","loon","lorikeet","loris","lynx","macaque","macaw","mackerel","magpie","mallard","mamba","mammoth","manatee","mandrill","manta","mantis","marlin","marmoset","marmot","marten","meerkat","merganser","mink","minnow","mole","mongoose","monitor","monkey","moose","moth","mouflon","mouse","mudpuppy","mule","muntjac","musk","muskox","muskrat","mussel","mustang","narwhal","newt","nightingale","numbat","nuthatch","nyala","ocelot","octopus","okapi","opossum","orangutan","orca","oriole","oryx","osprey","ostrich","otter","owl","oyster","oystercatcher","paca","panda","pangolin","panther","parakeet","parrot","parrotfish","partridge","peafowl","pelican","penguin","perch","petrel","pheasant","pigeon","pika","pike","pintail","pipefish","platypus","plover","pollock","pony","porcupine","porpoise","possum","ptarmigan","puffin","puma","pupfish","python","quail","quetzal","quokka","quoll","rabbit","raccoon","rail","rat","rattler","raven","ray","redpoll","reindeer","remora","rhino","roadrunner","robin","rook","sable","sailfish","salamander","salmon","sandpiper","sardine","scallop","scaup","scorpion","seahorse","seal","serval","shark","shearwater","shrew","shrike","shrimp","siskin","sitatunga","skate","skink","skua","skunk","sloth","smelt","snail","snipe","solenodon","sparrow","spider","springbok","squid","squirrel","starfish","starling","stilt","stingray","stoat","stork","sunbird","sunfish","swallow","swan","swift","swordfish","tahr","takin","tamarin","tanager","tapir","tarantula","tarpon","tarsier","teal","tenrec","terrapin","tern","tetra","thrasher","thrush","tiger","toad","tortoise","toucan","treecreeper","treefrog","trout","tuatara","tuna","turkey","turtle","urchin","urial","vicuna","viper","vole","vulture","wagtail","wallaby","walleye","walrus","warbler","warthog","waterbuck","weasel","wildebeest","wolf","wolverine","wombat","woodcock","woodpecker","wrasse","wren","yak","zebra","zebu","zorilla"];class SlugAllocator{activeSlugs;random;pool;pendingByRepo=new Map;chain=Promise.resolve();constructor(activeSlugs,options={}){this.activeSlugs=activeSlugs;if(this.random=options.random??Math.random,this.pool=options.pool??ANIMAL_NAMES,this.pool.length===0)throw Error("SlugAllocator: animal pool cannot be empty")}async allocate(repo){let previous=this.chain,release;this.chain=new Promise((resolve2)=>{release=resolve2}),await previous;try{return await this.pickLocked(repo)}finally{release()}}async claim(repo,slug){let previous=this.chain,release;this.chain=new Promise((resolve2)=>{release=resolve2}),await previous;try{if((await this.occupiedSlugs(repo)).has(slug))throw new WorktreeNameTakenError(slug);return this.addPending(repo,slug),slug}finally{release()}}commit(repo,slug){this.deletePending(repo,slug)}cancel(repo,slug){this.deletePending(repo,slug)}async pickLocked(repo){let occupied=await this.occupiedSlugs(repo),candidates=this.pool.filter((n)=>!occupied.has(n));if(candidates.length>0){let pick=candidates[Math.floor(this.random()*candidates.length)];return this.addPending(repo,pick),pick}let base=this.pool[Math.floor(this.random()*this.pool.length)];for(let v=2;;v++){let candidate=`${base}-v${v}`;if(!occupied.has(candidate))return this.addPending(repo,candidate),candidate}}async occupiedSlugs(repo){let set=new Set(this.pendingByRepo.get(repo)??[]);for(let slug of this.activeSlugs(repo))if(slug)set.add(slug);for(let dir of await listWorktreeDirNames(repo))set.add(dir);return set}addPending(repo,slug){let pending=this.pendingByRepo.get(repo);if(!pending)pending=new Set,this.pendingByRepo.set(repo,pending);pending.add(slug)}deletePending(repo,slug){let pending=this.pendingByRepo.get(repo);if(!pending)return;if(pending.delete(slug),pending.size===0)this.pendingByRepo.delete(repo)}}var WORKTREE_NAME_RE=/^[A-Za-z0-9_][A-Za-z0-9._-]*$/;class WorktreeCoordinator{store;worktrees;canonPath;ensureProject;slugs;worktreeLocks=new Map;adoptLocks=new Map;reservedBranches=new Set;constructor(store,worktrees,canonPath2,ensureProject){this.store=store,this.worktrees=worktrees,this.canonPath=canonPath2,this.ensureProject=ensureProject,this.slugs=new SlugAllocator((repo)=>this.store.list().filter((t)=>samePath(t.repo,repo)&&t.kind!=="main").map((t)=>{return t.worktreePath.match(/([^/\\]+)[/\\]*$/)?.[1]??""}).filter((s)=>s.length>0))}async claimWorktreeName(repo,name){if(!WORKTREE_NAME_RE.test(name))throw new InvalidWorktreeNameError(name);return await this.slugs.claim(repo,name)}forget(id){this.worktreeLocks.delete(id)}async ensure(task,onProgress){let inflight=this.worktreeLocks.get(task.id);if(inflight)return inflight;let work=this.createWorktree(task,onProgress);this.worktreeLocks.set(task.id,work);try{return await work}finally{this.worktreeLocks.delete(task.id)}}async createWorktree(task,onProgress){let slug=task.worktreeName||await this.slugs.allocate(task.repo),branch=task.branch||await this.deriveAutoBranch(task),baseRef=task.baseRef,info;try{info=await this.worktrees.createForTask({repo:task.repo,slug,branch,baseRef,onProgress})}catch(err){throw this.slugs.cancel(task.repo,slug),err}finally{this.reservedBranches.delete(branch)}try{await this.store.update(task.id,{worktreePath:info.path,branch})}catch(err){throw await this.rollbackWorktree(info.path,task.branch?void 0:{repo:task.repo,branch}),this.slugs.cancel(task.repo,slug),err}return this.slugs.commit(task.repo,slug),info.path}async deriveAutoBranch(task){let names=await this.worktrees.listBranchNames(task.repo),base=deriveConventionBranch(task.title,inferBranchStyle(names),task.id),taken=new Set([...names,...this.reservedBranches]),branch=uniqueBranchName(base,taken,task.id);return this.reservedBranches.add(branch),branch}async rollbackWorktree(worktreePath,fresh){try{await this.worktrees.remove(worktreePath,fresh?{force:!0,deleteBranch:!0,...fresh}:{force:!0})}catch(err){console.error(`[rove] ensureWorktree rollback failed for ${worktreePath}:`,err)}}async discoverAdoptable(repo){let all=await this.worktrees.listAll(repo),linked=new Set(this.store.list().filter((t)=>t.worktreePath).map((t)=>this.canonPath(t.worktreePath)));return all.filter((wt)=>!linked.has(this.canonPath(wt.path)))}async adopt(input){let target=this.canonPath(input.worktreePath),inflight=this.adoptLocks.get(target);if(inflight)return inflight;let work=this.adoptLocked(input,target);this.adoptLocks.set(target,work);try{return await work}finally{this.adoptLocks.delete(target)}}async adoptLocked(input,target){let holders=this.store.list().filter((t)=>t.worktreePath&&this.canonPath(t.worktreePath)===target),existing=holders.find((t)=>!t.sharesWorkspaceOf)??holders[0];if(existing){if(input.ifExists==="return")return existing;throw Error(`adoptWorktree: ${input.worktreePath} is already adopted as a task`)}let match=(await this.worktrees.listAdoptablePaths(input.repo)).find((wt)=>this.canonPath(wt.path)===target);if(!match)throw Error(`adoptWorktree: ${input.worktreePath} is not an adoptable git worktree of ${input.repo} (unknown, detached, or the main checkout)`);let branch=input.branch?.trim()||match.branch,title=(input.title??basename(match.path)).trim()||PLACEHOLDER_TASK_TITLE;return await this.ensureProject(input.repo),this.store.create({repo:input.repo,title,branch,worktreePath:match.path,status:"backlog",kind:"task",vendor:input.vendor??DEFAULT_TASK_VENDOR})}}class Orchestrator{store;worktrees;worktreeCoordinator;editor;deletions;tasksAcc;activeTaskAcc;unsubscribeStore;mainTasks;tearDownSession;constructor(deps){this.store=deps.store,this.worktrees=deps.worktrees,this.tearDownSession=deps.tearDownSession,this.worktreeCoordinator=new WorktreeCoordinator(this.store,this.worktrees,canonPath,(repo)=>this.mainTasks.ensureIfEligible(repo)),this.mainTasks=new MainTaskCoordinator(this.store,(id)=>this.worktreeCoordinator.forget(id)),this.editor=new TaskEditor(this.store,this.worktrees),this.deletions=new TaskDeletionCoordinator(this.store,this.worktrees,(id)=>this.worktreeCoordinator.forget(id),deps.onSalvage,deps.onWorktreeResidue,deps.onBranchKept),this.tasksAcc=createStateCell(this.store.list());let persistedFocus=readLastActiveTaskId();this.activeTaskAcc=createStateCell(persistedFocus&&this.store.get(persistedFocus)?persistedFocus:null),this.unsubscribeStore=this.store.subscribe((snapshot)=>{this.tasksAcc.set(snapshot.slice())})}async init(){try{let promotable=promotableDirTasks({tasks:this.store.list(),isRepoRoot:(path)=>isGitRepo(path)&&samePath(resolveRepoRoot(path),path)});for(let task of promotable)await this.mainTasks.ensureIfEligible(task.repo,"explicit")}catch{}}activeTaskSignal(){return this.activeTaskAcc}async setActiveTask(id){let next=id===null?null:String(id);if(next&&this.store.get(next)?.deletion)throw new TaskDeletingError(next);if(this.activeTaskAcc.set(next),next&&this.store.get(next))writeLastActiveTaskId(next),this.store.touchRecency(next)}tasksSignal(){return this.tasksAcc}subscribeTasks(listener){return this.store.subscribe(listener)}dispose(){this.unsubscribeStore()}listTasks(){return this.store.list()}getTask(id){return this.store.get(id)}createTask=(input)=>createTaskRow({store:this.store,mainTasks:this.mainTasks,claimWorktreeName:(repo,name)=>this.worktreeCoordinator.claimWorktreeName(repo,name)},input);openDirectoryTask=(input)=>openDirectoryTaskRow({store:this.store},input);adoptScratchRepo=(id,repo)=>adoptScratchRepoRow({store:this.store},id,repo);spawnChildTask=(input)=>spawnChildTaskRow({store:this.store,worktrees:this.worktrees,createTask:this.createTask,ensureWorktree:(id)=>this.ensureWorktree(id)},input);createMigratedChild=(input)=>createMigratedChildRow({store:this.store},input);setPtyAlias=(id,alias)=>setPtyAliasRow({store:this.store},String(id),alias);async ensureMainTask(repo){return await this.mainTasks.ensure(repo)}async ensureWorktree(id,opts){let task=this.requireTask(id);if(task.deletion)throw new TaskDeletingError(String(task.id));if(task.kind==="main")return repoWorkingDir(task.repo);if(task.kind==="dir")return task.worktreePath;let owner=task.sharesWorkspaceOf?this.store.get(task.sharesWorkspaceOf):void 0;if(owner){let path=await this.ensureWorktree(owner.id,opts);if(path!==task.worktreePath||owner.branch!==task.branch)await this.store.update(task.id,{worktreePath:path,branch:owner.branch});return path}if(task.worktreePath){if(await this.worktrees.pathExists(task.worktreePath))return task.worktreePath;return await this.worktrees.pruneWorktrees(task.repo),await this.store.update(task.id,{worktreePath:""}),this.worktreeCoordinator.ensure({...task,worktreePath:""},opts?.onProgress)}return this.worktreeCoordinator.ensure(task,opts?.onProgress)}async clearWorktreePath(id){let task=this.store.get(id);if(!task||!task.worktreePath)return;if(task.kind==="main"||task.kind==="dir")return;let gone=canonPath(task.worktreePath);for(let holder of this.store.list()){if(holder.kind!=="task"||!holder.worktreePath||canonPath(holder.worktreePath)!==gone)continue;await this.store.update(holder.id,{worktreePath:""}),this.worktreeCoordinator.forget(holder.id)}}setTitle=(id,title)=>this.editor.setTitle(id,title);setBranch=(id,branch)=>this.editor.setBranch(id,branch);observeLanguage=(id,text)=>this.editor.observeLanguage(id,text);setVendor=(id,vendor,effort,model)=>this.editor.setVendor(id,vendor,effort,model);setCommand=(id,command,vendor)=>this.editor.setCommand(id,command,vendor);setPinned=(id,pinned)=>this.editor.setPinned(id,pinned);setRequireReport=(id,required)=>this.editor.setRequireReport(id,required);moveTask=(id,delta)=>this.editor.moveTask(id,delta);moveTaskToTop=(id)=>this.editor.moveTaskToTop(id);setStatus=(id,status)=>this.editor.setStatus(id,status);setWorkerReport=(id,report)=>this.editor.setWorkerReport(id,report);setPRStatus=(id,prStatus)=>this.editor.setPRStatus(id,prStatus);setLinkedWorkItem=(id,item)=>this.editor.setLinkedWorkItem(id,item);setQuotaResume=(id,state)=>this.editor.setQuotaResume(id,state);setPrompt=(id,prompt)=>this.editor.setPrompt(id,prompt);async deleteTask(id,opts){await this.deletions.deleteNow(id,opts)}async prepareTaskDeletion(id,opts){return this.deletions.prepare(id,opts)}async beginTaskDeletion(id){return this.deletions.begin(id)}async finishTaskDeletion(id){return this.deletions.finish(id)}async landPreflight(id){let task=this.requireTask(id);if(task.kind==="main")throw Error("landTask: a main task has no branch to land");if(task.kind==="dir")throw Error("landTask: a directory task has no Rove-managed branch to land");if(task.deletion)throw new TaskDeletingError(String(task.id));return landPreflight(task)}async landTask(id,opts){let task=this.requireTask(id);if(task.deletion)throw new TaskDeletingError(String(task.id));return landTaskWithCleanup(task,opts??{},{worktrees:this.worktrees,clearWorktreePath:(tid)=>this.clearWorktreePath(tid),tearDownSession:this.tearDownSession,sharesWorktree:(landed)=>this.store.list().some((t)=>t.id!==landed.id&&t.worktreePath&&canonPath(t.worktreePath)===canonPath(landed.worktreePath))})}async forgetProject(repo){await this.mainTasks.forget(repo)}async discoverAdoptableWorktrees(repo){if(!repo)throw Error("discoverAdoptableWorktrees: repo is required");return this.worktreeCoordinator.discoverAdoptable(repo)}async adoptWorktree(input){if(!input.repo)throw Error("adoptWorktree: repo is required");if(!input.worktreePath)throw Error("adoptWorktree: worktreePath is required");return this.worktreeCoordinator.adopt(input)}requireTask(id){let task=this.store.get(id);if(!task)throw new TaskNotFoundError(String(id));return task}}
|
|
4
|
+
export{Orchestrator};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{activityHookAdapters}from"./chunk-
|
|
2
|
+
import{activityHookAdapters}from"./chunk-kj37wrjn.js";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let adapter of activityHookAdapters()){if(!adapter.hookConfigRefusal)continue;let file=adapter.globalSettingsPath();if(!file)continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let reason=adapter.hookConfigRefusal(raw);if(reason)issues.push({file,reason})}return issues}
|
|
3
3
|
export{hookConfigIssues};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{API_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb,unknownVerbError}from"./chunk-
|
|
2
|
+
import{API_VERBS,VERBS,VERB_ALIASES,VERB_GROUPS,findVerb,unknownVerbError}from"./chunk-rk6tm9zq.js";import"./chunk-zrvsp7tg.js";import"./chunk-av482xxw.js";import"./chunk-kwyxwcr8.js";import"./chunk-4b6r81r7.js";import"./chunk-p6jw0zcd.js";import"./chunk-heajz5tw.js";import"./chunk-17e2tgyg.js";import"./chunk-eyrt04mg.js";import"./chunk-mzk4p07t.js";import"./chunk-4f4vr50c.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-a569ctz6.js";import"./chunk-pr22s2c3.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-kc3e07fn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-nahwgea8.js";import"./chunk-n7t7eqcz.js";import"./chunk-93e1q2ea.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y9kq9x48.js";import"./chunk-n8am3mgq.js";import"./chunk-fvvb0072.js";import"./chunk-jravy0cc.js";import"./chunk-rxqdw6s5.js";import"./chunk-f5n0tgky.js";import"./chunk-yzkhwn31.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-tbpj22sn.js";import"./chunk-kj37wrjn.js";import"./chunk-4fa35dbn.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-48ynmrd8.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-y1xnjx8x.js";import"./chunk-zsfyj36g.js";import"./chunk-sfn4s219.js";import"./chunk-v8nvfyd4.js";import"./chunk-gak4aag4.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-dc842he4.js";import"./chunk-eqa843hf.js";import"./chunk-kq01awhv.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-548fwbx3.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-yytjrrdh.js";import"./chunk-6rdvvbyv.js";import"./chunk-cmp64q4j.js";import"./chunk-krnacq08.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,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{existsSync}from"fs";import{join}from"path";function webRoot(){return[join(import.meta.dir,"..","web"),join(import.meta.dir,"..","..","..","rove-web","dist")].find((dir)=>existsSync(join(dir,"index.html")))??null}async function runWebSubcommand(args){let root=webRoot();if(!root)console.error(`${ROVE_PRODUCT_NAME} --web: the browser client is not in this build. From a checkout, run \`bun --filter rove-web build\` first; the npm package ships it in dist/web.`),process.exit(2);let{runBridge}=await import("./chunk-
|
|
2
|
+
import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{existsSync}from"fs";import{join}from"path";function webRoot(){return[join(import.meta.dir,"..","web"),join(import.meta.dir,"..","..","..","rove-web","dist")].find((dir)=>existsSync(join(dir,"index.html")))??null}async function runWebSubcommand(args){let root=webRoot();if(!root)console.error(`${ROVE_PRODUCT_NAME} --web: the browser client is not in this build. From a checkout, run \`bun --filter rove-web build\` first; the npm package ships it in dist/web.`),process.exit(2);let{runBridge}=await import("./chunk-mgweygem.js");await runBridge(args,{name:`${ROVE_PRODUCT_NAME} --web`,web:{root}})}export{runWebSubcommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{RemoteOrchestrator}from"./chunk-
|
|
2
|
+
import{RemoteOrchestrator}from"./chunk-g01bct19.js";import{startTunnel}from"./chunk-dhcx1gna.js";import{dedupeMachines,discoverMachine,duplicateAliasOf,learnedFrom,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-s4nrmbqh.js";import{loadStateFile}from"./chunk-32j6y5d1.js";import{createStateCell}from"./chunk-cmp64q4j.js";import{RoveDaemonClient}from"./chunk-krnacq08.js";import{logClient,logClientError}from"./chunk-0g4wc808.js";var NO_LIVE={activity:new Map,changes:new Map,tokens:new Map},PEER_CHANNELS=["task.snapshot","engine-state","worktree.changes","task.tokens"];class MachineHub{slots=new Map;machinesAcc=createStateCell([],"machines.status");tasksAcc=createStateCell([],"machines.tasks");liveAcc=createStateCell(NO_LIVE,"machines.live");disposed=!1;machinesSignal(){return this.machinesAcc}tasksSignal(){return this.tasksAcc}liveSignal(){return this.liveAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}sync(entries=dedupeMachines(listMachines())){if(this.disposed)return;let wanted=new Map(entries.map((entry)=>[entry.alias,entry])),fresh=[];for(let[alias,slot]of this.slots){let next=wanted.get(alias);if(next&&sameAddress(slot.entry,next))slot.entry=next;else this.drop(alias)}for(let entry of entries){if(this.slots.has(entry.alias))continue;this.slots.set(entry.alias,{entry,tasks:[]}),fresh.push(entry)}if(fresh.length===0&&wanted.size===this.slots.size&&this.machinesAcc.get().length===wanted.size)return;let known=new Map(this.machinesAcc.get().map((row)=>[row.alias,row]));this.machinesAcc.set([...this.slots.values()].map((slot)=>known.get(slot.entry.alias)??{alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})),this.republishTasks(),this.republishLive();for(let entry of fresh)this.connect(entry)}drop(alias){let slot=this.slots.get(alias);if(!slot)return;this.slots.delete(alias),slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop()}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed||this.slots.get(entry.alias)!==slot)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}let learned=found.ok?learnedFrom(found):{};if(found.ok)updateMachine(entry.alias,learned);let tunnel=startTunnel({alias:entry.alias,config:{...entry,...learned,sockets},remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(this.slots.get(entry.alias)!==slot)return;if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new RoveDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",channels:PEER_CHANNELS,expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{if(await orchestrator.init(),this.slots.get(entry.alias)!==slot)return}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()}),live=[orchestrator.engineStateSignal(),orchestrator.worktreeChangesSignal(),orchestrator.rowTokensSignal()].map((signal)=>signal.subscribe(()=>this.republishLive()));slot.unsubscribe=()=>{stopTasks(),stopConnection();for(let stop of live)stop()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),this.republishLive(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}republishLive(){let activity=new Map,changes=new Map,tokens=new Map;for(let slot of this.slots.values()){let o=slot.orchestrator;if(!o)continue;for(let[id,state]of o.engineStateSignal().get())activity.set(id,state);for(let[path,change]of o.worktreeChangesSignal().get()??[])changes.set(path,change);for(let[id,chips]of o.rowTokensSignal().get())tokens.set(id,chips)}this.liveAcc.set({activity,changes,tokens})}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.roveVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}republishTasks(){let merged=[];for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.tasksAcc.set(merged)}dispose(){this.disposed=!0;for(let alias of[...this.slots.keys()])this.drop(alias)}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function sameAddress(a,b){return a.host===b.host&&a.user===b.user&&a.port===b.port&&JSON.stringify(a.auth)===JSON.stringify(b.auth)}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}
|
|
3
3
|
export{MachineHub,stampOrigin};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{deriveTitleFromPrompt}from"./chunk-eyrt04mg.js";import{TaskDeletingError}from"./chunk-mzk4p07t.js";import{taskCwd}from"./chunk-
|
|
2
|
+
import{deriveTitleFromPrompt}from"./chunk-eyrt04mg.js";import{TaskDeletingError}from"./chunk-mzk4p07t.js";import{taskCwd}from"./chunk-pr22s2c3.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedEngine,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,killHostedSessions,listHostedSessions,openHostedSessionHost,pastePromptWhenEngineUp,trustEngineWorktree}from"./chunk-93e1q2ea.js";import{engineLaunchArgv,protocolEntry}from"./chunk-y9kq9x48.js";import{hostedKeyFor}from"./chunk-n8am3mgq.js";import{resolveLoginShell}from"./chunk-f5n0tgky.js";import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";var MAX_SESSIONS_SCANNED=8;function titleFromMessages(messages){let firstUser=messages.find((m)=>m.role==="user");if(!firstUser)return"";let text=firstUser.blocks.filter((b)=>b.type==="text").map((b)=>b.text).join(" "),title=deriveTitleFromPrompt(text);return title.length>0?Buffer.from(title,"utf8").toString("utf8"):title}async function deriveTitleFromSession(worktree,vendor=DEFAULT_TASK_VENDOR){if(!worktree)return"";let{history}=protocolEntry(vendor),ids=await history.listSessionIdsForWorktree(worktree);for(let sessionId of ids.slice(0,MAX_SESSIONS_SCANNED)){let title=titleFromMessages(await history.readHistory(sessionId));if(title)return title}return""}async function deriveTitleFromSessionId(vendor,sessionId){if(!sessionId)return"";try{return titleFromMessages(await protocolEntry(vendor).history.readHistory(sessionId))}catch{return""}}async function getTask(link,taskId){let{task}=await link.request("task.get",{taskId});return task}async function ensureTaskWorktree(link,taskId){let task=await getTask(link,taskId);if(task.deletion)throw new TaskDeletingError(taskId);if(task.worktreePath)return{task,worktreePath:taskCwd(task)};let{worktreePath}=await link.request("task.ensureWorktree",{taskId});if(!worktreePath)throw Error(`task ${taskId} has no worktree`);return{task,worktreePath:taskCwd({worktreePath,cwdSubpath:task.cwdSubpath})}}async function ensureTaskSessionAdapter(link,taskId){let{task,worktreePath}=await ensureTaskWorktree(link,taskId),launch=taskEngineLaunch(task,worktreePath,{kind:"repo-init"}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)throw Error(`failed to start hosted engine session for ${taskId}`);if(launch.firstMessage){let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0];await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs}).catch(()=>!1)}}finally{host.close()}return{session:launch.key,worktreePath}}async function startTaskSessionWithPromptAdapter(link,taskId,prompt){let{task,worktreePath}=await ensureTaskWorktree(link,taskId);await link.request("task.observeLanguage",{taskId,text:prompt}).catch(()=>{});let launch=taskEngineLaunch(task,worktreePath,{kind:"new-task",prompt}),host=await ensureHostedSessionHost();try{if(!(await ensureHostedEngine(host.rpc,worktreePath,launch)).alive)return{started:!1,error:"hosted session did not open"};let engineBin=engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model})[0],wait={initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs};if(launch.firstMessage){if(await pastePromptWhenEngineUp(host.rpc,launch.key,engineBin,launch.firstMessage,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}if(await awaitEngineProcess(host.rpc,launch.key,engineBin,wait)!==null)return{started:!0};return{started:!1,error:await startFailureReason(host.rpc,launch.key)}}finally{host.close()}}async function startFailureReason(rpc,key){let tail=await hostedSessionFailureLine(rpc,key),base="engine process never started";return tail?`engine process never started; last session output: ${tail}`:"engine process never started"}function taskEngineLaunch(task,worktreePath,promptIntent){return trustEngineWorktree(task.vendor,worktreePath),buildEngineSessionLaunch({task:{id:task.id,kind:task.kind,vendor:task.vendor,repo:task.repo},worktreePath,shell:resolveLoginShell({fallback:"/bin/zsh"}),argv:engineLaunchArgv({command:task.command,vendor:task.vendor,effort:task.modelEffort,model:task.model}),promptIntent})}async function deliverPromptToLiveEngineAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return!1;try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0],task.scope);if(!key)return!1;let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return!1;return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})!==null}catch{return!1}finally{host.close()}}function tabIdFromHostedKey(key){return key.split("::")[1]??"tab-1"}async function deliverPromptToLiveEngineDetailedAdapter(task,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let sessions=await listHostedSessions(host.rpc),engineArgv=engineLaunchArgv({command:task.command,vendor:task.vendor}),key=findHostedEngineKey(sessions,task.id,engineArgv[0],task.scope);if(!key)return{outcome:"no-session"};let presence=await enginePresence(sessions.find((s)=>s.key===key)?.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:tabIdFromHostedKey(key)};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:tabIdFromHostedKey(key)}}catch{return{outcome:"no-session"}}finally{host.close()}}async function deliverPromptToLiveEngineTabDetailedAdapter(target,prompt){let host=await openHostedSessionHost();if(!host)return{outcome:"no-session"};try{let key=hostedKeyFor(target.id,target.tabId,target.scope);if(!key)return{outcome:"no-session"};let sessions;try{sessions=await listHostedSessions(host.rpc)}catch{return{outcome:"no-session"}}let session=sessions.find((candidate)=>candidate.alive&&candidate.key===key);if(!session)return{outcome:"no-session"};let engineArgv=engineLaunchArgv({command:target.command,vendor:target.vendor}),presence=await enginePresence(session.pid,engineArgv);if(presence.kind!=="engine")return{outcome:"no-engine",tabId:target.tabId};return await deliverToHostedKey(host.rpc,key,prompt,{vendor:presence.vendor})===null?{outcome:"no-session"}:{outcome:"delivered",tabId:target.tabId}}finally{host.close()}}async function tearDownTaskSessionAdapter(taskId,scope){let host=await openHostedSessionHost();if(!host)return;try{let keys=hostedTaskKeys(await listHostedSessions(host.rpc),taskId,scope);await killHostedSessions(host.rpc,keys,{wait:!0})}catch{}finally{host.close()}}
|
|
3
3
|
export{deriveTitleFromSession,deriveTitleFromSessionId,ensureTaskSessionAdapter,startTaskSessionWithPromptAdapter,deliverPromptToLiveEngineAdapter,deliverPromptToLiveEngineDetailedAdapter,deliverPromptToLiveEngineTabDetailedAdapter,tearDownTaskSessionAdapter};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{stampOrigin}from"./chunk-
|
|
2
|
+
import{stampOrigin}from"./chunk-wrmjgk0h.js";import{createStateCell}from"./chunk-cmp64q4j.js";var NO_LIVE={activity:new Map,changes:new Map,tokens:new Map},NONE={machines:[],tasks:[],live:NO_LIVE};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;remote=NONE;machinesAcc=createStateCell([],"machines.status");tasksAcc;liveAcc=createStateCell(NO_LIVE,"machines.live");stops;constructor(local){this.local=local;this.tasksAcc=createStateCell(local.tasksSignal().get(),"machines.tasks");let raw=local.rawChannelSignal("machines"),take=()=>{let next=decodeMachines(raw.get());if(!next)return;this.remote=next,this.machinesAcc.set(next.machines),this.liveAcc.set(next.live),this.merge()};this.stops=[raw.subscribe(take),local.tasksSignal().subscribe(()=>this.merge())],take()}machinesSignal(){return this.machinesAcc}tasksSignal(){return this.tasksAcc}liveSignal(){return this.liveAcc}merge(){let local=this.local.tasksSignal().get();if(this.remote.machines.length===0){this.tasksAcc.set(local);return}this.tasksAcc.set([...local.map((task)=>stampOrigin(task,"local","local")),...this.remote.tasks])}dispose(){for(let stop of this.stops)stop()}}
|
|
3
3
|
export{decodeMachines,MachineFeed};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{vendorFromArgv}from"./chunk-ga412sby.js";import{engineEntry}from"./chunk-3gegmpff.js";import{isContribEngine}from"./chunk-4fa35dbn.js";import{roveCliInvocation}from"./chunk-eqa843hf.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{getCustomEngineIds,getPersistedString}from"./chunk-rfp0ayra.js";function engineCommandKey(vendor){return`engineCommand.${vendor}`}function engineNameKey(vendor){return`engineName.${vendor}`}function engineDisplayName(vendor){return getPersistedString(engineNameKey(vendor))?.trim()||engineEntry(vendor).displayName}function humanizeSlug(id){return id.split(/[-_]+/).filter((word)=>word.length>0).map((word)=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function engineRenamedFrom(vendor,override){let name=override.trim(),base=engineEntry(vendor).displayName;if(!name||name===base||name===humanizeSlug(vendor))return;return base}function defaultEngineCommand(vendor){return engineEntry(coerceVendorId(vendor)).defaultCommand}function parseEngineCommand(command){let out=[],token="",hasToken=!1,quote=null;for(let ch of command){if(quote){if(ch===quote)quote=null;else token+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,hasToken=!0;continue}if(/\s/.test(ch)){if(hasToken)out.push(token),token="",hasToken=!1;continue}token+=ch,hasToken=!0}if(hasToken)out.push(token);return out}function interactiveEngineCommand(vendor,effort,model){let v=coerceVendorId(vendor),override=getPersistedString(engineCommandKey(v))?.trim(),base=(()=>{if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(v)})();return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,v,effort),v,model),v)}function withEngineTerminalTitle(argv,vendor){let args=engineEntry(coerceVendorId(vendor)).terminalTitle?.launchArgs;return args&&args.length>0?[...argv,...args]:argv}function withEngineEffort(argv,vendor,effort){let trimmed=effort?.trim();if(!trimmed)return argv;let entry=engineEntry(coerceVendorId(vendor));if(!entry.effortLevels?.includes(trimmed))return argv;return entry.effortArgv?.(argv,trimmed)??argv}function withEngineModel(argv,vendor,model){let trimmed=model?.trim();if(!trimmed)return argv;return engineEntry(coerceVendorId(vendor)).modelArgv?.(argv,trimmed)??argv}function roveApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}import{randomUUID}from"crypto";function hasFlag(argv,flag){return argv.some((a)=>a===flag||a.startsWith(`${flag}=`))}function controlsOwnSession(identity,argv){return(identity?.sessionControlFlags??[]).some((flag)=>hasFlag(argv,flag))}function pinSessionArgv(identity,argv,sessionId){if(!identity?.pinFlag)return argv;if(controlsOwnSession(identity,argv))return argv;return[...argv,identity.pinFlag,sessionId]}function acceptsPinnedSession(identity,argv){return!!identity?.pinFlag&&!controlsOwnSession(identity,argv)}function resumeSessionArgv(identity,base,sessionId){if(!sessionId||!identity?.resumeArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.resumeArgv(base,sessionId)}function pickUnclaimedSessionId(ids,claimed){for(let i=ids.length-1;i>=0;i--){let id=ids[i];if(id&&!claimed.has(id))return id}return null}function forkSessionArgvFor(identity,base,sourceId,newId){if(!sourceId||!identity?.forkArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.forkArgv(base,sourceId,newId)}function acceptsSessionFork(identity){return!!identity?.forkArgv}var GENERIC_PROTOCOL="generic",ENGINE_PROTOCOLS=BUILTIN_VENDORS;function engineProtocolKey(id){return`engineProtocol.${id}`}function getEngineProtocol(id){if(isBuiltinVendor(id)||isContribEngine(id))return id;let raw=getPersistedString(engineProtocolKey(id))?.trim();return raw&&ENGINE_PROTOCOLS.includes(raw)?raw:void 0}function isPresetId(id){return isBuiltinVendor(id)||isContribEngine(id)||getCustomEngineIds().includes(id)}function listPresetIds(){return[...BUILTIN_VENDORS,...getCustomEngineIds()]}function describePreset(id){let command=getPersistedString(engineCommandKey(id))?.trim()||defaultEngineCommand(id).join(" ");return{id,name:engineDisplayName(id),command,protocol:getEngineProtocol(id)??GENERIC_PROTOCOL,builtin:isBuiltinVendor(id)}}function listEnginePresets(){return listPresetIds().map(describePreset)}function resolveCommandProtocol(command){let trimmed=command?.trim();if(!trimmed)return GENERIC_PROTOCOL;if(isPresetId(trimmed))return getEngineProtocol(trimmed)??GENERIC_PROTOCOL;let fromArgv=vendorFromArgv(trimmed);if(fromArgv)return fromArgv;let argv0=parseEngineCommand(trimmed)[0];if(argv0)for(let id of getCustomEngineIds()){let preset=getPersistedString(engineCommandKey(id))?.trim();if(preset&&parseEngineCommand(preset)[0]===argv0)return getEngineProtocol(id)??GENERIC_PROTOCOL}return GENERIC_PROTOCOL}function engineLaunchArgv(spec){let command=spec.command?.trim();if(!command)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);let vendor=(isPresetId(command)?getEngineProtocol(command):void 0)??resolveCommandProtocol(command),base=isPresetId(command)?presetBaseArgv(command):(()=>{let argv=parseEngineCommand(command);return argv.length>0?argv:null})();if(!base)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,vendor,spec.effort),vendor,spec.model),vendor)}function presetBaseArgv(id){let override=getPersistedString(engineCommandKey(id))?.trim();if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(id)}function sessionProtocol(vendor){let id=vendor?.trim();if(!id)return"claude";return getEngineProtocol(id)??id}function protocolEntry(vendor){return engineEntry(sessionProtocol(vendor))}function withPinnedSessionId(argv,vendor,newId=randomUUID){let identity=engineEntry(sessionProtocol(vendor)).sessionIdentity;if(!acceptsPinnedSession(identity,argv))return{argv,sessionId:null};let sessionId=newId();return{argv:pinSessionArgv(identity,argv,sessionId),sessionId}}function engineResumeArgv(base,vendor,sessionId){return resumeSessionArgv(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sessionId)}function engineCanFork(vendor){return acceptsSessionFork(engineEntry(sessionProtocol(vendor)).sessionIdentity)}function engineForkArgv(base,vendor,sourceId,newId){return forkSessionArgvFor(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sourceId,newId)}var ID_RE=/^tab-(\d+)$/;function tabOrdinalOf(id){let match=ID_RE.exec(id);return match?Number(match[1]):null}var sameValue=(a,b)=>a===b||JSON.stringify(a)===JSON.stringify(b);function insertAfter(tabs,row,after){if(after===null)return[row,...tabs];let i=after===void 0?-1:tabs.findIndex((t)=>t.id===after);return i<0?[...tabs,row]:[...tabs.slice(0,i+1),row,...tabs.slice(i+1)]}function applyTabOps(current,ops,tombstones=new Set){let state=current,changed=!1,opened=[],set=(next)=>{state=next,changed=!0};for(let op of ops)switch(op.op){case"seed":{if(state===null||state.tabs.length===0){let floor=Math.max(op.state.nextOrdinal,maxOrdinal(op.state)+1,state?.nextOrdinal??0);set({...op.state,nextOrdinal:floor})}break}case"forget":{if(state!==null)set(null);break}case"open":{let base=state??{tabs:[],nextOrdinal:1},wanted=op.row.id;if(wanted!==void 0&&(base.tabs.some((t)=>t.id===wanted)||tombstones.has(wanted))){opened.push(null);break}let ordinal=wanted!==void 0?tabOrdinalOf(wanted)??op.row.ordinal??base.nextOrdinal:base.nextOrdinal,id=wanted??`tab-${ordinal}`,row={...op.row,id,ordinal};set({...base,tabs:insertAfter(base.tabs,row,op.after),nextOrdinal:Math.max(base.nextOrdinal,ordinal+1)}),opened.push(id);break}case"patch":{if(!state)break;let i=state.tabs.findIndex((t)=>t.id===op.id),row=state.tabs[i];if(!row)break;let next={...row},rowChanged=!1;for(let[key,value]of Object.entries(op.set??{})){if(key==="id"||key==="ordinal"||sameValue(next[key],value))continue;next[key]=value,rowChanged=!0}for(let key of op.unset??[]){if(key==="id"||key==="ordinal"||key==="kind"||!(key in next))continue;delete next[key],rowChanged=!0}if(!rowChanged)break;let tabs=[...state.tabs];tabs[i]=next,set({...state,tabs});break}case"close":{if(!state||!state.tabs.some((t)=>t.id===op.id))break;tombstones.add(op.id);let tabs=state.tabs.filter((t)=>t.id!==op.id),reopen=tabs.length===0&&op.reopenAs!==void 0?{reopenAs:op.reopenAs}:{},{activeId,...rest}=state;set({...rest,tabs,...activeId!==void 0&&activeId!==op.id?{activeId}:{},...reopen});break}case"order":{if(!state)break;let byId=new Map(state.tabs.map((t)=>[t.id,t])),tabs=[...op.ids.flatMap((id)=>{let row=byId.get(id);if(!row)return[];return byId.delete(id),[row]}),...state.tabs.filter((t)=>byId.has(t.id))];if(tabs.every((t,i)=>t===state?.tabs[i]))break;set({...state,tabs});break}case"focus":{if(!state||state.activeId===op.id||!state.tabs.some((t)=>t.id===op.id))break;set({...state,activeId:op.id});break}case"meta":{if(!state||sameValue(state.reopenAs,op.reopenAs))break;let{reopenAs:_drop,...rest}=state;set(op.reopenAs===void 0?rest:{...rest,reopenAs:op.reopenAs});break}}return{state,changed,opened}}function maxOrdinal(state){return state.tabs.reduce((max,tab)=>Math.max(max,tab.ordinal),0)}function reserveOrdinals(state,count){let base=state??{tabs:[],nextOrdinal:1},from=Math.max(base.nextOrdinal,maxOrdinal(base)+1);return{state:{...base,nextOrdinal:from+count},from}}function releaseOrdinals(state,from,to){if(!state||state.nextOrdinal!==to||from>=to)return state;let floor=Math.max(from,maxOrdinal(state)+1);return floor<state.nextOrdinal?{...state,nextOrdinal:floor}:state}function diffTabs(prev,next){if(prev===null)return[{op:"seed",state:next}];let ops=[],prevById=new Map(prev.tabs.map((t)=>[t.id,t])),nextIds=new Set(next.tabs.map((t)=>t.id));for(let row of prev.tabs){let reopen=next.tabs.length===0&&next.reopenAs!==void 0?{reopenAs:next.reopenAs}:{};if(!nextIds.has(row.id))ops.push({op:"close",id:row.id,...reopen})}next.tabs.forEach((row,i)=>{let before=prevById.get(row.id);if(!before){ops.push({op:"open",row,after:i===0?null:next.tabs[i-1]?.id??null});return}if(before===row)return;let set={},unset=[];for(let[key,value]of Object.entries(row))if(key!=="id"&&key!=="ordinal"&&!sameValue(before[key],value))set[key]=value;for(let key of Object.keys(before))if(!(key in row))unset.push(key);if(Object.keys(set).length>0||unset.length>0)ops.push({op:"patch",id:row.id,...Object.keys(set).length>0?{set}:{},...unset.length>0?{unset}:{}})});let kept=next.tabs.filter((t)=>prevById.has(t.id)).map((t)=>t.id),prevKept=prev.tabs.filter((t)=>nextIds.has(t.id)).map((t)=>t.id);if(kept.some((id,i)=>id!==prevKept[i]))ops.push({op:"order",ids:next.tabs.map((t)=>t.id)});if(!sameValue(prev.reopenAs,next.reopenAs)&&next.tabs.length>0)ops.push({op:"meta",reopenAs:next.reopenAs});return ops}
|
|
2
|
+
import{vendorFromArgv}from"./chunk-tbpj22sn.js";import{engineEntry}from"./chunk-kj37wrjn.js";import{isContribEngine}from"./chunk-4fa35dbn.js";import{roveCliInvocation}from"./chunk-eqa843hf.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{getCustomEngineIds,getPersistedString}from"./chunk-rfp0ayra.js";function engineCommandKey(vendor){return`engineCommand.${vendor}`}function engineNameKey(vendor){return`engineName.${vendor}`}function engineDisplayName(vendor){return getPersistedString(engineNameKey(vendor))?.trim()||engineEntry(vendor).displayName}function humanizeSlug(id){return id.split(/[-_]+/).filter((word)=>word.length>0).map((word)=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function engineRenamedFrom(vendor,override){let name=override.trim(),base=engineEntry(vendor).displayName;if(!name||name===base||name===humanizeSlug(vendor))return;return base}function defaultEngineCommand(vendor){return engineEntry(coerceVendorId(vendor)).defaultCommand}function parseEngineCommand(command){let out=[],token="",hasToken=!1,quote=null;for(let ch of command){if(quote){if(ch===quote)quote=null;else token+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,hasToken=!0;continue}if(/\s/.test(ch)){if(hasToken)out.push(token),token="",hasToken=!1;continue}token+=ch,hasToken=!0}if(hasToken)out.push(token);return out}function interactiveEngineCommand(vendor,effort,model){let v=coerceVendorId(vendor),override=getPersistedString(engineCommandKey(v))?.trim(),base=(()=>{if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(v)})();return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,v,effort),v,model),v)}function withEngineTerminalTitle(argv,vendor){let args=engineEntry(coerceVendorId(vendor)).terminalTitle?.launchArgs;return args&&args.length>0?[...argv,...args]:argv}function withEngineEffort(argv,vendor,effort){let trimmed=effort?.trim();if(!trimmed)return argv;let entry=engineEntry(coerceVendorId(vendor));if(!entry.effortLevels?.includes(trimmed))return argv;return entry.effortArgv?.(argv,trimmed)??argv}function withEngineModel(argv,vendor,model){let trimmed=model?.trim();if(!trimmed)return argv;return engineEntry(coerceVendorId(vendor)).modelArgv?.(argv,trimmed)??argv}function roveApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}import{randomUUID}from"crypto";function hasFlag(argv,flag){return argv.some((a)=>a===flag||a.startsWith(`${flag}=`))}function controlsOwnSession(identity,argv){return(identity?.sessionControlFlags??[]).some((flag)=>hasFlag(argv,flag))}function pinSessionArgv(identity,argv,sessionId){if(!identity?.pinFlag)return argv;if(controlsOwnSession(identity,argv))return argv;return[...argv,identity.pinFlag,sessionId]}function acceptsPinnedSession(identity,argv){return!!identity?.pinFlag&&!controlsOwnSession(identity,argv)}function resumeSessionArgv(identity,base,sessionId){if(!sessionId||!identity?.resumeArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.resumeArgv(base,sessionId)}function pickUnclaimedSessionId(ids,claimed){for(let i=ids.length-1;i>=0;i--){let id=ids[i];if(id&&!claimed.has(id))return id}return null}function forkSessionArgvFor(identity,base,sourceId,newId){if(!sourceId||!identity?.forkArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.forkArgv(base,sourceId,newId)}function acceptsSessionFork(identity){return!!identity?.forkArgv}var GENERIC_PROTOCOL="generic",ENGINE_PROTOCOLS=BUILTIN_VENDORS;function engineProtocolKey(id){return`engineProtocol.${id}`}function getEngineProtocol(id){if(isBuiltinVendor(id)||isContribEngine(id))return id;let raw=getPersistedString(engineProtocolKey(id))?.trim();return raw&&ENGINE_PROTOCOLS.includes(raw)?raw:void 0}function isPresetId(id){return isBuiltinVendor(id)||isContribEngine(id)||getCustomEngineIds().includes(id)}function listPresetIds(){return[...BUILTIN_VENDORS,...getCustomEngineIds()]}function describePreset(id){let command=getPersistedString(engineCommandKey(id))?.trim()||defaultEngineCommand(id).join(" ");return{id,name:engineDisplayName(id),command,protocol:getEngineProtocol(id)??GENERIC_PROTOCOL,builtin:isBuiltinVendor(id)}}function listEnginePresets(){return listPresetIds().map(describePreset)}function resolveCommandProtocol(command){let trimmed=command?.trim();if(!trimmed)return GENERIC_PROTOCOL;if(isPresetId(trimmed))return getEngineProtocol(trimmed)??GENERIC_PROTOCOL;let fromArgv=vendorFromArgv(trimmed);if(fromArgv)return fromArgv;let argv0=parseEngineCommand(trimmed)[0];if(argv0)for(let id of getCustomEngineIds()){let preset=getPersistedString(engineCommandKey(id))?.trim();if(preset&&parseEngineCommand(preset)[0]===argv0)return getEngineProtocol(id)??GENERIC_PROTOCOL}return GENERIC_PROTOCOL}function engineLaunchArgv(spec){let command=spec.command?.trim();if(!command)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);let vendor=(isPresetId(command)?getEngineProtocol(command):void 0)??resolveCommandProtocol(command),base=isPresetId(command)?presetBaseArgv(command):(()=>{let argv=parseEngineCommand(command);return argv.length>0?argv:null})();if(!base)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,vendor,spec.effort),vendor,spec.model),vendor)}function presetBaseArgv(id){let override=getPersistedString(engineCommandKey(id))?.trim();if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(id)}function sessionProtocol(vendor){let id=vendor?.trim();if(!id)return"claude";return getEngineProtocol(id)??id}function protocolEntry(vendor){return engineEntry(sessionProtocol(vendor))}function withPinnedSessionId(argv,vendor,newId=randomUUID){let identity=engineEntry(sessionProtocol(vendor)).sessionIdentity;if(!acceptsPinnedSession(identity,argv))return{argv,sessionId:null};let sessionId=newId();return{argv:pinSessionArgv(identity,argv,sessionId),sessionId}}function engineResumeArgv(base,vendor,sessionId){return resumeSessionArgv(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sessionId)}function engineCanFork(vendor){return acceptsSessionFork(engineEntry(sessionProtocol(vendor)).sessionIdentity)}function engineForkArgv(base,vendor,sourceId,newId){return forkSessionArgvFor(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sourceId,newId)}var ID_RE=/^tab-(\d+)$/;function tabOrdinalOf(id){let match=ID_RE.exec(id);return match?Number(match[1]):null}var sameValue=(a,b)=>a===b||JSON.stringify(a)===JSON.stringify(b);function insertAfter(tabs,row,after){if(after===null)return[row,...tabs];let i=after===void 0?-1:tabs.findIndex((t)=>t.id===after);return i<0?[...tabs,row]:[...tabs.slice(0,i+1),row,...tabs.slice(i+1)]}function applyTabOps(current,ops,tombstones=new Set){let state=current,changed=!1,opened=[],set=(next)=>{state=next,changed=!0};for(let op of ops)switch(op.op){case"seed":{if(state===null||state.tabs.length===0){let floor=Math.max(op.state.nextOrdinal,maxOrdinal(op.state)+1,state?.nextOrdinal??0);set({...op.state,nextOrdinal:floor})}break}case"forget":{if(state!==null)set(null);break}case"open":{let base=state??{tabs:[],nextOrdinal:1},wanted=op.row.id;if(wanted!==void 0&&(base.tabs.some((t)=>t.id===wanted)||tombstones.has(wanted))){opened.push(null);break}let ordinal=wanted!==void 0?tabOrdinalOf(wanted)??op.row.ordinal??base.nextOrdinal:base.nextOrdinal,id=wanted??`tab-${ordinal}`,row={...op.row,id,ordinal};set({...base,tabs:insertAfter(base.tabs,row,op.after),nextOrdinal:Math.max(base.nextOrdinal,ordinal+1)}),opened.push(id);break}case"patch":{if(!state)break;let i=state.tabs.findIndex((t)=>t.id===op.id),row=state.tabs[i];if(!row)break;let next={...row},rowChanged=!1;for(let[key,value]of Object.entries(op.set??{})){if(key==="id"||key==="ordinal"||sameValue(next[key],value))continue;next[key]=value,rowChanged=!0}for(let key of op.unset??[]){if(key==="id"||key==="ordinal"||key==="kind"||!(key in next))continue;delete next[key],rowChanged=!0}if(!rowChanged)break;let tabs=[...state.tabs];tabs[i]=next,set({...state,tabs});break}case"close":{if(!state||!state.tabs.some((t)=>t.id===op.id))break;tombstones.add(op.id);let tabs=state.tabs.filter((t)=>t.id!==op.id),reopen=tabs.length===0&&op.reopenAs!==void 0?{reopenAs:op.reopenAs}:{},{activeId,...rest}=state;set({...rest,tabs,...activeId!==void 0&&activeId!==op.id?{activeId}:{},...reopen});break}case"order":{if(!state)break;let byId=new Map(state.tabs.map((t)=>[t.id,t])),tabs=[...op.ids.flatMap((id)=>{let row=byId.get(id);if(!row)return[];return byId.delete(id),[row]}),...state.tabs.filter((t)=>byId.has(t.id))];if(tabs.every((t,i)=>t===state?.tabs[i]))break;set({...state,tabs});break}case"focus":{if(!state||state.activeId===op.id||!state.tabs.some((t)=>t.id===op.id))break;set({...state,activeId:op.id});break}case"meta":{if(!state||sameValue(state.reopenAs,op.reopenAs))break;let{reopenAs:_drop,...rest}=state;set(op.reopenAs===void 0?rest:{...rest,reopenAs:op.reopenAs});break}}return{state,changed,opened}}function maxOrdinal(state){return state.tabs.reduce((max,tab)=>Math.max(max,tab.ordinal),0)}function reserveOrdinals(state,count){let base=state??{tabs:[],nextOrdinal:1},from=Math.max(base.nextOrdinal,maxOrdinal(base)+1);return{state:{...base,nextOrdinal:from+count},from}}function releaseOrdinals(state,from,to){if(!state||state.nextOrdinal!==to||from>=to)return state;let floor=Math.max(from,maxOrdinal(state)+1);return floor<state.nextOrdinal?{...state,nextOrdinal:floor}:state}function diffTabs(prev,next){if(prev===null)return[{op:"seed",state:next}];let ops=[],prevById=new Map(prev.tabs.map((t)=>[t.id,t])),nextIds=new Set(next.tabs.map((t)=>t.id));for(let row of prev.tabs){let reopen=next.tabs.length===0&&next.reopenAs!==void 0?{reopenAs:next.reopenAs}:{};if(!nextIds.has(row.id))ops.push({op:"close",id:row.id,...reopen})}next.tabs.forEach((row,i)=>{let before=prevById.get(row.id);if(!before){ops.push({op:"open",row,after:i===0?null:next.tabs[i-1]?.id??null});return}if(before===row)return;let set={},unset=[];for(let[key,value]of Object.entries(row))if(key!=="id"&&key!=="ordinal"&&!sameValue(before[key],value))set[key]=value;for(let key of Object.keys(before))if(!(key in row))unset.push(key);if(Object.keys(set).length>0||unset.length>0)ops.push({op:"patch",id:row.id,...Object.keys(set).length>0?{set}:{},...unset.length>0?{unset}:{}})});let kept=next.tabs.filter((t)=>prevById.has(t.id)).map((t)=>t.id),prevKept=prev.tabs.filter((t)=>nextIds.has(t.id)).map((t)=>t.id);if(kept.some((id,i)=>id!==prevKept[i]))ops.push({op:"order",ids:next.tabs.map((t)=>t.id)});if(!sameValue(prev.reopenAs,next.reopenAs)&&next.tabs.length>0)ops.push({op:"meta",reopenAs:next.reopenAs});return ops}
|
|
3
3
|
export{engineCommandKey,engineNameKey,engineDisplayName,humanizeSlug,engineRenamedFrom,defaultEngineCommand,interactiveEngineCommand,roveApiInvocation,pickUnclaimedSessionId,GENERIC_PROTOCOL,ENGINE_PROTOCOLS,engineProtocolKey,getEngineProtocol,listPresetIds,describePreset,listEnginePresets,resolveCommandProtocol,engineLaunchArgv,sessionProtocol,protocolEntry,withPinnedSessionId,engineResumeArgv,engineCanFork,engineForkArgv,applyTabOps,reserveOrdinals,releaseOrdinals,diffTabs};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{defaultFixRuntime}from"./chunk-
|
|
2
|
+
import{defaultFixRuntime}from"./chunk-v8z4xnar.js";import{INBOUND_CLASSES,deniedClasses,setInbound}from"./chunk-dj742g75.js";import"./chunk-rk6tm9zq.js";import"./chunk-zrvsp7tg.js";import"./chunk-av482xxw.js";import"./chunk-kwyxwcr8.js";import"./chunk-4b6r81r7.js";import"./chunk-p6jw0zcd.js";import"./chunk-heajz5tw.js";import"./chunk-17e2tgyg.js";import"./chunk-eyrt04mg.js";import"./chunk-mzk4p07t.js";import"./chunk-4f4vr50c.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-a569ctz6.js";import"./chunk-pr22s2c3.js";import"./chunk-gq36nzg8.js";import"./chunk-5mhvjytn.js";import"./chunk-kc3e07fn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-nahwgea8.js";import"./chunk-n7t7eqcz.js";import"./chunk-93e1q2ea.js";import"./chunk-1z2sze0v.js";import"./chunk-sak1tphp.js";import"./chunk-y9kq9x48.js";import"./chunk-n8am3mgq.js";import"./chunk-fvvb0072.js";import"./chunk-jravy0cc.js";import"./chunk-rxqdw6s5.js";import"./chunk-f5n0tgky.js";import"./chunk-yzkhwn31.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-tbpj22sn.js";import"./chunk-kj37wrjn.js";import"./chunk-4fa35dbn.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{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{primaryCheckouts,repoIdOf,repoIdentity,setPrimaryCheckout}from"./chunk-48ynmrd8.js";import"./chunk-f09ex46c.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import{shQuote}from"./chunk-y1xnjx8x.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import"./chunk-sfn4s219.js";import"./chunk-v8nvfyd4.js";import"./chunk-gak4aag4.js";import"./chunk-2r1fgng9.js";import"./chunk-2brn8e1y.js";import"./chunk-dc842he4.js";import"./chunk-eqa843hf.js";import"./chunk-kq01awhv.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import{CURRENT_VERSION}from"./chunk-548fwbx3.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-yytjrrdh.js";import"./chunk-6rdvvbyv.js";import"./chunk-cmp64q4j.js";import"./chunk-krnacq08.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
|
`)}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-
|
|
2
|
+
import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-6rdvvbyv.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};
|