agkan
Overview
agkan is an SQLite-based CLI task management tool. It is optimized for collaboration with AI agents.
7 Statuses: icebox → backlog → ready → in_progress → review → done → closed
Quick Reference
Agent Guide
# Display a comprehensive guide for AI agents (overview, commands, workflows)
agkan agent-guide
Context
# Output context for AI agents (used in Claude Code SessionStart hook)
agkan context
# Output in JSON format (for SessionStart hook integration)
agkan context --hook
Note:
agkan agent-guide --hookis deprecated. Useagkan context --hookinstead.
Task Operations
# Create task
agkan task add "Title" "Body"
agkan task add "Title" --status ready --author "agent"
agkan task add "Subtask" --parent 1
agkan task add "Title" --file ./spec.md # Read body from file
agkan task add "Title" --blocked-by 1,2 # Set tasks that block this task
agkan task add "Title" --blocks 3,4 # Set tasks that this task blocks
agkan task add "Title" --assignees "alice,bob" # Set task assignees (comma-separated)
agkan task add "Title" --branch feature/my-branch # Assign a branch to this task
agkan task add "Title" --priority high # Set task priority (critical/high/medium/low)
agkan task add "Title" --tag frontend,3 # Attach tags at creation (comma-separated names or IDs)
agkan task add "Title" --model-planning opus # Model used for planning runs
agkan task add "Title" --model-run sonnet # Model used for implementation runs
agkan task add "Title" --effort-planning high # Reasoning effort for planning runs
agkan task add "Title" --effort-run xhigh # Reasoning effort for implementation runs
# List tasks
agkan task list # All tasks
agkan task list --status in_progress
agkan task list --tree # Hierarchical view
agkan task list --root-only # Root tasks only
agkan task list --tag 1,2 # Filter by tags
agkan task list --dep-tree # Dependency (blocking) tree view
agkan task list --sort title # Sort by field (id / title / status / priority / created_at / updated_at), default: created_at
agkan task list --order asc # Sort order (asc / desc), default: desc
agkan task list --assignees "alice,bob" # Filter by assignees (comma-separated)
agkan task list --all # Include all statuses (including done and closed)
agkan task list --priority high,critical # Filter by priority
agkan task list --sort priority # Sort by priority
agkan task list --archived # Include archived tasks in the results
# Get details
agkan task get <id>
# Search
agkan task find "keyword"
agkan task find "keyword" --all # Include done/closed
agkan task find "keyword" --status ready,in_progress # Filter by status (validated: icebox/backlog/ready/in_progress/review/done/closed)
# Update (positional argument form - backward compatible)
agkan task update <id> status in_progress
# Update (named option form - v1.6.0+)
agkan task update <id> --status in_progress
agkan task update <id> --title "New Title"
agkan task update <id> --body "New body text"
agkan task update <id> --author "agent"
agkan task update <id> --assignees "alice,bob"
agkan task update <id> --file ./spec.md # Read body from file
agkan task update <id> --status done --title "Updated Title" # Multiple options
agkan task update <id> --branch feature/my-branch # Set the branch column
agkan task update <id> --model-run sonnet --effort-run high # Set the task's run model / effort (planning: --model-planning / --effort-planning)
agkan task update <id> --priority high # Update task priority
agkan task update <id> --priority "" # Clear task priority
agkan task update <id> --model-planning opus # Set the planning model
agkan task update <id> --model-run sonnet # Set the implementation model
agkan task update <id> --effort-planning high # Set the planning reasoning effort
agkan task update <id> --effort-run xhigh # Set the implementation reasoning effort
agkan task update <id> --model-run "" # Pass an empty string to clear the value
# Count
agkan task count
agkan task count --status ready --quiet # Output numbers only
# Update parent-child relationship
agkan task update-parent <id> <parent_id>
agkan task update-parent <id> null # Remove parent
# Copy task
agkan task copy <id>
agkan task copy <id> --status ready # Specify destination status (default: backlog)
agkan task copy <id> --no-tags # Do not copy tags
agkan task copy <id> --json # Output in JSON format
# Delete task
agkan task delete <id>
agkan task delete <id> --dry-run # Preview the impact of deletion without deleting
# Archive done/closed tasks (hide but recoverable via unarchive)
agkan task archive # Archive done/closed tasks older than 3 days ago (default)
agkan task archive --before 2026-01-01 # Archive tasks last updated before the given date (ISO 8601)
agkan task archive --status done # Target specific statuses (default: done,closed)
agkan task archive --dry-run # Preview tasks that would be archived without archiving
agkan task archive --json # Output in JSON format
# Unarchive a specific task (restore from archived state)
agkan task unarchive <id> # Unarchive a task by ID
agkan task unarchive <id> --dry-run # Preview without unarchiving
agkan task unarchive <id> --json # Output in JSON format
# Purge old done/closed tasks (permanent deletion, irreversible)
agkan task purge # Delete done/closed tasks older than 3 days ago (default)
agkan task purge --before 2026-01-01 # Purge tasks last updated before the given date (ISO 8601)
agkan task purge --status done # Target specific statuses (default: done,closed)
agkan task purge --dry-run # Preview tasks that would be purged without deleting
agkan task purge --json # Output in JSON format
-pis the short form of--priority, not--parent. Specify a parent with the long form--parent <id>only.
Model / effort values
- Models:
fable,opus,sonnet,haiku,gpt-6-astra,gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna,gemini-3.8-flash,gemini-3.7-flash,claude-sonnet-4-6,claude-opus-4-6-thinking,gpt-oss-120b-medium- Efforts:
low,medium,high,xhigh,max- The accepted set comes from the
modelCatalogconfig key. Runagkan task add --helpto see the list this installation actually accepts.
archive vs purge
archive: Sets theis_archivedflag to hide tasks from default views. Recoverable withunarchive.purge: Permanently deletes tasks. Irreversible.
Blocking Relationships
# task1 blocks task2 (task2 cannot be started until task1 is complete)
agkan task block add <blocker-id> <blocked-id>
agkan task block remove <blocker-id> <blocked-id>
agkan task block list <id>
Comment Operations
# Add a comment to a task
agkan task comment add <task-id> <content>
agkan task comment add <task-id> <content> --author "agent"
# List all comments for a task
agkan task comment list <task-id>
# Update a comment by ID
agkan task comment update <comment-id> <content>
# Delete a comment by ID
agkan task comment delete <comment-id>
Tag Operations
# Tag management
agkan tag add "frontend"
agkan tag list
agkan tag delete <tag-id-or-name>
agkan tag delete <tag-id-or-name> --dry-run # Preview the impact of deletion without deleting
agkan tag rename <id-or-name> <new-name>
# Tag tasks
agkan tag attach <task-id> <tag-id-or-name>
agkan tag detach <task-id> <tag-id-or-name>
agkan tag show <task-id>
Export / Import Operations
# Export all tasks to JSON (output to stdout)
agkan export
# Export to file
agkan export > backup.json
# Import tasks from a JSON export file
agkan import <file>
agkan import backup.json
Export behavior:
- Outputs all tasks in JSON format to stdout
- Redirect to a file for backup or migration
Import behavior:
- Imports tasks from a JSON file created by
agkan export - Preserves timestamps from the exported data
- Automatically creates any tags that are missing in the target project
- ID mapping is handled internally (new IDs are assigned in the target DB)
Use cases:
- Task backup before destructive operations
- Migrating tasks to another project
- CI/CD pipeline task management
Process Operations
agkan ps # Show list of running Claude processes
agkan ps --port <number> # Specify port
agkan ps --json # Output in JSON format
Board Operations
agkan board start [--port <number>] [--title <title>] # Start the board
agkan board stop # Stop the board
agkan board restart [--port <number>] # Restart the board
agkan board status [--port <number>] # Check board status
Metadata Operations
# Set metadata
agkan task meta set <task-id> <key> <value>
# Get metadata
agkan task meta get <task-id> <key>
# List metadata
agkan task meta list <task-id>
# Delete metadata
agkan task meta delete <task-id> <key>
Priority
Task priority is managed with the native --priority flag:
# Set priority when creating a task
agkan task add "Title" --priority high
# Update priority on an existing task
agkan task update <id> --priority high
agkan task update <id> --priority "" # Clear priority
| Value | Meaning |
|---|---|
critical |
Requires immediate attention. Blocking issue |
high |
Should be prioritized |
medium |
Normal priority (default) |
low |
Work on if there is time |
When to set priority: Priority is set during the planning phase (agkan-planning-subtask), at the same time the task is moved from backlog to ready. This is the responsibility of the planning skill. Skills that select tasks for execution (e.g., agkan-run) read this value to determine which task to work on next.
Tag Priority
When selecting or tagging tasks, use the following priority order:
| Priority | Tag Name |
|---|---|
| 1 | bug |
| 2 | security |
| 3 | improvement |
| 4 | test |
| 5 | performance |
| 6 | refactor |
| 7 | docs |
This is the canonical definition. All skills refer to this table.
JSON Output
Use the --json flag when machine processing is needed:
agkan task list --json
agkan task get 1 --json
agkan task count --json
agkan tag list --json
# Combine with jq
agkan task list --status ready --json | jq '.tasks[].id'
JSON Output Schema
agkan task list --json
{
"totalCount": 10,
"filters": {
"status": "ready | null",
"author": "string | null",
"assignees": "string | null",
"tagIds": [1, 2],
"rootOnly": false,
"priority": "critical | high | medium | low | null"
},
"sort": "id | title | status | priority | created_at | updated_at | null",
"order": "asc | desc | null",
"tasks": [
{
"id": 1,
"title": "Task Title",
"body": "Body | null",
"author": "string | null",
"status": "icebox | backlog | ready | in_progress | review | done | closed",
"priority": "critical | high | medium | low | null",
"parent_id": "number | null",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"parent": "object | null",
"tags": [{ "id": 1, "name": "bug" }],
"metadata": []
}
]
}
Note:
priorityis a first-class column, notmetadata.metadataholds arbitrary key/value pairs unrelated to priority (e.g.pr).
agkan task get <id> --json
{
"success": true,
"task": {
"id": 1,
"title": "Task Title",
"body": "Body | null",
"author": "string | null",
"assignees": "string | null",
"status": "icebox | backlog | ready | in_progress | review | done | closed",
"priority": "critical | high | medium | low | null",
"parent_id": "number | null",
"is_archived": "boolean",
"branch": "string | null",
"model_planning": "string | null",
"model_run": "string | null",
"effort_planning": "string | null",
"effort_run": "string | null",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"parent": "object | null",
"children": [],
"blockedBy": [{ "id": 2, "title": "..." }],
"blocking": [{ "id": 3, "title": "..." }],
"tags": [{ "id": 1, "name": "bug" }],
"comments": [],
"metadata": []
}
agkan task count --json
{
"counts": {
"icebox": 0,
"backlog": 0,
"ready": 2,
"in_progress": 1,
"review": 0,
"done": 8,
"closed": 5
},
"total": 16
}
agkan task find <keyword> --json
{
"keyword": "Search keyword",
"excludeDoneClosed": true,
"totalCount": 3,
"tasks": [
{
"id": 1,
"title": "Task Title",
"body": "Body | null",
"author": "string | null",
"status": "ready",
"priority": "critical | high | medium | low | null",
"parent_id": "number | null",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"parent": "object | null",
"tags": [],
"metadata": []
}
]
}
agkan task block list <id> --json
{
"task": {
"id": 1,
"title": "Task Title",
"status": "ready"
},
"blockedBy": [{ "id": 2, "title": "...", "status": "in_progress" }],
"blocking": [{ "id": 3, "title": "...", "status": "ready" }]
}
agkan task meta list <id> --json
{
"success": true,
"data": [
{ "key": "pr", "value": "https://github.com/org/repo/pull/1" }
]
}
Note:
priorityis a first-class task field (seetask list/task getschemas above), not stored viatask meta. The example above usesprto avoid implying otherwise.
agkan tag list --json
{
"totalCount": 3,
"tags": [
{
"id": 1,
"name": "bug",
"created_at": "2026-01-01T00:00:00.000Z",
"taskCount": 2
}
]
}
Typical Workflows
Icebox Review (agkan-icebox)
Icebox holds ideas and candidates that are not yet ready for planning. Review them periodically to decide whether to promote or close each one.
# Review icebox tasks
agkan task list --status icebox
# Promote to backlog when requirements become clear
agkan task update <id> status backlog
# Close if no longer needed
agkan task update <id> status closed
Icebox → Backlog conditions:
- Requirements or background are now clear enough to plan
- External blockers have been resolved
- Circumstances have changed and the task is now relevant
Icebox → Closed conditions:
- The need no longer exists
- A duplicate already exists in a later stage
- Superseded by another approach
Receiving Tasks as an Agent
# Check assigned tasks
agkan task list --status ready
agkan task get <id>
# Start work
agkan task update <id> status in_progress
# Complete
agkan task update <id> status done
Structuring Tasks
# Create parent task
agkan task add "Feature Implementation" --status ready
# Add subtasks
agkan task add "Design" --parent 1 --status ready
agkan task add "Implementation" --parent 1 --status backlog
agkan task add "Testing" --parent 1 --status backlog
# Set dependencies (Design → Implementation → Testing)
agkan task block add 2 3
agkan task block add 3 4
# View overall structure
agkan task list --tree
Body Conventions
PR Label
Skills that create PRs write a structured label into the task body. This label is used by subsequent skill executions to resume work on the existing PR instead of opening a new one.
Format
PR: <URL>
Rules
- PR label is written by
agkan-subtaskafter the PR is opened (Step 7). - The label is appended to the existing task body, separated by a blank line.
- Skills that start work on a task must parse this label from the task body before creating a new PR.
- If a
PR:label is present → push to the branch to update the existing PR instead of opening a new one. - If no
PR:label is present → open a new PR.
- If a
- A PR opened while implementation is still remaining is created as a draft (
gh pr create --draft). It stays a draft while the task isin_progress; the skill marks it ready for review (gh pr ready) when the task advances toreview.
Branch Field
The branch column is a first-class field on the task record — it is not stored in the task body.
- Set:
agkan task add --branch <name>oragkan task update <id> --branch <name> - Read:
agkan task get <id> --json→.task.branch - Note:
agkan task list --jsondoes not include thebranchfield. Useagkan task get <id> --jsonwhen branch information is needed. - When
branchisnull, subtask skills (agkan-subtask,agkan-subtask-direct) auto-generate a branch name from the task ID and title, create the branch, and persist the name back viaagkan task update <id> --branch <name>.
Configuration
Place .agkan.yml in the project root. Every key agkan reads:
agent: claude # AI coding agent to run: claude | codex | agy (default: claude)
path: ./.agkan/data.db # SQLite DB path
board:
port: 3000 # Board server port
title: My Project # Board page title
models:
planning: # Applies to the agent selected by `agent`
model: opus
effort: high
run:
model: sonnet
effort: xhigh
claude: # Per-agent settings: `claude` | `codex` | `agy`,
planning: # each holding its own `planning` / `run`
model: opus
effort: high
run:
model: sonnet
effort: xhigh
modelCatalog: # Replaces the built-in (cli, model, efforts) catalog wholesale
- cli: claude
model: opus
efforts: [low, medium, high, xhigh, max]
permissionMode: auto # Passed through to the agent CLI.
# `skipPermissions` maps to --dangerously-skip-permissions.
Every key is optional. The DB path can also be set with the environment variable
AGENT_KANBAN_DB_PATH=/custom/path/data.db.
Config Commands
# Get all resolved config values from .agkan.yml
agkan config get
# Get a specific config value (dot notation)
agkan config get board.port
agkan config get models.planning.model
# Output in JSON format
agkan config get --json