Cards
Cards started with a problem I kept running into while working with coding agents: the work was in a plan.md, but by the next session it was hard to tell what had actually happened. A plan is easy to rewrite, and two workers can trip over the same file. I wanted the work queue, the decisions, and the evidence to stay with the project.

I didn't want another hosted tracker to set up and keep in sync with the code. Cards puts a board in the repo: JSON definitions describe the kinds of work and their states, and the same board is usable from the browser, CLI, terminal UI, HTTP API, and a Model Context Protocol (MCP) server for agents. I use Cards to manage Cards itself; the engineering board in the repo is its real backlog.
A card type defines the fields a work item needs. This excerpt from the programming-task type requires a description and branch, and gives the work log places to record a commit and its author:
{
"id": "programming-task",
"name": "Programming Task",
"schema_version": 1,
"fields": [
{ "id": "description", "type": "text", "required": true },
{ "id": "branch", "type": "string", "required": true },
{
"id": "work_log",
"type": "repeating",
"required": false,
"display": "feed",
"item_fields": [
{ "id": "commit_hash", "type": "string", "required": true },
{ "id": "notes", "type": "text", "required": false },
{ "id": "author", "type": "user", "required": true },
{ "id": "timestamp", "type": "date", "required": true }
]
}
],
"allowed_columns": ["backlog", "todo", "in_progress", "review", "done"]
}
An agent can ask the board for its next programming task. take-next claims it atomically; -q prints just the card ID:
$ cards take-next --board engineering --type programming-task -q
card_7e090c38
The agent can then record the branch, commit hash, and notes on that card. Each update includes the card's current version, so if I or another agent changed it meanwhile, the write is rejected instead of quietly overwriting the newer state. Comments and the work log leave a record I can review and the next session can pick up.
The live database is SQLite and the code is Go, so there's no dependencies. For a handoff, I export cards, comments, and links to a JSONL snapshot and commit it with the project; a fresh checkout can restore that board state. The database remains the working copy, while the definitions and snapshot keep project coordination readable and close to the code.

The terminal UI is another way to work with the same board.
Cards is still in beta but im using it on many projects for a while now. I want to keep the core small (cards, fields, events, links, comments, columns, and storage) and keep it open for integration to clients with a modular design and hooks for callbacks.
- Source on GitHub
- pi-cards, the pi extension for working with Cards from an agent session
- Documentation and quick start
- Latest releases