Vist's Agent pipeline board is a kanban board for coding agents such as Claude Code: each task's stage is an agent:* label, and the agent reports back through MCP or the Vist CLI.
Track the tasks you hand to coding agents on a board driven by labels. What's new is in the changelog, and why we built it is on the blog. Turn on the Agent pipeline board, learn the agent:* stages, and connect Claude Code with the /vist-next command.
What it is
The Agent pipeline board shows every task you've given to a coding agent, grouped by stage: waiting for your approval, being worked on, waiting for your review, or stuck. Each stage is a label on the task, so the board, the list view, MCP and the CLI all see the same state.
The board doesn't run agents. It shows what you and your agents write into Vist: labels on tasks and log entries in notes. Your code stays on your machine and in your Git host. Vist never sees the repository.
How the workflow works
- You write a plan as a Vist note: goal, scope, approach and acceptance criteria that can be tested.
- You create a task linked to that note, labelled
agent:ideaandrepo:<repo-name>. Link the note when you create the task; the link can't be changed afterwards. - When the plan is good to go, you swap
agent:ideaforagent:ready. Only you do this. - A coding agent picks up one ready task, swaps the label to
agent:in-progress, builds it on a branch namedagent/<task-id>-<slug>and opens a pull request. We use Claude Code with the/vist-nextcommand for this. - The agent writes what it did in the note's Agent log and sets
agent:pr-open,agent:needs-revieworagent:blocked. - You review the pull request. Either you merge it and complete the task, or you write your review feedback in the note and set the task back to
agent:ready.
The agent never merges, never pushes to main and never completes a task. Those steps are yours.
The stages
A task carries exactly one agent:* label at a time. Your other labels are never touched.
| Label | Column | Meaning | Set by |
|---|---|---|---|
agent:idea |
Idea | A plan exists but isn't approved. Never picked up. | You (or your planning assistant) |
agent:ready |
Ready for agent | Approved. An agent may pick it up. | You only |
agent:in-progress |
In progress | An agent has claimed it and is working. | Agent |
agent:pr-open |
PR open | PR opened, all acceptance criteria met, checks pass. | Agent |
agent:needs-review |
Needs review / Blocked | PR opened, but something needs your decision. | Agent |
agent:blocked |
Needs review / Blocked | Couldn't start or continue. The reason is in the note. | Agent or you |
| (completed) | Done | You merged the PR and completed the task. | You only |
Each task also needs a repo:<name> label, for example repo:vist-app, using the GitHub repository name. An agent following the convention skips tasks without one.
Turn on the board
- Go to Settings › Connect AI and find Task boards.
- Switch on Agent pipeline board.
- Open Tasks, choose Board, and pick Agent pipeline in the board switcher. You can also go straight to
/tasks?view=board&board=agent_pipeline.
Vist remembers the last board you opened. Switching the toggle off removes the board only. Your tasks and their labels stay as they are.
Using the board
- Move a card by dragging it to another column, or with the Move to… menu on the card, which works from the keyboard. Moving a card swaps its
agent:*label for the target column's label. - Done completes the task and keeps its labels. Moving a card out of Done reopens it. Done shows the 30 most recently completed tasks.
- Filter by repository with the repo chips above the board. Click a chip to show only that repo's tasks; click it again to clear the filter. The "Search labels…" filter works on this board too.
- Unsorted collects open tasks without an
agent:*label. It's collapsed and only appears when it has tasks. You can drag a task out of Unsorted to put it in the pipeline.
The board updates by itself. When a task or its labels change, from the app, MCP or the CLI, every open board refreshes without losing an open menu or a drag in progress.
What a card shows
Besides the usual title, priority, labels, note link and "Blocked by" line (see Task Management), a card on the Agent pipeline board shows:
- a repo chip for its
repo:*label (the column's ownagent:*label is hidden, since the column already says it) - the pull request link with its state: open, draft, merged or closed
- when the agent last reported, and what it did (claimed, pr-opened, blocked, and so on)
- the blocked reason, when there is one
- a Stale badge when the task has been
agent:in-progressfor more than 6 hours without a new log entry
These come from the Agent log in the linked note, not from GitHub.
Plan notes and the Agent log
The agent reports back by appending entries to a ## Agent log section at the bottom of the plan note. Vist reads the newest entries for the card. An entry looks like this:
### 2026-10-11T14:02:00+02:00 · claude-code@laptop · pr-opened
Attempt: 1
Branch: agent/1234-short-slug
PR: https://github.com/you/your-repo/pull/56 (open)
Tests: bundle exec rspec, 0 failures
Next: waiting for review
The header line is a timestamp with offset, the runner, and the event. Events are claimed, heartbeat, resumed, pr-opened, needs-review, blocked and stale-reset. Add Blocked reason: when the event is blocked.
Phased plans. Several tasks can share one plan note. Give each phase its own heading, such as ### Phase 2/3: Move cards. Task #1007, and prefix that phase's log events with [2/3]. Each card then only shows its own phase's PR.
Running /vist-next in Claude Code
/vist-next is a Claude Code custom command: a Markdown file of instructions that tells Claude Code how to take one ready task from Vist to a pull request. Each run it:
- Resumes or resets. If it was halfway through a task less than 6 hours ago, it continues on the same branch. A task with no log entry for more than 6 hours goes back to
agent:ready, or toagent:blockedafter three attempts. - Picks one task. Only
agent:readytasks with arepo:label on its allow-list and a linked note qualify. Tasks whose dependency isn't completed yet are skipped. Order: priority, then due date, then oldest. - Checks the plan. If the goal, scope, approach or testable acceptance criteria are missing, it sets
agent:blockedand says what's missing instead of guessing. - Claims it, swapping the label to
agent:in-progressand loggingclaimed. - Builds it on
agent/<task-id>-<slug>, adding tests for each criterion, and runs your test, lint and security checks. - Opens a pull request, writes the result in the Agent log and sets
agent:pr-open,agent:needs-revieworagent:blocked.
It handles one task per run. If Claude Code hits a usage limit, the run stops without changing labels and the next run picks up where it left off.
Usage:
/vist-next dry-run # report what it would do, change nothing
/vist-next # pick the next ready task
/vist-next 1234 # work on task 1234 only (it must still be ready)
Start with dry-run. It shows which task it would pick, why it skipped the others, and any plan it would block. The full command file is in Setup steps, ready to copy.
Running it on a schedule. The convention is built for an unattended run every couple of hours, for example claude -p "/vist-next" from cron or launchd. We haven't finished testing that yet, so for now we start runs by hand. Unattended runs need Claude Code permissions set up so the run never stops to ask. We'll update this page when the scheduled setup is tested.
Setup steps
- Install the Vist CLI and run
vist initso Claude Code can reach your notes and tasks (see Use Vist from the Command Line), or connect the Vist MCP server (see MCP Server). - Turn on Agent pipeline board in Settings › Connect AI.
- Save the
/vist-nextcommand below as~/.claude/commands/vist-next.md. It's the exact file we use for Vist itself. Before you run it, change these lines:- Repo allow-list: replace
repo:vist-app→~/Github/vist-appwith your ownrepo:<name>label and local path (andcd ~/Github/vist-appin step 6). - GitHub account: remove
Bash(gh auth switch -u davidheijl)fromallowed-toolsand thegh auth switchcall in step 8, or replace them with your own account. - Checks:
bundle exec rspec,rubocopandbrakemanare our Rails checks. Replace them with your project's test and lint commands, in step 7 and inallowed-tools.
- Repo allow-list: replace
---
description: Pick the next agent:ready Vist task, implement it on a branch, open a PR, report back to Vist. Args - [task-id] [dry-run]
argument-hint: "[task-id] [dry-run]"
disable-model-invocation: true
allowed-tools: Read Grep Glob Edit Write Bash(vist *) Bash(git status *) Bash(git fetch *) Bash(git switch *) Bash(git checkout *) Bash(git branch *) Bash(git log *) Bash(git diff *) Bash(git add *) Bash(git commit *) Bash(git push -u origin agent/*) Bash(gh pr create *) Bash(gh pr view *) Bash(gh pr list *) Bash(gh auth switch -u davidheijl) Bash(bundle exec *) Bash(bin/rails *) Bash(brakeman *) Bash(cd *) Bash(mkdir /tmp/vist-next.lock) Bash(rmdir /tmp/vist-next.lock) Bash(stat *) Bash(date *) Bash(hostname)
---
# /vist-next: one Vist task → one PR
Arguments: `$ARGUMENTS`
- empty → auto-pick the next task.
- a number (e.g. `1009`) → work on that task only (it must still pass every gate below; ordering is skipped).
- contains `dry-run` → **read-only**. Run steps 1–4 and report what you *would* do: stale resets, resume, the task you would pick (with why the others were skipped), and the plan gaps you'd block on. Do not take the lock, change labels, write notes, touch git, or call any write tool. Combine with an id to dry-run one task.
## Hard rules
- At most ONE task per run. Only tasks labelled `agent:ready` (or your own `agent:in-progress` task being resumed).
- Repo allow-list: `repo:vist-app` → `~/Github/vist-app`. Ignore all other repos.
- PRs only: never merge, never enable auto-merge, never push to `main`, never deploy, never delete, never call `complete_task`. Never change a task's description, priority or due date.
- Vist access: the `vist` CLI (`vist <tool> --flag value`) or the Vist MCP. The tools are `list_tasks`, `get_task`, `update_task`, `get_note`, `update_note`. On first use, run `vist schema <tool>` once for exact flags (e.g. `--task-id`, `--label`).
- Labels replace on update, and `list_tasks --label` returns ONLY the matched label (known bug, task 1010). So always `get_task` immediately before `update_task`, and resend the full label list with only the `agent:*` label swapped. Exactly one `agent:*` label at a time.
- `update_note` replaces the whole note. Always `get_note` immediately before writing, append only inside `## Agent log`, and write the full content back. Never edit sections above the log.
- Log entry header: `### <ISO 8601 with offset> · claude-code@<hostname> · <event>` (events: claimed, heartbeat, resumed, pr-opened, needs-review, blocked, stale-reset). For phased plans, prefix the event with the phase, e.g. `[1/3] claimed`.
- Status field: if `vist schema update_task` shows a `status` option that accepts `in_progress` (task 1011), also set `in_progress` when claiming and `todo` when parking (blocked, stale-reset, pr-open, needs-review). If not, skip silently.
- If you hit a usage or rate limit at any point, stop immediately without changing labels. The next run resumes.
## Steps
1. **Lock** (skip in dry-run). `mkdir /tmp/vist-next.lock`. If that fails and the lock is under 4h old (`stat`), exit with "locked". If it is older, `rmdir`, then `mkdir` again. Remove the lock when you finish, including on errors.
2. **Resume / stale.** `list_tasks --label agent:in-progress`, then `get_task` each one (full labels) and `get_note` its note to find the newest Agent log entry and its `Attempt:`.
- Your runner id and newest entry < 6h old → resume it (go to 5 on its existing branch; log `resumed`).
- Newest entry > 6h old → if attempt < 3, swap to `agent:ready` and log `stale-reset`; otherwise swap to `agent:blocked` and log "stale after 3 attempts; partial work on <branch>".
- Any repo that still has a fresh in-progress task is busy.
3. **Pick.** `list_tasks --label agent:ready --status incomplete --limit 100`, then `get_task` each candidate. Keep a task only if all of these hold:
- it has an allow-listed `repo:` label;
- its repo is not busy;
- it has a `note_id`;
- none of its dependencies is open: the plan note's "Depends on: … #N" line or Phases section names task #N, and `get_task` #N shows it is not completed.
Sort by priority (high > medium > low), then earliest due date (no due date last), then oldest `created_at`. Take the first. If none qualifies: report "nothing to do" and exit.
4. **Check the plan.** `get_note`. Goal, Scope, Approach and Acceptance criteria must exist; every criterion must be testable; no open question may block the work; the repo must match. Read any "Review feedback" section. If the plan fails this check: swap to `agent:blocked` and log what is missing, quoting the criterion. Then stop. In dry-run, report this instead. Don't guess intent.
5. **Claim.** `get_task`, then `update_task` with `agent:ready` swapped for `agent:in-progress`, then `get_task` again to confirm the swap. Log `claimed` with `Attempt: n` and `Branch: agent/<task-id>-<slug>`.
6. **Implement.** `cd ~/Github/vist-app`, `git fetch origin`, then create the branch from `origin/main` (or continue on it if it exists). Follow `AGENTS.md`/`CLAUDE.md`. Implement only what the plan scopes, and add tests per criterion. After each major step, append a short `heartbeat`.
7. **Verify.** Run the plan's verification commands plus `bundle exec rspec`, `bundle exec rubocop` and `brakeman --ignore-config config/brakeman.ignore --no-pager`. Separate pre-existing failures from new ones.
8. **PR.** Commit, then `git push -u origin agent/<task-id>-<slug>`, then `gh auth switch -u davidheijl` and `gh pr create --base main --title "[Vist #<id>] <title>"`. The body links the plan note title and lists each criterion [x]/[ ] with its evidence, the test results, and what you could not do. Use `--draft` if any criterion is unmet.
9. **Report back.** Append a final log entry: `pr-opened` or `needs-review`, with Branch, PR URL, tests, each criterion ticked with evidence, "Could not do", "Decisions made" and "Next". Then swap the label: all criteria met and checks green → `agent:pr-open`; otherwise → `agent:needs-review`; no PR possible → `agent:blocked` with the reason. Release the lock.
## Final output
Print exactly one line:
`vist-next: #<id> <title> → <PR URL or -> · <agent:state>` (dry-run: `vist-next (dry-run): would pick #<id> <title> · <reason>`), or `vist-next: nothing to do` / `vist-next: locked`.
- Write a plan note with testable acceptance criteria and a
## Agent logheading at the bottom. - Create a task linked to the note, labelled
agent:ideaandrepo:<name>. - When you're happy with the plan, swap
agent:ideaforagent:ready. - In your repository, run
claudeand then/vist-next dry-run. If the report looks right, run/vist-next. - Review the pull request when the card reaches PR open or Needs review.
Limitations
- The board is desktop and tablet only. Phones show the list view.
- PR state on a card is what the agent logged. Vist doesn't check GitHub.
- Editing a note on its own doesn't refresh the board. The card picks up new log entries on the next task or label change, which agents make right after logging.
- The Agent pipeline is the only label board for now. Columns can't be renamed or reordered yet.
- Through MCP, a task's status is only incomplete or completed. That's why the stages are labels.
Frequently asked questions
Do I need Claude Code?
No. The board only reads labels and notes. Any agent that can use Vist through MCP or the CLI and follow the same labels will show up on it. /vist-next is the Claude Code version we use, and the only one we've tested.
Does it work with Cursor, Codex or OpenCode?
In principle, yes, but we haven't tested them yet. The board only reads labels and notes, and any agent that can use Vist through the MCP server or the CLI can write those. vist init writes a Vist skill for Cursor and OpenCode (plus Claude Code and GitHub Copilot CLI); Codex would connect through the MCP server. The /vist-next command has only been tested in Claude Code. It's a Markdown file of instructions, so you can adapt it for another agent, but expect to adjust it.
Does the board start my agents?
No. Agents run on your machine, in your coding tool. The board shows their state.
Can an agent merge its own pull request?
Not if it follows /vist-next. It only opens pull requests. Merging and completing the task are yours.
What happens to my other labels?
Nothing. Moving a card, or an agent changing stage, only swaps the agent:* label.
What if I switch the board off?
Only the board disappears. Every task keeps its labels, and you can switch it back on at any time.
Which plans include it?
All of them, including Free.