@sma1lboy/rove 0.9.176 → 0.9.177
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/chunk-0c3pff95.js +2 -0
- package/dist/cli/{chunk-nbqetnzt.js → chunk-0s7e3cnc.js} +2 -2
- package/dist/cli/{chunk-95ymwsma.js → chunk-1ajvv66w.js} +1 -1
- package/dist/cli/chunk-1b0cmce4.js +2 -0
- package/dist/cli/{chunk-kes8k7gd.js → chunk-364q4ak8.js} +1 -1
- package/dist/cli/chunk-534se0f6.js +4 -0
- package/dist/cli/chunk-55qxr553.js +2 -0
- package/dist/cli/{chunk-c8qp0sy8.js → chunk-5msatcjn.js} +1 -1
- package/dist/cli/chunk-5rta19wp.js +3 -0
- package/dist/cli/{chunk-v7mrhwk1.js → chunk-5zh5fcpe.js} +1 -1
- package/dist/cli/chunk-63wmhbqs.js +3 -0
- package/dist/cli/{chunk-hz25s1jj.js → chunk-67jyf8x5.js} +1 -1
- package/dist/cli/{chunk-7an5n9mk.js → chunk-6xwg11k1.js} +1 -1
- package/dist/cli/{chunk-q3m9dzxf.js → chunk-71g9dn38.js} +1 -1
- package/dist/cli/chunk-77m8h1x8.js +2 -0
- package/dist/cli/{chunk-dsnph7ht.js → chunk-7r17j4te.js} +1 -1
- package/dist/cli/chunk-7w2vcjst.js +2 -0
- package/dist/cli/{chunk-14gcp2af.js → chunk-80hf0bbr.js} +9 -9
- package/dist/cli/chunk-81p6mm0p.js +3 -0
- package/dist/cli/{chunk-jfg12mxf.js → chunk-8mn798a6.js} +1 -1
- package/dist/cli/chunk-8npdrpq2.js +4 -0
- package/dist/cli/{chunk-sxpwjce6.js → chunk-8p120gdr.js} +7 -7
- package/dist/cli/{chunk-6zre8p23.js → chunk-8zn7pdc2.js} +1 -1
- package/dist/cli/{chunk-vwjzw4e5.js → chunk-92d2t5sk.js} +1 -1
- package/dist/cli/{chunk-7rpm6k3k.js → chunk-94eb11hz.js} +1 -1
- package/dist/cli/{chunk-acmzdf15.js → chunk-9gezfdvn.js} +1 -1
- package/dist/cli/{chunk-edz3rt42.js → chunk-9sa6vtp0.js} +1 -1
- package/dist/cli/{chunk-b6aadyde.js → chunk-ajtxh7kg.js} +1 -1
- package/dist/cli/{chunk-sc1jq2zy.js → chunk-b3xxh6v9.js} +2 -2
- package/dist/cli/{chunk-w6z05g8a.js → chunk-b5mbpv97.js} +1 -1
- package/dist/cli/chunk-ba4c8qjw.js +2 -0
- package/dist/cli/{chunk-x8h7b96n.js → chunk-bdgwqx8f.js} +1 -1
- package/dist/cli/{chunk-w469vwsm.js → chunk-bkm7vxr5.js} +1 -1
- package/dist/cli/chunk-ccwc3h8y.js +2 -0
- package/dist/cli/{chunk-fg1k7p5r.js → chunk-chfbbmf9.js} +1 -1
- package/dist/cli/chunk-cv6zwad5.js +2 -0
- package/dist/cli/chunk-d608mvsf.js +2 -0
- package/dist/cli/chunk-d7fk35g9.js +2 -0
- package/dist/cli/{chunk-z4zqbpnr.js → chunk-d9y4wvpj.js} +1 -1
- package/dist/cli/{chunk-wn8zhs65.js → chunk-dj5qqh6n.js} +1 -1
- package/dist/cli/{chunk-st3x0ehf.js → chunk-ea9t4hh5.js} +4 -4
- package/dist/cli/{chunk-f5qab80g.js → chunk-eg8ns7p3.js} +3 -3
- package/dist/cli/chunk-ejqs2ta9.js +3 -0
- package/dist/cli/{chunk-6yhtfs6j.js → chunk-emkfynn5.js} +1 -1
- package/dist/cli/{chunk-yw4cj66m.js → chunk-esgxxnwn.js} +1 -1
- package/dist/cli/chunk-f10n6063.js +3 -0
- package/dist/cli/{chunk-eqfprq4t.js → chunk-fbc5d1fq.js} +1 -1
- package/dist/cli/chunk-fczqwtmq.js +3 -0
- package/dist/cli/{chunk-0xqpzy2b.js → chunk-fg75vvv7.js} +1 -1
- package/dist/cli/chunk-g7baby60.js +3 -0
- package/dist/cli/chunk-garjd34w.js +2 -0
- package/dist/cli/{chunk-32xxbweh.js → chunk-ge7bva0a.js} +1 -1
- package/dist/cli/{chunk-vkzy1j14.js → chunk-gs4nhjah.js} +2 -2
- package/dist/cli/chunk-hcsfp7z7.js +2 -0
- package/dist/cli/{chunk-jywrajew.js → chunk-hfpmeck1.js} +1 -1
- package/dist/cli/{chunk-592kjpyz.js → chunk-jg61s3ce.js} +1 -1
- package/dist/cli/chunk-khsq49yp.js +2 -0
- package/dist/cli/{chunk-4g18ynjm.js → chunk-km4hx6kc.js} +1 -1
- package/dist/cli/{chunk-8v58vj5w.js → chunk-ksfqd3sm.js} +1 -1
- package/dist/cli/{chunk-ct2tf2t9.js → chunk-kyr0cyq1.js} +1 -1
- package/dist/cli/{chunk-js6nktck.js → chunk-mwzmw8q4.js} +1 -1
- package/dist/cli/{chunk-p1x376mx.js → chunk-n3b6yr9e.js} +1 -1
- package/dist/cli/chunk-ndtbxgyp.js +2 -0
- package/dist/cli/chunk-ndvccptj.js +8 -0
- package/dist/cli/{chunk-9v1sa0t2.js → chunk-pcrv3eyw.js} +2 -2
- package/dist/cli/{chunk-61xhnc6p.js → chunk-pz5y8f3r.js} +1 -1
- package/dist/cli/{chunk-fyvef32b.js → chunk-r0hekyyy.js} +1 -1
- package/dist/cli/{chunk-64tw0fqp.js → chunk-r2qn2k6r.js} +1 -1
- package/dist/cli/chunk-re5ke4fz.js +4 -0
- package/dist/cli/chunk-rmn9d90r.js +3 -0
- package/dist/cli/{chunk-k1k62hh8.js → chunk-s72y2s88.js} +1 -1
- package/dist/cli/chunk-s9h4m4k2.js +2 -0
- package/dist/cli/{chunk-s73wg3kw.js → chunk-w2d429hk.js} +1 -1
- package/dist/cli/chunk-wvb1f6pt.js +2 -0
- package/dist/cli/{chunk-26ta488k.js → chunk-wvq6kgcp.js} +2 -2
- package/dist/cli/chunk-xrqaqj84.js +2 -0
- package/dist/cli/{chunk-zqxynd2e.js → chunk-y13681dw.js} +1 -1
- package/dist/cli/{chunk-x23p7asn.js → chunk-y8dn3rez.js} +1 -1
- package/dist/cli/chunk-ydhngxy3.js +2 -0
- package/dist/cli/chunk-yvmz8cts.js +4 -0
- package/dist/cli/index.js +7 -7
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/rove.js +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-01s8k0kg.js +0 -2
- package/dist/cli/chunk-1452mw6e.js +0 -2
- package/dist/cli/chunk-1anv5sx4.js +0 -2
- package/dist/cli/chunk-1vt2mxv0.js +0 -2
- package/dist/cli/chunk-2fw5yz69.js +0 -4
- package/dist/cli/chunk-5rsttrmg.js +0 -2
- package/dist/cli/chunk-6ssj0adp.js +0 -3
- package/dist/cli/chunk-71wagt0n.js +0 -2
- package/dist/cli/chunk-72n17wac.js +0 -2
- package/dist/cli/chunk-7ezddcvf.js +0 -2
- package/dist/cli/chunk-8002w78e.js +0 -2
- package/dist/cli/chunk-97hd11fg.js +0 -8
- package/dist/cli/chunk-fysbm6gg.js +0 -2
- package/dist/cli/chunk-g35aq0ka.js +0 -2
- package/dist/cli/chunk-hrrv8y83.js +0 -3
- package/dist/cli/chunk-jk7gega5.js +0 -2
- package/dist/cli/chunk-kwbkdfvb.js +0 -3
- package/dist/cli/chunk-m8f8gv2w.js +0 -2
- package/dist/cli/chunk-ndm62s2f.js +0 -3
- package/dist/cli/chunk-nk21m1v0.js +0 -4
- package/dist/cli/chunk-p4yf9ym8.js +0 -3
- package/dist/cli/chunk-q16da5py.js +0 -2
- package/dist/cli/chunk-qhkag7ad.js +0 -3
- package/dist/cli/chunk-snydvexr.js +0 -2
- package/dist/cli/chunk-vra4m3zy.js +0 -4
- package/dist/cli/chunk-vrx73eyf.js +0 -4
- package/dist/cli/chunk-xzargt6y.js +0 -2
- package/dist/cli/chunk-ygtkanm0.js +0 -3
- package/dist/cli/chunk-z0ds727b.js +0 -2
- package/dist/cli/chunk-zwkedme6.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{buildPaneArgv}from"./chunk-1x7xjh3h.js";import{PluginCliError,installPlugin,linkPlugin}from"./chunk-
|
|
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-
|
|
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-9xkc34rf.js");await searchMarketplace(args.find((a)=>!a.startsWith("-")));return}case"outdated":{let{printOutdated}=await import("./chunk-
|
|
2
|
+
import{buildPaneArgv}from"./chunk-1x7xjh3h.js";import{PluginCliError,installPlugin,linkPlugin}from"./chunk-71g9dn38.js";import{resolvePluginBinPath}from"./chunk-7nndmapz.js";import{buildPluginEnv}from"./chunk-jpdf97cx.js";import{currentPluginPlatform,loadPluginRegistry,pluginCheckoutDir,pluginConfigDir,pluginLogPath,qualifiedActionId,readPluginManifest,removePluginEntry,savePluginRegistry,supportsPlatform}from"./chunk-g2e1dmxh.js";import{SUBCOMMAND_VERBS}from"./chunk-s76r56rj.js";import"./chunk-n3b6yr9e.js";import"./chunk-b99tf0jr.js";import{flagValue}from"./chunk-jvxh93nz.js";import"./chunk-mnqxgvyb.js";import"./chunk-w7zv47mp.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-q5jhy3t8.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import{defaultDaemonSocketPath}from"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{readFileSync,rmSync}from"fs";var CLI_NAME=activeCliName();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 (legacy kobe-plugin is included)",""].join(`
|
|
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-garjd34w.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-9xkc34rf.js");await searchMarketplace(args.find((a)=>!a.startsWith("-")));return}case"outdated":{let{printOutdated}=await import("./chunk-dj5qqh6n.js");printOutdated();return}case"update":{let{updatePlugins}=await import("./chunk-dj5qqh6n.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};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{getPersistedBool,loadStateFile,patchStateFile,readSavedRepos,updateStateFile}from"./chunk-3jh78dmc.js";import{projectRejection}from"./chunk-81p6mm0p.js";import{kvStatePath}from"./chunk-q5jhy3t8.js";import{pathIdentity,samePath}from"./chunk-f10n6063.js";import{spawnSync}from"child_process";import{realpathSync}from"fs";function isRemoteRepoKey(key){return key.startsWith("ssh://")}function isRemoteProjectsEnabled(){return getPersistedBool("experimental.remoteProjects",!1)}function remoteRepoKey(host,user,port,basePath){let authority=port?`${user}@${host}:${port}`:`${user}@${host}`,base=(basePath??"").trim().replace(/\/+$/,"");if(!base)return`ssh://${authority}`;return`ssh://${authority}${base.startsWith("/")?base:`/${base}`}`}function readRemoteRepos(state){let raw=state.remoteRepos;if(!raw||typeof raw!=="object"||Array.isArray(raw))return{};return raw}function getRemoteRepoConfig(key){return readRemoteRepos(loadStateFile())[key]??null}function getRemoteRepos(){return readRemoteRepos(loadStateFile())}function addRemoteRepo(config){let key=remoteRepoKey(config.host,config.user,config.port,config.basePath),added=!1;return updateStateFile((state)=>{let repos={...readRemoteRepos(state)},legacyKey=remoteRepoKey(config.host,config.user,config.port);if(key!==legacyKey&&repos[legacyKey]?.basePath===config.basePath)key=legacyKey;repos[key]=config,state.remoteRepos=repos;let saved=readSavedRepos(state);if(added=!saved.includes(key),added)state.savedRepos=[...saved,key];return}),{key,added}}function resolveRepoRoot(absPath){if(isRemoteRepoKey(absPath))return absPath;let r=spawnSync("git",["rev-parse","--show-toplevel"],{cwd:absPath,encoding:"utf8",shell:!1});if(r.status!==0)return absPath;let top=(r.stdout??"").trim();if(!top)return absPath;try{if(realpathSync(absPath)===realpathSync(top))return absPath}catch{}return top}function isGitRepo(absPath){if(isRemoteRepoKey(absPath))return!1;let r=spawnSync("git",["rev-parse","--is-inside-work-tree"],{cwd:absPath,encoding:"utf8",shell:!1});return r.status===0&&(r.stdout??"").trim()==="true"}function isValidBranchName(branch){return spawnSync("git",["check-ref-format","--branch",branch],{encoding:"utf8",shell:!1}).status===0}function resolveMainRepoRoot(absPath){if(isRemoteRepoKey(absPath))return absPath;let r=spawnSync("git",["worktree","list","--porcelain"],{cwd:absPath,encoding:"utf8",shell:!1});if(r.status!==0)return resolveRepoRoot(absPath);return(r.stdout??"").split(/\r?\n/).find((line)=>line.startsWith("worktree "))?.slice(9).trim()||resolveRepoRoot(absPath)}function statePath(){return kvStatePath()}function getSavedRepos(){return readSavedRepos(loadStateFile())}function getPersistedString(key){let value=loadStateFile()[key];return typeof value==="string"?value:void 0}function setPersistedString(key,value){patchStateFile({[key]:value})}function getCustomEngineIds(){let raw=loadStateFile().customEngineIds;if(!Array.isArray(raw))return[];return raw.filter((s)=>typeof s==="string"&&s.trim().length>0)}function getDisabledEngineIds(){let raw=loadStateFile().disabledEngineIds;if(!Array.isArray(raw))return[];return raw.filter((s)=>typeof s==="string"&&s.trim().length>0)}function addSavedRepo(absPath,opts={}){let normalized=resolveMainRepoRoot(absPath),rejected=opts.skipGate?null:projectRejection(normalized,isGitRepo,opts.intent??"explicit");if(rejected)return{added:!1,path:normalized,total:getSavedRepos().length,rejected};let result={added:!1,path:normalized,total:0};return updateStateFile((state)=>{let cur=readSavedRepos(state);if(cur.some((repo)=>samePath(repo,normalized)))return result={added:!1,path:normalized,total:cur.length},!1;state.savedRepos=[...cur,normalized],result={added:!0,path:normalized,total:cur.length+1};return}),result}function backfillSavedReposFromProjects(mainRepos){let added=[];for(let repo of mainRepos)if(addSavedRepo(repo,{intent:"explicit"}).added)added.push(repo);return added}function normalizeSavedRepos(){let cur=getSavedRepos(),seen=new Set,next=[],changed=!1;for(let p of cur){let top=resolveMainRepoRoot(p);if(top!==p)changed=!0;if(seen.has(pathIdentity(top))){changed=!0;continue}seen.add(pathIdentity(top)),next.push(top)}if(!changed)return;patchStateFile({savedRepos:next})}function readRepoConfigs(state){let raw=state.repoConfigs;if(!raw||typeof raw!=="object"||Array.isArray(raw))return{};return raw}function coerceOverride(entry){if(!entry||typeof entry!=="object")return{};let e=entry;return{initScript:typeof e.initScript==="string"&&e.initScript.length>0?e.initScript:void 0,initPrompt:typeof e.initPrompt==="string"&&e.initPrompt.length>0?e.initPrompt:void 0}}function getRepoInitOverride(repoRoot){let configs=readRepoConfigs(loadStateFile()),normalized=resolveRepoRoot(repoRoot),key=Object.keys(configs).find((key2)=>samePath(key2,normalized))??normalized;return coerceOverride(configs[key])}function setRepoInitOverride(repoRoot,patch){let resolved=resolveRepoRoot(repoRoot),next={};return updateStateFile((state)=>{let configs={...readRepoConfigs(state)},normalized=Object.keys(configs).find((key)=>samePath(key,resolved))??resolved,cur=coerceOverride(configs[normalized]),nextScript=patch.initScript===void 0?cur.initScript:patch.initScript||void 0,nextPrompt=patch.initPrompt===void 0?cur.initPrompt:patch.initPrompt||void 0;if(next={...nextScript?{initScript:nextScript}:{},...nextPrompt?{initPrompt:nextPrompt}:{}},!next.initScript&&!next.initPrompt){let{[normalized]:_dropped,...rest}=configs;state.repoConfigs=rest}else configs[normalized]=next,state.repoConfigs=configs;return}),next}function removeSavedRepo(absPath){let result={removed:!1,path:absPath,total:0};return updateStateFile((state)=>{let cur=readSavedRepos(state);if(!cur.some((repo)=>samePath(repo,absPath)))return result={removed:!1,path:absPath,total:cur.length},!1;let remaining=cur.filter((p)=>!samePath(p,absPath));if(state.savedRepos=remaining,isRemoteRepoKey(absPath)){let remotes=readRemoteRepos(state);if(absPath in remotes){let next={...remotes};delete next[absPath],state.remoteRepos=next}}result={removed:!0,path:absPath,total:remaining.length};return}),result}
|
|
3
|
+
export{isRemoteRepoKey,isRemoteProjectsEnabled,remoteRepoKey,getRemoteRepoConfig,getRemoteRepos,addRemoteRepo,resolveRepoRoot,isGitRepo,isValidBranchName,resolveMainRepoRoot,statePath,getSavedRepos,getPersistedString,setPersistedString,getCustomEngineIds,getDisabledEngineIds,addSavedRepo,backfillSavedReposFromProjects,normalizeSavedRepos,getRepoInitOverride,setRepoInitOverride,removeSavedRepo};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{binaryAvailable,resolveEditorCommand}from"./chunk-
|
|
2
|
+
import{binaryAvailable,resolveEditorCommand}from"./chunk-yvmz8cts.js";import"./chunk-6xppe9bj.js";import"./chunk-2fypr41w.js";import"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-81p6mm0p.js";import{kvStatePath}from"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{existsSync,mkdirSync,writeFileSync}from"fs";import{dirname}from"path";var CLI_NAME=activeCliName();function printUsage(out){out.write([`Usage: ${CLI_NAME} config [--path]`,"","Open Rove's user config (state.json \u2014 theme, locale, engine + editor prefs)","in your editor. The editor is your configured one (Settings \u2192 General \u2192","Editor); left on Auto it is $VISUAL / $EDITOR, else the first of","nvim / vim / emacs / nano.","Rove re-reads the file on its next launch.","","Options:"," --path Print the config file path and exit (don't open an editor)"," -h, --help Print this help",""].join(`
|
|
3
3
|
`))}async function runConfigSubcommand(argv=[]){if(argv.some((a)=>a==="-h"||a==="--help"||a==="help")){printUsage(process.stdout);return}let path=kvStatePath();if(argv.some((a)=>a==="--path"||a==="path")){console.log(path);return}let unknown=argv.find((a)=>a.length>0);if(unknown!==void 0)process.stderr.write(`${CLI_NAME} config: unexpected argument "${unknown}"
|
|
4
4
|
`),printUsage(process.stderr),process.exit(2);if(!existsSync(path))mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`{}
|
|
5
5
|
`);let resolved=await resolveEditorCommand(path);if(!resolved||!await binaryAvailable(resolved.bin))process.stderr.write(`${CLI_NAME} config: no editor found \u2014 set $EDITOR (or Settings \u2192 General \u2192 Editor), or edit directly:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{DIRTY_WORKTREE_CODE,canonicalize,describeDirtyWorktreeWork,isKobeManagedPath,isUnderManagedWorktreesRoot,managedWorktreeRootForPath,remoteManagedRootForPath,remoteWorktreePathFor,requireAbsolute,worktreePathFor}from"./chunk-
|
|
2
|
+
import{DIRTY_WORKTREE_CODE,canonicalize,describeDirtyWorktreeWork,isKobeManagedPath,isUnderManagedWorktreesRoot,managedWorktreeRootForPath,remoteManagedRootForPath,remoteWorktreePathFor,requireAbsolute,worktreePathFor}from"./chunk-g7baby60.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{execHostForRepo,execHostForWorktreePath}from"./chunk-jg61s3ce.js";import{getRemoteRepoConfig}from"./chunk-ejqs2ta9.js";import path3 from"path";function parseDirtyPaths(stdout){return stdout.split(`
|
|
3
3
|
`).filter((line)=>line.length>3).map((line)=>line.slice(3).trim()).filter((line)=>line.length>0)}function isDirtyOutput(stdout){return parseDirtyPaths(stdout).length>0}var defaultExecDeps={execForRepo:execHostForRepo,execForPath:execHostForWorktreePath,remoteBasePath(repoKey){return getRemoteRepoConfig(repoKey)?.basePath??null}};class GitCommandError extends Error{args;cwd;exitCode;stdout;stderr;constructor(args,cwd,result){super(`git ${args.join(" ")} (cwd=${cwd}) exited with code ${result.exitCode}: ${result.stderr.trim()||result.stdout.trim()}`);this.name="GitCommandError",this.args=args,this.cwd=cwd,this.exitCode=result.exitCode,this.stdout=result.stdout,this.stderr=result.stderr}}var MAX_IGNORED_ENTRY_KB=65536;function parseIgnoredPaths(stdoutZ){return stdoutZ.split("\x00").filter((entry)=>entry.startsWith("!! ")).map((entry)=>entry.slice(3)).filter((p)=>p.length>0)}var DU_ARGV_BUDGET_BYTES=98304;function parseDuKb(stdout){let sizes=new Map;for(let line of stdout.split(`
|
|
4
4
|
`)){let m=/^(\d+)\s+(.+)$/.exec(line.trim());if(m?.[1]&&m[2])sizes.set(m[2],Number.parseInt(m[1],10))}return sizes}async function duKb(exec,worktreePath,paths){let sizes=new Map,batch=[],bytes=0,flush=async()=>{if(batch.length===0)return;let du=await exec.run(["du","-sk","--",...batch],{cwd:worktreePath});for(let[p,kb]of parseDuKb(du.stdout))sizes.set(p,kb);batch.length=0,bytes=0};for(let p of paths){if(p.includes(`
|
|
5
5
|
`)){let one=await exec.run(["du","-sk","--",p],{cwd:worktreePath}),kb=/^\s*(\d+)/.exec(one.stdout)?.[1];if(one.exitCode===0&&kb)sizes.set(p,Number.parseInt(kb,10));continue}if(bytes+p.length+1>DU_ARGV_BUDGET_BYTES)await flush();batch.push(p),bytes+=p.length+1}return await flush(),sizes}async function smallIgnoredPaths(exec,worktreePath){try{let status=await exec.run(["git","status","--porcelain","-z","--ignored"],{cwd:worktreePath,env:READ_ONLY_GIT_ENV});if(status.exitCode!==0)return"unknown";let paths=parseIgnoredPaths(status.stdout);if(paths.length===0)return[];let sizes=await duKb(exec,worktreePath,paths);return paths.filter((p)=>{let kb=sizes.get(p);return kb!==void 0&&kb<=MAX_IGNORED_ENTRY_KB})}catch{return"unknown"}}async function gitlinkPaths(git,tree){let out=await git(["ls-tree","-r",tree]);if(out.exitCode!==0)return[];return out.stdout.split(`
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import path from"path";function pathSyntax(value){return/^[a-z]:/i.test(value)||/^[/\\]{2}[^/\\]+[/\\][^/\\]+/.test(value)?path.win32:path.posix}function pathIdentity(value){if(!value||/^[a-z][a-z\d+.-]+:\/\//i.test(value))return value;let syntax=pathSyntax(value),unprefixed=(syntax===path.win32?value.replaceAll("/","\\"):value).replace(/^\\\\\?\\UNC\\/i,"\\\\").replace(/^\\\\\?\\(?=[a-z]:\\)/i,""),normalized=syntax.normalize(unprefixed),root=syntax.parse(normalized).root,trimmed=normalized.length>root.length?normalized.replace(syntax===path.win32?/[/\\]+$/:/\/+$/,""):normalized;if(syntax===path.posix)return trimmed;return trimmed.replaceAll("\\","/").replace(/^[a-z]:/i,(drive)=>drive.toUpperCase())}function samePath(left,right){return!!left&&!!right&&pathIdentity(left)===pathIdentity(right)}function pathWithin(parent,candidate){if(!parent||!candidate)return null;let root=pathIdentity(parent),target=pathIdentity(candidate);if(root===target)return"";let prefix=root.endsWith("/")?root:`${root}/`;return target.startsWith(prefix)?target.slice(prefix.length):null}
|
|
3
|
+
export{pathSyntax,pathIdentity,samePath,pathWithin};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{stopDaemonProcess}from"./chunk-
|
|
2
|
+
import{stopDaemonProcess}from"./chunk-y13681dw.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import{DAEMON_PROTOCOL_VERSION}from"./chunk-re5ke4fz.js";import{isProcessAlive,readPidFile}from"./chunk-t915by6w.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath}from"./chunk-8cjr5ypt.js";import{LEGACY_KOBE_PRODUCT_NAME,ROVE_PRODUCT_NAME}from"./chunk-hq4b3fca.js";import{spawn}from"child_process";import{closeSync,existsSync,mkdirSync,openSync,statSync,unlinkSync}from"fs";import{dirname,resolve}from"path";import{fileURLToPath}from"url";var DAEMON_START_ARGS=["daemon","start"],DAEMON_HELLO_TIMEOUT_MS=3000,BUSY_DAEMON_GRACE_MS=15000;function detachOptions(platform=process.platform){return platform==="win32"?{windowsHide:!0}:{detached:!0}}function spawnDetachedDaemon(command,args,env,logPath){let stdio="ignore",logFd;try{mkdirSync(dirname(logPath),{recursive:!0}),logFd=openSync(logPath,"a"),stdio=["ignore",logFd,logFd]}catch{stdio="ignore"}if(spawn(command,[...args],{...detachOptions(),stdio,env}).unref(),logFd!==void 0)try{closeSync(logFd)}catch{}}function insideEngineSession(env=process.env){return typeof env.KOBE_TASK_ID==="string"&&env.KOBE_TASK_ID!==""}function autospawnDaemonEnv(env=process.env,reason="autospawn"){let{KOBE_TASK_ID:_task,KOBE_TAB_ID:_tab,KOBE_TUI:_tui,KOBE_TERMINAL_PTY:_pty,ROVE_TASK_ID:_roveTask,ROVE_TAB_ID:_roveTab,ROVE_TUI:_roveTui,ROVE_TERMINAL_PTY:_rovePty,...rest}=env;return{...rest,KOBE_DAEMON_AUTOSPAWNED:"1",ROVE_DAEMON_AUTOSPAWNED:"1",KOBE_DAEMON_SPAWN_REASON:reason,ROVE_DAEMON_SPAWN_REASON:reason}}function daemonSpawnReason(env=process.env){let raw=env.ROVE_DAEMON_SPAWN_REASON??env.KOBE_DAEMON_SPAWN_REASON;if(raw==="explicit-restart"||raw==="autospawn")return raw;return env.ROVE_DAEMON_AUTOSPAWNED==="1"||env.KOBE_DAEMON_AUTOSPAWNED==="1"?"autospawn":"manual"}var SPAWN_LOCK_STALE_MS=40000,SPAWN_LOCK_WAIT_MS=30000;function tryAcquireSpawnLock(lockPath,staleMs=SPAWN_LOCK_STALE_MS){let create=()=>{return mkdirSync(dirname(lockPath),{recursive:!0}),closeSync(openSync(lockPath,"wx")),!0};try{return create()}catch{try{if(Date.now()-statSync(lockPath).mtimeMs<=staleMs)return!1;return unlinkSync(lockPath),create()}catch{return!1}}}async function ensureDaemonReachable(resolveSpawn=resolveKobeSpawn,spawnReason="autospawn"){let socketPath=defaultDaemonSocketPath(),state=await probeDaemonSocket(socketPath);if(state==="alive")return socketPath;if(state==="wedged"&&insideEngineSession())throw Error(`rove: daemon at ${socketPath} is not answering hello (busy or wedged); not restarting it from inside an engine session \u2014 retry, or run \`rove daemon restart\` from a regular shell`);let lockPath=`${defaultDaemonPidPath()}.spawn-lock`;if(!tryAcquireSpawnLock(lockPath)){let deadline=Date.now()+SPAWN_LOCK_WAIT_MS;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,150))}throw Error(`rove: another process is starting the daemon but it never became reachable at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}try{if(await probeDaemonSocket(socketPath)==="alive")return socketPath;let livePid=await readPidFile(defaultDaemonPidPath());if(livePid!==null&&livePid!==process.pid&&isProcessAlive(livePid)){let deadline2=Date.now()+BUSY_DAEMON_GRACE_MS;while(Date.now()<deadline2){if(await new Promise((resolveTimer)=>setTimeout(resolveTimer,250)),await testDaemonResponds(socketPath))return socketPath;if(!isProcessAlive(livePid))break}}let[command,...args]=resolveSpawn(DAEMON_START_ARGS);await stopDaemonProcess(socketPath,defaultDaemonPidPath()).catch(()=>{}),spawnDetachedDaemon(command,args,autospawnDaemonEnv(process.env,spawnReason),defaultDaemonLogPath());let deadline=Date.now()+5000;while(Date.now()<deadline){if(await testDaemonResponds(socketPath))return socketPath;await new Promise((resolveTimer)=>setTimeout(resolveTimer,100))}throw Error(`rove: daemon did not start (or stayed wedged) at ${socketPath}; check ${defaultDaemonLogPath()} or run \`rove doctor\``)}finally{try{unlinkSync(lockPath)}catch{}}}async function connectOrStartDaemon(spawnReason="autospawn"){let socketPath=await ensureDaemonReachable(resolveKobeSpawn,spawnReason),client=new KobeDaemonClient(socketPath);return await client.connect(),client}async function connectIfRunning(){let socketPath=defaultDaemonSocketPath();if(!await testDaemonResponds(socketPath))return null;let client=new KobeDaemonClient(socketPath);return await client.connect(),client}async function probeDaemonSocket(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){let probe=new KobeDaemonClient(socketPath);try{await probe.connect()}catch{return probe.close(),"absent"}let droppedByPeer=!1,offClose=probe.onLifecycle("close",()=>{droppedByPeer=!0}),replied=probe.request("hello",{protocolVersion:DAEMON_PROTOCOL_VERSION}).then(()=>!0).catch(()=>!0),timer,timedOut=new Promise((resolve2)=>{timer=setTimeout(()=>resolve2(!1),timeoutMs)}),settled=await Promise.race([replied,timedOut]);if(timer)clearTimeout(timer);if(offClose(),probe.close(),droppedByPeer)return"absent";return settled?"alive":"wedged"}async function testDaemonResponds(socketPath,timeoutMs=DAEMON_HELLO_TIMEOUT_MS){return await probeDaemonSocket(socketPath,timeoutMs)==="alive"}class StaleInstallError extends Error{candidates;constructor(cliName,dir,candidates){super(`${cliName}: this process is running from an install that no longer exists on disk \u2014 no ${cliName} entry near ${dir} (checked ${candidates.join(", ")}). Reinstall (\`npm install -g @sma1lboy/rove\`) and relaunch Rove.`);this.name="StaleInstallError",this.candidates=candidates}}function isStaleInstallError(err){return err instanceof Error&&err.name==="StaleInstallError"}function resolveKobeSpawn(subcommand,env=process.env,moduleFile=fileURLToPath(import.meta.url)){let here=moduleFile;if(here.startsWith("/$bunfs")||here.startsWith("B:\\~BUN"))return[process.execPath,...subcommand];let dir=dirname(here),cliName=env.ROVE_INVOKED_AS===ROVE_PRODUCT_NAME?ROVE_PRODUCT_NAME:LEGACY_KOBE_PRODUCT_NAME,candidates=[resolve(dir,`../cli/${cliName}.ts`),resolve(dir,`../../../kobe/src/cli/${cliName}.ts`),resolve(dir,`../cli/${cliName}.js`),resolve(dir,"../cli/index.ts"),resolve(dir,"../../../kobe/src/cli/index.ts"),resolve(dir,"../cli/index.js")],entry=candidates.find((candidate)=>existsSync(candidate));if(entry)return[process.execPath,entry,...subcommand];throw new StaleInstallError(cliName,dir,candidates)}
|
|
3
3
|
export{detachOptions,spawnDetachedDaemon,autospawnDaemonEnv,daemonSpawnReason,tryAcquireSpawnLock,ensureDaemonReachable,connectOrStartDaemon,connectIfRunning,probeDaemonSocket,testDaemonResponds,StaleInstallError,isStaleInstallError,resolveKobeSpawn};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{homeDir}from"./chunk-q5jhy3t8.js";import{pathWithin}from"./chunk-f10n6063.js";import{homedir as osHomedir}from"os";import{join}from"path";function tildify(path,home=osHomedir()){let suffix=pathWithin(home,path);return suffix===null?path:suffix?`~/${suffix}`:"~"}function expandTilde(path){if(path==="~")return homeDir();if(path.startsWith("~/")||process.platform==="win32"&&path.startsWith("~\\"))return join(homeDir(),path.slice(2));return path}
|
|
3
|
+
export{tildify,expandTilde};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{closeTab,engineTabArgv,initialTabs,setTabTitle,terminalTabsKey}from"./chunk-6ssj0adp.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,writeHostedPromptIfLive}from"./chunk-kes8k7gd.js";import{engineLaunchArgv}from"./chunk-dsnph7ht.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-3jh78dmc.js";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}function renameTabsSnapshot(taskId,tabId,title){let found=!1,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(!state.tabs.some((tab)=>tab.id===tabId))return!1;found=!0;let next=setTabTitle(state,tabId,title);if(next===state)return!1;store[key]=next;return}),found}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}class ApiError extends Error{code;data;constructor(message,code,data){super(message);this.code=code;this.data=data}}var DAEMON_CODE_PREFIX=/^([A-Z][A-Z0-9_]{2,}): /;function splitDaemonCode(message){let match=DAEMON_CODE_PREFIX.exec(message);if(!match?.[1])return null;return{code:match[1],rest:message.slice(match[0].length)}}function helpStep(verbName){return{hint:"run the verb's --help for its exact flag contract, then retry",nextCommandArgs:["api",verbName,"--help"]}}var VERB_GROUP_IDS=["discover","read","create","drive","edit","issues","workitems","routine","lifecycle","worktree","feedback"];var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,writePrompt=writeHostedPromptIfLive,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid,presence=await enginePresence(pid,target.engineBin,opts?.snapshot);if(presence==="unknown")throw new ApiError(`could not read the process table, so task ${target.id}'s engine tab (${existingKey}) could not be checked for a live engine`,"ENGINE_PROBE_FAILED",{hint:"the `ps` probe failed or timed out; retry, or check the machine's process table",nextCommandArgs:["api","pty-list"]});if(presence!=="engine")throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let outcome=await deliverToKey(rpc,existingKey,prompt);return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs});return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let outcome=await writePrompt(rpc,launch.key,prompt);return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}var killTaskSessions=killHostedSessions;
|
|
2
|
+
import{closeTab,engineTabArgv,initialTabs,setTabTitle,terminalTabsKey}from"./chunk-rmn9d90r.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,writeHostedPromptIfLive}from"./chunk-364q4ak8.js";import{engineLaunchArgv}from"./chunk-7r17j4te.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-3jh78dmc.js";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}function renameTabsSnapshot(taskId,tabId,title){let found=!1,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(!state.tabs.some((tab)=>tab.id===tabId))return!1;found=!0;let next=setTabTitle(state,tabId,title);if(next===state)return!1;store[key]=next;return}),found}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}class ApiError extends Error{code;data;constructor(message,code,data){super(message);this.code=code;this.data=data}}var DAEMON_CODE_PREFIX=/^([A-Z][A-Z0-9_]{2,}): /;function splitDaemonCode(message){let match=DAEMON_CODE_PREFIX.exec(message);if(!match?.[1])return null;return{code:match[1],rest:message.slice(match[0].length)}}function helpStep(verbName){return{hint:"run the verb's --help for its exact flag contract, then retry",nextCommandArgs:["api",verbName,"--help"]}}var VERB_GROUP_IDS=["discover","read","create","drive","edit","issues","workitems","routine","lifecycle","worktree","feedback"];var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,writePrompt=writeHostedPromptIfLive,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid,presence=await enginePresence(pid,target.engineBin,opts?.snapshot);if(presence==="unknown")throw new ApiError(`could not read the process table, so task ${target.id}'s engine tab (${existingKey}) could not be checked for a live engine`,"ENGINE_PROBE_FAILED",{hint:"the `ps` probe failed or timed out; retry, or check the machine's process table",nextCommandArgs:["api","pty-list"]});if(presence!=="engine")throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let outcome=await deliverToKey(rpc,existingKey,prompt);return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs});return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let outcome=await writePrompt(rpc,launch.key,prompt);return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}var killTaskSessions=killHostedSessions;
|
|
3
3
|
export{ApiError,splitDaemonCode,helpStep,VERB_GROUP_IDS,taskEngineArgv,readTabsSnapshot,closeTabsSnapshot,renameTabsSnapshot,unregisteredTabIds,joinTaskTabs,publishCliTabSnapshot,markCliTabSession,mintCliTab,restoredTabLaunch,isTaskKey,findEngineKey,taskKeys,openPtyHost,ensurePtyHost,listSessions,listSessionsOrNull,deliverToKey,ENGINE_START_PROBE_MS,ENGINE_START_POLL_MS,ENGINE_NOT_OBSERVED_REASON,outcomeFields,deliverHostedPrompt,killTaskSessions};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{PROJECT_DIR_TOKEN,WORKTREE_BASE_KEY,defaultLocalWorktreesRoot,legacyLocalWorktreesRoot,managedWorktreeRootsFor,normalizeWorktreeBase,worktreeRootFor}from"./chunk-63wmhbqs.js";import{execHostForRepo}from"./chunk-jg61s3ce.js";import{getRemoteRepoConfig,isRemoteRepoKey}from"./chunk-ejqs2ta9.js";import{loadStateFile}from"./chunk-3jh78dmc.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{pathWithin}from"./chunk-f10n6063.js";class IllegalTransitionError extends Error{from;to;taskId;constructor(from,to,taskId){super(`illegal transition for task ${taskId}: ${from} -> ${to}`);this.from=from;this.to=to;this.taskId=taskId;this.name="IllegalTransitionError"}}class TaskNotFoundError extends Error{constructor(taskId){super(`task not found: ${taskId}`);this.name="TaskNotFoundError"}}class CannotDeleteMainTaskError extends Error{constructor(){super("cannot delete a main task; remove the repo from saved repos instead");this.name="CannotDeleteMainTaskError"}}var DIRTY_WORKTREE_CODE="DIRTY_WORKTREE";function describeDirtyWorktreeWork(ignored){return ignored==="unknown"?"gitignored work this check could not read (git status --ignored failed) \u2014 nothing here can confirm it is empty":ignored.length>0?`gitignored work git status cannot see: ${ignored.join(", ")}`:"uncommitted or untracked changes"}class DirtyWorktreeError extends Error{taskId;ignored;constructor(taskId,ignored=[]){super(`${DIRTY_WORKTREE_CODE}: task ${taskId} worktree has ${describeDirtyWorktreeWork(ignored)}`);this.taskId=taskId;this.ignored=ignored;this.name="DirtyWorktreeError"}}class WorktreeRemoveFailedError extends Error{taskId;cause;constructor(taskId,cause){super(`failed to remove worktree for task ${taskId}: ${errorMessage(cause)}`);this.taskId=taskId;this.cause=cause;this.name="WorktreeRemoveFailedError"}}var TASK_DELETING_CODE="TASK_DELETING";class TaskDeletingError extends Error{taskId;constructor(taskId){super(`${TASK_DELETING_CODE}: task ${taskId} is being deleted`);this.taskId=taskId;this.name="TaskDeletingError"}}var MAIN_CHECKOUT_DIRTY_CODE="MAIN_CHECKOUT_DIRTY";class MainCheckoutDirtyError extends Error{repo;dir;constructor(repo,dir){super(`${MAIN_CHECKOUT_DIRTY_CODE}: base checkout at ${dir} has uncommitted changes; commit them before landing (never git stash \u2014 the stash stack is shared by every worktree of this repo)`);this.repo=repo;this.dir=dir;this.name="MainCheckoutDirtyError"}}var EMPTY_BRANCH_CODE="EMPTY_BRANCH";class EmptyBranchError extends Error{branch;landedOn;constructor(branch,landedOn){super(`${EMPTY_BRANCH_CODE}: '${branch}' has no commits ahead of '${landedOn}' \u2014 landing it would be a no-op (the worker may not have delivered anything)`);this.branch=branch;this.landedOn=landedOn;this.name="EmptyBranchError"}}var EMPTY_BRANCH_DIRTY_WORKTREE_CODE="EMPTY_BRANCH_DIRTY_WORKTREE";class EmptyBranchDirtyWorktreeError extends Error{branch;landedOn;worktreePath;files;constructor(branch,landedOn,worktreePath,files){let list=files.length>0?files.join(", "):"(none reported)";super(`${EMPTY_BRANCH_DIRTY_WORKTREE_CODE}: '${branch}' has no commits ahead of '${landedOn}' but its worktree ${worktreePath} has uncommitted changes (${list}) \u2014 commit them in the worktree first, then land again`);this.branch=branch;this.landedOn=landedOn;this.worktreePath=worktreePath;this.files=files;this.name="EmptyBranchDirtyWorktreeError"}}var MISSING_REF_CODE="MISSING_REF";class MissingRefError extends Error{branch;landedOn;dir;constructor(branch,landedOn,dir){super(`${MISSING_REF_CODE}: '${branch}' does not resolve in the base repo at ${dir} (comparing against '${landedOn}') \u2014 the branch was renamed or deleted outside Rove; re-point the task with \`rove api set-branch\` or recreate the branch`);this.branch=branch;this.landedOn=landedOn;this.dir=dir;this.name="MissingRefError"}}var LAND_CONFLICT_CODE="LAND_CONFLICT";class LandConflictError extends Error{taskId;branch;files;constructor(taskId,branch,files){let list=files.length>0?files.join(", "):"(none reported)";super(`${LAND_CONFLICT_CODE}: merging '${branch}' hit conflicts, merge aborted \u2014 conflicted files: ${list}`);this.taskId=taskId;this.branch=branch;this.files=files;this.name="LandConflictError"}}var GIT_COMMAND_FAILED_CODE="GIT_COMMAND_FAILED";class GitCommandFailedError extends Error{command;stderr;constructor(command,stderr,hint){let detail=stderr.trim()||"(git printed nothing on stderr)";super(`${GIT_COMMAND_FAILED_CODE}: \`git ${command}\` failed \u2014 ${detail}${hint?`; ${hint}`:""}`);this.command=command;this.stderr=stderr;this.name="GitCommandFailedError"}}var WORKTREE_NAME_TAKEN_CODE="WORKTREE_NAME_TAKEN";class WorktreeNameTakenError extends Error{worktreeName;constructor(worktreeName){super(`${WORKTREE_NAME_TAKEN_CODE}: worktree name '${worktreeName}' is already in use in this repo \u2014 pick another, or omit --worktree-name for a generated one`);this.worktreeName=worktreeName;this.name="WorktreeNameTakenError"}}var INVALID_WORKTREE_NAME_CODE="INVALID_WORKTREE_NAME";class InvalidWorktreeNameError extends Error{worktreeName;constructor(worktreeName){super(`${INVALID_WORKTREE_NAME_CODE}: worktree name '${worktreeName}' must be a single path segment of letters, digits, '.', '_' or '-' (no '/', no '..', not starting with '.')`);this.worktreeName=worktreeName;this.name="InvalidWorktreeNameError"}}import fs from"fs";import path from"path";var WORKTREE_BASE_CUSTOM_KEY="worktree.basePath.custom",PROJECT_SIBLING_BASE=`${PROJECT_DIR_TOKEN}/..`;function worktreeBaseKindOf(raw){let trimmed=raw.trim();if(!trimmed)return"default";if(trimmed.replace(/\/+$/,"")===PROJECT_SIBLING_BASE)return"nextToProject";return"custom"}function getWorktreeBaseOverride(projectDir){let value=loadStateFile()[WORKTREE_BASE_KEY];return normalizeWorktreeBase(typeof value==="string"?value:null,projectDir)}function worktreeRootFor2(repo){return worktreeRootFor(repo,getWorktreeBaseOverride(repo))}function managedWorktreeRootsFor2(repo){return managedWorktreeRootsFor(repo,getWorktreeBaseOverride(repo))}function worktreePathFor(repo,slug){if(!slug||/[/\\\0]/.test(slug))throw Error(`worktreePathFor: invalid slug: ${JSON.stringify(slug)}`);return path.join(worktreeRootFor2(repo),slug)}async function listWorktreeDirNames(repo){if(isRemoteRepoKey(repo)){let basePath=getRemoteRepoConfig(repo)?.basePath;if(!basePath)return[];let names2=new Set,host=execHostForRepo(repo),entries=await Promise.all(remoteManagedWorktreeRootsFor(basePath).map((root)=>host.readdir(root)));for(let list of entries)for(let name of list)names2.add(name);return[...names2]}let names=new Set;for(let root of managedWorktreeRootsFor2(repo))try{for(let e of fs.readdirSync(root,{withFileTypes:!0}))if(e.isDirectory())names.add(e.name)}catch{}return[...names]}function managedWorktreeRootForPath(repo,candidate){if(!path.isAbsolute(repo)||!path.isAbsolute(candidate))return null;let target=canonicalize(candidate);for(let rootPath of managedWorktreeRootsFor2(repo)){let root=canonicalize(rootPath),rel=pathWithin(root,target);if(rel!==null&&rel!=="")return rootPath}return null}function isKobeManagedPath(repo,candidate){return managedWorktreeRootForPath(repo,candidate)!==null}function isUnderManagedWorktreesRoot(candidate,projectDir){if(!path.isAbsolute(candidate))return!1;let target=canonicalize(candidate),roots=[getWorktreeBaseOverride(projectDir)??"",defaultLocalWorktreesRoot(),legacyLocalWorktreesRoot()];for(let rootPath of roots){if(!rootPath)continue;let root=canonicalize(rootPath),rel=pathWithin(root,target);if(rel===null)continue;if(rel.split("/").filter(Boolean).length===2)return!0}return!1}function remoteWorktreeRootFor(basePath){return`${stripTrailingSlash(basePath)}/.rove/worktrees`}function remoteManagedWorktreeRootsFor(basePath){let base=stripTrailingSlash(basePath);return[`${base}/.rove/worktrees`,`${base}/.kobe/worktrees`]}function remoteWorktreePathFor(basePath,slug){if(!slug||/[/\\\0]/.test(slug))throw Error(`remoteWorktreePathFor: invalid slug: ${JSON.stringify(slug)}`);return`${remoteWorktreeRootFor(basePath)}/${slug}`}function remoteManagedRootForPath(basePath,candidate){for(let root of remoteManagedWorktreeRootsFor(basePath))if(candidate===root||candidate.startsWith(`${root}/`))return root;return null}function stripTrailingSlash(p){return p.length>1&&p.endsWith("/")?p.replace(/\/+$/,""):p}function requireAbsolute(name,value){if(!value||!path.isAbsolute(value))throw Error(`${name} must be an absolute path, got: ${JSON.stringify(value)}`)}function canonicalize(p){try{return fs.realpathSync(p)}catch{return path.resolve(p)}}
|
|
3
|
+
export{IllegalTransitionError,TaskNotFoundError,CannotDeleteMainTaskError,DIRTY_WORKTREE_CODE,describeDirtyWorktreeWork,DirtyWorktreeError,WorktreeRemoveFailedError,TASK_DELETING_CODE,TaskDeletingError,MainCheckoutDirtyError,EmptyBranchError,EMPTY_BRANCH_DIRTY_WORKTREE_CODE,EmptyBranchDirtyWorktreeError,MissingRefError,LandConflictError,GitCommandFailedError,WorktreeNameTakenError,InvalidWorktreeNameError,WORKTREE_BASE_CUSTOM_KEY,PROJECT_SIBLING_BASE,worktreeBaseKindOf,worktreePathFor,listWorktreeDirNames,managedWorktreeRootForPath,isKobeManagedPath,isUnderManagedWorktreesRoot,remoteWorktreePathFor,remoteManagedRootForPath,requireAbsolute,canonicalize};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{openDaemonSession,resolveActiveTaskId}from"./chunk-ajtxh7kg.js";import"./chunk-fbc5d1fq.js";import"./chunk-y13681dw.js";import"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{resolveActiveTaskId,openDaemonSession};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{$jsx,$jsxs,pageCloseBindings,require_react_production,useBindings,useRenderer,useT,useTheme}from"./chunk-
|
|
2
|
+
import{$jsx,$jsxs,pageCloseBindings,require_react_production,useBindings,useRenderer,useT,useTheme}from"./chunk-y8dn3rez.js";import{updaterShell,updaterShellFailureHint}from"./chunk-r2qn2k6r.js";import{CURRENT_VERSION,UPDATE_COMMAND,checkLatestVersion,fetchReleaseNotesRange,releasePageUrl}from"./chunk-n3b6yr9e.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";function waitForKeypress(){if(!process.stdin.isTTY)return Promise.resolve();return new Promise((resolve)=>{let stdin=process.stdin,done=()=>{stdin.off("data",done),stdin.setRawMode?.(!1),stdin.pause(),resolve()};stdin.setRawMode?.(!0),stdin.resume(),stdin.once("data",done)})}async function runShellUpdater(opts){opts.renderer?.destroy(),process.stdout.write(`
|
|
3
3
|
rove ${CURRENT_VERSION} -> ${opts.targetLabel}
|
|
4
4
|
`),process.stdout.write(`running: ${opts.command}
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{updaterShell,updaterShellFailureHint}from"./chunk-
|
|
2
|
+
import{updaterShell,updaterShellFailureHint}from"./chunk-r2qn2k6r.js";import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,fetchReleaseSummaries,recommendedGlobalInstallCommand}from"./chunk-n3b6yr9e.js";import"./chunk-b99tf0jr.js";import"./chunk-q5jhy3t8.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";var CLI_NAME=activeCliName();function updatePlan(target){let shell=target===void 0?UPDATE_COMMAND:`${UPDATE_COMMAND} -s -- ${target}`;return{command:updaterShell(),args:["-c",shell],display:shell}}var VERSION_SHAPE=/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;function isReleaseChannel(value){return RELEASE_CHANNELS.includes(value)}function parseUpdateArgs(args){let dryRun=!1,list=!1,version,channel;for(let i=0;i<args.length;i+=1){let arg=args[i];if(arg===void 0)continue;if(arg==="--help"||arg==="-h"||arg==="help")return{help:!0,dryRun,list,version,channel};if(arg==="dry-run"||arg==="--dry-run"){dryRun=!0;continue}if(arg==="list"||arg==="--list"){list=!0;continue}if(arg==="--channel"||arg.startsWith("--channel=")){let value=(arg.startsWith("--channel=")?arg.slice(10):void 0)??args[++i];if(value===void 0||!isReleaseChannel(value))process.stderr.write(`${CLI_NAME} update: --channel expects one of ${RELEASE_CHANNELS.join(", ")}${value===void 0?"":` (got "${value}")`}
|
|
3
3
|
|
|
4
4
|
`),printUsage(process.stderr),process.exit(2);channel=value;continue}if(channel===void 0&&isReleaseChannel(arg)){channel=arg;continue}if(version===void 0&&VERSION_SHAPE.test(arg)){version=arg;continue}process.stderr.write(`${CLI_NAME} update: unknown argument "${arg}"
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ import{updaterShell,updaterShellFailureHint}from"./chunk-64tw0fqp.js";import{BRE
|
|
|
10
10
|
install one with: ${CLI_NAME} update <version>
|
|
11
11
|
`)}async function warnBreakingCrossings(target,channel,io){if(BREAKING_VERSIONS.length===0)return;let resolved=target??(await checkLatestVersion({force:!0,channel}))?.latest;if(!resolved)return;let crossed=breakingVersionsCrossed(CURRENT_VERSION,resolved);if(crossed.length===0)return;io.stderr.write([`warning: ${CURRENT_VERSION} -> ${resolved} crosses breaking version(s): ${crossed.join(", ")}.`,`After this update, Rove will refuse to start until you run \`${CLI_NAME} reset\``,"(worktrees are never touched; add --hard only to also wipe the task index).",""].join(`
|
|
12
12
|
`))}var FOLLOW_UP_NOTE=["",`${CLI_NAME}: installed. Two background processes are still running the old build:`,` daemon \u2192 \`${CLI_NAME} daemon restart\` (safe; never touches live sessions)`,` pty host \u2192 only \`${CLI_NAME} reset\` replaces it, and that ends every live`," terminal and engine session \u2014 do it when you can afford to.",`Run \`${CLI_NAME} doctor\` to see which of the two is actually stale.`,""].join(`
|
|
13
|
-
`);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code))},parsed=parseUpdateArgs(args);if(parsed.help){printUsage(io.stdout);return}if(parsed.list){if(deps===void 0&&process.stdout.isTTY){let{startVersionsHost}=await import("./chunk-
|
|
13
|
+
`);async function runUpdateSubcommand(args,deps){let io={spawn:deps?.spawn??spawnSync,stdout:deps?.stdout??process.stdout,stderr:deps?.stderr??process.stderr,exit:deps?.exit??((code)=>process.exit(code))},parsed=parseUpdateArgs(args);if(parsed.help){printUsage(io.stdout);return}if(parsed.list){if(deps===void 0&&process.stdout.isTTY){let{startVersionsHost}=await import("./chunk-d7fk35g9.js");await startVersionsHost();return}await printVersionList(io);return}let channel=parsed.channel??channelOf(),target=parsed.version??(channel===DEFAULT_RELEASE_CHANNEL?void 0:channel),plan=updatePlan(target),switching=parsed.channel!==void 0&&parsed.channel!==channelOf();if(io.stdout.write(`${CLI_NAME} ${CURRENT_VERSION} -> ${target??channel}
|
|
14
14
|
`),switching)io.stdout.write(`switching channel: ${channelOf()} -> ${channel}
|
|
15
15
|
`);if(io.stdout.write(`running: ${plan.display}
|
|
16
16
|
`),await warnBreakingCrossings(parsed.version,channel,io),parsed.dryRun)return;let result=io.spawn(plan.command,plan.args,{stdio:"inherit"});if(result.error){io.stderr.write(`${CLI_NAME} update: failed to run ${plan.command}: ${result.error.message}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Orchestrator}from"./chunk-534se0f6.js";import"./chunk-hfpmeck1.js";import"./chunk-2kb4z64z.js";import"./chunk-esgxxnwn.js";import"./chunk-bkm7vxr5.js";import{PLACEHOLDER_TASK_TITLE}from"./chunk-xb9b93ts.js";import"./chunk-g7baby60.js";import"./chunk-63wmhbqs.js";import"./chunk-6xppe9bj.js";import"./chunk-jg61s3ce.js";import"./chunk-bkba9c4n.js";import"./chunk-g2advs8t.js";import"./chunk-hape5vwj.js";import"./chunk-sdyzxayr.js";import"./chunk-khj0apc7.js";import"./chunk-2fypr41w.js";import"./chunk-xy8be792.js";import"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-sb0ns0c7.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{PLACEHOLDER_TASK_TITLE,Orchestrator};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{canonicalize}from"./chunk-
|
|
2
|
+
import{canonicalize}from"./chunk-g7baby60.js";import{applyJitter,exponentialBackoff}from"./chunk-khj0apc7.js";import{getRemoteRepoConfig,isRemoteRepoKey,resolveRepoRoot}from"./chunk-ejqs2ta9.js";var canonPath=canonicalize;function randomDirTaskSuffix(){return Math.random().toString(36).slice(2,6).padEnd(4,"0")}function titleFromRepo(repo){let segs=repo.split(/[/\\]/).filter(Boolean);return segs.length>0?segs[segs.length-1]??repo:repo}function normalizeMainRepo(repo){let normalized=resolveRepoRoot(repo);return{repo:normalized,key:isRemoteRepoKey(normalized)?normalized:canonPath(normalized)}}function repoWorkingDir(repo){return getRemoteRepoConfig(repo)?.basePath??repo}var GH_PR_VIEW_FIELDS="number,url,title,state,baseRefName,reviewDecision,mergeable,statusCheckRollup";function lifecycleFromState(state,reviewDecision){switch((state??"").toUpperCase()){case"MERGED":return"merged";case"CLOSED":return"closed";case"OPEN":return(reviewDecision??"").toUpperCase()==="APPROVED"?"ready_to_merge":"open";default:return"unknown"}}function entryCheckState(entry){let status=(entry.status??"").toUpperCase(),conclusion=(entry.conclusion??"").toUpperCase(),contextState=(entry.state??"").toUpperCase();if(status&&status!=="COMPLETED")return"pending";if(conclusion){if(conclusion==="SUCCESS"||conclusion==="NEUTRAL"||conclusion==="SKIPPED")return"passing";return"failing"}if(contextState==="SUCCESS")return"passing";if(contextState==="PENDING"||contextState==="EXPECTED")return"pending";if(contextState==="FAILURE"||contextState==="ERROR")return"failing";return"unknown"}function checkStateFromRollup(rollup){if(!rollup||rollup.length===0)return"none";let sawPending=!1,sawPassing=!1;for(let entry of rollup){let s=entryCheckState(entry);if(s==="failing")return"failing";if(s==="pending")sawPending=!0;else if(s==="passing")sawPassing=!0}if(sawPending)return"pending";if(sawPassing)return"passing";return"unknown"}function mapGhPrView(view,at){if(!view||typeof view.number!=="number")return null;return{provider:"github",lifecycle:lifecycleFromState(view.state,view.reviewDecision),checkState:checkStateFromRollup(view.statusCheckRollup),number:view.number,url:view.url,title:view.title,baseRef:view.baseRefName,reviewDecision:view.reviewDecision||void 0,mergeable:view.mergeable||void 0,lastCheckedAt:at}}function samePrStatus(a,b){if(a===b)return!0;if(!a||!b)return!1;return a.provider===b.provider&&a.lifecycle===b.lifecycle&&a.checkState===b.checkState&&a.number===b.number&&a.url===b.url&&a.title===b.title&&a.baseRef===b.baseRef&&a.reviewDecision===b.reviewDecision&&a.mergeable===b.mergeable}var NO_REMOTE_PATTERNS=["none of the git remotes","no git remote","to use github cli in a github repository","not a github repository"],AUTH_PATTERNS=["gh auth login","authentication required","not logged in","http 401","bad credentials","requires authentication"],NETWORK_PATTERNS=["could not resolve host","no such host","dial tcp","connection refused","connection reset","network is unreachable","i/o timeout","timeout","tls handshake","http 5","rate limit","try again"];function matchesAny(haystack,needles){return needles.some((n)=>haystack.includes(n))}function classifyGhFailure(s){if(s.parseError)return{kind:"error",error:"parse"};if(s.timedOut)return{kind:"error",error:"timeout"};if(s.spawnError)return{kind:"error",error:"missing-binary"};let err=(s.stderr??"").toLowerCase();if(matchesAny(err,NO_REMOTE_PATTERNS))return{kind:"error",error:"no-remote"};if(matchesAny(err,AUTH_PATTERNS))return{kind:"error",error:"auth"};if(matchesAny(err,NETWORK_PATTERNS))return{kind:"error",error:"network"};return{kind:"error",error:"unknown"}}function nextPrPoll(outcome,prevFailures,now,cfg,rand=Math.random){let at=(delay)=>now+applyJitter(delay,cfg.jitterRatio,rand);if(outcome.kind==="pr")return{nextAllowedAt:at(outcome.settled?cfg.settledMs:cfg.tickMs),failures:0};if(outcome.kind==="empty")return{nextAllowedAt:at(cfg.noPrMs),failures:0};if(outcome.error==="no-remote")return{nextAllowedAt:at(cfg.noRemoteMs),failures:0};let failures=prevFailures+1;return{nextAllowedAt:at(exponentialBackoff(cfg.failureBaseMs,failures-1,cfg.failureCapMs)),failures}}function checkResolutionNotify(prev,next){if(prev!=="pending")return null;if(next==="passing"||next==="failing")return next;return null}
|
|
3
3
|
export{GH_PR_VIEW_FIELDS,mapGhPrView,samePrStatus,classifyGhFailure,nextPrPoll,checkResolutionNotify,canonPath,randomDirTaskSuffix,titleFromRepo,normalizeMainRepo,repoWorkingDir};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{LocalExecHost,RemoteExecHost}from"./chunk-bkba9c4n.js";import{getKeychainPassword}from"./chunk-g2advs8t.js";import{getRemoteRepoConfig,getRemoteRepos,isRemoteRepoKey}from"./chunk-
|
|
2
|
+
import{LocalExecHost,RemoteExecHost}from"./chunk-bkba9c4n.js";import{getKeychainPassword}from"./chunk-g2advs8t.js";import{getRemoteRepoConfig,getRemoteRepos,isRemoteRepoKey}from"./chunk-ejqs2ta9.js";import{remoteControlSocketPath}from"./chunk-q5jhy3t8.js";function remoteSpecFromConfig(config){let cfgAuth=config.auth,auth=cfgAuth.kind==="key"?{kind:"key",keyPath:cfgAuth.keyPath}:{kind:"password",getPassword:()=>getKeychainPassword(cfgAuth.keychainRef)};return{host:config.host,user:config.user,port:config.port,auth,controlPath:remoteControlSocketPath(config.host,config.user,config.port)}}var remoteHostCache=new Map;function cachedRemoteHost(config){let spec=remoteSpecFromConfig(config),cached=remoteHostCache.get(spec.controlPath);if(cached)return cached;let host=new RemoteExecHost(spec);return remoteHostCache.set(spec.controlPath,host),host}function execHostForRepo(repoKey){let config=getRemoteRepoConfig(repoKey);if(!config)return new LocalExecHost;return cachedRemoteHost(config)}function execHostForWorktreePath(worktreePath){for(let config of Object.values(getRemoteRepos()))if(worktreePath===config.basePath||worktreePath.startsWith(`${config.basePath}/`))return cachedRemoteHost(config);return new LocalExecHost}function remoteKeyForRepo(repo){return repo&&isRemoteRepoKey(repo)?repo:void 0}
|
|
3
3
|
export{execHostForRepo,execHostForWorktreePath,remoteKeyForRepo};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{StaleInstallError,autospawnDaemonEnv,connectIfRunning,connectOrStartDaemon,daemonSpawnReason,detachOptions,ensureDaemonReachable,isStaleInstallError,probeDaemonSocket,resolveKobeSpawn,spawnDetachedDaemon,testDaemonResponds,tryAcquireSpawnLock}from"./chunk-fbc5d1fq.js";import"./chunk-y13681dw.js";import"./chunk-b5mbpv97.js";import"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{tryAcquireSpawnLock,testDaemonResponds,spawnDetachedDaemon,resolveKobeSpawn,probeDaemonSocket,isStaleInstallError,ensureDaemonReachable,detachOptions,daemonSpawnReason,connectOrStartDaemon,connectIfRunning,autospawnDaemonEnv,StaleInstallError};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{engineEntry}from"./chunk-
|
|
2
|
+
import{engineEntry}from"./chunk-80hf0bbr.js";import{roveCliInvocation}from"./chunk-v61s3fps.js";import{getPersistedString}from"./chunk-ejqs2ta9.js";import{coerceVendorId}from"./chunk-bq3fyc0p.js";function engineCommandKey(vendor){return`engineCommand.${vendor}`}function engineNameKey(vendor){return`engineName.${vendor}`}function engineDisplayName(vendor){return getPersistedString(engineNameKey(vendor))?.trim()||engineEntry(vendor).displayName}function humanizeSlug(id){return id.split(/[-_]+/).filter((word)=>word.length>0).map((word)=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function defaultEngineCommand(vendor){return engineEntry(coerceVendorId(vendor)).defaultCommand}function parseEngineCommand(command){let out=[],token="",hasToken=!1,quote=null;for(let ch of command){if(quote){if(ch===quote)quote=null;else token+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,hasToken=!0;continue}if(/\s/.test(ch)){if(hasToken)out.push(token),token="",hasToken=!1;continue}token+=ch,hasToken=!0}if(hasToken)out.push(token);return out}function interactiveEngineCommand(vendor,effort){let v=coerceVendorId(vendor),override=getPersistedString(engineCommandKey(v))?.trim(),base=(()=>{if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(v)})();return withEngineTerminalTitle(withEngineEffort(base,v,effort),v)}function withEngineTerminalTitle(argv,vendor){let args=engineEntry(coerceVendorId(vendor)).terminalTitle?.launchArgs;return args&&args.length>0?[...argv,...args]:argv}function withEngineEffort(argv,vendor,effort){let trimmed=effort?.trim();if(!trimmed)return argv;let entry=engineEntry(coerceVendorId(vendor));if(!entry.effortLevels?.includes(trimmed))return argv;return entry.effortArgv?.(argv,trimmed)??argv}function kobeApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}
|
|
3
3
|
export{engineCommandKey,engineNameKey,engineDisplayName,humanizeSlug,defaultEngineCommand,parseEngineCommand,interactiveEngineCommand,withEngineTerminalTitle,withEngineEffort,kobeApiInvocation};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{applyFixes,daemonRestartFix,defaultFixRuntime,engineTabsManualFix,humanOnlyFix,killOrphansManualFix,noEngineFix,probeEngines,probeGit,reinstallManualFix,resetManualFix,skillInstallFix,spawnHelperFix}from"./chunk-
|
|
2
|
+
import{applyFixes,daemonRestartFix,defaultFixRuntime,engineTabsManualFix,humanOnlyFix,killOrphansManualFix,noEngineFix,probeEngines,probeGit,reinstallManualFix,resetManualFix,skillInstallFix,spawnHelperFix}from"./chunk-r0hekyyy.js";import{formatBytes}from"./chunk-my20q579.js";import"./chunk-94eb11hz.js";import"./chunk-ea9t4hh5.js";import"./chunk-px6axbd9.js";import"./chunk-rz8zs7j8.js";import"./chunk-xsrcwcjc.js";import"./chunk-jpdf97cx.js";import{kobeSkillState,skillInstallCommand}from"./chunk-wvq6kgcp.js";import{inspectLegacyTmux,legacyTmuxDoctorLines}from"./chunk-dqndd97s.js";import"./chunk-a74pa16c.js";import"./chunk-h4n8ffqy.js";import"./chunk-vyb5a2rh.js";import"./chunk-r2pztgm6.js";import"./chunk-g2e1dmxh.js";import"./chunk-63wmhbqs.js";import{CURRENT_VERSION,package_default}from"./chunk-n3b6yr9e.js";import{resolveNodeBinary}from"./chunk-s72y2s88.js";import"./chunk-7r17j4te.js";import{formatDaemonInfo}from"./chunk-rcyasw34.js";import"./chunk-km4hx6kc.js";import{t}from"./chunk-fa7s3d1e.js";import"./chunk-dazqahfp.js";import"./chunk-sdyzxayr.js";import"./chunk-b99tf0jr.js";import"./chunk-w25b7xxz.js";import"./chunk-jvxh93nz.js";import{isStaleInstallError,resolveKobeSpawn}from"./chunk-fbc5d1fq.js";import"./chunk-y13681dw.js";import{KobeDaemonClient}from"./chunk-b5mbpv97.js";import{isForeignDaemonHome}from"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import"./chunk-pz5y8f3r.js";import{createEngineHookAdapter}from"./chunk-80hf0bbr.js";import"./chunk-khj0apc7.js";import"./chunk-5zh5fcpe.js";import"./chunk-w7zv47mp.js";import{parseHookSettings}from"./chunk-v61s3fps.js";import"./chunk-7jkf3tvr.js";import"./chunk-2fypr41w.js";import{readableLegacyIndexPath}from"./chunk-r9gfh1zz.js";import"./chunk-xy8be792.js";import"./chunk-ejqs2ta9.js";import"./chunk-3jh78dmc.js";import"./chunk-ddcxvbme.js";import"./chunk-2brn8e1y.js";import{ALL_VENDORS}from"./chunk-bq3fyc0p.js";import"./chunk-81p6mm0p.js";import{homeDir,kvStatePath,roveStateDir}from"./chunk-q5jhy3t8.js";import{readPidFile}from"./chunk-t915by6w.js";import"./chunk-9prawccj.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import{LEGACY_KOBE_STATE_DIR_BASENAME}from"./chunk-sb0ns0c7.js";import"./chunk-pxk2c2vj.js";import"./chunk-0q6h4vt4.js";import"./chunk-pw6yfj10.js";import"./chunk-f10n6063.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyHostLogPath,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-8cjr5ypt.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{existsSync,readFileSync as readFileSync3,statSync as statSync2}from"fs";import{join as join2}from"path";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let vendor of ALL_VENDORS){let adapter=createEngineHookAdapter(vendor);if(!adapter.supportsHooks())continue;let file=adapter.globalSettingsPath();if(!file||!file.endsWith(".json"))continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let parsed=parseHookSettings(raw);if(!parsed.ok)issues.push({file,reason:parsed.reason})}return issues}var MIN_BUN_VERSION=package_default.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0";function parseBunVersion(raw){return raw.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function isBunAtLeast(raw,minimum=MIN_BUN_VERSION){let found=parseBunVersion(raw),floor=parseBunVersion(minimum);if(!found||!floor)return!0;let a=found.split(".").map(Number),b=floor.split(".").map(Number);for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(av!==bv)return av>bv}return!0}function classifyHookChannel(input){let total=0,hooked=0;for(let tabs of Object.values(input.tabs))for(let entry of Object.values(tabs))if(total++,entry.source==="hook")hooked++;if(total===0)return{kind:"no-tabs"};if(hooked===0)return{kind:"down",totalTabs:total};return{kind:"live",hookTabs:hooked,totalTabs:total}}function hookChannelDoctorLines(verdict,input,cliName){let configLines=(input.configIssues??[]).flatMap((issue)=>[` \u26A0 hook install skipped: ${issue.file}`,` ${issue.reason} \u2014 fix the file, then relaunch Rove`]);if(verdict.kind==="no-tabs")return["hooks: \u2014 no engine tabs yet (nothing to check)",...configLines];if(verdict.kind==="live")return[`hooks: \u2713 engine hook channel live (${verdict.hookTabs}/${verdict.totalTabs} tab(s) hook-sourced)`,...configLines];let out=[`hooks: \u2717 NO hook events reaching the daemon (0/${verdict.totalTabs} tab(s) hook-sourced)`," badges fall back to a ~10s poll, so activity looks seconds late",` daemon socket: ${input.socketPath}`,...configLines];return out.push(' \u2192 compare with an engine tab\'s own path: `ps eww -p <engine-pid> | tr " " "\\n" | grep DAEMON_SOCKET_PATH`',` \u2192 restart the engine tabs (they may hold a stale socket path), or run \`${cliName} daemon restart\``,` \u2192 debug one hook directly: \`KOBE_HOOK_DEBUG=1 echo '{}' | ${cliName} hook turn-start --engine claude\``),out}import{readdirSync,statSync}from"fs";import{createRequire}from"module";import{dirname,join}from"path";function installedSpawnHelpers(){let pkg;try{pkg=dirname(createRequire(import.meta.url).resolve("node-pty/package.json"))}catch{return[]}let prebuilds=join(pkg,"prebuilds"),arches;try{arches=readdirSync(prebuilds).filter((name)=>name.startsWith("darwin-"))}catch{return[]}let helpers=[];for(let arch of arches){let path=join(prebuilds,arch,"spawn-helper");try{helpers.push({path,executable:(statSync(path).mode&64)!==0})}catch{}}return helpers}function spawnHelperDoctorLines(helpers){let broken=helpers.filter((helper)=>!helper.executable).map((helper)=>helper.path);if(helpers.length===0)return{lines:["node-pty: ? no darwin spawn-helper found next to node-pty"],broken};if(broken.length===0)return{lines:[`node-pty: \u2713 spawn-helper executable (${helpers.length} arch)`],broken};return{lines:["node-pty: \u2717 spawn-helper is not executable \u2014 every node-pty PTY spawn fails",...broken.map((path)=>` ${path}`),` \u2192 chmod 755 ${broken.join(" ")}`],broken}}import{appendFileSync,readFileSync as readFileSync2}from"fs";var PTY_MARKER="KOBE_TERMINAL_PTY=1",run=async(argv)=>{try{let proc=Bun.spawn([...argv],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),[stdout,code]=await Promise.all([new Response(proc.stdout).text().catch(()=>""),proc.exited]);return{code,stdout}}catch{return{code:127,stdout:""}}};function parsePsRows(output){let rows=[];for(let line of output.split(`
|
|
3
3
|
`)){let parts=line.trim().split(/\s+/);if(parts.length<6)continue;let[pid,ppid,pgid]=[parts[0],parts[1],parts[2]].map((value)=>Number.parseInt(value??"",10)),rssKb=Number.parseInt(parts[4]??"",10);if(!Number.isFinite(pid)||!Number.isFinite(ppid)||!Number.isFinite(pgid)||!Number.isFinite(rssKb))continue;rows.push({pid,ppid,pgid,etime:parts[3]??"",rssKb,command:parts.slice(5).join(" ")})}return rows}function pidAlive(pid,rows){return rows.some((row)=>row.pid===pid)}function orphanCandidates(rows,selfPgid,liveSessionPids){return rows.filter((row)=>row.ppid===1&&row.pgid!==selfPgid&&!liveSessionPids.has(row.pgid)&&!pidAlive(row.pgid,rows))}async function markedPids(pids,deps={}){let runProbe=deps.run??run,readEnviron=deps.readEnviron??((pid)=>readFileSync2(`/proc/${pid}/environ`,"utf8")),marked=new Set;if(pids.length===0)return{marked,failed:null};if((deps.platform??process.platform)==="linux"){let refused=null;for(let pid of pids)try{if(readEnviron(pid).split("\x00").includes(PTY_MARKER))marked.add(pid)}catch(err){let code=err.code;if(code!=="ENOENT"&&code!=="ESRCH")refused??=`/proc/${pid}/environ: ${code??"unreadable"}`}return{marked,failed:refused}}let result=await runProbe(["ps","eww","-o","pid=,command=","-p",pids.join(",")]);if(result.code!==0)return{marked,failed:`ps eww exited ${result.code}`};let marker=new RegExp(`(^|\\s)${PTY_MARKER}(\\s|$)`);for(let line of result.stdout.split(`
|
|
4
4
|
`)){let pid=Number.parseInt(line.trim().split(/\s+/)[0]??"",10);if(Number.isFinite(pid)&&marker.test(line))marked.add(pid)}return{marked,failed:null}}async function ownPgid(runProbe){let result=await runProbe(["ps","-o","pgid=","-p",String(process.pid)]),pgid=Number.parseInt(result.stdout.trim(),10);return Number.isFinite(pgid)?pgid:-1}async function collectOrphans(liveSessionPids,deps={}){let runProbe=deps.run??run;if((deps.platform??process.platform)==="win32")return{orphans:[],error:null};let ps=await runProbe(["ps","-A","-o","pid=,ppid=,pgid=,etime=,rss=,command="]);if(ps.code!==0)return{orphans:[],error:`could not read the process table \u2014 ps exited ${ps.code}`};let rows=parsePsRows(ps.stdout),candidates=orphanCandidates(rows,await ownPgid(runProbe),liveSessionPids),{marked,failed}=await markedPids(candidates.map((row)=>row.pid),deps);if(failed)return{orphans:[],error:`could not read process environments \u2014 ${failed}`};return{orphans:candidates.filter((row)=>marked.has(row.pid)),error:null}}function formatMb(rssKb){return`${(rssKb/1024).toFixed(0)} MB`}function orphanDoctorLines(orphans,error,cliName,killing=!1){if(error)return[`orphans: \u2717 ${error}`];if(orphans.length===0)return["orphans: \u2713 none \u2014 no processes left behind by a dead PTY session"];let totalMb=orphans.reduce((sum,row)=>sum+row.rssKb,0)/1024,lines=[`orphans: \u26A0 ${orphans.length} process(es) outlived the PTY session that spawned them (${totalMb.toFixed(0)} MB RSS)`," each is reparented to init, carries Rove's PTY marker, and its process"," group leader is gone \u2014 no live task owns them"];for(let row of[...orphans].sort((a,b)=>b.rssKb-a.rssKb))lines.push(` pid ${row.pid} (group ${row.pgid}) up ${row.etime}, ${formatMb(row.rssKb)}: ${row.command.slice(0,90)}`);if(!killing)lines.push(` \u2192 \`${cliName} doctor --kill-orphans\` ends those process groups (SIGTERM, then SIGKILL)`," read the list first: something you backgrounded from a Rove terminal and then"," closed the tab on looks exactly like a leak, and doctor cannot tell them apart");return lines}var GROUP_EXIT_GRACE_MS=2000,GROUP_POLL_MS=100;function logOrphanKill(pgid,signal,logPath=defaultDaemonLogPath()){try{appendFileSync(logPath,formatDaemonInfo("doctor-kill-orphans",`${signal} process group ${pgid}`))}catch{}}function groupAlive(pgid){try{return process.kill(-pgid,0),!0}catch(err){return err.code!=="ESRCH"}}async function killOrphanGroups(orphans){let groups=[...new Set(orphans.map((row)=>row.pgid))];for(let pgid of groups)try{process.kill(-pgid,"SIGTERM"),logOrphanKill(pgid,"SIGTERM")}catch{}let deadline=Date.now()+GROUP_EXIT_GRACE_MS,survivors=groups.filter(groupAlive);while(survivors.length>0&&Date.now()<deadline)await new Promise((resolve)=>setTimeout(resolve,GROUP_POLL_MS)),survivors=survivors.filter(groupAlive);for(let pgid of survivors)try{process.kill(-pgid,"SIGKILL"),logOrphanKill(pgid,"SIGKILL")}catch{}return await new Promise((resolve)=>setTimeout(resolve,GROUP_POLL_MS)),{groups,survivors:survivors.filter(groupAlive)}}function multiplexerLabel(env){if(env.TMUX)return"tmux";if(env.ZELLIJ)return"zellij";if(env.STY)return"screen";return"no"}function terminalEnvLines(env){let show=(v)=>v&&v.length>0?v:"(unset)",program=env.TERM_PROGRAM?`${env.TERM_PROGRAM}${env.TERM_PROGRAM_VERSION?` v${env.TERM_PROGRAM_VERSION}`:""}`:"(unset)";return[`terminal: TERM=${show(env.TERM)} TERM_PROGRAM=${program} COLORTERM=${show(env.COLORTERM)}`,` running inside a multiplexer: ${multiplexerLabel(env)}`]}function parseKittyProbeReply(data){let kitty=data.match(/\x1b\[\?(\d+)u/);if(kitty?.[1]!==void 0)return{kind:"supported",flags:Number.parseInt(kitty[1],10)};if(/\x1b\[\?[\d;]*c/.test(data))return{kind:"unsupported"};return null}function kittyProbeLine(result){switch(result.kind){case"supported":return` kitty keyboard protocol: \u2713 answered (flags=${result.flags})`;case"unsupported":return[" kitty keyboard protocol: \u2717 not supported \u2014 legacy key path"," (ctrl+h/ctrl+j arrive as C0 backspace/linefeed bytes; the"," split chords ctrl+\\ and ctrl+= cannot be encoded at all)"].join(`
|
|
5
5
|
`);case"no-response":return" kitty keyboard protocol: ? no reply (terminal ignored both the kitty query and DA1)";case"skipped":return` kitty keyboard protocol: skipped (${result.reason})`}}async function probeKittyKeyboard(timeoutMs=300){let stdin=process.stdin;if(!stdin.isTTY||!process.stdout.isTTY)return{kind:"skipped",reason:"not an interactive terminal"};let wasRaw=stdin.isRaw===!0,buffer="";return await new Promise((resolve)=>{let done=!1,finish=(result)=>{if(done)return;if(done=!0,clearTimeout(timer),stdin.off("data",onData),stdin.pause(),!wasRaw)stdin.setRawMode(!1);resolve(result)},onData=(chunk)=>{buffer+=chunk.toString("latin1");let decided=parseKittyProbeReply(buffer);if(decided)finish(decided)},timer=setTimeout(()=>finish({kind:"no-response"}),timeoutMs);stdin.setRawMode(!0),stdin.resume(),stdin.on("data",onData),process.stdout.write("\x1B[?u\x1B[c")})}async function terminalDoctorLines(){return[...terminalEnvLines(process.env),kittyProbeLine(await probeKittyKeyboard())]}var CLI_NAME=activeCliName();function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(err){return err.code==="EPERM"}}async function requestIfReachable(socketPath,name){let client=new KobeDaemonClient(socketPath);try{return await client.request(name,{})}catch{return null}finally{client.close()}}function fmtDuration(ms){let seconds=Math.floor(ms/1000);if(seconds<60)return`${seconds}s`;let minutes=Math.floor(seconds/60);if(minutes<60)return`${minutes}m ${seconds%60}s`;return`${Math.floor(minutes/60)}h ${minutes%60}m`}function describeFile(path){try{let stat=statSync2(path);return`present (${formatBytes(stat.size)}, modified ${stat.mtime.toISOString()})`}catch{return"absent"}}function taskCount(path){try{let parsed=JSON.parse(readFileSync3(path,"utf8"));return Array.isArray(parsed.tasks)?parsed.tasks.length:null}catch{return null}}function tailFile(path,count){try{return readFileSync3(path,"utf8").split(`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{loadPluginRegistry,readPluginManifest}from"./chunk-g2e1dmxh.js";import{CONTRIB_ENGINE_IDS,clearPluginEngines,registerPluginEngine,resetAvailableVendorsCache}from"./chunk-
|
|
2
|
+
import{loadPluginRegistry,readPluginManifest}from"./chunk-g2e1dmxh.js";import{CONTRIB_ENGINE_IDS,clearPluginEngines,registerPluginEngine,resetAvailableVendorsCache}from"./chunk-5zh5fcpe.js";import{getCustomEngineIds}from"./chunk-ejqs2ta9.js";function loadPluginEngines(homeDir){let registered=[];try{for(let entry of loadPluginRegistry(homeDir).plugins){if(!entry.enabled)continue;try{let{manifest}=readPluginManifest(entry.root);for(let engine of manifest.engines){let identity={shortName:engine.identity?.shortName??engine.name};if(registerPluginEngine(engine.id,{displayName:engine.name,defaultCommand:engine.command,...engine.processNames?{processNames:engine.processNames}:{},screenManifest:{rules:engine.rules},identity,...engine.firstMessageDelivery?{firstMessageDelivery:engine.firstMessageDelivery}:{}}))registered.push(engine.id);else console.warn(`[rove] plugin ${entry.id}: engine id \`${engine.id}\` shadows a built-in or shipped engine \u2014 skipped`)}}catch{}}}catch{}return registered}function reloadPluginEngines(homeDir){clearPluginEngines();let registered=loadPluginEngines(homeDir);return loadedOnce=registered,resetAvailableVendorsCache(),registered}var loadedOnce;function ensurePluginEnginesLoaded(){return loadedOnce??=loadPluginEngines(),loadedOnce}function registeredEngineIds(){return[...new Set([...CONTRIB_ENGINE_IDS,...getCustomEngineIds(),...ensurePluginEnginesLoaded()])]}
|
|
3
3
|
export{loadPluginEngines,reloadPluginEngines,ensurePluginEnginesLoaded,registeredEngineIds};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{CURRENT_VERSION,repoSlug}from"./chunk-
|
|
2
|
+
import{CURRENT_VERSION,repoSlug}from"./chunk-n3b6yr9e.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
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{isDev}from"./chunk-q5jhy3t8.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.
|
|
2
|
+
import{isDev}from"./chunk-q5jhy3t8.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.177",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.KOBE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
|
|
3
3
|
export{package_default,CURRENT_VERSION,PACKAGE_NAME,repoSlug,UPDATE_SCRIPT_URL,UPDATE_COMMAND,owningNpmPrefix,recommendedGlobalInstallCommand,BREAKING_VERSIONS,breakingVersionsCrossed,RELEASE_CHANNELS,DEFAULT_RELEASE_CHANNEL,channelOf,isNewerSemver,compareSemver,checkLatestVersion,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,releasePageUrl};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{pathRejection,projectRejection,rejectionReason}from"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-sb0ns0c7.js";import"./chunk-f10n6063.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{rejectionReason,projectRejection,pathRejection};
|