Skip to content
aapzuPublic

About

A kanban board for AI coding agents, in your terminal

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

39 Commits

Folders and files

Repository files navigation

drover

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 …                                                          │

Requirements

  • tmux and git
  • Claude Code (claude) on your PATH, signed in

Install

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.

Use

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.

How it works

  • Shared board file. Columns come from drover.json at 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); press W to write it out. drover.local.json can override defaultBaseBranch and worktreesDir. worktreesDir (default .drover/worktrees) is where worktrees go, relative to the repo root or absolute, e.g. .claude/worktrees.
  • Sessions first, branches later. n opens 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, modelOverride and effortOverride become claude --permission-mode/--model/--effort. Columns without permissionMode use the board's defaultPermissionMode, 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" and sessionSpawnStrategy: "always_spawn_new" give a column its own conversation.
  • Automations. onEnter, onTurnEnd and onExit rows of type send_message (immediate or deferred), move_to_column, run_script, webhook and notify, with finalLine, maxRuns, condition (checked with claude -p --model haiku) and {{placeholders}} such as {{baseBranch}} and {{agentReply}}. planExitTarget moves a card once its plan is approved.
  • Activity. A --settings file adds Claude Code hooks that append events to sessions/…/events.jsonl in the state directory. The board reads them to show working, idle and needs-you states and to run turn-end automations.

One card per pull request

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, s and 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 view refreshes every open PR's card once a minute. Cards show ✓ approved, ✗ changes, merged and released.

Following a PR to release

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 opened here and sends the agent changesRequestedMessage. Once the agent has pushed a new head and is idle, the card goes back to opened.
  • merged: where a merged PR card goes, for example to verify it in a develop environment.
  • released: once the merge commit reaches releaseBranch on origin (default master, else main), a card in merged moves 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.

Reviewing other people's PRs

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 reviewed also 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.

Importing Claude Code agents

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 r and the board resumes the conversation with claude --resume in 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 Q prints, 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.

Linear

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.

Notes

  • 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.

About

A kanban board for AI coding agents, in your terminal

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages