Know where every ticket stands.

Five coding agents on five tickets. Your terminal tells you which one is busy. cairn tells you where the work is, and what is waiting for your decision.

git clone https://github.com/Gradrien/cairn && cairn/install.sh --herdr
Star on GitHub

For Claude Code in herdr. Works with Linear, or no tracker at all. Install steps

The agent wrote a plan and waits for you.Press to approve it.
cairn eng · web● herdr ● Linear ● GitHub
/ filter · ctrl+k search everything
Waiting for you
⚠ ENG-412 Rate-limit the public API
⚠ Approve the plan · 12 min
⚠ WEB-7 Export invoices as PDF
⚠ Answer 1 question
 
In progress
ENG-398 Retry failed webhooks
Build 4/6 ·
WEB-5 Dark mode for the editor
Review · PR #31 · CI ✓
 
› 2 shipped: show
 
Not on a ticket
○ Bump Go to 1.27
ENG-412 Rate-limit the public API
Linear · Todo · High · 3 pts
⚠ Your call: approve the planfor 12 min
Phase Plan ● → Build → Review → Shipped
 
── Open questions 2
? Per API key or per IP?
? Keep the 429 body as JSON?
── Tasks 0/4
○ Token bucket in middleware/ratelimit.go
○ Limits per plan, read from billing
○ Retry-After header on 429
○ Load test: 500 req/s for 60 s
── Side effects 0/2
○ Webhooks share the router: exempt them
○ Status page polls /health every 5 s
n new s settings t board ctrl+k palette ? helpexample data

Five agents. Five panes. One list.

Your terminal tells you an agent is idle. Not whether it finished, is waiting on your approval, or is stuck on a question. cairn reads every ticket's state and puts the answer on one screen, with the ones that need you first and the exact thing to decide.

Each ticket gets its own work site: the ticket, its branch, its terminal workspace, its agents, its plan and its pull request, moving from Plan to Build, Review and Shipped.

cairn5 tickets · 2 waiting for you
Waiting for you
ENG-412 Rate-limit the public APIApprove the plan · 12 min
WEB-7 Export invoices as PDFAnswer 1 question · 3 min
In progress
ENG-398 Retry failed webhooksBuild 4/6
WEB-5 Dark mode for the editorReview · CI ✓
Shipped
ENG-377 Paginate the audit logcleaned up
example data

Nothing ships without you.

Agents never push or open a pull request on their own. A Claude Code hook blocks git push and gh pr create on a ticket's branch until you press a on the commit you reviewed. Enforced, not requested.

Covers the commit you read
The go-ahead is for one commit. Push, PR and retries pass while the branch stays on it. New commits ask again.
Free once the PR is open
CI fixes and review feedback push without asking. From then on, you review on the pull request.
Merging stays yours
gh pr merge stays blocked for agents. cairn never merges anything.

Read the review where you work.

c opens the whole pull request in the terminal: description, reviews, inline comments with their file:line, screenshots included. Send any comment to the agent in one click. It becomes a task, gets fixed locally, and comes back to you as the next push to allow.

f does the same for a red CI: cairn fetches the failing steps' logs and hands them over.

PR #418Rate-limit the public API · 3 comments
mayarequested changes · 4 min ago

middleware/ratelimit.go:42

A fixed window lets a client burst 2× the limit at the boundary. Can we use a sliding window here?

-  if b.count >= b.limit {
+  if b.slidingCount(now) >= b.limit {
The agent adds it as a task and fixes it locally.
── ENG-412 tasksexample data
No new task. Send the comment to give the agent one.
◐ Sliding window in ratelimit.go:42 (from maya)

One command to remember. Everything else is a key.

Type cairn once, or press prefix a in herdr. Every key is also a button, and everything works with the mouse.

Decide

The three moments that are yours.

  • v Approve
  • e Answer
  • a Allow push

Move

Get to the right place fast.

  • ↵ Go to agent
  • t Board
  • ctrlk Palette

Act

Everything else a ticket needs.

  • p Plan
  • n New ticket
  • c Comments
  • f Fix CI
  • d Diff
  • s Settings

Bring your tracker. Or don't.

cairn follows as many repositories as you like, on one screen, each with its own tracker. The key says where a ticket comes from: ENG-412 next to WEB-7.

Linear

Paste a personal API key in the settings. cairn checks it, finds your team, assigns the tickets you take and moves them to In Progress when the plan starts.

cairn add --tracker linear --key ENG

No tracker at all

Type a title, get WEB-8. The plan file is the ticket; the pull request is found by its branch. Made for side projects.

cairn add

Your own

Jira, GitLab, something built in-house: plug it in by writing one small Go interface. List your tickets, take one, start it.

type Tracker interface {
  Mine() ([]Issue, error)
  Take(key string) error
  Start(is Issue) (bool, error)
  // …and three more
}
  • herdragents and workspaces
  • Claude Codethe agents and the push hook
  • GitHubpull requests, CI and images, through gh
  • browsediffor git diff, or your own diff

Up and running in three steps.

You need Go, gh logged in, and herdr. Run the installer again after every update: it restarts the cairn already open.

  1. Install

    The binary, the agents' skill, the push hook, and cairn's button in herdr's sidebar.

    git clone https://github.com/Gradrien/cairn && cairn/install.sh --herdr
  2. Add a repository

    From inside it. No option means no tracker; change anything later with s.

    cd ~/code/your-repo && cairn add
  3. Plan a ticket

    Open cairn from herdr with prefix a. Press n and type a title or a ticket number. The plan comes back to you for approval.

A cairn of flat stones on the Plateau d'Emparis, facing the glaciers of La Meije at dusk

Mark the trail.

Hikers stack a few stones so the next person knows where the path goes. cairn does that for every ticket your agents walk: where it is, what it waits for, who decides.

git clone https://github.com/Gradrien/cairn && cairn/install.sh --herdr
Star on GitHub

Photo: Plateau d'Emparis, Hautes-Alpes, by Dominicus Johannes Bergsma, CC BY-SA 3.0, colour-graded for this page (source).