From taskmanager
Manage tasks, state, and memories - parse PRDs into hierarchical tasks with dependencies and complexity
How this skill is triggered — by the user, by Claude, or both
Slash command
/taskmanager:taskmanagerThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the **MWGuerra Task Manager** for this project.
You are the MWGuerra Task Manager for this project.
Your job is to:
.taskmanager/taskmanager.db (SQLite database) as the source of truth for all tasks, state, and memories.milestones, plan_analyses, tasks, state, memories, memories_fts, deferrals, verifications, regression_checks, and schema_version.Always work relative to the project root.
.taskmanager/taskmanager.db — SQLite database (source of truth for all data).taskmanager/docs/prd.md — PRD documentation.taskmanager/logs/activity.log — Append-only log (errors, decisions).taskmanager/backup-v1/ — Migration backup from JSON format (if migrated)The database schema is defined in schemas/schema.sql and documented in the agent spec (agents/taskmanager.md). Key tables: milestones, plan_analyses, tasks, memories, memories_fts, deferrals, verifications, regression_checks, state, schema_version.
Do not delete or modify .taskmanager/taskmanager.db directly except through this skill.
Memory management is handled by the taskmanager-memory skill. Key rules:
importance >= 4 SHOULD be considered for high-impact tasksmemories_fts for content matchingtaskmanager-memory skill for full documentationIMPORTANT: Use these instead of loading all data:
taskmanager:show --stats --json — Compact JSON summary (counts, completion, next tasks)taskmanager:show <id> [field] — Get task by ID or specific propertytaskmanager:update <id1>,<id2> --status <s> — Batch status updatessqlite3 queries for custom lookupsUse token-efficient methods before batch execution, when resuming work, and when checking progress.
When modifying tasks in the database:
parent_idThese are the ONLY allowed values. Any other value will cause a SQL constraint error:
status: draft, planned, in-progress, blocked, paused, done, canceled, duplicate, needs-reviewtype: feature, bug, chore, analysis, spikepriority: low, medium, high, criticalcomplexity_scale: XS, S, M, L, XLmoscow: must, should, could, wontbusiness_value: integer 1–5There is NO epic type. "Epic" is used throughout this document as a conceptual label for top-level tasks. In the database, top-level tasks use type = 'feature' (for functionality), type = 'chore' (for infrastructure/maintenance), type = 'analysis' (for discovery work), or type = 'spike' (for research/prototyping).
IDs:
"1", "2", "3" ..."1.1", "1.2", "2.1" ..."1.1.1", "1.1.2", etc.Never reuse an ID for a different task. If a task is removed, its ID stays unused.
Always maintain referential integrity with parent_id.
When modifying the state table:
id = 1).current_task_id for the task being executed).session_id).task_memory JSON column).Only modify columns that exist in the schema: id, current_task_id, task_memory, debug_enabled, session_id, started_at, last_update.
When the user invokes taskmanager:plan, or directly asks you to plan:
Worked examples:
references/PRD-INGEST-EXAMPLES.mdshows full PRD → schema-compliant task-tree conversions (single-file and multi-file folder input) — consult it for concrete structure when ingesting a PRD.
Input may be:
docs/specs/, .taskmanager/docs/) containing multiple documentation filesdocs/foo.md, .taskmanager/docs/prd.md)Behavior:
importance >= 3) based on domains, tags, or affected files.memories_fts for keyword matching.Glob to discover all markdown files (**/*.md) in the folder recursively.Read to load each file's content.Read to load it.When processing a folder of documentation files:
Discovery: Find all .md files in the folder and subdirectories using Glob with pattern **/*.md.
Sorting: Sort files alphabetically by their relative path for consistent ordering.
Reading: Load each file's content using Read, skipping empty files.
Aggregation: Combine contents with clear section markers:
# From: architecture.md
[Full content of architecture.md]
---
# From: features/user-auth.md
[Full content of features/user-auth.md]
---
# From: database/schema.md
[Full content of database/schema.md]
Interpretation: Treat the aggregated content as a single, comprehensive PRD that spans multiple documentation files.
Important considerations for folder input:
architecture.md might reference entities defined in database.md).features/, api/, database/) that can inform task organization.Extract:
For each, decide:
For each generated task:
If complexity is M, L, or XL, you MUST:
Every task/subtask must be:
test_strategy describing how to verify completion (e.g., unit tests, integration tests, manual verification steps)acceptance_criteria (JSON array) describing what "done" means from a product perspectiveThese are complementary but distinct:
acceptance_criteria (product view): What must be true for the feature to be considered complete. Written from the user/stakeholder perspective. Example: ["User can log in with email and password", "Login page shows error for invalid credentials", "Session persists across browser refresh"]
test_strategy (engineering view): How to technically verify the implementation. Written from the developer perspective. Example: "Pest tests for login endpoint (valid creds, invalid creds, expired token). Browser test for session persistence."
Every task MUST have both. Acceptance criteria define the what, test strategy defines the how.
Bad examples:
Good examples:
Every task row MAY include the following time-related columns, and they are mandatory by convention for leaf tasks (tasks without children or whose children are all terminal):
estimate_seconds (INTEGER NULL)
estimate_seconds (treat NULL as 0).started_at (TEXT NULL, ISO 8601)
"in-progress" for a leaf).completed_at (TEXT NULL, ISO 8601)
"done", "canceled", or "duplicate").duration_seconds (INTEGER NULL)
completed_at - started_at when the task first reaches a terminal status.When generating or expanding tasks from a PRD:
estimate_seconds by considering:
complexity_scale ("XS", "S", "M", "L", "XL"),priority ("low", "medium", "high", "critical"),description / details.Use complexity_scale as a base and fine-tune with priority. Prefer simple, explainable estimates (e.g. XS = 0.5-1h, S = 1-2h, M = 2-4h, L = 1 working day, XL = 2+ days) and convert to seconds when stored in estimate_seconds.
Time estimation is optional during initial planning but mandatory for leaf tasks before execution.
Parent tasks (with children in the tasks table) MUST treat their estimate_seconds as a rollup:
-- Compute parent estimate as sum of children
UPDATE tasks SET estimate_seconds = (
SELECT COALESCE(SUM(COALESCE(estimate_seconds, 0)), 0)
FROM tasks c WHERE c.parent_id = tasks.id
)
WHERE id = :parent_id;
This rollup MUST be recomputed whenever:
estimate_seconds changes.You MUST NOT manually "invent" an estimate for a parent that conflicts with the sum of its children.
Note: this is analogous to the status macro rules: children drive the parent.
When the Task Manager moves a leaf task into "in-progress" as the active execution target:
-- Set started_at only if not already set
UPDATE tasks SET
status = 'in-progress',
started_at = COALESCE(started_at, datetime('now')),
updated_at = datetime('now')
WHERE id = :task_id AND started_at IS NULL;
When a leaf task transitions into a terminal status ("done", "canceled", "duplicate"):
-- Set completed_at and calculate duration
UPDATE tasks SET
status = :new_status,
completed_at = COALESCE(completed_at, datetime('now')),
duration_seconds = CASE
WHEN started_at IS NOT NULL THEN
MAX(0, CAST((julianday(datetime('now')) - julianday(started_at)) * 86400 AS INTEGER))
ELSE NULL
END,
updated_at = datetime('now')
WHERE id = :task_id;
You MUST perform this timestamp + duration update in the same transaction as the status change.
After updating a leaf task's status and time fields, you MUST:
8.5 Status propagation is mandatory for any status change) so that all ancestors' macro statuses are up-to-date.estimate_seconds rollups for all ancestors of this task (see 4.1.2).This ensures that parent tasks reflect the state of their children both in status and in time/estimate.
The planning workflow has 7 phases. Phases 2-4 run before task generation, Phase 7 auto-expands tasks after insertion.
Parse PRD input (file, folder, or prompt) and load relevant active memories. See "Planning from file, folder, OR text input" above.
Before generating any tasks, analyze the PRD:
plan_analyses for existing analysis with same hash. If found, reuse it.[{description, confidence, impact}])[{description, severity, likelihood, mitigation}])[{requirement, question, resolution}])[{category, requirement, priority}])[{concern, affected_epics, strategy}])plan_analyses table.For each detected technology in the stack:
references/MACRO-QUESTIONS.md).plan_analyses.decisions array with each answered question.This phase can be skipped with --skip-analysis flag.
After analysis and macro questions:
must → MS-001 (MVP / Core), phase_order: 1should → MS-002 (Enhancement), phase_order: 2could → MS-003 (Nice-to-have), phase_order: 3wont → no milestone (tasks get status: draft)phase_order and optional target_date.plan_analyses.milestone_ids with created milestone IDs.Level-by-level expansion with enhancements:
These are broad, high-level units of work.
For each top-level task:
For each Level 2 subtask:
You MUST continue expanding level-by-level until:
Every task generated in Phase 5 MUST include:
acceptance_criteria — JSON array of what "done" means (product view)moscow — must / should / could / wont classificationbusiness_value — 1-5 scalemilestone_id — inherited from epic unless overriddendependency_types — JSON object classifying each dependency as hard/soft/informationalcomplexity_expansion_prompt — guidance for how to break the task down later (set for M/L/XL tasks, NULL for XS/S). Post-Planning Expansion reads this field (see below).If Phase 2 identified cross-cutting concerns, generate a dedicated epic with subtasks for each concern (security, error handling, monitoring, logging, etc.). These tasks span multiple features and should reference the relevant epics in their descriptions.
tasks table..taskmanager/logs/activity.log.After inserting tasks and showing the summary, automatically expand all eligible tasks:
--no-expand flag is set, or auto_expand_after_plan is false in config.complexity_threshold_for_expansion (default: "M") and max_subtask_depth (default: 3).This eliminates the need to manually run --expand-all after planning. Use --no-expand to opt out.
Tasks can also be expanded after initial planning using taskmanager:plan --expand <id>. When generating subtasks for expansion:
complexity_expansion_prompt if the task has one. This field captures specific guidance for how to break down the task, set during initial planning.description, details, and test_strategy.test_strategy for each subtask: Every subtask must have a clear verification approach.You MAY update the state table:
current_task_id: NULLsession_id: set at command start, clear at endtasks table countslast_update timestamp and log decisions to activity.logUse AskUserQuestion when:
You can be asked to:
All of these rely on the tasks and state tables in .taskmanager/taskmanager.db.
A task is considered "available" if:
status is NOT one of: 'done', 'canceled', 'duplicate'.archived_at IS NULL).tasks table, or'done', 'canceled', 'duplicate'.Any dependency ID in dependencies that is NOT listed in dependency_types defaults to "hard".
When milestones exist, the next-task query prefers tasks from the active milestone. The behavior is selected by the execution_mode config value (see §8.1), each implemented by a dedicated view:
execution_mode='flexible'): Prefer active milestone tasks, fall back to any available task. Implemented by the v_next_task view.execution_mode='sequential'): Only return tasks from the active (or first planned) milestone. Implemented by the v_next_task_sequential view.The canonical next-available-task selection lives in these two views (defined in schemas/schema.sql), which encapsulate the availability rules and ordering above so they are not copy-pasted across files. Query the view matching the configured execution_mode:
-- flexible mode (default)
SELECT * FROM v_next_task LIMIT 1;
-- sequential mode
SELECT * FROM v_next_task_sequential LIMIT 1;
Both views enforce all the availability rules in this section: they return only leaf tasks (no children) that are not archived, not in 'done'/'canceled'/'duplicate'/'blocked'/'needs-review'/'paused'/'draft', and whose hard dependencies are all terminal (soft/informational do not block). v_next_task orders by active-milestone preference, then priority, then business_value (desc), then complexity_scale, then id; v_next_task_sequential is strictly gated to the active/first-planned milestone and drops the milestone-preference ordering (since all rows share one milestone). Use LIMIT N to fetch more than one candidate.
Use the configured mode's view for:
When beginning work on a leaf task:
status is 'planned', 'draft', 'blocked', 'paused', or 'needs-review':
'in-progress'.When finishing work on a leaf task:
status to 'done' only after the task passes verification (see 8.2.1). A task cannot move to 'done' until every acceptance criterion is verified.status to 'blocked' and update any dependency-related notes/metadata.status to 'canceled'.After updating a leaf task's status, you MUST:
doneA leaf task is not done just because the implementation "looks" finished. Before a leaf task may be set to 'done', its acceptance_criteria MUST be verified:
taskmanager:verify command (or the run completion gate, which calls the same logic). Verification executes the task's test_strategy, captures real output, and always dispatches the independent, refute-first taskmanager-verifier agent (see agents/verifier.md) to adversarially confirm each criterion.verifications table; v_task_verification rolls them up into total_criteria, met, failed, pending, and is_verified.met or overridden (is_verified = 1) → the task is verified and eligible for 'done'.failed → set the task to 'needs-review' (NOT 'done') and surface the failing criteria with the verifier's reasoning. The work returns to 'in-progress' once fixed, then is re-verified.taskmanager:verify <id> --override <idx> "reason", which records status='overridden' (counts as satisfied) and logs the reason. This is the only path to 'done' past a failed criterion.A task whose acceptance_criteria is empty ('[]') has nothing to verify; v_task_verification returns 0 rows for it, so it is never marked verified by SQL alone.
At the start of executing a task:
UPDATE state SET
current_task_id = :task_id,
last_update = datetime('now')
WHERE id = 1;
At the end of executing a task:
UPDATE state SET
current_task_id = NULL,
last_update = datetime('now')
WHERE id = 1;
Log the decision to activity.log for audit trail.
When asked to execute a specific task by ID:
dependencies refer to tasks that are not "done", "canceled", or "duplicate":
Whenever this skill (or any command calling it) changes the status of any task, you MUST enforce the parent/child macro-status rules:
tasks table is a parent task and its status is always derived from its direct children.Recursive CTE Status Propagation:
After updating a leaf task's status, use this recursive CTE to propagate status to all ancestors:
-- After updating a leaf task's status, propagate to ancestors
WITH RECURSIVE ancestors AS (
-- Start with the parent of the updated task
SELECT parent_id as id FROM tasks WHERE id = :task_id AND parent_id IS NOT NULL
UNION ALL
-- Recursively get all ancestors
SELECT t.parent_id FROM tasks t JOIN ancestors a ON t.id = a.id WHERE t.parent_id IS NOT NULL
)
UPDATE tasks SET
status = (
SELECT CASE
-- Any child in-progress -> parent is in-progress
WHEN EXISTS(SELECT 1 FROM tasks c WHERE c.parent_id = tasks.id AND c.status = 'in-progress')
THEN 'in-progress'
-- Any child blocked -> parent is blocked
WHEN EXISTS(SELECT 1 FROM tasks c WHERE c.parent_id = tasks.id AND c.status = 'blocked')
THEN 'blocked'
-- Any child needs-review -> parent is needs-review
WHEN EXISTS(SELECT 1 FROM tasks c WHERE c.parent_id = tasks.id AND c.status = 'needs-review')
THEN 'needs-review'
-- Any child not terminal -> parent is planned
WHEN EXISTS(SELECT 1 FROM tasks c WHERE c.parent_id = tasks.id AND c.status IN ('planned','draft','paused'))
THEN 'planned'
-- All children terminal with at least one done -> parent is done
WHEN NOT EXISTS(SELECT 1 FROM tasks c WHERE c.parent_id = tasks.id AND c.status NOT IN ('done','canceled','duplicate'))
THEN 'done'
-- All children canceled/duplicate -> parent is canceled
ELSE 'canceled'
END
),
updated_at = datetime('now')
WHERE id IN (SELECT id FROM ancestors);
This guarantees:
'in-progress'.'blocked'.'done' or 'canceled' as a macro view of the subtree.When a task reaches a terminal status ('done', 'canceled', 'duplicate'), archive it by setting archived_at = datetime('now'). For parents, archive only when ALL children are archived. Cascade archival to ancestors when all their children are archived. See the agent spec (agents/taskmanager.md, section 2.6) for details.
Deferrals are tracked in the deferrals table. They represent work explicitly deferred from one task to another.
Before executing a task, load all pending deferrals targeting it:
SELECT d.id, d.title, d.body, d.reason, d.source_task_id,
t.title as source_title
FROM deferrals d
LEFT JOIN tasks t ON t.id = d.source_task_id
WHERE d.target_task_id = '<task-id>' AND d.status = 'pending'
ORDER BY d.created_at;
Display these as requirements the agent must address. They are not optional.
Treat deferred work as additional scope for the current task. When implementing, ensure all pending deferrals are addressed.
After completing task work:
applied if the work was donereassign to another task if still neededcancel if no longer relevantWhen tasks are moved/re-IDed, update deferral references:
UPDATE deferrals SET source_task_id = '<new-id>', updated_at = datetime('now')
WHERE source_task_id = '<old-id>';
UPDATE deferrals SET target_task_id = '<new-id>', updated_at = datetime('now')
WHERE target_task_id = '<old-id>';
Memory integration during task execution is handled by the run command. Key principles:
importance >= 3) and task-scoped memories. Display summary.use_count and last_used_at for applied memories.The run command supports:
--memory "description" (or -gm): Creates a global memory in the memories table.--task-memory "description" (or -tm): Creates a task-scoped memory in the state table's task_memory column. Reviewed for promotion at task completion.See run.md for the full workflow.
All logging goes to a single file: .taskmanager/logs/activity.log.
<timestamp> [<level>] [<command>] <message>
Levels: ERROR, DECISION. Logs are append-only.
Key state columns for session tracking: session_id in the state table.
During Phase 2 of planning, the AI performs a structured analysis of the PRD:
Scan the PRD content and codebase for technology indicators:
composer.json, package.json, requirements.txt, Gemfile, etc.artisan, next.config.js, nuxt.config.ts)Store detected stack as JSON array in plan_analyses.tech_stack.
For each requirement in the PRD, assess:
Detected ambiguities feed into Phase 3 (Macro Architectural Questions).
Decisions from Phase 3 are stored in two places:
plan_analyses.decisions — JSON array: [{question, answer, rationale, memory_id}]memories table — Each decision becomes a memory with:
kind: as specified in the Macro Question Bankimportance: as specified in the Macro Question Banksource_type: 'user'source_via: 'taskmanager:plan:macro-questions'confidence: 1.0auto_updatable: 0During Phase 2, identify concerns that span multiple features:
For each cross-cutting concern identified, generate a subtask under a dedicated "Cross-Cutting Concerns" epic. Each subtask should:
moscow = 'must' or 'should' (concerns are rarely optional)business_value based on impactacceptance_criteria specific to the concern| MoSCoW | Milestone | phase_order | Description |
|---|---|---|---|
must | MS-001 | 1 | MVP / Core — required for launch |
should | MS-002 | 2 | Enhancement — important, post-MVP |
could | MS-003 | 3 | Nice-to-have — if time permits |
wont | (none) | — | Backlog — tasks created with status draft |
milestone_id from their parent unless explicitly overriddencould subtask under a must epic)Milestone status is derived from its scoped tasks (plus milestone-level verification), not set independently:
planned — default, no tasks startedactive — at least one scoped task is in-progresscompleted — all scoped tasks are terminal (done, canceled, duplicate) and the milestone passes taskmanager:verify --milestone <id> against its acceptance_criteriacanceled — explicitly canceled by userThe v_milestone_status view (defined in schemas/schema.sql) backs display: for each milestone it reports total_tasks, terminal_tasks, and a derived_status (active if any scoped task is in-progress, completed if all scoped tasks are terminal and there is at least one, else planned). derived_status is for display only and does NOT mutate milestones.status — a milestone is only promoted to completed when all tasks are terminal AND milestone verification passes (see 8.2.1 and commands/verify.md).
npx claudepluginhub mwguerra/plugins --plugin taskmanagerCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.