@matthamlin/dodo
v0.1.0
Published
A task management CLI with web UI
Readme
dodo
A local task management CLI with a web UI. Tasks are stored as JSONL in a .dodo/ directory, making them easy to track in version control.
Getting Started
Install dodo:
bun add --exact @matthamlin/dodoInitialize a new task store in your project:
dodo initThis creates a .dodo/ directory with a tasks.jsonl file.
Note: Most commands auto-initialize if
.dodo/doesn't exist yet, so you can skipinitand jump straight tododo add.
Commands
dodo init
Initialize a .dodo/ directory in the current working directory.
dodo initdodo add <title>
Create a new task. Aliases: create.
dodo add "Fix login bug"
dodo add "Setup database" --description "Configure PostgreSQL" --tags "setup,backend"
dodo add "Write tests" --parent <parent-id> --blocked-by <id1>,<id2>| Flag | Short | Description |
| ------------------------ | ----- | -------------------------------- |
| --description <text> | -d | Task description |
| --parent <id> | -p | Parent task ID |
| --tags <tag1,tag2> | -t | Comma-separated tags |
| --blocked-by <id1,id2> | -b | Comma-separated blocker task IDs |
dodo list
List tasks in a tree view (hides done tasks by default). Aliases: ls.
dodo list
dodo list --status open --tag important
dodo list --all| Flag | Short | Description |
| ------------------- | ----- | ----------------------------------------------------------- |
| --status <status> | -s | Filter by status (open, in-progress, blocked, done) |
| --tag <tag> | -t | Filter by tag |
| --parent <id> | -p | Filter by parent task |
| --all | -a | Include done tasks |
dodo show <id>
Display detailed information about a task, including its relationships, tags, and timestamps.
dodo show abc12345
dodo show abc12345 --prompt # render prompt template
dodo show abc12345 --prompt | pbcopy # pipe to clipboard| Flag | Description |
| ---------- | -------------------------------------------------------- |
| --prompt | Render the task as an agent prompt and copy to clipboard |
Tip: Use
--promptto quickly copy a task as a ready-made prompt for an AI coding agent. See Prompt Templates for customization.
dodo update <id>
Update task properties. Aliases: edit.
dodo update abc12345 --title "New title" --description "Updated description"
dodo update abc12345 --status in-progress
dodo update abc12345 --add-tag urgent --remove-tag backlog
dodo update abc12345 --add-blocker xyz99999
dodo update abc12345 --parent def67890 # set parent
dodo update abc12345 --parent "" # remove parent| Flag | Short | Description |
| ----------------------- | ----- | ---------------------------- |
| --title <text> | | New title |
| --description <text> | -d | New description |
| --status <status> | -s | Set status |
| --parent <id> | -p | Set or remove ("") parent |
| --add-tag <tag> | | Add a tag |
| --remove-tag <tag> | | Remove a tag |
| --add-blocker <id> | | Add a blocking dependency |
| --remove-blocker <id> | | Remove a blocking dependency |
dodo complete <id>
Mark a task as done. Any tasks that were blocked by this task will have their status automatically re-evaluated. Aliases: done.
dodo complete abc12345dodo delete <id>
Delete a task and clean up all references (parent/child links, blocking dependencies). Aliases: rm.
dodo delete abc12345dodo query <text>
Fuzzy search across task titles, descriptions, and tags. Powered by MiniSearch with prefix matching and fuzzy tolerance. Aliases: search.
dodo query "login"
dodo query "db" --status open --limit 10
dodo query "setup" --all| Flag | Short | Description |
| ------------------- | ----- | ------------------------- |
| --status <status> | -s | Filter by status |
| --all | -a | Include done tasks |
| --limit <count> | -n | Max results (default: 20) |
dodo api [method] <path>
Call REST API endpoints directly without a running server. Useful for scripting and automation.
dodo api tasks # GET /api/tasks
dodo api get tasks # explicit GET
dodo api post tasks -d '{"title": "My task"}' # create a task
dodo api patch tasks/abc123 -d '{"status": "done"}'
dodo api delete tasks/abc123
dodo api prompt-template # get the prompt template| Flag | Short | Description |
| --------------- | ----- | -------------------------- |
| --body <json> | -d | Request body (JSON string) |
dodo serve
Start the web UI.
dodo serve
dodo serve --port 8080| Flag | Short | Description |
| --------------- | ----- | --------------------------- |
| --port <port> | -p | Port number (default: 3456) |
Task Statuses
| Status | Description |
| ------------- | ------------------------------------ |
| open | Default status for new tasks |
| in-progress | Currently being worked on |
| blocked | Has incomplete blocking dependencies |
| done | Completed |
Task Relationships
Dodo supports two kinds of relationships between tasks:
Parent-child - Organize tasks hierarchically. A task can have one parent and many children. The list command renders these as a tree.
Blocking dependencies - Model task dependencies. When a task has blockers, its status automatically becomes blocked until all blockers are marked done. Dodo validates against cycles in both relationship types.
Storage
Tasks are stored in .dodo/tasks.jsonl as one JSON object per line. This format is human-readable and works well with version control. Writes are atomic (temp file + rename) to prevent corruption.
Web UI
Run dodo serve to open a browser-based interface for managing tasks. The web UI supports:
- List view with hierarchical tree layout
- Kanban view with columns for each status
- Task detail page with full markdown rendering, relationships, and timestamps
- Copy agent prompt button on the task detail page — copies a ready-made prompt to your clipboard
- Adding and deleting tasks
- Cycling task status by clicking the status badge
- Filtering by status and tag
- Fuzzy search
REST API
The web server exposes a JSON API at /api/. You can also call these endpoints directly from the CLI with dodo api.
| Method | Path | Description |
| -------- | ---------------------- | --------------------------------------------------- |
| GET | /api/tasks | List tasks (filter: status, tag, parent) |
| POST | /api/tasks | Create a task |
| GET | /api/tasks/search | Fuzzy search (q, status, tag, all, limit) |
| GET | /api/tasks/:id | Get a task by ID |
| PATCH | /api/tasks/:id | Update a task |
| DELETE | /api/tasks/:id | Delete a task |
| GET | /api/prompt-template | Get the prompt template and variables |
| PUT | /api/prompt-template | Save a custom prompt template |
| GET | /api/__introspect | List all API endpoints |
Prompt Templates
Dodo can render any task as a prompt for AI coding agents. Use this from the CLI with dodo show <id> --prompt or from the web UI with the Copy agent prompt button on any task detail page.
The default template produces a structured prompt with the task title, description, status, relationships, and a completion command. To customize it, create a .dodo/prompt-template.txt file with your own template.
Available variables
| Variable | Description |
| ----------------- | ------------------------------------- |
| {{id}} | Task ID |
| {{title}} | Task title |
| {{description}} | Task description |
| {{status}} | Task status (open, in-progress, etc.) |
| {{tags}} | Comma-separated tags |
| {{parent}} | Parent task title and ID |
| {{children}} | List of subtask titles and IDs |
| {{blocked_by}} | List of blocking task titles and IDs |
| {{blocks}} | List of tasks this one blocks |
| {{created_at}} | Creation timestamp |
| {{updated_at}} | Last update timestamp |
Custom template example
Create .dodo/prompt-template.txt:
Complete the following task: {{title}}
{{description}}
Related context:
- Blocked by: {{blocked_by}}
- Subtasks: {{children}}
When finished, run: `dodo complete {{id}}`Environment Variables
| Variable | Description |
| ---------- | ------------------------------ |
| NO_COLOR | Set to disable terminal colors |
Contributing
Building
This package uses hohoro and TypeScript to build the source code and generate types. The web UI is bundled separately with Bun.
To build, run bun run build from the root or from this workspace.
Code Quality
Type Checking - Uses TypeScript via tsgo. Run bun run type-check.
Linting - Uses oxlint with type-aware rules. Run bun run lint.
Tests - Uses Bun's built-in test runner. Run bun run test.
Publishing
To publish, run bun run pub from the workspace root. This will prompt you to login to npm and publish the package.
