@sma1lboy/rove 0.9.84 → 0.9.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +10 -10
- package/dist/cli/kobe-run.js +10 -10
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/rove-run.js +10 -10
- package/dist/cli/rove.js +1 -1
- package/dist/skills/rove/SKILL.md +17 -7
- package/dist/skills/rove/references/api-flags.md +143 -53
- package/package.json +1 -1
package/dist/cli/rove.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{join as z1}from"node:path";import{createInterface as $1}from"node:readline/promises";import{pathToFileURL as J1}from"node:url";import{spawnSync as h}from"node:child_process";import{constants as t,accessSync as u}from"node:fs";import{homedir as o}from"node:os";import{basename as r,delimiter as l,dirname as i,join as q}from"node:path";import{fileURLToPath as U}from"node:url";var c={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.
|
|
2
|
+
import{join as z1}from"node:path";import{createInterface as $1}from"node:readline/promises";import{pathToFileURL as J1}from"node:url";import{spawnSync as h}from"node:child_process";import{constants as t,accessSync as u}from"node:fs";import{homedir as o}from"node:os";import{basename as r,delimiter as l,dirname as i,join as q}from"node:path";import{fileURLToPath as U}from"node:url";var c={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.86",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/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:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/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:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.17","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var x="rove",w="kobe";var E="ROVE_INVOKED_AS";function Y(b=process.env){return b[E]===x?x:w}var K="ROVE_BUN",a="ROVE_NO_BUN_BOOTSTRAP",p="ROVE_SKIP_BUN_CHECK",F=c.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0",B=(b)=>{try{return u(b,t.X_OK),!0}catch{return!1}},e=(b)=>b==="win32"?"bun.exe":"bun",n=(b)=>{let W=h(b,["--version"],{encoding:"utf8",timeout:5000});if(W.error||W.status!==0)return null;return W.stdout?.split(`
|
|
3
3
|
`)[0]?.trim()??""};function g(b){return b.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function j(b,W=F){let k=g(b),J=g(W);if(!k||!J)return!0;let $=k.split(".").map(Number),z=J.split(".").map(Number);for(let Q=0;Q<3;Q++){let H=$[Q]??0,Z=z[Q]??0;if(H!==Z)return H>Z}return!0}function G(b=process.env){return b[p]==="1"}function C(b={}){let W=b.env??process.env,k=b.platform??process.platform,J=b.home??W.HOME??W.USERPROFILE??o(),$=e(k),z=[],Q=W[K]?.trim();if(Q)z.push(Q);for(let P of(W.PATH??W.Path??"").split(l))if(P)z.push(q(P,$));let H=W.BUN_INSTALL?.trim();if(H)z.push(q(H,"bin",$));if(J)z.push(q(J,".bun","bin",$));let Z=b.launcherDir;if(Z)z.push(q(Z,"..","..","node_modules","bun","bin",$)),z.push(q(Z,"..","..","..","bun","bin",$));return z}function b1(b={}){let W=b.isExecutable??B;return C(b).find((k)=>W(k))??null}function L(b={}){let W=b.isExecutable??B,k=b.bunVersionOf??n;if(G(b.env??process.env))return{bun:b1(b),stale:null,unusable:null};let J=null,$=null;for(let z of C(b)){if(!W(z))continue;let Q=k(z);if(Q===null){$??=z;continue}if(j(Q))return{bun:z,stale:J,unusable:$};J??={path:z,version:g(Q)??Q}}return{bun:null,stale:J,unusable:$}}function O(b){return i(U(b))}function M(b){return r(U(b)).replace(/\.[cm]?[jt]s$/,"")}function W1(b=process.platform){return b==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function T(b=Y(),W=process.platform){let k=W==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${b}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${k}`," 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: ${K}=/path/to/bun`,""].join(`
|
|
4
4
|
`)}function D(b,W,k=Y()){return[`${k}: this machine's Bun is too old for Rove — found ${W} at ${b}, need ${F} 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: ${K}=/path/to/bun`,`Run on this one anyway (unsupported, terminals will be blank): ${p}=1`,""].join(`
|
|
5
5
|
`)}function s(b,W=Y()){return[`${W}: the Bun at ${b} could not be run — \`${b} --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: ${K}=/path/to/bun`,""].join(`
|
|
@@ -3,7 +3,7 @@ name: rove
|
|
|
3
3
|
description: 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.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- rove-skill-version:
|
|
6
|
+
<!-- rove-skill-version: 41 — bump in lockstep with KOBE_SKILL_VERSION (src/lib/skill-install.ts). -->
|
|
7
7
|
|
|
8
8
|
# Rove shell control
|
|
9
9
|
|
|
@@ -229,12 +229,22 @@ Four names that have actually been guessed wrong here: `add --vendor` is
|
|
|
229
229
|
`--prompt` (`--text` belongs to `note`); `issue-list` has no `--state` at all
|
|
230
230
|
— filter its JSON yourself.
|
|
231
231
|
|
|
232
|
-
**[`references/api-flags.md`](references/api-flags.md) is every verb and flag
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
232
|
+
**[`references/api-flags.md`](references/api-flags.md) is every verb and flag.**
|
|
233
|
+
Find your section by what you were ASKED, not by Rove's noun for it:
|
|
234
|
+
|
|
235
|
+
| You are asked to … | Read section |
|
|
236
|
+
|---|---|
|
|
237
|
+
| schedule / recur / cron / "every morning" / "keep messaging one window" / 定时 / 每天自动 | routines |
|
|
238
|
+
| a GitHub issue, "file it upstream" / 提 issue | workitems |
|
|
239
|
+
| track work in Rove's own backlog, move a kanban card | issues |
|
|
240
|
+
| remember this for the repo, leave a field note / 记一笔 | drive |
|
|
241
|
+
| what did the agent do, per-turn cost, read its screen | read |
|
|
242
|
+
| make / rename / retarget / land / close a task | create / edit / lifecycle |
|
|
243
|
+
| materialize or adopt a checkout | worktree |
|
|
244
|
+
| which engines exist, send Rove product feedback | discover / feedback |
|
|
245
|
+
| an error code came back, `nextCommandArgs` | Error codes |
|
|
246
|
+
|
|
247
|
+
Reach for `schema` when the binary and that file disagree.
|
|
238
248
|
|
|
239
249
|
```bash
|
|
240
250
|
rove api schema --verb add # or --group create, --all
|
|
@@ -9,6 +9,11 @@ Authoritative source is still the binary — `rove api schema --verb <name>` or
|
|
|
9
9
|
`rove api <verb> --help`. Read that when this file and a rejection disagree;
|
|
10
10
|
the CLI is what ships.
|
|
11
11
|
|
|
12
|
+
Every fenced block below is GENERATED from the same verb specs `schema`
|
|
13
|
+
serves (`bun scripts/gen-skill-api-flags.ts`); the prose between them is
|
|
14
|
+
written by hand. Notation: `(REQ)` required, `(x)` the default when the flag is
|
|
15
|
+
omitted, `{a|b}` the allowed values, `--a|--b` two spellings of one choice.
|
|
16
|
+
|
|
12
17
|
Global: `--pretty` (readable JSON), `--help` (usage, exit).
|
|
13
18
|
Every `--repo` resolves relative paths against `$PWD` and wants the git toplevel.
|
|
14
19
|
|
|
@@ -52,24 +57,32 @@ Seeing one of these in guidance means that guidance predates the rename —
|
|
|
52
57
|
|
|
53
58
|
## read
|
|
54
59
|
|
|
60
|
+
<!-- generated:begin read -->
|
|
55
61
|
```text
|
|
56
|
-
list
|
|
57
|
-
get-task
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
list (none)
|
|
63
|
+
get-task --task-id(REQ)
|
|
64
|
+
pty-list (none)
|
|
65
|
+
collect --task-ids <a,b,c> --group --repo
|
|
66
|
+
digest --repo(REQ) --since-days(7)
|
|
67
|
+
agent-turns --task-id --repo --since-days(7) --limit(200)
|
|
68
|
+
inspect --task-id
|
|
69
|
+
read-output --task-id --tab --source{auto|history|terminal}(auto) --cursor --limit(40)
|
|
64
70
|
```
|
|
71
|
+
<!-- generated:end -->
|
|
72
|
+
|
|
73
|
+
`get-task` is the read before `send --tab` — one task plus its `.tabs[]`.
|
|
74
|
+
`collect` is the comparison snapshot across tasks: pass `--group <groupId>`
|
|
75
|
+
(what `add --count` returned), a `--task-ids` csv, or a `--repo`; `inspect` is
|
|
76
|
+
the wider diagnostic — daemon activity, a pty walk, and every tab snapshot.
|
|
65
77
|
|
|
66
78
|
`pty-list` is what `NO_ENGINE_TAB`'s hint points at: when `.tabs[]` and reality
|
|
67
|
-
disagree, it is the ground truth for what is actually alive
|
|
79
|
+
disagree, it is the ground truth for what is actually alive — key, alive, pid,
|
|
80
|
+
command, OSC title.
|
|
68
81
|
|
|
69
|
-
`read-output --limit` maxes at 50
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
`read-output --limit` maxes at 50. `--tab` is terminal-only — it cannot combine
|
|
83
|
+
with `--source history`. The cursor is pinned to one source/session/tab; a
|
|
84
|
+
moved target returns `SOURCE_CHANGED` rather than silently paging something
|
|
85
|
+
else.
|
|
73
86
|
|
|
74
87
|
`digest` and `agent-turns` are the measurement reads — `digest` aggregates a
|
|
75
88
|
repo's recent task + routine activity, `agent-turns` is per-turn telemetry
|
|
@@ -78,18 +91,22 @@ needs numbers, not when you want to know what a task is doing.
|
|
|
78
91
|
|
|
79
92
|
## drive
|
|
80
93
|
|
|
94
|
+
<!-- generated:begin drive -->
|
|
81
95
|
```text
|
|
82
|
-
send
|
|
83
|
-
dispatch
|
|
84
|
-
note
|
|
85
|
-
note-list
|
|
86
|
-
pane-open
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
send --task-id --prompt|--prompt-file(REQ) --tab --command --plain --allow-empty
|
|
97
|
+
dispatch --task-id(REQ) --prompt|--prompt-file(REQ) --tab
|
|
98
|
+
note --task-id(REQ) --text(REQ)
|
|
99
|
+
note-list --repo(REQ)
|
|
100
|
+
pane-open --task-id --tab --command --direction{right|down}(right)
|
|
101
|
+
--placement{split|tab}(split) --title
|
|
102
|
+
pane-close --task-id --title(REQ) --tab
|
|
103
|
+
tab-close --task-id(REQ) --tab(REQ)
|
|
104
|
+
notify --title(REQ) --kind(done) --task-id --source
|
|
105
|
+
prompt --title(REQ) --placeholder --initial --timeout
|
|
106
|
+
engine-report --task-id --kind(REQ) --engine --tab --detail
|
|
107
|
+
set-active --task-id --none
|
|
92
108
|
```
|
|
109
|
+
<!-- generated:end -->
|
|
93
110
|
|
|
94
111
|
**`note` is the repo's durable field-note store.** One line, a verified
|
|
95
112
|
conclusion another session could act on — it is appended to the repo's notes
|
|
@@ -97,6 +114,10 @@ conclusion another session could act on — it is appended to the repo's notes
|
|
|
97
114
|
dispatcher. Read them back with `note-list --repo`. This is the right home for
|
|
98
115
|
a resolved gotcha; an issue is for work that still needs doing.
|
|
99
116
|
|
|
117
|
+
`send --allow-empty` is the escape hatch for a `succeeded:` report from a task
|
|
118
|
+
that legitimately produced no commits (an investigation, a review, a question
|
|
119
|
+
answered); without it such a report is refused with `EMPTY_SUCCESS_REPORT`.
|
|
120
|
+
|
|
100
121
|
`notify --kind` styles the toast: `done`, `needs_input`, `error` get severity
|
|
101
122
|
treatment and an unread mark, anything else renders neutrally.
|
|
102
123
|
|
|
@@ -113,18 +134,36 @@ and ends that tab's hosted PTYs. It accepts engine, shell/command, and content
|
|
|
113
134
|
tabs; closing the last tab leaves the task open with no session. A missing or
|
|
114
135
|
already-closed id returns `TAB_NOT_FOUND` and points back to `get-task`.
|
|
115
136
|
|
|
137
|
+
`engine-report` is the engine adapter's own channel for reporting a session
|
|
138
|
+
event (`--kind`) back to the daemon — not a verb you reach for by hand.
|
|
139
|
+
|
|
140
|
+
`set-active` takes one or the other: a `--task-id` to focus, or `--none` to
|
|
141
|
+
clear the shared active task.
|
|
142
|
+
|
|
116
143
|
## create / edit / lifecycle
|
|
117
144
|
|
|
145
|
+
<!-- generated:begin create,edit,lifecycle -->
|
|
118
146
|
```text
|
|
119
|
-
add
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
147
|
+
add --repo(REQ) --title --branch --base-branch --command --count
|
|
148
|
+
--agents <claude:2,codex:1>
|
|
149
|
+
--status{backlog|in_progress|in_review|done|canceled|error}(backlog) --pin
|
|
150
|
+
--activate(false) --prompt|--prompt-file
|
|
151
|
+
rename --task-id(REQ) --title(REQ)
|
|
152
|
+
set-branch --task-id(REQ) --branch(REQ)
|
|
153
|
+
set-command --task-id(REQ) --command(REQ)
|
|
154
|
+
set-effort --task-id(REQ) --level(REQ)
|
|
155
|
+
set-status --task-id(REQ)
|
|
156
|
+
--status{backlog|in_progress|in_review|done|canceled|error}(REQ)
|
|
157
|
+
pin --task-id(REQ) --pinned(true)
|
|
158
|
+
land --task-id(REQ) --strategy{merge|squash}(merge) --delete-branch
|
|
159
|
+
--remove-worktree(true)
|
|
160
|
+
delete --task-id(REQ) --force --delete-branch --wait
|
|
127
161
|
```
|
|
162
|
+
<!-- generated:end -->
|
|
163
|
+
|
|
164
|
+
`set-command` takes effect on the NEXT launch only. `set-effort --level` is
|
|
165
|
+
engine-owned — the levels a vendor accepts come from its registry entry, so
|
|
166
|
+
check `engine-list` rather than guessing.
|
|
128
167
|
|
|
129
168
|
Task `--status` and issue `--status` are DIFFERENT enums — a task is
|
|
130
169
|
`backlog|in_progress|in_review|done|canceled|error`, an issue is
|
|
@@ -135,22 +174,29 @@ ahead (`EMPTY_BRANCH`; `EMPTY_BRANCH_DIRTY_WORKTREE` when the worktree still
|
|
|
135
174
|
holds the uncommitted work, with a send-back recovery path). Conflict aborts
|
|
136
175
|
cleanly and returns the conflicted files.
|
|
137
176
|
|
|
177
|
+
`delete --wait` is what turns "queued" into an answer — without it the call
|
|
178
|
+
returns before the worktree is gone.
|
|
179
|
+
|
|
138
180
|
## worktree
|
|
139
181
|
|
|
182
|
+
<!-- generated:begin worktree -->
|
|
140
183
|
```text
|
|
141
|
-
ensure-worktree
|
|
142
|
-
discover-adoptable
|
|
143
|
-
adopt
|
|
184
|
+
ensure-worktree --task-id(REQ)
|
|
185
|
+
discover-adoptable --repo(REQ)
|
|
186
|
+
adopt --repo(REQ) --worktree(REQ) --branch --command --title
|
|
144
187
|
```
|
|
188
|
+
<!-- generated:end -->
|
|
145
189
|
|
|
146
190
|
## issues (daemon-owned)
|
|
147
191
|
|
|
192
|
+
<!-- generated:begin issues -->
|
|
148
193
|
```text
|
|
149
194
|
issue-list --repo(REQ)
|
|
150
195
|
issue-create --repo(REQ) --title(REQ) --body
|
|
151
|
-
issue-
|
|
152
|
-
issue-
|
|
196
|
+
issue-set-status --repo(REQ) --id(REQ) --status{open|doing|hold|done}(REQ)
|
|
197
|
+
issue-update --repo(REQ) --id(REQ) --title --body --task
|
|
153
198
|
```
|
|
199
|
+
<!-- generated:end -->
|
|
154
200
|
|
|
155
201
|
`--id` is an int, not the ULID a task uses. `issue-update --task <taskId>` is
|
|
156
202
|
the kanban "move to In progress"; `--task none` unlinks. Kanban semantics are
|
|
@@ -161,31 +207,44 @@ in SKILL.md — do not move cards with `issue-set-status doing`.
|
|
|
161
207
|
Read-only against the repo's real GitHub issues; nothing is copied into Rove's
|
|
162
208
|
own store. These are the INBOUND user reports; Rove issues are the backlog.
|
|
163
209
|
|
|
210
|
+
<!-- generated:begin workitems -->
|
|
164
211
|
```text
|
|
165
|
-
workitem-list --repo(REQ) --state
|
|
166
|
-
|
|
212
|
+
workitem-list --repo(REQ) --state{open|closed|all}(open) --limit(20) --search --assignee
|
|
213
|
+
--label
|
|
214
|
+
workitem-start --repo(REQ) --number(REQ) --vendor{claude|codex|copilot|kimi}
|
|
215
|
+
--base-branch
|
|
167
216
|
```
|
|
217
|
+
<!-- generated:end -->
|
|
168
218
|
|
|
169
|
-
`workitem-start` creates a worktree +
|
|
170
|
-
issue title, body, and URL, and keeps a
|
|
171
|
-
`--vendor` (an engine enum), not
|
|
172
|
-
vocabulary survives.
|
|
219
|
+
`workitem-list --limit` caps at 50. `workitem-start` creates a worktree +
|
|
220
|
+
engine whose first message carries the issue title, body, and URL, and keeps a
|
|
221
|
+
link back to the issue. Note it takes `--vendor` (an engine enum), not
|
|
222
|
+
`--command` — the one place the older vocabulary survives.
|
|
173
223
|
|
|
174
224
|
## routines (scheduled prompts)
|
|
175
225
|
|
|
176
|
-
|
|
177
|
-
|
|
226
|
+
A cron rule + a prompt + a repo, owned by the daemon. By default each firing
|
|
227
|
+
creates a FRESH task — worktree, engine, delivered prompt. With
|
|
228
|
+
`--persistent-session` every firing lands in ONE standing task as the next
|
|
229
|
+
turn of the same conversation (a Claude Code-style routine: one window, one
|
|
230
|
+
vendor, messages keep arriving). An enabled routine holds the daemon alive so
|
|
231
|
+
it fires with no TUI attached.
|
|
178
232
|
|
|
233
|
+
<!-- generated:begin routine -->
|
|
179
234
|
```text
|
|
180
235
|
routine-list (none)
|
|
181
|
-
routine-create --repo(REQ) --name(REQ) --prompt(REQ) --schedule(REQ)
|
|
182
|
-
--vendor --base-branch --precheck
|
|
183
|
-
|
|
184
|
-
routine-
|
|
236
|
+
routine-create --repo(REQ) --name(REQ) --prompt|--prompt-file(REQ) --schedule(REQ)
|
|
237
|
+
--vendor{claude|codex|copilot|kimi} --base-branch --precheck
|
|
238
|
+
--precheck-timeout(120) --grace(60) --persistent-session --disabled
|
|
239
|
+
routine-update --id(REQ) --name --prompt|--prompt-file --schedule
|
|
240
|
+
--vendor{claude|codex|copilot|kimi} --base-branch --precheck
|
|
241
|
+
--precheck-timeout(120) --grace(60) --persistent-session
|
|
242
|
+
routine-set-enabled --id(REQ) --enabled(REQ)
|
|
185
243
|
routine-delete --id(REQ)
|
|
186
244
|
routine-run-now --id(REQ)
|
|
187
245
|
routine-runs --id(REQ)
|
|
188
246
|
```
|
|
247
|
+
<!-- generated:end -->
|
|
189
248
|
|
|
190
249
|
`--schedule` is five-field cron in the DAEMON HOST's local time
|
|
191
250
|
(`'0 9 * * MON-FRI'`). `--precheck` is a shell command run in the repo before
|
|
@@ -194,21 +253,50 @@ which is the cheap way to not burn a turn on "nothing to do". `--grace` is how
|
|
|
194
253
|
late a missed occurrence may still run after the daemon was down; only the
|
|
195
254
|
most recent missed occurrence ever runs.
|
|
196
255
|
|
|
256
|
+
Pick the mode by what the prompt DOES. A routine that EDITS code wants the
|
|
257
|
+
default: each run is its own branch you can review and land; a week of runs
|
|
258
|
+
piled onto one branch is a branch nobody can merge. A routine that ASKS the
|
|
259
|
+
same question every day (a trend check, a digest, "what changed since
|
|
260
|
+
yesterday?") is worthless from zero each morning — give it
|
|
261
|
+
`--persistent-session`. Its standing task is folded behind the sidebar's
|
|
262
|
+
`N routine sessions` row, raises an Inbox entry when a turn finishes, and
|
|
263
|
+
never wins the cold-start "which task to open" fallback. If the engine process
|
|
264
|
+
is gone when the next firing arrives (an overnight gap usually means it is),
|
|
265
|
+
the daemon respawns it in the SAME worktree — files and branch carry over, the
|
|
266
|
+
conversation does not — and records that run as `revived`, not `dispatched`.
|
|
267
|
+
|
|
268
|
+
**Routines take `--prompt` only.** Unlike `send`/`add`/`dispatch` there is no
|
|
269
|
+
`--prompt-file` here, so a prompt with backticks, `$vars` or quotes has no
|
|
270
|
+
escape hatch — write it with single quotes and keep `$` out of it, or set it
|
|
271
|
+
from the TUI.
|
|
272
|
+
|
|
273
|
+
A bare `--enabled` means true, so pausing a routine is
|
|
274
|
+
`routine-set-enabled --id <id> --enabled=false` (the same `=false` spelling
|
|
275
|
+
`pin --pinned=false` uses).
|
|
276
|
+
|
|
197
277
|
`routine-update --schedule` re-anchors the next run. `--precheck ''` clears it.
|
|
198
278
|
`routine-run-now` skips the precheck deliberately (asking for it IS the answer)
|
|
199
279
|
and does not shift the schedule. `routine-delete` leaves already-created tasks
|
|
200
280
|
alone.
|
|
201
281
|
|
|
202
|
-
Run statuses from `routine-runs`: `dispatched`, `
|
|
203
|
-
|
|
282
|
+
Run statuses from `routine-runs`: `dispatched`, `revived` (standing session
|
|
283
|
+
respawned — files kept, conversation did not), `deferred` (composer busy; the
|
|
284
|
+
prompt is queued in the Inbox, NOT lost), `skipped_precheck` (nothing to do),
|
|
285
|
+
`skipped_missed`, `skipped_unavailable`, `dispatch_failed`.
|
|
204
286
|
|
|
205
287
|
## discover / feedback
|
|
206
288
|
|
|
289
|
+
<!-- generated:begin discover,feedback -->
|
|
207
290
|
```text
|
|
208
|
-
schema
|
|
209
|
-
engine-list
|
|
210
|
-
feedback
|
|
291
|
+
schema --verb --group --all
|
|
292
|
+
engine-list (none)
|
|
293
|
+
feedback --title(REQ) --body(REQ) --category(feedback)
|
|
211
294
|
```
|
|
295
|
+
<!-- generated:end -->
|
|
296
|
+
|
|
297
|
+
Bare `schema` is the compact index; `--verb <name>` drills into one verb,
|
|
298
|
+
`--group <g>` lists one group, `--all` dumps everything. `engine-list` is the
|
|
299
|
+
ids + RAW launch command + protocol.
|
|
212
300
|
|
|
213
301
|
`feedback` opens a GitHub Discussion in the Rove repo through `gh` — Rove's own
|
|
214
302
|
product feedback channel, not a way to file work for another project (that is
|
|
@@ -225,6 +313,8 @@ Errors go to stderr as `{"error":{"message","code",...}}`. Most carry `hint`
|
|
|
225
313
|
| `BAD_FLAG` | flag not on that verb | check the table above, then `schema --verb <v>` |
|
|
226
314
|
| `TASK_NOT_FOUND` | id deleted or mistyped | `rove api list` |
|
|
227
315
|
| `NO_ENGINE_TAB` | live tabs exist, none is an engine | `--tab tab-N` from `pty-list`, or `--tab new` |
|
|
316
|
+
| `TAB_NOT_FOUND` | `--tab` names a closed/unknown tab | `get-task` for the live `.tabs[]` |
|
|
228
317
|
| `DISPATCHER_UNREACHABLE` | bare `send` reply, dispatcher gone | nothing alive to reply to — never silently spawns |
|
|
318
|
+
| `EMPTY_SUCCESS_REPORT` | `succeeded:` from a branch with 0 commits | commit first, or say so with `--allow-empty` |
|
|
229
319
|
| `SOURCE_CHANGED` | `read-output` cursor's target moved | re-read without the cursor |
|
|
230
320
|
| `EMPTY_BRANCH` | `land` on zero commits ahead | the worker committed nothing |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@sma1lboy/rove",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.86",
|
|
5
5
|
"description": "Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"terminal",
|