autonomous Claude Code fleets

Feed it tickets. Harvest PRs.

A rough idea becomes a sharp spec. gv grab becomes a worker on your Claude plan, a flat-rate GLM plan, or OpenRouter — on your laptop or a cheap VPS — and a reviewed PR comes back. Questions reach your phone, answers pre-drafted. You focus on the product; you review and merge.

shopfront — one morning, on repeat
orchestrator chat
checkout is leaky — carts vanish on refresh, guests can't re-order, and support keeps asking for an order-status page
That's three tickets, each with criteria and a repo. Filing them now →
github.com/you/shopfront — issues
#14 persist cart to localStorage rotejust now
#15 guest re-order from order history just now
#16 public order-status page just now
$ gv grab ×3 · gv ls
shop-14·zai ⚙ working — flat-rate GLM, $0 marginal
shop-14·zai ✓ PR #98 open · CI running
shop-15 ⚙ working — your Claude plan
shop-16@vps ⚙ working — on the server, laptop's closed
main
✓ PR #98 merged persist cart zai · $0.41
✓ PR #99 merged guest re-order claude · $3.10
✓ PR #100 merged order-status page @vps · $1.87

main is 3 PRs richer. you wrote zero lines — and reviewed every one.

Grove builds itself.

149

tickets on this repo, grabbed and shipped by grove workers

$1–7

what a typical merged PR costs, per the built-in cost ledger

grove-245

this site's README rewrite: a GLM worker on a $5 VPS

Act I

It settles in.

Plant grove in a project — the folder that keeps a product's repos together: a frontend here, its backend there. It doesn't ask you to restructure anything — it walks in, looks around, and settles in.

i.

Spread out

gv init probes every repo in the project: the stack, the base branch, the setup command a fresh worktree needs. One grove per project — and run gv anywhere else, it simply asks which project you mean.

ii.

Wire itself up

The connections board fills in — tmux, GitHub, Claude, hooks. And gv doctor notices the moment any of it drifts, so “it worked last week” never becomes a mystery.

iii.

Hook into your tasks

Point it at wherever your tickets already live — GitHub Issues by default, Linear or plain markdown files as adapters. Grove reads tickets; it never closes them. That's your job, and it stays your job.

~/projects/shopfront — one product, two repos
~/projects/shopfront $ ls webapp/ api/ # a frontend and its backend. independent repos, # one shared folder. not a monorepo. ~/projects/shopfront $ gv init 🌱 taking root… ├───── webapp/ pnpm · main └───── api/ go · main workspace rooted · 2 repos · gv doctor ✓ green ~/projects/shopfront $ gv doctor tmux 3.4 gh authed claude on PATH hooks installed linear no API key — want one? → # .grove/config.yaml provider: kind: github # or linear, or markdown # tickets are your issues: webapp-14 = issue #14
Act II

Turn ideas into specs.

Describe a rough idea. The orchestrator pushes back like a good tech lead: scores it for agent-suitability, asks what's missing, drafts the acceptance criteria.

orchestrator chat
you
something's off with checkout — people abandon carts when they come back later. fix that somehow?
orchestrator
That's two tickets. Drafted the first: shop-14 — persist cart to localStorage, with acceptance criteria, repo, and a reproduction. Small surface, zero design decisions — labeled rote, so it can run on the flat-rate lane. Ready: gv grab shop-14 --repo webapp --profile zai-plan
“A backlog an agent can execute is a backlog you never babysit.”

The quality of the ticket sets the cost of the work. Sized small, sequenced into merge trains, labeled for routing — spend is decided at writing time, not at runtime.

Act III

Dispatch — the right worker, wherever there's room.

A model profile is six lines of YAML naming any Anthropic-compatible endpoint. The flag is per-dispatch — no config edits, no restarts. Two lanes can run the identical model; one of them is already paid for.

one fleet · three backends · two machines
$ gv grab shop-14 --repo webapp # hard one → your Claude plan $ gv grab shop-15 --repo webapp --profile zai-plan # rote → flat-rate GLM. marginal cost: $0 $ gv grab shop-16 --repo api --profile openrouter --host vps # overflow → per-token, on the server $ gv handoff shop-14 --to vps # laptop's closing — the PR body carries the context $ gv ls shop-14 @vps ⚙ working · CI queued shop-15 ·zai ⚙ working shop-16 @vps ⚙ working

No state sync between machines — GitHub is the only shared layer. Every task lives on exactly one host at a time.

Act IV

They walk it through.

Implement, commit, self-review with your taste — your CLAUDE.md, your skills, before/after screenshots posted to the ticket — open the PR, ride CI. Questions land with a drafted answer: unblocking is usually one “yes”.

shop-14 · GitHub Issues
shop-14 · webapp
Persist cart to localStorage
worker/shop-14 · bot · 2 min ago
before
after
📸 before/after attached — PR #98 ready for review.
status: In Review  ← workers move tickets here, never to Done
🔒 grove.tail-net.ts.net
shop-14 has a question: use sessionStorage instead so carts expire with the tab?
drafted answer“no — localStorage, per the ticket. carts should survive a restart.”
send it edit

tailnet-only · no terminal · no destructive verbs

Act V

You stay on the product.

Chats are disposable; state is durable. Triage in one chat, close it when the workers spawn, open a fresh one to catch up — fleet state lives in .grove/, not in scrollback. By default the merge button is yours; per repo, you can grant grove that too — it reviews against your bar, waits for green CI, and merges with your standing permission instead of your presence.

One chat per investigation.

Parallel threads never share a scrollback. Triage in one chat, unblock in another, cost report in a third — each stays sharp.

Close it when the worker spawns.

The chat was scaffolding; the worker is the building. Once it's dispatched, the chat has nothing left to hold for you.

Open a fresh one to catch up.

Fleet state lives in .grove/, not in chat history. A brand-new orchestrator re-derives everything from gv ls in one command.

Grove runs the process so you can run the product.

For the scanners

Everything in the toolshed.

Cockpit dashboard

One tmux session: live fleet table on the left, orchestrator chats stacked on the right. One glance answers “who needs me?”

Backend-agnostic tasks

Local markdown by default; Linear and GitHub Issues as adapters. Grove reads tickets, agents transition them, humans finish them.

Ticket sharpening

Orchestrators score every ticket for agent-suitability and draft the fix when one isn't grabbable.

Bring your own models

Claude native · z.ai / Kimi coding plans · OpenRouter. Mixed per ticket; orchestrators and workers on different backends.

One fleet, many machines

--host dispatch, gv handoff for running tasks, merged gv ls, phone chats over Tailscale.

Guardrails, not vibes

Never closes tickets. Never deletes worktrees it didn't create. Propose, then dispose — irreversible actions wait for your yes.

Audit & sweep

Cross-checks every task against reality: merged, drifted, abandoned, disconnected. Orphans get reported — removal is your call.

Σ

Cost ledger

Per-ticket token estimates joined to PR outcomes. See which ticket shapes burn tokens and what a merged PR actually costs.

Plugins

--json output and an append-only events.jsonl are a stable contract, so new surfaces grow outside the core: a reMarkable e-ink fleet dashboard already builds against it — your Notion board or Discord bot could be next.

Plant your own

Install.

one line — prebuilt binaries, macOS & Linux
$ curl -fsSL https://raw.githubusercontent.com/JollyGrin/grove/main/install.sh | bash $ gv doctor # preflight: tmux, gh, claude $ cd ~/projects/your-app && gv init # 🌱 take root $ gv # open the cockpit $ gv update # any time later: newest release, in place # or from source (Go 1.26+): $ go install github.com/JollyGrin/grove/cmd/gv@latest
your first harvest — tickets are your GitHub issues
$ gh issue create --title "empty cart shows broken illustration" → created issue #14 $ gv grab your-app-14 --repo your-app # worktree + worker + kickoff prompt $ gv ls # … a coffee later: your-app-14 ✓ PR ready · CI green — review & merge

Daily loop

$ gv # cockpit: dashboard + orchestrator $ gv grab DEV-123 --repo webapp $ gv ls # fleet table $ gv attach DEV-123 # jump into a worker $ gv answer DEV-123 "yes" # unblock a question $ gv diff DEV-123 # review without attaching $ gv done DEV-123 # verify merged → clean up

You'll need

tmux
cockpit + every worker live here
gh
PR & CI state — merges checked via GitHub, never git ancestry
claude
Claude Code CLI, logged in
Go 1.26+
only if building from source — the installer ships prebuilt binaries

Grove is the successor to parkranger — built when editing the code was still first-class: the worktree, the file tree, the diff front and center. Agentic coding flipped that. You can still attach to any worker, but the first-class surface is now the tasks and the orchestration.