Agtx Task Sweep
fynnfluegge/agtx
Breaks a conversation's results into feature-level tasks and pushes them to the agtx kanban board, where each task gets its own worktree and agent session.
A skill your agent uses when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell.
$ npx skills add Sma1lboy/rove --skill rove -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Sma1lboy/rove rove --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/rove .claude/skills/rove && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .claude/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Sma1lboy/rove/tree/main/.agents/skills/roveType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Sma1lboy/rove --skill rove -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Sma1lboy/rove rove --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/rove .agents/skills/rove && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .agents/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Sma1lboy/rove --skill rove -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Sma1lboy/rove rove --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/rove .cursor/skills/rove && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .cursor/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Sma1lboy/rove.git --path .agents/skills/rove--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Sma1lboy/rove --skill rove -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Sma1lboy/rove rove --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/rove .gemini/skills/rove && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .gemini/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Sma1lboy/rove roveInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Sma1lboy/rove --skill rove -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/rove .github/skills/rove && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .github/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Sma1lboy/rove --skill rove -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Sma1lboy/rove rove --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Sma1lboy/rove.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/rove .opencode/skills/rove && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "rove" agent skill from https://github.com/Sma1lboy/rove/tree/main/.agents/skills/rove into .opencode/skills/rove/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rove", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
roveA skill your agent uses when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell.
Rove is an agent skill from Sma1lboy/rove. Use when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell. Also the ONLY channel for messaging another agent session on this machine — rove api send, never a peer/MCP side channel.
Its SKILL.md is about 8.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/api-flags.md`).
It sits in Agent Workflows, covering Issue triage and Git worktrees. It works with Model Context Protocol and Git. The repository describes itself as: Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions. The licence is MIT.
Read from SKILL.md and the folder at commit 139a8cb. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitclaudekindFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Rove loads about 8.9k tokens when it runs, and up to ~13k if it reads all its reference files. Until then it costs about 69 tokens; SKILL.md has 4,427 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Sma1lboy/rove at commit 139a8cb, republished under its MIT licence (© Sma1lboy). 4,427 words, ~8,889 tokens.
.claude/skills/rove/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.<!-- rove-skill-version: 56 — bump in lockstep with ROVE_SKILL_VERSION (src/lib/skill-install.ts). -->
Use rove api to manage local coding tasks. Managed Tasks created by API
automation own a git Worktree and branch plus Hosted PTY engine tabs; project
main and directory Tasks reuse existing directories. API automation works
without an open TUI; prompted send and add ensure a target engine tab.
Check where you are before choosing how to delegate or parallelize:
test -n "${ROVE_TASK_ID:-}"When that passes, you are an engine session Rove manages — $ROVE_TASK_ID
is your task, $ROVE_TAB_ID your tab. Coordination should then go through
Rove, not around it, because work routed through rove api gets what
ad-hoc subprocesses never do: its own Worktree and branch (no file
collisions with you), a sidebar row with live state the user can watch,
lifecycle tracking, and an explicit outcome contract.
add --count N, not N hand-rolled subagents.add --prompt, not a raw claude -p
child the user cannot see or manage.send; comparing → collect;
finished your own task and were spawned by another → a bare send
(no --task-id) replies to the DISPATCHER — the exact task + tab that
created you, recorded at creation (.task.dispatcher on get-task).
If that tab died it falls back to the dispatcher task's live canonical
engine tab; nothing alive fails loud (DISPATCHER_UNREACHABLE) — it
never spawns a new engine, so a failed reply is visible, not fake-ok.send, and ONLY send
— never relay through the user, a side file, or a generic peer channel
(an MCP server offering to message "other instances" is exactly that
channel: it reaches a process, not a task, so nothing it delivers is
attributable, watchable, or replyable). Sent from
inside a Rove task, the prompt arrives prefixed [ROVE PEER] from "<title>" (task <id> — Rove agent skill /rove, read it once per session …),
so the receiver knows who is talking, that this skill is required reading,
and how to answer — the baked-in reply command is tab-precise
(--task-id <sender> --tab <sender's tab>), so peer conversations need
no coordinator and no human relay. That prefix is the contract: do not
strip it with --plain for
coordination messages (--plain is only for a verbatim paste the
receiver should treat as content, not conversation). Received a
[ROVE PEER] message yourself? Read this skill once per session. The
baked-in command identifies where a necessary reply goes; it is not an
instruction to acknowledge every message. Act on FYIs without replying.send carries text, but that text can carry FILES: peers share a
filesystem, so put the absolute path of a screenshot, log, diff, or any
artifact in the prompt and the receiver opens it with its own Read tool —
images included. An annotated screenshot beats a paragraph describing one;
prefer "see /path/to/shot.png — the arrow marks the broken card" over
re-narrating pixels. Paths under the sender's Worktree work too (worktrees
are world-readable locally); just never expect the receiver to WRITE
there.dispatch stays the dispatcher's verb (deliver-only into an
already-hosted session; never impersonate the user in someone else's
terminal).Your own engine's in-context subagents remain fine for read-only research/exploration inside your task — the boundary is WORK: anything that edits files, runs long, or the user should be able to see and steer belongs in a Rove task. Do not recursively fan out from a spawned task.
When the check fails, none of this applies — use rove api only if the
user asks for Rove by name.
| Term | What it is | Isolation it gives | Users also say |
|---|---|---|---|
| Task | one tracked workspace record — managed worktree, saved-project main, or existing directory | managed Tasks own files + branch; main/directory Tasks reuse files | "a task", "a new one", "a separate attempt" |
| Worktree | the isolated git working tree a managed Task owns (.task.worktreePath) — a filesystem address, never shown in the UI | — | "workspace", "this checkout", "this branch", "here" |
| Terminal Tab | one engine, shell, command, or content surface inside a Task | an engine tab has its own conversation, but every tab uses the SAME Task files | "tab", "chattab", "another chat", "a second agent on this" |
| Split | the tree that divides ONE Terminal Tab into several regions (the pane-open verb's unit; a leaf is not called a pane) | none — same session's screen, same files | "split it", "side by side", "put the logs next to it" |
Two of those colloquialisms are traps, so read them as INTENT, not as product terms: in Rove's own vocabulary Workspace is the center Terminal Tab region of the UI (CONTEXT.md), not a checkout, and ChatTab is retired vocabulary for Terminal Tab. A user saying "in this workspace" means the worktree they are looking at — answer the intent, keep writing the real term.
They nest — Task ⊃ Terminal Tab ⊃ Split — and isolation drops at every level down:
new Task → own worktree + own branch (parallel work can't collide)
new Tab → own engine session, SAME files (a helper in the same checkout)
new Split → same session's screen, one tab divided (a monitor beside the work)The distinction that decides every routing call: a new tab shares the
worktree and branch; only a new task gets its own. Two tabs in one task
edit the same files, so they can collide — that is a feature when the user
wants a helper in the same checkout, and a bug when they wanted parallel
attempts. A split isolates nothing at all: it is a layout, for watching
something (logs, btop, a test loop) next to the work — never the answer to
"do this work".
One boundary the isolation model does NOT cover: never git stash in a
managed worktree. The stash stack lives in the repo's common dir
(.git/refs/stash) and is shared by every linked worktree — two tasks that
stash in parallel can pop or drop each other's work. Commit instead; a
commit is per-branch and isolates exactly the way the model promises.
Inside a Rove session ($ROVE_TASK_ID non-empty — check first: it is what
makes the tab/split rows addressable at all), match top to bottom and take
the first row that fits:
| The user says | Lands in | Command |
|---|---|---|
| "you do it", "just fix it", "change X to Y" | you, right here | no Rove verb — edit the files yourself |
| "try it N ways", "compare approaches" | N new tasks | rove api add --repo "$PWD" --count N --prompt "…" |
| "split", "side by side", "keep an eye on X while…" | a new region in the CURRENT tab | rove api pane-open --command "…" |
| names a tab: "tell the agent in tab 3" | that exact tab | rove api send --task-id <id> --tab tab-3 --prompt "…" |
| a LOCATION word: "in this workspace/worktree/checkout", "on this branch", "here", "same task" | THIS task, a NEW Terminal Tab | rove api send --task-id "$ROVE_TASK_ID" --tab new --prompt "…" |
| names an ENGINE for the same files: "let codex take over here", "try this one with claude instead" | THIS task, a new tab pinned to that engine | rove api send --task-id "$ROVE_TASK_ID" --tab new --command codex --prompt "…" |
| anything else — no row above matched | a NEW task — new worktree + branch | rove api add --repo "$PWD" --prompt "…" |
Order is the tiebreak: a count ("3 ways in this workspace") beats a location word, and delegation language loses to "you do it" — the user asking YOU is not asking for a fleet. Two more rules the table can't show:
Outside a Rove session none of this applies: there is no "this task" to add
a tab to, so add (single or --count) is the only routing available.
echo "$ROVE_TASK_ID / $ROVE_TAB_ID" # who you are (empty = not a Rove session)
rove api get-task --task-id "$ROVE_TASK_ID" # .task.title, .task.branch, .task.id, .running, .tabs[]
# .task.worktreePath too — only if you are about to read/write its filesget-task is the per-task read that answers "what is my worktree, my
branch, and which sibling tabs exist" — .tabs[] carries each tab's id, kind,
vendor, liveVendor, lastTitle and alive, which is exactly the target list for
send --tab. A tab flagged unregistered: true is a live session the tab
snapshot lost; it is addressable like any other.
contextIf you spawned tasks, begin each turn with one read instead of your memory — between two of your turns a worker can finish, crash, stall on a permission prompt or get its PR approved, and you witnessed none of it:
rove api context --repo "$PWD" --textOne line per task, sorted so the first line is what needs a person next.
The group on each row is DERIVED from that task's report, PR observation,
engine activity and tab liveness — it is NOT the status field, which a
crashed worker leaves reading in_progress forever:
| group | your move |
|---|---|
waiting-on-you | answer it — permission prompt, quota wall, settled error, dead tab that delivered nothing |
landing | merge it — PR open and approved |
ready-for-review | read the diff — a report landed, nobody acted |
working | nothing. An engine is producing output |
idle | nothing. We looked; it is quiet |
unknown | look (get-task, read-output). We could NOT look — this is not "idle" |
Never read unknown as idle, and never act on a group as if it were a
verification: ready-for-review means a worker CLAIMED something, so
collect and the actual diff still decide whether it lands. Drop --text
for structured rows (group, rank, checkState, report) when you are
going to branch on the fields rather than read them.
context also carries the unhandled attention inbox and the repo's newest
field notes — the same notes a fresh session here is handed, so brief your
workers from those and don't re-derive what is already written down.
The sidebar row is the task's title; the line under it is its branch.
Nothing in Rove's UI ever renders worktreePath, so the directory name in it
(~/.rove/worktrees/<repo>/marlin) is a filesystem address the daemon picked
from an animal pool — the user has never read that word and cannot find it on
screen. Never name a task by its directory to a user or in a report.
Use the title when a human reads it, the task id (or its last six characters) when you need it to be unique, and both when you need both:
marlin opened a PR · landed in zorilla · see mammoth's branch"Skill version guard…" (task …CWWA) opened PR #972succeeded: guard now fails the build (branch fix/skill-version-bump)worktreePath earns a mention only when the sentence is about files on disk —
cd, a path in a command, a file you edited.
The repos on this machine are deliberately interdependent — one project using (and stumbling over) another is the normal case, not the edge case. Each saved project can keep a main task: a long-lived resident agent on that repo's own checkout. It is more than "task kind = existing directory" — it is that project's standing inbox, addressable from any other repo's session, and it dispatches what it receives.
So when work in repo A surfaces a defect in product B, the default is to file a request with B's main task — not to quietly patch around it in A. The test: would this bite someone else? A local workaround fixes only you; a fix in B fixes everyone. Work around locally to unblock yourself if you must, but file the report either way.
rove api list # find B's main task id
rove api get-task --task-id <their-main> # .tabs[] → the engine tab's id
rove api send --task-id <their-main> --tab tab-N --prompt "<report>"Address the engine tab explicitly (--tab tab-N from get-task's .tabs[],
kind == "engine"): a long-lived main task's engine tab is often not
tab-1, and an un-addressed send may refuse with NO_ENGINE_TAB rather
than guess.
A report worth sending carries: symptoms (what happened, concretely, how many times), root cause if you found it, why it is worth fixing (who else it bites), and suggestions without prescribing the implementation — the receiving project decides how to fix its own product.
Send the report — never add a task into someone else's repo. You hold
the problem-side context (symptoms, root cause, impact); only that project's
main agent holds the solution-side context (code structure, existing issues,
what's mid-flight, where this slots in the schedule). A task you compose
would bake YOUR guess at the fix into the brief, and that guess is usually
wrong — one field report here looked like "add a line to the docs" and
actually split into a docs fix plus a runtime-detection issue anchored in
files the reporter didn't know existed. You raise the problem; their main
agent decomposes it into tasks. That translation is the main task's whole
job, and it is why every project should keep one.
A managed task's worktree is a brand-new checkout: no node_modules, no
build artifacts, nothing a lockfile promises. Two consequences:
.rove/init.sh — it runs once
per worktree, before the engine, in the worktree (per-user override:
rove repo set --init-script; inspect with rove repo show, which lists
.rove/init.sh: absent when unset). Working in a repo that lacks one and
you just paid the install tax? Suggest adding it.Do not guess flags — but do not pay a round-trip for the ones you use every turn either. These five carry almost all traffic:
add --repo(REQ) --prompt --title --command --count --agents --activate
send --prompt|--prompt-file(REQ) --task-id --tab --command --plain
get-task --task-id(REQ) list (no flags)
collect --group <groupId> | --task-ids <csv> | --repoNames that have actually been guessed wrong here: add --vendor is
--command; read-output --task is --task-id; per-field verbs
(set-<field>, rename, pin) are all update --<field>; dispatch --text is
--prompt (--text belongs to note); issue-list has no --state at all
— filter its JSON yourself.
references/api-flags.md is every verb and flag.
Find your section by what you were ASKED, not by Rove's noun for it:
| You are asked to … | Read section |
|---|---|
| schedule / recur / cron / "every morning" / "keep messaging one window" / 定时 / 每天自动 | routines |
| a GitHub issue, "file it upstream" / 提 issue | workitems |
| track work in Rove's own backlog, move a kanban card | issues |
| remember this for the repo, leave a field note / 记一笔 | drive |
| what did the agent do, per-turn cost, read its screen | read |
| make / rename / retarget / land / close a task | create / edit / lifecycle |
| materialize or adopt a checkout | worktree |
| which engines exist, send Rove product feedback | discover / feedback |
an error code came back, nextCommandArgs | Error codes |
Reach for schema when the binary and that file disagree.
rove api schema --verb add # or --group create, --all
rove api <verb> --help
rove api engine-list # what you can launch, and with what commandCommands emit one JSON object; errors use
{"error":{"message","code",...}} on stderr. Common rejections also carry
hint (what to do) and nextCommandArgs (argv for the same Rove
executable — run rove <args...> verbatim to recover, e.g. ["api","list"]
after TASK_NOT_FOUND). Add --pretty for readable output.
# Create one task and start its first engine turn.
rove api add --repo "$PWD" --title "focused title" --command claude \
--prompt "<complete scoped instruction>"
# Parallel attempts of the same prompt (hard cap 10; prefer 3-4).
rove api add --repo "$PWD" --count 3 --prompt "<prompt>"
rove api add --repo "$PWD" --agents claude:2,codex:1 --prompt "<prompt>"
# Follow up. Use an explicit id for unattended work; the active task can drift.
# From inside a Rove task this auto-prefixes [ROVE PEER] provenance
# (sender + reply command) — `add --prompt` wears it too, so a dispatched
# task's opening brief carries its reply address; --plain sends verbatim.
#
# A prompt with backticks, $vars, or quotes goes through --prompt-file, NEVER
# a double-quoted --prompt: in double quotes `rove api send …` is command
# substitution — the shell RUNS it and ships its output, and the words vanish.
# Single quotes block $ROVE_TASK_ID too, so there is no quoting that fits both.
rove api send --task-id <id> --prompt "<complete next turn>" # plain text only
rove api send --task-id <id> --prompt-file - <<'EOF' # anything else
<turn — backticks, $vars, quotes, multi-line, all verbatim>
EOF
# Reply home: no --task-id inside a dispatched task = the dispatcher's tab.
rove api send --prompt "succeeded: <one line> (branch <final branch>)"
# A task can hold several Terminal Tabs. `get-task` lists ONE task's tabs (the
# usual read before addressing one); `inspect` is the wider diagnostic — every
# task's snapshot plus daemon activity and live pty sessions.
rove api inspect --task-id <id>
rove api send --task-id <id> --tab tab-3 --prompt "<turn>" # exact alive tab
rove api send --task-id <id> --tab new --prompt "<turn>" # fresh engine tab
# Same worktree, DIFFERENT agent — the API twin of the TUI's ctrl+e pick. The
# engine is pinned to that tab (survives restarts, unaffected by a later
# update --command) and the task's own engine is left alone. --tab new only.
rove api send --task-id <id> --tab new --command codex --prompt "<turn>"
rove api get-task --task-id <id>
# One read for the whole round — the groupId `add --count` returned. Never
# hand-copy N task ids across turns: collect by group. Lost the groupId? Any
# sibling task's `.groupId` in `list` output recovers it.
rove api collect --group <groupId> --pretty
rove api list --pretty.running is true / false / null. It means an ENGINE PROCESS is alive
in one of the task's engine tabs — a live shell, command, or content tab alone
does not count, and neither does an engine tab whose engine exited (the PTY
survives it as a login shell; each tab reports that as engineAlive). null
means the pty host could not be asked: "couldn't look", NOT "nothing is
running". Never act on null as if it were false — deleting a task on it
destroys a worktree that may hold live work. It is process truth, not
progress: a task whose work is merged and whose worker has signed off still
reads true until somebody deletes it (see "A task is finished when it is
GONE").
Omitting BOTH --task-id and --tab inside a task that has a dispatcher
targets that dispatcher's tab (see the reply rule above); otherwise the
target is the active task. Omitting only --tab targets a live engine tab
(tab-1 first, then any surviving engine tab). Trap: omitting only
--task-id while giving --tab tab-N inside a dispatched task delivers to
tab-N of the DISPATCHER's task — the dispatcher's id fills in for
--task-id, but an explicit --tab is kept, so your send --tab tab-3
lands in the middle of another session's tab-3, not yours. Target your own
task's tab with --task-id "$ROVE_TASK_ID" --tab tab-N. Only when the task
has NO live session at all does send
auto-start the canonical engine in the task's worktree (started: true in
the result marks that fresh session). If live tabs exist but none resolves
as an engine, it refuses with NO_ENGINE_TAB — address one with --tab tab-N or spawn one with --tab new; it never silently spawns a duplicate
engine. Its hint names pty-list — the live-PTY read (key, alive, pid,
command); use it when .tabs[] and reality disagree.
Split the workspace terminal the user is watching (tmux-style) or open a separate command tab — the attached TUI performs it, so this is a no-op headless:
# Split the focused tab; the pane runs the command through your login
# shell's `-ilc` (so it sees the same rc-exported PATH the engine tab does)
# and closes when it exits. Omit --command for an interactive shell.
rove api pane-open --command "btop"
rove api pane-open --direction down --command "watch -n1 git status -sb"
rove api pane-open --placement tab --title logs --command "tail -f app.log"
# Close panes you opened, by their --title (engine panes are never closed).
rove api pane-close --title logs
# Close one whole Terminal Tab by the id from `get-task .tabs[]`.
# This works with or without an attached TUI.
rove api tab-close --task-id <id> --tab tab-3
# Toast a one-liner in every attached Rove UI — surface "done / needs input /
# error" moments without touching any session (kinds get severity styling).
rove api notify --title "build green, artifacts in dist/" --kind doneDefaults: the caller's own task ($ROVE_TASK_ID, then the active task),
--placement split, --direction right. Alternate right/down to build a
grid; screen size bounds splitting — a split that would shrink any pane
below the minimum usable size (20×6 cells) falls back to a tab.
Panes land in the USER'S live workspace — open them when asked (monitors,
logs, dashboards), don't scatter panes for work add should own.
| Verb | Purpose |
|---|---|
update --task-id ID [--title T] [--branch B] [--command CMD] [--model M] [--effort L] [--pinned true|false] [--status S] [--report-branch B --report-pr N --report-summary TEXT] | Change any combination of fields in one call: validated first, applied branch → command → model/effort → title → pinned → status; not atomic (a mid-way failure reports applied). --command takes effect on the next launch; --tab tab-N with --title renames that tab. --status sets the lifecycle LABEL (backlog/in_progress/in_review/done/canceled/error) — cosmetic: the row, its Worktree, its branch and its engine all stay, and canceled does NOT close or clean up anything. --report-* (need --status) record what you delivered: update --task-id "$ROVE_TASK_ID" --status in_review --report-pr N |
set-active --task-id ID / --none | Change shared active task |
ensure-worktree --task-id ID | Materialize without starting an engine |
land --task-id ID [--strategy merge|squash] [--delete-branch] [--remove-worktree=false] | Merge the task's branch into the base repo's current branch; the Worktree is removed by default (--remove-worktree=false keeps it). The branch always stays; dirty/self/base removals are refused, outcome in the result's worktree field |
delete --task-id ID [--force] [--delete-branch] | Remove task + Worktree; the git branch stays unless --delete-branch (and --force never implies it) |
discover-adoptable --repo PATH | Find untracked Worktrees |
adopt --repo PATH --worktree PATH | Import a Worktree |
deletedelete is the ONLY verb that ends a task: it removes the row and its
Worktree, and the git branch survives as the durable record. update --status canceled is a label — the row, Worktree, branch and engine all stay, so a
"close" done that way changes nothing the user can see. Reach for delete
whether or not the work merged; an unmerged branch is still on disk
afterwards, which is what makes this recoverable.
There is no "hide the row without deleting" verb (archive was removed).
Deleting still needs the user to ask for it in that turn — say what you
would remove and wait. --delete-branch (or --force on a dirty Worktree)
destroys the recoverable half and needs its own explicit authorization; the
two flags are never implied by one another.
Issues are daemon-owned, not repo files:
rove api issue-list --repo "$PWD" --pretty
rove api issue-create --repo "$PWD" --title "title" --body "context"
rove api issue-update --repo "$PWD" --id <n> --status done
rove api issue-update --repo "$PWD" --id <n> --title "new" --body "body"
rove api issue-update --repo "$PWD" --id <n> --task <taskId> # link; `--task none` unlinksThe TUI and web render issues as a Backlog / In progress / Done board whose
columns derive from the issue's own lifecycle — do NOT move cards with
issue-update --status doing:
issue-update --task <taskId>
IS the move (typical flow: issue-create → add a task → link them).status done; the daemon mirrors it automatically when the
linked task finishes.open/doing/hold, unlinked).--command)Rove picks an engine by COMMAND, not by a vendor name. --command on add
and send --tab new takes either an engine id from rove api engine-list
(claude, codex, …, plus any preset the user registered) or a full command
line Rove runs verbatim:
rove api engine-list --pretty # ids + the RAW command each runs
rove api add --repo "$PWD" --command "codex --search" --prompt "…"Nothing validates an engine's flags — that is your job. Before dispatching
an unfamiliar engine or an unfamiliar flag, probe it yourself (<cmd> --help,
<cmd> --version) and only then compose the command. A bad command line
starts a session that dies or ignores you; Rove will not catch it for you.
Model is a conscious either/or — default to WITHOUT. Your own model knowledge is training-data stale; the user's engine default is fresher than your guess, and model ids you have never heard of are routinely valid.
--help first to confirm the flag exists;
never "correct" an unfamiliar model id to one you know).rove api add --repo "$PWD" --command claude --prompt "…" # user's default model
rove api add --repo "$PWD" --command claude --model "<id as the user wrote it>" \
--prompt "…" # user named a model this turn
# `--model` is gated per engine (BAD_MODEL when the engine has no model flag);
# `engine-list` prints each engine's `models` as suggestions, never a closed set.
# `--tier swift|standard|deep` fills engine+model+effort from Settings → Auto
# effort instead — exclusive with --command/--model/--effort.Omit --command to use the repo's default engine. engine-list's protocol
field says how much Rove understands about an entry — generic means it
launches fine but Rove reads no history and pre-answers no trust dialog.
Spawn a parallel round (add --count N / --agents) only when the user
requests parallel approaches, comparison, or an explicit count.
Give each round a scoped prompt, report returned IDs, then use
collect to compare. Do not recursively fan out from spawned tasks. Do not
poll send in a tight loop or use it as casual chat; every call is a full
engine turn.
Default to one complete task brief and one final outcome. Send an interim message only when it changes the recipient's next action: a blocking dependency, a file-ownership or interface conflict, a scope correction, or evidence that makes their current approach invalid. Resolve routine choices within the assigned scope without asking the dispatcher.
Do not send receipt acknowledgements, skill-loaded notices, starting-work announcements, routine progress, or acknowledgements of acknowledgements. An incoming message does not by itself require a response. Answer explicit questions once; bundle related findings and review corrections into one message with artifact paths. Forward only the facts the recipient needs, not the research trail or messages already delivered.
Before send, ask: does this unblock or change work now? If not, include it
in the final report. If a handoff contract has already been agreed, do not
reconfirm it. Avoid status pings; use a bounded read-only get-task or
collect when an actual coordination decision needs current state.
The dispatcher gives the user concise milestone updates; workers need not relay those updates back to the dispatcher. Do not create another task solely to coordinate or review a small, reversible change.
send)Outcomes are explicit, never inferred — and they travel as a MESSAGE to the spawning agent's engine tab, not as stored state nobody reads.
Worker side — a task created from inside another Rove task records its
dispatcher (the creating task + tab); when the work is finished, a bare
rove api send --prompt "<succeeded|failed>: <one line> (branch <final branch>)" routes the outcome back to that exact tab. Include the final
branch name — the spawner needs it to land. Use the BARE form: an explicit
--task-id <spawner> skips dispatcher routing and lands on that task's
canonical engine tab, which can be a different agent's session.
Name your branch before you report it. A new task starts on an
auto-generated placeholder branch (new-task, duck, …); you are the only
party who knows what the work turned out to be. Once the shape is clear,
rename it to a short descriptive name in this repo's own convention:
rove api update --task-id "$ROVE_TASK_ID" --branch <descriptive-slug>Do this while you work, not at the end — the branch name is what the user reads in the sidebar to tell your task from its siblings.
"Succeeded" means COMMITTED. Green tests in your working tree are not a
deliverable — the only thing land can merge is commits on your branch.
Before reporting success: git status clean, your work committed with a
real message (you wrote the code; you write its message). A worker that ran
everything, passed everything, and committed nothing has delivered nothing —
that exact mismatch has shipped empty merges before.
Rove checks this at the moment you claim it: a succeeded: report from a
managed task whose branch has 0 commits is refused with
EMPTY_SUCCESS_REPORT and never reaches the coordinator. Commit, then send.
When the task genuinely produced no commits — an investigation, a review, a
question answered — say so explicitly with --allow-empty:
rove api send --allow-empty --prompt "succeeded: no bug — root cause is upstream, see notes""CI is green" means checkState: passing. A local test run is not CI: it
does not run the other jobs, the other platform, or the merge gates. Rove
polls your PR's checks and keeps the answer on the task —
rove api get-task --task-id "$ROVE_TASK_ID" # .task.prStatus.checkStatenone (no PR yet) / pending (still running) / passing / failing /
unknown. Anything but passing is not green. Report what the field says,
not what your local run implied.
Coordinator side — do NOT block or poll. Keep working (or end your
turn); each worker's outcome arrives in your chat as a [ROVE PEER] message
with its task id. What arrives is the worker's claim, not Rove-verified —
verify the winner's actual diff before landing. Silence never proves a
worker died (it may be mid-turn or stuck on a permission prompt): peek with
collect/get-task, nudge with send, and never mark a silent task failed
or auto-retry it.
The dispatcher closes tasks. A worker cannot delete itself, so when it reports "done" the round is not over — its engine is still running, its Worktree still holds a branch, and its row is still in the sidebar.
None of these mean a task is finished:
| Looks final | What it actually is |
|---|---|
| the worker said "done" | a message; it has no verb to remove itself |
| its PR is MERGED | the code landed; the task did not move |
its issue is status done | a field in a different store |
update --status canceled | a label — see Lifecycle above |
The only evidence is that rove api list no longer shows it. Check the
task, not the paperwork:
rove api get-task --task-id <id> # .running true = its engine is still alive
rove api delete --task-id <id> --wait--wait is what turns "queued" into an answer; without it the call returns
before the Worktree is gone.
Before ending a round, sweep for both halves — they drift apart:
rove api list # tasks whose work is done but which are still here
git worktree list # directories no task claims (delete finds tasks by id,
# so a stray one is only reachable via git)A worker that has taken over main in its Worktree will block the dispatcher's
own checkout — a release cannot even start until that task is closed.
After comparing attempts, finish the round instead of leaving tasks behind:
# Land the winner: merge its branch into the base repo's CURRENT branch.
# Verify the base checkout is on the intended branch first.
rove api land --task-id <winner>
# Delete the losers: task + worktree go away, the git branch survives
# (recoverable). NOT --delete-branch — that destroys history and needs
# explicit user authorization.
rove api delete --task-id <loser1>
rove api delete --task-id <loser2>land refuses a dirty base checkout; on merge conflict it aborts cleanly and
returns the conflicted files for manual resolution. delete removes a
loser's Worktree but keeps its branch (recoverable); --delete-branch
destroys the history and is never part of closing a round without explicit
user authorization.
© Sma1lboy, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in .agents/skills/rove of Sma1lboy/rove.
Open the folder on GitHubat commit 139a8cb
Rove next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Rove this skillSma1lboy/rove | 160 | — | ~8.9k | Automated safety check: Pass | MIT | |
| Agtx Task Sweepfynnfluegge/agtx | 1.7k | — | ~1.7k | Automated safety check: Pass | Apache-2.0 | |
| Devcontainer Devstacklok/toolhive-studio | 170 | — | ~3.8k | Automated safety check: Notes | Apache-2.0 | |
| Parallel Feature ManagersCotal-AI/Cotal | 313 | — | ~5.3k | Automated safety check: Pass | Apache-2.0 | |
| PmApra-Labs/apra-fleet | 101 | — | ~5.4k | Automated safety check: Pass | Custom licence | |
| Swarmguaardvark/guaardvark | 257 | — | ~746 | Automated safety check: Pass | MIT |
fynnfluegge/agtx
Breaks a conversation's results into feature-level tasks and pushes them to the agtx kanban board, where each task gets its own worktree and agent session.
stacklok/toolhive-studio
Spin up and interact with ToolHive Studio's containerized dev environment (Xvfb + noVNC + DinD).
Cotal-AI/Cotal
Run several independent Cotal features concurrently by creating one Git worktree and one spawn-capable mesh manager per feature; each manager staffs a review panel in a dedicated channel, adds one…
Apra-Labs/apra-fleet
Project Manager skill. An agent skill from Apra-Labs/apra-fleet.
guaardvark/guaardvark
Launch and watch Guaardvark's Swarm Orchestrator: parallel coding agents, each in its own git worktree, working a markdown plan and merging back deterministically.
asheshgoplani/agent-deck
agent-deck, the terminal session manager for AI coding agents.
Sma1lboy/rove
Generate a single image from a text prompt using the MiniMax image generation API.
Sma1lboy/rove
Non-animation creative direction for HyperFrames videos. An agent skill from Sma1lboy/rove.
Sma1lboy/rove
Draft Rove release notes as Changesets. An agent skill from Sma1lboy/rove.
Sma1lboy/rove
Turn a rough idea, a bug, or a batch of unsolved problems into well-structured GitHub issue(s) and file them with gh, auto-classifying type + labels from the content (recommend, then confirm) and…
Sma1lboy/rove
Strip AI writing tells from Rove's user-facing prose — README, the docs/ pages that sync to docs.rove.run, landing copy, and release notes.
Sma1lboy/rove
A skill your agent uses for 'why does X work this way', 'why we picked Y', '为什么这么设计', design rationale, regressions, or where a magic number came from.
Works with
Categories
A skill your agent uses when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell. Rove is an agent skill from Sma1lboy/rove. Use when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell.
Rove fits situations like: controlling Rove tasks; parallel coding attempts; hosted agent sessions; the daemon-owned issue tracker from a shell.
Run `npx skills add Sma1lboy/rove --skill rove -a claude-code`. Or copy the skill folder (.agents/skills/rove in Sma1lboy/rove) into .claude/skills/rove in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Sma1lboy/rove --skill rove -a codex`. Or copy the skill folder (.agents/skills/rove in Sma1lboy/rove) into .agents/skills/rove in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Sma1lboy/rove --skill rove -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/rove, .gemini/skills/rove, .github/skills/rove and .opencode/skills/rove in your project.
Going by SKILL.md and its folder, Rove needs the command-line tools its instructions call (git, claude and kind).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Rove is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 8.9k tokens (SKILL.md is roughly 36k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 4.4k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Rove: Agtx Task Sweep (fynnfluegge/agtx, 1.7k stars), Devcontainer Dev (stacklok/toolhive-studio, 170 stars), Parallel Feature Managers (Cotal-AI/Cotal, 313 stars) and Pm (Apra-Labs/apra-fleet, 101 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Sma1lboy (a GitHub user) maintains it in Sma1lboy/rove, which has 160 GitHub stars. The repository holds 13 skills in this directory. The repository was last updated on October 8, 2026.
Source: Sma1lboy/rove on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.