@sma1lboy/rove 0.9.274 → 0.9.276
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-0d7517kk.js +6 -0
- package/dist/cli/{chunk-55ajzrj6.js → chunk-0r1jf8m9.js} +1 -1
- package/dist/cli/{chunk-qe7xb4rm.js → chunk-1ca2j9w6.js} +2 -2
- package/dist/cli/chunk-1eef3z5v.js +3 -0
- package/dist/cli/{chunk-8h437k1q.js → chunk-1jjqk7sq.js} +1 -1
- package/dist/cli/chunk-1n03wzx4.js +3 -0
- package/dist/cli/{chunk-9trbc3kj.js → chunk-22rgewg0.js} +2 -2
- package/dist/cli/{chunk-jwedmkm8.js → chunk-283vd9h7.js} +1 -1
- package/dist/cli/chunk-2kqxz9a4.js +5 -0
- package/dist/cli/chunk-2xsxcdp6.js +3 -0
- package/dist/cli/{chunk-bj6sa371.js → chunk-372g44dg.js} +1 -1
- package/dist/cli/{chunk-4dxc29mm.js → chunk-387w0db1.js} +1 -1
- package/dist/cli/{chunk-ypd337d0.js → chunk-3xkhcfet.js} +2 -2
- package/dist/cli/{chunk-qvnr8c18.js → chunk-3y9xzbqh.js} +1 -1
- package/dist/cli/chunk-4117kgmx.js +2 -0
- package/dist/cli/chunk-4a05fgdh.js +2 -0
- package/dist/cli/chunk-4dt1gfb3.js +3 -0
- package/dist/cli/{chunk-ycd28edp.js → chunk-4xvmrg86.js} +3 -4
- package/dist/cli/{chunk-sa48rtjz.js → chunk-511103e8.js} +1 -1
- package/dist/cli/chunk-59p3h5e9.js +2 -0
- package/dist/cli/{chunk-egpcaxwb.js → chunk-5e9y8aw5.js} +1 -1
- package/dist/cli/chunk-5nvg3ek8.js +3 -0
- package/dist/cli/chunk-5yfffvqe.js +2 -0
- package/dist/cli/{chunk-16ttm9x6.js → chunk-63cwjceg.js} +1 -1
- package/dist/cli/{chunk-y5axx6ev.js → chunk-6mtfafaw.js} +1 -1
- package/dist/cli/{chunk-0g3sjn8z.js → chunk-6xga1a2d.js} +1 -1
- package/dist/cli/{chunk-xbwq4bc0.js → chunk-745pg3xm.js} +1 -1
- package/dist/cli/{chunk-29s67j3k.js → chunk-81thm1eb.js} +4 -4
- package/dist/cli/chunk-82apkcrk.js +5 -0
- package/dist/cli/chunk-84pvn784.js +2 -0
- package/dist/cli/{chunk-1exwrmjd.js → chunk-883fyezq.js} +1 -1
- package/dist/cli/{chunk-gryq2vgw.js → chunk-8dd60adw.js} +1 -1
- package/dist/cli/{chunk-qfe1wf5c.js → chunk-91tcwxph.js} +1 -1
- package/dist/cli/{chunk-mxgtz5vz.js → chunk-9c3brkb3.js} +1 -1
- package/dist/cli/chunk-9gh8kgjs.js +2 -0
- package/dist/cli/{chunk-h8t4xg1p.js → chunk-9rj2fx6v.js} +1 -1
- package/dist/cli/{chunk-w9cdc97q.js → chunk-a4r45qdn.js} +1 -1
- package/dist/cli/{chunk-p6jw0zcd.js → chunk-agvtzads.js} +1 -1
- package/dist/cli/{chunk-gcg5h667.js → chunk-awh7np6x.js} +1 -1
- package/dist/cli/chunk-b035pej7.js +20 -0
- package/dist/cli/{chunk-ez438kn3.js → chunk-b95q6zhk.js} +1 -1
- package/dist/cli/chunk-brgfsm5v.js +2 -0
- package/dist/cli/chunk-bw98jn7g.js +18 -0
- package/dist/cli/{chunk-bexnp6g4.js → chunk-c63vgbkw.js} +1 -1
- package/dist/cli/{chunk-8sggyn8y.js → chunk-c6fy8xew.js} +1 -1
- package/dist/cli/chunk-c7mz2aq0.js +2 -0
- package/dist/cli/{chunk-ec7f3wcm.js → chunk-cbrt4s7m.js} +2 -2
- package/dist/cli/chunk-ccwe9n56.js +19 -0
- package/dist/cli/chunk-cfzg8q3e.js +4 -0
- package/dist/cli/{chunk-387ecqb8.js → chunk-d0hpes59.js} +1 -1
- package/dist/cli/{chunk-edrxs4cy.js → chunk-d7f022eb.js} +5 -5
- package/dist/cli/{chunk-by6fjf7m.js → chunk-d7xbm9jp.js} +1 -1
- package/dist/cli/{chunk-3v9s3bcz.js → chunk-d9643dwf.js} +1 -1
- package/dist/cli/{chunk-x20bs6bs.js → chunk-dgx02565.js} +1 -1
- package/dist/cli/{chunk-ecrw211n.js → chunk-dt676ks9.js} +1 -1
- package/dist/cli/{chunk-g9yba5vh.js → chunk-e3cd4qd2.js} +2 -2
- package/dist/cli/chunk-e3t1zbv1.js +5 -0
- package/dist/cli/{chunk-0rrmz6k6.js → chunk-eege1x0a.js} +1 -1
- package/dist/cli/{chunk-t34kjg5y.js → chunk-ehm9abge.js} +4 -3
- package/dist/cli/{chunk-mmq6922s.js → chunk-eq7vey2j.js} +2 -2
- package/dist/cli/chunk-eyvw70yb.js +2 -0
- package/dist/cli/{chunk-m6yy3qc1.js → chunk-f76gzvq3.js} +1 -1
- package/dist/cli/{chunk-xkmdxcjg.js → chunk-fn7ffyam.js} +1 -1
- package/dist/cli/chunk-g4dtqbrj.js +2 -0
- package/dist/cli/chunk-g9ba25q5.js +3 -0
- package/dist/cli/{chunk-22d4fjjb.js → chunk-gafkp74h.js} +1 -1
- package/dist/cli/chunk-gctqthxq.js +97 -0
- package/dist/cli/{chunk-dpq60qph.js → chunk-gq57he03.js} +1 -1
- package/dist/cli/chunk-h2gznz46.js +2 -0
- package/dist/cli/{chunk-03rbg95q.js → chunk-h64rsbrx.js} +5 -5
- package/dist/cli/{chunk-5dd7trgf.js → chunk-h7vwn62z.js} +1 -1
- package/dist/cli/chunk-hcvp84b3.js +4 -0
- package/dist/cli/chunk-hhcmzs67.js +78 -0
- package/dist/cli/chunk-hmjg1qh3.js +2 -0
- package/dist/cli/{chunk-jd7p0y5x.js → chunk-j9b285x6.js} +1 -1
- package/dist/cli/{chunk-tw9w8pzg.js → chunk-jckx79gk.js} +3 -3
- package/dist/cli/{chunk-r77pfw4m.js → chunk-je80r59s.js} +1 -1
- package/dist/cli/{chunk-sbds7zx4.js → chunk-jfcn77n9.js} +1 -1
- package/dist/cli/chunk-jn10xeft.js +2 -0
- package/dist/cli/{chunk-g263457v.js → chunk-k1pwp155.js} +1 -1
- package/dist/cli/chunk-k235z3ct.js +2 -0
- package/dist/cli/{chunk-qs1r0tqr.js → chunk-m2a19yt4.js} +1 -1
- package/dist/cli/{chunk-5gzpq34w.js → chunk-m73x5nry.js} +3 -3
- package/dist/cli/chunk-ma21srvx.js +3 -0
- package/dist/cli/chunk-mdc7b01e.js +3 -0
- package/dist/cli/{chunk-kgs56yns.js → chunk-mkfc9a09.js} +1 -1
- package/dist/cli/{chunk-9er68n24.js → chunk-mq88bvj6.js} +1 -1
- package/dist/cli/chunk-mqfvzdpr.js +3 -0
- package/dist/cli/{chunk-m4dvx7bd.js → chunk-mz1ffkqb.js} +3 -3
- package/dist/cli/{chunk-1rjq808h.js → chunk-n0rdn2fn.js} +1 -1
- package/dist/cli/{chunk-sza3tyhs.js → chunk-n6marmjn.js} +1 -1
- package/dist/cli/chunk-n8t4y0bj.js +10 -0
- package/dist/cli/chunk-nbpq1tkx.js +98 -0
- package/dist/cli/{chunk-b492aee1.js → chunk-ne6x6g2c.js} +1 -1
- package/dist/cli/{chunk-fexzfgd1.js → chunk-nr7e3e82.js} +1 -1
- package/dist/cli/chunk-ns35rdyk.js +3 -0
- package/dist/cli/chunk-pap7k3b4.js +3 -0
- package/dist/cli/chunk-pdq3ya2e.js +3 -0
- package/dist/cli/chunk-q8ffd1pc.js +3 -0
- package/dist/cli/{chunk-39sfhppm.js → chunk-qna1s1r4.js} +1 -1
- package/dist/cli/{chunk-tjj9bt7n.js → chunk-qqr4tfhk.js} +1 -1
- package/dist/cli/chunk-r7kmn4js.js +2 -0
- package/dist/cli/chunk-r7ntkd6y.js +15 -0
- package/dist/cli/{chunk-rtpa8hg3.js → chunk-rjfdzjhj.js} +1 -1
- package/dist/cli/chunk-syfs63r2.js +2 -0
- package/dist/cli/{chunk-4hnz77xf.js → chunk-syn0tfwy.js} +1 -1
- package/dist/cli/chunk-t4qr9sv4.js +4 -0
- package/dist/cli/{chunk-6jk2khme.js → chunk-t52gzaeb.js} +1 -1
- package/dist/cli/chunk-teh40faw.js +1 -1
- package/dist/cli/{chunk-gqh6atvp.js → chunk-tjhw09bz.js} +1 -1
- package/dist/cli/chunk-tq0h3vy6.js +3 -0
- package/dist/cli/{chunk-snqa07h6.js → chunk-tvdrvgen.js} +1 -1
- package/dist/cli/chunk-tz373e5w.js +3 -0
- package/dist/cli/chunk-v1r83m3n.js +3 -0
- package/dist/cli/chunk-vp171as9.js +65 -0
- package/dist/cli/chunk-vtcr71fs.js +8 -0
- package/dist/cli/{chunk-zaw71cf4.js → chunk-vz0f8e8q.js} +1 -1
- package/dist/cli/chunk-w77s2df8.js +3 -0
- package/dist/cli/chunk-w7v4jzwy.js +3 -0
- package/dist/cli/chunk-wvqn1t55.js +2 -0
- package/dist/cli/{chunk-r40aj7z6.js → chunk-x1ghdmp1.js} +1 -1
- package/dist/cli/{chunk-nzbq51h9.js → chunk-x3n4y5sp.js} +1 -1
- package/dist/cli/{chunk-q6septaj.js → chunk-xb3p11g0.js} +1 -1
- package/dist/cli/{chunk-yzkhwn31.js → chunk-xd93fm1k.js} +1 -1
- package/dist/cli/chunk-xn2f56tg.js +3 -0
- package/dist/cli/chunk-xv3217yv.js +2 -0
- package/dist/cli/chunk-yhytkwpv.js +2 -0
- package/dist/cli/{chunk-hfdk7j28.js → chunk-yk9b8zgn.js} +1 -1
- package/dist/cli/chunk-zat16a83.js +2 -0
- package/dist/cli/chunk-zcrs4sm2.js +3 -0
- package/dist/cli/{chunk-kx53jjee.js → chunk-zkp6nty3.js} +8 -6
- package/dist/cli/index.js +5 -5
- package/dist/cli/pty-host-node.mjs +258 -29
- package/dist/cli/rove-run.js +1 -1
- package/dist/cli/rove.js +1 -1
- package/dist/completions/rove.bash +2 -2
- package/dist/completions/rove.fish +2 -2
- package/dist/completions/rove.zsh +2 -2
- package/dist/skills/rove/SKILL.md +23 -9
- package/dist/skills/rove/references/api-flags.md +20 -11
- package/dist/web/assets/index-C5t3gibI.css +1 -0
- package/dist/web/assets/index-Djp7M6r8.js +122 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +52 -0
- package/package.json +3 -3
- package/dist/cli/chunk-033k4ap7.js +0 -2
- package/dist/cli/chunk-0ppkvphp.js +0 -2
- package/dist/cli/chunk-11wyec8z.js +0 -2
- package/dist/cli/chunk-15fp4p9v.js +0 -15
- package/dist/cli/chunk-1ffqacz9.js +0 -3
- package/dist/cli/chunk-2v68zaaa.js +0 -2
- package/dist/cli/chunk-2y29zrm1.js +0 -2
- package/dist/cli/chunk-4d1v6066.js +0 -3
- package/dist/cli/chunk-5zsdjrgz.js +0 -4
- package/dist/cli/chunk-68wpp5y8.js +0 -20
- package/dist/cli/chunk-6h4qdckd.js +0 -3
- package/dist/cli/chunk-6jj82bej.js +0 -2
- package/dist/cli/chunk-783d1ba0.js +0 -3
- package/dist/cli/chunk-78v1q5mz.js +0 -2
- package/dist/cli/chunk-7z463zkx.js +0 -3
- package/dist/cli/chunk-97m9nyw7.js +0 -2
- package/dist/cli/chunk-9bae7f3m.js +0 -4
- package/dist/cli/chunk-b5c7p22a.js +0 -2
- package/dist/cli/chunk-b5pytfgm.js +0 -2
- package/dist/cli/chunk-b68dd36h.js +0 -3
- package/dist/cli/chunk-bbksmb5a.js +0 -3
- package/dist/cli/chunk-cpf78z3x.js +0 -4
- package/dist/cli/chunk-cyzp2btw.js +0 -63
- package/dist/cli/chunk-e01321zn.js +0 -5
- package/dist/cli/chunk-erx7x9xg.js +0 -97
- package/dist/cli/chunk-ewqqwtrj.js +0 -2
- package/dist/cli/chunk-fmbv4m3y.js +0 -25
- package/dist/cli/chunk-fs51wx31.js +0 -3
- package/dist/cli/chunk-fvvb0072.js +0 -3
- package/dist/cli/chunk-g3tv8kht.js +0 -2
- package/dist/cli/chunk-g53yqr82.js +0 -78
- package/dist/cli/chunk-k67vbszb.js +0 -3
- package/dist/cli/chunk-kyt9ytz2.js +0 -20
- package/dist/cli/chunk-n2ejvjrd.js +0 -3
- package/dist/cli/chunk-p4s826r2.js +0 -96
- package/dist/cli/chunk-p6334e7v.js +0 -2
- package/dist/cli/chunk-q9zgj6kw.js +0 -3
- package/dist/cli/chunk-rzef6szc.js +0 -3
- package/dist/cli/chunk-sqxdfzdq.js +0 -5
- package/dist/cli/chunk-sz2xs0a2.js +0 -4
- package/dist/cli/chunk-t5y8k772.js +0 -2
- package/dist/cli/chunk-vht2e44j.js +0 -10
- package/dist/cli/chunk-vjp7drne.js +0 -2
- package/dist/cli/chunk-vm551pxs.js +0 -2
- package/dist/cli/chunk-w09356fj.js +0 -20
- package/dist/cli/chunk-xmqv1zx6.js +0 -2
- package/dist/cli/chunk-xn7bk4f9.js +0 -3
- package/dist/cli/chunk-zybjm7d5.js +0 -2
- package/dist/web/assets/index-C9vaSoIJ.js +0 -113
- package/dist/web/assets/index-sA2EEQJw.css +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{detectShell,installCompletions,recordWelcomeChoices,runPendingWelcomeInstalls,settleWelcomeInstall}from"./chunk-n8t4y0bj.js";import"./chunk-eege1x0a.js";import"./chunk-qqr4tfhk.js";import"./chunk-32j6y5d1.js";import"./chunk-372g44dg.js";import"./chunk-1eef3z5v.js";import"./chunk-cmp64q4j.js";import"./chunk-bejhca6z.js";import"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{settleWelcomeInstall,runPendingWelcomeInstalls,recordWelcomeChoices,installCompletions,detectShell};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{__require}from"./chunk-91sykzqq.js";var welcomeWrite=Promise.resolve();function trackWelcomeWrite(write){welcomeWrite=write}async function launchTui(){let{startTui}=await import("./chunk-
|
|
2
|
+
import{__require}from"./chunk-91sykzqq.js";var welcomeWrite=Promise.resolve();function trackWelcomeWrite(write){welcomeWrite=write}async function launchTui(){let{startTui}=await import("./chunk-eyvw70yb.js");await startTui(),await welcomeWrite;let{runPendingWelcomeInstalls}=await import("./chunk-k235z3ct.js");runPendingWelcomeInstalls()}
|
|
3
3
|
export{trackWelcomeWrite,launchTui};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{generateCompletions,isShellKind,mergeSubVerbs,shippedCompletionsPath}from"./chunk-
|
|
2
|
+
import{generateCompletions,isShellKind,mergeSubVerbs,shippedCompletionsPath}from"./chunk-eege1x0a.js";import"./chunk-qqr4tfhk.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-91sykzqq.js";import{existsSync,readFileSync}from"fs";var HELP_WORDS=["--help","-h","help"];function completionUsage(cliName){return[`Usage: ${cliName} completions <bash|zsh|fish> [--path|--install]`,"",`Print a shell completion script for ${cliName}, or locate the copy shipped`,"with this install.","",` ${cliName} completions zsh --path print the shipped script's path`,` ${cliName} completions zsh --install hook it into your shell config`,"","Install:",` zsh source <(${cliName} completions zsh) # one-off, or in ~/.zshrc after compinit`," # with no process start per shell \u2014 what the first-run wizard writes:",` # ${cliName} completions zsh --install`,` bash ${cliName} completions bash --install # appends to ~/.bashrc`,` fish ${cliName} completions fish --install # writes ~/.config/fish/completions/${cliName}.fish`," # the manual way, any shell:",` # ${cliName} completions zsh > ~/.zsh/completions/_${cliName}`," # fpath=(~/.zsh/completions $fpath) # in ~/.zshrc, BEFORE compinit"," # rm -f ~/.zcompdump && exec zsh # rebuild the completion cache",""].join(`
|
|
3
3
|
`)}async function runCompletionsSubcommand(rest,cliName=ROVE_PRODUCT_NAME,deps={}){let usage=completionUsage(cliName),fail=(message)=>{process.stderr.write(`${cliName} completions: ${message}
|
|
4
4
|
|
|
5
5
|
${usage}`),process.exit(2)};if(rest.some((arg)=>HELP_WORDS.includes(arg))){process.stdout.write(usage);return}let flags=rest.filter((arg)=>arg.startsWith("-")),shells=rest.filter((arg)=>!arg.startsWith("-")),unknownFlag=flags.find((flag)=>flag!=="--path"&&flag!=="--install");if(unknownFlag)fail(`unknown option "${unknownFlag}"`);if(new Set(flags).size>1)fail("--path and --install are different things; pass one");let shell=shells.length===1?shells[0]:void 0;if(!isShellKind(shell))fail(`unknown shell "${shells.join(" ")}"`);let scriptPath=shippedCompletionsPath(shell,cliName,deps.shippedDir),shipped=existsSync(scriptPath)?scriptPath:null;if(flags[0]==="--path"){if(!shipped)fail(`no pre-generated ${shell} script at ${scriptPath}
|
|
6
6
|
${cliName} completions ${shell} # print the script to stdout instead`);process.stdout.write(`${shipped}
|
|
7
|
-
`);return}if(flags[0]==="--install"){let[{installCompletions,settleWelcomeInstall},{t}]=await Promise.all([import("./chunk-
|
|
8
|
-
`);return}if(shipped){process.stdout.write(readFileSync(shipped,"utf8"));return}let{API_VERBS}=await import("./chunk-
|
|
7
|
+
`);return}if(flags[0]==="--install"){let[{installCompletions,settleWelcomeInstall},{t}]=await Promise.all([import("./chunk-k235z3ct.js"),import("./chunk-qna1s1r4.js")]),completion=installCompletions(shell,deps.home,cliName,shipped);settleWelcomeInstall("completions",shell);let line=completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions";process.stdout.write(`${t(line,{path:completion.path})}
|
|
8
|
+
`);return}if(shipped){process.stdout.write(readFileSync(shipped,"utf8"));return}let{API_VERBS}=await import("./chunk-84pvn784.js");process.stdout.write(generateCompletions(shell,cliName,mergeSubVerbs(API_VERBS)))}export{runCompletionsSubcommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{ensurePtyHostReachable}from"./chunk-cfzg8q3e.js";import{DEFAULT_TERMINAL_COLORS,parseTerminalDefaultColors}from"./chunk-mqfvzdpr.js";import{BUNDLED_THEMES,DEFAULT_THEME,readPersistedUiPrefs}from"./chunk-5nvg3ek8.js";import{loadUserThemes,parseRgbLiteral}from"./chunk-xd93fm1k.js";import{ENGINE_EXIT_BANNER,REPO_INIT_TIMEOUT_SECONDS,initMarkerSaysFinished}from"./chunk-r7ntkd6y.js";import{aliasKey,isUnderKey,unclaimedSessions}from"./chunk-g9ba25q5.js";import{engineProcessIn,foregroundEngineIn,parsePsSnapshot,psSnapshot}from"./chunk-3y9xzbqh.js";import{engineEntry}from"./chunk-d7f022eb.js";import{terminalRows}from"./chunk-etfh8f4z.js";import{RoveDaemonClient}from"./chunk-n6marmjn.js";import{BUILTIN_VENDORS}from"./chunk-h2m7em1e.js";import{LockfileError,acquire,release}from"./chunk-bejhca6z.js";import{defaultDeliveryLockDir,defaultPtyHostSocketPath}from"./chunk-eqdbfgq5.js";function normalizeHex(value){let m=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.exec(value);if(!m)return null;let digits=m[1];if(digits.length===3){let[r,g,b]=digits;return`#${r}${r}${g}${g}${b}${b}`.toLowerCase()}return`#${digits.slice(0,6)}`.toLowerCase()}function rgbToHex({r,g,b}){let hex=(n)=>n.toString(16).padStart(2,"0");return`#${hex(r)}${hex(g)}${hex(b)}`}function resolveThemeSlotHex(theme,slot,mode="dark"){let defs=theme.defs??{};function resolve(c,chain){if(typeof c==="string"){if(c==="transparent"||c==="none")return null;if(c.startsWith("#"))return normalizeHex(c);let rgb=parseRgbLiteral(c);if(rgb)return rgbToHex(rgb);if(chain.includes(c))return null;let next=defs[c]??theme.theme[c];if(next===void 0)return null;return resolve(next,[...chain,c])}if(!c||typeof c!=="object")return null;let variant=c[mode];return typeof variant==="string"?resolve(variant,chain):null}let value=theme.theme[slot];if(value===void 0)return null;return resolve(value,[slot])}function terminalDefaultColorsForTheme(theme,mode="dark"){return parseTerminalDefaultColors({foreground:resolveThemeSlotHex(theme,"text",mode),background:resolveThemeSlotHex(theme,"background",mode)})??DEFAULT_TERMINAL_COLORS}function readPersistedTerminalDefaultColors(){let themes={...BUNDLED_THEMES};for(let{name,theme}of loadUserThemes())themes[name]=theme;let prefs=readPersistedUiPrefs(DEFAULT_THEME,(name)=>Boolean(themes[name])),selected=themes[prefs.theme]??themes[DEFAULT_THEME];return selected?terminalDefaultColorsForTheme(selected,prefs.themeMode==="light"?"light":"dark"):DEFAULT_TERMINAL_COLORS}async function enginePresence(pid,extraLaunch,snapshot=psSnapshot){if(!pid)return{kind:"none"};try{let rows=parsePsSnapshot(await snapshot([pid])),engine=foregroundEngineIn(rows,pid);if(engine)return{kind:"engine",vendor:engine.vendor};return engineProcessIn(rows,pid,extraLaunch)?{kind:"engine",vendor:null}:{kind:"none"}}catch{return{kind:"unknown"}}}import{basename}from"path";import path from"path";var DELIVERY_LOCK_TIMEOUT_MS=5000,DELIVERY_LOCK_RETRY_MS=20;function lockFileName(key){return`${key.replace(/[^A-Za-z0-9._-]/g,"_")}.lock`}function deliveryLockPath(key,lockDir=defaultDeliveryLockDir()){return path.join(lockDir,lockFileName(key))}var sleep=(ms)=>new Promise((resolve)=>setTimeout(resolve,ms));async function withDeliveryLock(key,fn,opts={}){let lockPath=deliveryLockPath(key,opts.lockDir??defaultDeliveryLockDir()),deadline=Date.now()+(opts.timeoutMs??DELIVERY_LOCK_TIMEOUT_MS),token=null;for(;;)try{token=await acquire(lockPath);break}catch(err){if(!(err instanceof LockfileError))break;if(Date.now()>=deadline)break;await sleep(DELIVERY_LOCK_RETRY_MS)}try{return await fn()}finally{if(token!==null)await release(lockPath,token).catch(()=>{})}}var PASTE_READY_TIMEOUT_MS=15000,PASTE_READY_POLL_MS=100;function bracketedPasteActive(output){let on=output.lastIndexOf("\x1B[?2004h");if(on===-1)return!1;return on>output.lastIndexOf("\x1B[?2004l")}function encodePaste(prompt,bracketed){return bracketed?`\x1B[200~${prompt}\x1B[201~`:prompt}async function connectHostedSessionClient(socketPath){let client=new RoveDaemonClient(socketPath);try{await client.connect()}catch(error){throw client.close(),error}return{rpc:client,close:()=>client.close()}}async function openHostedSessionHost(){try{return await connectHostedSessionClient(defaultPtyHostSocketPath())}catch{return null}}async function ensureHostedSessionHost(){return connectHostedSessionClient(await ensurePtyHostReachable())}async function listHostedSessionsOrNull(rpc){try{let{sessions}=await rpc.request("pty.list",{});return sessions??[]}catch{return null}}async function listHostedSessions(rpc){return await listHostedSessionsOrNull(rpc)??[]}function isHostedTaskKey(key,taskId){return(key.split("::")[0]??key)===taskId}function hostedTaskKeys(sessions,taskId,scope){return sessions.filter((session)=>isHostedTaskKey(session.key,taskId)&&!scope?.spare.some((base)=>isUnderKey(session.key,base))||(scope?.also.some((base)=>isUnderKey(session.key,base))??!1)).map((session)=>session.key)}async function killHostedSessions(rpc,keys,opts){let payload=opts?.wait===!0?{wait:!0}:{};await Promise.all(keys.map((key)=>rpc.request("pty.kill",{key,...payload}).catch(()=>{})))}function commandHasEngineWord(command,engineBin){for(let part of command)for(let token of part.split(/\s+/)){let bare=token.replace(/^['"]+|['"]+$/g,"");if(bare&&basename(bare)===engineBin)return!0}return!1}function builtinEngineBins(){return BUILTIN_VENDORS.flatMap((vendor)=>{let entry=engineEntry(vendor);return[entry.defaultCommand[0],...entry.processNames??[]]}).filter((bin)=>Boolean(bin))}function sessionArgvNamesEngine(command,engineBin){if(!command||command.length===0)return!1;if(engineBin&&commandHasEngineWord(command,engineBin))return!0;return builtinEngineBins().some((bin)=>commandHasEngineWord(command,bin))}function tabOrder(key){let n=Number(/tab-(\d+)$/.exec(key)?.[1]);return Number.isFinite(n)?n:Number.POSITIVE_INFINITY}function findHostedEngineKey(sessions,taskId,engineBin,scope){if(scope?.alias){let key=aliasKey(scope.alias);if(sessions.some((s)=>s.alive&&s.key===key))return key}let mine=unclaimedSessions(sessions,scope).filter((s)=>s.alive&&isHostedTaskKey(s.key,taskId)).sort((a,b)=>tabOrder(a.key)-tabOrder(b.key)),tab1=mine.find((s)=>s.key===`${taskId}::tab-1`);if(tab1)return tab1.key;if(engineBin){let byCommand=mine.find((s)=>commandHasEngineWord(s.command,engineBin));if(byCommand)return byCommand.key}return mine.find((s)=>sessionArgvNamesEngine(s.command))?.key??null}var SUBMIT_DELAY_MS=150,CONFIRM_TAIL_CHARS=24,CONFIRM_TIMEOUT_MS=2000,CONFIRM_POLL_MS=100;function flatten(text){return text.replace(/\s+/g," ")}async function confirmPromptLanded(rpc,key,prompt,sinceOffset){let tail=flatten(prompt).trim().slice(-CONFIRM_TAIL_CHARS);if(tail.length===0)return!1;let deadline=Date.now()+CONFIRM_TIMEOUT_MS;for(;;){let peek=await rpc.request("pty.peek",{key,sinceOffset});if(!peek.alive)return!1;if(flatten(Buffer.from(peek.data,"base64").toString("utf8")).includes(tail))return!0;if(Date.now()>=deadline)return!1;await new Promise((resolve)=>setTimeout(resolve,CONFIRM_POLL_MS))}}async function writeAndConfirm(rpc,key,prompt,sinceOffset,opts){let ready=await awaitPasteReady(rpc,key,{timeoutMs:opts?.pasteReadyTimeoutMs}),{bytes}=await writeHostedPrompt(rpc,key,prompt,{ready,vendor:opts?.vendor}),confirmed=await confirmPromptLanded(rpc,key,prompt,sinceOffset);return{bytes,ready,confirmed}}async function writeHostedPromptIfLive(rpc,key,prompt,opts){let peek=await rpc.request("pty.peek",{key});if(!peek.alive)return null;return writeAndConfirm(rpc,key,prompt,peek.offset,opts)}async function awaitPasteReady(rpc,key,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),deadline=Date.now()+(opts.timeoutMs??PASTE_READY_TIMEOUT_MS);for(;;){let peek=await rpc.request("pty.peek",{key});if(!peek.alive)return!1;if(bracketedPasteActive(Buffer.from(peek.data,"base64").toString("latin1")))return!0;if(Date.now()>=deadline)return!1;await sleep2(PASTE_READY_POLL_MS)}}async function writeHostedPrompt(rpc,key,prompt,opts){let bracketed=opts?.ready??await awaitPasteReady(rpc,key),capabilities=opts?.vendor?engineEntry(opts.vendor).capabilities:void 0,prepared=capabilities?.preparePromptSubmission?.(prompt),data=encodePaste(prepared??prompt,bracketed);return await withDeliveryLock(key,async()=>{await rpc.request("pty.write",{key,data}),await new Promise((resolve)=>setTimeout(resolve,SUBMIT_DELAY_MS)),await rpc.request("pty.write",{key,data:`${capabilities?.beforePromptSubmit??""}\r`})}),{bytes:Buffer.byteLength(data,"utf8")}}var deliverToHostedKey=writeHostedPromptIfLive;async function ensureHostedEngine(rpc,cwd,launch,defaultColors=readPersistedTerminalDefaultColors()){let result=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors});return await rpc.request("pty.detach",{key:launch.key}).catch(()=>{}),result}var FIRST_MESSAGE_ENGINE_TIMEOUT_MS=20000,FIRST_MESSAGE_POLL_INTERVAL_MS=500,FIRST_MESSAGE_SETTLE_MS=1500;async function awaitEngineProcess(rpc,key,engineBin,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),snapshot=opts.snapshot;if(opts.initMarkerPath){let initDeadline=Date.now()+(opts.initTimeoutMs??REPO_INIT_TIMEOUT_SECONDS*1000);while(Date.now()<initDeadline){let{sessions=[]}=await rpc.request("pty.list",{});if(!sessions.find((s)=>s.key===key)?.alive)return null;if(initMarkerSaysFinished(opts.initMarkerPath))break;await sleep2(opts.intervalMs??FIRST_MESSAGE_POLL_INTERVAL_MS)}}let deadline=Date.now()+(opts.timeoutMs??FIRST_MESSAGE_ENGINE_TIMEOUT_MS);while(Date.now()<deadline){let{sessions=[]}=await rpc.request("pty.list",{}),session=sessions.find((s)=>s.key===key);if(!session?.alive)return null;if(session.pid){let presence=await enginePresence(session.pid,engineBin,snapshot);if(presence.kind==="engine")return{pid:session.pid,vendor:presence.vendor}}await sleep2(opts.intervalMs??FIRST_MESSAGE_POLL_INTERVAL_MS)}return null}async function hostedSessionFailureLine(rpc,key,limit=200){try{let peek=await rpc.request("pty.peek",{key}),lines=terminalRows(Buffer.from(peek.data,"base64").toString("utf8")).map((row)=>row.trim()).filter((row)=>row.length>0),line=lines.findLast((row)=>ENGINE_EXIT_BANNER.test(row))??lines.at(-1);return line===void 0?void 0:line.slice(0,limit)}catch{return}}async function pastePromptWhenEngineUp(rpc,key,engineBin,prompt,opts={}){let sleep2=opts.sleep??((ms)=>new Promise((resolve)=>setTimeout(resolve,ms))),engine=await awaitEngineProcess(rpc,key,engineBin,opts);if(engine!==null){if(!await awaitPasteReady(rpc,key,{timeoutMs:opts.pasteReadyTimeoutMs,sleep:sleep2}))await sleep2(opts.settleMs??FIRST_MESSAGE_SETTLE_MS);return await writeHostedPromptIfLive(rpc,key,prompt,{...opts,vendor:engine.vendor})}return null}
|
|
3
|
+
export{resolveThemeSlotHex,readPersistedTerminalDefaultColors,withDeliveryLock,enginePresence,awaitEngineProcess,hostedSessionFailureLine,pastePromptWhenEngineUp,openHostedSessionHost,ensureHostedSessionHost,listHostedSessionsOrNull,listHostedSessions,isHostedTaskKey,hostedTaskKeys,killHostedSessions,sessionArgvNamesEngine,findHostedEngineKey,deliverToHostedKey,ensureHostedEngine};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";var TERMINAL_TABS_PREFIX="terminalTabs.";function terminalTabsKey(taskId){return`${TERMINAL_TABS_PREFIX}${taskId}`}var stateFileTabsPersistence={load(){let out={};for(let[key,value]of Object.entries(loadStateFile())){if(!key.startsWith(TERMINAL_TABS_PREFIX))continue;let state=value;if(state&&Array.isArray(state.tabs))out[key.slice(TERMINAL_TABS_PREFIX.length)]=state}return out},save(changes){let patch={};for(let[taskId,state]of Object.entries(changes))patch[terminalTabsKey(taskId)]=state??void 0;patchStateFile(patch)}};
|
|
3
|
+
export{TERMINAL_TABS_PREFIX,terminalTabsKey,stateFileTabsPersistence};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{PTY_STOP_REFUSED,RoveDaemonClient}from"./chunk-n6marmjn.js";import{isProcessAlive,readPidFile}from"./chunk-br8r72bf.js";import{unlink}from"fs/promises";async function stopDaemonProcess(socketPath,pidPath,opts={}){let oldPid=await readPidFile(pidPath),targetPid=oldPid!==null&&oldPid!==process.pid?oldPid:null,wasAlive=targetPid!==null&&isProcessAlive(targetPid),method=wasAlive?"graceful":"absent",client=new RoveDaemonClient(socketPath),refusal=client.request("daemon.stop",{reason:opts.reason??"stop",...opts.force?{force:!0}:{}}).then(()=>!1,(err)=>err instanceof Error&&err.name===PTY_STOP_REFUSED),{promise:stopTimeout,resolve:timedOut}=Promise.withResolvers();setTimeout(()=>timedOut(!1),2000);let refused=await Promise.race([refusal,stopTimeout]);if(client.close(),refused)return{pid:oldPid,method:"refused"};if(wasAlive&&targetPid!==null){let deadline=Date.now()+5000,escalated=!1;while(Date.now()<deadline){try{process.kill(targetPid,0)}catch{break}if(!escalated&&Date.now()-(deadline-5000)>2000){try{process.kill(targetPid,"SIGTERM")}catch{}method="sigterm",escalated=!0}await new Promise((resolve)=>setTimeout(resolve,50))}try{process.kill(targetPid,0),process.kill(targetPid,"SIGKILL"),method="sigkill",await new Promise((resolve)=>setTimeout(resolve,100))}catch{}}let survivor=await readPidFile(pidPath);if(survivor!==null&&survivor!==process.pid&&isProcessAlive(survivor))return{pid:oldPid,method};return await unlink(socketPath).catch(()=>{}),await unlink(pidPath).catch(()=>{}),{pid:oldPid,method}}
|
|
3
3
|
export{stopDaemonProcess};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{CURRENT_VERSION,repoSlug}from"./chunk-
|
|
2
|
+
import{CURRENT_VERSION,repoSlug}from"./chunk-a4r45qdn.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
|
|
3
3
|
query($owner: String!, $name: String!) {
|
|
4
4
|
repository(owner: $owner, name: $name) {
|
|
5
5
|
id
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var OPEN=Buffer.from("\x1B_"),CLOSE=Buffer.from("\x1B\\");function parseKeys(control){let keys=new Map;for(let pair of control.split(",")){let eq=pair.indexOf("=");if(eq>0)keys.set(pair.slice(0,eq),pair.slice(eq+1))}return keys}class KittyTransmits{images=new Map;bytes=0;apc=null;apcBytes=0;escPending=!1;upload=null;push(buf){let i=0;if(this.escPending&&buf.length>0)if(this.escPending=!1,this.apc&&buf[0]===92)this.finish(),i=1;else{if(this.apc=null,buf[0]===95)this.open();if(buf[0]===95||buf[0]===99)i=1;if(buf[0]===99)this.clear()}while(i<buf.length){if(this.apc){let esc2=buf.indexOf(27,i);if(esc2===-1){this.append(buf.subarray(i));return}if(this.append(buf.subarray(i,esc2)),esc2+1>=buf.length){this.escPending=!0;return}if(buf[esc2+1]===92)this.finish();else this.apc=null;i=esc2+2;continue}let esc=buf.indexOf(27,i);if(esc===-1)return;if(esc+1>=buf.length){this.escPending=!0;return}let next=buf[esc+1];if(next===95)this.open();else if(next===99)this.clear();i=esc+2}}replay(){return Buffer.concat([...this.images.values()])}open(){this.apc=[],this.apcBytes=0}append(part){if(!this.apc||part.length===0)return;if(this.apcBytes+=part.length,this.apcBytes>16777216)this.apc=null;else this.apc.push(Buffer.from(part))}finish(){let body=this.apc?Buffer.concat(this.apc):null;if(this.apc=null,!body||body[0]!==71)return;let semi=body.indexOf(59),keys=parseKeys(body.subarray(1,semi===-1?body.length:semi).toString("latin1")),raw=Buffer.concat([OPEN,body,CLOSE]);if(this.upload&&[...keys.keys()].every((k)=>k==="m"||k==="q")){if(this.upload.parts.push(raw),this.upload.bytes+=raw.length,this.upload.bytes>16777216)this.upload=null;else if(keys.get("m")!=="1"){let{id:id2,parts}=this.upload;this.upload=null,this.keep(id2,Buffer.concat(parts))}return}this.upload=null;let action=keys.get("a")??"t",id=Number(keys.get("i"));if((action==="t"||action==="T")&&(keys.get("t")??"d")==="d"&&id>0)if(keys.get("m")==="1")this.upload={id,parts:[raw],bytes:raw.length};else this.keep(id,raw);else if(action==="d"&&(keys.get("d")==="i"||keys.get("d")==="I"))this.drop(id)}keep(id,raw){this.drop(id),this.images.set(id,raw),this.bytes+=raw.length;for(let[old,kept]of this.images){if(this.images.size<=8&&this.bytes<=16777216)break;this.images.delete(old),this.bytes-=kept.length}}drop(id){let kept=this.images.get(id);if(!kept)return;this.images.delete(id),this.bytes-=kept.length}clear(){this.images.clear(),this.bytes=0,this.upload=null}}var DEFAULT_TERMINAL_COLORS={foreground:"#eae7df",background:"#141413"},HEX_COLOR_RE=/^#[0-9a-f]{6}$/i,DEFAULT_COLOR_QUERY_RE=/\x1b\](10|11);\?(?:\x07|\x1b\\)/g,QUERY_PREFIXES=["\x1B]10;?","\x1B]11;?"];function normalizeColor(value){return typeof value==="string"&&HEX_COLOR_RE.test(value)?value.toLowerCase():null}function parseTerminalDefaultColors(value){if(typeof value!=="object"||value===null||Array.isArray(value))return null;let raw=value,foreground=normalizeColor(raw.foreground),background=normalizeColor(raw.background);return foreground&&background?{foreground,background}:null}function oscRgb(color){let hex=color.slice(1);return[hex.slice(0,2),hex.slice(2,4),hex.slice(4,6)].map((component)=>component.repeat(2)).join("/")}function formatDefaultColorReply(slot,colors){let color=slot===10?colors.foreground:colors.background;return`\x1B]${slot};rgb:${oscRgb(color)}\x1B\\`}function trailingQueryPrefix(text){let maxLength=QUERY_PREFIXES[0].length+1,start=Math.max(0,text.length-maxLength);for(let index=start;index<text.length;index++){let suffix=text.slice(index);if(QUERY_PREFIXES.some((prefix)=>prefix.startsWith(suffix)||suffix===`${prefix}\x1B`))return suffix}return""}function foldDefaultColorQueries(previousCarry,chunkText){let text=previousCarry+chunkText,slots=[],end=0;DEFAULT_COLOR_QUERY_RE.lastIndex=0;for(let match=DEFAULT_COLOR_QUERY_RE.exec(text);match;match=DEFAULT_COLOR_QUERY_RE.exec(text))slots.push(match[1]==="10"?10:11),end=match.index+match[0].length;return{slots,carry:trailingQueryPrefix(text.slice(end))}}var DEFAULT_MODES={applicationCursorKeys:!1,applicationKeypad:!1,origin:!1,wraparound:!0,reverseWraparound:!1,cursorBlink:!1,cursorVisible:!0,insertMode:!1,sendFocus:!1,bracketedPaste:!1,synchronizedOutput:!1,altScreen:!1,mouseProtocol:"none",mouseEncoding:"default"},MOUSE_PROTOCOLS={9:"x10",1000:"vt200",1002:"drag",1003:"any"},MOUSE_ENCODINGS={1006:"sgr",1016:"sgr-pixels"};function freshModeTrack(modes={...DEFAULT_MODES}){return{modes,carry:"",inString:null}}function normalizeTerminalModes(raw){let modes={...DEFAULT_MODES};if(typeof raw!=="object"||raw===null)return modes;let record=raw;for(let key of Object.keys(DEFAULT_MODES))if(typeof record[key]==="boolean"&&typeof modes[key]==="boolean")modes[key]=record[key];if(Object.values(MOUSE_PROTOCOLS).includes(record.mouseProtocol))modes.mouseProtocol=record.mouseProtocol;if(Object.values(MOUSE_ENCODINGS).includes(record.mouseEncoding))modes.mouseEncoding=record.mouseEncoding;return modes}function scanTerminalModes(track,chunk){let text=track.carry+chunk;track.carry="";let replies=[],i=0;if(track.inString){let end=stringEnd(text,0,track.inString);if(end<0){if(text.endsWith("\x1B"))track.carry="\x1B";return replies}track.inString=null,i=end}i=text.indexOf("\x1B",i);while(i!==-1){if(i+1>=text.length){track.carry="\x1B";break}let next=text.charCodeAt(i+1);if(next===91){let end=csiEnd(text,i+2);if(end===-1){if(text.length-i<=64)track.carry=text.slice(i);break}if(end>=0)applyCsi(track.modes,text.slice(i+2,end),text[end],replies);i=text.indexOf("\x1B",end>=0?end+1:i+2);continue}let kind=STRING_INTRODUCERS[text[i+1]];if(kind){let end=stringEnd(text,i+2,kind);if(end<0){if(track.inString=kind,text.endsWith("\x1B"))track.carry="\x1B";break}i=text.indexOf("\x1B",end);continue}if(next===61)track.modes.applicationKeypad=!0;else if(next===62)track.modes.applicationKeypad=!1;else if(next===99)track.modes={...DEFAULT_MODES};i=text.indexOf("\x1B",i+1)}return replies}function terminalModePreamble(modes){let set=[],reset=[];if(modes.applicationCursorKeys)set.push(1);if(modes.origin)set.push(6);if(!modes.wraparound)reset.push(7);if(modes.cursorBlink)set.push(12);if(!modes.cursorVisible)reset.push(25);if(modes.reverseWraparound)set.push(45);for(let[mode,protocol]of Object.entries(MOUSE_PROTOCOLS))if(modes.mouseProtocol===protocol)set.push(+mode);for(let[mode,encoding]of Object.entries(MOUSE_ENCODINGS))if(modes.mouseEncoding===encoding)set.push(+mode);if(modes.sendFocus)set.push(1004);if(modes.bracketedPaste)set.push(2004);let out=modes.altScreen?"\x1B[?1049h":"";if(set.length>0)out+=`\x1B[?${set.join(";")}h`;if(reset.length>0)out+=`\x1B[?${reset.join(";")}l`;if(modes.applicationKeypad)out+="\x1B=";if(modes.insertMode)out+="\x1B[4h";return out}function replayStart(track,ring){if(!track.inString)return 0;let text=track.carry+ring.toString("latin1"),end=stringEnd(text,0,track.inString);return end<0?ring.byteLength:Math.max(0,end-track.carry.length)}var STRING_INTRODUCERS={_:"st",P:"st","^":"st",X:"st","]":"osc"};function stringEnd(text,from,kind){let esc=text.indexOf("\x1B",from),bel=kind==="osc"?text.indexOf("\x07",from):-1;if(bel!==-1&&(esc===-1||bel<esc))return bel+1;if(esc===-1||esc+1>=text.length)return-1;return text[esc+1]==="\\"?esc+2:esc}function csiEnd(text,from){for(let j=from;j<text.length;j++){let c=text.charCodeAt(j);if(c>=64&&c<=126)return j;if(c<32||c>63)return-2}return-1}function applyCsi(modes,body,final,replies){let start=0,prefix="",first=body.charCodeAt(0);if(first>=60&&first<=63)prefix=body[0],start=1;let end=body.length;while(end>start&&body.charCodeAt(end-1)<=47)end--;let intermediates=body.slice(end),params=body.slice(start,end).split(";").map((param)=>Number.parseInt(param.split(":")[0]??"",10)||0);if(intermediates===""&&(final==="h"||final==="l")){let on=final==="h";if(prefix==="?")for(let mode of params)setPrivateMode(modes,mode,on);else if(prefix===""&¶ms.includes(4))modes.insertMode=on}else if(intermediates==="$"&&final==="p"&&(prefix==="?"||prefix==="")){let mode=params[0]??0,value=prefix==="?"?privateModeValue(modes,mode):ansiModeValue(modes,mode);replies.push(`\x1B[${prefix}${mode};${value}$y`)}else if(intermediates==="!"&&final==="p"&&prefix==="")softReset(modes);else if(intermediates===""&&final==="c"&&prefix===""&&(params[0]??0)===0)replies.push("\x1B[?1;2c")}function setPrivateMode(modes,mode,on){if(mode in MOUSE_PROTOCOLS){modes.mouseProtocol=on?MOUSE_PROTOCOLS[mode]:"none";return}if(mode in MOUSE_ENCODINGS){modes.mouseEncoding=on?MOUSE_ENCODINGS[mode]:"default";return}switch(mode){case 1:modes.applicationCursorKeys=on;break;case 6:modes.origin=on;break;case 7:modes.wraparound=on;break;case 12:modes.cursorBlink=on;break;case 25:modes.cursorVisible=on;break;case 45:modes.reverseWraparound=on;break;case 66:modes.applicationKeypad=on;break;case 1004:modes.sendFocus=on;break;case 47:case 1047:case 1049:modes.altScreen=on;break;case 2004:modes.bracketedPaste=on;break;case 2026:modes.synchronizedOutput=on;break}}function softReset(modes){Object.assign(modes,{applicationCursorKeys:!1,applicationKeypad:!1,origin:!1,wraparound:!0,reverseWraparound:!1,cursorVisible:!0,insertMode:!1,sendFocus:!1,bracketedPaste:!1,synchronizedOutput:!1})}var NOT_RECOGNIZED=0,SET=1,RESET=2,PERMANENTLY_SET=3,PERMANENTLY_RESET=4,flag=(on)=>on?SET:RESET;function privateModeValue(modes,mode){if(mode in MOUSE_PROTOCOLS)return flag(modes.mouseProtocol===MOUSE_PROTOCOLS[mode]);if(mode in MOUSE_ENCODINGS)return flag(modes.mouseEncoding===MOUSE_ENCODINGS[mode]);switch(mode){case 1:return flag(modes.applicationCursorKeys);case 6:return flag(modes.origin);case 7:return flag(modes.wraparound);case 8:return PERMANENTLY_SET;case 12:return flag(modes.cursorBlink);case 25:return flag(modes.cursorVisible);case 45:return flag(modes.reverseWraparound);case 66:return flag(modes.applicationKeypad);case 67:case 1005:case 1015:return PERMANENTLY_RESET;case 1004:return flag(modes.sendFocus);case 1048:return SET;case 47:case 1047:case 1049:return flag(modes.altScreen);case 2004:return flag(modes.bracketedPaste);case 2026:return flag(modes.synchronizedOutput);default:return NOT_RECOGNIZED}}function ansiModeValue(modes,mode){switch(mode){case 2:return PERMANENTLY_RESET;case 4:return flag(modes.insertMode);case 12:return PERMANENTLY_SET;case 20:return RESET;default:return NOT_RECOGNIZED}}
|
|
3
|
+
export{KittyTransmits,DEFAULT_TERMINAL_COLORS,parseTerminalDefaultColors,formatDefaultColorReply,foldDefaultColorQueries,freshModeTrack,normalizeTerminalModes,scanTerminalModes,terminalModePreamble,replayStart};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{defaultFixRuntime}from"./chunk-
|
|
2
|
+
import{defaultFixRuntime}from"./chunk-c6fy8xew.js";import{INBOUND_CLASSES,deniedClasses,setInbound}from"./chunk-6mtfafaw.js";import"./chunk-bw98jn7g.js";import"./chunk-ehm9abge.js";import"./chunk-283vd9h7.js";import"./chunk-tvdrvgen.js";import"./chunk-rjfdzjhj.js";import"./chunk-fn7ffyam.js";import"./chunk-agvtzads.js";import"./chunk-pm91e38v.js";import"./chunk-17e2tgyg.js";import"./chunk-2xsxcdp6.js";import"./chunk-eq7vey2j.js";import"./chunk-q8ffd1pc.js";import"./chunk-4hestsjp.js";import"./chunk-qgrg9a5n.js";import"./chunk-2bgmby1d.js";import"./chunk-n0rdn2fn.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-mq88bvj6.js";import{primaryCheckouts,repoIdOf,repoIdentity,setPrimaryCheckout}from"./chunk-0d7517kk.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-vz0f8e8q.js";import"./chunk-ns35rdyk.js";import"./chunk-gq36nzg8.js";import"./chunk-sq6zj3fb.js";import"./chunk-qkehg2c1.js";import"./chunk-zcrs4sm2.js";import"./chunk-ma21srvx.js";import"./chunk-cfzg8q3e.js";import"./chunk-w77s2df8.js";import"./chunk-mqfvzdpr.js";import"./chunk-5nvg3ek8.js";import"./chunk-rxqdw6s5.js";import"./chunk-xd93fm1k.js";import"./chunk-pdq3ya2e.js";import"./chunk-r7ntkd6y.js";import"./chunk-1n03wzx4.js";import"./chunk-r5j8fycq.js";import"./chunk-xfgqae9t.js";import"./chunk-j1z9kgyd.js";import"./chunk-g9ba25q5.js";import"./chunk-ggnq2vvk.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-mdc7b01e.js";import"./chunk-tn9gtf18.js";import"./chunk-895yqjjz.js";import"./chunk-sak1tphp.js";import{shQuote}from"./chunk-y1xnjx8x.js";import"./chunk-3y9xzbqh.js";import"./chunk-d7f022eb.js";import"./chunk-h64rsbrx.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-9rj2fx6v.js";import"./chunk-rfp0ayra.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-40dgv828.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import{CURRENT_VERSION}from"./chunk-a4r45qdn.js";import{argvHasFlag}from"./chunk-zsfyj36g.js";import"./chunk-2r1fgng9.js";import"./chunk-d0hpes59.js";import"./chunk-mkfc9a09.js";import"./chunk-syn0tfwy.js";import"./chunk-2brn8e1y.js";import"./chunk-7mwvvj46.js";import{loadStateFile}from"./chunk-32j6y5d1.js";import"./chunk-372g44dg.js";import"./chunk-1eef3z5v.js";import"./chunk-cmp64q4j.js";import"./chunk-n6marmjn.js";import"./chunk-96kvwzj8.js";import"./chunk-2kqxz9a4.js";import"./chunk-e3t1zbv1.js";import"./chunk-7kysxgbq.js";import"./chunk-w7v4jzwy.js";import"./chunk-cbrt4s7m.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-8t7qbr1e.js";import"./chunk-bejhca6z.js";import{homeDir}from"./chunk-z1nj22va.js";import"./chunk-br8r72bf.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0g4wc808.js";import"./chunk-pn5ygqn6.js";import"./chunk-eqdbfgq5.js";import"./chunk-f8gg8cqh.js";import"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-91sykzqq.js";import{spawn}from"child_process";import{appendFileSync,chmodSync,existsSync,mkdirSync}from"fs";import{homedir}from"os";import{dirname}from"path";function parseSshG(stdout,home=homedir()){let values=new Map;for(let line of stdout.split(`
|
|
3
3
|
`)){let space=line.indexOf(" ");if(space>0)values.set(line.slice(0,space).toLowerCase(),line.slice(space+1).trim())}let hostname=values.get("hostname")??"",port=Number(values.get("port")??"22")||22,files=(key)=>(values.get(key)??"").split(/\s+/).filter((f)=>f&&f!=="none").map((f)=>f.startsWith("~/")?`${home}${f.slice(1)}`:f),alias=values.get("hostkeyalias"),proxy=(key)=>{let v=values.get(key);return v!==void 0&&v!=="none"};return{knownHostsName:alias&&alias!=="none"?alias:port===22?hostname:`[${hostname}]:${port}`,hostname,port,userKnownHosts:files("userknownhostsfile"),globalKnownHosts:files("globalknownhostsfile"),proxied:proxy("proxyjump")||proxy("proxycommand")}}async function checkHostKey(config){let target=sshTargetOf(config),resolved=await run(["ssh","-G",...config.port?["-p",String(config.port)]:[],target]);if(resolved.code!==0)return{state:"skipped",reason:"ssh -G failed"};let destination=parseSshG(resolved.stdout);if(!destination.hostname)return{state:"skipped",reason:"ssh -G named no host"};if(destination.proxied)return{state:"skipped",reason:"reached through a proxy"};for(let file of[...destination.userKnownHosts,...destination.globalKnownHosts]){if(!existsSync(file))continue;if((await run(["ssh-keygen","-F",destination.knownHostsName,"-f",file])).code===0)return{state:"known"}}let keys=(await run(["ssh-keyscan","-T","5","-p",String(destination.port),destination.hostname])).stdout.split(`
|
|
4
4
|
`).filter((line)=>line.trim()&&!line.startsWith("#"));if(keys.length===0)return{state:"skipped",reason:"the host offered no key"};let named=keys.map((line)=>line.replace(/^\S+/,destination.knownHostsName)),fingerprints=(await run(["ssh-keygen","-l","-f","-"],`${named.join(`
|
|
5
5
|
`)}
|
|
@@ -39,12 +39,12 @@ ${MACHINE_USAGE}
|
|
|
39
39
|
`),process.exit(1)}function flagValue(argv,name){for(let i=0;i<argv.length;i++){let arg=argv[i];if(arg===void 0)continue;if(arg.startsWith(`--${name}=`))return arg.slice(name.length+3);if(arg!==`--${name}`)continue;let value=argv[i+1];if(value===void 0||value.startsWith("--"))usageError(`--${name} needs a value`);return value}return}async function runMachineSubcommand(argv){let[verb,...rest]=argv;if(!verb||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${MACHINE_USAGE}
|
|
40
40
|
`);return}if(verb==="list")return list();if(verb==="add")return await add(rest);if(verb==="doctor")return await doctor(rest);if(verb==="remove")return remove(rest);if(verb==="tunnel")return tunnel(rest);if(verb==="inbound")return inbound(rest);if(verb==="primary")return machinePrimary(rest,usageError);usageError(`unknown verb "${verb}"`)}async function add(argv){let target=positionalOf(argv);if(!target)usageError("add needs an ssh target, e.g. `machine add narwhal`");let parsed=parseSshTarget(target);if(!parsed)usageError(`"${target}" is not a valid ssh target ([user@]host[:port])`);let portFlag=flagValue(argv,"port"),port=portFlag?Number(portFlag):parsed.port;if(port!==void 0&&(!Number.isInteger(port)||port<1||port>65535))usageError("--port must be 1-65535");let identity=flagValue(argv,"identity"),requested=flagValue(argv,"alias");if(requested&&!isValidMachineAlias(requested))usageError(`--alias must be letters/digits/._- and cannot be "local" (got "${requested}")`);let probeAlias=requested??sanitizeAlias(parsed.host),config={host:parsed.host,...parsed.user?{user:parsed.user}:{},...port?{port}:{},auth:identity?{kind:"key",keyPath:identity}:{kind:"key"}};await confirmHostKey(config),process.stderr.write(`${CLI_NAME} machine: contacting ${sshTargetOf(config)}\u2026
|
|
41
41
|
`);let established=await establishMachine(probeAlias,config,setupRuntime(argv));if(!established.ok)fail("nothing was saved");let{found,config:settled}=established,alias=requested??defaultMachineAlias({typedHost:parsed.host,typedUser:parsed.user,port,remoteHostname:found.status.hostname});if(!isValidMachineAlias(alias))fail(`could not derive a usable alias from "${found.status.hostname}" \u2014 pass --alias`);let identityTriple={hostname:found.status.hostname,homeDir:found.status.homeDir,daemonPid:found.status.daemonPid},duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identityTriple),learned=learnedFrom(found),sockets=learned.sockets;if(found.roveBin)process.stderr.write(`${CLI_NAME} machine: rove is not on ${alias}'s non-interactive PATH; using ${found.roveBin}
|
|
42
|
-
`);addMachine(alias,{...settled,...learned,identity:identityTriple}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-
|
|
42
|
+
`);addMachine(alias,{...settled,...learned,identity:identityTriple}),setMachineIdentity(alias,identityTriple);let{ensureForwards}=await import("./chunk-9gh8kgjs.js"),up=await ensureForwards({alias,config:{...settled,...learned},remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(process.stdout.write(`${CLI_NAME} machine: ${alias} \u2192 ${sshTargetOf(settled)} (rove ${found.status.roveVersion||"?"} on ${found.status.hostname||"?"})
|
|
43
43
|
`),!up)process.stderr.write(`${CLI_NAME} machine: registered, but could not forward ${alias}'s socket yet \u2014 it will show as offline until the connection comes up
|
|
44
44
|
`);if(duplicate)process.stdout.write(`${CLI_NAME} machine: ${alias} is the same machine as ${duplicate} (hostname/homeDir/pid match) \u2014 the sidebar shows one row
|
|
45
45
|
`)}function setupRuntime(argv){let yes=argv.includes("--yes"),fixRuntime=defaultFixRuntime();return{confirm:fixRuntime.confirm,exec:fixRuntime.exec,out:(line)=>process.stderr.write(`${line}
|
|
46
46
|
`),ask:!yes,planOnly:!yes&&process.stdin.isTTY!==!0}}async function doctor(argv){let alias=positionalOf(argv),entries=listMachines().filter((m)=>!alias||m.alias===alias);if(alias&&entries.length===0)fail(`no machine named "${alias}" (see \`${CLI_NAME} machine list\`)`);if(entries.length===0){process.stdout.write(`No machines registered. Add one with \`${CLI_NAME} machine add <ssh-target>\`.
|
|
47
|
-
`);return}let rt=setupRuntime(argv),{ensureForwards}=await import("./chunk-
|
|
47
|
+
`);return}let rt=setupRuntime(argv),{ensureForwards}=await import("./chunk-9gh8kgjs.js"),failed=0;for(let{alias:name,...config}of entries){process.stderr.write(`${CLI_NAME} machine: checking ${name} (${sshTargetOf(config)})\u2026
|
|
48
48
|
`);let established=await establishMachine(name,config,rt);if(!established.ok){failed++,process.stdout.write(`${name} \u2717 ${established.failure.code}
|
|
49
49
|
`);continue}let{found}=established,learned=learnedFrom(found),sockets=learned.sockets,settled={...established.config,...learned};updateMachine(name,settled);let up=await ensureForwards({alias:name,config:settled,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty}),version=found.status.roveVersion||"?",skew=version!==CURRENT_VERSION?` (this machine runs ${CURRENT_VERSION})`:"";process.stdout.write(`${name} ${up?"\u2713":"\u2717 socket not forwarded"} rove ${version}${skew} on ${found.status.hostname||"?"}
|
|
50
50
|
`);for(let note of await doctorNotes(name,settled,found))process.stdout.write(` ${note}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{legacyPluginsRootDir,pluginRegistryPath,pluginsRootDir}from"./chunk-j1z9kgyd.js";import{parse}from"./chunk-w7zv47mp.js";import{OWNER_ONLY_FILE_MODE}from"./chunk-yt15y085.js";import{PLUGIN_EVENT_NAMES}from"./chunk-96kvwzj8.js";import{existsSync,readFileSync}from"fs";import{basename,join}from"path";var PLUGIN_PLATFORMS=["macos","linux","windows"];class ManifestError extends Error{}function fail(message){throw new ManifestError(`rove-plugin.toml: ${message}`)}function asString(value,field){if(typeof value!=="string"||value.length===0)fail(`\`${field}\` must be a non-empty string`);return value}function asSettingDefault(value,field){if(value===void 0||value===!1)return;if(value===!0)return"1";if(typeof value==="number"&&Number.isFinite(value))return String(value);return asString(value,field)}var TIMEOUT_MIN_MS=100,TIMEOUT_MAX_MS=600000;function asTimeoutMs(value,field){if(value===void 0)return;if(typeof value!=="number"||!Number.isInteger(value)||value<TIMEOUT_MIN_MS||value>TIMEOUT_MAX_MS)fail(`\`${field}\` must be a whole number of milliseconds between ${TIMEOUT_MIN_MS} and ${TIMEOUT_MAX_MS}`);return value}function asCommand(value,field){if(!Array.isArray(value)||value.length===0||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings (argv form)`);return value}function asPlatforms(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>PLUGIN_PLATFORMS.includes(v)))fail(`\`${field}\` must be an array drawn from ${PLUGIN_PLATFORMS.join(", ")}`);return value}function asTableArray(value,field){if(value===void 0)return[];if(!Array.isArray(value)||!value.every((v)=>typeof v==="object"&&v!==null&&!Array.isArray(v)))fail(`\`[[${field}]]\` must be an array of tables`);return value}function asStringArray(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings`);return value}import{isAbsolute,normalize,sep}from"path";var DEFAULT_PAGE_ORDER=100;function insidePlugin(entry){if(isAbsolute(entry))return!1;return normalize(entry).split(/[\\/]/)[0]!==".."&&!normalize(entry).startsWith(`..${sep}`)}function parsePages(raw,localId){let pages=asTableArray(raw,"pages").map((t,i)=>{let id=asString(t.id,`pages[${i}].id`);if(!localId.test(id))fail(`page id \`${id}\` may not contain dots`);let entry=asString(t.entry,`pages[${i}].entry`);if(!insidePlugin(entry))fail(`page \`${id}\` entry \`${entry}\` must be a path inside the plugin`);let order=t.order??DEFAULT_PAGE_ORDER;if(typeof order!=="number"||!Number.isInteger(order))fail(`\`pages[${i}].order\` must be an integer`);let action=t.action===void 0?void 0:asString(t.action,`pages[${i}].action`);return{id,title:asString(t.title,`pages[${i}].title`),entry,order,...action?{action}:{}}}),seen=new Set;for(let page of pages){if(seen.has(page.id))fail(`duplicate page id \`${page.id}\``);seen.add(page.id)}return pages}var SETTING_KEY_RE=/^[A-Za-z_][A-Za-z0-9_]*$/,RESERVED_SETTING_KEYS=["PATH","HOME","SHELL","IFS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","NODE_OPTIONS","BUN_INSPECT","PYTHONPATH","PYTHONSTARTUP","PERL5OPT","PERL5LIB","RUBYOPT","BASH_ENV","ENV","GIT_SSH_COMMAND","GIT_SSH","GIT_EXTERNAL_DIFF","GIT_PAGER","PAGER","EDITOR","VISUAL"];function settingKeyRejection(key){if(!SETTING_KEY_RE.test(key))return`\`${key}\` is not a valid env var name (${SETTING_KEY_RE.source})`;if(RESERVED_SETTING_KEYS.includes(key))return`\`${key}\` is reserved; it steers how the plugin's own process runs`;return null}var PLUGIN_MANIFEST_FILENAME="rove-plugin.toml",PLUGIN_MANIFEST_FILENAMES=[PLUGIN_MANIFEST_FILENAME],RESERVED_ENGINE_IDS=["claude","codex","copilot","kimi","pi","omp","gemini","opencode","cursor","grok","droid","amp","devin","qodercli","cline","kiro","maki","antigravity","bob","hermes","kilo","mastracode"];function pluginManifestPath(root){for(let filename of PLUGIN_MANIFEST_FILENAMES){let path=join(root,filename);if(existsSync(path))return path}return null}function readPluginManifest(root){let path=pluginManifestPath(root);if(!path)throw new ManifestError(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);return parsePluginManifest(readFileSync(path,"utf8"),basename(path))}var PLUGIN_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._:-]*$/,LOCAL_ID_RE=/^[A-Za-z0-9][A-Za-z0-9_:-]*$/;function qualifiedActionId(pluginId,actionId){return`${pluginId}.${actionId}`}function currentPluginPlatform(platform=process.platform){if(platform==="darwin")return"macos";if(platform==="linux")return"linux";if(platform==="win32")return"windows";return}function supportsPlatform(item,manifest,platform){let declared=item.platforms??manifest.platforms;if(!declared)return!0;return platform!==void 0&&declared.includes(platform)}function parsePluginManifest(text,filename=PLUGIN_MANIFEST_FILENAME){try{return parseCanonicalPluginManifest(text)}catch(err){if(filename!==PLUGIN_MANIFEST_FILENAME&&err instanceof ManifestError)throw new ManifestError(err.message.replace(/^rove-plugin\.toml:/,`${filename}:`));throw err}}function parseCanonicalPluginManifest(text){let raw;try{raw=parse(text)}catch(err){fail(`invalid TOML \u2014 ${err instanceof Error?err.message:String(err)}`)}let warnings=[],id=asString(raw.id,"id");if(!PLUGIN_ID_RE.test(id))fail(`plugin id \`${id}\` may use ASCII letters, digits, dot, colon, underscore, hyphen`);let name=asString(raw.name,"name"),version=asString(raw.version,"version"),rawMinVersion=raw.min_rove_version,minRoveVersion=asString(rawMinVersion,"min_rove_version"),description=raw.description===void 0?void 0:asString(raw.description,"description"),platforms=asPlatforms(raw.platforms,"platforms");if(!platforms)warnings.push("no top-level `platforms` declared; assuming the plugin runs everywhere");let build=asTableArray(raw.build,"build").map((t,i)=>({command:asCommand(t.command,`build[${i}].command`),platforms:asPlatforms(t.platforms,`build[${i}].platforms`)})),startup=asTableArray(raw.startup,"startup").map((t,i)=>({command:asCommand(t.command,`startup[${i}].command`),platforms:asPlatforms(t.platforms,`startup[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`startup[${i}].timeout_ms`)})),shutdown=asTableArray(raw.shutdown,"shutdown").map((t,i)=>({command:asCommand(t.command,`shutdown[${i}].command`),platforms:asPlatforms(t.platforms,`shutdown[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`shutdown[${i}].timeout_ms`)})),actions=asTableArray(raw.actions,"actions").map((t,i)=>{let actionId=asString(t.id,`actions[${i}].id`);if(t.timeout_ms!==void 0)warnings.push(`actions[${i}] declares \`timeout_ms\`; actions are user-invoked and are never killed on a deadline`);if(!LOCAL_ID_RE.test(actionId))fail(`action id \`${actionId}\` may not contain dots`);return{id:actionId,title:asString(t.title,`actions[${i}].title`),command:asCommand(t.command,`actions[${i}].command`),platforms:asPlatforms(t.platforms,`actions[${i}].platforms`)}}),seen=new Set;for(let a of actions){if(seen.has(a.id))fail(`duplicate action id \`${a.id}\``);seen.add(a.id)}let panes=asTableArray(raw.panes,"panes").map((t,i)=>{let paneId=asString(t.id,`panes[${i}].id`);if(!LOCAL_ID_RE.test(paneId))fail(`pane id \`${paneId}\` may not contain dots`);if(t.timeout_ms!==void 0)warnings.push(`panes[${i}] declares \`timeout_ms\`; a pane is a terminal the user closes, not a bounded hook`);if(t.placement!==void 0&&t.placement!=="tab"&&t.placement!=="split")warnings.push(`pane \`${paneId}\` placement \`${String(t.placement)}\` is not supported yet; opening as a split`);return{id:paneId,title:asString(t.title,`panes[${i}].title`),placement:t.placement==="tab"?"tab":"split",command:asCommand(t.command,`panes[${i}].command`),platforms:asPlatforms(t.platforms,`panes[${i}].platforms`)}}),paneSeen=new Set;for(let p of panes){if(paneSeen.has(p.id))fail(`duplicate pane id \`${p.id}\``);paneSeen.add(p.id)}let pages=parsePages(raw.pages,LOCAL_ID_RE),events=asTableArray(raw.events,"events").flatMap((t,i)=>{let on=asString(t.on,`events[${i}].on`),hook={on,command:asCommand(t.command,`events[${i}].command`),platforms:asPlatforms(t.platforms,`events[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`events[${i}].timeout_ms`)};if(!PLUGIN_EVENT_NAMES.includes(on))warnings.push(`unknown event \`${on}\`; this hook will never fire on this Rove version`);return[hook]}),settings=asTableArray(raw.settings,"settings").map((t,i)=>{let type=asString(t.type,`settings[${i}].type`);if(type!=="string"&&type!=="number"&&type!=="boolean"&&type!=="enum"&&type!=="secret")fail(`settings[${i}].type must be string | number | boolean | enum | secret`);let options=t.options===void 0?void 0:Array.isArray(t.options)&&t.options.every((o)=>typeof o==="string"&&o.length>0)?t.options:fail(`settings[${i}].options must be an array of strings`);if(type==="enum"&&(!options||options.length===0))fail(`settings[${i}] enum needs \`options\``);let settingDefault=asSettingDefault(t.default,`settings[${i}].default`),key=asString(t.key,`settings[${i}].key`),rejection=settingKeyRejection(key);if(rejection)fail(`settings[${i}].key ${rejection}`);return{key,label:asString(t.label,`settings[${i}].label`),type,...options?{options}:{},...settingDefault===void 0?{}:{default:settingDefault}}}),fileHandlers=asTableArray(raw.file_handlers,"file_handlers").map((t,i)=>{let pattern=asString(t.pattern,`file_handlers[${i}].pattern`);try{new RegExp(pattern)}catch{fail(`file_handlers[${i}].pattern is not a valid regex`)}let action=asString(t.action,`file_handlers[${i}].action`);if(!actions.some((a)=>a.id===action))fail(`file_handlers[${i}] names unknown action \`${action}\``);return{pattern,action}}),engines=asTableArray(raw.engines,"engines").map((t,i)=>{let engineId=asString(t.id,`engines[${i}].id`);if(!LOCAL_ID_RE.test(engineId))fail(`engine id \`${engineId}\` may not contain dots`);if(RESERVED_ENGINE_IDS.includes(engineId))fail(`engine id \`${engineId}\` shadows a built-in or shipped engine`);let rules=asTableArray(t.rules,`engines[${i}].rules`).map((r,j)=>{let state=asString(r.state,`engines[${i}].rules[${j}].state`);if(state!=="working"&&state!=="blocked"&&state!=="idle")fail(`engines[${i}].rules[${j}].state must be working | blocked | idle`);let lineRegex=asStringArray(r.line_regex,`engines[${i}].rules[${j}].line_regex`);for(let re of lineRegex??[])try{new RegExp(re)}catch{fail(`engines[${i}].rules[${j}].line_regex \`${re}\` is not a valid regex`)}let all=asStringArray(r.all,`engines[${i}].rules[${j}].all`),any=asStringArray(r.any,`engines[${i}].rules[${j}].any`);if(!all&&!any&&!lineRegex)fail(`engines[${i}].rules[${j}] needs at least one of all/any/line_regex`);return{state,...typeof r.bottom_lines==="number"?{bottomLines:r.bottom_lines}:{},...all?{all}:{},...any?{any}:{},...lineRegex?{lineRegex}:{}}}),identityRaw=t.identity,identity;if(identityRaw!==void 0){if(typeof identityRaw!=="object"||identityRaw===null||Array.isArray(identityRaw))fail(`engines[${i}].identity must be a table`);let idt=identityRaw,shortName=((key)=>idt[key]===void 0?void 0:asString(idt[key],`engines[${i}].identity.${key}`))("short_name");identity={...shortName!==void 0?{shortName}:{}}}let firstMessageDelivery;if(t.first_message_delivery!==void 0){let raw2=asString(t.first_message_delivery,`engines[${i}].first_message_delivery`);if(raw2!=="argv"&&raw2!=="paste")fail(`engines[${i}].first_message_delivery must be argv | paste`);firstMessageDelivery=raw2}return{id:engineId,name:asString(t.name,`engines[${i}].name`),command:asCommand(t.command,`engines[${i}].command`),...t.process_names===void 0?{}:{processNames:asCommand(t.process_names,`engines[${i}].process_names`)},rules,...identity?{identity}:{},...firstMessageDelivery?{firstMessageDelivery}:{}}}),engineSeen=new Set;for(let e of engines){if(engineSeen.has(e.id))fail(`duplicate engine id \`${e.id}\``);engineSeen.add(e.id)}let mod;if(raw.mod!==void 0){if(!raw.mod||typeof raw.mod!=="object"||Array.isArray(raw.mod))fail("`mod` must be a table");let t=raw.mod;if(t.timeout_ms!==void 0)warnings.push("`mod` declares `timeout_ms`; a mod runs until the daemon stops");mod={command:asCommand(t.command,"mod.command"),platforms:asPlatforms(t.platforms,"mod.platforms")}}return{manifest:{id,name,version,minRoveVersion,description,platforms,build,startup,shutdown,actions,events,panes,pages,settings,fileHandlers,engines,...mod?{mod}:{}},warnings}}import{mkdirSync,readFileSync as readFileSync2,writeFileSync}from"fs";import{dirname,join as join2,relative}from"path";var EMPTY={plugins:[]};function loadPluginRegistry(homeDir){let text;try{text=readFileSync2(pluginRegistryPath(homeDir),"utf8")}catch{return EMPTY}try{let raw=JSON.parse(text);if(!Array.isArray(raw.plugins))return EMPTY;return{plugins:raw.plugins.filter(isEntry).map((entry)=>withCanonicalRoot(entry,homeDir))}}catch{return EMPTY}}function withCanonicalRoot(entry,homeDir){if(entry.source.kind!=="github")return entry;let legacy=legacyPluginsRootDir(homeDir),canonical=pluginsRootDir(homeDir);if(legacy===canonical)return entry;let inside=relative(legacy,entry.root);if(inside===""||inside.startsWith("..")||inside.startsWith("/"))return entry;return{...entry,root:join2(canonical,inside)}}function isEntry(v){if(typeof v!=="object"||v===null)return!1;let e=v,source=e.source;return typeof e.id==="string"&&typeof e.root==="string"&&typeof e.enabled==="boolean"&&typeof e.version==="string"&&typeof e.installedAt==="number"&&typeof source==="object"&&source!==null&&(source.kind==="link"||source.kind==="github"&&typeof source.spec==="string")}function savePluginRegistry(registry,homeDir){let path=pluginRegistryPath(homeDir);mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(registry,null,2)}
|
|
2
|
+
import{legacyPluginsRootDir,pluginRegistryPath,pluginsRootDir}from"./chunk-j1z9kgyd.js";import{parse}from"./chunk-w7zv47mp.js";import{PLUGIN_EVENT_NAMES}from"./chunk-96kvwzj8.js";import{OWNER_ONLY_FILE_MODE}from"./chunk-yt15y085.js";import{existsSync,readFileSync}from"fs";import{basename,join}from"path";var PLUGIN_PLATFORMS=["macos","linux","windows"];class ManifestError extends Error{}function fail(message){throw new ManifestError(`rove-plugin.toml: ${message}`)}function asString(value,field){if(typeof value!=="string"||value.length===0)fail(`\`${field}\` must be a non-empty string`);return value}function asSettingDefault(value,field){if(value===void 0||value===!1)return;if(value===!0)return"1";if(typeof value==="number"&&Number.isFinite(value))return String(value);return asString(value,field)}var TIMEOUT_MIN_MS=100,TIMEOUT_MAX_MS=600000;function asTimeoutMs(value,field){if(value===void 0)return;if(typeof value!=="number"||!Number.isInteger(value)||value<TIMEOUT_MIN_MS||value>TIMEOUT_MAX_MS)fail(`\`${field}\` must be a whole number of milliseconds between ${TIMEOUT_MIN_MS} and ${TIMEOUT_MAX_MS}`);return value}function asCommand(value,field){if(!Array.isArray(value)||value.length===0||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings (argv form)`);return value}function asPlatforms(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>PLUGIN_PLATFORMS.includes(v)))fail(`\`${field}\` must be an array drawn from ${PLUGIN_PLATFORMS.join(", ")}`);return value}function asTableArray(value,field){if(value===void 0)return[];if(!Array.isArray(value)||!value.every((v)=>typeof v==="object"&&v!==null&&!Array.isArray(v)))fail(`\`[[${field}]]\` must be an array of tables`);return value}function asStringArray(value,field){if(value===void 0)return;if(!Array.isArray(value)||!value.every((v)=>typeof v==="string"&&v.length>0))fail(`\`${field}\` must be a non-empty array of strings`);return value}import{isAbsolute,normalize,sep}from"path";var DEFAULT_PAGE_ORDER=100;function insidePlugin(entry){if(isAbsolute(entry))return!1;return normalize(entry).split(/[\\/]/)[0]!==".."&&!normalize(entry).startsWith(`..${sep}`)}function parsePages(raw,localId){let pages=asTableArray(raw,"pages").map((t,i)=>{let id=asString(t.id,`pages[${i}].id`);if(!localId.test(id))fail(`page id \`${id}\` may not contain dots`);let entry=asString(t.entry,`pages[${i}].entry`);if(!insidePlugin(entry))fail(`page \`${id}\` entry \`${entry}\` must be a path inside the plugin`);let order=t.order??DEFAULT_PAGE_ORDER;if(typeof order!=="number"||!Number.isInteger(order))fail(`\`pages[${i}].order\` must be an integer`);let action=t.action===void 0?void 0:asString(t.action,`pages[${i}].action`);return{id,title:asString(t.title,`pages[${i}].title`),entry,order,...action?{action}:{}}}),seen=new Set;for(let page of pages){if(seen.has(page.id))fail(`duplicate page id \`${page.id}\``);seen.add(page.id)}return pages}var SETTING_KEY_RE=/^[A-Za-z_][A-Za-z0-9_]*$/,RESERVED_SETTING_KEYS=["PATH","HOME","SHELL","IFS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","NODE_OPTIONS","BUN_INSPECT","PYTHONPATH","PYTHONSTARTUP","PERL5OPT","PERL5LIB","RUBYOPT","BASH_ENV","ENV","GIT_SSH_COMMAND","GIT_SSH","GIT_EXTERNAL_DIFF","GIT_PAGER","PAGER","EDITOR","VISUAL"];function settingKeyRejection(key){if(!SETTING_KEY_RE.test(key))return`\`${key}\` is not a valid env var name (${SETTING_KEY_RE.source})`;if(RESERVED_SETTING_KEYS.includes(key))return`\`${key}\` is reserved; it steers how the plugin's own process runs`;return null}var PLUGIN_MANIFEST_FILENAME="rove-plugin.toml",PLUGIN_MANIFEST_FILENAMES=[PLUGIN_MANIFEST_FILENAME],RESERVED_ENGINE_IDS=["claude","codex","copilot","kimi","pi","omp","gemini","opencode","cursor","grok","droid","amp","devin","qodercli","cline","kiro","maki","antigravity","bob","hermes","kilo","mastracode"];function pluginManifestPath(root){for(let filename of PLUGIN_MANIFEST_FILENAMES){let path=join(root,filename);if(existsSync(path))return path}return null}function readPluginManifest(root){let path=pluginManifestPath(root);if(!path)throw new ManifestError(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);return parsePluginManifest(readFileSync(path,"utf8"),basename(path))}var PLUGIN_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._:-]*$/,LOCAL_ID_RE=/^[A-Za-z0-9][A-Za-z0-9_:-]*$/;function qualifiedActionId(pluginId,actionId){return`${pluginId}.${actionId}`}function currentPluginPlatform(platform=process.platform){if(platform==="darwin")return"macos";if(platform==="linux")return"linux";if(platform==="win32")return"windows";return}function supportsPlatform(item,manifest,platform){let declared=item.platforms??manifest.platforms;if(!declared)return!0;return platform!==void 0&&declared.includes(platform)}function parsePluginManifest(text,filename=PLUGIN_MANIFEST_FILENAME){try{return parseCanonicalPluginManifest(text)}catch(err){if(filename!==PLUGIN_MANIFEST_FILENAME&&err instanceof ManifestError)throw new ManifestError(err.message.replace(/^rove-plugin\.toml:/,`${filename}:`));throw err}}function parseCanonicalPluginManifest(text){let raw;try{raw=parse(text)}catch(err){fail(`invalid TOML \u2014 ${err instanceof Error?err.message:String(err)}`)}let warnings=[],id=asString(raw.id,"id");if(!PLUGIN_ID_RE.test(id))fail(`plugin id \`${id}\` may use ASCII letters, digits, dot, colon, underscore, hyphen`);let name=asString(raw.name,"name"),version=asString(raw.version,"version"),rawMinVersion=raw.min_rove_version,minRoveVersion=asString(rawMinVersion,"min_rove_version"),description=raw.description===void 0?void 0:asString(raw.description,"description"),platforms=asPlatforms(raw.platforms,"platforms");if(!platforms)warnings.push("no top-level `platforms` declared; assuming the plugin runs everywhere");let build=asTableArray(raw.build,"build").map((t,i)=>({command:asCommand(t.command,`build[${i}].command`),platforms:asPlatforms(t.platforms,`build[${i}].platforms`)})),startup=asTableArray(raw.startup,"startup").map((t,i)=>({command:asCommand(t.command,`startup[${i}].command`),platforms:asPlatforms(t.platforms,`startup[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`startup[${i}].timeout_ms`)})),shutdown=asTableArray(raw.shutdown,"shutdown").map((t,i)=>({command:asCommand(t.command,`shutdown[${i}].command`),platforms:asPlatforms(t.platforms,`shutdown[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`shutdown[${i}].timeout_ms`)})),actions=asTableArray(raw.actions,"actions").map((t,i)=>{let actionId=asString(t.id,`actions[${i}].id`);if(t.timeout_ms!==void 0)warnings.push(`actions[${i}] declares \`timeout_ms\`; actions are user-invoked and are never killed on a deadline`);if(!LOCAL_ID_RE.test(actionId))fail(`action id \`${actionId}\` may not contain dots`);return{id:actionId,title:asString(t.title,`actions[${i}].title`),command:asCommand(t.command,`actions[${i}].command`),platforms:asPlatforms(t.platforms,`actions[${i}].platforms`)}}),seen=new Set;for(let a of actions){if(seen.has(a.id))fail(`duplicate action id \`${a.id}\``);seen.add(a.id)}let panes=asTableArray(raw.panes,"panes").map((t,i)=>{let paneId=asString(t.id,`panes[${i}].id`);if(!LOCAL_ID_RE.test(paneId))fail(`pane id \`${paneId}\` may not contain dots`);if(t.timeout_ms!==void 0)warnings.push(`panes[${i}] declares \`timeout_ms\`; a pane is a terminal the user closes, not a bounded hook`);if(t.placement!==void 0&&t.placement!=="tab"&&t.placement!=="split")warnings.push(`pane \`${paneId}\` placement \`${String(t.placement)}\` is not supported yet; opening as a split`);return{id:paneId,title:asString(t.title,`panes[${i}].title`),placement:t.placement==="tab"?"tab":"split",command:asCommand(t.command,`panes[${i}].command`),platforms:asPlatforms(t.platforms,`panes[${i}].platforms`)}}),paneSeen=new Set;for(let p of panes){if(paneSeen.has(p.id))fail(`duplicate pane id \`${p.id}\``);paneSeen.add(p.id)}let pages=parsePages(raw.pages,LOCAL_ID_RE),events=asTableArray(raw.events,"events").flatMap((t,i)=>{let on=asString(t.on,`events[${i}].on`),hook={on,command:asCommand(t.command,`events[${i}].command`),platforms:asPlatforms(t.platforms,`events[${i}].platforms`),timeoutMs:asTimeoutMs(t.timeout_ms,`events[${i}].timeout_ms`)};if(!PLUGIN_EVENT_NAMES.includes(on))warnings.push(`unknown event \`${on}\`; this hook will never fire on this Rove version`);return[hook]}),settings=asTableArray(raw.settings,"settings").map((t,i)=>{let type=asString(t.type,`settings[${i}].type`);if(type!=="string"&&type!=="number"&&type!=="boolean"&&type!=="enum"&&type!=="secret")fail(`settings[${i}].type must be string | number | boolean | enum | secret`);let options=t.options===void 0?void 0:Array.isArray(t.options)&&t.options.every((o)=>typeof o==="string"&&o.length>0)?t.options:fail(`settings[${i}].options must be an array of strings`);if(type==="enum"&&(!options||options.length===0))fail(`settings[${i}] enum needs \`options\``);let settingDefault=asSettingDefault(t.default,`settings[${i}].default`),key=asString(t.key,`settings[${i}].key`),rejection=settingKeyRejection(key);if(rejection)fail(`settings[${i}].key ${rejection}`);return{key,label:asString(t.label,`settings[${i}].label`),type,...options?{options}:{},...settingDefault===void 0?{}:{default:settingDefault}}}),fileHandlers=asTableArray(raw.file_handlers,"file_handlers").map((t,i)=>{let pattern=asString(t.pattern,`file_handlers[${i}].pattern`);try{new RegExp(pattern)}catch{fail(`file_handlers[${i}].pattern is not a valid regex`)}let action=asString(t.action,`file_handlers[${i}].action`);if(!actions.some((a)=>a.id===action))fail(`file_handlers[${i}] names unknown action \`${action}\``);return{pattern,action}}),engines=asTableArray(raw.engines,"engines").map((t,i)=>{let engineId=asString(t.id,`engines[${i}].id`);if(!LOCAL_ID_RE.test(engineId))fail(`engine id \`${engineId}\` may not contain dots`);if(RESERVED_ENGINE_IDS.includes(engineId))fail(`engine id \`${engineId}\` shadows a built-in or shipped engine`);let rules=asTableArray(t.rules,`engines[${i}].rules`).map((r,j)=>{let state=asString(r.state,`engines[${i}].rules[${j}].state`);if(state!=="working"&&state!=="blocked"&&state!=="idle")fail(`engines[${i}].rules[${j}].state must be working | blocked | idle`);let lineRegex=asStringArray(r.line_regex,`engines[${i}].rules[${j}].line_regex`);for(let re of lineRegex??[])try{new RegExp(re)}catch{fail(`engines[${i}].rules[${j}].line_regex \`${re}\` is not a valid regex`)}let all=asStringArray(r.all,`engines[${i}].rules[${j}].all`),any=asStringArray(r.any,`engines[${i}].rules[${j}].any`);if(!all&&!any&&!lineRegex)fail(`engines[${i}].rules[${j}] needs at least one of all/any/line_regex`);return{state,...typeof r.bottom_lines==="number"?{bottomLines:r.bottom_lines}:{},...all?{all}:{},...any?{any}:{},...lineRegex?{lineRegex}:{}}}),identityRaw=t.identity,identity;if(identityRaw!==void 0){if(typeof identityRaw!=="object"||identityRaw===null||Array.isArray(identityRaw))fail(`engines[${i}].identity must be a table`);let idt=identityRaw,shortName=((key)=>idt[key]===void 0?void 0:asString(idt[key],`engines[${i}].identity.${key}`))("short_name");identity={...shortName!==void 0?{shortName}:{}}}let firstMessageDelivery;if(t.first_message_delivery!==void 0){let raw2=asString(t.first_message_delivery,`engines[${i}].first_message_delivery`);if(raw2!=="argv"&&raw2!=="paste")fail(`engines[${i}].first_message_delivery must be argv | paste`);firstMessageDelivery=raw2}return{id:engineId,name:asString(t.name,`engines[${i}].name`),command:asCommand(t.command,`engines[${i}].command`),...t.process_names===void 0?{}:{processNames:asCommand(t.process_names,`engines[${i}].process_names`)},rules,...identity?{identity}:{},...firstMessageDelivery?{firstMessageDelivery}:{}}}),engineSeen=new Set;for(let e of engines){if(engineSeen.has(e.id))fail(`duplicate engine id \`${e.id}\``);engineSeen.add(e.id)}let mod;if(raw.mod!==void 0){if(!raw.mod||typeof raw.mod!=="object"||Array.isArray(raw.mod))fail("`mod` must be a table");let t=raw.mod;if(t.timeout_ms!==void 0)warnings.push("`mod` declares `timeout_ms`; a mod runs until the daemon stops");mod={command:asCommand(t.command,"mod.command"),platforms:asPlatforms(t.platforms,"mod.platforms")}}return{manifest:{id,name,version,minRoveVersion,description,platforms,build,startup,shutdown,actions,events,panes,pages,settings,fileHandlers,engines,...mod?{mod}:{}},warnings}}import{mkdirSync,readFileSync as readFileSync2,writeFileSync}from"fs";import{dirname,join as join2,relative}from"path";var EMPTY={plugins:[]};function loadPluginRegistry(homeDir){let text;try{text=readFileSync2(pluginRegistryPath(homeDir),"utf8")}catch{return EMPTY}try{let raw=JSON.parse(text);if(!Array.isArray(raw.plugins))return EMPTY;return{plugins:raw.plugins.filter(isEntry).map((entry)=>withCanonicalRoot(entry,homeDir))}}catch{return EMPTY}}function withCanonicalRoot(entry,homeDir){if(entry.source.kind!=="github")return entry;let legacy=legacyPluginsRootDir(homeDir),canonical=pluginsRootDir(homeDir);if(legacy===canonical)return entry;let inside=relative(legacy,entry.root);if(inside===""||inside.startsWith("..")||inside.startsWith("/"))return entry;return{...entry,root:join2(canonical,inside)}}function isEntry(v){if(typeof v!=="object"||v===null)return!1;let e=v,source=e.source;return typeof e.id==="string"&&typeof e.root==="string"&&typeof e.enabled==="boolean"&&typeof e.version==="string"&&typeof e.installedAt==="number"&&typeof source==="object"&&source!==null&&(source.kind==="link"||source.kind==="github"&&typeof source.spec==="string")}function savePluginRegistry(registry,homeDir){let path=pluginRegistryPath(homeDir);mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(registry,null,2)}
|
|
3
3
|
`,{mode:OWNER_ONLY_FILE_MODE})}function upsertPluginEntry(registry,entry){return{plugins:[...registry.plugins.filter((p)=>p.id!==entry.id),entry]}}function removePluginEntry(registry,id){return{plugins:registry.plugins.filter((p)=>p.id!==id)}}
|
|
4
4
|
export{PLUGIN_MANIFEST_FILENAMES,pluginManifestPath,readPluginManifest,qualifiedActionId,currentPluginPlatform,supportsPlatform,parsePluginManifest,loadPluginRegistry,savePluginRegistry,upsertPluginEntry,removePluginEntry};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import{DAEMON_CHANNELS}from"./chunk-96kvwzj8.js";import{logClientError}from"./chunk-0g4wc808.js";import{samePath}from"./chunk-pn5ygqn6.js";import{preRenameRuntimePaths}from"./chunk-f8gg8cqh.js";import{readRoveEnv}from"./chunk-nc46gddg.js";import{connect}from"net";import{StringDecoder}from"string_decoder";import{spawnSync}from"child_process";import{existsSync}from"fs";function normalizeRemoteUrl(url){let u=url.trim();return u=u.replace(/^[a-z+]+:\/\//i,""),u=u.replace(/^[^@/]+@/,""),u=u.replace(/^([^/:]+):(?!\d+\/)/,"$1/"),u=u.replace(/^([^/:]+):\d+\//,"$1/"),u=u.replace(/\/+$/,"").replace(/\.git$/i,""),u=u.replace(/^ssh\.github\.com\//i,"github.com/"),u.toLowerCase()}function git(cwd,args){let res=spawnSync("git",["-C",cwd,...args],{encoding:"utf8",timeout:5000,windowsHide:!0});return res.status===0?res.stdout.trim():null}function computeRepoId(path){let origin=git(path,["remote","get-url","origin"]);if(origin)return normalizeRemoteUrl(origin);let root=git(path,["rev-list","--max-parents=0","HEAD"])?.split(`
|
|
3
|
-
`).filter(Boolean).sort()[0];return root?`root:${root}`:void 0}var memo=new Map;function repoIdOf(path){if(!path)return;if(memo.has(path))return memo.get(path);if(!existsSync(path))return;let id=computeRepoId(path);return memo.set(path,id),id}function automationRunNeedsAttention(status){return status==="dispatch_failed"||status==="skipped_unavailable"||status==="script_failed"}var ROUTINE_RESPONSE_MAX_CHARS=32000,ROUTINE_RESPONSE_WINDOW_MS=7200000;function routineRunResponseState(run,nowMs){if(run.response)return"responded";if(run.status!=="dispatched"&&run.status!=="revived")return null;if(run.deliveryStatus==="missing")return"missing";if(run.deliveryStatus==="awaiting")return"awaiting";return nowMs-Date.parse(run.at)>ROUTINE_RESPONSE_WINDOW_MS?"missing":"awaiting"}var GATE_QUESTION_MAX=500,GATE_CONTEXT_MAX=4000,GATE_OPTIONS_MAX=6;function gateInboxKey(gateId){return`\x00gate\x00${gateId}`}var ATTENTION_INBOX_STATES=["turn_complete","permission_needed","error","rate_limited","dead","routine_failed","report_missing","decision_needed"];function isRoutineInboxState(state){return state==="routine_failed"}function isAttentionInboxState(value){return typeof value==="string"&&ATTENTION_INBOX_STATES.includes(value)}function attentionInboxItemKey(item){if(isRoutineInboxState(item.state)&&item.detail?.routine)return`\x00${item.state}\x00${item.detail.routine.automationId}`;if(item.state==="report_missing"&&item.detail?.delivery)return`\x00delivery\x00${item.detail.delivery.id}`;if(item.state==="decision_needed"&&item.detail?.gate)return gateInboxKey(item.detail.gate.id);return`${item.taskId}\x00${item.tabId??""}`}var DELIVERY_OUTCOMES=["done","partial","blocked","failed"],DELIVERY_SUMMARY_MAX_CHARS=32000,DELIVERY_EVIDENCE_MAX_ITEMS=50,DELIVERY_EVIDENCE_MAX_CHARS=2000,DELIVERY_NEXT_MAX_CHARS=4000,DELIVERY_PROMPT_HEAD_CHARS=200,MAX_DELIVERIES_PER_TASK=50,DELIVERY_STALL_MS=600000;function deliveryFooter(deliveryId,api){return`[ROVE] When this turn ends, report: ${api} report --delivery ${deliveryId} --outcome done|partial|blocked|failed --summary \u2026 [--evidence \u2026]\u2026 [--next \u2026]`}var SKIP_REASONS=["task-missing","awaiting-owner","report-missing","quota","engine-error","engine-dead","awaiting-permission","busy"],SHOULD_RUN_SKIP_EXIT_CODE=3;function parseSkipVerdict(value){if(!value||typeof value!=="object"||Array.isArray(value))return;let raw=value;if(raw.run!==!1||!SKIP_REASONS.includes(raw.reason))return;let text=(v)=>typeof v==="string"&&v.length>0?v:void 0;return{run:!1,reason:raw.reason,...text(raw.detail)?{detail:raw.detail}:{},...text(raw.until)?{until:raw.until}:{},...Array.isArray(raw.gateIds)?{gateIds:raw.gateIds.filter((g)=>typeof g==="string")}:{}}}var CHANNEL_NAMES=DAEMON_CHANNELS;var CHANNEL_NAME_SET=new Set(CHANNEL_NAMES);function isChannelName(value){return typeof value==="string"&&CHANNEL_NAME_SET.has(value)}function normalizeChannelFilter(value){if(!Array.isArray(value))return null;let set=new Set;for(let name of value)if(isChannelName(name))set.add(name);return set.size>0?set:null}var DAEMON_PROTOCOL_VERSION=5,MIN_COMPATIBLE_PROTOCOL_VERSION=2;function isProtocolCompatible(args){return args.remoteVersion>=args.localMin&&args.localVersion>=args.remoteMin}function isDaemonVersionStale(daemonVersion,clientVersion){if(!daemonVersion)return!1;return daemonVersion!==clientVersion}function isForeignDaemonHome(daemonHome,clientHome){if(!daemonHome)return!1;return!samePath(daemonHome,clientHome)}var BLOCKING_RPCS=new Set(["api.invoke","ui.prompt","task.land","workitem.start","automation.runNow","pr.rerunFailedChecks","pr.reviewComments","task.ensureWorktree","task.spawn","task.ensureMain","worktree.discoverAdoptable","worktree.adopt","worktree.list","worktree.remove"]),PTY_STOP_REFUSED="PtyStopRefused";function displayTaskTitle(task){return task.title||task.branch||task.worktreePath||task.repo||"scratch"}function serializeTask(task){let repoId=repoIdOf(task.repo);return{id:task.id,title:displayTaskTitle(task),repo:task.repo,branch:task.branch,worktreePath:task.worktreePath,kind:task.kind??"task",...task.scratch?{scratch:!0}:{},...task.noProject?{noProject:!0}:{},...task.routine?{routine:task.routine}:{},status:task.status,pinned:task.pinned??!1,...task.archived?{archived:!0}:{},vendor:task.vendor,command:task.command,prStatus:task.prStatus,modelEffort:task.modelEffort,model:task.model,tier:task.tier,groupId:task.groupId,observedLanguage:task.observedLanguage,deletion:task.deletion,quotaResume:task.quotaResume,linkedWorkItem:task.linkedWorkItem,dispatcher:task.dispatcher,...task.parentTaskId?{parentTaskId:task.parentTaskId}:{},...task.sharesWorkspaceOf?{sharesWorkspaceOf:task.sharesWorkspaceOf}:{},...task.cwdSubpath?{cwdSubpath:task.cwdSubpath}:{},...task.ptyAlias?{ptyAlias:task.ptyAlias}:{},...task.extraRepos?.length?{extraRepos:task.extraRepos}:{},...task.sessionPrs?.length?{sessionPrs:task.sessionPrs}:{},requireReport:task.requireReport,prompt:task.prompt,baseRef:task.baseRef,worktreeName:task.worktreeName,report:task.report,...repoId?{repoId}:{},createdAt:task.createdAt,updatedAt:task.updatedAt}}function frameToLine(frame){return`${JSON.stringify(frame)}
|
|
3
|
+
`).filter(Boolean).sort()[0];return root?`root:${root}`:void 0}var memo=new Map;function repoIdOf(path){if(!path)return;if(memo.has(path))return memo.get(path);if(!existsSync(path))return;let id=computeRepoId(path);return memo.set(path,id),id}function automationRunNeedsAttention(status){return status==="dispatch_failed"||status==="skipped_unavailable"||status==="script_failed"}var ROUTINE_RESPONSE_MAX_CHARS=32000,ROUTINE_RESPONSE_WINDOW_MS=7200000;function routineRunResponseState(run,nowMs){if(run.response)return"responded";if(run.status!=="dispatched"&&run.status!=="revived")return null;if(run.deliveryStatus==="missing")return"missing";if(run.deliveryStatus==="awaiting")return"awaiting";return nowMs-Date.parse(run.at)>ROUTINE_RESPONSE_WINDOW_MS?"missing":"awaiting"}var GATE_QUESTION_MAX=500,GATE_CONTEXT_MAX=4000,GATE_OPTIONS_MAX=6;function gateInboxKey(gateId){return`\x00gate\x00${gateId}`}var ATTENTION_INBOX_STATES=["turn_complete","permission_needed","error","rate_limited","dead","routine_failed","report_missing","decision_needed"];function isRoutineInboxState(state){return state==="routine_failed"}function isAttentionInboxState(value){return typeof value==="string"&&ATTENTION_INBOX_STATES.includes(value)}function attentionInboxItemKey(item){if(isRoutineInboxState(item.state)&&item.detail?.routine)return`\x00${item.state}\x00${item.detail.routine.automationId}`;if(item.state==="report_missing"&&item.detail?.delivery)return`\x00delivery\x00${item.detail.delivery.id}`;if(item.state==="decision_needed"&&item.detail?.gate)return gateInboxKey(item.detail.gate.id);return`${item.taskId}\x00${item.tabId??""}`}var DELIVERY_OUTCOMES=["done","partial","blocked","failed"],DELIVERY_SUMMARY_MAX_CHARS=32000,DELIVERY_EVIDENCE_MAX_ITEMS=50,DELIVERY_EVIDENCE_MAX_CHARS=2000,DELIVERY_NEXT_MAX_CHARS=4000,DELIVERY_PROMPT_HEAD_CHARS=200,MAX_DELIVERIES_PER_TASK=50,DELIVERY_STALL_MS=600000;function deliveryFooter(deliveryId,api){return`[ROVE] When this turn ends, report: ${api} report --delivery ${deliveryId} --outcome done|partial|blocked|failed --summary \u2026 [--evidence \u2026]\u2026 [--next \u2026]`}var SKIP_REASONS=["task-missing","awaiting-owner","report-missing","quota","engine-error","engine-dead","awaiting-permission","busy"],SHOULD_RUN_SKIP_EXIT_CODE=3;function parseSkipVerdict(value){if(!value||typeof value!=="object"||Array.isArray(value))return;let raw=value;if(raw.run!==!1||!SKIP_REASONS.includes(raw.reason))return;let text=(v)=>typeof v==="string"&&v.length>0?v:void 0;return{run:!1,reason:raw.reason,...text(raw.detail)?{detail:raw.detail}:{},...text(raw.until)?{until:raw.until}:{},...Array.isArray(raw.gateIds)?{gateIds:raw.gateIds.filter((g)=>typeof g==="string")}:{}}}var CHANNEL_NAMES=DAEMON_CHANNELS;var CHANNEL_NAME_SET=new Set(CHANNEL_NAMES);function isChannelName(value){return typeof value==="string"&&CHANNEL_NAME_SET.has(value)}function normalizeChannelFilter(value){if(!Array.isArray(value))return null;let set=new Set;for(let name of value)if(isChannelName(name))set.add(name);return set.size>0?set:null}var DAEMON_PROTOCOL_VERSION=5,MIN_COMPATIBLE_PROTOCOL_VERSION=2;function isProtocolCompatible(args){return args.remoteVersion>=args.localMin&&args.localVersion>=args.remoteMin}function isDaemonVersionStale(daemonVersion,clientVersion){if(!daemonVersion)return!1;return daemonVersion!==clientVersion}function isForeignDaemonHome(daemonHome,clientHome){if(!daemonHome)return!1;return!samePath(daemonHome,clientHome)}var BLOCKING_RPCS=new Set(["api.invoke","ui.prompt","task.land","workitem.start","automation.runNow","pr.rerunFailedChecks","pr.reviewComments","task.ensureWorktree","task.spawn","task.ensureMain","task.moveToProject","worktree.discoverAdoptable","worktree.adopt","worktree.list","worktree.remove","task.checkpoint","task.rewind","task.exportBranch"]),PTY_STOP_REFUSED="PtyStopRefused";function displayTaskTitle(task){return task.title||task.branch||task.worktreePath||task.repo||"scratch"}function serializeTask(task){let repoId=repoIdOf(task.repo);return{id:task.id,title:displayTaskTitle(task),repo:task.repo,branch:task.branch,worktreePath:task.worktreePath,kind:task.kind??"task",...task.scratch?{scratch:!0}:{},...task.noProject?{noProject:!0}:{},...task.routine?{routine:task.routine}:{},status:task.status,pinned:task.pinned??!1,...task.archived?{archived:!0}:{},vendor:task.vendor,command:task.command,prStatus:task.prStatus,modelEffort:task.modelEffort,model:task.model,tier:task.tier,groupId:task.groupId,observedLanguage:task.observedLanguage,deletion:task.deletion,quotaResume:task.quotaResume,linkedWorkItem:task.linkedWorkItem,dispatcher:task.dispatcher,...task.parentTaskId?{parentTaskId:task.parentTaskId}:{},...task.sharesWorkspaceOf?{sharesWorkspaceOf:task.sharesWorkspaceOf}:{},...task.cwdSubpath?{cwdSubpath:task.cwdSubpath}:{},...task.ptyAlias?{ptyAlias:task.ptyAlias}:{},...task.extraRepos?.length?{extraRepos:task.extraRepos}:{},...task.workspace?{workspace:task.workspace}:{},...task.sessionPrs?.length?{sessionPrs:task.sessionPrs}:{},requireReport:task.requireReport,prompt:task.prompt,baseRef:task.baseRef,worktreeName:task.worktreeName,report:task.report,...repoId?{repoId}:{},createdAt:task.createdAt,updatedAt:task.updatedAt}}function frameToLine(frame){return`${JSON.stringify(frame)}
|
|
4
4
|
`}class RpcTimeoutError extends Error{constructor(name,timeoutMs){super(`daemon rpc "${name}" timed out after ${timeoutMs}ms (daemon wedged?)`);this.name="RpcTimeoutError"}}function rpcTimeoutMs(){let raw=readRoveEnv("RPC_TIMEOUT_MS")?.trim();if(raw){let parsed=Number.parseInt(raw,10);if(Number.isFinite(parsed))return parsed}return 20000}class ConnectTimeoutError extends Error{constructor(socketPath,timeoutMs){super(`connecting to ${socketPath} timed out after ${timeoutMs}ms \u2014 nothing accepted the connection (daemon or PTY host not listening at that address)`);this.name="ConnectTimeoutError"}}function connectTimeoutMs(){let raw=readRoveEnv("CONNECT_TIMEOUT_MS")?.trim();if(raw){let parsed=Number.parseInt(raw,10);if(Number.isFinite(parsed))return parsed}return 5000}class RoveDaemonClient{socketPath;socket=null;buffer="";nextId=1;pending=new Map;handlers=new Map;lifecycleHandlers=new Map;connecting=null;disposed=!1;constructor(socketPath){this.socketPath=socketPath}connect(){if(this.socket)return Promise.resolve();if(this.disposed)return Promise.reject(Error("daemon client disposed"));if(this.connecting)return this.connecting;let p=this.openSocketWithFallback();this.connecting=p;let cleanup=()=>{if(this.connecting===p)this.connecting=null};return p.then(cleanup,cleanup),p}get isDisposed(){return this.disposed}close(){this.disposed=!0,this.socket?.end(),this.socket=null,this.failPending()}forceDisconnect(){let socket=this.socket;if(!socket)return;this.socket=null,socket.destroy(),this.failPending()}failPending(){if(this.pending.size===0)return;let err=Error("daemon connection closed");for(let pending of this.pending.values()){if(pending.timer)clearTimeout(pending.timer);pending.reject(err)}this.pending.clear()}on(name,handler){let set=this.handlers.get(name);if(!set)set=new Set,this.handlers.set(name,set);return set.add(handler),()=>{if(set?.delete(handler),set?.size===0)this.handlers.delete(name)}}onChannel(channel,handler){return this.on(channel,(frame)=>handler(frame.payload))}subscribe(opts={}){let payload={};if(opts.channels)payload.channels=opts.channels;if(opts.role)payload.role=opts.role;if(opts.cellPixelSize)payload.cellPixelWidth=opts.cellPixelSize.width,payload.cellPixelHeight=opts.cellPixelSize.height;return this.request("subscribe",payload)}onLifecycle(name,handler){let set=this.lifecycleHandlers.get(name);if(!set)set=new Set,this.lifecycleHandlers.set(name,set);return set.add(handler),()=>{if(set?.delete(handler),set?.size===0)this.lifecycleHandlers.delete(name)}}async request(name,payload){await this.connect();let socket=this.socket;if(!socket)throw Error("daemon connection is not open");let id=String(this.nextId++),promise=new Promise((resolve,reject)=>{let entry={resolve:(value)=>resolve(value),reject},timeoutMs=rpcTimeoutMs();if(timeoutMs>0&&!BLOCKING_RPCS.has(name))entry.timer=setTimeout(()=>this.onRequestTimeout(id,name,timeoutMs),timeoutMs);this.pending.set(id,entry)});return socket.write(frameToLine({type:"request",id,name,payload})),promise}onRequestTimeout(id,name,timeoutMs){let pending=this.pending.get(id);if(!pending)return;this.pending.delete(id),pending.reject(new RpcTimeoutError(name,timeoutMs)),this.forceDisconnect(),this.emitLifecycle("close")}async openSocketWithFallback(){try{await this.openSocket(this.socketPath);return}catch(err){if(!(err instanceof Error)||!("code"in err)||!["ENOENT","ECONNREFUSED"].includes(String(err.code)))throw err;for(let path of preRenameRuntimePaths(this.socketPath)){if(this.disposed)throw err;try{await this.openSocket(path);return}catch{}}throw err}}openSocket(path){return new Promise((resolve,reject)=>{let socket=connect(path);this.socket=socket;let timeoutMs=connectTimeoutMs(),timer;if(timeoutMs>0)timer=setTimeout(()=>{if(socket.off("connect",onConnect),socket.off("error",onError),socket.destroy(),this.socket===socket)this.socket=null;reject(new ConnectTimeoutError(this.socketPath,timeoutMs))},timeoutMs);let onConnect=()=>{if(timer)clearTimeout(timer);socket.off("error",onError),socket.on("error",()=>socket.destroy()),resolve()},onError=(err)=>{if(timer)clearTimeout(timer);if(socket.off("connect",onConnect),this.socket===socket)this.socket=null;reject(err)};socket.once("connect",onConnect),socket.once("error",onError);let decoder=new StringDecoder("utf8");this.buffer="",socket.on("data",(chunk)=>this.onData(decoder.write(chunk))),socket.on("close",()=>this.onSocketClose(socket))})}onSocketClose(which){if(this.socket!==which)return;this.socket=null,this.failPending(),this.emitLifecycle("close")}emitLifecycle(name){for(let handler of this.lifecycleHandlers.get(name)??[])try{handler()}catch(err){console.error(`[rove] lifecycle handler for "${name}" threw:`,err)}}onData(chunk){this.buffer+=chunk;let nl=this.buffer.indexOf(`
|
|
5
5
|
`);while(nl!==-1){let line=this.buffer.slice(0,nl);if(this.buffer=this.buffer.slice(nl+1),line.trim().length>0)this.onLine(line);nl=this.buffer.indexOf(`
|
|
6
6
|
`)}}onLine(line){let frame;try{frame=JSON.parse(line)}catch(err){logClientError("client-frame",err);return}if(frame.type==="event"){this.emit(frame);return}if(frame.type!=="response")return;let pending=this.pending.get(frame.id);if(!pending)return;if(this.pending.delete(frame.id),pending.timer)clearTimeout(pending.timer);if(frame.error){let err=Error(frame.error.message);if(frame.error.name)err.name=frame.error.name;if(frame.error.data!==void 0)err.data=frame.error.data;pending.reject(err)}else pending.resolve(frame.payload)}emit(frame){for(let handler of this.handlers.get(frame.name)??[])try{handler(frame)}catch(err){logClientError("client-event",err)}for(let handler of this.handlers.get("*")??[])try{handler(frame)}catch(err){logClientError("client-event",err)}}}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{isShellKind,shippedCompletionsPath}from"./chunk-eege1x0a.js";import{loadStateFile,patchStateFile}from"./chunk-32j6y5d1.js";import{t}from"./chunk-372g44dg.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{appendFileSync,existsSync,mkdirSync,readFileSync,writeFileSync}from"fs";import{homedir}from"os";import{basename,join}from"path";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
|
+
`),{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
|
+
# ${cli} completions
|
|
5
|
+
${hook}
|
|
6
|
+
`),{path:rc,installed:!0}}function recordWelcomeChoices(choices,shell){try{patchStateFile({[PENDING_COMPLETIONS_KEY]:choices.completions&&shell!==null?shell:void 0,"welcomeInstall.completions":choices.completions?{status:"queued"}:void 0})}catch{}}function runPendingWelcomeInstalls(){let shell=loadStateFile()[PENDING_COMPLETIONS_KEY],pendingShell=typeof shell==="string"&&isShellKind(shell)?shell:null;if(shell!==void 0&&pendingShell===null){process.stdout.write(`! Ignoring invalid pending completion shell; run rove completions --help to choose a supported shell.
|
|
7
|
+
`);try{patchStateFile({[PENDING_COMPLETIONS_KEY]:void 0,"welcomeInstall.completions":{status:"failed",reason:"Unsupported shell"}})}catch{}}if(pendingShell===null)return;let cli=ROVE_PRODUCT_NAME,out=(line)=>process.stdout.write(`${line}
|
|
8
|
+
`),save=(patch)=>{try{patchStateFile(patch)}catch{out("! Could not save setup results; check permissions before retrying.")}},failed=(item,reason,command)=>{save({[`welcomeInstall.${item}`]:{status:"failed",reason}}),out(t("onboarding.installFailed",{item,reason,command}))};if(pendingShell!==null)try{let completion=installCompletions(pendingShell);save({[PENDING_COMPLETIONS_KEY]:void 0,"welcomeInstall.completions":{status:"succeeded"}}),out(t(completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions",{path:completion.path}))}catch(error){failed("completions",error instanceof Error?error.message:String(error),`${cli} completions ${pendingShell} --install`)}}function settleWelcomeInstall(item,shell){if(loadStateFile()[PENDING_COMPLETIONS_KEY]!==shell)return;try{patchStateFile({[PENDING_COMPLETIONS_KEY]:void 0,[`welcomeInstall.${item}`]:{status:"succeeded"}})}catch{process.stderr.write(`! Setup succeeded, but its queued state could not be saved. Check settings permissions.
|
|
9
|
+
`)}}
|
|
10
|
+
export{detectShell,installCompletions,recordWelcomeChoices,runPendingWelcomeInstalls,settleWelcomeInstall};
|