@kythin/stackydo
v0.10.0
Published
Context-aware CLI task manager, based on the best task management system I ever had; a stack of todo's on sticky notes. Designed for maximum flexibility and AI-friendly workflow support!
Downloads
397
Readme
stackydo
One person's entire workload, in one place.
Stackydo is a context-aware CLI task manager designed for individual engineers, leads, and makers who juggle work across many projects, teams, and responsibilities. Tasks are plain markdown files with YAML frontmatter — no database, no server, no vendor lock-in.
The core idea: your work doesn't live in one project. You might be debugging a production incident, reviewing a teammate's PR, prepping a conference talk, and planning next sprint — all in the same afternoon. Stackydo uses stacks to separate these workstreams while keeping everything in a single, searchable task store.
Why This Exists
Most task managers are built for teams or for single projects. Stackydo is built for you — the individual who needs to:
- Track work across multiple projects, random ideas, ad-hoc tasks, team duties, and personal goals simultaneously
- Create tasks from wherever you are — terminal, editor, scripts, or AI agents — so fast it becomes muscle memory to offload every stray thought
- Search across everything at once ("what was that security thing last week?")
- Let AI tools triage, summarize, and report on your workload via the built-in MCP server
- Own your data as plain files you can grep, version, and back up
Features
- Headless CLI — create, list, search, update, complete, delete from scripts and pipelines
- MCP server — gives AI assistants (Claude Desktop, Claude Code, etc.) full access to your task store
- Stacks — organize tasks into named workstreams (e.g. "work", "personal", "sprint-12")
- Short IDs — human-friendly IDs like SD1, SD2 alongside ULIDs; all commands accept either
- Automatic context capture — records git branch/commit, working directory, and project context on task creation
- Task graph — subtasks, dependencies (blocked-by, blocks, related-to)
- AI-friendly storage — plain markdown+YAML files that any LLM or script can read and write
stackydo.jsonconfig files — project-level workspace location, context, and workflow customisation (with~/.stackydo.jsonglobal fallback)- Session chaining — tracks the last task ID created per shell session via
$STACKYDO_LAST_ID - Configurable storage — set
dirinstackydo.jsonfor per-project workspaces, or$STACKYDO_DIRfor per-session overrides (defaults to~/.stackydo/) - Multi-workspace — discover, list, and migrate tasks across workspaces
- Doctor — diagnose and auto-fix workspace issues (missing short IDs, orphan refs, corrupt files)
Install
Homebrew (macOS/Linux)
brew tap kythin/homebrew-tap && brew install stackydoShell (curl one-liner)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/kythin/stackydo-cli/releases/latest/download/stackydo-installer.sh | shPowerShell (Windows)
powershell -c "irm https://github.com/kythin/stackydo-cli/releases/latest/download/stackydo-installer.ps1 | iex"From source
cargo install --git https://github.com/kythin/stackydo-cliUpdate
# Homebrew
brew upgrade stackydo
# Shell — re-run the curl installer, or use the built-in updater:
stackydo-updateAll methods install two binaries: stackydo (CLI) and stackydo-mcp (MCP server).
Quick Start
# Create a task
stackydo create --title "Fix auth bug" --tags "backend,urgent" --priority high --stack work \
-- The login endpoint returns 500 when the token expires
# List tasks
stackydo list
stackydo list --status todo --sort priority
stackydo list --stack work
stackydo list --overdue
# Show task detail (prefix matching and short IDs work everywhere)
stackydo show SD1
stackydo show 01HQ
# Update a task
stackydo update SD1 --status in_progress --note "Investigating root cause"
# Complete a task
stackydo complete SD1
# Search
stackydo search "auth"
# Add a comment
stackydo comment SD1 "Turns out it was a timezone issue"
# Check workspace health
stackydo doctor
stackydo doctor --fixCLI Commands
| Command | Description |
|---------|-------------|
| create | Create a new task with title, tags, priority, stack, body, due date, dependencies |
| list | List/filter tasks by status, stage, tag, priority, stack, due date; sort, group, paginate |
| show | Show a task's full details |
| update | Update fields, append body text, sed-style substitution, add timestamped notes |
| complete | Mark task(s) as done (single or bulk with --all) |
| delete | Permanently delete task(s) (single or bulk with --all) |
| search | Search title and body (case-insensitive) with same filters as list |
| comment | Add a comment to a task |
| stats | Summary statistics: totals, overdue count, breakdowns by status/stack/tag |
| stacks | All stacks with per-stack task counts and status breakdowns |
| context | Preview what context would be captured for a new task |
| init | Initialize a new workspace (optionally with --here and --git) |
| doctor | Diagnose and optionally fix workspace issues |
| bulk-status | Move all tasks matching a status (and optional filters) to a new status |
| shuffle | Randomise the order of tasks in a stack+status group |
| draw | Draw the top task from one group and move it to another |
| list-workspaces | Discover all stackydo workspaces on the system |
| migrate | Move or copy tasks between workspaces |
| import | Import tasks from stdin (JSON or YAML) |
| mcp-setup | Register stackydo-mcp with Claude Code via claude mcp add |
| agent-setup | Generate an AI agent playbook in your project's CLAUDE.md |
Stacks
A task can belong to one stack — a named group like "work", "personal", or "sprint-12". Think of stacks as physical piles of tasks rather than flat database categories.
# Create a task on a stack
stackydo create --title "Deploy v2" --stack work
# Filter tasks by stack
stackydo list --stack work
stackydo list --stack personal --status todo
# See all stacks with counts
stackydo stacksThe manifest tracks known stack names. Tasks without a stack are unstacked and won't appear in stack-filtered results.
Workflows
Workflows define the statuses available to tasks and how they map to lifecycle stages (backlog, active, archive). Each stack can use a different workflow.
Built-in Workflows
Kanban (default) — traditional task board:
| Stage | Statuses |
|-------|----------|
| Backlog | todo, on_hold |
| Active | in_progress, blocked, in_review |
| Archive | done, cancelled |
Deck — card game metaphor for randomised/prioritised work:
| Stage | Statuses |
|-------|----------|
| Backlog | deck |
| Active | hand, table |
| Archive | discard |
Per-Stack Assignment
Set a stack's workflow in your project's stackydo.json (or in ~/.stackydo.json for a global default):
{
"$schema": "https://raw.githubusercontent.com/kythin/stackydo/main/schemas/stackydo.schema.json",
"stack_workflows": {
"ideas": "deck",
"work": "kanban"
}
}Stacks without a workflow inherit the workspace default (kanban). You can also define a fully custom workflow inline in stackydo.json — see public-root/docs/workflows.md for the complete reference.
Index Ordering
Tasks within the same stack+status group have an index field for positional ordering. Indexes are maintained automatically when tasks are created, moved, or deleted. Use shuffle to randomise order, and draw to pull the top task from one group to another:
# Randomise the deck
stackydo shuffle --stack ideas --status deck
# Draw the top card into your hand
stackydo draw --source ideas/deck --target ideas/handMCP Server (Claude Desktop / Claude Code)
Stackydo includes an MCP server that gives AI assistants full access to your task store.
Setup
Install stackydo using any method from the Install section. Both stackydo and stackydo-mcp are included.
Claude Code (quickest):
stackydo mcp-setupThis runs claude mcp add to register the server. Use --scope user for global access or --scope project (default) for per-project.
Claude Desktop — add to your config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"stackydo": {
"command": "stackydo-mcp"
}
}
}To use a non-default storage directory, add an env key:
{
"mcpServers": {
"stackydo": {
"command": "stackydo-mcp",
"env": {
"STACKYDO_DIR": "/path/to/your/tasks"
}
}
}
}Restart Claude Desktop after editing the config.
Available MCP Tools
| Tool | Description |
|------|-------------|
| list_tasks | List/filter tasks by status, tag, priority, stack, due date; sort and group |
| get_task | Get a single task by ID (prefix matching) |
| create_task | Create a task with title, priority, tags, stack, body, due date |
| update_task | Update fields, append timestamped notes, body editing |
| complete_task | Mark a task as done |
| delete_task | Permanently delete a task |
| search_tasks | Search title and body (case-insensitive) |
| add_comment | Add a comment to a task |
| get_stats | Summary statistics: totals, overdue count, breakdowns by status/stack/tag |
| get_stacks | All stacks with per-stack task counts and status breakdowns |
| list_workspaces | Discover all stackydo workspaces on the system |
| migrate_tasks | Move or copy tasks between workspaces |
| doctor | Diagnose and optionally fix workspace issues |
| shuffle | Randomise task order in a stack+status group |
| draw | Draw top task from one group and move to another |
The server also exposes a stackydo://guide resource with a full agent guide, and prompt templates for triage, planning, and task extraction.
AI Agent Setup
Stackydo is designed to be used by AI coding agents (Claude Code, Cursor, etc.) as their own task tracker:
# Generate a CLAUDE.md playbook for your project
stackydo agent-setup
# Register the MCP server with Claude Code
stackydo mcp-setupagent-setup writes instructions into your project's CLAUDE.md so agents know how to create, update, and complete tasks as they work.
Environment Variables
| Variable | Description |
|----------|-------------|
| STACKYDO_DIR | Override the task storage directory (highest priority, overrides stackydo.json; default: ~/.stackydo/) |
| STACKYDO_LAST_ID | Set automatically by stackydo create; chains tasks in a shell session |
Task Storage
Each task is a markdown file at <STACKYDO_DIR>/<ULID>.md:
---
id: 01HQXYZ...
short_id: SD1
title: Fix auth bug
status: todo
priority: high
tags: [backend, urgent]
stack: work
index: 0
created: 2025-02-13T10:30:00Z
modified: 2025-02-13T10:30:00Z
context:
working_dir: /home/user/project
git_branch: main
git_commit: a3f7d92
---
The login endpoint returns 500 when the token expires.A manifest at <STACKYDO_DIR>/manifest.json tracks tags, stacks, and the short-ID counter. This file is internal state managed automatically — all user-facing configuration lives in stackydo.json (see public-root/docs/config.md).
Context Discovery
On task creation, stackydo automatically captures:
- Current working directory
- Git branch, remote URL, and HEAD commit (if in a repo)
- Content from the nearest
stackydo.jsonfile (walks up from CWD, falls back to~/.stackydo.json) $STACKYDO_LAST_ID— the ID of the previous task created in the same shell session
Use stackydo context to preview what would be captured without creating a task.
Workspace Resolution
stackydo.json can set the task store location via the dir field. This lets a project root define a shared workspace without requiring every user to set an environment variable.
Resolution priority:
$STACKYDO_DIRenv var (highest — per-session override)dirfield in the neareststackydo.json(per-project)~/.stackydo/(default)
Example stackydo.json:
{
"$schema": "https://raw.githubusercontent.com/kythin/stackydo/main/schemas/stackydo.schema.json",
"dir": ".stackydo-workspace",
"context": {
"project": "my-app",
"description": "Project-level context captured on new tasks"
}
}The dir path is resolved relative to the config file's location. Use stackydo context to see which source resolved the task store. For workflow customisation and per-stack workflow assignment, see public-root/docs/config.md and public-root/docs/workflows.md.
To set up a project workspace:
stackydo init --here --dir .stackydo-workspaceContributing
# Build
cargo build
# Run tests
cargo test # unit tests
cargo build && bash tests/smoke_test.sh # CLI smoke tests
bash tests/test_all.sh # full suite: clippy + unit + build + smoke + scenario + scale
# Lint
cargo clippyTests use $STACKYDO_DIR to write to a local tests/.test-data/ directory — they never touch ~/.stackydo/.
License
MIT
