@sma1lboy/rove 0.9.240 → 0.9.242

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.
Files changed (49) hide show
  1. package/dist/cli/{chunk-4dv0mgan.js → chunk-00twck20.js} +1 -1
  2. package/dist/cli/{chunk-bb5zqmea.js → chunk-089zn7my.js} +1 -1
  3. package/dist/cli/{chunk-m1ekbqyz.js → chunk-0pw3xfqz.js} +1 -1
  4. package/dist/cli/{chunk-q7zzycy7.js → chunk-1wdtwxbt.js} +3 -3
  5. package/dist/cli/{chunk-8tadwbx9.js → chunk-2ss0xjsp.js} +1 -1
  6. package/dist/cli/{chunk-34261s0m.js → chunk-460bba4e.js} +2 -2
  7. package/dist/cli/{chunk-szrfp0jq.js → chunk-4ev7g7j1.js} +1 -1
  8. package/dist/cli/{chunk-wp9bygh4.js → chunk-4j8g3fcd.js} +1 -1
  9. package/dist/cli/{chunk-m19q29wk.js → chunk-54h93msh.js} +1 -1
  10. package/dist/cli/{chunk-kz4txj2e.js → chunk-599q1w3a.js} +3 -3
  11. package/dist/cli/{chunk-yybpg7fh.js → chunk-6ms5chc3.js} +1 -1
  12. package/dist/cli/{chunk-4tx2kayk.js → chunk-808wt4qs.js} +1 -1
  13. package/dist/cli/chunk-94zjxcnf.js +3 -0
  14. package/dist/cli/chunk-9hmzrmdt.js +39 -0
  15. package/dist/cli/{chunk-5nsvp4h7.js → chunk-a2wf3nkw.js} +1 -1
  16. package/dist/cli/{chunk-4xj52nx1.js → chunk-c84a6t3t.js} +1 -1
  17. package/dist/cli/{chunk-xckpezd9.js → chunk-c8c44dty.js} +3 -3
  18. package/dist/cli/{chunk-abyk3w2j.js → chunk-d0qgz1es.js} +1 -1
  19. package/dist/cli/chunk-e1x88j3k.js +3 -0
  20. package/dist/cli/{chunk-twyda1p8.js → chunk-f0qamp5r.js} +1 -1
  21. package/dist/cli/{chunk-85zr7kph.js → chunk-g7jgmz7p.js} +2 -2
  22. package/dist/cli/{chunk-g0eygcnq.js → chunk-hg72x88m.js} +1 -1
  23. package/dist/cli/{chunk-3vyk7bzb.js → chunk-k6886jet.js} +1 -1
  24. package/dist/cli/{chunk-ekg3h5z3.js → chunk-my6xhnej.js} +1 -1
  25. package/dist/cli/chunk-n3he2z72.js +3 -0
  26. package/dist/cli/{chunk-jxqs4y9j.js → chunk-n77m138t.js} +1 -1
  27. package/dist/cli/{chunk-801h8bze.js → chunk-nnjqb4nb.js} +1 -1
  28. package/dist/cli/{chunk-f1nf99hj.js → chunk-q08abj38.js} +1 -1
  29. package/dist/cli/{chunk-ze0htjr5.js → chunk-rjq1ryb1.js} +1 -1
  30. package/dist/cli/chunk-s3bqmn0s.js +2 -0
  31. package/dist/cli/{chunk-m5gx53yr.js → chunk-s4xfj2xj.js} +1 -1
  32. package/dist/cli/{chunk-g4j41mky.js → chunk-skf7y627.js} +1 -1
  33. package/dist/cli/{chunk-ekd274v3.js → chunk-tjb8fftb.js} +2 -2
  34. package/dist/cli/{chunk-q5eee34y.js → chunk-tntt3ken.js} +1 -1
  35. package/dist/cli/chunk-wp3ts69s.js +4 -0
  36. package/dist/cli/{chunk-31y92jm8.js → chunk-x5fdsft6.js} +2 -2
  37. package/dist/cli/{chunk-fwqd5ta2.js → chunk-xkv2vm37.js} +2 -2
  38. package/dist/cli/chunk-y7jhc2zf.js +2 -0
  39. package/dist/cli/{chunk-thsmzarw.js → chunk-yc09g6vq.js} +1 -1
  40. package/dist/cli/{chunk-80ydqr3s.js → chunk-z6acdd5c.js} +1 -1
  41. package/dist/cli/index.js +3 -3
  42. package/dist/cli/rove.js +3 -3
  43. package/dist/completions/rove.bash +2 -1
  44. package/dist/completions/rove.fish +2 -0
  45. package/dist/completions/rove.zsh +2 -1
  46. package/package.json +2 -1
  47. package/dist/cli/chunk-a0ave3g6.js +0 -3
  48. package/dist/cli/chunk-fhch0x0q.js +0 -3
  49. package/dist/cli/chunk-nzh30nty.js +0 -4
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{submitFeedback}from"./chunk-4tx2kayk.js";import"./chunk-a0ave3g6.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME,FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
2
+ import{submitFeedback}from"./chunk-808wt4qs.js";import"./chunk-94zjxcnf.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME,FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
3
3
  `);function usageError(message){process.stderr.write(`${CLI_NAME} feedback: ${message}
4
4
 
5
5
  ${FEEDBACK_USAGE}
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{buildPaneArgv}from"./chunk-ffs26p85.js";import{PluginCliError,installPlugin,linkPlugin}from"./chunk-3vyk7bzb.js";import{resolvePluginBinPath}from"./chunk-b0ssvpht.js";import{buildPluginEnv}from"./chunk-axsm0gn5.js";import{currentPluginPlatform,loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginLogPath,qualifiedActionId,readPluginManifest,removePluginEntry,savePluginRegistry,supportsPlatform}from"./chunk-rqyaf0dw.js";import"./chunk-vjvkkrzc.js";import"./chunk-w7zv47mp.js";import{flagValue}from"./chunk-zsfyj36g.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{SUBCOMMAND_VERBS}from"./chunk-fhch0x0q.js";import"./chunk-a0ave3g6.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0422g8ac.js";import{defaultDaemonSocketPath}from"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{readFileSync,rmSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME;function printUsage(out){out.write([`usage: ${CLI_NAME} plugin <command>`,""," install <owner/repo[/subdir]> [--yes] [--ref <rev>] clone from GitHub, preview, build, register"," link <dir> register a local plugin directory (dev)"," list installed + linked plugins"," search [query] browse the marketplace (GitHub topic rove-plugin)"," outdated check GitHub-installed plugins against upstream"," update <id\u2026> | --all [--yes] reinstall stale plugins from GitHub"," enable <id> | disable <id> toggle a plugin without unregistering it"," unlink <id> unregister a linked plugin (files untouched)"," uninstall <id-or-spec> unregister + remove the managed checkout"," config-dir <id> print the plugin's config directory"," log <id> [-n <count>] tail the plugin's command-run log"," action list [--plugin <id>] declared actions"," action invoke <plugin-id.action-id> run an action now"," pane open <plugin-id.pane-id> [--task <task-id>] open a plugin pane as a terminal tab (JSON:"," clients \u2014 0 = no attached UI performed the split)","","Marketplace: https://github.com/topics/rove-plugin",""].join(`
2
+ import{buildPaneArgv}from"./chunk-ffs26p85.js";import{PluginCliError,installPlugin,linkPlugin}from"./chunk-k6886jet.js";import{resolvePluginBinPath}from"./chunk-b0ssvpht.js";import{buildPluginEnv}from"./chunk-axsm0gn5.js";import{currentPluginPlatform,loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginLogPath,qualifiedActionId,readPluginManifest,removePluginEntry,savePluginRegistry,supportsPlatform}from"./chunk-rqyaf0dw.js";import"./chunk-vjvkkrzc.js";import"./chunk-w7zv47mp.js";import{flagValue}from"./chunk-zsfyj36g.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{SUBCOMMAND_VERBS}from"./chunk-e1x88j3k.js";import"./chunk-94zjxcnf.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0422g8ac.js";import{defaultDaemonSocketPath}from"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{readFileSync,rmSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME;function printUsage(out){out.write([`usage: ${CLI_NAME} plugin <command>`,""," install <owner/repo[/subdir]> [--yes] [--ref <rev>] clone from GitHub, preview, build, register"," link <dir> register a local plugin directory (dev)"," list installed + linked plugins"," search [query] browse the marketplace (GitHub topic rove-plugin)"," outdated check GitHub-installed plugins against upstream"," update <id\u2026> | --all [--yes] reinstall stale plugins from GitHub"," enable <id> | disable <id> toggle a plugin without unregistering it"," unlink <id> unregister a linked plugin (files untouched)"," uninstall <id-or-spec> unregister + remove the managed checkout"," config-dir <id> print the plugin's config directory"," log <id> [-n <count>] tail the plugin's command-run log"," action list [--plugin <id>] declared actions"," action invoke <plugin-id.action-id> run an action now"," pane open <plugin-id.pane-id> [--task <task-id>] open a plugin pane as a terminal tab (JSON:"," clients \u2014 0 = no attached UI performed the split)","","Marketplace: https://github.com/topics/rove-plugin",""].join(`
3
3
  `))}function loadAll(){return loadPluginRegistry().plugins.map((entry)=>{try{return{entry,manifest:readPluginManifest(entry.root).manifest}}catch{return{entry,manifest:void 0}}})}function requireEntry(id){let entry=loadPluginRegistry().plugins.find((p)=>p.id===id);if(!entry)throw new PluginCliError(`no plugin registered as \`${id}\`; see \`${CLI_NAME} plugin list\``);return entry}function listPlugins(){let all=loadAll();if(all.length===0){console.log(`no plugins installed. Try: ${CLI_NAME} plugin install <owner/repo> \u2014 browse the \`rove-plugin\` GitHub topic.`);return}for(let{entry,manifest}of all){let state=entry.enabled?"enabled":"disabled",kind=entry.source.kind==="link"?`linked ${entry.root}`:entry.source.spec,broken=manifest?"":" [manifest unreadable]";console.log(`${entry.id} v${entry.version} ${state} (${kind})${broken}`)}}function setEnabled(id,enabled){let entry=requireEntry(id),registry=loadPluginRegistry();savePluginRegistry({plugins:registry.plugins.map((p)=>p.id===id?{...entry,enabled}:p)}),console.log(`${enabled?"enabled":"disabled"} ${id}`)}function unlink(id){let entry=requireEntry(id);if(entry.source.kind!=="link")throw new PluginCliError(`\`${id}\` is a GitHub install; use uninstall`);savePluginRegistry(removePluginEntry(loadPluginRegistry(),id)),console.log(`unlinked ${id} (files untouched at ${entry.root})`)}function uninstall(idOrSpec){let registry=loadPluginRegistry(),entry=registry.plugins.find((p)=>p.id===idOrSpec||p.source.kind==="github"&&p.source.spec===idOrSpec);if(!entry)throw new PluginCliError(`no plugin registered as \`${idOrSpec}\``);if(entry.source.kind==="link")throw new PluginCliError(`\`${entry.id}\` is linked; use unlink`);savePluginRegistry(removePluginEntry(registry,entry.id)),rmSync(pluginCheckoutDir(entry.id),{recursive:!0,force:!0}),console.log(`uninstalled ${entry.id} (config/state kept under ~/.rove/plugins/${entry.id}/)`)}function listActions(pluginFilter){for(let{entry,manifest}of loadAll()){if(!manifest||pluginFilter&&entry.id!==pluginFilter)continue;for(let action of manifest.actions)console.log(`${qualifiedActionId(entry.id,action.id)} ${action.title}`)}}function findByLongestPluginPrefix(qualified,options,findItem){for(let{entry,manifest}of loadAll().filter(({entry:entry2,manifest:manifest2})=>Boolean(manifest2&&(!options.enabledOnly||entry2.enabled)&&qualified.startsWith(`${entry2.id}.`))).sort((a,b)=>b.entry.id.length-a.entry.id.length)){let item=findItem(manifest,qualified.slice(entry.id.length+1));if(item!==void 0)return{entry,manifest,item}}return}function assertPlatformSupported(label,item,manifest){if(supportsPlatform(item,manifest,currentPluginPlatform()))return;let declared=(item.platforms??manifest.platforms??[]).join(", ");throw new PluginCliError(`\`${label}\` is not supported on this platform (declares ${declared})`)}function invokeAction(qualified,extraArgs){let hit=findByLongestPluginPrefix(qualified,{enabledOnly:!0},(manifest,actionId)=>manifest.actions.find((a)=>a.id===actionId));if(!hit)throw new PluginCliError(`no action \`${qualified}\`; see \`${CLI_NAME} plugin action list\``);assertPlatformSupported(qualified,hit.item,hit.manifest);let action=hit.item,[cmd,...args]=[...action.command,...extraArgs],res=spawnSync(cmd,args,{cwd:hit.entry.root,stdio:"inherit",env:buildPluginEnv({socketPath:defaultDaemonSocketPath(),binPath:resolvePluginBinPath(),pluginId:hit.entry.id,pluginRoot:hit.entry.root,extra:{ROVE_PLUGIN_ACTION_ID:action.id,ROVE_PLUGIN_INVOKE_CWD:process.cwd()}})});process.exit(res.status??1)}function resolvePaneQualified(qualified){let hit=findByLongestPluginPrefix(qualified,{enabledOnly:!1},(manifest,entrypoint)=>manifest.panes.find((p)=>p.id===entrypoint));if(!hit)throw new PluginCliError(`no pane \`${qualified}\`; see \`${CLI_NAME} plugin list\``);return{pluginId:hit.entry.id,entrypoint:hit.item.id}}async function openPane(pluginId,entrypoint,taskFlag){let loaded=loadAll().find(({entry})=>entry.id===pluginId);if(!loaded?.manifest)throw new PluginCliError(`no plugin \`${pluginId}\` (or its manifest is unreadable)`);if(!loaded.entry.enabled)throw new PluginCliError(`\`${pluginId}\` is disabled`);let pane=loaded.manifest.panes.find((p)=>p.id===entrypoint);if(!pane)throw new PluginCliError(`no pane \`${entrypoint}\` in \`${pluginId}\`; declare it under [[panes]]`);assertPlatformSupported(`${pluginId}.${pane.id}`,pane,loaded.manifest);let{openDaemonSession,resolveActiveTaskId}=await import("./chunk-yvjgwnb9.js"),session=await openDaemonSession({mode:"start"});try{let taskId=taskFlag??await resolveActiveTaskId(session.client);if(!taskId)throw new PluginCliError("no active task; pass --task <id>");let argv=buildPaneArgv(loaded.entry.id,loaded.entry.root,pane,{socketPath:defaultDaemonSocketPath(),binPath:resolvePluginBinPath(),taskId}),reply=await session.client.request("tab.open",{taskId,argv,title:pane.title,placement:pane.placement});console.log(JSON.stringify({...reply,ok:!0,pane:`${pluginId}.${pane.id}`,taskId,title:pane.title}))}finally{session.close()}}function tailLog(id,count){requireEntry(id);let text;try{text=readFileSync(pluginLogPath(id),"utf8")}catch{console.log("(no runs logged yet)");return}let lines=text.trimEnd().split(`
4
- `);for(let line of lines.slice(-count))console.log(line)}async function runPluginSubcommand(rest){let[command,...args]=rest;if(command!==void 0&&!SUBCOMMAND_VERBS.plugin.includes(command)){let isHelp=command==="help"||command==="--help"||command==="-h";if(printUsage(isHelp?process.stdout:process.stderr),!isHelp)process.exit(2);return}try{switch(command){case"install":{let spec=args.find((a)=>!a.startsWith("-"));if(!spec)throw new PluginCliError("install needs <owner/repo[/subdir]>");await installPlugin(spec,{yes:args.includes("--yes"),ref:flagValue(args,"--ref")});return}case"link":{if(!args[0])throw new PluginCliError("link needs a directory");linkPlugin(args[0]);return}case"list":listPlugins();return;case"search":{let{searchMarketplace}=await import("./chunk-nem2x959.js");await searchMarketplace(args.find((a)=>!a.startsWith("-")));return}case"outdated":{let{printOutdated}=await import("./chunk-szrfp0jq.js");printOutdated();return}case"update":{let{updatePlugins}=await import("./chunk-szrfp0jq.js");await updatePlugins(args.filter((a)=>!a.startsWith("-")),{all:args.includes("--all"),yes:args.includes("--yes")});return}case"enable":case"disable":{if(!args[0])throw new PluginCliError(`${command} needs a plugin id`);setEnabled(args[0],command==="enable");return}case"unlink":{if(!args[0])throw new PluginCliError("unlink needs a plugin id");unlink(args[0]);return}case"uninstall":{if(!args[0])throw new PluginCliError("uninstall needs a plugin id or owner/repo spec");uninstall(args[0]);return}case"config-dir":{if(!args[0])throw new PluginCliError("config-dir needs a plugin id");requireEntry(args[0]),console.log(pluginConfigDir(args[0]));return}case"log":{if(!args[0])throw new PluginCliError("log needs a plugin id");tailLog(args[0],Number.parseInt(flagValue(args,"-n")??"20",10)||20);return}case"pane":{let[sub,...paneArgs]=args;if(sub==="open"){let positional=paneArgs.find((a)=>!a.startsWith("-")&&a!==flagValue(paneArgs,"--task")),pluginId=flagValue(paneArgs,"--plugin"),entrypoint=flagValue(paneArgs,"--entrypoint");if(!pluginId||!entrypoint){if(!positional)throw new PluginCliError("pane open needs <plugin-id.pane-id> (or --plugin <id> --entrypoint <pane-id>) [--task <task-id>]");({pluginId,entrypoint}=resolvePaneQualified(positional))}await openPane(pluginId,entrypoint,flagValue(paneArgs,"--task"));return}printUsage(process.stderr),process.exit(2);return}case"action":{let[sub,...actionArgs]=args;if(sub==="list"){listActions(flagValue(actionArgs,"--plugin"));return}if(sub==="invoke"){if(!actionArgs[0])throw new PluginCliError("action invoke needs <plugin-id.action-id>");invokeAction(actionArgs[0],actionArgs.slice(1));return}printUsage(process.stderr),process.exit(2);return}default:{let isHelp=command===void 0||command==="help"||command==="--help"||command==="-h";if(printUsage(isHelp?process.stdout:process.stderr),!isHelp)process.exit(2);return}}}catch(err){if(err instanceof PluginCliError)console.error(`${CLI_NAME} plugin: ${err.message}`),process.exit(1);console.error(`${CLI_NAME} plugin: ${errorMessage(err)}`),process.exit(1)}}export{runPluginSubcommand};
4
+ `);for(let line of lines.slice(-count))console.log(line)}async function runPluginSubcommand(rest){let[command,...args]=rest;if(command!==void 0&&!SUBCOMMAND_VERBS.plugin.includes(command)){let isHelp=command==="help"||command==="--help"||command==="-h";if(printUsage(isHelp?process.stdout:process.stderr),!isHelp)process.exit(2);return}try{switch(command){case"install":{let spec=args.find((a)=>!a.startsWith("-"));if(!spec)throw new PluginCliError("install needs <owner/repo[/subdir]>");await installPlugin(spec,{yes:args.includes("--yes"),ref:flagValue(args,"--ref")});return}case"link":{if(!args[0])throw new PluginCliError("link needs a directory");linkPlugin(args[0]);return}case"list":listPlugins();return;case"search":{let{searchMarketplace}=await import("./chunk-nem2x959.js");await searchMarketplace(args.find((a)=>!a.startsWith("-")));return}case"outdated":{let{printOutdated}=await import("./chunk-4ev7g7j1.js");printOutdated();return}case"update":{let{updatePlugins}=await import("./chunk-4ev7g7j1.js");await updatePlugins(args.filter((a)=>!a.startsWith("-")),{all:args.includes("--all"),yes:args.includes("--yes")});return}case"enable":case"disable":{if(!args[0])throw new PluginCliError(`${command} needs a plugin id`);setEnabled(args[0],command==="enable");return}case"unlink":{if(!args[0])throw new PluginCliError("unlink needs a plugin id");unlink(args[0]);return}case"uninstall":{if(!args[0])throw new PluginCliError("uninstall needs a plugin id or owner/repo spec");uninstall(args[0]);return}case"config-dir":{if(!args[0])throw new PluginCliError("config-dir needs a plugin id");requireEntry(args[0]),console.log(pluginConfigDir(args[0]));return}case"log":{if(!args[0])throw new PluginCliError("log needs a plugin id");tailLog(args[0],Number.parseInt(flagValue(args,"-n")??"20",10)||20);return}case"pane":{let[sub,...paneArgs]=args;if(sub==="open"){let positional=paneArgs.find((a)=>!a.startsWith("-")&&a!==flagValue(paneArgs,"--task")),pluginId=flagValue(paneArgs,"--plugin"),entrypoint=flagValue(paneArgs,"--entrypoint");if(!pluginId||!entrypoint){if(!positional)throw new PluginCliError("pane open needs <plugin-id.pane-id> (or --plugin <id> --entrypoint <pane-id>) [--task <task-id>]");({pluginId,entrypoint}=resolvePaneQualified(positional))}await openPane(pluginId,entrypoint,flagValue(paneArgs,"--task"));return}printUsage(process.stderr),process.exit(2);return}case"action":{let[sub,...actionArgs]=args;if(sub==="list"){listActions(flagValue(actionArgs,"--plugin"));return}if(sub==="invoke"){if(!actionArgs[0])throw new PluginCliError("action invoke needs <plugin-id.action-id>");invokeAction(actionArgs[0],actionArgs.slice(1));return}printUsage(process.stderr),process.exit(2);return}default:{let isHelp=command===void 0||command==="help"||command==="--help"||command==="-h";if(printUsage(isHelp?process.stdout:process.stderr),!isHelp)process.exit(2);return}}}catch(err){if(err instanceof PluginCliError)console.error(`${CLI_NAME} plugin: ${err.message}`),process.exit(1);console.error(`${CLI_NAME} plugin: ${errorMessage(err)}`),process.exit(1)}}export{runPluginSubcommand};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{writeOutdatedCache}from"./chunk-atmaakwp.js";import{PluginCliError,installPlugin}from"./chunk-3vyk7bzb.js";import{loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginDataDir,pluginStateDir,removePluginEntry,savePluginRegistry}from"./chunk-rqyaf0dw.js";import"./chunk-w7zv47mp.js";import"./chunk-a0ave3g6.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0422g8ac.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{execFileSync}from"child_process";import{existsSync,mkdirSync,readdirSync,renameSync}from"fs";import{join}from"path";function gitOut(args,cwd){try{return execFileSync("git",args,{cwd,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function checkEntry(entry){let repoSpec=entry.source.spec.split("/").slice(0,2).join("/"),localSha=gitOut(["rev-parse","HEAD"],pluginCheckoutDir(entry.id)),remote=gitOut(["ls-remote",`https://github.com/${repoSpec}.git`,"HEAD"]),remoteSha=remote?remote.split(/\s+/)[0]??null:null;return{id:entry.id,spec:entry.source.spec,version:entry.version,localSha,remoteSha,behind:Boolean(localSha&&remoteSha&&localSha!==remoteSha)}}function listOutdated(){let rows=loadPluginRegistry().plugins.filter((p)=>p.source.kind==="github").map(checkEntry);return writeOutdatedCache(rows.filter((r)=>r.behind).map((r)=>r.id)),rows}function printOutdated(){let rows=listOutdated();if(rows.length===0){console.log("no GitHub-installed plugins.");return}for(let r of rows){let status=r.behind?"update available":r.remoteSha===null?"remote unreachable":r.localSha===null?"local sha unreadable":"up to date";console.log(`${r.id} v${r.version} ${status}`)}}function migrateRenamedPlugin(oldId,newId){for(let dirOf of[pluginConfigDir,pluginStateDir]){let from=dirOf(oldId),to=dirOf(newId);if(!existsSync(from))continue;mkdirSync(to,{recursive:!0});for(let entry of readdirSync(from)){if(existsSync(join(to,entry)))continue;renameSync(join(from,entry),join(to,entry))}}savePluginRegistry(removePluginEntry(loadPluginRegistry(),oldId)),console.log(`renamed ${oldId} \u2192 ${newId}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${pluginDataDir(oldId)}`)}async function updatePlugins(ids,opts){let rows=listOutdated(),targets;if(opts.all){if(targets=rows.filter((r)=>r.behind),targets.length===0){console.log("all plugins up to date.");return}}else{if(ids.length===0)throw new PluginCliError("update takes plugin ids or --all");targets=ids.map((id)=>{let row=rows.find((r)=>r.id===id);if(!row)throw new PluginCliError(`\`${id}\` is not a GitHub-installed plugin; see \`${ROVE_PRODUCT_NAME} plugin list\``);return row})}for(let target of targets){if(!target.behind&&!ids.includes(target.id))continue;console.log(`updating ${target.id} (${target.spec})\u2026`);let installedId=await installPlugin(target.spec,{yes:opts.yes});if(installedId!==target.id)migrateRenamedPlugin(target.id,installedId)}listOutdated()}export{updatePlugins,printOutdated};
2
+ import{writeOutdatedCache}from"./chunk-atmaakwp.js";import{PluginCliError,installPlugin}from"./chunk-k6886jet.js";import{loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginDataDir,pluginStateDir,removePluginEntry,savePluginRegistry}from"./chunk-rqyaf0dw.js";import"./chunk-w7zv47mp.js";import"./chunk-94zjxcnf.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-0422g8ac.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";import{execFileSync}from"child_process";import{existsSync,mkdirSync,readdirSync,renameSync}from"fs";import{join}from"path";function gitOut(args,cwd){try{return execFileSync("git",args,{cwd,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function checkEntry(entry){let repoSpec=entry.source.spec.split("/").slice(0,2).join("/"),localSha=gitOut(["rev-parse","HEAD"],pluginCheckoutDir(entry.id)),remote=gitOut(["ls-remote",`https://github.com/${repoSpec}.git`,"HEAD"]),remoteSha=remote?remote.split(/\s+/)[0]??null:null;return{id:entry.id,spec:entry.source.spec,version:entry.version,localSha,remoteSha,behind:Boolean(localSha&&remoteSha&&localSha!==remoteSha)}}function listOutdated(){let rows=loadPluginRegistry().plugins.filter((p)=>p.source.kind==="github").map(checkEntry);return writeOutdatedCache(rows.filter((r)=>r.behind).map((r)=>r.id)),rows}function printOutdated(){let rows=listOutdated();if(rows.length===0){console.log("no GitHub-installed plugins.");return}for(let r of rows){let status=r.behind?"update available":r.remoteSha===null?"remote unreachable":r.localSha===null?"local sha unreadable":"up to date";console.log(`${r.id} v${r.version} ${status}`)}}function migrateRenamedPlugin(oldId,newId){for(let dirOf of[pluginConfigDir,pluginStateDir]){let from=dirOf(oldId),to=dirOf(newId);if(!existsSync(from))continue;mkdirSync(to,{recursive:!0});for(let entry of readdirSync(from)){if(existsSync(join(to,entry)))continue;renameSync(join(from,entry),join(to,entry))}}savePluginRegistry(removePluginEntry(loadPluginRegistry(),oldId)),console.log(`renamed ${oldId} \u2192 ${newId}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${pluginDataDir(oldId)}`)}async function updatePlugins(ids,opts){let rows=listOutdated(),targets;if(opts.all){if(targets=rows.filter((r)=>r.behind),targets.length===0){console.log("all plugins up to date.");return}}else{if(ids.length===0)throw new PluginCliError("update takes plugin ids or --all");targets=ids.map((id)=>{let row=rows.find((r)=>r.id===id);if(!row)throw new PluginCliError(`\`${id}\` is not a GitHub-installed plugin; see \`${ROVE_PRODUCT_NAME} plugin list\``);return row})}for(let target of targets){if(!target.behind&&!ids.includes(target.id))continue;console.log(`updating ${target.id} (${target.spec})\u2026`);let installedId=await installPlugin(target.spec,{yes:opts.yes});if(installedId!==target.id)migrateRenamedPlugin(target.id,installedId)}listOutdated()}export{updatePlugins,printOutdated};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,PACKAGE_NAME,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,compareSemver,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,isNewerSemver,owningNpmPrefix,recommendedGlobalInstallCommand,releasePageUrl,repoSlug}from"./chunk-a0ave3g6.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{repoSlug,releasePageUrl,recommendedGlobalInstallCommand,owningNpmPrefix,isNewerSemver,fetchReleaseSummaries,fetchReleaseNotesRange,fetchReleaseNotes,compareSemver,checkLatestVersion,channelOf,breakingVersionsCrossed,UPDATE_SCRIPT_URL,UPDATE_COMMAND,RELEASE_CHANNELS,PACKAGE_NAME,DEFAULT_RELEASE_CHANNEL,CURRENT_VERSION,BREAKING_VERSIONS};
2
+ import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,PACKAGE_NAME,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,compareSemver,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,isNewerSemver,owningNpmPrefix,recommendedGlobalInstallCommand,releasePageUrl,repoSlug}from"./chunk-94zjxcnf.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";export{repoSlug,releasePageUrl,recommendedGlobalInstallCommand,owningNpmPrefix,isNewerSemver,fetchReleaseSummaries,fetchReleaseNotesRange,fetchReleaseNotes,compareSemver,checkLatestVersion,channelOf,breakingVersionsCrossed,UPDATE_SCRIPT_URL,UPDATE_COMMAND,RELEASE_CHANNELS,PACKAGE_NAME,DEFAULT_RELEASE_CHANNEL,CURRENT_VERSION,BREAKING_VERSIONS};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{RemoteOrchestrator}from"./chunk-80ydqr3s.js";import{discoverMachine}from"./chunk-wtb8cycx.js";import"./chunk-atn06ncf.js";import"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import{startTunnel}from"./chunk-9jsm6h5y.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-9aydqazr.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-xy8be792.js";import"./chunk-a0ave3g6.js";import"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{createStateCell}from"./chunk-nhakrm1f.js";import{RoveDaemonClient}from"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import{logClient,logClientError}from"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";class MachineHub{local;slots=new Map;machinesAcc=createStateCell([],"machines.status");mergedAcc=createStateCell([],"machines.tasks");localUnsubscribe=null;disposed=!1;constructor(local){this.local=local}machinesSignal(){return this.machinesAcc}tasksSignal(){if(this.slots.size===0)return this.local.tasksSignal();return this.mergedAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}attach(){let entries=dedupeMachines(listMachines());if(entries.length===0)return;for(let entry of entries)this.slots.set(entry.alias,{entry,tasks:[]});this.publishStatuses(),this.localUnsubscribe=this.local.tasksSignal().subscribe(()=>this.republishTasks()),this.republishTasks();for(let entry of entries)this.connect(entry)}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}if(found.ok)updateMachine(entry.alias,{sockets});let tunnel=startTunnel({alias:entry.alias,config:entry,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new RoveDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{await orchestrator.init()}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()});slot.unsubscribe=()=>{stopTasks(),stopConnection()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.roveVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}publishStatuses(){this.machinesAcc.set([...this.slots.values()].map((slot)=>({alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})))}republishTasks(){let merged=this.local.tasksSignal().get().map((task)=>stampOrigin(task,"local","local"));for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.mergedAcc.set(merged)}dispose(){this.disposed=!0,this.localUnsubscribe?.();for(let slot of this.slots.values())slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop();this.slots.clear()}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}export{classifyHandshakeFailure,MachineHub};
2
+ import{discoverMachine}from"./chunk-wtb8cycx.js";import{RemoteOrchestrator}from"./chunk-z6acdd5c.js";import"./chunk-atn06ncf.js";import"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import{startTunnel}from"./chunk-9jsm6h5y.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-9aydqazr.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-xy8be792.js";import"./chunk-94zjxcnf.js";import"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{createStateCell}from"./chunk-nhakrm1f.js";import{RoveDaemonClient}from"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import{logClient,logClientError}from"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-wqfp8d9w.js";class MachineHub{local;slots=new Map;machinesAcc=createStateCell([],"machines.status");mergedAcc=createStateCell([],"machines.tasks");localUnsubscribe=null;disposed=!1;constructor(local){this.local=local}machinesSignal(){return this.machinesAcc}tasksSignal(){if(this.slots.size===0)return this.local.tasksSignal();return this.mergedAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}attach(){let entries=dedupeMachines(listMachines());if(entries.length===0)return;for(let entry of entries)this.slots.set(entry.alias,{entry,tasks:[]});this.publishStatuses(),this.localUnsubscribe=this.local.tasksSignal().subscribe(()=>this.republishTasks()),this.republishTasks();for(let entry of entries)this.connect(entry)}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}if(found.ok)updateMachine(entry.alias,{sockets});let tunnel=startTunnel({alias:entry.alias,config:entry,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new RoveDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{await orchestrator.init()}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()});slot.unsubscribe=()=>{stopTasks(),stopConnection()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.roveVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}publishStatuses(){this.machinesAcc.set([...this.slots.values()].map((slot)=>({alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})))}republishTasks(){let merged=this.local.tasksSignal().get().map((task)=>stampOrigin(task,"local","local"));for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.mergedAcc.set(merged)}dispose(){this.disposed=!0,this.localUnsubscribe?.();for(let slot of this.slots.values())slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop();this.slots.clear()}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}export{classifyHandshakeFailure,MachineHub};
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{generateCompletions,isShellKind,mergeSubVerbs,shippedCompletionsPath}from"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.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(`
2
+ import{generateCompletions,isShellKind,mergeSubVerbs,shippedCompletionsPath}from"./chunk-6ms5chc3.js";import"./chunk-e1x88j3k.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-nc46gddg.js";import{__require}from"./chunk-wqfp8d9w.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-f1nf99hj.js"),import("./chunk-28zg6p31.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-abyk3w2j.js");process.stdout.write(generateCompletions(shell,cliName,mergeSubVerbs(API_VERBS)))}export{runCompletionsSubcommand};
7
+ `);return}if(flags[0]==="--install"){let[{installCompletions,settleWelcomeInstall},{t}]=await Promise.all([import("./chunk-q08abj38.js"),import("./chunk-28zg6p31.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-d0qgz1es.js");process.stdout.write(generateCompletions(shell,cliName,mergeSubVerbs(API_VERBS)))}export{runCompletionsSubcommand};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{SUBCOMMAND_VERBS,TOP_LEVEL_SUBCOMMANDS}from"./chunk-fhch0x0q.js";import{join}from"path";import{fileURLToPath}from"url";var SHELLS=["bash","zsh","fish"];function isShellKind(value){return SHELLS.some((shell)=>shell===value)}var SHIPPED_COMPLETIONS_DIR=fileURLToPath(new URL("../completions/",import.meta.url));function shippedCompletionsPath(shell,cliName,dir=SHIPPED_COMPLETIONS_DIR){return join(dir,`${cliName}.${shell}`)}function mergeSubVerbs(apiVerbs){let merged={...SUBCOMMAND_VERBS,api:apiVerbs};return Object.keys(merged).sort().map((command)=>[command,merged[command]??[]])}function generateCompletions(shell,cliName,subVerbs){return shell==="bash"?generateBashCompletions(cliName,subVerbs):shell==="zsh"?generateZshCompletions(cliName,subVerbs):generateFishCompletions(cliName,subVerbs)}function generateBashCompletions(cliName,subVerbs){let subcommands=TOP_LEVEL_SUBCOMMANDS.join(" "),fn=`_${cliName}`;return[`# ${cliName} bash completions`,`# Source: ${cliName} completions bash`,"",`${fn}() {`," local cur prev"," COMPREPLY=()",' cur="${COMP_WORDS[COMP_CWORD]}"',' prev="${COMP_WORDS[COMP_CWORD-1]}"'," if [[ ${COMP_CWORD} -eq 1 ]]; then",` COMPREPLY=( $(compgen -W "${subcommands}" -- "\${cur}") )`," return"," fi"," if [[ ${COMP_CWORD} -eq 2 ]]; then",' case "${prev}" in',...subVerbs.map(([command,verbs])=>` ${command}) COMPREPLY=( $(compgen -W "${verbs.join(" ")}" -- "\${cur}") ) ;;`)," esac"," fi","}",`complete -F ${fn} ${cliName}`,""].join(`
2
+ import{SUBCOMMAND_VERBS,TOP_LEVEL_SUBCOMMANDS}from"./chunk-e1x88j3k.js";import{join}from"path";import{fileURLToPath}from"url";var SHELLS=["bash","zsh","fish"];function isShellKind(value){return SHELLS.some((shell)=>shell===value)}var SHIPPED_COMPLETIONS_DIR=fileURLToPath(new URL("../completions/",import.meta.url));function shippedCompletionsPath(shell,cliName,dir=SHIPPED_COMPLETIONS_DIR){return join(dir,`${cliName}.${shell}`)}function mergeSubVerbs(apiVerbs){let merged={...SUBCOMMAND_VERBS,api:apiVerbs};return Object.keys(merged).sort().map((command)=>[command,merged[command]??[]])}function generateCompletions(shell,cliName,subVerbs){return shell==="bash"?generateBashCompletions(cliName,subVerbs):shell==="zsh"?generateZshCompletions(cliName,subVerbs):generateFishCompletions(cliName,subVerbs)}function generateBashCompletions(cliName,subVerbs){let subcommands=TOP_LEVEL_SUBCOMMANDS.join(" "),fn=`_${cliName}`;return[`# ${cliName} bash completions`,`# Source: ${cliName} completions bash`,"",`${fn}() {`," local cur prev"," COMPREPLY=()",' cur="${COMP_WORDS[COMP_CWORD]}"',' prev="${COMP_WORDS[COMP_CWORD-1]}"'," if [[ ${COMP_CWORD} -eq 1 ]]; then",` COMPREPLY=( $(compgen -W "${subcommands}" -- "\${cur}") )`," return"," fi"," if [[ ${COMP_CWORD} -eq 2 ]]; then",' case "${prev}" in',...subVerbs.map(([command,verbs])=>` ${command}) COMPREPLY=( $(compgen -W "${verbs.join(" ")}" -- "\${cur}") ) ;;`)," esac"," fi","}",`complete -F ${fn} ${cliName}`,""].join(`
3
3
  `)}function generateZshCompletions(cliName,subVerbs){let subcommandsList=TOP_LEVEL_SUBCOMMANDS.map((s)=>`"${s}"`).join(" "),fn=`_${cliName}`;return[`#compdef ${cliName}`,`# ${cliName} zsh completions`,`# Source: ${cliName} completions zsh`,"",`${fn}() {`," local -a subcommands verbs",` subcommands=(${subcommandsList})`,""," if (( CURRENT == 2 )); then"," _describe -t commands 'subcommand' subcommands"," return"," fi",""," verbs=()",' case "${words[2]}" in',...subVerbs.map(([command,verbs])=>` ${command}) verbs=(${verbs.map((v)=>`"${v}"`).join(" ")}) ;;`)," esac"," if (( CURRENT == 3 && ${#verbs} > 0 )); then"," _describe -t verbs 'verb' verbs"," fi","}","","# Autoloaded from $fpath -> run as the completion function;","# sourced directly -> register with compdef instead.",`if [ "\${funcstack[1]}" = "${fn}" ]; then`,` ${fn} "$@"`,"elif (( $+functions[compdef] )); then",` compdef ${fn} ${cliName}`,"fi",""].join(`
4
4
  `)}function generateFishCompletions(cliName,subVerbs){let lines=[...TOP_LEVEL_SUBCOMMANDS.map((s)=>`complete -c ${cliName} -f -n __fish_use_subcommand -a ${s}`),...subVerbs.map(([command,verbs])=>`complete -c ${cliName} -f -n "__fish_seen_subcommand_from ${command}" -a "${verbs.join(" ")}"`)];return`# ${cliName} fish completions
5
5
  # Source: ${cliName} completions fish
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CURRENT_VERSION,repoSlug}from"./chunk-a0ave3g6.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
2
+ import{CURRENT_VERSION,repoSlug}from"./chunk-94zjxcnf.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
+ import{isDev}from"./chunk-prqeddy7.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.242",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.20","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-weixin":"0.0.3",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.ROVE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
3
+ export{package_default,CURRENT_VERSION,PACKAGE_NAME,repoSlug,UPDATE_SCRIPT_URL,UPDATE_COMMAND,owningNpmPrefix,recommendedGlobalInstallCommand,BREAKING_VERSIONS,breakingVersionsCrossed,RELEASE_CHANNELS,DEFAULT_RELEASE_CHANNEL,channelOf,isNewerSemver,compareSemver,checkLatestVersion,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,releasePageUrl};
@@ -0,0 +1,39 @@
1
+ // @bun
2
+ import{invokeVerb}from"./chunk-xkv2vm37.js";import{defaultApiRuntime,loadContext}from"./chunk-c8c44dty.js";import"./chunk-svm809bx.js";import{ensurePluginEnginesLoaded}from"./chunk-h3fckxn3.js";import"./chunk-hr2xky15.js";import"./chunk-p024scd4.js";import"./chunk-808wt4qs.js";import"./chunk-17e2tgyg.js";import"./chunk-cbc1h345.js";import"./chunk-qvfdqrbf.js";import"./chunk-4hestsjp.js";import"./chunk-2bgmby1d.js";import"./chunk-rqyaf0dw.js";import"./chunk-41x1hrqe.js";import"./chunk-5mhvjytn.js";import"./chunk-atn06ncf.js";import"./chunk-qkehg2c1.js";import"./chunk-zx2n95qe.js";import"./chunk-bn73kd6z.js";import"./chunk-yxt1y0n3.js";import"./chunk-cbjh43yc.js";import"./chunk-2apszxn2.js";import"./chunk-sak1tphp.js";import"./chunk-x9s14ppv.js";import"./chunk-rxqdw6s5.js";import"./chunk-4250pw6r.js";import"./chunk-nckmga7j.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-dkgxz9hf.js";import"./chunk-hpay0ax8.js";import"./chunk-g5c5jytr.js";import"./chunk-y8tysjc2.js";import"./chunk-576r5nht.js";import"./chunk-w7zv47mp.js";import"./chunk-2tfnscxk.js";import"./chunk-etfh8f4z.js";import"./chunk-6xppe9bj.js";import{ApiError}from"./chunk-f7zjggfv.js";import"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-yexx8nec.js";import"./chunk-znjcesdr.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import{SUBCOMMAND_VERBS}from"./chunk-e1x88j3k.js";import"./chunk-94zjxcnf.js";import{getSavedRepos}from"./chunk-h9cg0j3a.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-pxk2c2vj.js";import{RoveDaemonClient}from"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import{resolveDaemonHomeDir}from"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveEnv}from"./chunk-nc46gddg.js";import{__commonJS,__toESM}from"./chunk-wqfp8d9w.js";var require_QRMode=__commonJS((exports,module)=>{module.exports={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8}});var require_QR8bitByte=__commonJS((exports,module)=>{var QRMode=require_QRMode();function QR8bitByte(data){this.mode=QRMode.MODE_8BIT_BYTE,this.data=data}QR8bitByte.prototype={getLength:function(){return this.data.length},write:function(buffer){for(var i=0;i<this.data.length;i++)buffer.put(this.data.charCodeAt(i),8)}};module.exports=QR8bitByte});var require_QRMath=__commonJS((exports,module)=>{var QRMath={glog:function(n){if(n<1)throw Error("glog("+n+")");return QRMath.LOG_TABLE[n]},gexp:function(n){while(n<0)n+=255;while(n>=256)n-=255;return QRMath.EXP_TABLE[n]},EXP_TABLE:Array(256),LOG_TABLE:Array(256)};for(i=0;i<8;i++)QRMath.EXP_TABLE[i]=1<<i;var i;for(i=8;i<256;i++)QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];var i;for(i=0;i<255;i++)QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;var i;module.exports=QRMath});var require_QRPolynomial=__commonJS((exports,module)=>{var QRMath=require_QRMath();function QRPolynomial(num,shift){if(num.length===void 0)throw Error(num.length+"/"+shift);var offset=0;while(offset<num.length&&num[offset]===0)offset++;this.num=Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++)this.num[i]=num[i+offset]}QRPolynomial.prototype={get:function(index){return this.num[index]},getLength:function(){return this.num.length},multiply:function(e){var num=Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++)for(var j=0;j<e.getLength();j++)num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));return new QRPolynomial(num,0)},mod:function(e){if(this.getLength()-e.getLength()<0)return this;var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0)),num=Array(this.getLength());for(var i=0;i<this.getLength();i++)num[i]=this.get(i);for(var x=0;x<e.getLength();x++)num[x]^=QRMath.gexp(QRMath.glog(e.get(x))+ratio);return new QRPolynomial(num,0).mod(e)}};module.exports=QRPolynomial});var require_QRMaskPattern=__commonJS((exports,module)=>{module.exports={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7}});var require_QRUtil=__commonJS((exports,module)=>{var QRMode=require_QRMode(),QRPolynomial=require_QRPolynomial(),QRMath=require_QRMath(),QRMaskPattern=require_QRMaskPattern(),QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0)d^=QRUtil.G15<<QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15);return(data<<10|d)^QRUtil.G15_MASK},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0)d^=QRUtil.G18<<QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18);return data<<12|d},getBCHDigit:function(data){var digit=0;while(data!==0)digit++,data>>>=1;return digit},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1]},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2===0;case QRMaskPattern.PATTERN001:return i%2===0;case QRMaskPattern.PATTERN010:return j%3===0;case QRMaskPattern.PATTERN011:return(i+j)%3===0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2===0;case QRMaskPattern.PATTERN101:return i*j%2+i*j%3===0;case QRMaskPattern.PATTERN110:return(i*j%2+i*j%3)%2===0;case QRMaskPattern.PATTERN111:return(i*j%3+(i+j)%2)%2===0;default:throw Error("bad maskPattern:"+maskPattern)}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++)a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));return a},getLengthInBits:function(mode,type){if(1<=type&&type<10)switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw Error("mode:"+mode)}else if(type<27)switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw Error("mode:"+mode)}else if(type<41)switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw Error("mode:"+mode)}else throw Error("type:"+type)},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount(),lostPoint=0,row=0,col=0;for(row=0;row<moduleCount;row++)for(col=0;col<moduleCount;col++){var sameCount=0,dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r)continue;for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c)continue;if(r===0&&c===0)continue;if(dark===qrCode.isDark(row+r,col+c))sameCount++}}if(sameCount>5)lostPoint+=3+sameCount-5}for(row=0;row<moduleCount-1;row++)for(col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count===0||count===4)lostPoint+=3}for(row=0;row<moduleCount;row++)for(col=0;col<moduleCount-6;col++)if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6))lostPoint+=40;for(col=0;col<moduleCount;col++)for(row=0;row<moduleCount-6;row++)if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col))lostPoint+=40;var darkCount=0;for(col=0;col<moduleCount;col++)for(row=0;row<moduleCount;row++)if(qrCode.isDark(row,col))darkCount++;var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;return lostPoint+=ratio*10,lostPoint}};module.exports=QRUtil});var require_QRErrorCorrectLevel=__commonJS((exports,module)=>{module.exports={L:1,M:0,Q:3,H:2}});var require_QRRSBlock=__commonJS((exports,module)=>{var QRErrorCorrectLevel=require_QRErrorCorrectLevel();function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount,this.dataCount=dataCount}QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock===void 0)throw Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);var length=rsBlock.length/3,list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0],totalCount=rsBlock[i*3+1],dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++)list.push(new QRRSBlock(totalCount,dataCount))}return list};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return}};module.exports=QRRSBlock});var require_QRBitBuffer=__commonJS((exports,module)=>{function QRBitBuffer(){this.buffer=[],this.length=0}QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return(this.buffer[bufIndex]>>>7-index%8&1)==1},put:function(num,length){for(var i=0;i<length;i++)this.putBit((num>>>length-i-1&1)==1)},getLengthInBits:function(){return this.length},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex)this.buffer.push(0);if(bit)this.buffer[bufIndex]|=128>>>this.length%8;this.length++}};module.exports=QRBitBuffer});var require_QRCode=__commonJS((exports,module)=>{var QR8bitByte=require_QR8bitByte(),QRUtil=require_QRUtil(),QRPolynomial=require_QRPolynomial(),QRRSBlock=require_QRRSBlock(),QRBitBuffer=require_QRBitBuffer();function QRCode(typeNumber,errorCorrectLevel){this.typeNumber=typeNumber,this.errorCorrectLevel=errorCorrectLevel,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}QRCode.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData),this.dataCache=null},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col)throw Error(row+","+col);return this.modules[row][col]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var typeNumber=1;for(typeNumber=1;typeNumber<40;typeNumber++){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,this.errorCorrectLevel),buffer=new QRBitBuffer,totalDataCount=0;for(var i=0;i<rsBlocks.length;i++)totalDataCount+=rsBlocks[i].dataCount;for(var x=0;x<this.dataList.length;x++){var data=this.dataList[x];buffer.put(data.mode,4),buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber)),data.write(buffer)}if(buffer.getLengthInBits()<=totalDataCount*8)break}this.typeNumber=typeNumber}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17,this.modules=Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++)this.modules[row][col]=null}if(this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(test,maskPattern),this.typeNumber>=7)this.setupTypeNumber(test);if(this.dataCache===null)this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);this.mapData(this.dataCache,maskPattern)},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if(0<=r&&r<=6&&(c===0||c===6)||0<=c&&c<=6&&(r===0||r===6)||2<=r&&r<=4&&2<=c&&c<=4)this.modules[row+r][col+c]=!0;else this.modules[row+r][col+c]=!1}}},getBestMaskPattern:function(){var minLostPoint=0,pattern=0;for(var i=0;i<8;i++){this.makeImpl(!0,i);var lostPoint=QRUtil.getLostPoint(this);if(i===0||minLostPoint>lostPoint)minLostPoint=lostPoint,pattern=i}return pattern},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth),cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs,dark=this.modules[row][col];if(dark)qr_mc.beginFill(0,100),qr_mc.moveTo(x,y),qr_mc.lineTo(x+cs,y),qr_mc.lineTo(x+cs,y+cs),qr_mc.lineTo(x,y+cs),qr_mc.endFill()}}return qr_mc},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!==null)continue;this.modules[r][6]=r%2===0}for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!==null)continue;this.modules[6][c]=c%2===0}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++)for(var j=0;j<pos.length;j++){var row=pos[i],col=pos[j];if(this.modules[row][col]!==null)continue;for(var r=-2;r<=2;r++)for(var c=-2;c<=2;c++)if(Math.abs(r)===2||Math.abs(c)===2||r===0&&c===0)this.modules[row+r][col+c]=!0;else this.modules[row+r][col+c]=!1}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber),mod;for(var i=0;i<18;i++)mod=!test&&(bits>>i&1)===1,this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;for(var x=0;x<18;x++)mod=!test&&(bits>>x&1)===1,this.modules[x%3+this.moduleCount-8-3][Math.floor(x/3)]=mod},setupTypeInfo:function(test,maskPattern){var data=this.errorCorrectLevel<<3|maskPattern,bits=QRUtil.getBCHTypeInfo(data),mod;for(var v=0;v<15;v++)if(mod=!test&&(bits>>v&1)===1,v<6)this.modules[v][8]=mod;else if(v<8)this.modules[v+1][8]=mod;else this.modules[this.moduleCount-15+v][8]=mod;for(var h=0;h<15;h++)if(mod=!test&&(bits>>h&1)===1,h<8)this.modules[8][this.moduleCount-h-1]=mod;else if(h<9)this.modules[8][15-h-1+1]=mod;else this.modules[8][15-h-1]=mod;this.modules[this.moduleCount-8][8]=!test},mapData:function(data,maskPattern){var inc=-1,row=this.moduleCount-1,bitIndex=7,byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col===6)col--;while(!0){for(var c=0;c<2;c++)if(this.modules[row][col-c]===null){var dark=!1;if(byteIndex<data.length)dark=(data[byteIndex]>>>bitIndex&1)===1;var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask)dark=!dark;if(this.modules[row][col-c]=dark,bitIndex--,bitIndex===-1)byteIndex++,bitIndex=7}if(row+=inc,row<0||this.moduleCount<=row){row-=inc,inc=-inc;break}}}}};QRCode.PAD0=236;QRCode.PAD1=17;QRCode.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel),buffer=new QRBitBuffer;for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4),buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber)),data.write(buffer)}var totalDataCount=0;for(var x=0;x<rsBlocks.length;x++)totalDataCount+=rsBlocks[x].dataCount;if(buffer.getLengthInBits()>totalDataCount*8)throw Error("code length overflow. ("+buffer.getLengthInBits()+">"+totalDataCount*8+")");if(buffer.getLengthInBits()+4<=totalDataCount*8)buffer.put(0,4);while(buffer.getLengthInBits()%8!==0)buffer.putBit(!1);while(!0){if(buffer.getLengthInBits()>=totalDataCount*8)break;if(buffer.put(QRCode.PAD0,8),buffer.getLengthInBits()>=totalDataCount*8)break;buffer.put(QRCode.PAD1,8)}return QRCode.createBytes(buffer,rsBlocks)};QRCode.createBytes=function(buffer,rsBlocks){var offset=0,maxDcCount=0,maxEcCount=0,dcdata=Array(rsBlocks.length),ecdata=Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount,ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount),maxEcCount=Math.max(maxEcCount,ecCount),dcdata[r]=Array(dcCount);for(var i=0;i<dcdata[r].length;i++)dcdata[r][i]=255&buffer.buffer[i+offset];offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount),rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1),modPoly=rawPoly.mod(rsPoly);ecdata[r]=Array(rsPoly.getLength()-1);for(var x=0;x<ecdata[r].length;x++){var modIndex=x+modPoly.getLength()-ecdata[r].length;ecdata[r][x]=modIndex>=0?modPoly.get(modIndex):0}}var totalCodeCount=0;for(var y=0;y<rsBlocks.length;y++)totalCodeCount+=rsBlocks[y].totalCount;var data=Array(totalCodeCount),index=0;for(var z=0;z<maxDcCount;z++)for(var s=0;s<rsBlocks.length;s++)if(z<dcdata[s].length)data[index++]=dcdata[s][z];for(var xx=0;xx<maxEcCount;xx++)for(var t=0;t<rsBlocks.length;t++)if(xx<ecdata[t].length)data[index++]=ecdata[t][xx];return data};module.exports=QRCode});var require_main=__commonJS((exports,module)=>{var QRCode=require_QRCode(),QRErrorCorrectLevel=require_QRErrorCorrectLevel(),black="\x1B[40m \x1B[0m",white="\x1B[47m \x1B[0m",toCell=function(isBlack){return isBlack?black:white},repeat=function(color){return{times:function(count){return Array(count).join(color)}}},fill=function(length,value){var arr=Array(length);for(var i=0;i<length;i++)arr[i]=value;return arr};module.exports={error:QRErrorCorrectLevel.L,generate:function(input,opts,cb){if(typeof opts==="function")cb=opts,opts={};var qrcode=new QRCode(-1,this.error);qrcode.addData(input),qrcode.make();var output="";if(opts&&opts.small){var BLACK=!0,WHITE=!1,moduleCount=qrcode.getModuleCount(),moduleData=qrcode.modules.slice(),oddRow=moduleCount%2===1;if(oddRow)moduleData.push(fill(moduleCount,WHITE));var platte={WHITE_ALL:"\u2588",WHITE_BLACK:"\u2580",BLACK_WHITE:"\u2584",BLACK_ALL:" "},borderTop=repeat(platte.BLACK_WHITE).times(moduleCount+3),borderBottom=repeat(platte.WHITE_BLACK).times(moduleCount+3);output+=borderTop+`
3
+ `;for(var row=0;row<moduleCount;row+=2){output+=platte.WHITE_ALL;for(var col=0;col<moduleCount;col++)if(moduleData[row][col]===WHITE&&moduleData[row+1][col]===WHITE)output+=platte.WHITE_ALL;else if(moduleData[row][col]===WHITE&&moduleData[row+1][col]===BLACK)output+=platte.WHITE_BLACK;else if(moduleData[row][col]===BLACK&&moduleData[row+1][col]===WHITE)output+=platte.BLACK_WHITE;else output+=platte.BLACK_ALL;output+=platte.WHITE_ALL+`
4
+ `}if(!oddRow)output+=borderBottom}else{var border=repeat(white).times(qrcode.getModuleCount()+3);output+=border+`
5
+ `,qrcode.modules.forEach(function(row2){output+=white,output+=row2.map(toCell).join(""),output+=white+`
6
+ `}),output+=border}if(cb)cb(output);else console.log(output)},setErrorLevel:function(error){this.error=QRErrorCorrectLevel[error]||this.error}}});import{setTimeout as delay}from"timers/promises";import{basename}from"path";function shortId(taskId){return taskId.slice(-6)}function clip(text,max){let flat=text.replace(/\s+/g," ").trim();return flat.length<=max?flat:`${flat.slice(0,max-1)}\u2026`}function rowDetail(row){let bits=[];if(row.group==="waiting-on-you"&&row.activity)bits.push(row.activity.state.replace(/_/g," "));if(row.pr!==void 0)bits.push(`PR#${row.pr}`);if(row.checkState&&row.checkState!=="none")bits.push(`CI ${row.checkState}`);if(row.report?.summary)bits.push(`\u201C${clip(row.report.summary,48)}\u201D`);return bits.join(" \xB7 ")}function rowLine(row){let detail=rowDetail(row);return`\u2022 ${shortId(row.taskId)} ${clip(row.title||row.branch||"(untitled)",36)}${detail?` \u2014 ${detail}`:""}`}var SECTIONS=[["waiting-on-you","Needs you"],["landing","Ready to merge"],["ready-for-review","To review"],["working","Running"]];function renderStatus(payload){let count=(group)=>payload.tasks.filter((t)=>t.group===group).length,needs=count("waiting-on-you"),merge=count("landing"),review=count("ready-for-review"),running=count("working"),quiet=payload.tasks.length-needs-merge-review-running+(payload.omittedTasks??0);if(payload.tasks.length===0)return"No tasks right now.";let headline=[needs>0?`${needs} need you`:null,merge>0?`${merge} ready to merge`:null,review>0?`${review} to review`:null,`${running} running`,quiet>0?`${quiet} quiet`:null].filter(Boolean).join(" \xB7 "),lines=[needs+merge+review===0?`Nothing needs you. ${headline}`:headline];for(let[group,label]of SECTIONS){let rows=payload.tasks.filter((t)=>t.group===group);if(rows.length===0)continue;lines.push("",`${label}:`);for(let row of rows.slice(0,5))lines.push(rowLine(row));if(rows.length>5)lines.push(` +${rows.length-5} more`)}return lines.join(`
7
+ `)}function toBubbles(text){let pieces=text.trim().split(`
8
+ `).flatMap((line)=>line.match(new RegExp("[\\s\\S]{1,1800}","g"))??[""]),bubbles=[],current=null;for(let piece of pieces)if(current!==null&&current.length+1+piece.length<=1800)current=`${current}
9
+ ${piece}`;else{if(current!==null)bubbles.push(current);current=piece}if(current?.trim())bubbles.push(current);if(bubbles.length<=3)return bubbles;let marker=`\u2026(cut, ${bubbles.slice(3).reduce((n,b)=>n+b.split(`
10
+ `).length,0)} more lines)`,kept=bubbles.slice(0,3),last=kept[2]??"";return kept[2]=`${last.slice(0,1800-marker.length-1)}
11
+ ${marker}`,kept}var MIN_ID_CHARS=4,TAB_RE=/^tab-\d+$/,HELP_TEXT=["Rove commands:","status \u2014 what needs you, what's running","status <repo> \u2014 one repo only","send <id> <text> \u2014 message a task's agent","send <id> tab-2 <text> \u2014 a specific tab","add <repo> <prompt> \u2014 start a new task","<id> is the 6-char code from status."].join(`
12
+ `);function resolveTask(tasks,ref){let needle=ref.toLowerCase(),exact=tasks.find((t)=>t.id.toLowerCase()===needle);if(exact)return{ok:!0,value:exact};if(needle.length<MIN_ID_CHARS)return{ok:!1,reply:`"${ref}" is too short \u2014 use the 6-char code from status.`};let hits=tasks.filter((t)=>t.id.toLowerCase().endsWith(needle));if(hits.length===1&&hits[0])return{ok:!0,value:hits[0]};if(hits.length===0)return{ok:!1,reply:`No task ending in "${ref}". Send "status" for the list.`};return{ok:!1,reply:[`"${ref}" matches ${hits.length} tasks:`,...hits.slice(0,5).map((t)=>`\u2022 ${t.id} ${t.title}`)].join(`
13
+ `)}}function resolveRepo(repos,ref){let unique=[...new Set(repos)],exact=unique.find((r)=>r===ref);if(exact)return{ok:!0,value:exact};let hits=unique.filter((r)=>basename(r).toLowerCase()===ref.toLowerCase());if(hits.length===1&&hits[0])return{ok:!0,value:hits[0]};let names=unique.map((r)=>basename(r)).sort();if(hits.length===0)return{ok:!1,reply:names.length>0?`No repo "${ref}". Known: ${names.join(", ")}`:`No repo "${ref}" \u2014 none saved yet.`};return{ok:!1,reply:[`"${ref}" names ${hits.length} repos; use the full path:`,...hits].join(`
14
+ `)}}function failure(err){if(err instanceof ApiError)return`Failed (${err.code}): ${err.message}`;return`Failed: ${err instanceof Error?err.message:String(err)}`}function head(text){let match=/^(\S+)\s*([\s\S]*)$/.exec(text.trim());return match?[match[1]??"",match[2]??""]:["",""]}async function handleCommand(text,ops){let[word,rest]=head(text);try{switch(word.toLowerCase()){case"":case"help":case"h":case"?":case"\u5E2E\u52A9":return HELP_TEXT;case"status":case"s":case"ls":case"\u72B6\u6001":{if(!rest.trim())return renderStatus(await ops.status(null));let repo=resolveRepo(await ops.repos(),rest.trim());return repo.ok?`${basename(repo.value)}: ${renderStatus(await ops.status(repo.value))}`:repo.reply}case"send":{let[ref,afterRef]=head(rest),[tab,prompt]=head(afterRef);if(!TAB_RE.test(tab))prompt=afterRef,tab="";if(!ref||!prompt.trim())return"Usage: send <id> [tab-N] <text>";let task=resolveTask(await ops.tasks(),ref);if(!task.ok)return task.reply;let result=await ops.send(task.value.id,tab||void 0,prompt.trim()),where=result.tab??tab;return`Sent to ${shortId(task.value.id)} ${task.value.title}${where?` (${where})`:""}${result.started?" \u2014 started a new engine":""}.`}case"add":case"new":{let[repoRef,prompt]=head(rest);if(!repoRef||!prompt.trim())return"Usage: add <repo> <prompt>";let repo=resolveRepo(await ops.repos(),repoRef);if(!repo.ok)return repo.reply;let{taskId}=await ops.add(repo.value,prompt.trim());return`Started task ${shortId(taskId)} in ${basename(repo.value)}. I'll message you when it needs you.`}default:return`Unknown command "${word}".
15
+ ${HELP_TEXT}`}}catch(err){return failure(err)}}import{randomBytes,randomUUID}from"crypto";var ILINK_BASE_URL="https://ilinkai.weixin.qq.com",APP_ID="bot",CHANNEL_VERSION="2.2.0",APP_CLIENT_VERSION=String(131584),BOT_TYPE="3",LONG_POLL_TIMEOUT_MS=35000,API_TIMEOUT_MS=15000,ITEM_TEXT=1,ITEM_VOICE=3,MSG_TYPE_BOT=2,MSG_STATE_FINISH=2,SESSION_EXPIRED=-14,RATE_LIMITED=-2;function resolveIlinkBaseUrl(env=process.env){return(readRoveEnv("WEIXIN_BASE_URL",env)??ILINK_BASE_URL).replace(/\/+$/,"")}function classifyIlink(resp){let ret=resp.ret??0,errcode=resp.errcode??0;if(ret===0&&errcode===0)return"ok";if(ret===SESSION_EXPIRED||errcode===SESSION_EXPIRED)return"session-expired";if(ret===RATE_LIMITED||errcode===RATE_LIMITED){let msg=(resp.errmsg??resp.msg??"").toLowerCase();return msg==="unknown error"||msg==="prepare failed"?"session-expired":"rate-limited"}return"error"}function describeIlink(resp){return`ret=${resp.ret??0} errcode=${resp.errcode??0}${resp.errmsg||resp.msg?` (${resp.errmsg??resp.msg})`:""}`}function messageText(message){let items=message.item_list??[];for(let item of items)if(item.type===ITEM_TEXT)return(item.text_item?.text??"").trim();for(let item of items)if(item.type===ITEM_VOICE&&item.voice_item?.text)return item.voice_item.text.trim();return""}function isDirectUserMessage(message){return!message.room_id&&!message.chat_room_id&&message.message_type!==MSG_TYPE_BOT}async function requestJson(fetchFn,url,init,timeoutMs){let res=await fetchFn(url,{...init,signal:AbortSignal.timeout(timeoutMs)}),raw=await res.text();if(!res.ok)throw Error(`iLink HTTP ${res.status}`);return JSON.parse(raw)}function isTimeout(err){return err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")}function loginHeaders(){return{"iLink-App-Id":APP_ID,"iLink-App-ClientVersion":APP_CLIENT_VERSION}}async function fetchLoginQr(baseUrl,fetchFn=fetch){let resp=await requestJson(fetchFn,`${baseUrl}/ilink/bot/get_bot_qrcode?bot_type=${BOT_TYPE}`,{method:"GET",headers:loginHeaders()},LONG_POLL_TIMEOUT_MS);if(!resp.qrcode)throw Error("iLink returned no QR code");return{qrcode:resp.qrcode,url:resp.qrcode_img_content||resp.qrcode}}async function pollLoginStatus(baseUrl,qrcode,fetchFn=fetch){let resp;try{resp=await requestJson(fetchFn,`${baseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(qrcode)}`,{method:"GET",headers:loginHeaders()},LONG_POLL_TIMEOUT_MS)}catch(err){if(isTimeout(err))return{status:"wait"};throw err}switch(resp.status){case"scaned":case"expired":return{status:resp.status};case"scaned_but_redirect":return resp.redirect_host?{status:"redirect",baseUrl:`https://${resp.redirect_host}`}:{status:"scaned"};case"confirmed":if(!resp.ilink_bot_id||!resp.bot_token)throw Error("iLink confirmed the login without credentials");return{status:"confirmed",accountId:resp.ilink_bot_id,token:resp.bot_token,baseUrl:(resp.baseurl||baseUrl).replace(/\/+$/,""),userId:resp.ilink_user_id??""};default:return{status:"wait"}}}class IlinkClient{baseUrl;token;fetchFn;constructor(baseUrl,token,fetchFn=fetch){this.baseUrl=baseUrl;this.token=token;this.fetchFn=fetchFn}post(endpoint,payload,timeoutMs){let body=JSON.stringify({...payload,base_info:{channel_version:CHANNEL_VERSION}});return requestJson(this.fetchFn,`${this.baseUrl}/${endpoint}`,{method:"POST",headers:{"Content-Type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${this.token}`,"X-WECHAT-UIN":Buffer.from(String(randomBytes(4).readUInt32BE(0))).toString("base64"),...loginHeaders()},body},timeoutMs)}async getUpdates(syncBuf,timeoutMs=LONG_POLL_TIMEOUT_MS){try{return await this.post("ilink/bot/getupdates",{get_updates_buf:syncBuf},timeoutMs)}catch(err){if(isTimeout(err))return{ret:0,msgs:[],get_updates_buf:syncBuf};throw err}}sendText(to,text,contextToken){return this.post("ilink/bot/sendmessage",{msg:{from_user_id:"",to_user_id:to,client_id:`rove-weixin-${randomUUID()}`,message_type:MSG_TYPE_BOT,message_state:MSG_STATE_FINISH,item_list:[{type:ITEM_TEXT,text_item:{text}}],...contextToken?{context_token:contextToken}:{}}},API_TIMEOUT_MS)}}var PUSH_LABEL={"waiting-on-you":"Needs you",landing:"Ready to merge","ready-for-review":"Ready for review"};class GroupTracker{settled=new Map;pending=new Map;seeded=!1;observe(rows){let arrivals=[],present=new Set;for(let row of rows){if(present.add(row.taskId),!this.seeded){this.settled.set(row.taskId,row.group);continue}if(this.settled.get(row.taskId)===row.group){this.pending.delete(row.taskId);continue}if(this.pending.get(row.taskId)!==row.group){this.pending.set(row.taskId,row.group);continue}if(this.pending.delete(row.taskId),this.settled.set(row.taskId,row.group),PUSH_LABEL[row.group])arrivals.push(row)}this.seeded=!0;for(let id of[...this.settled.keys()])if(!present.has(id))this.settled.delete(id);for(let id of[...this.pending.keys()])if(!present.has(id))this.pending.delete(id);return arrivals}}function renderArrivals(rows){let lines=[];for(let row of rows)lines.push(`${PUSH_LABEL[row.group]??row.group}:`,rowLine(row));let first=rows[0];if(first?.group==="waiting-on-you")lines.push(`Reply: send ${first.taskId.slice(-6)} <text>`);return lines.join(`
16
+ `)}import{appendFileSync,mkdirSync,readFileSync,renameSync,rmSync,writeFileSync}from"fs";import{join}from"path";var DIR_MODE=448,FILE_MODE=384,REJECTED_CAP=10;function readJson(path){try{return JSON.parse(readFileSync(path,"utf8"))}catch{return null}}function writeJson(path,value){let tmp=`${path}.${process.pid}.tmp`;writeFileSync(tmp,`${JSON.stringify(value,null,2)}
17
+ `,{mode:FILE_MODE}),renameSync(tmp,path)}function ensureDir(dir){mkdirSync(dir,{recursive:!0,mode:DIR_MODE})}class WeixinStore{dir;constructor(homeDir){this.dir=join(resolveDaemonHomeDir(homeDir),ROVE_STATE_DIR_BASENAME,"weixin")}get accountPath(){return join(this.dir,"account.json")}get statePath(){return join(this.dir,"state.json")}get undeliveredPath(){return join(this.dir,"undelivered.jsonl")}readAccount(){let raw=readJson(this.accountPath);if(!raw||typeof raw.accountId!=="string"||typeof raw.token!=="string"||!raw.accountId||!raw.token)return null;return{accountId:raw.accountId,token:raw.token,baseUrl:typeof raw.baseUrl==="string"&&raw.baseUrl?raw.baseUrl:"",ownerUserId:typeof raw.ownerUserId==="string"?raw.ownerUserId:"",allow:Array.isArray(raw.allow)?raw.allow.filter((id)=>typeof id==="string"):[],savedAt:typeof raw.savedAt==="string"?raw.savedAt:""}}writeAccount(account){ensureDir(this.dir),writeJson(this.accountPath,account)}clearAccount(){let had=this.readAccount()!==null;return rmSync(this.accountPath,{force:!0}),rmSync(this.statePath,{force:!0}),had}readState(accountId){let raw=readJson(this.statePath);if(!raw||raw.accountId!==accountId)return{accountId,syncBuf:"",peers:{},rejected:[]};return{accountId,syncBuf:typeof raw.syncBuf==="string"?raw.syncBuf:"",peers:raw.peers&&typeof raw.peers==="object"?raw.peers:{},rejected:Array.isArray(raw.rejected)?raw.rejected:[]}}writeState(state){ensureDir(this.dir),writeJson(this.statePath,{...state,rejected:state.rejected.slice(0,REJECTED_CAP)})}appendUndelivered(entry){ensureDir(this.dir),appendFileSync(this.undeliveredPath,`${JSON.stringify(entry)}
18
+ `,{mode:FILE_MODE})}readUndelivered(){let text;try{text=readFileSync(this.undeliveredPath,"utf8")}catch{return[]}let entries=[];for(let line of text.split(`
19
+ `)){if(!line.trim())continue;try{entries.push(JSON.parse(line))}catch{}}return entries}}function isAllowedSender(account,userId){return userId!==""&&(userId===account.ownerUserId||account.allow.includes(userId))}var REPLY_WINDOW_MS=86400000,ACCOUNT_RECHECK_MS=5000,RETRY_MS=2000,BACKOFF_MS=30000,MAX_CONSECUTIVE_FAILURES=3,EXPIRED_PAUSE_MS=600000,BUBBLE_GAP_MS=300,DEFAULT_NOTIFY_TICK_MS=20000,SEEN_CAP=256;function redact(id){return id.length>8?`${id.slice(0,8)}\u2026`:id}function startWeixinBridge(deps){let now=deps.now??Date.now,pollTimeoutMs=deps.pollTimeoutMs??LONG_POLL_TIMEOUT_MS,stopped=!1,account=deps.store.readAccount(),client=null,state=null,seen=new Set,tracker=new GroupTracker,sleep=(ms)=>delay(ms,void 0,{ref:!1});async function pause(ms){let before=account?.token,until=now()+ms;while(!stopped&&now()<until)if(await sleep(Math.min(ACCOUNT_RECHECK_MS,until-now())),deps.store.readAccount()?.token!==before)return}function saveState(next){state=next,deps.store.writeState(next)}function refreshAccount(){let next=deps.store.readAccount();if(!next){let wasBound=account!==null;if(account=null,client=null,state=null,wasBound)deps.log("weixin","unbound \u2014 stopped polling"),deps.onUnbound?.();return!1}if(!client||!account||next.token!==account.token||next.accountId!==account.accountId)client=new IlinkClient(next.baseUrl||ILINK_BASE_URL,next.token,deps.fetch),state=deps.store.readState(next.accountId),deps.log("weixin",`bound to ${redact(next.accountId)} \u2014 polling`);return account=next,!0}function recordUndelivered(to,reason,text){deps.store.appendUndelivered({at:new Date(now()).toISOString(),to,reason,text}),deps.log("weixin",`push to ${redact(to)} not delivered: ${reason}`)}async function deliver(to,text){if(!client||!state)return!1;let bubbles=toBubbles(text);for(let i=0;i<bubbles.length;i++){let bubble=bubbles[i]??"",token=state.peers[to]?.contextToken??null,retried=!1;for(;;){let resp;try{resp=await client.sendText(to,bubble,token)}catch(err){return recordUndelivered(to,`network: ${err instanceof Error?err.message:String(err)}`,bubbles.slice(i).join(`
20
+ `)),!1}let outcome=classifyIlink(resp);if(outcome==="ok")break;if(!retried&&outcome==="session-expired"&&token){retried=!0,token=null;continue}if(!retried&&outcome==="rate-limited"){retried=!0,await sleep(RETRY_MS);continue}let hint=outcome==="session-expired"?" \u2014 they need to message the bot first":"";return recordUndelivered(to,`iLink refused: ${describeIlink(resp)}${hint}`,bubbles.slice(i).join(`
21
+ `)),!1}if(i<bubbles.length-1)await sleep(BUBBLE_GAP_MS)}return!0}async function handleInbound(message){if(!account||!state)return;let from=message.from_user_id?.trim()??"";if(!from||from===account.accountId||!isDirectUserMessage(message))return;let id=message.message_id===void 0?"":String(message.message_id);if(id){if(seen.has(id))return;if(seen.add(id),seen.size>SEEN_CAP)seen.delete(seen.values().next().value??"")}if(!isAllowedSender(account,from)){deps.log("weixin",`dropped a message from unlisted sender ${redact(from)}`),saveState({...state,rejected:[{userId:from,at:now()},...state.rejected.filter((r)=>r.userId!==from)]});return}let peer=state.peers[from];saveState({...state,peers:{...state.peers,[from]:{contextToken:message.context_token||peer?.contextToken,lastInboundAt:now()}}});let text=messageText(message),reply=text?await handleCommand(text,deps.ops):"Text messages only. Send help for commands.";await deliver(from,reply)}async function pollLoop(){let failures=0;while(!stopped){if(!refreshAccount()||!client||!state){await pause(ACCOUNT_RECHECK_MS);continue}let resp;try{resp=await client.getUpdates(state.syncBuf,pollTimeoutMs)}catch(err){if(failures++,deps.log("weixin",`getupdates failed (${failures}): ${err instanceof Error?err.message:String(err)}`),await pause(failures>=MAX_CONSECUTIVE_FAILURES?BACKOFF_MS:RETRY_MS),failures>=MAX_CONSECUTIVE_FAILURES)failures=0;continue}let outcome=classifyIlink(resp);if(outcome==="session-expired"){deps.log("weixin","binding expired \u2014 run `rove weixin login` again; pausing 10m"),await pause(EXPIRED_PAUSE_MS);continue}if(outcome!=="ok"){if(failures++,deps.log("weixin",`getupdates refused: ${describeIlink(resp)}`),await pause(failures>=MAX_CONSECUTIVE_FAILURES?BACKOFF_MS:RETRY_MS),failures>=MAX_CONSECUTIVE_FAILURES)failures=0;continue}failures=0;for(let message of resp.msgs??[])try{await handleInbound(message)}catch(err){deps.log("weixin",`inbound failed: ${err instanceof Error?err.message:String(err)}`)}if(state&&resp.get_updates_buf&&resp.get_updates_buf!==state.syncBuf)saveState({...state,syncBuf:resp.get_updates_buf})}}async function push(text){if(!account||!state)return;let targets=[...new Set([account.ownerUserId,...account.allow].filter(Boolean))];for(let to of targets){let last=state.peers[to]?.lastInboundAt;if(last===void 0||now()-last>REPLY_WINDOW_MS){recordUndelivered(to,last===void 0?"no message from this user yet":"reply window closed (>24h since their last message)",text);continue}await deliver(to,text)}}let notifying=!1;async function notifyTick(){if(notifying||stopped||!account)return;notifying=!0;try{let arrivals=tracker.observe((await deps.ops.status(null)).tasks);if(arrivals.length>0)await push(renderArrivals(arrivals))}catch(err){deps.log("weixin",`notify tick failed: ${err instanceof Error?err.message:String(err)}`)}finally{notifying=!1}}pollLoop().catch((err)=>deps.log("weixin",`poll loop died: ${err instanceof Error?err.message:String(err)}`));let notifyTimer=setInterval(()=>void notifyTick(),deps.notifyTickMs??DEFAULT_NOTIFY_TICK_MS);return notifyTimer.unref?.(),notifyTick(),{isBound:()=>account!==null,stop:()=>{stopped=!0,clearInterval(notifyTimer)}}}var STATUS_TASK_LIMIT=500;function stringField(value,key){if(value&&typeof value==="object"&&key in value){let field=Reflect.get(value,key);if(typeof field==="string")return field}return}async function liveTasks(client){let{tasks}=await client.request("task.list");return tasks.filter((t)=>t.deletion?.phase!=="queued"&&t.deletion?.phase!=="running")}function createRoveOps(client){return{status:async(repo)=>(await loadContext(client,defaultApiRuntime,{repo,limit:STATUS_TASK_LIMIT})).payload,tasks:async()=>(await liveTasks(client)).map((t)=>({id:t.id,title:t.title,repo:t.repo})),repos:async()=>[...new Set([...getSavedRepos(),...(await liveTasks(client)).map((t)=>t.repo)])],send:async(taskId,tab,prompt)=>{let result=await invokeVerb("send",["--task-id",taskId,...tab?["--tab",tab]:[],"--plain","--prompt",prompt],{client}),landedTab=stringField(result,"session")?.split("::")[1],started=Boolean(result&&typeof result==="object"&&Reflect.get(result,"started")===!0);return{...landedTab?{tab:landedTab}:{},started}},add:async(repo,prompt)=>{ensurePluginEnginesLoaded();let result=await invokeVerb("add",["--repo",repo,"--prompt",prompt],{client}),taskId=stringField(result,"taskId");if(!taskId)throw Error("add returned no task id");return{taskId}}}}function createWeixinChannel(){let bridge=null;return{async start(ctx){let client=new RoveDaemonClient(ctx.socketPath);try{await client.connect()}catch(err){ctx.log("weixin",`could not reach the daemon socket: ${err instanceof Error?err.message:String(err)}`);return}bridge=startWeixinBridge({store:new WeixinStore,ops:createRoveOps(client),log:(event,message)=>ctx.log(event,message),onUnbound:()=>ctx.keepAliveChanged()})},stop:()=>bridge?.stop(),keepAlive:()=>bridge?.isBound()??!1}}import{setTimeout as delay2}from"timers/promises";var import_qrcode_terminal=__toESM(require_main(),1);var MAX_QR_REFRESHES=3,DEFAULT_TIMEOUT_MS=480000,POLL_GAP_MS=1000;async function runQrLogin(store,baseUrl,io,fetchFn=fetch,timeoutMs=DEFAULT_TIMEOUT_MS){let qr=await fetchLoginQr(baseUrl,fetchFn);io.say("Scan with WeChat (\u5FAE\u4FE1 \u2192 \u626B\u4E00\u626B), then confirm on the phone:"),io.showQr(qr.url);let pollBase=baseUrl,refreshes=0,announcedScan=!1,deadline=io.now()+timeoutMs;while(io.now()<deadline){let status=await pollLoginStatus(pollBase,qr.qrcode,fetchFn).catch(()=>({status:"wait"}));switch(status.status){case"scaned":if(!announcedScan)io.say("Scanned \u2014 confirm on your phone\u2026");announcedScan=!0;break;case"redirect":pollBase=status.baseUrl;break;case"expired":if(refreshes++,refreshes>MAX_QR_REFRESHES)return{ok:!1,reason:"the QR code expired too many times"};io.say(`QR expired \u2014 here is a new one (${refreshes}/${MAX_QR_REFRESHES}):`),qr=await fetchLoginQr(baseUrl,fetchFn),pollBase=baseUrl,announcedScan=!1,io.showQr(qr.url);break;case"confirmed":{let previous=store.readAccount(),account={accountId:status.accountId,token:status.token,baseUrl:status.baseUrl,ownerUserId:status.userId,allow:previous?.accountId===status.accountId?previous.allow:[],savedAt:new Date(io.now()).toISOString()};return store.writeAccount(account),{ok:!0,account}}case"wait":break}await io.sleep(POLL_GAP_MS)}return{ok:!1,reason:"timed out waiting for the scan"}}var CLI_NAME=ROVE_PRODUCT_NAME,WEIXIN_USAGE=[`Usage: ${CLI_NAME} weixin <login|logout|status|allow|deny>`,"","Talk to Rove from WeChat (\u5FAE\u4FE1): ask for status, message a task's agent,","start a task, and get pinged when a task needs you. The daemon must be","running for messages to flow.","","Commands:"," login Show a QR code; scan it in WeChat to bind (re-run to re-bind)"," logout Remove the binding and its credentials"," status Binding, allowed senders, reply windows, undelivered pushes"," allow <user-id> Let another WeChat user command Rove (ids: see status)"," deny <user-id> Revoke a user added with allow",""].join(`
22
+ `);function usageError(message){process.stderr.write(`${CLI_NAME} weixin: ${message}
23
+
24
+ ${WEIXIN_USAGE}
25
+ `),process.exit(2)}function fail(message){process.stderr.write(`${CLI_NAME} weixin: ${message}
26
+ `),process.exit(1)}function age(ms){let m=Math.floor(ms/60000);if(m<60)return`${m}m ago`;let h=Math.floor(m/60);return h<48?`${h}h ago`:`${Math.floor(h/24)}d ago`}async function runWeixinCli(argv){let[verb,arg]=argv;if(!verb||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${WEIXIN_USAGE}
27
+ `);return}if(!SUBCOMMAND_VERBS.weixin.includes(verb))usageError(`unknown verb "${verb}"`);let store=new WeixinStore;switch(verb){case"login":return await login(store);case"logout":process.stdout.write(store.clearAccount()?`WeChat binding removed.
28
+ `:`No WeChat binding to remove.
29
+ `);return;case"status":return await status(store);case"allow":case"deny":return editAllow(store,verb,arg);default:usageError(`"${verb}" has no handler`)}}async function login(store){let result=await runQrLogin(store,resolveIlinkBaseUrl(),{showQr:(url)=>{import_qrcode_terminal.default.generate(url,{small:!0},(art)=>process.stdout.write(`${art}
30
+ `)),process.stdout.write(`Or open: ${url}
31
+ `)},say:(line)=>process.stdout.write(`${line}
32
+ `),sleep:(ms)=>delay2(ms),now:Date.now}).catch((err)=>fail(`login failed: ${err instanceof Error?err.message:String(err)}`));if(!result.ok)fail(`login failed: ${result.reason}`);process.stdout.write(["Bound. Send the bot `help` from WeChat to try it.",`Credentials: ${store.accountPath} (owner-only)`,await daemonRunning()?"The running daemon picks this up within seconds.":`The daemon is not running \u2014 start it with \`${CLI_NAME} daemon start\`.`,""].join(`
33
+ `))}async function daemonRunning(){let client=await connectIfRunning().catch(()=>null);return client?.close(),client!==null}async function status(store){let account=store.readAccount();if(!account){process.stdout.write(`Not bound. Run \`${CLI_NAME} weixin login\`.
34
+ `);return}let state=store.readState(account.accountId),now=Date.now(),lines=[`Bound to bot ${account.accountId} since ${account.savedAt||"unknown"}`,`Daemon: ${await daemonRunning()?"running":`not running \u2014 \`${CLI_NAME} daemon start\``}`,`Owner: ${account.ownerUserId||"(unknown \u2014 re-run login)"}`,`Allowed: ${account.allow.length>0?account.allow.join(", "):"owner only"}`],peers=Object.entries(state.peers);if(peers.length>0){lines.push("Reply windows:");for(let[id,peer]of peers)lines.push(` ${id} last message ${age(now-peer.lastInboundAt)} \u2014 ${now-peer.lastInboundAt<=REPLY_WINDOW_MS?"open":"closed"}`)}if(state.rejected.length>0){lines.push(`Refused senders (\`${CLI_NAME} weixin allow <id>\` to let one in):`);for(let r of state.rejected)lines.push(` ${r.userId} ${age(now-r.at)}`)}let undelivered=store.readUndelivered();if(undelivered.length>0){let last=undelivered[undelivered.length-1];if(lines.push(`Undelivered pushes: ${undelivered.length} (${store.undeliveredPath})`),last)lines.push(` latest ${last.at}: ${last.reason}`)}process.stdout.write(`${lines.join(`
35
+ `)}
36
+ `)}function editAllow(store,verb,userId){if(!userId)usageError(`${verb} needs a WeChat user id (see \`${CLI_NAME} weixin status\`)`);let account=store.readAccount();if(!account)fail(`not bound \u2014 run \`${CLI_NAME} weixin login\` first`);let allow=verb==="allow"?[...new Set([...account.allow,userId])]:account.allow.filter((id)=>id!==userId);store.writeAccount({...account,allow}),process.stdout.write(verb==="allow"?`Allowed ${userId}.
37
+ `:allow.length===account.allow.length?`${userId} was not on the list.
38
+ `:`Removed ${userId}.
39
+ `)}var weixin={id:"weixin",createChannel:createWeixinChannel,runCli:runWeixinCli},src_default=weixin;export{src_default as default};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{$jsx,$jsxs,ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useRenderer,useT,useTheme}from"./chunk-g0eygcnq.js";import"./chunk-80ydqr3s.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-764bsyb0.js";import"./chunk-4xj52nx1.js";import"./chunk-atn06ncf.js";import"./chunk-nckmga7j.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-a0ave3g6.js";import"./chunk-40dgv828.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:`${UPDATE_COMMAND} -s -- ${selected.version}`})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
2
+ import{$jsx,$jsxs,ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useRenderer,useT,useTheme}from"./chunk-hg72x88m.js";import"./chunk-z6acdd5c.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-764bsyb0.js";import"./chunk-c84a6t3t.js";import"./chunk-atn06ncf.js";import"./chunk-nckmga7j.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-dgs0m8r4.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-96cjpssp.js";import"./chunk-9w5g7frx.js";import"./chunk-gvrtrvnz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,UPDATE_COMMAND,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries}from"./chunk-94zjxcnf.js";import"./chunk-40dgv828.js";import"./chunk-7q43tysm.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-snhcvjdb.js";import"./chunk-zt49bbg9.js";import"./chunk-nhakrm1f.js";import"./chunk-adkva3ep.js";import"./chunk-0422g8ac.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:`${UPDATE_COMMAND} -s -- ${selected.version}`})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recommendedGlobalInstallCommand}from"./chunk-a0ave3g6.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
2
+ import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recommendedGlobalInstallCommand}from"./chunk-94zjxcnf.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
3
3
  `)}
4
4
  export{updaterShell,updaterShellFailureHint};