agkan
v2.14.3
Published
TypeScript-based CLI task management tool with SQLite storage
Maintainers
Readme
agkan
A lightweight CLI task management tool implemented in TypeScript. Optimized for collaborative work with AI agents.
Features
- Simple CLI: Intuitive command-line interface
- SQLite-based: Fast local data management
- Kanban Format: Manage tasks with 7 statuses (icebox, backlog, ready, in_progress, review, done, closed)
- Flexible Input: Create tasks from command-line arguments or Markdown files
- Filtering: Narrow down tasks by status or author
- Color-coded Display: Easy-to-read color-coded display by status
- Parent-Child Relationships: Manage task hierarchy (tree view supported)
- Blocking Relationships: Manage task dependencies (includes circular reference detection)
- Tag System: Classify and search tasks with tags
- Kanban Board: Local web-based Kanban board viewer
Agent Skills
To use agkan with Claude Code skills (automated task execution, planning, review, etc.), install the companion skills package:
- agkan-skills - Claude Code skills for agkan task management
Installation
Prerequisites
- Node.js 20 or higher
- npm
Install from npm (Recommended)
Install as a global command:
npm install -g agkanNow the agkan command is available system-wide.
Install from GitHub
Install directly from the repository:
npm install -g https://github.com/gendosu/agkan.gitUsage
Create Tasks
Basic task creation:
agkan task add "Task title" "Task description"Create with options:
agkan task add "Implement login feature" "Implement user authentication system" \
--status ready \
--author "developer-name"Create with parent task:
agkan task add "Subtask" "Detailed work item" --parent 1Create from Markdown file:
agkan task add "Design review" --file ./design-doc.md --status backlogJSON output format:
agkan task add "Fix bug in login" --json{
"success": true,
"task": {
"id": 1,
"title": "Fix bug in login",
"status": "backlog",
"body": null,
"author": null,
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
},
"parent": null,
"blockedBy": [],
"blocking": []
}List Tasks
Display all tasks:
agkan task listDisplay in tree format (including parent-child relationships):
agkan task list --treeDisplay root tasks only (tasks without parents):
agkan task list --root-onlyFilter by status:
agkan task list --status in_progressFilter by author:
agkan task list --author "developer-name"Combined filters:
agkan task list --status ready --author "developer-name"Filter by tag:
agkan task list --tag "frontend"JSON output format:
agkan task list --json{
"tasks": [
{
"id": 1,
"title": "Implement login feature",
"status": "in_progress",
"body": "Implement user authentication system",
"author": "developer-name",
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
},
{
"id": 2,
"title": "Design review",
"status": "backlog",
"body": null,
"author": null,
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
}
]
}Search Tasks
Search by keyword (in title and body):
agkan task find "search keyword"Include completed tasks in search:
agkan task find "search keyword" --allNote: By default, done and closed tasks are excluded from search results.
JSON output format:
agkan task find "login" --json{
"tasks": [
{
"id": 1,
"title": "Implement login feature",
"status": "in_progress",
"body": "Implement user authentication system",
"author": "developer-name",
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
}
]
}Get Task Details
agkan task get 1JSON output format:
agkan task get 1 --json{
"task": {
"id": 1,
"title": "Implement login feature",
"status": "in_progress",
"body": "Implement user authentication system",
"author": "developer-name",
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
}
}Update Tasks
Change status:
agkan task update 1 status doneChange title:
agkan task update 1 title "New title"Change body:
agkan task update 1 body "New description"Change author:
agkan task update 1 author "new-author"Manage Parent-Child Relationships
Update parent task:
# Set parent of task 2 to task 1
agkan task update-parent 2 1
# Remove parent (orphan task 2)
agkan task update-parent 2 nullNotes:
- Deleting a parent task automatically removes the parent reference from child tasks (orphaning them)
- Circular references are automatically detected and prevented
JSON output format:
agkan task update-parent 2 1 --json{
"success": true,
"task": {
"id": 2,
"title": "Child Task",
"status": "backlog",
"body": null,
"author": null,
"parent_id": 1,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
},
"parent": {
"id": 1,
"title": "Parent Task",
"status": "backlog",
"body": null,
"author": null,
"parent_id": null,
"created_at": "2026-02-15T00:00:00.000Z",
"updated_at": "2026-02-15T00:00:00.000Z"
}
}Manage Blocking Relationships
Add blocking relationship (task 1 blocks task 2):
agkan task block add 1 2Remove blocking relationship:
agkan task block remove 1 2List blocking relationships:
# Show blocking relationships for task 1
agkan task block list 1Notes:
- Circular references are automatically detected and prevented
- Blocking relationships are automatically deleted when a task is deleted (CASCADE DELETE)
JSON output format:
agkan task block list 2 --json{
"task": {
"id": 2,
"title": "API implementation",
"status": "backlog"
},
"blockedBy": [
{
"id": 1,
"title": "Database design",
"status": "in_progress"
}
],
"blocking": [
{
"id": 3,
"title": "Frontend implementation",
"status": "backlog"
}
]
}Delete Tasks
Delete a task:
agkan task delete 1Manage Tags
Create a tag:
agkan tag add "frontend"List all tags:
agkan tag listDelete a tag:
agkan tag delete "frontend"JSON output format for tag list:
agkan tag list --json{
"totalCount": 2,
"tags": [
{
"id": 1,
"name": "frontend",
"taskCount": 3,
"created_at": "2026-02-15T00:00:00.000Z"
},
{
"id": 2,
"name": "backend",
"taskCount": 1,
"created_at": "2026-02-15T00:00:00.000Z"
}
]
}Attach Tags to Tasks
Attach a tag to a task:
agkan tag attach 1 "frontend"Remove a tag from a task:
agkan tag detach 1 "frontend"Display tags on a task:
agkan tag show 1JSON output format for tag show:
agkan tag show 1 --json{
"task": {
"id": 1,
"title": "Implement login screen",
"status": "in_progress"
},
"tags": [
{
"id": 1,
"name": "frontend",
"created_at": "2026-02-15T00:00:00.000Z"
},
{
"id": 3,
"name": "urgent",
"created_at": "2026-02-15T00:00:00.000Z"
}
]
}Manage Metadata
Set metadata:
agkan task meta set 1 priority highGet metadata:
agkan task meta get 1 priorityList all metadata:
agkan task meta list 1Delete metadata:
agkan task meta delete 1 priorityPriority (priority)
Task priority is managed with the priority key:
| Value | Meaning |
|-------|---------|
| critical | Requires immediate action. A blocking issue. |
| high | Should be addressed with priority |
| medium | Normal priority (default) |
| low | Address when time permits |
Count Tasks
Display task count for all statuses:
agkan task countDisplay task count for a specific status:
agkan task count --status in_progressScript-friendly output (numbers only):
agkan task count -s in_progress -qJSON output format for all statuses:
agkan task count --json{
"total": 10,
"counts": {
"backlog": 3,
"ready": 2,
"in_progress": 4,
"done": 1,
"closed": 0
}
}JSON output format for specific status:
agkan task count --status in_progress --json{
"status": "in_progress",
"count": 4
}Kanban Board (Web UI)
Start a local Kanban board viewer in your browser:
agkan boardSpecify a custom port:
agkan board -p 3000The board is served at http://localhost:8080 by default.
Display Help
Show command list:
agkan --helpShow task command help:
agkan task --helpShow help for specific command:
agkan task add --helpJSON Output Format
agkan supports machine-readable JSON output for 9 data retrieval and display commands. Add the --json flag to output structured data instead of human-readable text.
Supported Commands
The following commands support JSON output:
task add- Create a new tasktask list- List tasks (with filtering)task get- Get task detailstask find- Search tasks by keywordtask count- Count tasks by statustask update-parent- Update parent-child relationshiptask block list- List blocking relationshipstask tag list- List all tags with task countstask tag show- Show tags for a specific tasktask meta list- List all metadata for a task
Output Structure
All JSON responses follow these patterns:
Success responses include:
- Operation-specific data (task, tasks array, counts, etc.)
- Related data (parent, blockedBy, blocking, tags, etc.)
- Optional
success: truefield for write operations
Error responses follow the format:
{
"success": false,
"error": {
"message": "Error description"
}
}Common Use Cases
1. Scripting and Automation
# Get task count for CI/CD pipeline
TASK_COUNT=$(agkan task count --status backlog --json | jq '.counts.backlog')
# Extract task IDs for processing
agkan task list --status ready --json | jq -r '.tasks[].id'2. Integration with Other Tools
# Export tasks to external system
agkan task list --json | jq '.tasks' > tasks.json
# Process blocking relationships
agkan task block list 1 --json | jq '.blockedBy[].title'3. Validation and Testing
# Verify task creation
RESULT=$(agkan task add "Test" --json)
echo $RESULT | jq -e '.success == true' && echo "Success"Usage Examples
Hierarchical Task Management with Parent-Child Relationships
Example of managing a project as a parent task with individual work items as children:
# Create parent task
agkan task add "Website redesign"
# Output: Task created with ID: 1
# Create child tasks
agkan task add "Create design mockup" --parent 1
agkan task add "Implement frontend" --parent 1
agkan task add "Implement backend" --parent 1
# Display in tree format
agkan task list --tree
# Output:
# 1 [backlog] Website redesign
# ├─ 2 [backlog] Create design mockup
# ├─ 3 [backlog] Implement frontend
# └─ 4 [backlog] Implement backend
# Display task details (including parent information)
agkan task get 2
# Output:
# ID: 2
# Title: Create design mockup
# Parent ID: 1
# ...
# Change parent
agkan task add "UI/UX improvements"
# Output: Task created with ID: 5
agkan task update-parent 2 5
# Remove parent (orphan task)
agkan task update-parent 2 nullManaging Dependencies with Blocking Relationships
Example of explicitly managing task dependencies:
# Create tasks
agkan task add "Database design"
# Output: Task created with ID: 1
agkan task add "API implementation"
# Output: Task created with ID: 2
agkan task add "Frontend implementation"
# Output: Task created with ID: 3
# Set blocking relationships (1 blocks 2, 2 blocks 3)
# Database design blocks API implementation
agkan task block add 1 2
# API implementation blocks Frontend implementation
agkan task block add 2 3
# Verify blocking relationships
agkan task block list 1
# Output:
# Task 1 blocks:
# - Task 2 (API implementation)
# Task 1 is blocked by:
# (none)
agkan task block list 2
# Output:
# Task 2 blocks:
# - Task 3 (Frontend implementation)
# Task 2 is blocked by:
# - Task 1 (Database design)
# Attempt circular reference (error)
agkan task block add 3 1
# Output: Error: Circular reference detected
# Remove blocking relationship
agkan task block remove 1 2Task Management with Tags
Example of classifying tasks with tags:
# Create tags
agkan tag add "frontend"
agkan tag add "backend"
agkan tag add "urgent"
# Create tasks and attach tags
agkan task add "Implement login screen"
# Output: Task created with ID: 1
agkan tag attach 1 "frontend"
agkan tag attach 1 "urgent"
agkan task add "API development"
# Output: Task created with ID: 2
agkan tag attach 2 "backend"
# Filter by tag
agkan task list --tag "frontend"
# Output:
# 1 [backlog] Implement login screen (tags: frontend, urgent)
# Display task tags
agkan tag show 1
# Output:
# Tags for task 1:
# - frontend
# - urgent
# Remove a tag
agkan tag detach 1 "urgent"
# Delete a tag (removes from all associated tasks)
agkan tag delete "urgent"Task Statuses
- icebox: Frozen tasks not actively being considered (white display)
- backlog: Not yet started tasks (gray display)
- ready: Tasks ready to be started (blue display)
- in_progress: Tasks currently being worked on (yellow display)
- review: Tasks under review (cyan display)
- done: Completed tasks (green display)
- closed: Closed tasks (magenta display)
Configuration
Database Storage Location
agkan allows customization of the database storage location via a configuration file.
Configuration File: .agkan.yml
Create a .agkan.yml file in your project root directory to specify the database storage location.
Configuration Example:
# Path to database file
path: ./.agkan/data.dbPath Specification
Relative Path: Resolved relative to the current directory
path: ./data/kanban.db path: ./.agkan/data.dbAbsolute Path: Used as-is
path: /home/user/.config/akan/data.db
Environment Variable Configuration
agkan supports the AGENT_KANBAN_DB_PATH environment variable for specifying the database location. This is particularly useful in CI/CD environments and for managing multiple environments.
Setting the Environment Variable:
# Use a custom database path
export AGENT_KANBAN_DB_PATH=/path/to/your/database.db
agkan task list
# Use absolute path
export AGENT_KANBAN_DB_PATH=/home/user/.config/akan/data.db
# Use relative path
export AGENT_KANBAN_DB_PATH=./custom/location/data.dbPriority Order:
The database path is resolved in the following priority order:
Normal Mode (when NODE_ENV is not test):
- Environment Variable (highest priority):
AGENT_KANBAN_DB_PATH - Configuration File (fallback):
pathfield in.agkan.yml - Default Path (lowest priority):
.agkan/data.db
Test Mode (when NODE_ENV=test):
- Environment Variable (highest priority):
AGENT_KANBAN_DB_PATH - Configuration File (fallback):
pathfield in.agkan-test.yml - Default Path (lowest priority):
.agkan-test/data.db
Test Mode Explanation:
Test mode (NODE_ENV=test) automatically isolates test data from production data:
- Uses separate configuration file:
.agkan-test.ymlinstead of.agkan.yml - Uses separate default directory:
.agkan-test/instead of.agkan/ - Environment variable still takes highest priority in test mode
- Prevents accidental mixing of test and production data
Use Cases:
CI/CD Pipeline:
# Use temporary database for CI tests export AGENT_KANBAN_DB_PATH=/tmp/ci-test-db.db agkan task listMultiple Environments:
# Development environment export AGENT_KANBAN_DB_PATH=./dev/data.db # Staging environment export AGENT_KANBAN_DB_PATH=./staging/data.db # Production environment export AGENT_KANBAN_DB_PATH=./prod/data.dbTesting:
# Automated tests with isolated database NODE_ENV=test npm test # Uses .agkan-test/data.db by default # Override with custom test database NODE_ENV=test AGENT_KANBAN_DB_PATH=/tmp/test.db npm test
Default Behavior
If no .agkan.yml file exists and no environment variable is set, the database is created in:
<current-directory>/.agkan/data.dbIn test mode (NODE_ENV=test), the default location is:
<current-directory>/.agkan-test/data.dbPer-Project Management
To manage separate tasks for different projects, place .agkan.yml in each project root:
# Project A
cd /path/to/projectA
cat > .agkan.yml << EOF
path: ./.agkan/data.db
EOF
# Project B
cd /path/to/projectB
cat > .agkan.yml << EOF
path: ./.agkan/data.db
EOFThis enables independent task management for each project.
Board Settings
The board section in .agkan.yml allows you to customize the behavior of the agkan board command.
Available Fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| board.port | number | 3000 | Port number for the board web server |
| board.title | string | "agkan Board" | Title displayed in the board UI |
Configuration Example
# Path to database file
path: ./.agkan/data.db
# Board settings
board:
port: 8080
title: "My Project Board"Field Details
board.port: Specifies the TCP port on which the board web server listens. Useful when the default port3000is already in use.board: port: 8080board.title: Sets the title shown in the board UI. Helps distinguish boards when managing multiple projects.board: title: "My Project Board"
Planned Features
Task Attachments
Task attachment management is currently under development. This feature will allow users to attach files to tasks for better context and documentation.
Planned CLI Commands:
agkan task attach add <task-id> <file-path>- Attach a file to a taskagkan task attach list <task-id>- List all attachments for a taskagkan task attach delete <attachment-id>- Remove an attachment from a task
For detailed information about planned features, see docs/planned-features.md.
Technology Stack
- Language: TypeScript 5.x
- CLI Framework: Commander.js
- Database: SQLite3 (better-sqlite3)
- Terminal Display: Chalk
- Web Server: Hono (for Kanban board viewer)
- Build Tool: TypeScript Compiler
Project Structure
agkan/
├── bin/
│ └── agkan # CLI entry point
├── src/
│ ├── cli/
│ │ ├── commands/
│ │ │ ├── block/ # Blocking relationship commands
│ │ │ │ ├── add.ts
│ │ │ │ ├── list.ts
│ │ │ │ └── remove.ts
│ │ │ ├── meta/ # Metadata commands
│ │ │ │ ├── delete.ts
│ │ │ │ ├── get.ts
│ │ │ │ ├── list.ts
│ │ │ │ └── set.ts
│ │ │ ├── tag/ # Tag commands
│ │ │ │ ├── add.ts
│ │ │ │ ├── attach.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── detach.ts
│ │ │ │ ├── list.ts
│ │ │ │ └── show.ts
│ │ │ ├── board.ts # Kanban board command
│ │ │ └── task/ # Task commands
│ │ │ ├── add.ts
│ │ │ ├── count.ts
│ │ │ ├── delete.ts
│ │ │ ├── find.ts
│ │ │ ├── get.ts
│ │ │ ├── list.ts
│ │ │ ├── update-parent.ts
│ │ │ └── update.ts
│ │ ├── utils/ # CLI utilities
│ │ └── index.ts # CLI entry point and command registration
│ ├── board/
│ │ └── server.ts # Kanban board web server (Hono)
│ ├── db/
│ │ ├── config.ts # DB configuration
│ │ ├── connection.ts # Database connection management
│ │ ├── schema.ts # Schema definition and migration
│ │ └── reset.ts # DB reset for testing
│ ├── models/
│ │ ├── Task.ts # Task model
│ │ ├── Tag.ts # Tag model
│ │ ├── TaskBlock.ts # Blocking relationship model
│ │ ├── TaskMetadata.ts # Metadata model
│ │ ├── TaskTag.ts # Task-tag association model
│ │ └── index.ts
│ ├── services/
│ │ ├── TaskService.ts # Task management business logic
│ │ ├── TagService.ts # Tag management business logic
│ │ ├── TaskBlockService.ts # Blocking relationship management
│ │ ├── TaskTagService.ts # Task-tag association management
│ │ ├── MetadataService.ts # Metadata management
│ │ ├── FileService.ts # File reading
│ │ └── index.ts
│ └── utils/
│ ├── format.ts # Format utilities
│ ├── cycle-detector.ts # Circular reference detection
│ ├── input-validators.ts # Input validation
│ └── security.ts # Security utilities
├── dist/ # Build output directory
├── package.json
├── tsconfig.json
└── README.mdDatabase Schema
tasks Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | title | TEXT | Task title (required) | | body | TEXT | Task body | | status | TEXT | Status (icebox, backlog, ready, in_progress, review, done, closed) | | author | TEXT | Creator/author | | parent_id | INTEGER | Parent task ID (foreign key, nullable) | | created_at | TEXT | Creation timestamp (ISO 8601 format) | | updated_at | TEXT | Update timestamp (ISO 8601 format) |
Notes:
parent_idis automatically set to NULL when parent task is deleted (ON DELETE SET NULL)
attachments Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | task_id | INTEGER | Task ID (foreign key) | | file_path | TEXT | File path (required) | | created_at | TEXT | Creation timestamp (ISO 8601 format) |
task_blocks Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | blocker_task_id | INTEGER | Task ID that blocks (foreign key) | | blocked_task_id | INTEGER | Task ID that is blocked (foreign key) | | created_at | TEXT | Creation timestamp (ISO 8601 format) |
Notes:
blocker_task_idandblocked_task_idcombination has a unique constraint- Blocking relationships are automatically deleted when either task is deleted (ON DELETE CASCADE)
tags Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | name | TEXT | Tag name (required, unique) | | created_at | TEXT | Creation timestamp (ISO 8601 format) |
task_tags Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | task_id | INTEGER | Task ID (foreign key) | | tag_id | INTEGER | Tag ID (foreign key) | | created_at | TEXT | Creation timestamp (ISO 8601 format) |
Notes:
task_idandtag_idcombination has a unique constraint- Associations are automatically deleted when task or tag is deleted (ON DELETE CASCADE)
task_metadata Table
| Column Name | Type | Description | |-------------|------|-------------| | id | INTEGER | Primary key (auto-increment) | | task_id | INTEGER | Task ID (foreign key) | | key | TEXT | Metadata key | | value | TEXT | Metadata value | | created_at | TEXT | Creation timestamp (ISO 8601 format) |
Notes:
task_idandkeycombination has a unique constraint- Metadata is automatically deleted when the task is deleted (ON DELETE CASCADE)
Development
Developer Setup
For contributors and developers who want to work on agkan itself:
- Clone the repository:
git clone https://github.com/gendosu/agkan.git
cd agkan- Install dependencies:
npm install- Build the TypeScript code:
npm run build- Register as a global command:
npm linkDevelopment Guidelines
For comprehensive development information, see the following documentation:
- TESTING.md - Testing guide, coverage execution, and test patterns
- CONTRIBUTING.md - Contribution guidelines and TDD practices
- docs/TDD-GUIDE.md - Test-Driven Development guide with practical examples
- docs/ARCHITECTURE.md - Project architecture and design patterns
Code Quality
This project uses ESLint and Prettier for code quality:
npm run lint # Check code
npm run lint:fix # Auto-fix issues
npm run format # Format code
npm run check # Run all checksTesting
Unit Tests
Run unit tests with Vitest:
npm testAll service and model layers are tested.
End-to-End Tests
Run comprehensive e2e tests that execute actual CLI commands:
npm run test:e2eE2E tests cover the following features:
- Build and unit tests
- Tag management (create, list, delete, duplicate check)
- Tag assignment (attach, detach, display, duplicate check)
- Tag filtering (single tag, multiple tags, status combinations)
- CASCADE delete (database integrity verification)
Tests use a local test database (.agkan-test/test-e2e.db) and are automatically cleaned up after execution.
Build
npm run buildAuto-build During Development
npm run devTypeScript Type Checking
npx tsc --noEmitInitialize Database
The database is automatically created on first command execution. To manually recreate:
rm -rf data/agkan.db
agkan task list # Database will be recreatedLicense
ISC
Author
Generated with Claude Code
