npx claudepluginhub builtby-win/skills --plugin todoThis skill uses the workspace's default tool permissions.
Add a new task to a beads repository with smart project inference.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Add a new task to a beads repository with smart project inference.
/todo <task description>Extract from the user's input:
-p or --priority, default: 2)--project, optional)--tag, optional, can be multiple)Example parsing:
/todo -p 1 Fix critical login bug --tag security --tag urgent
-> title: "Fix critical login bug"
-> priority: 1
-> tags: ["security", "urgent"]
/todo --project homebase Add dark mode
-> title: "Add dark mode"
-> project: "homebase"
-> priority: 2 (default)
Use smart inference to find the right beads repo:
import os
import subprocess
import json
from pathlib import Path
def find_beads_in_cwd():
"""Check if current directory has .beads"""
cwd = Path.cwd()
beads_dir = cwd / '.beads'
if beads_dir.exists():
return beads_dir
return None
def find_beads_in_git_root():
"""Check if git root has .beads"""
try:
result = subprocess.run(
['git', 'rev-parse', '--show-toplevel'],
capture_output=True, text=True
)
if result.returncode == 0:
git_root = Path(result.stdout.strip())
beads_dir = git_root / '.beads'
if beads_dir.exists():
return beads_dir
except:
pass
return None
def find_all_beads_repos():
"""Find all .beads directories for project selection."""
home = os.path.expanduser('~')
# Try fd first (faster)
try:
result = subprocess.run(
['fd', '-H', '-t', 'd', r'^\.beads$', home],
capture_output=True, text=True, timeout=30
)
if result.returncode == 0 and result.stdout.strip():
return [Path(p.strip()) for p in result.stdout.strip().split('\n') if p.strip()]
except (FileNotFoundError, subprocess.TimeoutExpired):
pass
# Fallback to find
try:
result = subprocess.run(
['find', home, '-type', 'd', '-name', '.beads', '-not', '-path', '*/node_modules/*'],
capture_output=True, text=True, timeout=60
)
if result.stdout.strip():
return [Path(p.strip()) for p in result.stdout.strip().split('\n') if p.strip()]
except subprocess.TimeoutExpired:
pass
return []
def match_project_by_name(name, repos):
"""Match explicit project name to a beads repo."""
# Exact match first
for repo in repos:
project_name = repo.parent.name
if project_name.lower() == name.lower():
return repo
# Fuzzy match (contains)
for repo in repos:
project_name = repo.parent.name
if name.lower() in project_name.lower():
return repo
return None
def infer_target_repo(explicit_project=None):
"""
Smart inference logic:
1. If explicit project given, find it
2. If cwd has .beads, use it
3. If cwd is in git repo with .beads, use it
4. If ambiguous, return list for user selection
"""
all_repos = find_all_beads_repos()
if not all_repos:
return None, "NO_REPOS"
# Explicit project specified
if explicit_project:
repo = match_project_by_name(explicit_project, all_repos)
if repo:
return repo, None
return all_repos, f"NO_MATCH:{explicit_project}"
# Check current directory
local_repo = find_beads_in_cwd()
if local_repo:
return local_repo, None
# Check git root
git_repo = find_beads_in_git_root()
if git_repo:
return git_repo, None
# Ambiguous - need user selection
if len(all_repos) == 1:
return all_repos[0], None
return all_repos, "AMBIGUOUS"
If NO_REPOS:
No beads repositories found on this system.
To initialize beads in a project:
cd /path/to/project
bd init
Or manually:
mkdir -p .beads && touch .beads/issues.jsonl
If NO_MATCH:<project>:
No beads repository found matching "{project}".
Available projects:
1. homebase (~/homebase)
2. skills (~/builtby.win/skills)
Use: /todo --project homebase <task>
If AMBIGUOUS:
Multiple beads repositories found. Where should this task go?
1. homebase (~/homebase)
2. skills (~/builtby.win/skills)
3. myapp (~/code/myapp)
Enter number or project name:
Then wait for user input before proceeding.
import random
import string
def get_project_prefix(beads_dir):
"""Get prefix from existing tasks or derive from project name."""
issues_file = beads_dir / 'issues.jsonl'
if issues_file.exists():
with open(issues_file, 'r') as f:
for line in f:
line = line.strip()
if line:
try:
task = json.loads(line)
task_id = task.get('id', '')
if '-' in task_id:
# Extract prefix from existing ID pattern
return task_id.rsplit('-', 1)[0]
except json.JSONDecodeError:
continue
# Derive from project name
project_name = beads_dir.parent.name
return project_name.lower().replace(' ', '-').replace('_', '-')
def generate_task_id(beads_dir):
"""Generate a unique task ID."""
prefix = get_project_prefix(beads_dir)
chars = string.ascii_lowercase + string.digits
suffix = ''.join(random.choices(chars, k=3))
return f"{prefix}-{suffix}"
from datetime import datetime, timezone
def create_task(task_id, title, priority=2, tags=None, description=None):
"""Create a task object compatible with beads format."""
now = datetime.now(timezone.utc).astimezone().isoformat()
user = os.environ.get('USER', 'unknown')
task = {
"id": task_id,
"title": title,
"status": "open",
"priority": priority,
"issue_type": "task",
"created_at": now,
"created_by": user,
"updated_at": now
}
if description:
task["description"] = description
if tags:
task["tags"] = tags
return task
def append_task(beads_dir, task):
"""Append task to issues.jsonl file."""
issues_file = beads_dir / 'issues.jsonl'
# Create file if it doesn't exist
if not issues_file.exists():
issues_file.touch()
with open(issues_file, 'a') as f:
f.write(json.dumps(task) + '\n')
return True
# If bd is available, sync the changes
if command -v bd >/dev/null 2>&1; then
cd "{project_path}"
bd sync 2>/dev/null || true
fi
Display confirmation:
Task created!
ID: homebase-7xy
Title: Add dark mode toggle
Priority: 2 (medium)
Project: homebase (~/homebase)
Check the target repo's Beads task list to see the new entry.
If tags were added:
Task created!
ID: webapp-2cd
Title: Fix mobile layout
Priority: 2 (medium)
Tags: frontend, urgent
Project: webapp (~/code/webapp)
User input:
/todo -p 1 --tag security Fix XSS vulnerability in login form
Claude execution:
.beads/ - not found.beads/ - found at ~/webapp/.beads/webapp-8ab~/webapp/.beads/issues.jsonlbd sync if availableOutput:
Task created!
ID: webapp-8ab
Title: Fix XSS vulnerability in login form
Priority: 1 (high)
Tags: security
Project: webapp (~/webapp)
Create the task anyway - the file will be created or appended to.
The 3-character random suffix makes collisions extremely unlikely. If it happens, the task is still valid - beads uses the ID as a reference, not a unique key.
Error: Cannot write to ~/protected/.beads/issues.jsonl
Check file permissions and try again.
If priority is not 1, 2, or 3, default to 2:
priority = max(1, min(3, int(priority_arg))) if priority_arg else 2
Optional settings in project's CLAUDE.md:
## Beads Configuration
DEFAULT_BEADS_PRIORITY=2
BEADS_PROJECT_PREFIX=myapp
The prefix from CLAUDE.md takes precedence over auto-detection.