Guide
Yes! Did It is a CLI-first todo tracker designed for developers. Capture tasks from your terminal or AI assistant, query them, and mark them done — without leaving your workflow.
Core Concepts
- CLI-first — all mutations (add, complete, update) happen via the CLI or API. The web dashboard is for viewing and deleting.
- MCP-ready — Claude can manage your todos through the MCP server integration.
- Time filters — query todos by time: today, tomorrow, this-week, overdue, upcoming, next-hour.
- Tags — organize todos with tags for grouping and filtering.
CLI Commands
Adding Todos
ydi add "Ship the API" --due "today 5pm"
ydi add "Review PR" --due "tomorrow 10am" --tag work --tag review
ydi add "Buy groceries" Due dates support natural language. Tags are comma-separated.
Listing Todos
ydi list # All pending todos
ydi list --filter today # Due today
ydi list --filter overdue # Past due
ydi list --filter this-week # Due this week
ydi list --all # Include completed
ydi list --tag work # Filter by tag
ydi list --current-branch # Todos on current git branch
ydi list --branch feat/auth # Todos on a specific branch
ydi list --here # Todos in current repo
ydi list --active # Todos on branches with recent commits
ydi list --verbose # Show full git context Updating Todos
ydi update abc123 --text "New text" # Change text
ydi update abc123 --due "friday 5pm" # Change due date
ydi update abc123 --clear-due # Remove due date
ydi update abc123 --tag work --tag v2 # Replace tags
ydi update abc123 --clear-tags # Remove all tags
ydi update # Interactive picker Combine multiple flags in one command to update several fields at once.
Completing Todos
ydi done abc123 # By ID (short prefix works)
ydi done # Interactive picker
When you run ydi done without an ID, an interactive picker lets you
search and select from your pending todos.
Deleting Todos
ydi delete abc123 # By ID
ydi delete # Interactive picker Managing API Keys
ydi keys create --name "CI" # Generate a new key
ydi keys list # List active keys Git Context
When you create a todo inside a git repository, the CLI automatically captures the current branch, commit SHA, and repository URL. This context links your todos to the code you're working on.
ydi add "Fix auth token refresh"
# Added: abc123 [feat/auth-fix]
ydi context # See what would be captured
# Branch: feat/auth-fix
# Commit: a1b2c3d
# Repo: https://github.com/you/project.git
# Slug: you/project
ydi add "Unrelated task" --no-context # Skip capture
Context powers branch-based filtering (ydi list --current-branch),
verbose display (-v), stale todo detection, and more.
Stale Todo Detection
When a branch is deleted (usually after a PR merge), its todos become stale.
The sweep command finds and cleans them up:
ydi sweep # Interactive — select which stale todos to complete
ydi sweep --dry-run # Preview stale todos without acting
ydi sweep --auto # Mark all stale todos as done
ydi list --stale # List stale todos without completing them A todo is considered stale when its branch no longer exists on the remote (i.e., the branch was deleted after a PR merge). Local-only branches are not considered stale.
Standup Reports
Generate a standup report showing recently completed todos grouped by branch, plus your current in-progress work:
ydi standup # Last 24 hours (default)
ydi standup --since "yesterday 9am" # Custom lookback
ydi standup --since 48h # Duration format
ydi standup --json # Structured output Configuration
Customize CLI behavior with persistent settings stored in
~/.config/yesdidit/settings.json:
ydi config list # Show all settings
ydi config set context.auto false # Disable auto git context
ydi config set default_filter today # Default list filter
ydi config set standup.since 48h # Default standup lookback
ydi config get verbose # Check a setting Using with Claude (MCP)
Once the MCP server is configured, you can ask Claude to manage your todos conversationally:
- "Add a todo to deploy the staging server by Friday"
- "What's due today?"
- "What todos are on this branch?"
- "Give me a standup report"
- "Are there any stale todos to clean up?"
- "Mark the deploy todo as done"
- "Show me everything tagged 'urgent'"
- "Delete the grocery todo"
API Overview
The full API is available at https://api.yesdidit.com/api. Authenticate with
a Bearer JWT or API key.
# List todos due today
curl -H "Authorization: ApiKey ydi_live_..." \
"https://api.yesdidit.com/api/todos?filter=today"
# Create a todo
curl -X POST \
-H "Authorization: ApiKey ydi_live_..." \
-H "Content-Type: application/json" \
-d '{"text": "Deploy v2", "due_at": "2026-03-23T17:00:00Z"}' \
https://api.yesdidit.com/api/todos
# Mark complete
curl -X POST \
-H "Authorization: ApiKey ydi_live_..." \
https://api.yesdidit.com/api/todos/ID/done For the complete API specification, see the GitHub repository.
Scripting & Automation
Every ydi command supports --json for machine-readable output,
making it easy to chain with other tools in shell scripts. Use an
API key for headless environments where interactive login isn't possible.
Piping & Filtering
# Print just the text of today's todos
ydi list --filter today --json | jq -r '.[].text'
# Count overdue items
ydi list --filter overdue --json | jq length
# Get IDs of todos tagged "release"
ydi list --tag release --json | jq -r '.[].id' Bulk Operations
# Add multiple todos from a file (one per line)
while IFS= read -r line; do
ydi add "$line" --tag sprint
done < backlog.txt
# Mark all overdue todos as done
ydi list --filter overdue --json \
| jq -r '.[].id' \
| xargs -I{} ydi done {} CI / Deploy Gates
# Fail a CI build if release todos are still open
export YDI_API_KEY="ydi_live_..."
open_count=$(ydi list --tag release --json | jq length)
if [ "$open_count" -gt 0 ]; then
echo "❌ $open_count release todo(s) still open"
ydi list --tag release
exit 1
fi
# Log a deploy as a completed todo
ydi add "Deploy v$VERSION to prod" --tag deploy
ydi done $(ydi list --tag deploy --json | jq -r '.[-1].id') Cron & Notifications
# Daily digest via cron (add to crontab)
# 0 9 * * * /path/to/daily-digest.sh
#!/bin/bash
todos=$(ydi list --filter today --json)
count=$(echo "$todos" | jq length)
if [ "$count" -gt 0 ]; then
echo "$count todo(s) due today:" | mail -s "YDI Daily Digest" you@example.com
echo "$todos" | jq -r '.[].text' | mail -s "YDI Daily Digest" you@example.com
fi Troubleshooting
Token expired
The CLI automatically refreshes tokens. If you see auth errors, run ydi login
to re-authenticate.
API unreachable
For local development, make sure the API server is running (pnpm turbo dev).
To point the CLI at a local API:
YDI_API_URL=http://localhost:3000 ydi list MCP not responding
Ensure you're signed in via the CLI first (ydi login). The MCP server
reads credentials from the same config file.