A kanban board for AI coding agents, in your terminal. Move a card, an agent starts.
▦ drover my-app on main ⠧ 1 working ◆ 1 need you
1 Sessions 2 2 Planning 1 3 Executing 1 4 Code Review 0
sessions · main check… plan · opus · xhigh auto · opus · xhigh · ⚡2 auto · isolated · ⚡2
╭──────────────────────╮╭──────────────────────╮╭──────────────────────╮
│ #3 Upgrade React ││ #1 Fix the login bug ││ #2 Add dark mode │
│ ││ ││ to settings page │
│ ││ ◆ needs you fix-the… ││ ⠧ working add-dark… │
╰──────────────────────╯╰──────────────────────╯╰──────────────────────╯
╭─ #1 Fix the login bug · enter to attach, Ctrl-q inside to return ───────────────────────────╮
│ live view of the agent's terminal … │
tmuxandgit- Claude Code (
claude) on yourPATH, signed in
go install github.com/aapzu/drover@latest
# or, from a checkout:
go build -o ~/.local/bin/drover .Install the binary somewhere permanent. Claude's hooks call it to report
activity, so don't run it with go run.
cd your-repo
drover| Key | Action |
|---|---|
←→ / h l, ↑↓ / j k |
select column / card |
H / L (or shift+←→) |
move card to previous / next column |
m then 1–9 |
move card to a column |
n, e, x |
new Claude session (attaches right away), edit, delete task |
I |
import Claude Code agents and sessions, or Linear issues (tab switches) |
enter |
attach to the agent's terminal (Ctrl-q returns) |
tab |
type into the agent from the preview (Ctrl-q returns) |
s |
send the agent a message |
r / S |
start or resume / suspend the agent |
+ / -, < / > |
taller / shorter preview, narrower / wider column |
z, 0 |
cycle card size (normal, compact, tall with the last reply), reset layout |
p, i, ? |
toggle preview, task details and log, help |
M |
toggle mouse capture (off lets the terminal select text) |
q |
quit (agents keep running) |
Q |
suspend every agent and quit, printing a claude --resume command for each |
With the mouse on, drag a card onto another column to move it, double-click
a card to attach, drag a column's right edge or the preview's top border to
resize, and click the preview to type into the agent. Layout is saved in
ui.json in the project's state directory.
In live mode (tab or a click on the preview) every key goes to the agent,
esc and ctrl+c included. ctrl+q returns to the board.
The mouse wheel over the preview scrolls the agent's history, as do pgup /
pgdown on the board. Typing in live mode jumps back to the bottom.
- Shared board file. Columns come from
drover.jsonat the repo root, so you and your teammates share one board. With no file it uses a built-in default (Sessions, Planning, Executing, Self-review, In review, Verify in develop, Done); pressWto write it out.drover.local.jsoncan overridedefaultBaseBranchandworktreesDir.worktreesDir(default.drover/worktrees) is where worktrees go, relative to the repo root or absolute, e.g..claude/worktrees. - Sessions first, branches later.
nopens a Claude session in the main checkout, on a card in the first (To Do role) column. Your first message becomes the card's title. When that turn ends, the card moves to the first agent column that isn't isolated (Planning by default), which creates its worktree and branch and resumes the same conversation there; if you're attached, you follow it. Move it yourself to go elsewhere sooner. - Worktree per task. Entering an agent column creates
.drover/worktrees/<N>on branch<slug>-<id8>from the base branch. To Do removes the worktree and resets the conversation. Done suspends the agent and removes the worktree, asking first if there are uncommitted changes. Branches are never deleted. - Column settings.
autoSpawn,permissionMode,modelOverrideandeffortOverridebecomeclaude --permission-mode/--model/--effort. Columns withoutpermissionModeuse the board'sdefaultPermissionMode, or Claude Code's own default when that is unset. A model or effort change respawns the agent with--resume. A permission change switches it in place while it is idle, and respawns it when that fails or the target leaves the mode to Claude Code.sessionTarget: "isolated"andsessionSpawnStrategy: "always_spawn_new"give a column its own conversation. - Automations.
onEnter,onTurnEndandonExitrows of typesend_message(immediateor deferred),move_to_column,run_script,webhookandnotify, withfinalLine,maxRuns,condition(checked withclaude -p --model haiku) and{{placeholders}}such as{{baseBranch}}and{{agentReply}}.planExitTargetmoves a card once its plan is approved. - Activity. A
--settingsfile adds Claude Code hooks that append events tosessions/…/events.jsonlin the state directory. The board reads them to show working, idle and needs-you states and to run turn-end automations.
The first pull request an agent opens (gh pr create or gh stack) stays on
the session's own card, which moves to the prFlow opened column once the
agent's turn ends. Every further PR gets its own card, so one session can ship
several. The cards are marked ⧉ 1/3, ⧉ 2/3 and so on, and the marker has
the same color on every card of the group.
- The cards share one agent, worktree and conversation.
enter,tab,sand the preview all reach the same agent from any of them. - Moving a card into an agent column points the agent at that card: it takes that column's settings and runs its automations with the card's PR. Turn-end automations act only on the card the agent is working for.
- The agent stops once no card in the group is in an agent column. The worktree goes once every card is in Done or To Do, and the conversation resets once every card is back in To Do.
- Deleting a card removes only that card while others remain.
{{prUrl}},{{prNumber}},{{prTitle}}and{{prBranch}}work in automations.{{branchName}}is the PR's branch when known.gh pr viewrefreshes every open PR's card once a minute. Cards show✓ approved,✗ changes,mergedandreleased.
prFlow in drover.json moves PR cards as their PR progresses. Targets are
column ids or names; leave one out to keep cards where they are. The default
board uses:
"prFlow": {
"requested": "self-review",
"opened": "in-review",
"changesRequested": "executing",
"changesRequestedMessage": "PR #{{prNumber}} got review comments…",
"merged": "verify",
"released": "done"
}- requested: a prompt asking the agent to open a PR, like "open a PR" or
"create pull requests", moves its card here from an earlier agent column.
Negated asks ("don't open a PR yet") are ignored. The column must have
autoSpawn. Its enter automations are skipped, as the agent is already on it, but its turn-end automations run when that turn ends. - opened: where the session card goes once its first PR is open, and where each further PR's card starts.
- changesRequested: a new review requesting changes moves a card from
openedhere and sends the agentchangesRequestedMessage. Once the agent has pushed a new head and is idle, the card goes back toopened. - merged: where a merged PR card goes, for example to verify it in a develop environment.
- released: once the merge commit reaches
releaseBranchon origin (defaultmaster, elsemain), a card inmergedmoves here.
Moves only happen when the PR changes, so a card you move by hand stays put,
including before the session card's move to opened. You get a notice once all
the session's PRs are released.
Ask an agent to review a PR by its URL, for example
/code-review https://github.com/o/r/pull/12, and its card tracks that PR.
Any URL after a slash command with review in its name counts. In a plain
prompt a URL counts when "review" or "reviewing" comes shortly before it in the
same sentence, unless it is negated ("don't review") or reads "review
comments". gh then confirms the PR isn't yours. If it is, drover forgets it
again.
A session that is still in To Do takes the PR on its own card. One already working on something gets a separate card for it.
drover itself never posts a review. Nothing stops the agent from posting if you
ask it to, for example with --comment.
The card shows review PR #12 @author once gh has confirmed it, and
✓ you approved, ✗ you requested changes or ✓ you reviewed once you have
reviewed it. ↻ new commits replaces that when the author has pushed since.
reviewFlow in drover.json moves the card as the PR changes, with the
same column targets as prFlow:
"reviewFlow": {
"started": "reviewing",
"reviewed": "waiting-on-author",
"updated": "reviewing",
"done": "done"
}- started: where the card goes once the agent's turn ends and gh has confirmed the PR isn't yours, from To Do or an agent column.
- reviewed: where it goes, from any column, when a review of yours shows up on the PR once the agent is idle. A review already there when drover first sees the PR is only recorded.
- updated: you get a notice when the author pushes after your review. A
card in
reviewedalso moves here. - done: where it goes once the PR merges or closes. A PR that was already merged or closed when drover first sees it moves nothing.
Your own review is never sent to the agent as feedback to address, and review cards don't follow a PR to release.
I lists Claude Code conversations started in this repo or any directory
below it, such as worktrees. Running agents come first and are preselected.
Past sessions follow, newest first.
- Running agents land in the first agent column. The card mirrors the
agent's working or idle status, and the preview shows its latest reply.
While it runs in its own terminal, the board won't start a second copy of
it, and moves to To Do or Done are refused. Once you exit it there, press
rand the board resumes the conversation withclaude --resumein the agent's original directory. - Past sessions land in To Do. Moving one into an agent column resumes it.
- Board conversations you resume yourself, for example with the commands
Qprints, are tracked the same way. The board won't start them again until you exit them. - The board never deletes a directory it didn't create. Imported sessions that live in the main checkout or in another tool's worktree keep their directory.
Set LINEAR_API_KEY to a personal API key (Linear → Settings → Security &
access). Then I, followed by tab, lists your open assigned issues. /
fetches any issue by key or URL.
- Imported issues land in To Do. The issue description becomes the prompt.
- The worktree uses Linear's branch name (for example
you/dx-123-fix-login), so pull requests link back to the issue. {{issueKey}}and{{issueUrl}}work in automations.- With
DROVER_LINEAR_SYNC=1, starting an agent on an unstarted issue moves it to the team's first "started" state, such as In Progress.
- Tasks live in
$XDG_STATE_HOME/drover/<repo>-<hash>/state.json(default~/.local/state), outside the repo so they can't be committed. Every worktree of a repo opens the same board. - Agents run in a private tmux server (
tmux -L drover ls) and keep running after you quit. Automations only run while the board is open. Events that arrive while it's closed are processed when you reopen it. - Only Claude Code is supported. Issues import from Linear only.