Kanban Board
Work items from the user's tracker by stage. The user reorganizes them, and every change goes back to the agent instead of being written directly.
≈ 2,158 tokens per use (tool 893 · guidance 303 · typical payload 962)How token costs are estimated
Example: Kanban Board
Show me the sprint board
Sprint 42
Press Space or Enter to pick up this card. Then use the arrow keys to move it between and within columns, Space or Enter to drop it, or Escape to cancel. You can also use the card's move menu. Nothing is saved until you apply.
Backlog
2 cards- Labels: UILow priorityENG-151
- Labels: SecurityMedium priorityENG-155
To do
3 cards- Labels: BackendHigh priorityENG-149, open Add retry to the webhook sender (opens in a new tab)Due Oct 14Assigned to Omar Haddad
- Labels: UIMedium priorityENG-147, open Empty state for saved reports (opens in a new tab)Due Oct 16Assigned to Priya Nair
- Labels: Backend, SecurityMedium priorityENG-153
In progress
4 cards, limit 3Over limit- Labels: Bug, AuthUrgent priorityENG-142, open Fix login redirect loop on Safari (opens in a new tab)Overdue · Oct 6Assigned to Dana Cole
- Labels: BackendHigh priorityENG-138, open Migrate invoices to the new PDF service (opens in a new tab)Due Oct 10Assigned to Leo Martins
- Labels: UIMedium priorityENG-144, open Keyboard shortcuts for the editor (opens in a new tab)Assigned to Priya Nair
- Labels: PerformanceHigh priorityENG-146, open Speed up dashboard first load (opens in a new tab)Due todayAssigned to Sam Ortiz
Review
2 cards, limit 3- Labels: Growth
- Labels: Bug, SecurityHigh priorityENG-140, open Sanitize filenames on upload (opens in a new tab)Due Oct 9Assigned to Omar Haddad
Done
3 cards- Labels: Auth
- Labels: BackendLow priorityENG-133, open CSV export for the activity log (opens in a new tab)Assigned to Leo Martins
When to use
- The user wants to see work items by stage: a sprint board, a bug triage, a hiring or sales pipeline.
- The user wants to reorganize items between stages, or the agent is suggesting moves for them to review.
When not to use
- There are only a few items or a single stage. Use a list.
- The user needs to compare many fields per item. Use a Data Table.
- The agent can't read the items from the tracker. Fetch them first; never invent cards.
- The change is to a field other than the stage. Use a Change Preview.
How the agent should use it
- Pass columns and cards exactly as the tracker returns them, in order. A card belongs to the column named by its
columnId. - Put recommended moves in
proposals, each with a one-linereason. They show already applied and marked "Suggested · from Inbox", with Undo; thereasonis read to screen readers, not shown on the card. Never pre-move a card by changing itscolumnId. - Set
editable: falsewhen the user only asked to look. Without proposals, the board is display-only. - Apply nothing until the result arrives, then apply exactly the returned moves.
Moving cards
Nothing is written while the user rearranges. Every move is collected and shown on the card ("Moved from In progress", with Undo); the footer counts them ("3 changes"), and the agent receives the moves only when the user applies. Reset restores the starting arrangement and Request changes (the message icon) opens a feedback box; with proposals, Reset becomes an icon button next to Dismiss.
| Input | How |
|---|---|
| Mouse | Drag a card. A line shows where it will land; the board scrolls when you drag near its edge |
| Touch and pen | Press and hold a card, then drag. A quick swipe still scrolls the board |
| Keyboard | Focus a card's title, press Space or Enter to pick it up, use ←/→ to change column and ↑/↓ to change position, then Space or Enter to drop. Escape cancels. Each step is announced to screen readers |
| Move menu | Each card's move button lists the columns, for anyone who prefers not to drag. It shows when you hover or focus a card (always on touch screens) |
Each column is a filled panel with its own header block (the title, then the card count beside it, and "Over limit" at the right); cards sit in the panel on a lighter fill. Each card shows its title over one quiet row: priority (an Urgent red or High orange badge; medium and low are a small muted signal), subtitle, due date and the assignee's initials. Columns with a limit show "3 / 4" and say "Over limit" when they hold more cards. Due dates show "Overdue" once they're past; pass now to fix the date that's compared against (it defaults to the viewer's clock). A column marked done shows its cards faded with a filled check. When the columns are wider than the card, previous and next arrows appear beside the title (with edge fades on the board) and scroll one column at a time.
Installation
npx shadcn@latest add https://your-site.com/r/kanban-board.json
Usage
import { tool } from "ai"
import { kanbanBoardTool } from "@/components/genui/kanban-board.schema"
const tools = {
// No execute(): the call is completed by the user's decision in the UI.
[kanbanBoardTool.name]: tool({
description: kanbanBoardTool.description,
inputSchema: kanbanBoardTool.inputSchema,
}),
}<KanbanBoard
{...part.input}
status={part.state === "input-streaming" ? "streaming" : undefined}
result={part.state === "output-available" ? part.output : undefined}
onResult={(result) =>
addToolResult({ tool: "show_board", toolCallId: part.toolCallId, output: result })
}
/>The agent receives one of:
{ action: "apply", moves: [{ cardId: "eng-142", fromColumnId: "doing", toColumnId: "done", index: 0 }] }
{ action: "revise", feedback: "Keep the payment bugs in Now" }
{ action: "dismiss" }moves is the shortest list that turns the original board into the user's: accepted suggestions are included, and a card moved away and back again is not. Each index is the card's final 0-based position in its target column. On revise or dismiss, apply nothing.
A read-only board (editable: false, no proposals) sends nothing back, so give that tool call an execute that returns immediately.
With LangGraph
Push it from a graph node with ui.push({ name: "show_board", props: { toolCallId, ...args } }, { message }), and render the thread's UI messages with the Renderer.
Restoring from history
Pass the stored result back as result. The board restores the final arrangement read-only, with "Applied" (or the requested changes, or "Dismissed") in the footer, and never calls onResult again.
<KanbanBoard {...part.input} result={part.state === "output-available" ? part.output : undefined} />Schema
| Prop | Type | Notes |
|---|---|---|
title | string? | e.g. "Sprint 42" |
source | { label, url? } | Data-bound. Where the board comes from |
columns | { id, title, limit?, done? }[] | Data-bound. 1–8 stages, in order. limit is the WIP limit; done marks a finished stage |
cards | KanbanCard[] | Data-bound. In order within each column, top first |
proposals | { cardId, toColumnId, reason? }[] | Moves the agent suggests, shown pre-applied as "Suggested" |
editable | boolean | Let the user move cards. Default true |
submitLabel | string? | Apply button label. Default "Apply N changes" |
KanbanCard
| Field | Type | Notes |
|---|---|---|
id | string | Returned in moves |
columnId | string | The column it's in now |
title | string | |
subtitle | string? | A short key, e.g. "ENG-142" |
assignee | { name, initials }? | Shown as initials |
labels | string[]? | Up to 3. Read to screen readers, not shown on the card |
due | string? | ISO date, e.g. "2026-10-14" |
priority | "urgent" | "high" | "medium" | "low" | Urgent and high are shown as badges, medium and low as a small signal; all have a text label for screen readers |
url | string? | http(s) link to the item. The card's subtitle (its key) becomes the link and opens in a new tab, with no icon; give the card a subtitle |
Host props: status (streaming, ready, submitting, applied, revised, dismissed), onResult, result, now and className.