Cards & Workflows
A card is a plain markdown file. Priority, comments, logs, forms — everything layers on top of that.
Card anatomy
Every card is stored as a .md file in .kanban/<status>/. The filename derives from the title and timestamp — for example implement-dark-mode-2026-01-29.md.
YAML frontmatter stores metadata. The markdown body is free-form.
---
title: Implement dark mode
status: in-progress
priority: high
assignee: alice
labels: [frontend, ux]
dueDate: "2026-04-01"
---
Free-form markdown body here.
SDK: create a card
const card = await sdk.createCard({
content: '# Fix login bug\n\nUsers cannot log in with email.',
status: 'todo',
priority: 'high',
labels: ['bug', 'auth'],
assignee: 'alice',
metadata: { sprint: 'Q2', points: 5 },
boardId: 'bugs'
})
console.log(card.id) // '7'
Priority levels
Cards carry one of four priority levels: Critical, High, Medium, Low. Displayed as color-coded badges in the board and the card detail view. Set via the web UI, CLI, or API.
kl add --title "Fix login bug" --priority critical
kl edit fix-login-bug --priority high
Assignees
Assign one team member per card. Filter the board by assignee from the toolbar or via --assignee in the CLI.
kl add --title "Auth refactor" --assignee alice
kl list --assignee alice
Labels
Apply one or many labels to categorize cards. Labels are defined per-board in Settings → Labels. Click a label in the board or card detail panel to filter the board view instantly.
kl add --title "Improve search UX" --label "frontend,search,ux"
Due dates
Smart relative formatting: cards show Overdue, Today, Tomorrow, or a compact notation like 5d. Filter by due status from the toolbar.
kl edit my-card-id --due 2026-04-15
Comments
Threaded discussion stored in the same markdown file. Timestamps and authors are tracked automatically.
kl comment add my-card-id --author alice --body "Looks good, needs tests"
kl comment list my-card-id
SDK: add a comment
const card = await sdk.addComment('42', 'alice', 'This needs more investigation.')
console.log(card.comments.length) // 1
Logs
Timestamped append-only log entries stored in a separate <cardId>.log file. Support optional source labels and structured JSON objects — ideal for CI output, deployment events, or audit trails.
kl log add my-card-id --text "Build passed" --source ci --object '{"version":"1.2.0"}'
kl log list my-card-id
SDK: add a log entry
const entry = await sdk.addLog('42', 'Deploy complete', {
source: 'ci',
object: { version: '1.2.3', duration: 42 }
})
Attachments
Attach files to any card. File references are stored in frontmatter; the files are copied to the card's attachment directory.
kl attach add my-card-id ./screenshot.png
kl attach my-card-id # list attachments
Actions
Named triggers attached to a card — for example retry, deploy, notify. Fire them from the web UI, CLI, REST API, or MCP server. Kanban Lite calls the configured webhook URL with the card's full context.
kl add --title "Deploy service" --actions "retry,rollback,notify"
kl action trigger deploy-service retry
Card frontmatter with actions
---
title: Deploy service
status: in-progress
actions: [retry, rollback, notify]
---
SDK: trigger an action
await sdk.triggerAction('42', 'retry')
await sdk.triggerAction('42', 'sendEmail', 'bugs')
Metadata
Attach arbitrary key-value metadata to any card. Filter with meta.field: value tokens from the search bar or CLI.
kl add --title "User profile page" --meta sprint=Q2 --meta points=5
kl list --search "meta.sprint: Q2"
Forms
Attach reusable forms from .kanban.json or define card-local inline forms. Each form renders as its own tab in the card editor. Submitted data is stored per-form under formData[formId] in the card frontmatter.
kl add --title "Investigate outage" --forms '[{"name":"incident-report"}]'
kl form submit investigate-outage incident-report --data '{"severity":"high","owner":"alice"}'
Form definition in .kanban.json
{
"forms": {
"incident-report": {
"schema": {
"type": "object",
"required": ["severity", "summary"],
"properties": {
"severity": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
"summary": { "type": "string", "minLength": 1 },
"owner": { "type": "string" }
}
},
"data": { "severity": "medium" }
}
}
}