CLI reference
Everything the rove and kobe binaries do. The scriptable surface for agents and
scripts has its own page: rove api.
Two things stay authoritative if this page and the binary ever disagree:
rove --help for the command list, and rove api schema for the rove api
surface.
Install and update
Needs Bun ≥ 1.3.11, git, and at least one engine CLI on PATH.
bun install -g @sma1lboy/rove # install
bunx @sma1lboy/rove # try without installingThe installed package exposes both rove and kobe. rove is the canonical
entry point; kobe remains a fully supported compatibility alias. They run the
same commands against the same daemon, worktrees, and persisted state. This
rename uses ~/.rove and ~/.config/rove/state.json for canonical product
data. First launch copies supported legacy data without overwriting or removing
the old files; runtime and plugin paths retain their compatibility names.
rove update # latest
rove update 0.7.90 # pin a version
rove update list # browse recent versions
rove update dry-run # print the command without running itrove updates using whichever package manager owns the rove on your PATH,
so the new version can't land in a shadowed prefix. Manual fallback:
npm install -g @sma1lboy/rove@latest.
Some versions are marked breaking. Installing across one prints a heads-up,
and the next launch asks you to run rove reset first. Worktrees are never
touched.
Launching
rove # the TUI (first run: onboarding wizard)
rove . # open a directory as a task — the `code .` gesture
rove web # the browser dashboard on http://localhost:45174A typo never silently opens the TUI: an unknown subcommand prints usage and exits 2.
All commands
Usage: rove [command] [options]
Commands:
web [options] Launch the browser dashboard
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 `rove api --help`)
daemon <verb> Manage the daemon (start|stop|status|restart)
doctor [--report] Diagnose daemon/PTY/engines/git; --report writes a bundle
config [--path] Open Rove'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 Rove agent skill (install|status|command|print)
plugin <verb> Install and run plugins (install|link|list|action|…)
feedback Send feedback to GitHub Discussions
update [version|list] Self-update Rove, or browse versions with `list`
Options:
-v, --version Print version
-h, --help Print this help
--skill Print the agent skill file and exitManaging projects
rove add [path] # save a repo for the new-task picker (defaults to .)
rove remove [path] # forget it — files, worktrees, and tasks all stay
rove adopt [glob] [--repo <path>] [--vendor <engine>] [--yes]
# list/import existing git worktrees as tasksrove add needs a real git repo. It creates the project's sidebar row and
folds in any existing unlinked worktrees as tasks.
rove adopt scans the current repo by default; --repo <path> selects another
one and --vendor <engine> chooses the engine recorded on imported tasks. With
no glob it is a dry run that lists what it would import; pass a glob to filter
(rove adopt 'feature-*') and --yes / -y to actually do it.
Remote projects (experimental — enable Settings → Dev → Experimental first) can register an SSH host and create task worktrees there:
rove add --remote --host <host> --user <user> --path <basePath> \
[--port N] [--key [path] | --password]Auth is either --key (ssh-agent when you omit the path) or --password.
Password auth is macOS-only today: Rove prompts for it and stores only a
reference in state.json; the secret lives in the macOS keychain. Linux and
Windows reject --password, so use a key or ssh-agent there.
This is not remote-execution parity yet. Remote worktree creation is wired, but the current Hosted PTY engine launcher does not wrap the engine command in SSH. A remote-only worktree path therefore cannot be treated like a supported local engine cwd, and engine launch may fail. Files/diffs and repo init also lack full remote parity. Do not use this experiment as a security boundary or assume prompts, engine execution, or repository reads are confined to the SSH host.
web
rove web [--port <n>] [--routes-only] [--no-takeover]Serves the dashboard on :45174, plus a sidecar for browser terminal tabs.
--routes-only starts/verifies only the daemon-hosted HTTP/SSE routes, for a
separate Vite dev server. Normally Rove may replace an older Rove PTY sidecar
on <port + 2>; --no-takeover disables that replacement and never probes or
kills the prior sidecar.
ROVE_DAEMON_WEB_PORT is read when the daemon starts (0/off/false
disables its web transport). It is not a substitute for rove web --port:
rove web targets 45174 unless --port is present. Neither setting can
rebind a daemon that is already running; after changing the daemon port, run
rove daemon restart, then pass the same port to rove web.
completions
source <(rove completions zsh)
rove completions bash > ~/.bash_completion.d/rove
rove completions fish > ~/.config/fish/completions/rove.fishCompletes subcommands; each subcommand owns its own flags.
export
rove export [--json | --csv | --format <json|csv|table>]Prints your task list. Read-only and works with the daemon down, which is
what makes it different from rove api list. Columns: id, title, status, archived, vendor, branch, repo, worktreePath. Default is JSON; --format table aligns it for humans.
config
rove config [--path]Opens ~/.config/rove/state.json in your editor. See
Configuration.
theme
rove theme list
rove theme add <url|path> [--name <name>] [--force]
rove theme remove <name>User themes land in ~/.rove/themes/ and can shadow a bundled name. Bundled
themes can't be removed. See Themes.
repo
rove repo show [path]
rove repo set [path] --init-script <text> | --init-script-file <path>
[--init-prompt <text> | --init-prompt-file <path>]
rove repo unset [path] [--init-script] [--init-prompt]Sets a per-user init override for a repo. If the repo commits its own
.rove/init.sh / .rove/init-prompt.md, those win. Legacy .kobe files are
field-by-field fallbacks. Path defaults to the current directory. unset with
no flag clears both.
skill
rove skill install [--global|-g | --project|-p] [--agent NAME]…
rove skill status
rove skill command [--global|-g | --project|-p] [--agent NAME]…
# print, don't run
rove skill print # print the SKILL.md itselfInstalls the Rove agent skill — what teaches a coding agent to drive
rove api. Installs are global (user-level) by default: the skill
drives a machine-wide daemon, so one copy per machine keeps one staleness
lifecycle; --project / -p installs into the current project instead.
--global / -g restates the default explicitly. With no --agent it
detects your installed agents and asks. To name them yourself, repeat the flag
(--agent claude-code --agent codex; --agent=codex also works); a
comma-joined list is rejected rather than silently using only the first.
The skill ships inside the npm package, so nothing is downloaded.
rove --skill (top-level flag) is shorthand for rove skill print: it dumps
the bundled SKILL.md to stdout so an agent can learn the rove api surface in
one command — e.g. prompt your agent with read `rove --skill` then fan out tasks, no pre-installed skill required.
plugin
rove plugin install <owner/repo[/subdir]> [--yes] [--ref <rev>]
rove plugin link <dir> register a local directory (dev)
rove plugin list installed + linked plugins
rove plugin search [query] browse the marketplace
rove plugin outdated check installs against upstream
rove plugin update <id…> | --all [--yes] reinstall stale plugins
rove plugin enable <id> | disable <id> toggle without unregistering
rove plugin unlink <id> unregister a linked plugin
rove plugin uninstall <id-or-spec> unregister + remove the checkout
rove plugin config-dir <id> print its config directory
rove plugin log <id> [-n <count>] tail its command log
rove plugin action list [--plugin <id>]
rove plugin action invoke <plugin-id.action-id> [args…]
rove plugin pane open <plugin-id.pane-id> [--task <task-id>]Changes apply to a running daemon without a restart. Writing one:
Plugin authoring. Marketplace:
https://github.com/topics/rove-plugin. Repositories carrying the legacy
kobe-plugin topic remain included.
doctor
rove doctor [--report]Read-only check of your build, terminal, git, engine CLIs and logins, daemon,
running sessions, agent skill, and state files. Never changes anything.
--report also writes a bug bundle (diagnosis + recent logs + env) and
prints its path — attach that to bug reports. See
Troubleshooting.
reset
rove reset [--hard] [--yes]Recovers a wedged install: stops the daemon and the PTY host (ending all
background sessions). Never touches git worktrees. --hard also deletes
your task index and UI state. Asks for confirmation unless --yes.
daemon
rove daemon status # status JSON; exit 1 when nothing is running
rove daemon start # run in the FOREGROUND (this process becomes it)
rove daemon stop
rove daemon restart # stop, then respawn in the backgroundThe daemon auto-starts when the TUI or rove api needs it, so start is
mainly for debugging. Logs are at ~/.kobe/daemon.log — read them first when
something's wrong.
Working on Rove itself? Run
rove daemon restartafter editing daemon/orchestrator/engine code. Bun doesn't hot-reload.
feedback
rove feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]Opens a GitHub Discussion via the gh CLI (needs gh auth login).
--body-file - reads from stdin.
Internal subcommands
Not in --help, listed so they aren't a mystery if you see them:
rove pty-host— the process that owns embedded terminals so they survive TUI exits and daemon restarts. Spawned automatically.rove hook <verb>— fired by an engine's own hooks to report activity. It always exits 0 and never starts the daemon, so it can't fail your engine.
Exit codes
- 0 — success, including "already in that state" (
daemon stopwith no daemon). - 1 — runtime failure:
rove addon a non-repo, no editor found, no daemon fordaemon status, plugin errors. - 2 — bad invocation: unknown command, verb, or flag; missing value. Always comes with usage text.
rove api is the JSON-first surface (JSON on stdout, a JSON error envelope on
stderr). Everything else prints human text — for machine-readable task data
without a daemon, use rove export --json.
Environment variables
ROVE_* is the canonical spelling. Every one of these also accepts the
established KOBE_* name as a compatibility alias, and ROVE_* wins when both
are set — ROVE_HOME_DIR beats KOBE_HOME_DIR, ROVE_OPEN_EDITOR beats
KOBE_OPEN_EDITOR, and so on for the whole table.
| Variable | What it does |
|---|---|
ROVE_HOME_DIR | Move Rove's home-rooted task/runtime data; platform settings and engine-owned history keep their own locations |
ROVE_OPEN_EDITOR | Command that opens a worktree in a GUI editor (code, cursor, …) |
ROVE_DAEMON_WEB_PORT | Daemon web-transport port at daemon startup (default 45174; 0/off/false disables). rove web itself uses --port. |
ROVE_DEV=1 | Mark a developer checkout — hides the update chip |
ROVE_DEBUG=1 | Print full startup errors instead of one line |
ROVE_TASK_ID / ROVE_TAB_ID | Set inside tabs Rove opens; how rove api verbs resolve the calling task |
The KOBE_* aliases stay fully supported: engine hooks and older automation
keep reading KOBE_TASK_ID / KOBE_TAB_ID, which Rove exports beside the
canonical names.
ROVE_OPEN_EDITOR wins over Rove's auto-detection, and it's separate from the
editor.* settings, which pick your TTY editor.
Where state lives
Canonical product data under ~/.rove/ (or ROVE_HOME_DIR, with
KOBE_HOME_DIR as fallback):
tasks.json— the task indexworktrees/<repo-key>/<task-slug>/— per-task worktreesthemes/,settings/keybindings.yaml, issues, notes, and automations
Plus ~/.config/rove/state.json, the settings file rove config or
kobe config opens. Existing ~/.kobe/worktrees paths remain recognized and
are never copied or rewritten. Daemon/PTY runtime files and plugins.json +
plugins/<id>/ deliberately remain under ~/.kobe for continuity. The first
launch copies other supported legacy data additively and never deletes the
source or overwrites canonical files. Daemon-owned stores are copied at
new-daemon startup, only after the legacy writer has stopped.