🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman
Kanban CLI and TUI for agent task boards
kanban-md keeps work in Markdown task files and lets agents claim, move, and finish tasks from the terminal. It pairs a single-binary CLI with a live TUI, plus agent skills and context files, so a project can run with shared board state instead of repeated prompts.
Builders who want Claude Code, Codex, or other agents to share a file-based task board and work in parallel.
You can coordinate multiple agents on one Kanban board without manual handoffs or task clashes.
What it does
Atomic task claiming
`pick --claim` finds the next available task, claims it, and can move it in one step.
File-based task storage
Each task lives as a Markdown file with YAML frontmatter, so humans and agents can read and edit it directly.
Multi-agent safety
Claims act like cooperative locks, with expiration and checks that help prevent agents from working the same task at once.
CLI and TUI board views
Use the command line for batch work and `kanban-md tui` for an interactive terminal board that refreshes from disk.
Installable agent skills
The repo ships skills that teach agents how to use the board and follow the workflow.
Context export
`kanban-md context` writes a board summary into files like `AGENTS.md` or `CLAUDE.md`.
Board workflow commands
Commands cover init, create, list, show, edit, move, handoff, archive, delete, board, metrics, log, and config.
Self-healing IDs and links
The CLI detects and repairs duplicate IDs, filename/frontmatter mismatches, and invalid parent or dependency cycles.
How to get it
- 1Install the tool
brew install antopolskiy/tap/kanban-md
- 2Go to your project directory and create a board there
kanban-md init
- 3Install skills for your agents
# install skills locally in this project -- I prefer this kanban-md skill install # install skills globally (home directory) kanban-md skill install --global
- 4Create tickets manually, or ask your agents do it for you
kanban-md add "Set up CI pipeline" --priority high kanban-md add "Fix login bug" --priority critical claude "add ticket: there is a bug on the login page when the user enters an invalid email address"
- 5Kick off /kanban-based-development skill in a single agent and observe how it behaves.…
kanban-md tui
- 6Run
brew install antopolskiy/tap/kanban-md
README
kanban-md
An agents-first file-based Kanban. Built for multi-agent workflows to allow AI agents work in parallel without clashing. Ultra-fast single binary CLI. Agent skills included. Lean and future-proof: no database, no server, no SaaS — just files.

How to use it
kanban-md is a flexible tool, and you can use it in many ways. Here is one of the ways I use it in my own projects:
- Install the tool
brew install antopolskiy/tap/kanban-md
- Go to your project directory and create a board there
kanban-md init
This will create a kanban/ directory and a config.yml file. I also usually add it to .gitignore.
- Install skills for your agents
# install skills locally in this project -- I prefer this
kanban-md skill install
# install skills globally (home directory)
kanban-md skill install --global
- Create tickets manually, or ask your agents do it for you
kanban-md add "Set up CI pipeline" --priority high
kanban-md add "Fix login bug" --priority critical
claude "add ticket: there is a bug on the login page when the user enters an invalid email address"
- Kick off
/kanban-based-developmentskill in a single agent and observe how it behaves. It should claim a task, create a worktree, implement, test, commit, release the claim and mark the task as done. When confident, kick off the skill in multiple agents -- they will work in parallel without clashing. You should see the progress in the TUI.
kanban-md tui
- Adjust the local skill / AGENTS.md to steer the agents in a way that would make sense for this project.
Why kanban-md?
Project management tools are designed for humans clicking buttons. kanban-md is designed for AI agents running commands and human supervision.
- Agents-first. Token-efficient output formats (
--compact), atomic claim-and-move operations (pick --claim), and installable agent skills that teach agents how to use the board — out of the box. - Multi-agent safe. Claims provide cooperative locking so multiple agents can work the same board without stepping on each other. Claims expire automatically, and the
pickcommand atomically finds, claims, and moves the next available task. - Self-healing task IDs. Commands automatically detect duplicate IDs, filename/frontmatter ID mismatches, and
next_iddrift, then repair them before proceeding. - Plain files. Every task is a Markdown file. Agents, humans, scripts, and
grepall work equally well. No API tokens, no authentication, no rate limits. - Zero dependencies at runtime. A single static binary. No database, no server, no config service.
- Skills included. Pre-written skills for using the CLI tool and a multi-agent development workflow. Installable via
kanban-md skill install. - TUI for observation. A full interactive terminal board with keyboard navigation. It auto-refreshes when task files change on disk.
kanban-md tui

Installation
Homebrew (macOS/Linux)
brew install antopolskiy/tap/kanban-md
Go
go install github.com/antopolskiy/kanban-md/cmd/kanban-md@latest
Homebrew also installs kbmd as a shorthand alias for kanban-md.
Binary downloads
Pre-built binaries for macOS, Linux, and Windows are available on the Releases page.
Quick start
Note: normally, you wouldn't run the CLI commands directly. Your agents will do that for you.
# Initialize a board in the current directory
kanban-md init --name "My Project"
# Create some tasks
kanban-md create "Set up CI pipeline" --priority high --tags devops
kanban-md create "Write API docs" --assignee alice --due 2026-03-01
kanban-md create "Fix login bug" --status todo --priority critical
# List all tasks
kanban-md list
# Filter and sort, highest priority first
kanban-md list --status todo,in-progress --sort priority
# Move a task forward
kanban-md move 3 in-progress
kanban-md move 3 --next
# Edit a task
kanban-md edit 2 --add-tag documentation --body "Cover all REST endpoints"
# View task details
kanban-md show 1
# Done with a task
kanban-md move 1 done
# Or delete it
kanban-md delete 3 --yes
How it works
Running kanban-md init creates a kanban/ directory:
kanban/
config.yml
tasks/
001-set-up-ci-pipeline.md
002-write-api-docs.md
003-fix-login-bug.md
Each task file is standard Markdown with YAML frontmatter:
---
id: 1
title: Set up CI pipeline
status: backlog
priority: high
created: 2026-02-07T10:30:00Z
updated: 2026-02-07T10:30:00Z
tags:
- devops
---
Optional body with more detail, context, or notes.
The config.yml tracks board settings:
version: 3
board:
name: My Project
tasks_dir: tasks
statuses:
- backlog
- todo
- name: in-progress
require_claim: true
- name: review
require_claim: true
- done
- archived
priorities:
- low
- medium
- high
- critical
wip_limits:
in-progress: 3
review: 2
classes:
- name: expedite
wip_limit: 1
bypass_column_wip: true
- name: fixed-date
- name: standard
- name: intangible
claim_timeout: 1h
defaults:
status: backlog
priority: medium
class: standard
next_id: 4
Commands
init
Create a new kanban board.
kanban-md init [--name NAME] [--statuses s1,s2,s3] [--wip-limit status:N]
| Flag | Description |
|---|---|
--name | Board name (defaults to parent directory name) |
--statuses | Comma-separated status list (default: backlog,todo,in-progress,review,done,archived) |
--wip-limit | WIP limit per status (format: status:N, repeatable) |
After creating a board, kanban-md prompts to add the board directory (for example, kanban/) to .gitignore:
- If
.gitignoreexists in the board directory parent, the entry is appended. - If
.gitignoredoes not exist, it is created with the board directory entry.
create
Create a new task. Aliases: add. Title can be provided as a positional argument or via --title.
kanban-md create "My task" [FLAGS]
kanban-md create --title "My task" --description "Details here" [FLAGS]
| Flag | Default | Description |
|---|---|---|
--title | Task title (alternative to positional argument) | |
--status | backlog | Initial status |
--priority | medium | Priority level |
--assignee | Person assigned | |
--tags | Comma-separated tags | |
--due | Due date (YYYY-MM-DD) | |
--estimate | Time estimate (e.g. 4h, 2d) | |
--class | standard | Class of service (expedite, fixed-date, standard, intangible) |
--parent | Parent task ID | |
--depends-on | Dependency task IDs (comma-separated) | |
--body | Task description (alias: --description) |
list
List tasks with filtering and sorting. Aliases: ls.
kanban-md list [FLAGS]
| Flag | Default | Description |
|---|---|---|
--status | Filter by status (comma-separated) | |
--priority | Filter by priority (comma-separated) | |
--assignee | Filter by assignee | |
--tag | Filter by tag | |
-s, --search | Search tasks by title, body, or tags (case-insensitive) | |
--blocked | false | Show only blocked tasks |
--not-blocked | false | Show only non-blocked tasks |
--parent | Filter by parent task ID | |
--unblocked | false | Show only tasks with all dependencies satisfied (missing dependency IDs are treated as satisfied) |
--unclaimed | false | Show only unclaimed or expired-claim tasks |
--claimed-by | Filter by claimant name | |
--class | Filter by class of service | |
--archived | false | Show only archived tasks |
--group-by | Group results by field (assignee, tag, class, priority, status) | |
--sort | id | Sort by: id, title, status, priority, created, updated, due |
-r, --reverse | false | Reverse sort order |
-n, --limit | 0 | Max results (0 = unlimited) |
show
Show full details of a task. When the task has direct children, the detail view includes their IDs, statuses, titles, and a terminal/total roll-up. Parent status remains independently managed; the roll-up is informational only.
kanban-md show ID
kanban-md show ID --archived # include archived children in the roll-up
| Flag | Description |
|---|---|
--archived | Include archived direct children (hidden by default) |
Children are ordered by task ID, matching the default list --parent order.
Human-readable CLI and TUI detail views prefix them with ├─ and └─ tree
guides so the parent-child relationship remains visually clear.
Tasks with a direct parent show an upward relation such as
↑ Parent #1 [in-progress] Parent title; if the parent file is unavailable,
the relationship falls back to its stored task ID.
JSON output always contains a children array; compact output adds a
children:DONE/TOTAL done annotation only when children are present.
Parent links stay acyclic. create and edit reject a parent that would
close a ring, naming the chain it would form:
$ kanban-md edit 2 --parent 1
Error: parent would create a cycle (#2 → #1 → #2)
depends_on is checked the same way, since two tasks that depend on each other
can never become unblocked. Both checks run wherever the link is written, so
create --parent, edit --parent and edit --add-dep are all covered.
A representative board for trying the CLI and TUI behavior is available in
examples/issue-11-demo.
edit
Modify an existing task.
kanban-md edit ID [FLAGS]
kanban-md edit 1,2,3 --priority high # batch edit
| Flag | Description |
|---|---|
--title | New title (renames the file) |
--status | New status |
--priority | New priority |
--assignee | New assignee |
--add-tag | Add tags (comma-separated) |
--remove-tag | Remove tags (comma-separated) |
--due | New due date (YYYY-MM-DD) |
--clear-due | Remove due date |
--estimate | New time estimate |
--body | New body text (replaces entire body) |
--append-body, -a | Append text to task body |
--timestamp, -t | Prefix a timestamp line when appending |
--started | Set started date (YYYY-MM-DD) |
--clear-started | Clear started timestamp |
--completed | Set completed date (YYYY-MM-DD) |
--clear-completed | Clear completed timestamp |
--parent | Set parent task ID |
--clear-parent | Clear parent |
--add-dep | Add dependency task IDs (comma-separated) |
--remove-dep | Remove dependency task IDs (comma-separated) |
--block | Mark task as blocked with reason |
--unblock | Clear blocked state |
--claim | Claim task for an agent (set claimed_by) |
--release | Release claim on task |
--class | Set class of service |
move
Change a task's status.
kanban-md move ID [STATUS]
kanban-md move ID --next
kanban-md move ID --prev
kanban-md move 1,2,3 todo # batch move
| Flag | Description |
|---|---|
--next | Advance to next status in the configured order |
--prev | Move back to previous status |
--claim | Claim task for an agent |
handoff
Hand off a task for review. Moves to review status, appends a note, and optionally blocks/releases.
kanban-md handoff ID --claim NAME [--note TEXT] [--block REASON] [-t] [--release]
| Flag | Description |
|---|---|
--claim | Claim name (required) |
--note | Handoff note to append to body |
--timestamp, -t | Prefix a timestamp line to the note |
--block | Mark task as blocked with reason |
--release | Release claim after handoff |
delete
Delete a task. Aliases: rm.
kanban-md delete ID [--yes]
kanban-md delete 1,2,3 --yes # batch delete
Prompts for confirmation in interactive terminals. Use --yes (-y) to skip the prompt (required in non-interactive contexts like scripts). Batch delete always requires --yes.
archive
Soft-delete a task by moving it to the archived status. Archived tasks are hidden from all normal commands (list, board, metrics, context, TUI) but remain on disk.
kanban-md archive ID
kanban-md archive ID --claim agent-1 # archive a task claimed by agent-1
kanban-md archive 1,2,3 # batch archive
To see archived tasks:
kanban-md list --archived
kanban-md list --status archived
board
Show a board summary with task counts per status, WIP utilization, blocked/overdue counts, and priority distribution. Aliases: summary.
kanban-md board
kanban-md board --watch # live-update on file changes
| Flag | Default | Description |
|---|---|---|
-w, --watch | false | Live-update the board on file changes (Ctrl+C to stop) |
--group-by | Group by field (assignee, tag, class, priority, status) |
pick
Atomically find and claim the next available task. Designed for multi-agent workflows where agents need exclusive task assignment.
kanban-md pick --claim agent-1
kanban-md pick --claim agent-1 --status todo --move in-progress
kanban-md pick --claim agent-1 --tags backend
kanban-md pick --claim agent-1 --parent 42
kanban-md pick --claim agent-1 --no-body
| Flag | Default | Description |
|---|---|---|
--claim | (required) | Agent name to claim the task for |
--status | all non-terminal | Source status(es) to pick from (comma-separated) |
--move | Also move picked task to this status | |
--tags | Only pick tasks matching at least one tag | |
--parent | Only pick tasks that are children of this parent task ID | |
--no-body | false | Show only the pick confirmation line (skip full task details) |
By default, pick prints the one-line confirmation and then the full task details (same as show, including body) so agents do not need a follow-up show command.
The pick algorithm selects from unclaimed, unblocked tasks with satisfied dependencies, prioritizing by class of service (expedite > fixed-date > standard > intangible), then by priority within each class. Fixed-date tasks are further sorted by earliest due date.
agent-name
Generate a random two-word name for use with --claim. Uses the system dictionary when available, with a built-in word list as fallback.
kanban-md agent-name
# → quiet-storm
kanban-md pick --claim $(kanban-md agent-name) --status todo --move in-progress
metrics
Show flow metrics: throughput, average lead/cycle time, flow efficiency, and aging work items.
kanban-md metrics [--since YYYY-MM-DD]
| Flag | Default | Description |
|---|---|---|
--since | Only include tasks completed after this date |
log
Show the activity log of board mutations (create, move, edit, delete, block, unblock).
kanban-md log [FLAGS]
| Flag | Default | Description |
|---|---|---|
--since | Show entries after this date (YYYY-MM-DD) | |
--limit | 0 | Maximum number of entries (most recent) |
--action | Filter by action type (create, move, edit, delete, block, unblock) | |
--task | Filter by task ID |
config
View or modify board configuration.
kanban-md config # show all config values
kanban-md config get KEY # get a single value
kanban-md config set KEY VALUE # set a writable value
Available keys:
| Key | Writable | Description |
|---|---|---|
board.name | yes | Board name |
board.description | yes | Board description |
defaults.status | yes | Default status for new tasks |
defaults.priority | yes | Default priority for new tasks |
defaults.class | yes | Default class of service for new tasks |
statuses | no | List of statuses |
priorities | no | List of priorities |
tasks_dir | no | Tasks directory name |
wip_limits | no | WIP limits per status |
claim_timeout | yes | Claim expiration duration (e.g. 1h, 30m) |
classes | no | Class of service definitions |
tui.title_lines | yes | Number of title lines shown in TUI cards |
tui.hide_empty_columns | yes | Hide columns with zero tasks in TUI |
tui.age_thresholds | no | TUI age color thresholds |
next_id | no | Next task ID |
version | no | Config schema version |
context
Generate a markdown summary of the board state for embedding in context files (e.g. CLAUDE.md, AGENTS.md).
kanban-md context # print to stdout
kanban-md context --write-to AGENTS.md # write/update in file
kanban-md context --sections blocked,overdue # limit sections
kanban-md context --days 14 # recently completed lookback
| Flag | Default | Description |
|---|---|---|
--write-to | Write context to file (creates or updates in-place) | |
--sections | all | Comma-separated section filter |
--days | 7 | Recently completed lookback in days |
Available section names: in-progress, blocked, overdue, recently-completed.
When using --write-to, the context block is wrapped in HTML comment markers (<!-- BEGIN kanban-md context --> / <!-- END kanban-md context -->). If the file already contains these markers, only the block between them is replaced — all other content is preserved.
Interactive TUI
kanban-md tui opens a full interactive terminal board with keyboard navigation. It auto-refreshes when task files change on disk.
If no board exists in the current directory, kanban-md tui can initialize one and then offers to add that board directory to .gitignore.
kanban-md tui # launch from any directory with a kanban/ board
kanban-md tui --dir PATH # point to a specific kanban directory
kanban-md tui --hide-empty-columns # override config and hide empty columns
kanban-md tui --show-empty-columns # override config and show empty columns
kanban-md tui --mouse # opt in to mouse navigation
kanban-md tui --narrow # force the single-column layout at any width
Set tui.hide_empty_columns in config.yml to control the default behavior.
Note: Older releases shipped a standalone
kanban-md-tuibinary. It has been retired — usekanban-md tuiinstead.
In create/edit dialogs, text fields support cursor-based editing (←/→, Home/End, Backspace, Delete).
Opening a task with direct children shows the same child list and roll-up as
show. Archived children remain hidden in the TUI. A board search controls
which cards are visible, but does not hide children from the selected parent's
detail view.
Task bodies are rendered as Markdown using the terminal's default foreground for the main text, so they remain readable when a terminal switches between light and dark themes while the TUI is running.
Narrow mode (small terminals)
On terminals too narrow to show every column side by side — a phone over SSH, a split pane — the board automatically switches to a single-column layout. It shows one column at a time, full width, under a two-line header: a tab strip of all columns (the active one highlighted) on top, and the active column's own full name, count, and WIP limit below. Card titles stay readable instead of being crushed to a few characters per column.
Switch columns with ←/→, h/l, or Tab/Shift+Tab. With --mouse, tap a
tab to jump straight to that column; tapping a card selects it as usual.
Narrow mode activates automatically once columns can no longer get a usable width. To force or tune it:
kanban-md tui --narrow # force narrow mode for this run
kanban-md config set tui.narrow_threshold 80 # persist a custom trigger width
Set tui.narrow_threshold with kanban-md config set (or directly in
config.yml) to override the automatic trigger — the board goes narrow below
that terminal width. Use 0 for automatic behavior or 1 to effectively
disable narrow mode.
Mouse mode
Mouse controls are opt-in, so the normal keyboard-only TUI remains unchanged. Start mouse mode with:
kanban-md tui --mouse
| Mouse action | Result |
|---|---|
| Click a card | Select the card and synchronize keyboard navigation |
| Double-click the same card within 500 ms | Open its detail view |
Click Back | Return to the board |
| Wheel over a column | Activate that column and move its selection one card |
| Wheel in a detail view | Scroll the task body three lines |
| Hold a card, drag to another visible column, and release | Move the task to that status |
The entire rendered destination column is a drop target, including its header, cards, and visible empty area. Releasing over the source column or outside a valid column cancels the drag. Keyboard shortcuts continue to work while mouse mode is active, so both input styles can be mixed freely.
The board status line begins with the card count and ? help, followed by the
optional mouse indicator and the remaining actions. Shortcut characters are
highlighted inside their action labels so the essential hints survive narrow
terminal widths.
Status moves made in the TUI preserve an existing task claim. If an unclaimed
task enters a require_claim status, the TUI automatically claims it using the
local hostname; that claim remains attached if the task later moves elsewhere.
Terminals commonly reserve a modifier such as Shift or Option/Alt to bypass
application mouse reporting for native text selection. The exact modifier is
terminal-dependent; use the terminal's normal selection shortcut or omit
--mouse when native selection is preferred.
Keyboard shortcuts
| Key | Action |
|---|---|
h / l | Move between columns |
j / k | Move between tasks within a column |
Enter | View task details |
c | Create task in current column |
e | Edit selected task (same 4-step flow as create) |
E | Open the selected task's Markdown file in $VISUAL, then $EDITOR, then vi when available |
m | Move task to a different status (picker dialog) |
n / p | Move task to next / previous status |
d | Delete task (with confirmation) |
s | Cycle the sort field (priority → created → updated → title) |
S | Reverse the sort direction |
/ | Search/filter tasks live. By default matches a case-insensitive substring of the title. Start the query with # to search ticket IDs instead: #12 matches every ID beginning with 12 (e.g. #12, #121), and a trailing space (#12 ) requires an exact match (only #12). Enter keeps the filter, Esc clears it |
r | Refresh board |
? | Show help |
Files in the repo
- .agents
- .claude
- .githooks
- .github
- .vscode
- assets
- cmd
- docs
- e2e
- examples
- internal
- site
- .codex
- .cursor
- .gitattributes
- .gitignore
- .golangci.yml
- .goreleaser.yml
- .markdownlint.yml
- AGENTS.md
- CLAUDE.md
- CODEX.md
- GEMINI.md
- go.mod
- go.sum
- LICENSE
- Makefile
- README.md
Discussion (0)
Ask about usage, or say what you built with itSign in to join the discussion.
No comments yet. Be the first to say what this is good for.
More tools
The best-benchmarked open-source AI memory system. And it's free.
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io
Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors
Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.