@sma1lboy/rove 0.9.237 → 0.9.238

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/cli/{chunk-aj3fk7xz.js → chunk-0wgheepg.js} +2 -2
  2. package/dist/cli/{chunk-kavsx69v.js → chunk-1265fmzk.js} +1 -1
  3. package/dist/cli/{chunk-4bmap7dg.js → chunk-1bm6sryf.js} +1 -1
  4. package/dist/cli/{chunk-qyzvcgva.js → chunk-2yd128k1.js} +1 -1
  5. package/dist/cli/chunk-507zn8rs.js +3 -0
  6. package/dist/cli/{chunk-sp99y6eb.js → chunk-67ev8k22.js} +1 -1
  7. package/dist/cli/{chunk-63xy91mc.js → chunk-77w83wgh.js} +1 -1
  8. package/dist/cli/{chunk-40dk2add.js → chunk-8h0khkap.js} +1 -1
  9. package/dist/cli/{chunk-xhgmnvjz.js → chunk-9ek7xm94.js} +2 -2
  10. package/dist/cli/{chunk-hkq7c6hy.js → chunk-a1k2z44b.js} +1 -1
  11. package/dist/cli/{chunk-rvx5zz72.js → chunk-acw32w13.js} +1 -1
  12. package/dist/cli/{chunk-b9ywdsdj.js → chunk-aj7fkrha.js} +1 -1
  13. package/dist/cli/{chunk-3gmzrstj.js → chunk-b503z32q.js} +1 -1
  14. package/dist/cli/{chunk-4y1fdz34.js → chunk-be757xzj.js} +1 -1
  15. package/dist/cli/{chunk-tdze2mnn.js → chunk-bhqracn8.js} +1 -1
  16. package/dist/cli/{chunk-v4y0sf0x.js → chunk-grt1e2s8.js} +1 -1
  17. package/dist/cli/{chunk-5e39zhvj.js → chunk-hk8mc43r.js} +1 -1
  18. package/dist/cli/{chunk-5bsk7qmg.js → chunk-janvvpv5.js} +1 -1
  19. package/dist/cli/{chunk-12kgbrj1.js → chunk-mb1e73jm.js} +2 -2
  20. package/dist/cli/chunk-nntg9d85.js +3 -0
  21. package/dist/cli/{chunk-kbje1cpy.js → chunk-pzbrj3gd.js} +1 -1
  22. package/dist/cli/{chunk-efx1gqmp.js → chunk-r8xqvg26.js} +1 -1
  23. package/dist/cli/{chunk-1q8tbbpz.js → chunk-tcj36cqg.js} +1 -1
  24. package/dist/cli/{chunk-a8et9f63.js → chunk-y4048296.js} +1 -1
  25. package/dist/cli/{chunk-072x915d.js → chunk-yj5pjxx2.js} +1 -1
  26. package/dist/cli/{chunk-dhtsd706.js → chunk-z5fnv7nk.js} +4 -4
  27. package/dist/cli/{chunk-c4dx3er1.js → chunk-zwgns5ce.js} +1 -1
  28. package/dist/cli/index.js +3 -3
  29. package/dist/cli/kobe.js +1 -1
  30. package/dist/cli/pty-host-node.mjs +310 -9
  31. package/dist/cli/rove.js +1 -1
  32. package/dist/web-ui/assets/harness-CQ-1WI4q.js +87 -0
  33. package/dist/web-ui/assets/index-C4dLQEqf.css +1 -0
  34. package/dist/web-ui/assets/{index-D2wALq0b.js → index-_ttAn6pY.js} +2 -2
  35. package/dist/web-ui/index.html +2 -2
  36. package/dist/web-ui/pty-server.mjs +44 -0
  37. package/dist/web-ui/pty-session-lifecycle.mjs +41 -2
  38. package/package.json +1 -1
  39. package/dist/cli/chunk-1m7cp5ze.js +0 -3
  40. package/dist/cli/chunk-vz5g1p3w.js +0 -3
  41. package/dist/web-ui/assets/harness-CLsfHgXB.js +0 -86
  42. package/dist/web-ui/assets/index-B4knjCIs.css +0 -1
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{submitFeedback}from"./chunk-63xy91mc.js";import"./chunk-4y1fdz34.js";import{activeCliName}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var CLI_NAME=activeCliName(),FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
2
+ import{submitFeedback}from"./chunk-77w83wgh.js";import"./chunk-be757xzj.js";import{activeCliName}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";var CLI_NAME=activeCliName(),FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
3
3
  `);function usageError(message){process.stderr.write(`${CLI_NAME} feedback: ${message}
4
4
 
5
5
  ${FEEDBACK_USAGE}
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{matchPathGlob}from"./chunk-kg11c1py.js";import{argvHasFlag}from"./chunk-jvxh93nz.js";import{connectIfRunning}from"./chunk-wtqxv2rv.js";import"./chunk-pz907kve.js";import{expandTilde}from"./chunk-nvqdmx7q.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-05jej26n.js";import{CURRENT_VERSION}from"./chunk-4y1fdz34.js";import{rejectionReason}from"./chunk-mkksdcsw.js";import{activeCliName,prepareCliEnvironment}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-qagek3wg.js";import"./chunk-544bwsss.js";import"./chunk-hqbmzz4t.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import{pathSyntax}from"./chunk-f10n6063.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.KOBE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}`;let raw=errorMessage(err);return`${subject}: ${summarizeCliGitError(raw,opts.cwd)??raw}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-xhgmnvjz.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-s1e0e9hc.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-4d54zgc7.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-40dk2add.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-12kgbrj1.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-k7g060qr.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-c4dx3er1.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-3gmzrstj.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-3sg5v7cg.js");await runMachineSubcommand(args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-qyzvcgva.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-8pa1ph1s.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-v4y0sf0x.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-vz5g1p3w.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-cv1kaq8a.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-aj3fk7xz.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-wpsbyq4s.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-vzqrj32e.js"),{GitWorktreeManager}=await import("./chunk-9k47xr7m.js"),{Orchestrator}=await import("./chunk-md8k7c5w.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-7s1kx9ez.js"),{projectRejection}=await import("./chunk-9mtxxsb3.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${activeCliName()}: "${arg}" is not a directory (resolved to ${dir}).
4
- `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-hgx20x94.js");writeLastActiveTaskId(String(task.id))}});let{publishKobeTerminalTitle}=await import("./chunk-1tx1s5v6.js");publishKobeTerminalTitle();let{startTui}=await import("./chunk-1q8tbbpz.js");await startTui()}function topLevelUsage(cliName=activeCliName()){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|remove|list)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"].join(`
3
+ import{matchPathGlob}from"./chunk-kg11c1py.js";import{argvHasFlag}from"./chunk-jvxh93nz.js";import{connectIfRunning}from"./chunk-wtqxv2rv.js";import"./chunk-pz907kve.js";import{expandTilde}from"./chunk-nvqdmx7q.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-05jej26n.js";import{CURRENT_VERSION}from"./chunk-be757xzj.js";import{rejectionReason}from"./chunk-mkksdcsw.js";import{activeCliName,prepareCliEnvironment}from"./chunk-ppwpjm39.js";import"./chunk-fxs82dsx.js";import"./chunk-zyd6k6ak.js";import"./chunk-8hbtca1g.js";import"./chunk-hq2n27y1.js";import"./chunk-sb0ns0c7.js";import"./chunk-vnpqemb0.js";import"./chunk-9prawccj.js";import"./chunk-qagek3wg.js";import"./chunk-544bwsss.js";import"./chunk-hqbmzz4t.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import{pathSyntax}from"./chunk-f10n6063.js";import"./chunk-y8fqdnh3.js";import"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{resolve as resolve2}from"path";function debugEnabled(env){return env.KOBE_DEBUG==="1"||env.ROVE_DEBUG==="1"}function failureSubject(cliName,argv){let verb=argv[2];return verb&&!verb.startsWith("-")&&!verb.includes("/")?`${cliName} ${verb}`:cliName}function summarizeCliGitError(message,cwd){if(!/not a git repository/i.test(message))return null;return`${cwd} is not a git repository \u2014 run this inside one, or pass a repo path.`}function formatCliFailure(err,opts){let subject=failureSubject(opts.cliName,opts.argv);if(debugEnabled(opts.env))return`${subject}: ${String(err instanceof Error?err.stack??err:err)}`;let raw=errorMessage(err);return`${subject}: ${summarizeCliGitError(raw,opts.cwd)??raw}`}var DYNAMIC_COMMANDS=new Map([["completions",async(args)=>{let{runCompletionsSubcommand}=await import("./chunk-9ek7xm94.js");await runCompletionsSubcommand(args)}],["export",async(args)=>{let{runExportSubcommand}=await import("./chunk-s1e0e9hc.js");await runExportSubcommand(args)}],["repo",async(args)=>{let{runRepoSubcommand}=await import("./chunk-4d54zgc7.js");await runRepoSubcommand(args)}],["api",async(args)=>{let{runApiSubcommand}=await import("./chunk-8h0khkap.js");await runApiSubcommand(args)}],["update",async(args)=>{let{runUpdateSubcommand}=await import("./chunk-mb1e73jm.js");await runUpdateSubcommand(args)}],["theme",async(args)=>{let{runThemeSubcommand}=await import("./chunk-k7g060qr.js");await runThemeSubcommand(args)}],["feedback",async(args)=>{let{runFeedbackSubcommand}=await import("./chunk-zwgns5ce.js");await runFeedbackSubcommand(args)}],["daemon",async(args)=>{let{runDaemonSubcommand}=await import("./chunk-b503z32q.js");await runDaemonSubcommand(args)}],["machine",async(args)=>{let{runMachineSubcommand}=await import("./chunk-3sg5v7cg.js");await runMachineSubcommand(args)}],["doctor",async(args)=>{let{runDoctorSubcommand}=await import("./chunk-2yd128k1.js");await runDoctorSubcommand(args)}],["config",async(args)=>{let{runConfigSubcommand}=await import("./chunk-8pa1ph1s.js");await runConfigSubcommand(args)}],["reset",async(args)=>{let{runResetSubcommand}=await import("./chunk-grt1e2s8.js");await runResetSubcommand(args)}],["pty-host",async(args)=>{let{runPtyHostSubcommand}=await import("./chunk-507zn8rs.js");await runPtyHostSubcommand(args)}],["skill",async(args)=>{let{runSkillSubcommand}=await import("./chunk-cv1kaq8a.js");await runSkillSubcommand(args)}],["plugin",async(args)=>{let{runPluginSubcommand}=await import("./chunk-0wgheepg.js");await runPluginSubcommand(args)}],["hook",async(args)=>{let{runHookSubcommand}=await import("./chunk-wpsbyq4s.js");await runHookSubcommand(args)}]]);import{statSync}from"fs";import{resolve}from"path";async function openLocalOrchestrator(){let{TaskIndexStore}=await import("./chunk-vzqrj32e.js"),{GitWorktreeManager}=await import("./chunk-9k47xr7m.js"),{Orchestrator}=await import("./chunk-md8k7c5w.js"),store=new TaskIndexStore;return await store.load(),new Orchestrator({store,worktrees:new GitWorktreeManager})}async function withDaemonOrLocal(bridge){let client=await connectIfRunning();if(client)try{return await bridge.daemon(client)}finally{client.close()}let orch=await openLocalOrchestrator();return bridge.local(orch)}function isPathLikeArg(arg){return arg==="."||arg===".."||arg.startsWith("./")||arg.startsWith("../")||arg.startsWith(".\\")||arg.startsWith("..\\")||pathSyntax(arg).isAbsolute(arg)||arg.startsWith("/")||arg==="~"||arg.startsWith("~/")||arg.startsWith("~\\")}async function projectRootFor(dir){let{isGitRepo,resolveRepoRoot}=await import("./chunk-7s1kx9ez.js"),{projectRejection}=await import("./chunk-9mtxxsb3.js"),top=resolveRepoRoot(dir);if(top!==dir)return null;return projectRejection(top,isGitRepo,"explicit")?null:top}async function runOpenDirectory(arg){let dir=resolve(process.cwd(),expandTilde(arg)),isDir=!1;try{isDir=statSync(dir).isDirectory()}catch{isDir=!1}if(!isDir)process.stderr.write(`${activeCliName()}: "${arg}" is not a directory (resolved to ${dir}).
4
+ `),process.exit(1);let projectRoot=await projectRootFor(dir);await withDaemonOrLocal({daemon:async(client)=>{let taskId;if(projectRoot)taskId=(await client.request("task.ensureMain",{repo:projectRoot})).task.id;else taskId=(await client.request("task.openDir",{dir})).taskId;await client.request("task.setActive",{taskId})},local:async(orch)=>{let task=projectRoot?await orch.ensureMainTask(projectRoot):await orch.openDirectoryTask({dir}),{writeLastActiveTaskId}=await import("./chunk-hgx20x94.js");writeLastActiveTaskId(String(task.id))}});let{publishKobeTerminalTitle}=await import("./chunk-1tx1s5v6.js");publishKobeTerminalTitle();let{startTui}=await import("./chunk-tcj36cqg.js");await startTui()}function topLevelUsage(cliName=activeCliName()){return[`${cliName} ${CURRENT_VERSION}`,"",`Usage: ${cliName} [command] [options]`,"","Run with no command to launch PureTUI.",`Run \`${cliName} .\` (or \`${cliName} <path>\`) to open a directory as a standalone task.`,"","Commands:"," completions <shell> Generate shell completion script (bash/zsh/fish)"," add [path] Save a repo path for the new-task picker"," remove [path] Forget a saved project (inverse of add; non-destructive)"," adopt [glob] Import existing git worktrees as tasks"," export [--csv|--json] Print the task list (json/csv/table; daemon-free)"," repo <verb> Per-repo init script + first prompt (show|set|unset)",` api <verb> Scriptable RPC surface for agents (see \`${cliName} api --help\`)`," daemon <verb> Manage the daemon (start|stop|status|restart)"," machine <verb> Other computers running Rove (add|remove|list)"," doctor [--report|--fix] Diagnose daemon/PTY/engines/git; --fix walks the remedies",` config [--path] Open ${cliName}'s config file (state.json) in your editor`," reset [--hard] Stop runtimes; optionally wipe task/UI state"," theme <verb> Manage user themes (list|add|remove)",` skill <verb> Install the ${cliName} agent skill (install|status|command|print)`," plugin <verb> Install and run plugins (install|link|list|action|\u2026)"," feedback Send feedback to GitHub Discussions",` update [version|channel|list] Self-update ${cliName}, switch channel, or list versions`,"","Options:"," -v, --version Print version"," -h, --help Print this help"," --skill Print the agent skill file and exit"].join(`
5
5
  `)}prepareCliEnvironment();var CLI_NAME=activeCliName(),ADD_USAGE=[`Usage: ${CLI_NAME} add [path]`,` ${CLI_NAME} add --remote --host <host> --user <user> --path <basePath> [--port N] [--key [path] | --password]`,"","Save a repo for the new-task picker. With --remote, register an SSH-backed","project whose worktrees live on <host>; engine launch over SSH is pending.",""].join(`
6
6
  `);async function runAddSubcommand(rest){let arg=rest[0];if(arg==="--help"||arg==="-h"||arg==="help"){process.stdout.write(ADD_USAGE);return}if(arg==="--remote"){let{runAddRemote}=await import("./chunk-s1p650mm.js");await runAddRemote(rest.slice(1));return}if(arg?.startsWith("-"))process.stderr.write(`${CLI_NAME} add: unknown flag "${arg}"
7
7
 
@@ -22,4 +22,4 @@ ${ADOPT_USAGE}
22
22
  pass a path glob to adopt, e.g. ${CLI_NAME} adopt '${repo}/*' --yes`);return}let matched=worktrees.filter(isMatch);if(matched.length===0){console.log(`
23
23
  no worktrees match glob ${JSON.stringify(glob)}`);return}if(!yes){console.log(`
24
24
  ${matched.length} worktree(s) match \u2014 re-run with --yes to adopt them`);return}await adoptWorktreesInto(orch,repo,matched,vendor),console.log(`done \u2014 adopted ${matched.length} worktree(s)`)}function printTopLevelUsage(out){out.write(`${topLevelUsage()}
25
- `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-hkq7c6hy.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-cv1kaq8a.js");await runSkillSubcommand(["print"]);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishKobeTerminalTitle}=await import("./chunk-1tx1s5v6.js");publishKobeTerminalTitle();let{startTui}=await import("./chunk-1q8tbbpz.js");await startTui();let{runPendingWelcomeInstalls}=await import("./chunk-sp99y6eb.js");runPendingWelcomeInstalls()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
25
+ `)}var COMMANDS=new Map([["add",runAddSubcommand],["remove",runRemoveSubcommand],["adopt",runAdoptSubcommand],...DYNAMIC_COMMANDS]);async function main(){let[,,...rawArgs]=process.argv,[subcommand,...rest]=rawArgs;if(subcommand==="--version"||subcommand==="-v"||subcommand==="version"){let{CURRENT_VERSION:CURRENT_VERSION2}=await import("./chunk-a1k2z44b.js");console.log(`${CLI_NAME} ${CURRENT_VERSION2}`);return}if(subcommand==="--help"||subcommand==="-h"||subcommand==="help"){printTopLevelUsage(process.stdout);return}if(subcommand==="--skill"){let{runSkillSubcommand}=await import("./chunk-cv1kaq8a.js");await runSkillSubcommand(["print"]);return}let handler=subcommand!==void 0?COMMANDS.get(subcommand):void 0;if(handler){await handler(rest);return}if(subcommand!==void 0&&isPathLikeArg(subcommand)){await runOpenDirectory(subcommand);return}if(subcommand!==void 0)console.error(`${CLI_NAME}: unknown command '${subcommand}'`),printTopLevelUsage(process.stderr),process.exit(2);let{publishKobeTerminalTitle}=await import("./chunk-1tx1s5v6.js");publishKobeTerminalTitle();let{startTui}=await import("./chunk-tcj36cqg.js");await startTui();let{runPendingWelcomeInstalls}=await import("./chunk-67ev8k22.js");runPendingWelcomeInstalls()}main().catch((err)=>{console.error(formatCliFailure(err,{cliName:CLI_NAME,argv:process.argv,cwd:process.cwd(),env:process.env})),process.exit(1)});
package/dist/cli/kobe.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{join as G1}from"node:path";import{createInterface as K1}from"node:readline/promises";import{pathToFileURL as U1}from"node:url";import{spawnSync as V}from"node:child_process";import{constants as a,accessSync as e}from"node:fs";import{homedir as W1}from"node:os";import{basename as z1,delimiter as J1,dirname as Q1,join as G}from"node:path";import{fileURLToPath as N}from"node:url";var M={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.237",description:"Rove — 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/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev: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","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"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 scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var O="rove",T="kobe";var I=T;var L=O;var t="ROVE_INVOKED_AS";function K(W=process.env){return W[t]===L?L:I}var U="ROVE_BUN",Z1="ROVE_NO_BUN_BOOTSTRAP",R="ROVE_SKIP_BUN_CHECK",x=M.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",y=(W)=>{try{return e(W,a.X_OK),!0}catch{return!1}},$1=(W)=>W==="win32"?"bun.exe":"bun",X1=(W)=>{let z=V(W,["--version"],{encoding:"utf8",timeout:5000});if(z.error||z.status!==0)return null;return z.stdout?.split(`
2
+ import{join as G1}from"node:path";import{createInterface as K1}from"node:readline/promises";import{pathToFileURL as U1}from"node:url";import{spawnSync as V}from"node:child_process";import{constants as a,accessSync as e}from"node:fs";import{homedir as W1}from"node:os";import{basename as z1,delimiter as J1,dirname as Q1,join as G}from"node:path";import{fileURLToPath as N}from"node:url";var M={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.238",description:"Rove — 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/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev: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","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"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 scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var O="rove",T="kobe";var I=T;var L=O;var t="ROVE_INVOKED_AS";function K(W=process.env){return W[t]===L?L:I}var U="ROVE_BUN",Z1="ROVE_NO_BUN_BOOTSTRAP",R="ROVE_SKIP_BUN_CHECK",x=M.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",y=(W)=>{try{return e(W,a.X_OK),!0}catch{return!1}},$1=(W)=>W==="win32"?"bun.exe":"bun",X1=(W)=>{let z=V(W,["--version"],{encoding:"utf8",timeout:5000});if(z.error||z.status!==0)return null;return z.stdout?.split(`
3
3
  `)[0]?.trim()??""};function F(W){return W.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function C(W,z=x){let J=F(W),$=F(z);if(!J||!$)return!0;let Z=J.split(".").map(Number),Q=$.split(".").map(Number);for(let X=0;X<3;X++){let Y=Z[X]??0,b=Q[X]??0;if(Y!==b)return Y>b}return!0}function j(W=process.env){return W[R]==="1"}function k(W={}){let z=W.env??process.env,J=W.platform??process.platform,$=W.home??z.HOME??z.USERPROFILE??W1(),Z=$1(J),Q=[],X=z[U]?.trim();if(X)Q.push(X);for(let w of(z.PATH??z.Path??"").split(J1))if(w)Q.push(G(w,Z));let Y=z.BUN_INSTALL?.trim();if(Y)Q.push(G(Y,"bin",Z));if($)Q.push(G($,".bun","bin",Z));let b=W.launcherDir;if(b)Q.push(G(b,"..","..","node_modules","bun","bin",Z)),Q.push(G(b,"..","..","..","bun","bin",Z));return Q}function q1(W={}){let z=W.isExecutable??y;return k(W).find((J)=>z(J))??null}function B(W={}){let z=W.isExecutable??y,J=W.bunVersionOf??X1;if(j(W.env??process.env))return{bun:q1(W),stale:null,unusable:null};let $=null,Z=null;for(let Q of k(W)){if(!z(Q))continue;let X=J(Q);if(X===null){Z??=Q;continue}if(C(X))return{bun:Q,stale:$,unusable:Z};$??={path:Q,version:F(X)??X}}return{bun:null,stale:$,unusable:Z}}function _(W){return Q1(N(W))}function P(W){return z1(N(W)).replace(/\.[cm]?[jt]s$/,"")}function b1(W=process.platform){return W==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(W=K(),z=process.platform){let J=z==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${W}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${U}=/path/to/bun`,""].join(`
4
4
  `)}function g(W,z,J=K()){return[`${J}: this machine's Bun is too old for Rove — found ${z} at ${W}, need ${x} or newer.`,"","Rove's terminals are built on Bun's PTY API. An older Bun ignores it silently,","so every terminal and engine tab would open empty and stay empty.","","Upgrade Bun, then run this command again:"," bun upgrade # Bun installed itself (~/.bun)"," brew upgrade bun # Homebrew"," npm install -g bun@latest # npm-managed Bun","",`Have a newer Bun elsewhere? Point Rove at it: ${U}=/path/to/bun`,`Run on this one anyway (unsupported, terminals will be blank): ${R}=1`,""].join(`
5
5
  `)}function p(W,z=K()){return[`${z}: the Bun at ${W} could not be run — \`${W} --version\` failed or never returned.`,"","Rove skipped it rather than starting through it, which would hang or fail","with a message from that binary instead of this one.","","Reinstall Bun, then run this command again:"," curl -fsSL https://bun.sh/install | bash","",`Have a working Bun elsewhere? Point Rove at it: ${U}=/path/to/bun`,""].join(`
@@ -758,6 +758,278 @@ function foldDefaultColorQueries(previousCarry, chunkText) {
758
758
  return { slots, carry: trailingQueryPrefix(text.slice(end)) };
759
759
  }
760
760
 
761
+ // ../kobe-daemon/src/daemon/terminal-modes.ts
762
+ var DEFAULT_MODES = {
763
+ applicationCursorKeys: false,
764
+ applicationKeypad: false,
765
+ origin: false,
766
+ wraparound: true,
767
+ reverseWraparound: false,
768
+ cursorBlink: false,
769
+ cursorVisible: true,
770
+ insertMode: false,
771
+ sendFocus: false,
772
+ bracketedPaste: false,
773
+ synchronizedOutput: false,
774
+ altScreen: false,
775
+ mouseProtocol: "none",
776
+ mouseEncoding: "default"
777
+ };
778
+ var MOUSE_PROTOCOLS = { 9: "x10", 1000: "vt200", 1002: "drag", 1003: "any" };
779
+ var MOUSE_ENCODINGS = { 1006: "sgr", 1016: "sgr-pixels" };
780
+ var MAX_CARRY = 64;
781
+ var DA1_REPLY = "\x1B[?1;2c";
782
+ function freshModeTrack(modes = { ...DEFAULT_MODES }) {
783
+ return { modes, carry: "" };
784
+ }
785
+ function normalizeTerminalModes(raw) {
786
+ const modes = { ...DEFAULT_MODES };
787
+ if (typeof raw !== "object" || raw === null)
788
+ return modes;
789
+ const record = raw;
790
+ for (const key of Object.keys(DEFAULT_MODES)) {
791
+ if (typeof record[key] === "boolean" && typeof modes[key] === "boolean")
792
+ modes[key] = record[key];
793
+ }
794
+ if (Object.values(MOUSE_PROTOCOLS).includes(record.mouseProtocol))
795
+ modes.mouseProtocol = record.mouseProtocol;
796
+ if (Object.values(MOUSE_ENCODINGS).includes(record.mouseEncoding))
797
+ modes.mouseEncoding = record.mouseEncoding;
798
+ return modes;
799
+ }
800
+ function scanTerminalModes(track, chunk) {
801
+ const text = track.carry + chunk;
802
+ track.carry = "";
803
+ const replies = [];
804
+ let i = text.indexOf("\x1B");
805
+ while (i !== -1) {
806
+ if (i + 1 >= text.length) {
807
+ track.carry = "\x1B";
808
+ break;
809
+ }
810
+ const next = text.charCodeAt(i + 1);
811
+ if (next === 91) {
812
+ const end = csiEnd(text, i + 2);
813
+ if (end === -1) {
814
+ if (text.length - i <= MAX_CARRY)
815
+ track.carry = text.slice(i);
816
+ break;
817
+ }
818
+ if (end >= 0)
819
+ applyCsi(track.modes, text.slice(i + 2, end), text[end], replies);
820
+ i = text.indexOf("\x1B", end >= 0 ? end + 1 : i + 2);
821
+ continue;
822
+ }
823
+ if (next === 61)
824
+ track.modes.applicationKeypad = true;
825
+ else if (next === 62)
826
+ track.modes.applicationKeypad = false;
827
+ else if (next === 99)
828
+ track.modes = { ...DEFAULT_MODES };
829
+ i = text.indexOf("\x1B", i + 1);
830
+ }
831
+ return replies;
832
+ }
833
+ function terminalModePreamble(modes) {
834
+ const set = [];
835
+ const reset = [];
836
+ if (modes.applicationCursorKeys)
837
+ set.push(1);
838
+ if (modes.origin)
839
+ set.push(6);
840
+ if (!modes.wraparound)
841
+ reset.push(7);
842
+ if (modes.cursorBlink)
843
+ set.push(12);
844
+ if (!modes.cursorVisible)
845
+ reset.push(25);
846
+ if (modes.reverseWraparound)
847
+ set.push(45);
848
+ for (const [mode, protocol] of Object.entries(MOUSE_PROTOCOLS))
849
+ if (modes.mouseProtocol === protocol)
850
+ set.push(+mode);
851
+ for (const [mode, encoding] of Object.entries(MOUSE_ENCODINGS))
852
+ if (modes.mouseEncoding === encoding)
853
+ set.push(+mode);
854
+ if (modes.sendFocus)
855
+ set.push(1004);
856
+ if (modes.bracketedPaste)
857
+ set.push(2004);
858
+ let out = modes.altScreen ? "\x1B[?1049h" : "";
859
+ if (set.length > 0)
860
+ out += `\x1B[?${set.join(";")}h`;
861
+ if (reset.length > 0)
862
+ out += `\x1B[?${reset.join(";")}l`;
863
+ if (modes.applicationKeypad)
864
+ out += "\x1B=";
865
+ if (modes.insertMode)
866
+ out += "\x1B[4h";
867
+ return out;
868
+ }
869
+ function csiEnd(text, from) {
870
+ for (let j = from;j < text.length; j++) {
871
+ const c = text.charCodeAt(j);
872
+ if (c >= 64 && c <= 126)
873
+ return j;
874
+ if (c < 32 || c > 63)
875
+ return -2;
876
+ }
877
+ return -1;
878
+ }
879
+ function applyCsi(modes, body, final, replies) {
880
+ let start = 0;
881
+ let prefix = "";
882
+ const first = body.charCodeAt(0);
883
+ if (first >= 60 && first <= 63) {
884
+ prefix = body[0];
885
+ start = 1;
886
+ }
887
+ let end = body.length;
888
+ while (end > start && body.charCodeAt(end - 1) <= 47)
889
+ end--;
890
+ const intermediates = body.slice(end);
891
+ const params = body.slice(start, end).split(";").map((param) => Number.parseInt(param.split(":")[0] ?? "", 10) || 0);
892
+ if (intermediates === "" && (final === "h" || final === "l")) {
893
+ const on = final === "h";
894
+ if (prefix === "?")
895
+ for (const mode of params)
896
+ setPrivateMode(modes, mode, on);
897
+ else if (prefix === "" && params.includes(4))
898
+ modes.insertMode = on;
899
+ } else if (intermediates === "$" && final === "p" && (prefix === "?" || prefix === "")) {
900
+ const mode = params[0] ?? 0;
901
+ const value = prefix === "?" ? privateModeValue(modes, mode) : ansiModeValue(modes, mode);
902
+ replies.push(`\x1B[${prefix}${mode};${value}$y`);
903
+ } else if (intermediates === "!" && final === "p" && prefix === "") {
904
+ softReset(modes);
905
+ } else if (intermediates === "" && final === "c" && prefix === "" && (params[0] ?? 0) === 0) {
906
+ replies.push(DA1_REPLY);
907
+ }
908
+ }
909
+ function setPrivateMode(modes, mode, on) {
910
+ if (mode in MOUSE_PROTOCOLS) {
911
+ modes.mouseProtocol = on ? MOUSE_PROTOCOLS[mode] : "none";
912
+ return;
913
+ }
914
+ if (mode in MOUSE_ENCODINGS) {
915
+ modes.mouseEncoding = on ? MOUSE_ENCODINGS[mode] : "default";
916
+ return;
917
+ }
918
+ switch (mode) {
919
+ case 1:
920
+ modes.applicationCursorKeys = on;
921
+ break;
922
+ case 6:
923
+ modes.origin = on;
924
+ break;
925
+ case 7:
926
+ modes.wraparound = on;
927
+ break;
928
+ case 12:
929
+ modes.cursorBlink = on;
930
+ break;
931
+ case 25:
932
+ modes.cursorVisible = on;
933
+ break;
934
+ case 45:
935
+ modes.reverseWraparound = on;
936
+ break;
937
+ case 66:
938
+ modes.applicationKeypad = on;
939
+ break;
940
+ case 1004:
941
+ modes.sendFocus = on;
942
+ break;
943
+ case 47:
944
+ case 1047:
945
+ case 1049:
946
+ modes.altScreen = on;
947
+ break;
948
+ case 2004:
949
+ modes.bracketedPaste = on;
950
+ break;
951
+ case 2026:
952
+ modes.synchronizedOutput = on;
953
+ break;
954
+ }
955
+ }
956
+ function softReset(modes) {
957
+ Object.assign(modes, {
958
+ applicationCursorKeys: false,
959
+ applicationKeypad: false,
960
+ origin: false,
961
+ wraparound: true,
962
+ reverseWraparound: false,
963
+ cursorVisible: true,
964
+ insertMode: false,
965
+ sendFocus: false,
966
+ bracketedPaste: false,
967
+ synchronizedOutput: false
968
+ });
969
+ }
970
+ var NOT_RECOGNIZED = 0;
971
+ var SET = 1;
972
+ var RESET = 2;
973
+ var PERMANENTLY_SET = 3;
974
+ var PERMANENTLY_RESET = 4;
975
+ var flag = (on) => on ? SET : RESET;
976
+ function privateModeValue(modes, mode) {
977
+ if (mode in MOUSE_PROTOCOLS)
978
+ return flag(modes.mouseProtocol === MOUSE_PROTOCOLS[mode]);
979
+ if (mode in MOUSE_ENCODINGS)
980
+ return flag(modes.mouseEncoding === MOUSE_ENCODINGS[mode]);
981
+ switch (mode) {
982
+ case 1:
983
+ return flag(modes.applicationCursorKeys);
984
+ case 6:
985
+ return flag(modes.origin);
986
+ case 7:
987
+ return flag(modes.wraparound);
988
+ case 8:
989
+ return PERMANENTLY_SET;
990
+ case 12:
991
+ return flag(modes.cursorBlink);
992
+ case 25:
993
+ return flag(modes.cursorVisible);
994
+ case 45:
995
+ return flag(modes.reverseWraparound);
996
+ case 66:
997
+ return flag(modes.applicationKeypad);
998
+ case 67:
999
+ case 1005:
1000
+ case 1015:
1001
+ return PERMANENTLY_RESET;
1002
+ case 1004:
1003
+ return flag(modes.sendFocus);
1004
+ case 1048:
1005
+ return SET;
1006
+ case 47:
1007
+ case 1047:
1008
+ case 1049:
1009
+ return flag(modes.altScreen);
1010
+ case 2004:
1011
+ return flag(modes.bracketedPaste);
1012
+ case 2026:
1013
+ return flag(modes.synchronizedOutput);
1014
+ default:
1015
+ return NOT_RECOGNIZED;
1016
+ }
1017
+ }
1018
+ function ansiModeValue(modes, mode) {
1019
+ switch (mode) {
1020
+ case 2:
1021
+ return PERMANENTLY_RESET;
1022
+ case 4:
1023
+ return flag(modes.insertMode);
1024
+ case 12:
1025
+ return PERMANENTLY_SET;
1026
+ case 20:
1027
+ return RESET;
1028
+ default:
1029
+ return NOT_RECOGNIZED;
1030
+ }
1031
+ }
1032
+
761
1033
  // ../kobe-daemon/src/daemon/pty-freeze-store.ts
762
1034
  var FREEZE_VERSION = 1;
763
1035
  function freezeSession(session, now = new Date) {
@@ -772,6 +1044,7 @@ function freezeSession(session, now = new Date) {
772
1044
  totalBytes: session.totalBytes,
773
1045
  exit: session.exit,
774
1046
  ringB64: Buffer.concat(session.chunks).toString("base64"),
1047
+ ...session.ringModes ? { ringModes: session.ringModes.modes } : {},
775
1048
  updatedAt: now.toISOString()
776
1049
  };
777
1050
  }
@@ -782,13 +1055,20 @@ function thawRing(record, cap) {
782
1055
  } catch {
783
1056
  return null;
784
1057
  }
785
- const trimmed = ring.byteLength > cap ? ring.subarray(ring.byteLength - cap) : ring;
786
- return { chunks: trimmed.byteLength > 0 ? [trimmed] : [], bytes: trimmed.byteLength };
1058
+ const cut = Math.max(0, ring.byteLength - cap);
1059
+ const trimmed = ring.subarray(cut);
1060
+ const ringModes = freshModeTrack(normalizeTerminalModes(record.ringModes));
1061
+ if (cut > 0)
1062
+ scanTerminalModes(ringModes, ring.subarray(0, cut).toString("latin1"));
1063
+ return { chunks: trimmed.byteLength > 0 ? [trimmed] : [], bytes: trimmed.byteLength, ringModes };
787
1064
  }
788
1065
  function thawSession(record, cap) {
789
1066
  const ring = thawRing(record, cap);
790
1067
  if (!ring)
791
1068
  return null;
1069
+ const modes = freshModeTrack({ ...ring.ringModes.modes });
1070
+ for (const chunk of ring.chunks)
1071
+ scanTerminalModes(modes, chunk.toString("latin1"));
792
1072
  return {
793
1073
  key: record.key,
794
1074
  generation: randomUUID3(),
@@ -806,7 +1086,10 @@ function thawSession(record, cap) {
806
1086
  titleDecoder: new StringDecoder("utf8"),
807
1087
  colorQueryCarry: "",
808
1088
  defaultColors: DEFAULT_TERMINAL_COLORS,
1089
+ modes,
1090
+ ringModes: ring.ringModes,
809
1091
  sinks: new Map,
1092
+ emulatorSinks: new Set,
810
1093
  parked: false,
811
1094
  parkedScreenBytes: 0,
812
1095
  exit: record.exit,
@@ -1033,7 +1316,10 @@ function freshSessionState(key, spec, argv) {
1033
1316
  titleDecoder: new StringDecoder2("utf8"),
1034
1317
  colorQueryCarry: "",
1035
1318
  defaultColors: parseTerminalDefaultColors(spec.defaultColors) ?? DEFAULT_TERMINAL_COLORS,
1319
+ modes: freshModeTrack(),
1320
+ ringModes: freshModeTrack(),
1036
1321
  sinks: new Map,
1322
+ emulatorSinks: new Set,
1037
1323
  parked: false,
1038
1324
  parkedScreenBytes: 0,
1039
1325
  exit: null,
@@ -1256,11 +1542,16 @@ class PtyChildController {
1256
1542
  }
1257
1543
  onData(session, data) {
1258
1544
  const buf = typeof data === "string" ? Buffer.from(data, "utf8") : Buffer.from(data);
1259
- const colorQueries = foldDefaultColorQueries(session.colorQueryCarry, buf.toString("latin1"));
1545
+ const text = buf.toString("latin1");
1546
+ const colorQueries = foldDefaultColorQueries(session.colorQueryCarry, text);
1260
1547
  session.colorQueryCarry = colorQueries.carry;
1261
- for (const slot of colorQueries.slots) {
1548
+ const replies = colorQueries.slots.map((slot) => formatDefaultColorReply(slot, session.defaultColors));
1549
+ const modeReplies = scanTerminalModes(session.modes, text);
1550
+ if (session.emulatorSinks.size === 0)
1551
+ replies.push(...modeReplies);
1552
+ if (replies.length > 0) {
1262
1553
  try {
1263
- session.proc?.write(formatDefaultColorReply(slot, session.defaultColors));
1554
+ session.proc?.write(replies.join(""));
1264
1555
  } catch {}
1265
1556
  }
1266
1557
  scanOscTitle(session, buf);
@@ -1269,8 +1560,10 @@ class PtyChildController {
1269
1560
  session.totalBytes += buf.byteLength;
1270
1561
  while (session.bytes > this.deps.scrollbackCap && session.chunks.length > 1) {
1271
1562
  const dropped = session.chunks.shift();
1272
- if (dropped)
1273
- session.bytes -= dropped.byteLength;
1563
+ if (!dropped)
1564
+ break;
1565
+ session.bytes -= dropped.byteLength;
1566
+ scanTerminalModes(session.ringModes, dropped.toString("latin1"));
1274
1567
  }
1275
1568
  this.deps.onOutput?.(session, buf);
1276
1569
  }
@@ -1412,7 +1705,7 @@ class PtyHost {
1412
1705
  onSessionStart: () => this.opts.onSessionStart?.()
1413
1706
  });
1414
1707
  }
1415
- open(key, spec, token, sink, sinceOffset, sincePid) {
1708
+ open(key, spec, token, sink, sinceOffset, sincePid, answersQueries = false) {
1416
1709
  let session = this.sessions.get(key);
1417
1710
  let created = false;
1418
1711
  let respawned = false;
@@ -1430,6 +1723,10 @@ class PtyHost {
1430
1723
  if (defaultColors)
1431
1724
  session.defaultColors = defaultColors;
1432
1725
  session.sinks.set(token, sink);
1726
+ if (answersQueries)
1727
+ session.emulatorSinks.add(token);
1728
+ else
1729
+ session.emulatorSinks.delete(token);
1433
1730
  session.parked = false;
1434
1731
  session.parkedScreenBytes = 0;
1435
1732
  const windowStart = session.totalBytes - session.bytes;
@@ -1445,6 +1742,8 @@ class PtyHost {
1445
1742
  else
1446
1743
  this.parkRestoreFallbacks++;
1447
1744
  }
1745
+ if (!sinceValid)
1746
+ replay = Buffer.concat([Buffer.from(terminalModePreamble(session.ringModes.modes), "latin1"), replay]);
1448
1747
  return {
1449
1748
  replay: replay.toString("base64"),
1450
1749
  alive: session.alive,
@@ -1516,10 +1815,12 @@ class PtyHost {
1516
1815
  if (!session)
1517
1816
  return;
1518
1817
  session.sinks.delete(token);
1818
+ session.emulatorSinks.delete(token);
1519
1819
  this.applyParkedOnDetach(session, parked, parkedScreenBytes);
1520
1820
  }
1521
1821
  detachClient(token) {
1522
1822
  for (const session of this.sessions.values()) {
1823
+ session.emulatorSinks.delete(token);
1523
1824
  if (!session.sinks.delete(token))
1524
1825
  continue;
1525
1826
  this.applyParkedOnDetach(session);
@@ -1642,7 +1943,7 @@ function dispatchPtyRequest(req, client, deps) {
1642
1943
  cols: typeof payload.cols === "number" ? payload.cols : undefined,
1643
1944
  rows: typeof payload.rows === "number" ? payload.rows : undefined,
1644
1945
  defaultColors: parseTerminalDefaultColors(payload.defaultColors) ?? undefined
1645
- }, client, (frame) => deps.writeFrame(client, frame), typeof payload.sinceOffset === "number" ? payload.sinceOffset : undefined, typeof payload.sincePid === "number" ? payload.sincePid : undefined);
1946
+ }, client, (frame) => deps.writeFrame(client, frame), typeof payload.sinceOffset === "number" ? payload.sinceOffset : undefined, typeof payload.sincePid === "number" ? payload.sincePid : undefined, payload.answersQueries === true);
1646
1947
  }
1647
1948
  case "pty.write": {
1648
1949
  const payload = objectPayload(req.payload);
package/dist/cli/rove.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{join as G1}from"node:path";import{createInterface as K1}from"node:readline/promises";import{pathToFileURL as U1}from"node:url";import{spawnSync as V}from"node:child_process";import{constants as a,accessSync as e}from"node:fs";import{homedir as W1}from"node:os";import{basename as z1,delimiter as J1,dirname as Q1,join as G}from"node:path";import{fileURLToPath as N}from"node:url";var M={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.237",description:"Rove — 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/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev: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","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"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 scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var O="rove",T="kobe";var I=T;var L=O;var t="ROVE_INVOKED_AS";function K(W=process.env){return W[t]===L?L:I}var U="ROVE_BUN",Z1="ROVE_NO_BUN_BOOTSTRAP",R="ROVE_SKIP_BUN_CHECK",x=M.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",y=(W)=>{try{return e(W,a.X_OK),!0}catch{return!1}},$1=(W)=>W==="win32"?"bun.exe":"bun",X1=(W)=>{let z=V(W,["--version"],{encoding:"utf8",timeout:5000});if(z.error||z.status!==0)return null;return z.stdout?.split(`
2
+ import{join as G1}from"node:path";import{createInterface as K1}from"node:readline/promises";import{pathToFileURL as U1}from"node:url";import{spawnSync as V}from"node:child_process";import{constants as a,accessSync as e}from"node:fs";import{homedir as W1}from"node:os";import{basename as z1,delimiter as J1,dirname as Q1,join as G}from"node:path";import{fileURLToPath as N}from"node:url";var M={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.238",description:"Rove — 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/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev: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","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"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 scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var O="rove",T="kobe";var I=T;var L=O;var t="ROVE_INVOKED_AS";function K(W=process.env){return W[t]===L?L:I}var U="ROVE_BUN",Z1="ROVE_NO_BUN_BOOTSTRAP",R="ROVE_SKIP_BUN_CHECK",x=M.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",y=(W)=>{try{return e(W,a.X_OK),!0}catch{return!1}},$1=(W)=>W==="win32"?"bun.exe":"bun",X1=(W)=>{let z=V(W,["--version"],{encoding:"utf8",timeout:5000});if(z.error||z.status!==0)return null;return z.stdout?.split(`
3
3
  `)[0]?.trim()??""};function F(W){return W.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function C(W,z=x){let J=F(W),$=F(z);if(!J||!$)return!0;let Z=J.split(".").map(Number),Q=$.split(".").map(Number);for(let X=0;X<3;X++){let Y=Z[X]??0,b=Q[X]??0;if(Y!==b)return Y>b}return!0}function j(W=process.env){return W[R]==="1"}function k(W={}){let z=W.env??process.env,J=W.platform??process.platform,$=W.home??z.HOME??z.USERPROFILE??W1(),Z=$1(J),Q=[],X=z[U]?.trim();if(X)Q.push(X);for(let w of(z.PATH??z.Path??"").split(J1))if(w)Q.push(G(w,Z));let Y=z.BUN_INSTALL?.trim();if(Y)Q.push(G(Y,"bin",Z));if($)Q.push(G($,".bun","bin",Z));let b=W.launcherDir;if(b)Q.push(G(b,"..","..","node_modules","bun","bin",Z)),Q.push(G(b,"..","..","..","bun","bin",Z));return Q}function q1(W={}){let z=W.isExecutable??y;return k(W).find((J)=>z(J))??null}function B(W={}){let z=W.isExecutable??y,J=W.bunVersionOf??X1;if(j(W.env??process.env))return{bun:q1(W),stale:null,unusable:null};let $=null,Z=null;for(let Q of k(W)){if(!z(Q))continue;let X=J(Q);if(X===null){Z??=Q;continue}if(C(X))return{bun:Q,stale:$,unusable:Z};$??={path:Q,version:F(X)??X}}return{bun:null,stale:$,unusable:Z}}function _(W){return Q1(N(W))}function P(W){return z1(N(W)).replace(/\.[cm]?[jt]s$/,"")}function b1(W=process.platform){return W==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(W=K(),z=process.platform){let J=z==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${W}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${U}=/path/to/bun`,""].join(`
4
4
  `)}function g(W,z,J=K()){return[`${J}: this machine's Bun is too old for Rove — found ${z} at ${W}, need ${x} or newer.`,"","Rove's terminals are built on Bun's PTY API. An older Bun ignores it silently,","so every terminal and engine tab would open empty and stay empty.","","Upgrade Bun, then run this command again:"," bun upgrade # Bun installed itself (~/.bun)"," brew upgrade bun # Homebrew"," npm install -g bun@latest # npm-managed Bun","",`Have a newer Bun elsewhere? Point Rove at it: ${U}=/path/to/bun`,`Run on this one anyway (unsupported, terminals will be blank): ${R}=1`,""].join(`
5
5
  `)}function p(W,z=K()){return[`${z}: the Bun at ${W} could not be run — \`${W} --version\` failed or never returned.`,"","Rove skipped it rather than starting through it, which would hang or fail","with a message from that binary instead of this one.","","Reinstall Bun, then run this command again:"," curl -fsSL https://bun.sh/install | bash","",`Have a working Bun elsewhere? Point Rove at it: ${U}=/path/to/bun`,""].join(`