{"owner":"eyaltoledano","repo":"claude-task-master","hasSkills":true,"totalSkillsCount":41,"totalTokensCount":130026,"categories":["marketplace","command-prompt","mcp-config","cursor-rule","claude-rule","root-instruction","plugin-manifest","anthropic-skill"],"hasMcp":true,"mcpConfig":{"mcpServers":{"task-master-ai":{"command":"node","args":["./dist/mcp-server.js"],"env":{"ANTHROPIC_API_KEY":"ANTHROPIC_API_KEY_HERE","PERPLEXITY_API_KEY":"PERPLEXITY_API_KEY_HERE","OPENAI_API_KEY":"OPENAI_API_KEY_HERE","GOOGLE_API_KEY":"GOOGLE_API_KEY_HERE","GROQ_API_KEY":"GROQ_API_KEY_HERE","XAI_API_KEY":"XAI_API_KEY_HERE","OPENROUTER_API_KEY":"OPENROUTER_API_KEY_HERE","MISTRAL_API_KEY":"MISTRAL_API_KEY_HERE","AZURE_OPENAI_API_KEY":"AZURE_OPENAI_API_KEY_HERE","OLLAMA_API_KEY":"OLLAMA_API_KEY_HERE","GITHUB_API_KEY":"GITHUB_API_KEY_HERE"}}}},"found":[".claude-plugin/marketplace.json",".claude/commands/dedupe.md",".claude/commands/go/ham.md",".claude/commands/go/pr-comments.md",".cursor/commands/goham.md",".cursor/mcp.json",".cursor/rules/ai_providers.mdc",".cursor/rules/ai_services.mdc",".cursor/rules/architecture.mdc",".cursor/rules/changeset.mdc",".cursor/rules/commands.mdc",".cursor/rules/context_gathering.mdc",".cursor/rules/cursor_rules.mdc",".cursor/rules/dependencies.mdc",".cursor/rules/dev_workflow.mdc",".cursor/rules/git_workflow.mdc",".cursor/rules/glossary.mdc",".cursor/rules/hamster.mdc",".cursor/rules/mcp.mdc",".cursor/rules/new_features.mdc",".cursor/rules/self_improve.mdc",".cursor/rules/tags.mdc",".cursor/rules/taskmaster.mdc",".cursor/rules/taskmaster/dev_workflow.mdc",".cursor/rules/taskmaster/taskmaster.mdc",".cursor/rules/tasks.mdc",".cursor/rules/telemetry.mdc",".cursor/rules/test_workflow.mdc",".cursor/rules/tests.mdc",".cursor/rules/ui.mdc",".cursor/rules/utilities.mdc",".taskmaster/CLAUDE.md","CLAUDE.md","assets/AGENTS.md","packages/ai-sdk-provider-grok-cli/README.md","packages/claude-code-plugin/.claude-plugin/plugin.json","packages/claude-code-plugin/commands/sync-readme.md","packages/tm-bridge/README.md","packages/tm-core/README.md","packages/tm-core/docs/listTasks-architecture.md","tests/unit/scripts/modules/commands/README.md"],"skills":{".claude-plugin/marketplace.json":"{\n\t\"name\": \"taskmaster\",\n\t\"owner\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"email\": \"ralph@tryhamster.com\"\n\t},\n\t\"metadata\": {\n\t\t\"description\": \"Official marketplace for Taskmaster AI - AI-powered task management for ambitious development\",\n\t\t\"version\": \"1.0.0\"\n\t},\n\t\"plugins\": [\n\t\t{\n\t\t\t\"name\": \"taskmaster\",\n\t\t\t\"source\": \"./packages/claude-code-plugin\",\n\t\t\t\"description\": \"AI-powered task management system for ambitious development workflows with intelligent orchestration, complexity analysis, and automated coordination\",\n\t\t\t\"author\": {\n\t\t\t\t\"name\": \"Hamster\"\n\t\t\t},\n\t\t\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"keywords\": [\n\t\t\t\t\"task-management\",\n\t\t\t\t\"ai\",\n\t\t\t\t\"workflow\",\n\t\t\t\t\"orchestration\",\n\t\t\t\t\"automation\",\n\t\t\t\t\"mcp\"\n\t\t\t],\n\t\t\t\"category\": \"productivity\"\n\t\t}\n\t]\n}\n",".claude/commands/dedupe.md":"---\nallowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)\ndescription: Find duplicate GitHub issues\n---\n\nFind up to 3 likely duplicate issues for a given GitHub issue.\n\nTo do this, follow these steps precisely:\n\n1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.\n2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue\n3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1\n4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.\n5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)\n\nNotes (be sure to tell this to your agents, too):\n\n- Use `gh` to interact with Github, rather than web fetch\n- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)\n- Make a todo list first\n- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):\n\n---\n\nFound 3 possible duplicate issues:\n\n1. <link to issue>\n2. <link to issue>\n3. <link to issue>\n\nThis issue will be automatically closed as a duplicate in 3 days.\n\n- If your issue is a duplicate, please close it and 👍 the existing issue instead\n- To prevent auto-closure, add a comment or 👎 this comment\n\n🤖 Generated with \\[Task Master Bot\\]\n\n---",".claude/commands/go/ham.md":"# Hamster (Go ham!) Run Task Workflow\n\nThis command initiates the HAM (Hamster Automated Management) workflow for task execution.\n\n## Usage\n\n```\n/go:ham [task-id]\n```\n\n- `task-id` (optional): Specific task identifier to work on (e.g., \"1\", \"1.2\", \"2.3.1\")\n  - If provided, start working on that specific task immediately\n  - If omitted, automatically identify the next available task\n\n## Process\n\nWhen the user invokes this command, follow these steps:\n\n### 1. Task Selection\n\n#### If task-id is provided ($ARGUMENTS is not empty):\n```bash\ntm show $ARGUMENTS\n```\nStart working on the specified task immediately, skipping to step 3.\n\n#### If no task-id is provided ($ARGUMENTS is empty):\n```bash\ntm list\n```\nDisplay all tasks with their current status to provide context.\n\n### 2. Identify Next Task (only if no task-id provided)\nDetermine which task should be worked on next based on:\n- Dependencies\n- Priority\n- Current status (pending tasks only)\n\n### 3. Show Task Details (only if task wasn't specified in step 1)\n```bash\ntm show <task-id>\n```\nDisplay the full details of the identified task including:\n- Title and description\n- Dependencies\n- Test strategy\n- Subtasks (if any)\n\n### 4. Kickoff Workflow\n\nBased on the task type, follow the appropriate workflow:\n\n#### For Main Tasks (e.g., \"1\", \"2\", \"3\")\n- Review the task's subtasks\n- If no subtasks exist, suggest expanding the task first\n- Identify the first pending subtask\n- Begin implementation following the subtask's requirements\n\n#### For Subtasks (e.g., \"1.1\", \"2.3\")\n- Mark the subtask as in-progress:\n  ```bash\n  tm set-status --id=<subtask-id> --status=in-progress\n  ```\n- Review the task details and requirements\n- Check for related code files or dependencies\n- Create an implementation plan\n- Begin implementation following project conventions\n\n### 5. Implementation Guidelines\n\nFollow these principles during implementation:\n\n1. **Understand First**: Read related files and understand the current architecture\n2. **Plan**: Create a mental model or brief plan before coding\n3. **Follow Conventions**: Adhere to project structure and coding standards\n4. **Test As You Go**: Validate changes incrementally\n5. **Stay Focused**: Complete the current subtask before moving to the next\n\n### 6. Task Completion\n\nWhen the subtask is complete:\n```bash\ntm set-status --id=<subtask-id> --status=done\n```\n\nThen automatically check for the next available task by repeating from step 2.\n\n## Example Flows\n\n### With Specific Task ID\n```\nUser: \"/go:ham 1.2\"\n\n1. Claude runs: tm show 1.2\n   → Displays full task details\n2. Claude analyzes the task and creates an implementation plan\n3. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n4. Claude begins implementation following the task requirements\n5. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n6. Claude automatically identifies next task with tm list\n```\n\n### Without Specific Task ID (Auto-discovery)\n```\nUser: \"/go:ham\"\n\n1. Claude runs: tm list\n2. Claude identifies next available task (e.g., 1.2)\n3. Claude runs: tm show 1.2\n   → Displays full task details\n4. Claude analyzes the task and creates an implementation plan\n5. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n6. Claude begins implementation following the task requirements\n7. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n8. Claude automatically identifies next task with tm list\n```\n\n## Notes\n\n- Always verify task dependencies are complete before starting\n- If a task is blocked, mark it as such and move to the next available task\n- Keep the user informed of progress at each major step\n- Ask for clarification if task requirements are unclear\n- Follow the project's CLAUDE.md and .cursor/rules/* guidelines at all times\n- Unlike the usual Taskmaster process, do not bother using update-task nor update-subtask as they do not work with Hamster tasks yet.\n\n- Use only `tm list`, `tm show <sub/task id>` and `tm set status` - other commands don't yet work with it.\n- Do not use the MCP tools when connected with Hamster briefs - that is not yet up to date.\n- Use `.cursor/rules/git_workflow.mdc` as a guide for the workflow\n- When starting a task, mark it as in-progress. You can mark multiple task statuses at once with comma separation (i.e. `tm set-status -i 1,1.1 -s in-progress`)\n- Read the task, then if it has subtasks, begin implementing the subtasks one at a time.\n- When the subtask is done, run lint and typecheck, mark the task as done if it passes, and commit.\n- Continue until all subtasks are done, then run a final lint and typecheck (`npm lint` and `npm typecheck`) and create a PR using `gh` cli for that Task.\n- Keep committing to the same PR as long as the scope is maintained. An entire task list (brief) might fit into a single PR but not if it ends up being huge. It is preferred for everything to land in one PR if it is possible, otherwise commit to different PRs that build on top of the previous ones. Confirm with the human when doing this.\n- When the parent task is completed, ensure you mark is as done.\n- When the first task is done, repeat this process for all tasks until all tasks are done.\n- If you run into an issue where the JWT seems expired or commands don't work, ensure you use `tm auth refresh` to refresh the token and if that does not work, use `tm context <brief url>` to reconnect the context. If you do not have the brief url, ask the user for it (perhaps use it at the beginning)\n\nYou're a fast hamster. Go go go.",".claude/commands/go/pr-comments.md":"Fix PR review comments: PR # $ARGUMENTS\n\nThis command collects all review comments from a GitHub PR (including CodeRabbit, human reviewers, and other bots), consolidates them by author and severity, shows them to you for approval, then implements the approved fixes.\n\nSteps:\n\n1. **Collect PR comments**\n   - Run: `gh pr view $ARGUMENTS --comments` to get ALL comments (no truncation)\n   - Parse and extract all review comments from:\n     - PR review comments (file-level)\n     - General comments\n     - Review threads\n   - Include author information for each comment\n   - IMPORTANT: Do NOT use `head`, `tail`, or any truncation - we need complete comment history\n\n2. **Consolidate comments**\n   - Group comments by:\n     - Author (CodeRabbit, human reviewers, other bots)\n     - Severity (🚨 Critical, ⚠️ Important, 💡 Suggestion, ℹ️ Info)\n     - Category (Security, Performance, Best Practices, Style, etc.)\n   - Remove duplicates and group similar issues\n   - Present in a clear, numbered list format showing author for each\n\n3. **Show consolidated issues for approval**\n   - Display the organized list with:\n     - Issue number for reference\n     - Severity indicator\n     - File location\n     - Description\n     - Suggested fix\n   - Ask: \"Which issues would you like me to fix? (Enter numbers separated by commas, or 'all' for everything)\"\n   - Wait for user confirmation\n\n4. **Implement approved fixes**\n   - For each approved issue:\n     - Read the relevant file(s)\n     - Implement the suggested fix\n     - Log what was changed\n\n5. **Validate changes**\n   - Run: `pnpm typecheck`\n   - If fails: review errors, fix them, retry\n   - Run: `pnpm lint`\n   - If fails: review errors, fix them, retry\n   - Continue until both pass\n\n6. **Commit and push**\n   - Stage changes: `git add .`\n   - Create commit: `git commit -m \"fix: address review comments from PR #$ARGUMENTS\"`\n   - Push: `git push`\n   - Confirm completion with summary of fixes applied\n\nNotes:\n- If no review comments found, inform user and exit\n- If typecheck/lint fails after fixes, show errors and ask for guidance\n- Keep fixes focused on reviewers' specific suggestions\n- Preserve existing code style and patterns\n- Group related fixes in the commit message if many changes\n- Treat all reviewers equally - human and bot feedback both matter\n\nYou previously got all the PR comments in a temporary JSON file and then ran something like this;\n\ncat > /tmp/parse_comments.js << 'EOF'\nconst fs = require('fs');\nconst comments = JSON.parse(fs.readFileSync('/tmp/all-pr-comments.json', 'utf8'));\n\nconst byFile = {};\nconst bySeverity = {\n  critical: [],\n  important: [],\n  suggestion: [],\n  info: []\n};\n\ncomments.forEach((c, idx) => {\n  const file = c.path;\n  const author = c.user.login;\n  const line = c.line || c.original_line || 'N/A';\n  const body = c.body;\n  \n  if (!byFile[file]) byFile[file] = [];\n  \n  const comment = {\n    num: idx + 1,\n    author,\n    line,\n    body: body.substring(0, 200) + (body.length > 200 ? '...' : ''),\n    fullBody: body\n  };\n  \n  byFile[file].push(comment);\n  \n  // Categorize by severity\n  const lower = body.toLowerCase();\n  if (lower.includes('critical') || lower.includes('security') || lower.includes('bug:')) {\n    bySeverity.critical.push({...comment, file});\n  } else if (lower.includes('important') || lower.includes('error') || lower.includes('fail')) {\n    bySeverity.important.push({...comment, file});\n  } else if (lower.includes('suggestion') || lower.includes('consider') || lower.includes('recommend')) {\n    bySeverity.suggestion.push({...comment, file});\n  } else {\n    bySeverity.info.push({...comment, file});\n  }\n});\n\nconsole.log('\\n=== SUMMARY BY SEVERITY ===\\n');\nconsole.log(`🚨 Critical: ${bySeverity.critical.length}`);\nconsole.log(`⚠️  Important: ${bySeverity.important.length}`);\nconsole.log(`💡 Suggestion: ${bySeverity.suggestion.length}`);\nconsole.log(`ℹ️  Info: ${bySeverity.info.length}`);\n\nconsole.log('\\n=== SUMMARY BY FILE ===\\n');\nObject.entries(byFile)\n  .sort((a, b) => b[1].length - a[1].length)\n  .forEach(([file, comments]) => {\n    console.log(`${file}: ${comments.length} comments`);\n  });\n\nconsole.log('\\n=== CRITICAL ISSUES ===\\n');\nbySeverity.critical.forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\n\nconsole.log('\\n=== IMPORTANT ISSUES ===\\n');\nbySeverity.important.slice(0, 10).forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\nEOF\nnode /tmp/parse_comments.js\n\nAnd got a nice report you could act on.",".cursor/commands/goham.md":"# Start Working with Hamster Brief\n\nEnd-to-end workflow for working on tasks from a connected Hamster brief. All tasks from the brief are worked on in a single branch, with one PR created at the end.\n\n## Step 1: Verify Connection & Authentication\n\n```bash\n# Check current context and authentication status\ntm context\n```\n\nIf not connected or authentication fails:\n- Get brief URL from user if not available\n- Connect: `tm context <brief url>`\n- Refresh token if needed: `tm auth refresh`\n\n## Step 2: List Available Tasks\n\n```bash\n# View all tasks from the brief\ntm list\n```\n\nReview the task list to understand what needs to be done. Note the total number of tasks.\n\n## Step 3: Initialize Git Branch for Brief\n\n```bash\n# Ensure you're on dev branch and pull latest\ngit checkout dev\ngit pull origin dev\n\n# Create a single branch for the entire brief (e.g., hamster-brief-YYYY-MM-DD or brief-specific name)\ngit checkout -b hamster-brief\n\n# Verify branch creation\ngit branch\n```\n\n**Note**: This branch will be used for ALL tasks in the brief. Do not create separate branches per task.\n\n## Step 4: Task Loop (Repeat for Each Task)\n\nWork through all tasks sequentially in the same branch:\n\n### 4.1: Read Task Details\n\n```bash\n# Get detailed information about the task\ntm show 1\n\n# If task has subtasks, examine them all\ntm show 1,1.1,1.2,1.3  # Adjust IDs as needed\n```\n\n### 4.2: Log Initial Context\n\n```bash\n# Document task understanding and initial findings\ntm update-task -i 1 --append --prompt=\"Starting task implementation.\n\nInitial context:\n- Task requirements: [summarize key requirements]\n- Dependencies identified: [list any dependencies]\n- Files that may need modification: [list relevant files]\n- Approach planned: [brief implementation approach]\"\n```\n\n### 4.3: Mark Task as In-Progress\n\n```bash\n# Mark task and first subtask (if exists) as in-progress\ntm set-status -i 1,1.1 -s in-progress\n```\n\n### 4.4: Subtask Implementation Loop\n\nFor each subtask (1.1, 1.2, 1.3, etc.):\n\n#### 4.4.1: Read Subtask Details\n```bash\ntm show 1.1  # Replace with current subtask ID\n```\n\n#### 4.4.2: Log Research & Context Gathering\n```bash\n# Document findings during implementation\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Context gathered:\n\n- Code exploration findings: [what you discovered]\n- Implementation approach: [how you plan to implement]\n- Key decisions made: [important choices]\n- Challenges encountered: [any blockers or issues]\"\n```\n\n#### 4.4.3: Implement Subtask\n- Write code following the subtask requirements\n- Make necessary changes to files\n\n#### 4.4.4: Quality Verification\n```bash\n# Run linting\npnpm lint\n\n# Run type checking\npnpm typecheck\n\n# If either fails, fix issues and re-run until both pass\n```\n\n#### 4.4.5: CodeRabbit Review\n```bash\n# Generate code review (wait for plain text results)\ncoderabbit --prompt-only\n\n# Review the output and address any critical issues if needed\n```\n\n#### 4.4.6: Log Implementation Completion\n```bash\n# Document what was completed\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Implementation complete:\n\n- Files modified: [list files changed]\n- Key changes: [summary of implementation]\n- CodeRabbit feedback addressed: [if any issues were fixed]\n- Ready for commit\"\n```\n\n#### 4.4.7: Commit Subtask Work\n```bash\n# Stage changes\ngit add .\n\n# Commit with detailed message following git_workflow.mdc format\ngit commit -m \"feat(task-1): Complete subtask 1.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Files modified: [list files]\n- CodeRabbit review completed\n\nSubtask 1.1: [Brief description of what was accomplished]\nRelates to Task 1: [Main task title]\"\n```\n\n#### 4.4.8: Mark Subtask as Done\n```bash\ntm set-status -i 1.1 -s done\n```\n\n#### 4.4.9: Move to Next Subtask\nRepeat steps 4.4.1 through 4.4.8 for the next subtask (1.2, 1.3, etc.)\n\n### 4.5: Complete Parent Task\n\nAfter all subtasks are complete:\n\n#### 4.5.1: Final Quality Checks\n```bash\n# Final linting\npnpm lint\n\n# Final type checking\npnpm typecheck\n\n# Final CodeRabbit review\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n#### 4.5.2: Log Task Completion\n```bash\n# Document final task completion\ntm update-task -i 1 --append --prompt=\"Task 1 - Complete:\n\n- All subtasks completed: [list all subtasks]\n- Final verification passed: lint, typecheck, CodeRabbit review\n- Files changed: [comprehensive list]\n- Committed to brief branch\"\n```\n\n#### 4.5.3: Mark Parent Task as Done\n```bash\ntm set-status -i 1 -s done\n```\n\n**Note**: Do NOT push or create PR yet. Continue to next task in the same branch.\n\n### 4.6: Move to Next Task\n\n```bash\n# Verify remaining tasks\ntm list\n\n# Continue with next task (e.g., Task 2)\n# Repeat steps 4.1 through 4.5 for Task 2, then Task 3, etc.\n```\n\n## Step 5: Complete All Tasks\n\nContinue working through all tasks (Steps 4.1-4.6) until all tasks in the brief are complete. All work is committed to the same `hamster-brief` branch.\n\n## Step 6: Final Verification & PR Creation\n\nAfter ALL tasks are complete:\n\n### 6.1: Verify All Tasks Complete\n```bash\n# Verify all tasks are done\ntm list\n\n# Should show all tasks with status 'done'\n```\n\n### 6.2: Final Quality Checks\n```bash\n# Final comprehensive checks\npnpm lint\npnpm typecheck\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n### 6.3: Push Branch\n```bash\n# Push the brief branch to remote\ngit push origin hamster-brief\n```\n\n### 6.4: Create Pull Request to Dev\n```bash\n# Get all task titles (adjust task IDs as needed)\n# Create comprehensive PR description\n\ngh pr create \\\n  --base dev \\\n  --title \"Hamster Brief: Complete Implementation\" \\\n  --body \"## Brief Overview\nCompleted all tasks from Hamster brief.\n\n## Tasks Completed\n- [x] Task 1: [Task 1 title]\n  - Subtasks: 1.1, 1.2, 1.3\n- [x] Task 2: [Task 2 title]\n  - Subtasks: 2.1, 2.2\n- [x] Task 3: [Task 3 title]\n  - [Continue listing all tasks]\n\n## Implementation Summary\n- Total tasks: [number]\n- Total subtasks: [number]\n- Files modified: [comprehensive list]\n- All quality checks passed\n\n## Quality Checks\n- ✅ Linting passed (pnpm lint)\n- ✅ Type checking passed (pnpm typecheck)\n- ✅ CodeRabbit review completed for all changes\n\n## Testing\n- [ ] Manual testing completed\n- [ ] All checks passing\n\nComplete implementation of Hamster brief tasks\"\n```\n\n## Step 7: Cleanup\n\n```bash\n# After PR is merged, switch back to dev\ngit checkout dev\ngit pull origin dev\n\n# Delete local branch (optional)\ngit branch -d hamster-brief\n```\n\n## Important Notes\n\n- **Use ONLY**: `tm list`, `tm show <id>`, `tm set-status`, `tm update-task`, `tm auth refresh`, `tm context <brief url>`\n- **DON'T use MCP tools** - not compatible with Hamster integration\n- **Single branch per brief**: All tasks work in the same branch (`hamster-brief`)\n- **Single PR per brief**: One PR created after all tasks are complete\n- **Always target dev branch** - never main branch\n- **Regular logging**: Use `tm update-task -i <id> --append` frequently to document:\n  - Context gathered during exploration\n  - Implementation decisions made\n  - Challenges encountered\n  - Completion status\n- **Quality gates**: Never skip lint, typecheck, or CodeRabbit review\n- **Commit format**: Follow git_workflow.mdc commit message standards\n- **PR format**: Always use `--base dev` when creating PRs\n\n## Workflow Summary\n\n```\n1. Verify connection → tm context\n2. List tasks → tm list\n3. Create single branch → git checkout -b hamster-brief\n4. For each task (in same branch):\n   a. Read task → tm show X\n   b. Log context → tm update-task -i X --append\n   c. Mark in-progress → tm set-status -i X,X.Y -s in-progress\n   d. For each subtask:\n      - Read → tm show X.Y\n      - Log context → tm update-task -i X --append\n      - Implement code\n      - Verify → pnpm lint && pnpm typecheck\n      - Review → coderabbit --prompt-only\n      - Log completion → tm update-task -i X --append\n      - Commit → git commit (following git_workflow.mdc format)\n      - Mark done → tm set-status -i X.Y -s done\n   e. Final checks → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   f. Log completion → tm update-task -i X --append\n   g. Mark task done → tm set-status -i X -s done\n   h. Continue to next task (same branch)\n5. After ALL tasks complete:\n   a. Final verification → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   b. Push branch → git push origin hamster-brief\n   c. Create PR → gh pr create --base dev\n```\n\n## References\n\n- Full guidelines: [hamster.mdc](mdc:.cursor/rules/hamster.mdc)\n- Git workflow: [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc)\n",".cursor/mcp.json":"{\n\t\"mcpServers\": {\n\t\t\"task-master-ai\": {\n\t\t\t\"command\": \"node\",\n\t\t\t\"args\": [\"./dist/mcp-server.js\"],\n\t\t\t\"env\": {\n\t\t\t\t\"ANTHROPIC_API_KEY\": \"ANTHROPIC_API_KEY_HERE\",\n\t\t\t\t\"PERPLEXITY_API_KEY\": \"PERPLEXITY_API_KEY_HERE\",\n\t\t\t\t\"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n\t\t\t\t\"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n\t\t\t\t\"GROQ_API_KEY\": \"GROQ_API_KEY_HERE\",\n\t\t\t\t\"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n\t\t\t\t\"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n\t\t\t\t\"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n\t\t\t\t\"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n\t\t\t\t\"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\",\n\t\t\t\t\"GITHUB_API_KEY\": \"GITHUB_API_KEY_HERE\"\n\t\t\t}\n\t\t}\n\t}\n}\n",".cursor/rules/ai_providers.mdc":"---\ndescription: Guidelines for managing Task Master AI providers and models.\nglobs: \nalwaysApply: false\n---\n# Task Master AI Provider Management\n\nThis rule guides AI assistants on how to view, configure, and interact with the different AI providers and models supported by Task Master. For internal implementation details of the service layer, see [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc).\n\n-   **Primary Interaction:**\n    -   Use the `models` MCP tool or the `task-master models` CLI command to manage AI configurations. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for detailed command/tool usage.\n\n-   **Configuration Roles:**\n    -   Task Master uses three roles for AI models:\n        -   `main`: Primary model for general tasks (generation, updates).\n        -   `research`: Model used when the `--research` flag or `research: true` parameter is used (typically models with web access or specialized knowledge).\n        -   `fallback`: Model used if the primary (`main`) model fails.\n    -   Each role is configured with a specific `provider:modelId` pair (e.g., `openai:gpt-4o`).\n\n-   **Viewing Configuration & Available Models:**\n    -   To see the current model assignments for each role and list all models available for assignment:\n        -   **MCP Tool:** `models` (call with no arguments or `listAvailableModels: true`)\n        -   **CLI Command:** `task-master models`\n    -   The output will show currently assigned models and a list of others, prefixed with their provider (e.g., `google:gemini-2.5-pro-exp-03-25`).\n\n-   **Setting Models for Roles:**\n    -   To assign a model to a role:\n        -   **MCP Tool:** `models` with `setMain`, `setResearch`, or `setFallback` parameters.\n        -   **CLI Command:** `task-master models` with `--set-main`, `--set-research`, or `--set-fallback` flags.\n    -   **Crucially:** When providing the model ID to *set*, **DO NOT include the `provider:` prefix**. Use only the model ID itself.\n        -   ✅ **DO:** `models(setMain='gpt-4o')` or `task-master models --set-main=gpt-4o`\n        -   ❌ **DON'T:** `models(setMain='openai:gpt-4o')` or `task-master models --set-main=openai:gpt-4o`\n    -   The tool/command will automatically determine the provider based on the model ID.\n\n-   **Setting Custom Models (Ollama/OpenRouter):**\n    -   To set a model ID not in the internal list for Ollama or OpenRouter:\n        -   **MCP Tool:** Use `models` with `set<Role>` and **also** `ollama: true` or `openrouter: true`.\n            -   Example: `models(setMain='my-custom-ollama-model', ollama=true)`\n            -   Example: `models(setMain='some-openrouter-model', openrouter=true)`\n        -   **CLI Command:** Use `task-master models` with `--set-<role>` and **also** `--ollama` or `--openrouter`.\n            -   Example: `task-master models --set-main=my-custom-ollama-model --ollama`\n            -   Example: `task-master models --set-main=some-openrouter-model --openrouter`\n        -   **Interactive Setup:** Use `task-master models --setup` and select the `Ollama (Enter Custom ID)` or `OpenRouter (Enter Custom ID)` options.\n    -   **OpenRouter Validation:** When setting a custom OpenRouter model, Taskmaster attempts to validate the ID against the live OpenRouter API.\n    -   **Ollama:** No live validation occurs for custom Ollama models; ensure the model is available on your Ollama server.\n\n-   **Supported Providers & Required API Keys:**\n    -   Task Master integrates with various providers via the Vercel AI SDK.\n    -   **API keys are essential** for most providers and must be configured correctly.\n    -   **Key Locations** (See [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) - Configuration Management):\n        -   **MCP/Cursor:** Set keys in the `env` section of `.cursor/mcp.json`.\n        -   **CLI:** Set keys in a `.env` file in the project root.\n    -   **Provider List & Keys:**\n        -   **`anthropic`**: Requires `ANTHROPIC_API_KEY`.\n        -   **`google`**: Requires `GOOGLE_API_KEY`.\n        -   **`openai`**: Requires `OPENAI_API_KEY`.\n        -   **`perplexity`**: Requires `PERPLEXITY_API_KEY`.\n        -   **`xai`**: Requires `XAI_API_KEY`.\n        -   **`mistral`**: Requires `MISTRAL_API_KEY`.\n        -   **`azure`**: Requires `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT`.\n        -   **`openrouter`**: Requires `OPENROUTER_API_KEY`.\n        -   **`ollama`**: Might require `OLLAMA_API_KEY` (not currently supported) *and* `OLLAMA_BASE_URL` (default: `http://localhost:11434/api`). *Check specific setup.*\n\n-   **Troubleshooting:**\n    -   If AI commands fail (especially in MCP context):\n        1.  **Verify API Key:** Ensure the correct API key for the *selected provider* (check `models` output) exists in the appropriate location (`.cursor/mcp.json` env or `.env`).\n        2.  **Check Model ID:** Ensure the model ID set for the role is valid (use `models` listAvailableModels/`task-master models`).\n        3.  **Provider Status:** Check the status of the external AI provider's service.\n        4.  **Restart MCP:** If changes were made to configuration or provider code, restart the MCP server.\n\n## Adding a New AI Provider (Vercel AI SDK Method)\n\nFollow these steps to integrate a new AI provider that has an official Vercel AI SDK adapter (`@ai-sdk/<provider>`):\n\n1.  **Install Dependency:**\n    -   Install the provider-specific package:\n        ```bash\n        npm install @ai-sdk/<provider-name>\n        ```\n\n2.  **Create Provider Module:**\n    -   Create a new file in `src/ai-providers/` named `<provider-name>.js`.\n    -   Use existing modules (`openai.js`, `anthropic.js`, etc.) as a template.\n    -   **Import:**\n        -   Import the provider's `create<ProviderName>` function from `@ai-sdk/<provider-name>`.\n        -   Import `generateText`, `streamText`, `generateObject` from the core `ai` package.\n        -   Import the `log` utility from `../../scripts/modules/utils.js`.\n    -   **Implement Core Functions:**\n        -   `generate<ProviderName>Text(params)`:\n            -   Accepts `params` (apiKey, modelId, messages, etc.).\n            -   Instantiate the client: `const client = create<ProviderName>({ apiKey });`\n            -   Call `generateText({ model: client(modelId), ... })`.\n            -   Return `result.text`.\n            -   Include basic validation and try/catch error handling.\n        -   `stream<ProviderName>Text(params)`:\n            -   Similar structure to `generateText`.\n            -   Call `streamText({ model: client(modelId), ... })`.\n            -   Return the full stream result object.\n            -   Include basic validation and try/catch.\n        -   `generate<ProviderName>Object(params)`:\n            -   Similar structure.\n            -   Call `generateObject({ model: client(modelId), schema, messages, ... })`.\n            -   Return `result.object`.\n            -   Include basic validation and try/catch.\n    -   **Export Functions:** Export the three implemented functions (`generate<ProviderName>Text`, `stream<ProviderName>Text`, `generate<ProviderName>Object`).\n\n3.  **Integrate with Unified Service:**\n    -   Open `scripts/modules/ai-services-unified.js`.\n    -   **Import:** Add `import * as <providerName> from '../../src/ai-providers/<provider-name>.js';`\n    -   **Map:** Add an entry to the `PROVIDER_FUNCTIONS` map:\n        ```javascript\n        '<provider-name>': {\n            generateText: <providerName>.generate<ProviderName>Text,\n            streamText: <providerName>.stream<ProviderName>Text,\n            generateObject: <providerName>.generate<ProviderName>Object\n        },\n        ```\n\n4.  **Update Configuration Management:**\n    -   Open `scripts/modules/config-manager.js`.\n    -   **`MODEL_MAP`:** Add the new `<provider-name>` key to the `MODEL_MAP` loaded from `supported-models.json` (or ensure the loading handles new providers dynamically if `supported-models.json` is updated first).\n    -   **`VALID_PROVIDERS`:** Ensure the new `<provider-name>` is included in the `VALID_PROVIDERS` array (this should happen automatically if derived from `MODEL_MAP` keys).\n    -   **API Key Handling:**\n        -   Update the `keyMap` in `_resolveApiKey` and `isApiKeySet` with the correct environment variable name (e.g., `PROVIDER_API_KEY`).\n        -   Update the `switch` statement in `getMcpApiKeyStatus` to check the corresponding key in `mcp.json` and its placeholder value.\n        -   Add a case to the `switch` statement in `getMcpApiKeyStatus` for the new provider, including its placeholder string if applicable.\n    -   **Ollama Exception:** If adding Ollama or another provider *not* requiring an API key, add a specific check at the beginning of `isApiKeySet` and `getMcpApiKeyStatus` to return `true` immediately for that provider.\n\n5.  **Update Supported Models List:**\n    -   Edit `scripts/modules/supported-models.json`.\n    -   Add a new key for the `<provider-name>`.\n    -   Add an array of model objects under the provider key, each including:\n        -   `id`: The specific model identifier (e.g., `claude-3-opus-20240229`).\n        -   `name`: A user-friendly name (optional).\n        -   `swe_score`, `cost_per_1m_tokens`: (Optional) Add performance/cost data if available.\n        -   `allowed_roles`: An array of roles (`\"main\"`, `\"research\"`, `\"fallback\"`) the model is suitable for.\n        -   `max_tokens`: (Optional but recommended) The maximum token limit for the model.\n\n6.  **Update Environment Examples:**\n    -   Add the new `PROVIDER_API_KEY` to `.env.example`.\n    -   Add the new `PROVIDER_API_KEY` with its placeholder (`YOUR_PROVIDER_API_KEY_HERE`) to the `env` section for `taskmaster-ai` in `.cursor/mcp.json.example` (if it exists) or update instructions.\n\n7.  **Add Unit Tests:**\n    -   Create `tests/unit/ai-providers/<provider-name>.test.js`.\n    -   Mock the `@ai-sdk/<provider-name>` module and the core `ai` module functions (`generateText`, `streamText`, `generateObject`).\n    -   Write tests for each exported function (`generate<ProviderName>Text`, etc.) to verify:\n        -   Correct client instantiation.\n        -   Correct parameters passed to the mocked Vercel AI SDK functions.\n        -   Correct handling of results.\n        -   Error handling (missing API key, SDK errors).\n\n8.  **Documentation:**\n    -   Update any relevant documentation (like `README.md` or other rules) mentioning supported providers or configuration.\n\n*(Note: For providers **without** an official Vercel AI SDK adapter, the process would involve directly using the provider's own SDK or API within the `src/ai-providers/<provider-name>.js` module and manually constructing responses compatible with the unified service layer, which is significantly more complex.)*",".cursor/rules/ai_services.mdc":"---\ndescription: Guidelines for interacting with the unified AI service layer.\nglobs: scripts/modules/ai-services-unified.js, scripts/modules/task-manager/*.js, scripts/modules/commands.js\n---\n\n# AI Services Layer Guidelines\n\nThis document outlines the architecture and usage patterns for interacting with Large Language Models (LLMs) via Task Master's unified AI service layer (`ai-services-unified.js`). The goal is to centralize configuration, provider selection, API key management, fallback logic, and error handling.\n\n**Core Components:**\n\n*   **Configuration (`.taskmasterconfig` & [`config-manager.js`](mdc:scripts/modules/config-manager.js)):**\n    *   Defines the AI provider and model ID for different **roles** (`main`, `research`, `fallback`).\n    *   Stores parameters like `maxTokens` and `temperature` per role.\n    *   Managed via the `task-master models --setup` CLI command.\n    *   [`config-manager.js`](mdc:scripts/modules/config-manager.js) provides **getters** (e.g., `getMainProvider()`, `getParametersForRole()`) to access these settings. Core logic should **only** use these getters for *non-AI related application logic* (e.g., `getDefaultSubtasks`). The unified service fetches necessary AI parameters internally based on the `role`.\n    *   **API keys** are **NOT** stored here; they are resolved via `resolveEnvVariable` (in [`utils.js`](mdc:scripts/modules/utils.js)) from `.env` (for CLI) or the MCP `session.env` object (for MCP calls). See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc).\n\n*   **Unified Service (`ai-services-unified.js`):**\n    *   Exports primary interaction functions: `generateTextService`, `generateObjectService`. (Note: `streamTextService` exists but has known reliability issues with some providers/payloads).\n    *   Contains the core `_unifiedServiceRunner` logic.\n    *   Internally uses `config-manager.js` getters to determine the provider/model/parameters based on the requested `role`.\n    *   Implements the **fallback sequence** (e.g., main -> fallback -> research) if the primary provider/model fails.\n    *   Constructs the `messages` array required by the Vercel AI SDK.\n    *   Implements **retry logic** for specific API errors (`_attemptProviderCallWithRetries`).\n    *   Resolves API keys automatically via `_resolveApiKey` (using `resolveEnvVariable`).\n    *   Maps requests to the correct provider implementation (in `src/ai-providers/`) via `PROVIDER_FUNCTIONS`.\n    *   Returns a structured object containing the primary AI result (`mainResult`) and telemetry data (`telemetryData`). See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for details on how this telemetry data is propagated and handled.\n\n*   **Provider Implementations (`src/ai-providers/*.js`):**\n    *   Contain provider-specific wrappers around Vercel AI SDK functions (`generateText`, `generateObject`).\n\n**Usage Pattern (from Core Logic like `task-manager/*.js`):**\n\n1.  **Import Service:** Import `generateTextService` or `generateObjectService` from `../ai-services-unified.js`.\n    ```javascript\n    // Preferred for most tasks (especially with complex JSON)\n    import { generateTextService } from '../ai-services-unified.js';\n\n    // Use if structured output is reliable for the specific use case\n    // import { generateObjectService } from '../ai-services-unified.js';\n    ```\n\n2.  **Prepare Parameters:** Construct the parameters object for the service call.\n    *   `role`: **Required.** `'main'`, `'research'`, or `'fallback'`. Determines the initial provider/model/parameters used by the unified service.\n    *   `session`: **Required if called from MCP context.** Pass the `session` object received by the direct function wrapper. The unified service uses `session.env` to find API keys.\n    *   `systemPrompt`: Your system instruction string.\n    *   `prompt`: The user message string (can be long, include stringified data, etc.).\n    *   (For `generateObjectService` only): `schema` (Zod schema), `objectName`.\n\n3.  **Call Service:** Use `await` to call the service function.\n    ```javascript\n    // Example using generateTextService (most common)\n    try {\n        const resultText = await generateTextService({\n            role: useResearch ? 'research' : 'main', // Determine role based on logic\n            session: context.session, // Pass session from context object\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // Process the raw text response (e.g., parse JSON, use directly)\n        // ...\n    } catch (error) {\n        // Handle errors thrown by the unified service (if all fallbacks/retries fail)\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n\n    // Example using generateObjectService (use cautiously)\n    try {\n        const resultObject = await generateObjectService({\n            role: 'main',\n            session: context.session,\n            schema: myZodSchema,\n            objectName: 'myDataObject',\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // resultObject is already a validated JS object\n        // ...\n    } catch (error) {\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n    ```\n\n4.  **Handle Results/Errors:** Process the returned text/object or handle errors thrown by the unified service layer.\n\n**Key Implementation Rules & Gotchas:**\n\n*   ✅ **DO**: Centralize **all** LLM calls through `generateTextService` or `generateObjectService`.\n*   ✅ **DO**: Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.\n*   ✅ **DO**: Pass the `session` object (received in the `context` parameter, especially from direct function wrappers) to the service call when in MCP context.\n*   ✅ **DO**: Ensure API keys are correctly configured in `.env` (for CLI) or `.cursor/mcp.json` (for MCP).\n*   ✅ **DO**: Ensure `.taskmasterconfig` exists and has valid provider/model IDs for the roles you intend to use (manage via `task-master models --setup`).\n*   ✅ **DO**: Use `generateTextService` and implement robust manual JSON parsing (with Zod validation *after* parsing) when structured output is needed, as `generateObjectService` has shown unreliability with some providers/schemas.\n*   ❌ **DON'T**: Import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.\n*   ❌ **DON'T**: Initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (`task-manager/`) or MCP direct functions.\n*   ❌ **DON'T**: Fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters *for the AI call*. Pass the `role` instead.\n*   ❌ **DON'T**: Implement fallback or retry logic outside `ai-services-unified.js`.\n*   ❌ **DON'T**: Handle API key resolution outside the service layer (it uses `utils.js` internally).\n*   ⚠️ **generateObjectService Caution**: Be aware of potential reliability issues with `generateObjectService` across different providers and complex schemas. Prefer `generateTextService` + manual parsing as a more robust alternative for structured data needs.\n",".cursor/rules/architecture.mdc":"---\ndescription: Describes the high-level architecture of the Task Master CLI application.\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Application Architecture Overview\n\n- **Modular Structure**: The Task Master CLI is built using a modular architecture, with distinct modules responsible for different aspects of the application. This promotes separation of concerns, maintainability, and testability.\n\n- **Main Modules and Responsibilities**:\n\n  - **[`commands.js`](mdc:scripts/modules/commands.js): Command Handling**\n    - **Purpose**: Defines and registers all CLI commands using Commander.js.\n    - **Responsibilities** (See also: [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n      - Parses command-line arguments and options.\n      - Invokes appropriate core logic functions from `scripts/modules/`.\n      - Handles user input/output for CLI.\n      - Implements CLI-specific validation.\n\n  - **[`task-manager.js`](mdc:scripts/modules/task-manager.js) & `task-manager/` directory: Task Data & Core Logic**\n    - **Purpose**: Contains core functions for task data manipulation (CRUD), AI interactions, and related logic.\n    - **Responsibilities**:\n      - Reading/writing `tasks.json` with tagged task lists support.\n      - Implementing functions for task CRUD, parsing PRDs, expanding tasks, updating status, etc.\n      - **Tagged Task Lists**: Handles task organization across multiple contexts (tags) like \"master\", branch names, or project phases.\n      - **Tag Resolution**: Provides backward compatibility by resolving tagged format to legacy format transparently.\n      - **Delegating AI interactions** to the `ai-services-unified.js` layer.\n      - Accessing non-AI configuration via `config-manager.js` getters.\n    - **Key Files**: Individual files within `scripts/modules/task-manager/` handle specific actions (e.g., `add-task.js`, `expand-task.js`).\n\n  - **[`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js): Dependency Management**\n    - **Purpose**: Manages task dependencies.\n    - **Responsibilities**: Add/remove/validate/fix dependencies across tagged task contexts.\n\n  - **[`ui.js`](mdc:scripts/modules/ui.js): User Interface Components**\n    - **Purpose**: Handles CLI output formatting (tables, colors, boxes, spinners).\n    - **Responsibilities**: Displaying tasks, reports, progress, suggestions, and migration notices for tagged systems.\n\n  - **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js): Unified AI Service Layer**\n    - **Purpose**: Centralized interface for all LLM interactions using Vercel AI SDK.\n    - **Responsibilities** (See also: [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc)):\n      - Exports `generateTextService`, `generateObjectService`.\n      - Handles provider/model selection based on `role` and `.taskmasterconfig`.\n      - Resolves API keys (from `.env` or `session.env`).\n      - Implements fallback and retry logic.\n      - Orchestrates calls to provider-specific implementations (`src/ai-providers/`).\n    - Telemetry data generated by the AI service layer is propagated upwards through core logic, direct functions, and MCP tools. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the detailed integration pattern.\n\n  - **[`src/ai-providers/*.js`](mdc:src/ai-providers/): Provider-Specific Implementations**\n    - **Purpose**: Provider-specific wrappers for Vercel AI SDK functions.\n    - **Responsibilities**: Interact directly with Vercel AI SDK adapters.\n\n  - **[`config-manager.js`](mdc:scripts/modules/config-manager.js): Configuration Management**\n    - **Purpose**: Loads, validates, and provides access to configuration.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Reads and merges `.taskmasterconfig` with defaults.\n      - Provides getters (e.g., `getMainProvider`, `getLogLevel`, `getDefaultSubtasks`) for accessing settings.\n      - **Tag Configuration**: Manages `global.defaultTag` and `tags` section for tag system settings.\n      - **Note**: Does **not** store or directly handle API keys (keys are in `.env` or MCP `session.env`).\n\n  - **[`utils.js`](mdc:scripts/modules/utils.js): Core Utility Functions**\n    - **Purpose**: Low-level, reusable CLI utilities.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Logging (`log` function), File I/O (`readJSON`, `writeJSON`), String utils (`truncate`).\n      - Task utils (`findTaskById`), Dependency utils (`findCycles`).\n      - API Key Resolution (`resolveEnvVariable`).\n      - Silent Mode Control (`enableSilentMode`, `disableSilentMode`).\n      - **Tagged Task Lists**: Silent migration system, tag resolution, current tag management.\n      - **Migration System**: `performCompleteTagMigration`, `migrateConfigJson`, `createStateJson`.\n\n  - **[`mcp-server/`](mdc:mcp-server/): MCP Server Integration**\n    - **Purpose**: Provides MCP interface using FastMCP.\n    - **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):\n      - Registers tools (`mcp-server/src/tools/*.js`). Tool `execute` methods **should be wrapped** with the `withNormalizedProjectRoot` HOF (from `tools/utils.js`) to ensure consistent path handling.\n      - The HOF provides a normalized `args.projectRoot` to the `execute` method.\n      - Tool `execute` methods call **direct function wrappers** (`mcp-server/src/core/direct-functions/*.js`), passing the normalized `projectRoot` and other args.\n      - Direct functions use path utilities (`mcp-server/src/core/utils/`) to resolve paths based on `projectRoot` from session.\n      - Direct functions implement silent mode, logger wrappers, and call core logic functions from `scripts/modules/`.\n      - **Tagged Task Lists**: MCP tools fully support the tagged format with complete tag management capabilities.\n      - Manages MCP caching and response formatting.\n\n  - **[`init.js`](mdc:scripts/init.js): Project Initialization Logic**\n    - **Purpose**: Sets up new Task Master project structure.\n    - **Responsibilities**: Creates directories, copies templates, manages `package.json`, sets up `.cursor/mcp.json`, initializes state.json for tagged system.\n\n## Tagged Task Lists System Architecture\n\n**Data Structure**: Task Master now uses a tagged task lists system where the `tasks.json` file contains multiple named task lists as top-level keys:\n\n```json\n{\n  \"master\": {\n    \"tasks\": [/* standard task objects */]\n  },\n  \"feature-branch\": {\n    \"tasks\": [/* separate task context */]\n  }\n}\n```\n\n**Key Components:**\n\n- **Silent Migration**: Automatically transforms legacy `{\"tasks\": [...]}` format to tagged format `{\"master\": {\"tasks\": [...]}}` on first read\n- **Tag Resolution Layer**: Provides 100% backward compatibility by intercepting tagged format and returning legacy format to existing code\n- **Configuration Integration**: `global.defaultTag` and `tags` section in config.json manage tag system settings\n- **State Management**: `.taskmaster/state.json` tracks current tag, migration status, and tag-branch mappings\n- **Migration Notice**: User-friendly notification system for seamless migration experience\n\n**Backward Compatibility**: All existing CLI commands and MCP tools continue to work unchanged. The tag resolution layer ensures that existing code receives the expected legacy format while the underlying storage uses the new tagged structure.\n\n- **Data Flow and Module Dependencies (Updated)**:\n\n  - **CLI**: `bin/task-master.js` -> `scripts/dev.js` (loads `.env`) -> `scripts/modules/commands.js` -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **MCP**: External Tool -> `mcp-server/server.js` -> Tool (`mcp-server/src/tools/*`) -> Direct Function (`mcp-server/src/core/direct-functions/*`) -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **Configuration**: Core logic needing non-AI settings calls `config-manager.js` getters (passing `session.env` via `explicitRoot` if from MCP). Unified AI Service internally calls `config-manager.js` getters (using `role`) for AI params and `utils.js` (`resolveEnvVariable` with `session.env`) for API keys.\n\n## Silent Mode Implementation Pattern in MCP Direct Functions\n\nDirect functions (the `*Direct` functions in `mcp-server/src/core/direct-functions/`) need to carefully implement silent mode to prevent console logs from interfering with the structured JSON responses required by MCP. This involves both using `enableSilentMode`/`disableSilentMode` around core function calls AND passing the MCP logger via the standard wrapper pattern (see mcp.mdc). Here's the standard pattern for correct implementation:\n\n1. **Import Silent Mode Utilities**:\n   ```javascript\n   import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n   ```\n\n2. **Parameter Matching with Core Functions**:\n   - ✅ **DO**: Ensure direct function parameters match the core function parameters\n   - ✅ **DO**: Check the original core function signature before implementing\n   - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n   ```javascript\n   // Example: Core function signature\n   // async function expandTask(tasksPath, taskId, numSubtasks, useResearch, additionalContext, options)\n   \n   // Direct function implementation - extract only parameters that exist in core\n   export async function expandTaskDirect(args, log, context = {}) {\n     // Extract parameters that match the core function\n     const taskId = parseInt(args.id, 10);\n     const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n     const useResearch = args.research === true;\n     const additionalContext = args.prompt || '';\n     \n     // Later pass these parameters in the correct order to the core function\n     const result = await expandTask(\n       tasksPath, \n       taskId, \n       numSubtasks, \n       useResearch, \n       additionalContext,\n       { mcpLog: log, session: context.session }\n     );\n   }\n   ```\n\n3. **Checking Silent Mode State**:\n   - ✅ **DO**: Always use `isSilentMode()` function to check current status\n   - ❌ **DON'T**: Directly access the global `silentMode` variable or `global.silentMode`\n   ```javascript\n   // CORRECT: Use the function to check current state\n   if (!isSilentMode()) {\n     // Only create a loading indicator if not in silent mode\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   \n   // INCORRECT: Don't access global variables directly\n   if (!silentMode) { // ❌ WRONG\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   ```\n\n4. **Wrapping Core Function Calls**:\n   - ✅ **DO**: Use a try/finally block pattern to ensure silent mode is always restored\n   - ✅ **DO**: Enable silent mode before calling core functions that produce console output\n   - ✅ **DO**: Disable silent mode in a finally block to ensure it runs even if errors occur\n   - ❌ **DON'T**: Enable silent mode without ensuring it gets disabled\n   ```javascript\n   export async function someDirectFunction(args, log) {\n     try {\n       // Argument preparation\n       const tasksPath = findTasksJsonPath(args, log);\n       const someArg = args.someArg;\n       \n       // Enable silent mode to prevent console logs\n       enableSilentMode();\n       \n       try {\n         // Call core function which might produce console output\n         const result = await someCoreFunction(tasksPath, someArg);\n         \n         // Return standardized result object\n         return { \n           success: true, \n           data: result, \n           fromCache: false \n         };\n       } finally {\n         // ALWAYS disable silent mode in finally block\n         disableSilentMode();\n       }\n     } catch (error) {\n       // Standard error handling\n       log.error(`Error in direct function: ${error.message}`);\n       return { \n         success: false, \n         error: { code: 'OPERATION_ERROR', message: error.message }, \n         fromCache: false \n       };\n     }\n   }\n   ```\n\n5. **Mixed Parameter and Global Silent Mode Handling**:\n   - For functions that need to handle both a passed `silentMode` parameter and check global state:\n   ```javascript\n   // Check both the function parameter and global state\n   const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n   \n   if (!isSilent) {\n     console.log('Operation starting...');\n   }\n   ```\n\nBy following these patterns consistently, direct functions will properly manage console output suppression while ensuring that silent mode is always properly reset, even when errors occur. This creates a more robust system that helps prevent unexpected silent mode states that could cause logging problems in subsequent operations.\n\n- **Testing Architecture**:\n\n  - **Test Organization Structure** (See also: [`tests.mdc`](mdc:.cursor/rules/tests.mdc)):\n    - **Unit Tests**: Located in `tests/unit/`, reflect the module structure with one test file per module\n    - **Integration Tests**: Located in `tests/integration/`, test interactions between modules\n    - **End-to-End Tests**: Located in `tests/e2e/`, test complete workflows from a user perspective\n    - **Test Fixtures**: Located in `tests/fixtures/`, provide reusable test data\n    - **Tagged System Tests**: Test migration, tag resolution, and multi-context functionality\n\n  - **Module Design for Testability**:\n    - **Explicit Dependencies**: Functions accept their dependencies as parameters rather than using globals\n    - **Functional Style**: Pure functions with minimal side effects make testing deterministic\n    - **Separate Logic from I/O**: Core business logic is separated from file system operations\n    - **Clear Module Interfaces**: Each module has well-defined exports that can be mocked in tests\n    - **Callback Isolation**: Callbacks are defined as separate functions for easier testing\n    - **Stateless Design**: Modules avoid maintaining internal state where possible\n    - **Tag Resolution Testing**: Test both tagged and legacy format handling\n\n  - **Mock Integration Patterns**:\n    - **External Libraries**: Libraries like `fs`, `commander`, and `@anthropic-ai/sdk` are mocked at module level\n    - **Internal Modules**: Application modules are mocked with appropriate spy functions\n    - **Testing Function Callbacks**: Callbacks are extracted from mock call arguments and tested in isolation\n    - **UI Elements**: Output functions from `ui.js` are mocked to verify display calls\n    - **Tagged Data Mocking**: Test both legacy and tagged task data structures\n\n  - **Testing Flow**:\n    - Module dependencies are mocked (following Jest's hoisting behavior)\n    - Test modules are imported after mocks are established\n    - Spy functions are set up on module methods\n    - Tests call the functions under test and verify behavior\n    - Mocks are reset between test cases to maintain isolation\n    - Tagged system behavior is tested for both migration and normal operation\n\n- **Benefits of this Architecture**:\n\n  - **Maintainability**: Modules are self-contained and focused, making it easier to understand, modify, and debug specific features.\n  - **Testability**:  Each module can be tested in isolation (unit testing), and interactions between modules can be tested (integration testing).\n    - **Mocking Support**: The clear dependency boundaries make mocking straightforward\n    - **Test Isolation**: Each component can be tested without affecting others\n    - **Callback Testing**: Function callbacks can be extracted and tested independently\n    - **Multi-Context Testing**: Tagged system enables testing different task contexts independently\n  - **Reusability**: Utility functions and UI components can be reused across different parts of the application.\n  - **Scalability**:  New features can be added as new modules or by extending existing ones without significantly impacting other parts of the application.\n  - **Multi-Context Support**: Tagged task lists enable working across different contexts (branches, environments, phases) without conflicts.\n  - **Backward Compatibility**: Seamless migration and tag resolution ensure existing workflows continue unchanged.\n  - **Clarity**: The modular structure provides a clear separation of concerns, making the codebase easier to navigate and understand for developers.\n\nThis architectural overview should help AI models understand the structure and organization of the Task Master CLI codebase, enabling them to more effectively assist with code generation, modification, and understanding.\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.\n\n2.  **Create Direct Function File in `mcp-server/src/core/direct-functions/`:**\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**.\n    - Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:\n        - **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` being provided.\n        - Parse other `args` and perform necessary validation.\n        - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()`.\n        - Implement caching with `getCachedOrExecute` if applicable.\n        - Call core logic.\n        - Return `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n    - **Note**: Tag-aware MCP tools are fully implemented with complete tag management support.\n\n3.  **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method:\n      - Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).\n      - Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)` or use `asyncOperationManager.addOperation`.\n      - Pass the result to `handleApiResult`.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition.\n\n## Project Initialization\n\nThe `initialize_project` command provides a way to set up a new Task Master project:\n\n- **CLI Command**: `task-master init`\n- **MCP Tool**: `initialize_project`\n- **Functionality**:\n  - Creates necessary directories and files for a new project\n  - Sets up `tasks.json` with tagged structure and initial task files\n  - Configures project metadata (name, description, version)\n  - Initializes state.json for tag system\n  - Handles shell alias creation if requested\n  - Works in both interactive and non-interactive modes",".cursor/rules/changeset.mdc":"---\ndescription: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\nalwaysApply: true\n---\n\n# Changesets Workflow Guidelines\n\nChangesets is used to manage package versioning and generate accurate `CHANGELOG.md` files automatically. It's crucial to use it correctly after making meaningful changes that affect the package from an external perspective or significantly impact internal development workflow documented elsewhere.\n\n## When to Run Changeset\n\n- Run `npm run changeset` (or `npx changeset add`) **after** you have staged (`git add .`) a logical set of changes that should be communicated in the next release's `CHANGELOG.md`.\n- This typically includes:\n    - **New Features** (Backward-compatible additions)\n    - **Bug Fixes** (Fixes to existing functionality)\n    - **Breaking Changes** (Changes that are not backward-compatible)\n    - **Performance Improvements** (Enhancements to speed or resource usage)\n    - **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability) - *Such as reorganizing the MCP server's direct function implementations into separate files*\n    - **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)\n    - **Dependency Updates** (Especially if they fix known issues or introduce significant changes)\n    - **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)\n- **Every Pull Request** containing one or more of the above change types **should include a changeset file**.\n\n## What NOT to Add a Changeset For\n\nAvoid creating changesets for changes that have **no impact or relevance to external consumers** of the `task-master` package or contributors following **public-facing documentation**. Examples include:\n\n- **Internal Documentation Updates:** Changes *only* to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.\n- **Trivial Chores:** Very minor code cleanup, adding comments that don't clarify behavior, typo fixes in non-user-facing code or internal docs.\n- **Non-Impactful Test Updates:** Minor refactoring of tests, adding tests for existing functionality without fixing bugs.\n- **Local Configuration Changes:** Updates to personal editor settings, local `.env` files, etc.\n\n**Rule of Thumb:** If a user installing or using the `task-master` package wouldn't care about the change, or if a contributor following the main README wouldn't need to know about it for their workflow, you likely don't need a changeset.\n\n## How to Run and What It Asks\n\n1.  **Run the command**:\n    ```bash\n    npm run changeset\n    # or\n    npx changeset add\n    ```\n2.  **Select Packages**: It will prompt you to select the package(s) affected by your changes using arrow keys and spacebar. If this is not a monorepo, select the main package.\n3.  **Select Bump Type**: Choose the appropriate semantic version bump for **each** selected package:\n    *   **`Major`**: For **breaking changes**. Use sparingly.\n    *   **`Minor`**: For **new features**.\n    *   **`Patch`**: For **bug fixes**, performance improvements, **user-facing documentation changes**, significant refactoring, relevant dependency updates, or impactful build/tooling changes.\n4.  **Enter Summary**: Provide a concise summary of the changes **for the `CHANGELOG.md`**.\n    *   **Purpose**: This message is user-facing and explains *what* changed in the release.\n    *   **Format**: Use the imperative mood (e.g., \"Add feature X\", \"Fix bug Y\", \"Update README setup instructions\"). Keep it brief, typically a single line.\n    *   **Audience**: Think about users installing/updating the package or developers consuming its public API/CLI.\n    *   **Not a Git Commit Message**: This summary is *different* from your detailed Git commit message.\n\n## Changeset Summary vs. Git Commit Message\n\n- **Changeset Summary**:\n    - **Audience**: Users/Consumers of the package (reads `CHANGELOG.md`).\n    - **Purpose**: Briefly describe *what* changed in the released version that is relevant to them.\n    - **Format**: Concise, imperative mood, single line usually sufficient.\n    - **Example**: `Fix dependency resolution bug in 'next' command.`\n- **Git Commit Message**:\n    - **Audience**: Developers browsing the Git history of *this* repository.\n    - **Purpose**: Explain *why* the change was made, the context, and the implementation details (can include internal context).\n    - **Format**: Follows commit conventions (e.g., Conventional Commits), can be multi-line with a subject and body.\n    - **Example**:\n      ```\n      fix(deps): Correct dependency lookup in 'next' command\n\n      The logic previously failed to account for subtask dependencies when\n      determining the next available task. This commit refactors the\n      dependency check in `findNextTask` within `task-manager.js` to\n      correctly traverse both direct and subtask dependencies. Added\n      unit tests to cover this specific scenario.\n      ```\n- ✅ **DO**: Provide *both* a concise changeset summary (when appropriate) *and* a detailed Git commit message.\n- ❌ **DON'T**: Use your detailed Git commit message body as the changeset summary.\n- ❌ **DON'T**: Skip running `changeset` for user-relevant changes just because you wrote a good commit message.\n\n## The `.changeset` File\n\n- Running the command creates a unique markdown file in the `.changeset/` directory (e.g., `.changeset/random-name.md`).\n- This file contains the bump type information and the summary you provided.\n- **This file MUST be staged and committed** along with your relevant code changes.\n\n## Standard Workflow Sequence (When a Changeset is Needed)\n\n1.  Make your code or relevant documentation changes.\n2.  Stage your changes: `git add .`\n3.  Run changeset: `npm run changeset`\n    *   Select package(s).\n    *   Select bump type (`Patch`, `Minor`, `Major`).\n    *   Enter the **concise summary** for the changelog.\n4.  Stage the generated changeset file: `git add .changeset/*.md`\n5.  Commit all staged changes (code + changeset file) using your **detailed Git commit message**:\n    ```bash\n    git commit -m \"feat(module): Add new feature X...\"\n    ```\n\n## Release Process (Context)\n\n- The generated `.changeset/*.md` files are consumed later during the release process.\n- Commands like `changeset version` read these files, update `package.json` versions, update the `CHANGELOG.md`, and delete the individual changeset files.\n- Commands like `changeset publish` then publish the new versions to npm.\n\nFollowing this workflow ensures that versioning is consistent and changelogs are automatically and accurately generated based on the contributions made.\n",".cursor/rules/commands.mdc":"---\ndescription: Guidelines for implementing CLI commands using Commander.js\nglobs: scripts/modules/commands.js\nalwaysApply: false\n---\n\n# Command-Line Interface Implementation Guidelines\n\n**Note on Interaction Method:**\n\nWhile this document details the implementation of Task Master's **CLI commands**, the **preferred method for interacting with Task Master in integrated environments (like Cursor) is through the MCP server tools**. \n\n- **Use MCP Tools First**: Always prefer using the MCP tools (e.g., `get_tasks`, `add_task`) when interacting programmatically or via an integrated tool. They offer better performance, structured data, and richer error handling. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a comprehensive list of MCP tools and their corresponding CLI commands.\n- **CLI as Fallback/User Interface**: The `task-master` CLI commands described here are primarily intended for:\n    - Direct user interaction in the terminal.\n    - A fallback mechanism if the MCP server is unavailable or a specific functionality is not exposed via an MCP tool.\n- **Implementation Context**: This document (`commands.mdc`) focuses on the standards for *implementing* the CLI commands using Commander.js within the [`commands.js`](mdc:scripts/modules/commands.js) module.\n\n## Command Structure Standards\n\n- **Basic Command Template**:\n  ```javascript\n  // ✅ DO: Follow this structure for all commands\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-o, --option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n- **Command Handler Organization**:\n  - ✅ DO: Keep action handlers concise and focused\n  - ✅ DO: Extract core functionality to appropriate modules\n  - ✅ DO: Have the action handler import and call the relevant functions from core modules, like `task-manager.js` or `init.js`, passing the parsed `options`.\n  - ✅ DO: Perform basic parameter validation, such as checking for required options, within the action handler or at the start of the called core function.\n  - ❌ DON'T: Implement business logic in command handlers\n\n## Best Practices for Removal/Delete Commands\n\nWhen implementing commands that delete or remove data (like `remove-task` or `remove-subtask`), follow these specific guidelines:\n\n- **Confirmation Prompts**:\n  - ✅ **DO**: Include a confirmation prompt by default for destructive operations\n  - ✅ **DO**: Provide a `--yes` or `-y` flag to skip confirmation, useful for scripting or automation\n  - ✅ **DO**: Show what will be deleted in the confirmation message\n  - ❌ **DON'T**: Perform destructive operations without user confirmation unless explicitly overridden\n\n  ```javascript\n  // ✅ DO: Include confirmation for destructive operations\n  programInstance\n    .command('remove-task')\n    .description('Remove a task or subtask permanently')\n    .option('-i, --id <id>', 'ID of the task to remove')\n    .option('-y, --yes', 'Skip confirmation prompt', false)\n    .action(async (options) => {\n      // Validation code...\n      \n      if (!options.yes) {\n        const confirm = await inquirer.prompt([{\n          type: 'confirm',\n          name: 'proceed',\n          message: `Are you sure you want to permanently delete task ${taskId}? This cannot be undone.`,\n          default: false\n        }]);\n        \n        if (!confirm.proceed) {\n          console.log(chalk.yellow('Operation cancelled.'));\n          return;\n        }\n      }\n      \n      // Proceed with removal...\n    });\n  ```\n\n- **File Path Handling**:\n  - ✅ **DO**: Use `path.join()` to construct file paths\n  - ✅ **DO**: Follow established naming conventions for tasks, like `task_001.txt`\n  - ✅ **DO**: Check if files exist before attempting to delete them\n  - ✅ **DO**: Handle file deletion errors gracefully\n  - ❌ **DON'T**: Construct paths with string concatenation\n\n  ```javascript\n  // ✅ DO: Properly construct file paths\n  const taskFilePath = path.join(\n    path.dirname(tasksPath),\n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ✅ DO: Check existence before deletion\n  if (fs.existsSync(taskFilePath)) {\n    try {\n      fs.unlinkSync(taskFilePath);\n      console.log(chalk.green(`Task file deleted: ${taskFilePath}`));\n    } catch (error) {\n      console.warn(chalk.yellow(`Could not delete task file: ${error.message}`));\n    }\n  }\n  ```\n\n- **Clean Up References**:\n  - ✅ **DO**: Clean up references to the deleted item in other parts of the data\n  - ✅ **DO**: Handle both direct and indirect references\n  - ✅ **DO**: Explain what related data is being updated\n  - ❌ **DON'T**: Leave dangling references\n\n  ```javascript\n  // ✅ DO: Clean up references when deleting items\n  console.log(chalk.blue('Cleaning up task dependencies...'));\n  let referencesRemoved = 0;\n  \n  // Update dependencies in other tasks\n  data.tasks.forEach(task => {\n    if (task.dependencies && task.dependencies.includes(taskId)) {\n      task.dependencies = task.dependencies.filter(depId => depId !== taskId);\n      referencesRemoved++;\n    }\n  });\n  \n  if (referencesRemoved > 0) {\n    console.log(chalk.green(`Removed ${referencesRemoved} references to task ${taskId} from other tasks`));\n  }\n  ```\n\n- **Task File Regeneration**:\n  - ✅ **DO**: Regenerate task files after destructive operations\n  - ✅ **DO**: Pass all required parameters to generation functions\n  - ✅ **DO**: Provide an option to skip regeneration if needed\n  - ❌ **DON'T**: Assume default parameters will work\n\n  ```javascript\n  // ✅ DO: Properly regenerate files after deletion\n  if (!options.skipGenerate) {\n    console.log(chalk.blue('Regenerating task files...'));\n    try {\n      // Note both parameters are explicitly provided\n      await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n      console.log(chalk.green('Task files regenerated successfully'));\n    } catch (error) {\n      console.warn(chalk.yellow(`Warning: Could not regenerate task files: ${error.message}`));\n    }\n  }\n  ```\n\n- **Alternative Suggestions**:\n  - ✅ **DO**: Suggest non-destructive alternatives when appropriate\n  - ✅ **DO**: Explain the difference between deletion and status changes\n  - ✅ **DO**: Include examples of alternative commands\n\n  ```javascript\n  // ✅ DO: Suggest alternatives for destructive operations\n  console.log(chalk.yellow('Note: If you just want to exclude this task from active work, consider:'));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='cancelled'`));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='deferred'`));\n  console.log('This preserves the task and its history for reference.');\n  ```\n\n## Option Naming Conventions\n\n- **Command Names**:\n  - ✅ DO: Use kebab-case for command names (`analyze-complexity`)\n  - ❌ DON'T: Use camelCase for command names (`analyzeComplexity`)\n  - ✅ DO: Use descriptive, action-oriented names\n\n- **Option Names**:\n  - ✅ DO: Use kebab-case for long-form option names, like `--output-format`\n  - ✅ DO: Provide single-letter shortcuts when appropriate, like `-f, --file`\n  - ✅ DO: Use consistent option names across similar commands\n  - ❌ DON'T: Use different names for the same concept, such as `--file` in one command and `--path` in another\n\n  ```javascript\n  // ✅ DO: Use consistent option naming\n  .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <dir>', 'Output directory', 'tasks')\n  \n  // ❌ DON'T: Use inconsistent naming\n  .option('-f, --file <path>', 'Path to the tasks file')\n  .option('-p, --path <dir>', 'Output directory') // Should be --output\n  ```\n\n  > **Note**: Although options are defined with kebab-case, like `--num-tasks`, Commander.js stores them internally as camelCase properties. Access them in code as `options.numTasks`, not `options['num-tasks']`.\n\n- **Boolean Flag Conventions**:\n  - ✅ DO: Use positive flags with `--skip-` prefix for disabling behavior\n  - ❌ DON'T: Use negated boolean flags with `--no-` prefix\n  - ✅ DO: Use consistent flag handling across all commands\n\n  ```javascript\n  // ✅ DO: Use positive flag with skip- prefix \n  .option('--skip-generate', 'Skip generating task files')\n  \n  // ❌ DON'T: Use --no- prefix \n  .option('--no-generate', 'Skip generating task files')\n  ```\n\n  > **Important**: When handling boolean flags in the code, make your intent clear:\n  ```javascript\n  // ✅ DO: Use clear variable naming that matches the flag's intent\n  const generateFiles = !options.skipGenerate;\n  \n  // ❌ DON'T: Use confusing double negatives\n  const dontSkipGenerate = !options.skipGenerate;\n  ```\n\n## Input Validation\n\n- **Required Parameters**:\n  - ✅ DO: Check that required parameters are provided\n  - ✅ DO: Provide clear error messages when parameters are missing\n  - ✅ DO: Use early returns with `process.exit(1)` for validation failures\n\n  ```javascript\n  // ✅ DO: Validate required parameters early\n  if (!prompt) {\n    console.error(chalk.red('Error: --prompt parameter is required. Please provide a task description.'));\n    process.exit(1);\n  }\n  ```\n\n- **Parameter Type Conversion**:\n  - ✅ DO: Convert string inputs to appropriate types, such as numbers or booleans\n  - ✅ DO: Handle conversion errors gracefully\n\n  ```javascript\n  // ✅ DO: Parse numeric parameters properly\n  const fromId = parseInt(options.from, 10);\n  if (isNaN(fromId)) {\n    console.error(chalk.red('Error: --from must be a valid number'));\n    process.exit(1);\n  }\n  ```\n\n- **Enhanced Input Validation**:\n  - ✅ DO: Validate file existence for critical file operations\n  - ✅ DO: Provide context-specific validation for identifiers\n  - ✅ DO: Check required API keys for features that depend on them\n\n  ```javascript\n  // ✅ DO: Validate file existence\n  if (!fs.existsSync(tasksPath)) {\n    console.error(chalk.red(`Error: Tasks file not found at path: ${tasksPath}`));\n    if (tasksPath === 'tasks/tasks.json') {\n      console.log(chalk.yellow('Hint: Run task-master init or task-master parse-prd to create tasks.json first'));\n    } else {\n      console.log(chalk.yellow(`Hint: Check if the file path is correct: ${tasksPath}`));\n    }\n    process.exit(1);\n  }\n  \n  // ✅ DO: Validate task ID\n  const taskId = parseInt(options.id, 10);\n  if (isNaN(taskId) || taskId <= 0) {\n    console.error(chalk.red(`Error: Invalid task ID: ${options.id}. Task ID must be a positive integer.`));\n    console.log(chalk.yellow(\"Usage example: task-master update-task --id='23' --prompt='Update with new information.\\\\nEnsure proper error handling.'\"));\n    process.exit(1);\n  }\n  \n  // ✅ DO: Check for required API keys\n  if (useResearch && !process.env.PERPLEXITY_API_KEY) {\n    console.log(chalk.yellow('Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'));\n    console.log(chalk.yellow('Falling back to Claude AI for task update.'));\n  }\n  ```\n\n## User Feedback\n\n- **Operation Status**:\n  - ✅ DO: Provide clear feedback about the operation being performed\n  - ✅ DO: Display success or error messages after completion\n  - ✅ DO: Use colored output to distinguish between different message types\n\n  ```javascript\n  // ✅ DO: Show operation status\n  console.log(chalk.blue(`Parsing PRD file: ${file}`));\n  console.log(chalk.blue(`Generating ${numTasks} tasks...`));\n  \n  try {\n    await parsePRD(file, outputPath, numTasks);\n    console.log(chalk.green('Successfully generated tasks from PRD'));\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    process.exit(1);\n  }\n  ```\n\n- **Success Messages with Next Steps**:\n  - ✅ DO: Use boxen for important success messages with clear formatting\n  - ✅ DO: Provide suggested next steps after command completion\n  - ✅ DO: Include ready-to-use commands for follow-up actions\n\n  ```javascript\n  // ✅ DO: Display success with next steps\n  console.log(boxen(\n    chalk.white.bold(`Subtask ${parentId}.${subtask.id} Added Successfully`) + '\\n\\n' +\n    chalk.white(`Title: ${subtask.title}`) + '\\n' +\n    chalk.white(`Status: ${getStatusWithColor(subtask.status)}`) + '\\n' +\n    (dependencies.length > 0 ? chalk.white(`Dependencies: ${dependencies.join(', ')}`) + '\\n' : '') +\n    '\\n' +\n    chalk.white.bold('Next Steps:') + '\\n' +\n    chalk.cyan(`1. Run ${chalk.yellow(`task-master show '${parentId}'`)} to see the parent task with all subtasks`) + '\\n' +\n    chalk.cyan(`2. Run ${chalk.yellow(`task-master set-status --id='${parentId}.${subtask.id}' --status='in-progress'`)} to start working on it`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Command Registration\n\n- **Command Grouping**:\n  - ✅ DO: Group related commands together in the code\n  - ✅ DO: Add related commands in a logical order\n  - ✅ DO: Use comments to delineate command groups\n\n- **Command Export**:\n  - ✅ DO: Export the registerCommands function\n  - ✅ DO: Keep the CLI setup code clean and maintainable\n\n  ```javascript\n  // ✅ DO: Follow this export pattern\n  export {\n    registerCommands,\n    setupCLI,\n    runCLI,\n    checkForUpdate, // Include version checking functions\n    compareVersions,\n    displayUpgradeNotification\n  };\n  ```\n\n## Context-Aware Command Pattern\n\nFor AI-powered commands that benefit from project context, follow the research command pattern:\n\n- **Context Integration**:\n  - ✅ DO: Use `ContextGatherer` utility for multi-source context extraction\n  - ✅ DO: Support task IDs, file paths, custom context, and project tree\n  - ✅ DO: Implement fuzzy search for automatic task discovery\n  - ✅ DO: Display detailed token breakdown for transparency\n\n  ```javascript\n  // ✅ DO: Follow this pattern for context-aware commands\n  programInstance\n    .command('research')\n    .description('Perform AI-powered research queries with project context')\n    .argument('<prompt>', 'Research prompt to investigate')\n    .option('-i, --id <ids>', 'Comma-separated task/subtask IDs to include as context')\n    .option('-f, --files <paths>', 'Comma-separated file paths to include as context')\n    .option('-c, --context <text>', 'Additional custom context')\n    .option('--tree', 'Include project file tree structure')\n    .option('-d, --detail <level>', 'Output detail level: low, medium, high', 'medium')\n    .action(async (prompt, options) => {\n      // 1. Parameter validation and parsing\n      const taskIds = options.id ? parseTaskIds(options.id) : [];\n      const filePaths = options.files ? parseFilePaths(options.files) : [];\n      \n      // 2. Initialize context gatherer\n      const projectRoot = findProjectRoot() || '.';\n      const gatherer = new ContextGatherer(projectRoot, tasksPath);\n      \n      // 3. Auto-discover relevant tasks if none specified\n      if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n          fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n      }\n      \n      // 4. Gather context with token breakdown\n      const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n      });\n      \n      // 5. Display token breakdown and execute AI call\n      // Implementation continues...\n    });\n  ```\n\n## Error Handling\n\n- **Exception Management**:\n  - ✅ DO: Wrap async operations in try/catch blocks\n  - ✅ DO: Display user-friendly error messages\n  - ✅ DO: Include detailed error information in debug mode\n\n  ```javascript\n  // ✅ DO: Handle errors properly\n  try {\n    // Command implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n- **Unknown Options Handling**:\n  - ✅ DO: Provide clear error messages for unknown options\n  - ✅ DO: Show available options when an unknown option is used\n  - ✅ DO: Include command-specific help displays for common errors\n  - ❌ DON'T: Allow unknown options with `.allowUnknownOption()`\n\n  ```javascript\n  // ✅ DO: Register global error handlers for unknown options\n  programInstance.on('option:unknown', function(unknownOption) {\n    const commandName = this._name || 'unknown';\n    console.error(chalk.red(`Error: Unknown option '${unknownOption}'`));\n    console.error(chalk.yellow(`Run 'task-master ${commandName} --help' to see available options`));\n    process.exit(1);\n  });\n  \n  // ✅ DO: Add command-specific help displays\n  function showCommandHelp() {\n    console.log(boxen(\n      chalk.white.bold('Command Help') + '\\n\\n' +\n      chalk.cyan('Usage:') + '\\n' +\n      `  task-master command --option1=<value> [options]\\n\\n` +\n      chalk.cyan('Options:') + '\\n' +\n      '  --option1 <value>    Description of option1 (required)\\n' +\n      '  --option2 <value>    Description of option2\\n\\n' +\n      chalk.cyan('Examples:') + '\\n' +\n      '  task-master command --option1=\\'value1\\' --option2=\\'value2\\'',\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n- **Global Error Handling**:\n  - ✅ DO: Set up global error handlers for uncaught exceptions\n  - ✅ DO: Detect and format Commander-specific errors\n  - ✅ DO: Provide suitable guidance for fixing common errors\n\n  ```javascript\n  // ✅ DO: Set up global error handlers with helpful messages\n  process.on('uncaughtException', (err) => {\n    // Handle Commander-specific errors\n    if (err.code === 'commander.unknownOption') {\n      const option = err.message.match(/'([^']+)'/)?.[1]; // Safely extract option name\n      console.error(chalk.red(`Error: Unknown option '${option}'`));\n      console.error(chalk.yellow(\"Run 'task-master <command> --help' to see available options\"));\n      process.exit(1);\n    }\n    \n    // Handle other error types...\n    console.error(chalk.red(`Error: ${err.message}`));\n    process.exit(1);\n  });\n  ```\n\n- **Contextual Error Handling**:\n  - ✅ DO: Provide specific error handling for common issues\n  - ✅ DO: Include troubleshooting hints for each error type\n  - ✅ DO: Use consistent error formatting across all commands\n\n  ```javascript\n  // ✅ DO: Provide specific error handling with guidance\n  try {\n    // Implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    // Provide more helpful error messages for common issues\n    if (error.message.includes('task') && error.message.includes('not found')) {\n      console.log(chalk.yellow('\\nTo fix this issue:'));\n      console.log('  1. Run \\'task-master list\\' to see all available task IDs');\n      console.log('  2. Use a valid task ID with the --id parameter');\n    } else if (error.message.includes('API key')) {\n      console.log(chalk.yellow('\\nThis error is related to API keys. Check your environment variables.'));\n    }\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n## Integration with Other Modules\n\n- **Import Organization**:\n  - ✅ DO: Group imports by module/functionality\n  - ✅ DO: Import only what's needed, not entire modules\n  - ❌ DON'T: Create circular dependencies\n\n  ```javascript\n  // ✅ DO: Organize imports by module\n  import { program } from 'commander';\n  import path from 'path';\n  import chalk from 'chalk';\n  import https from 'https';\n  \n  import { CONFIG, log, readJSON } from './utils.js';\n  import { displayBanner, displayHelp } from './ui.js';\n  import { parsePRD, listTasks } from './task-manager.js';\n  import { addDependency } from './dependency-manager.js';\n  ```\n\n## Subtask Management Commands\n\n- **Add Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for adding subtasks\n  programInstance\n    .command('add-subtask')\n    .description('Add a new subtask to a parent task or convert an existing task to a subtask')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-p, --parent <id>', 'ID of the parent task (required)')\n    .option('-i, --task-id <id>', 'Existing task ID to convert to subtask')\n    .option('-t, --title <title>', 'Title for the new subtask, required if not converting')\n    .option('-d, --description <description>', 'Description for the new subtask, optional')\n    .option('--details <details>', 'Implementation details for the new subtask, optional')\n    .option('--dependencies <ids>', 'Comma-separated list of subtask IDs this subtask depends on')\n    .option('--status <status>', 'Initial status for the subtask', 'pending')\n    .option('--generate', 'Regenerate task files after adding subtask')\n    .action(async (options) => {\n      // Validate required parameters\n      if (!options.parent) {\n        console.error(chalk.red('Error: --parent parameter is required'));\n        showAddSubtaskHelp(); // Show contextual help\n        process.exit(1);\n      }\n      \n      // Implementation with detailed error handling\n    });\n  ```\n\n- **Remove Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for removing subtasks\n  programInstance\n    .command('remove-subtask')\n    .description('Remove a subtask from its parent task, optionally converting it to a standalone task')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-i, --id <id>', 'ID of the subtask to remove in format parentId.subtaskId, required')\n    .option('-c, --convert', 'Convert the subtask to a standalone task instead of deleting')\n    .option('--generate', 'Regenerate task files after removing subtask')\n    .action(async (options) => {\n      // Implementation with detailed error handling\n    })\n    .on('error', function(err) {\n      console.error(chalk.red(`Error: ${err.message}`));\n      showRemoveSubtaskHelp(); // Show contextual help\n      process.exit(1);\n    });\n  ```\n\n## Version Checking and Updates\n\n- **Automatic Version Checking**:\n  - ✅ DO: Implement version checking to notify users of available updates\n  - ✅ DO: Use non-blocking version checks that don't delay command execution\n  - ✅ DO: Display update notifications after command completion\n\n  ```javascript\n  // ✅ DO: Implement version checking function\n  async function checkForUpdate() {\n    // Implementation details...\n    // Example return structure:\n    return { currentVersion, latestVersion, updateAvailable };\n  }\n  \n  // ✅ DO: Implement semantic version comparison\n  function compareVersions(v1, v2) {\n    const v1Parts = v1.split('.').map(p => parseInt(p, 10));\n    const v2Parts = v2.split('.').map(p => parseInt(p, 10));\n    \n    // Implementation details...\n    return result; // -1, 0, or 1\n  }\n  \n  // ✅ DO: Display attractive update notifications\n  function displayUpgradeNotification(currentVersion, latestVersion) {\n    const message = boxen(\n      `${chalk.blue.bold('Update Available!')} ${chalk.dim(currentVersion)} → ${chalk.green(latestVersion)}\\n\\n` +\n      `Run ${chalk.cyan('npm i task-master-ai@latest -g')} to update to the latest version with new features and bug fixes.`,\n      {\n        padding: 1,\n        margin: { top: 1, bottom: 1 },\n        borderColor: 'yellow',\n        borderStyle: 'round'\n      }\n    );\n    \n    console.log(message);\n  }\n  \n  // ✅ DO: Integrate version checking in CLI run function\n  async function runCLI(argv = process.argv) {\n    try {\n      // Start the update check in the background - don't await yet\n      const updateCheckPromise = checkForUpdate();\n      \n      // Setup and parse\n      const programInstance = setupCLI();\n      await programInstance.parseAsync(argv);\n      \n      // After command execution, check if an update is available\n      const updateInfo = await updateCheckPromise;\n      if (updateInfo.updateAvailable) {\n        displayUpgradeNotification(updateInfo.currentVersion, updateInfo.latestVersion);\n      }\n    } catch (error) {\n      // Error handling...\n    }\n  }\n  ```\n\nRefer to [`commands.js`](mdc:scripts/modules/commands.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. \n// Helper function to show add-subtask command help\nfunction showAddSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Add Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master add-subtask --parent=<id> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -p, --parent <id>         Parent task ID (required)\\n' +\n    '  -i, --task-id <id>        Existing task ID to convert to subtask\\n' +\n    '  -t, --title <title>       Title for the new subtask\\n' +\n    '  -d, --description <text>  Description for the new subtask\\n' +\n    '  --details <text>          Implementation details for the new subtask\\n' +\n    '  --dependencies <ids>      Comma-separated list of dependency IDs\\n' +\n    '  -s, --status <status>     Status for the new subtask (default: \"pending\")\\n' +\n    '  -f, --file <file>         Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate                Regenerate task files after adding subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master add-subtask --parent=\\'5\\' --task-id=\\'8\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Implement login UI\\' -d \\'Create the login form\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Handle API Errors\\' --details \"Handle 401 Unauthorized.\\\\nHandle 500 Server Error.\" --generate',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n}\n\n// Helper function to show remove-subtask command help\nfunction showRemoveSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Remove Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master remove-subtask --id=<parentId.subtaskId> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -i, --id <id>       Subtask ID(s) to remove in format \"parentId.subtaskId\" (can be comma-separated, required)\\n' +\n    '  -c, --convert       Convert the subtask to a standalone task instead of deleting it\\n' +\n    '  -f, --file <file>   Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate          Regenerate task files after removing subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2,6.3,7.1\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\' --convert',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n} \n",".cursor/rules/context_gathering.mdc":"---\ndescription: Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\nglobs: \nalwaysApply: false\n---\n# Context Gathering Patterns and Utilities\n\nThis document outlines the standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\n\n## Core Context Gathering Utility\n\nThe `ContextGatherer` class (`scripts/modules/utils/contextGatherer.js`) provides a centralized, reusable utility for extracting context from multiple sources:\n\n### **Key Features**\n- **Multi-source Context**: Tasks, files, custom text, project file tree\n- **Token Counting**: Detailed breakdown using `gpt-tokens` library\n- **Format Support**: Different output formats (research, chat, system-prompt)\n- **Error Handling**: Graceful handling of missing files, invalid task IDs\n- **Performance**: File size limits, depth limits for tree generation\n\n### **Usage Pattern**\n```javascript\nimport { ContextGatherer } from '../utils/contextGatherer.js';\n\n// Initialize with project paths\nconst gatherer = new ContextGatherer(projectRoot, tasksPath);\n\n// Gather context with detailed token breakdown\nconst result = await gatherer.gather({\n    tasks: ['15', '16.2'],           // Task and subtask IDs\n    files: ['src/api.js', 'README.md'], // File paths\n    customContext: 'Additional context text',\n    includeProjectTree: true,        // Include file tree\n    format: 'research',              // Output format\n    includeTokenCounts: true         // Get detailed token breakdown\n});\n\n// Access results\nconst contextString = result.context;\nconst tokenBreakdown = result.tokenBreakdown;\n```\n\n### **Token Breakdown Structure**\n```javascript\n{\n    customContext: { tokens: 150, characters: 800 },\n    tasks: [\n        { id: '15', type: 'task', title: 'Task Title', tokens: 245, characters: 1200 },\n        { id: '16.2', type: 'subtask', title: 'Subtask Title', tokens: 180, characters: 900 }\n    ],\n    files: [\n        { path: 'src/api.js', tokens: 890, characters: 4500, size: '4.5 KB' }\n    ],\n    projectTree: { tokens: 320, characters: 1600 },\n    total: { tokens: 1785, characters: 8000 }\n}\n```\n\n## Fuzzy Search Integration\n\nThe `FuzzyTaskSearch` class (`scripts/modules/utils/fuzzyTaskSearch.js`) provides intelligent task discovery:\n\n### **Key Features**\n- **Semantic Matching**: Uses Fuse.js for similarity scoring\n- **Purpose Categories**: Pattern-based task categorization\n- **Relevance Scoring**: High/medium/low relevance thresholds\n- **Context-Aware**: Different search configurations for different use cases\n\n### **Usage Pattern**\n```javascript\nimport { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n\n// Initialize with tasks data and context\nconst fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n\n// Find relevant tasks\nconst searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n});\n\n// Get task IDs for context gathering\nconst taskIds = fuzzySearch.getTaskIds(searchResults);\n```\n\n## Implementation Patterns for Commands\n\n### **1. Context-Aware Command Structure**\n```javascript\n// In command action handler\nasync function commandAction(prompt, options) {\n    // 1. Parameter validation and parsing\n    const taskIds = options.id ? parseTaskIds(options.id) : [];\n    const filePaths = options.files ? parseFilePaths(options.files) : [];\n    \n    // 2. Initialize context gatherer\n    const projectRoot = findProjectRoot() || '.';\n    const tasksPath = path.join(projectRoot, 'tasks', 'tasks.json');\n    const gatherer = new ContextGatherer(projectRoot, tasksPath);\n    \n    // 3. Auto-discover relevant tasks if none specified\n    if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n            fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n    }\n    \n    // 4. Gather context with token breakdown\n    const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n    });\n    \n    // 5. Display token breakdown (for CLI)\n    if (outputFormat === 'text') {\n        displayDetailedTokenBreakdown(contextResult.tokenBreakdown);\n    }\n    \n    // 6. Use context in AI call\n    const aiResult = await generateTextService(role, session, systemPrompt, userPrompt);\n    \n    // 7. Display results with enhanced formatting\n    displayResults(aiResult, contextResult.tokenBreakdown);\n}\n```\n\n### **2. Token Display Pattern**\n```javascript\nfunction displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    // Build context breakdown\n    if (tokenBreakdown.tasks?.length > 0) {\n        const taskDetails = tokenBreakdown.tasks.map(task => \n            `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n        ).join('\\n');\n        sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    if (tokenBreakdown.files?.length > 0) {\n        const fileDetails = tokenBreakdown.files.map(file =>\n            `  ${file.path}: ${file.tokens.toLocaleString()} (${file.size})`\n        ).join('\\n');\n        sections.push(`Files (${tokenBreakdown.files.reduce((sum, f) => sum + f.tokens, 0).toLocaleString()}):\\n${fileDetails}`);\n    }\n    \n    // Add prompts breakdown\n    sections.push(`Prompts: system ${systemTokens.toLocaleString()}, user ${userTokens.toLocaleString()}`);\n    \n    // Display in clean box\n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n        title: chalk.cyan('Token Usage'),\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        borderStyle: 'round',\n        borderColor: 'cyan'\n    }));\n}\n```\n\n### **3. Enhanced Result Display Pattern**\n```javascript\nfunction displayResults(result, query, detailLevel, tokenBreakdown) {\n    // Header with query info\n    const header = boxen(\n        chalk.green.bold('Research Results') + '\\n\\n' +\n        chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n        chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n        {\n            padding: { top: 1, bottom: 1, left: 2, right: 2 },\n            margin: { top: 1, bottom: 0 },\n            borderStyle: 'round',\n            borderColor: 'green'\n        }\n    );\n    console.log(header);\n    \n    // Process and highlight code blocks\n    const processedResult = processCodeBlocks(result);\n    \n    // Main content in clean box\n    const contentBox = boxen(processedResult, {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 0, bottom: 1 },\n        borderStyle: 'single',\n        borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Research complete'));\n}\n```\n\n## Code Block Enhancement\n\n### **Syntax Highlighting Pattern**\n```javascript\nimport { highlight } from 'cli-highlight';\n\nfunction processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n        try {\n            const highlighted = highlight(code.trim(), { \n                language: language || 'javascript',\n                theme: 'default'\n            });\n            return `\\n${highlighted}\\n`;\n        } catch (error) {\n            return `\\n${code.trim()}\\n`;\n        }\n    });\n}\n```\n\n## Integration Guidelines\n\n### **When to Use Context Gathering**\n- ✅ **DO**: Use for AI-powered commands that benefit from project context\n- ✅ **DO**: Use when users might want to reference specific tasks or files\n- ✅ **DO**: Use for research, analysis, or generation commands\n- ❌ **DON'T**: Use for simple CRUD operations that don't need AI context\n\n### **Performance Considerations**\n- ✅ **DO**: Set reasonable file size limits (50KB default)\n- ✅ **DO**: Limit project tree depth (3-5 levels)\n- ✅ **DO**: Provide token counts to help users understand context size\n- ✅ **DO**: Allow users to control what context is included\n\n### **Error Handling**\n- ✅ **DO**: Gracefully handle missing files with warnings\n- ✅ **DO**: Validate task IDs and provide helpful error messages\n- ✅ **DO**: Continue processing even if some context sources fail\n- ✅ **DO**: Provide fallback behavior when context gathering fails\n\n### **Future Command Integration**\nCommands that should consider adopting this pattern:\n- `analyze-complexity` - Could benefit from file context\n- `expand-task` - Could use related task context\n- `update-task` - Could reference similar tasks for consistency\n- `add-task` - Could use project context for better task generation\n\n## Export Patterns\n\n### **Context Gatherer Module**\n```javascript\nexport {\n    ContextGatherer,\n    createContextGatherer  // Factory function\n};\n```\n\n### **Fuzzy Search Module**\n```javascript\nexport {\n    FuzzyTaskSearch,\n    PURPOSE_CATEGORIES,\n    RELEVANCE_THRESHOLDS\n};\n```\n\nThis context gathering system provides a foundation for building more intelligent, context-aware commands that can leverage project knowledge to provide better AI-powered assistance.\n",".cursor/rules/cursor_rules.mdc":"---\ndescription: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\nglobs: .cursor/rules/*.mdc\nalwaysApply: true\n---\n\n- **Required Rule Structure:**\n  ```markdown\n  ---\n  description: Clear, one-line description of what the rule enforces\n  globs: path/to/files/*.ext, other/path/**/*\n  alwaysApply: boolean\n  ---\n\n  - **Main Points in Bold**\n    - Sub-points with details\n    - Examples and explanations\n  ```\n\n- **File References:**\n  - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files\n  - Example: [prisma.mdc](mdc:.cursor/rules/prisma.mdc) for rule references\n  - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references\n\n- **Code Examples:**\n  - Use language-specific code blocks\n  ```typescript\n  // ✅ DO: Show good examples\n  const goodExample = true;\n  \n  // ❌ DON'T: Show anti-patterns\n  const badExample = false;\n  ```\n\n- **Rule Content Guidelines:**\n  - Start with high-level overview\n  - Include specific, actionable requirements\n  - Show examples of correct implementation\n  - Reference existing code when possible\n  - Keep rules DRY by referencing other rules\n\n- **Rule Maintenance:**\n  - Update rules when new patterns emerge\n  - Add examples from actual codebase\n  - Remove outdated patterns\n  - Cross-reference related rules\n\n- **Best Practices:**\n  - Use bullet points for clarity\n  - Keep descriptions concise\n  - Include both DO and DON'T examples\n  - Reference actual code over theoretical examples\n  - Use consistent formatting across rules ",".cursor/rules/dependencies.mdc":"---\ndescription: Guidelines for managing task dependencies and relationships\nglobs: scripts/modules/dependency-manager.js\nalwaysApply: false\n---\n\n# Dependency Management Guidelines\n\n## Dependency Structure Principles\n\n- **Dependency References**:\n  - ✅ DO: Represent task dependencies as arrays of task IDs\n  - ✅ DO: Use numeric IDs for direct task references\n  - ✅ DO: Use string IDs with dot notation (e.g., \"1.2\") for subtask references\n  - ❌ DON'T: Mix reference types without proper conversion\n\n  ```javascript\n  // ✅ DO: Use consistent dependency formats\n  // For main tasks\n  task.dependencies = [1, 2, 3]; // Dependencies on other main tasks\n  \n  // For subtasks\n  subtask.dependencies = [1, \"3.2\"]; // Dependency on main task 1 and subtask 2 of task 3\n  ```\n\n- **Subtask Dependencies**:\n  - ✅ DO: Allow numeric subtask IDs to reference other subtasks within the same parent\n  - ✅ DO: Convert between formats appropriately when needed\n  - ❌ DON'T: Create circular dependencies between subtasks\n\n  ```javascript\n  // ✅ DO: Properly normalize subtask dependencies\n  // When a subtask refers to another subtask in the same parent\n  if (typeof depId === 'number' && depId < 100) {\n    // It's likely a reference to another subtask in the same parent task\n    const fullSubtaskId = `${parentId}.${depId}`;\n    // Now use fullSubtaskId for validation\n  }\n  ```\n\n## Dependency Validation\n\n- **Existence Checking**:\n  - ✅ DO: Validate that referenced tasks exist before adding dependencies\n  - ✅ DO: Provide clear error messages for non-existent dependencies\n  - ✅ DO: Remove references to non-existent tasks during validation\n\n  ```javascript\n  // ✅ DO: Check if the dependency exists before adding\n  if (!taskExists(data.tasks, formattedDependencyId)) {\n    log('error', `Dependency target ${formattedDependencyId} does not exist in tasks.json`);\n    process.exit(1);\n  }\n  ```\n\n- **Circular Dependency Prevention**:\n  - ✅ DO: Check for circular dependencies before adding new relationships\n  - ✅ DO: Use graph traversal algorithms (DFS) to detect cycles\n  - ✅ DO: Provide clear error messages explaining the circular chain\n\n  ```javascript\n  // ✅ DO: Check for circular dependencies before adding\n  const dependencyChain = [formattedTaskId];\n  if (isCircularDependency(data.tasks, formattedDependencyId, dependencyChain)) {\n    log('error', `Cannot add dependency ${formattedDependencyId} to task ${formattedTaskId} as it would create a circular dependency.`);\n    process.exit(1);\n  }\n  ```\n\n- **Self-Dependency Prevention**:\n  - ✅ DO: Prevent tasks from depending on themselves\n  - ✅ DO: Handle both direct and indirect self-dependencies\n\n  ```javascript\n  // ✅ DO: Prevent self-dependencies\n  if (String(formattedTaskId) === String(formattedDependencyId)) {\n    log('error', `Task ${formattedTaskId} cannot depend on itself.`);\n    process.exit(1);\n  }\n  ```\n\n## Dependency Modification\n\n- **Adding Dependencies**:\n  - ✅ DO: Format task and dependency IDs consistently\n  - ✅ DO: Check for existing dependencies to prevent duplicates\n  - ✅ DO: Sort dependencies for better readability\n\n  ```javascript\n  // ✅ DO: Format IDs consistently when adding dependencies\n  const formattedTaskId = typeof taskId === 'string' && taskId.includes('.') \n    ? taskId : parseInt(taskId, 10);\n  \n  const formattedDependencyId = formatTaskId(dependencyId);\n  ```\n\n- **Removing Dependencies**:\n  - ✅ DO: Check if the dependency exists before removing\n  - ✅ DO: Handle different ID formats consistently\n  - ✅ DO: Provide feedback about the removal result\n\n  ```javascript\n  // ✅ DO: Properly handle dependency removal\n  const dependencyIndex = targetTask.dependencies.findIndex(dep => {\n    // Convert both to strings for comparison\n    let depStr = String(dep);\n    \n    // Handle relative subtask references\n    if (typeof dep === 'number' && dep < 100 && isSubtask) {\n      const [parentId] = formattedTaskId.split('.');\n      depStr = `${parentId}.${dep}`;\n    }\n    \n    return depStr === normalizedDependencyId;\n  });\n  \n  if (dependencyIndex === -1) {\n    log('info', `Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`);\n    return;\n  }\n  \n  // Remove the dependency\n  targetTask.dependencies.splice(dependencyIndex, 1);\n  ```\n\n## Dependency Cleanup\n\n- **Duplicate Removal**:\n  - ✅ DO: Use Set objects to identify and remove duplicates\n  - ✅ DO: Handle both numeric and string ID formats\n\n  ```javascript\n  // ✅ DO: Remove duplicate dependencies\n  const uniqueDeps = new Set();\n  const uniqueDependencies = task.dependencies.filter(depId => {\n    // Convert to string for comparison to handle both numeric and string IDs\n    const depIdStr = String(depId);\n    if (uniqueDeps.has(depIdStr)) {\n      log('warn', `Removing duplicate dependency from task ${task.id}: ${depId}`);\n      return false;\n    }\n    uniqueDeps.add(depIdStr);\n    return true;\n  });\n  ```\n\n- **Invalid Reference Cleanup**:\n  - ✅ DO: Check for and remove references to non-existent tasks\n  - ✅ DO: Check for and remove self-references\n  - ✅ DO: Track and report changes made during cleanup\n\n  ```javascript\n  // ✅ DO: Filter invalid task dependencies\n  task.dependencies = task.dependencies.filter(depId => {\n    const numericId = typeof depId === 'string' ? parseInt(depId, 10) : depId;\n    if (!validTaskIds.has(numericId)) {\n      log('warn', `Removing invalid task dependency from task ${task.id}: ${depId} (task does not exist)`);\n      return false;\n    }\n    return true;\n  });\n  ```\n\n## Dependency Visualization\n\n- **Status Indicators**:\n  - ✅ DO: Use visual indicators to show dependency status (✅/⏱️)\n  - ✅ DO: Format dependency lists consistently\n\n  ```javascript\n  // ✅ DO: Format dependencies with status indicators\n  function formatDependenciesWithStatus(dependencies, allTasks) {\n    if (!dependencies || dependencies.length === 0) {\n      return 'None';\n    }\n    \n    return dependencies.map(depId => {\n      const depTask = findTaskById(allTasks, depId);\n      if (!depTask) return `${depId} (Not found)`;\n      \n      const isDone = depTask.status === 'done' || depTask.status === 'completed';\n      const statusIcon = isDone ? '✅' : '⏱️';\n      \n      return `${statusIcon} ${depId} (${depTask.status})`;\n    }).join(', ');\n  }\n  ```\n\n## Cycle Detection\n\n- **Graph Traversal**:\n  - ✅ DO: Use depth-first search (DFS) for cycle detection\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Support both task and subtask dependencies\n\n  ```javascript\n  // ✅ DO: Use proper cycle detection algorithms\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set()) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    \n    const cyclesToBreak = [];\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    for (const depId of dependencies) {\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack);\n        cyclesToBreak.push(...cycles);\n      } \n      else if (recursionStack.has(depId)) {\n        // Found a cycle, add the edge to break\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\nRefer to [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/dev_workflow.mdc":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*",".cursor/rules/git_workflow.mdc":"---\ndescription: Git workflow integrated with Task Master for feature development and collaboration\nglobs: \"**/*\"\nalwaysApply: true\n---\n# Git Workflow with Task Master Integration\n\n## **Branch Strategy**\n\n### **Main Branch Protection**\n- **main** branch contains production-ready code\n- All feature development happens on task-specific branches\n- Direct commits to main are prohibited\n- All changes merge via Pull Requests\n\n### **Task Branch Naming**\n```bash\n# ✅ DO: Use consistent task branch naming\ntask-001  # For Task 1\ntask-004  # For Task 4\ntask-015  # For Task 15\n\n# ❌ DON'T: Use inconsistent naming\nfeature/user-auth\nfix-database-issue\nrandom-branch-name\n```\n\n## **Tagged Task Lists Integration**\n\nTask Master's **tagged task lists system** provides significant benefits for Git workflows:\n\n### **Multi-Context Development**\n- **Branch-Specific Tasks**: Each branch can have its own task context using tags\n- **Merge Conflict Prevention**: Tasks in different tags are completely isolated\n- **Context Switching**: Seamlessly switch between different development contexts\n- **Parallel Development**: Multiple team members can work on separate task contexts\n\n### **Migration and Compatibility**\n- **Seamless Migration**: Existing projects automatically migrate to use a \"master\" tag\n- **Zero Disruption**: All existing Git workflows continue unchanged\n- **Backward Compatibility**: Legacy projects work exactly as before\n\n### **Manual Git Integration**\n- **Manual Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Switching**: Explicitly switch tag contexts as needed for different branches\n- **Simplified Integration**: Focused on manual control rather than automatic workflows\n\n## **Workflow Overview**\n\n```mermaid\nflowchart TD\n    A[Start: On main branch] --> B[Pull latest changes]\n    B --> C[Create task branch<br/>git checkout -b task-XXX]\n    C --> D[Set task status: in-progress]\n    D --> E[Get task context & expand if needed<br/>Tasks automatically use current tag]\n    E --> F[Identify next subtask]\n    \n    F --> G[Set subtask: in-progress]\n    G --> H[Research & collect context<br/>update_subtask with findings]\n    H --> I[Implement subtask]\n    I --> J[Update subtask with completion]\n    J --> K[Set subtask: done]\n    K --> L[Git commit subtask]\n    \n    L --> M{More subtasks?}\n    M -->|Yes| F\n    M -->|No| N[Run final tests]\n    \n    N --> O[Commit tests if added]\n    O --> P[Push task branch]\n    P --> Q[Create Pull Request]\n    Q --> R[Human review & merge]\n    R --> S[Switch to main & pull]\n    S --> T[Delete task branch]\n    T --> U[Ready for next task]\n    \n    style A fill:#e1f5fe\n    style C fill:#f3e5f5\n    style G fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n    style R fill:#f1f8e9\n    style U fill:#e1f5fe\n```\n\n## **Complete Task Development Workflow**\n\n### **Phase 1: Task Preparation**\n```bash\n# 1. Ensure you're on main branch and pull latest\ngit checkout main\ngit pull origin main\n\n# 2. Check current branch status\ngit branch  # Verify you're on main\n\n# 3. Create task-specific branch\ngit checkout -b task-004  # For Task 4\n\n# 4. Set task status in Task Master (tasks automatically use current tag context)\n# Use: set_task_status tool or `task-master set-status --id=4 --status=in-progress`\n```\n\n### **Phase 2: Task Analysis & Planning**\n```bash\n# 5. Get task context and expand if needed (uses current tag automatically)\n# Use: get_task tool or `task-master show 4`\n# Use: expand_task tool or `task-master expand --id=4 --research --force` (if complex)\n\n# 6. Identify next subtask to work on\n# Use: next_task tool or `task-master next`\n```\n\n### **Phase 3: Subtask Implementation Loop**\nFor each subtask, follow this pattern:\n\n```bash\n# 7. Mark subtask as in-progress\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=in-progress`\n\n# 8. Gather context and research (if needed)\n# Use: update_subtask tool with research flag or:\n# `task-master update-subtask --id=4.1 --prompt=\"Research findings...\" --research`\n\n# 9. Collect code context through AI exploration\n# Document findings in subtask using update_subtask\n\n# 10. Implement the subtask\n# Write code, tests, documentation\n\n# 11. Update subtask with completion details\n# Use: update_subtask tool or:\n# `task-master update-subtask --id=4.1 --prompt=\"Implementation complete...\"`\n\n# 12. Mark subtask as done\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=done`\n\n# 13. Commit the subtask implementation\ngit add .\ngit commit -m \"feat(task-4): Complete subtask 4.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Any important notes\n\nSubtask 4.1: [Brief description of what was accomplished]\nRelates to Task 4: [Main task title]\"\n```\n\n### **Phase 4: Task Completion**\n```bash\n# 14. When all subtasks are complete, run final testing\n# Create test file if needed, ensure all tests pass\nnpm test  # or jest, or manual testing\n\n# 15. If tests were added/modified, commit them\ngit add .\ngit commit -m \"test(task-4): Add comprehensive tests for Task 4\n\n- Unit tests for core functionality\n- Integration tests for API endpoints\n- All tests passing\n\nTask 4: [Main task title] - Testing complete\"\n\n# 16. Push the task branch\ngit push origin task-004\n\n# 17. Create Pull Request\n# Title: \"Task 4: [Task Title]\"\n# Description should include:\n# - Task overview\n# - Subtasks completed\n# - Testing approach\n# - Any breaking changes or considerations\n```\n\n### **Phase 5: PR Merge & Cleanup**\n```bash\n# 18. Human reviews and merges PR into main\n\n# 19. Switch back to main and pull merged changes\ngit checkout main\ngit pull origin main\n\n# 20. Delete the feature branch (optional cleanup)\ngit branch -d task-004\ngit push origin --delete task-004\n```\n\n## **Commit Message Standards**\n\n### **Subtask Commits**\n```bash\n# ✅ DO: Consistent subtask commit format\ngit commit -m \"feat(task-4): Complete subtask 4.1 - Initialize Express server\n\n- Set up Express.js with TypeScript configuration\n- Added CORS and body parsing middleware\n- Implemented health check endpoints\n- Basic error handling middleware\n\nSubtask 4.1: Initialize project with npm and install dependencies\nRelates to Task 4: Setup Express.js Server Project\"\n\n# ❌ DON'T: Vague or inconsistent commits\ngit commit -m \"fixed stuff\"\ngit commit -m \"working on task\"\n```\n\n### **Test Commits**\n```bash\n# ✅ DO: Separate test commits when substantial\ngit commit -m \"test(task-4): Add comprehensive tests for Express server setup\n\n- Unit tests for middleware configuration\n- Integration tests for health check endpoints\n- Mock tests for database connection\n- All tests passing with 95% coverage\n\nTask 4: Setup Express.js Server Project - Testing complete\"\n```\n\n### **Commit Type Prefixes**\n- `feat(task-X):` - New feature implementation\n- `fix(task-X):` - Bug fixes\n- `test(task-X):` - Test additions/modifications\n- `docs(task-X):` - Documentation updates\n- `refactor(task-X):` - Code refactoring\n- `chore(task-X):` - Build/tooling changes\n\n## **Task Master Commands Integration**\n\n### **Essential Commands for Git Workflow**\n```bash\n# Task management (uses current tag context automatically)\ntask-master show <id>           # Get task/subtask details\ntask-master next                # Find next task to work on\ntask-master set-status --id=<id> --status=<status>\ntask-master update-subtask --id=<id> --prompt=\"...\" --research\n\n# Task expansion (for complex tasks)\ntask-master expand --id=<id> --research --force\n\n# Progress tracking\ntask-master list                # View all tasks and status\ntask-master list --status=in-progress  # View active tasks\n```\n\n### **MCP Tool Equivalents**\nWhen using Cursor or other MCP-integrated tools:\n- `get_task` instead of `task-master show`\n- `next_task` instead of `task-master next`\n- `set_task_status` instead of `task-master set-status`\n- `update_subtask` instead of `task-master update-subtask`\n\n## **Branch Management Rules**\n\n### **Branch Protection**\n```bash\n# ✅ DO: Always work on task branches\ngit checkout -b task-005\n# Make changes\ngit commit -m \"...\"\ngit push origin task-005\n\n# ❌ DON'T: Commit directly to main\ngit checkout main\ngit commit -m \"...\"  # NEVER do this\n```\n\n### **Keeping Branches Updated**\n```bash\n# ✅ DO: Regularly sync with main (for long-running tasks)\ngit checkout task-005\ngit fetch origin\ngit rebase origin/main  # or merge if preferred\n\n# Resolve any conflicts and continue\n```\n\n## **Pull Request Guidelines**\n\n### **PR Title Format**\n```\nTask <ID>: <Task Title>\n\nExamples:\nTask 4: Setup Express.js Server Project\nTask 7: Implement User Authentication\nTask 12: Add Stripe Payment Integration\n```\n\n### **PR Description Template**\n```markdown\n## Task Overview\nBrief description of the main task objective.\n\n## Subtasks Completed\n- [x] 4.1: Initialize project with npm and install dependencies\n- [x] 4.2: Configure TypeScript, ESLint and Prettier  \n- [x] 4.3: Create basic Express app with middleware and health check route\n\n## Implementation Details\n- Key architectural decisions made\n- Important code changes\n- Any deviations from original plan\n\n## Testing\n- [ ] Unit tests added/updated\n- [ ] Integration tests passing\n- [ ] Manual testing completed\n\n## Breaking Changes\nList any breaking changes or migration requirements.\n\n## Related Tasks\nMention any dependent tasks or follow-up work needed.\n```\n\n## **Conflict Resolution**\n\n### **Task Conflicts with Tagged System**\n```bash\n# With tagged task lists, merge conflicts are significantly reduced:\n# 1. Different branches can use different tag contexts\n# 2. Tasks in separate tags are completely isolated\n# 3. Use Task Master's move functionality to reorganize if needed\n\n# Manual git integration available:\n# - Use `task-master add-tag --from-branch` to create tags from current branch\n# - Manually switch contexts with `task-master use-tag <name>`\n# - Simple, predictable workflow without automatic behavior\n```\n\n### **Code Conflicts**\n```bash\n# Standard Git conflict resolution\ngit fetch origin\ngit rebase origin/main\n# Resolve conflicts in files\ngit add .\ngit rebase --continue\n```\n\n## **Emergency Procedures**\n\n### **Hotfixes**\n```bash\n# For urgent production fixes:\ngit checkout main\ngit pull origin main\ngit checkout -b hotfix-urgent-issue\n\n# Make minimal fix\ngit commit -m \"hotfix: Fix critical production issue\n\n- Specific fix description\n- Minimal impact change\n- Requires immediate deployment\"\n\ngit push origin hotfix-urgent-issue\n# Create emergency PR for immediate review\n```\n\n### **Task Abandonment**\n```bash\n# If task needs to be abandoned or significantly changed:\n# 1. Update task status\ntask-master set-status --id=<id> --status=cancelled\n\n# 2. Clean up branch\ngit checkout main\ngit branch -D task-<id>\ngit push origin --delete task-<id>\n\n# 3. Document reasoning in task\ntask-master update-task --id=<id> --prompt=\"Task cancelled due to...\"\n```\n\n## **Tagged System Benefits for Git Workflows**\n\n### **Multi-Team Development**\n- **Isolated Contexts**: Different teams can work on separate tag contexts without conflicts\n- **Feature Branches**: Each feature branch can have its own task context\n- **Release Management**: Separate tags for different release versions or environments\n\n### **Merge Conflict Prevention**\n- **Context Separation**: Tasks in different tags don't interfere with each other\n- **Clean Merges**: Reduced likelihood of task-related merge conflicts\n- **Parallel Development**: Multiple developers can work simultaneously without task conflicts\n\n### **Manual Git Integration**\n- **Branch-Based Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Management**: Explicitly switch tag contexts as needed\n- **Predictable Workflow**: Simple, manual control without automatic behavior\n\n---\n\n**References:**\n- [Task Master Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Architecture Guidelines](mdc:.cursor/rules/architecture.mdc)\n- [Task Master Commands](mdc:.cursor/rules/taskmaster.mdc)\n",".cursor/rules/glossary.mdc":"---\ndescription: Glossary of other Cursor rules\nglobs: **/*\nalwaysApply: true\n---\n# Glossary of Task Master Cursor Rules\n\nThis file provides a quick reference to the purpose of each rule file located in the `.cursor/rules` directory.\n\n- **[`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)**: Describes the high-level architecture of the Task Master CLI application, including the new tagged task lists system.\n- **[`changeset.mdc`](mdc:.cursor/rules/changeset.mdc)**: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\n- **[`commands.mdc`](mdc:.cursor/rules/commands.mdc)**: Guidelines for implementing CLI commands using Commander.js.\n- **[`cursor_rules.mdc`](mdc:.cursor/rules/cursor_rules.mdc)**: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\n- **[`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc)**: Guidelines for managing task dependencies and relationships across tagged task contexts.\n- **[`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc)**: Guide for using Task Master to manage task-driven development workflows with tagged task lists support.\n- **[`glossary.mdc`](mdc:.cursor/rules/glossary.mdc)**: This file; provides a glossary of other Cursor rules.\n- **[`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)**: Guidelines for implementing and interacting with the Task Master MCP Server.\n- **[`new_features.mdc`](mdc:.cursor/rules/new_features.mdc)**: Guidelines for integrating new features into the Task Master CLI with tagged system considerations.\n- **[`self_improve.mdc`](mdc:.cursor/rules/self_improve.mdc)**: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\n- **[`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)**: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information.\n- **[`tasks.mdc`](mdc:.cursor/rules/tasks.mdc)**: Guidelines for implementing task management operations with tagged task lists system support.\n- **[`tests.mdc`](mdc:.cursor/rules/tests.mdc)**: Guidelines for implementing and maintaining tests for Task Master CLI.\n- **[`ui.mdc`](mdc:.cursor/rules/ui.mdc)**: Guidelines for implementing and maintaining user interface components.\n- **[`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)**: Guidelines for implementing utility functions including tagged task lists utilities.\n- **[`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc)**: Guidelines for integrating AI usage telemetry across Task Master.\n\n",".cursor/rules/hamster.mdc":"---\ndescription: Guidelines for implementing tasks imported from Hamster using Task Master CLI\nglobs: \"**/*\"\nalwaysApply: true\n---\n\n# Hamster Integration Workflow\n\nThis guide outlines the process for working with tasks imported from Hamster briefs using Task Master. When connected to a Hamster brief, follow these specific guidelines to ensure proper task management and workflow execution.\n\n## **Command Restrictions**\n\n### **Supported Commands**\n- **✅ DO**: Use only these Task Master CLI commands when working with Hamster briefs:\n  ```bash\n  tm list                      # List all tasks\n  tm show <sub/task id> --json # Show task details\n  tm set-status                # Update task status\n  tm auth refresh              # Refresh authentication token\n  tm context <brief url>       # Reconnect to Hamster brief context\n  ```\n\n### **Unsupported Commands**\n- **❌ DON'T**: Use MCP tools when connected with Hamster briefs - they are not yet up to date with Hamster integration\n- **❌ DON'T**: Use other Task Master CLI commands that haven't been verified to work with Hamster integration\n\n## **Task Workflow Process**\n\n### **Starting a Task**\n```bash\n# ✅ DO: Mark task and subtasks as in-progress when starting\ntm set-status -i 1,1.1 -s in-progress\n\n# Multiple tasks/subtasks can be marked at once using comma separation\ntm set-status -i 1,1.1,1.2,2 -s in-progress\n```\n\n### **Task Implementation Flow**\n1. **Read the Task**: Use `tm show <id> --json` to understand the task requirements (json used to save tokens, gets you same information)\n2. **Check for Subtasks**: If the task has subtasks, implement them one at a time\n3. **Implement Subtask**: Complete the subtask implementation\n4. **Verify Quality**: Run lint and typecheck before marking as done\n   ```bash\n   npm lint\n   npm typecheck\n   ```\n5. **Mark Complete**: If verification passes, mark the subtask as done\n   ```bash\n   tm set-status -i 1.1 -s done\n   ```\n6. **Commit Changes**: Commit the completed subtask work\n7. **Repeat**: Continue until all subtasks are complete\n\n### **Parent Task Completion**\n- After all subtasks are done, run final verification:\n  ```bash\n  npm lint\n  npm typecheck\n  ```\n- Mark the parent task as done:\n  ```bash\n  tm set-status -i 1 -s done\n  ```\n- Move to the next task and repeat the process\n\n## **Multiple Task Context**\n\n### **Viewing Multiple Tasks**\n```bash\n# ✅ DO: Use comma-separated IDs to get context from multiple tasks\ntm show 1,1.1,2,2.1 --json\n\n# This is more efficient than calling tm show multiple times\n```\n\n### **Parallel Subtask Execution**\n- **When to Parallelize**: If a task has subtasks that can be completed in parallel\n- **Requirements**:\n  - Ensure work/files to adjust are **not the same** across subtasks\n  - Spawn sub-agents for each parallel subtask\n  - Verify clear separation of work before parallelizing\n- **Example**: If subtask 1.1 modifies `src/api.js` and subtask 1.2 modifies `src/utils.js`, these can run in parallel\n\n## **Pull Request Management**\n\n### **PR Creation Strategy**\n- **Preferred Approach**: Keep everything in one PR if scope remains manageable\n- **When to Split**: Create separate PRs if the work becomes too large\n- **Multi-PR Strategy**: If splitting is necessary:\n  - Create PRs that build on top of previous ones\n  - **Always confirm with the human** before creating multiple PRs\n- **PR Creation**: Use GitHub CLI after completing a task:\n  ```bash\n  gh pr create --title \"Task X: [Task Title]\" --body \"Description\"\n  ```\n\n### **Committing to PRs**\n- Keep committing to the same PR as long as the scope is maintained\n- An entire task list (brief) might fit into a single PR\n- If scope grows too large, discuss with human before creating new PRs\n\n## **Authentication & Context Management**\n\n### **Token Refresh**\n```bash\n# ✅ DO: Refresh token if JWT seems expired or commands don't work\ntm auth refresh\n\n# If refresh doesn't work, reconnect context\ntm context <brief url>\n```\n\n### **Context Reconnection**\n- **When Needed**: If commands stop working or authentication fails\n- **Required Information**: Brief URL (ask user if not available)\n- **Best Practice**: Store brief URL at the beginning of the session\n- **Command**: `tm context <brief url>`\n\n## **Integration with Git Workflow**\n\nWhen working with Hamster briefs, follow the standard Git workflow patterns outlined in [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc):\n\n- Create task-specific branches: `task-XXX`\n- Commit subtask work incrementally\n- Create PRs after task completion\n- Follow commit message standards\n\n## **Workflow Summary**\n\n```mermaid\nflowchart TD\n    A[Start: Connect to Hamster Brief] --> B[Get Brief URL]\n    B --> C[tm list - View Tasks]\n    C --> D[Select Task]\n    D --> E[tm show <id> --json - Read Task]\n    E --> F{Has Subtasks?}\n    F -->|Yes| G[Select First Subtask]\n    F -->|No| M[Implement Task]\n    G --> H[tm set-status -i X.Y -s in-progress]\n    H --> I[Implement Subtask]\n    I --> J[npm lint && npm typecheck]\n    J --> K{Passes?}\n    K -->|Yes| L[tm set-status -i X.Y -s done]\n    K -->|No| I\n    L --> N{More Subtasks?}\n    N -->|Yes| G\n    N -->|No| O[Final lint/typecheck]\n    M --> O\n    O --> P[tm set-status -i X -s done]\n    P --> Q[Commit & Create PR]\n    Q --> R{More Tasks?}\n    R -->|Yes| D\n    R -->|No| S[Complete]\n    \n    style A fill:#e1f5fe\n    style H fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n```\n\n## **Key Principles**\n\n- **Incremental Progress**: Work through subtasks one at a time\n- **Quality Gates**: Always run lint and typecheck before marking tasks as done\n- **Clear Communication**: Confirm with human before splitting work across multiple PRs\n- **Efficient Context Gathering**: Use comma-separated IDs when viewing multiple tasks\n- **Authentication Management**: Proactively refresh tokens and reconnect context when needed\n\n## **Related Rules**\n\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - Standard Git branching and PR practices\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - General Task Master development patterns\n- [Task Management](mdc:.cursor/rules/tasks.mdc) - Task structure and operations\n",".cursor/rules/mcp.mdc":"---\ndescription: Guidelines for implementing and interacting with the Task Master MCP Server\nglobs: mcp-server/src/**/*, scripts/modules/**/*\nalwaysApply: false\n---\n# Task Master MCP Server Guidelines\n\nThis document outlines the architecture and implementation patterns for the Task Master Model Context Protocol (MCP) server, designed for integration with tools like Cursor.\n\n## Architecture Overview (See also: [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc))\n\nThe MCP server acts as a bridge between external tools (like Cursor) and the core Task Master CLI logic. It leverages FastMCP for the server framework.\n\n- **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/direct-functions/*.js`, exported via `task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`)\n- **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation.\n\n## Direct Function Implementation Best Practices\n\nWhen implementing a new direct function in `mcp-server/src/core/direct-functions/`, follow these critical guidelines:\n\n1. **Verify Function Dependencies**:\n   - ✅ **DO**: Check that all helper functions your direct function needs are properly exported from their source modules\n   - ✅ **DO**: Import these dependencies explicitly at the top of your file\n   - ❌ **DON'T**: Assume helper functions like `findTaskById` or `taskExists` are automatically available\n   - **Example**:\n     ```javascript\n     // At top of direct-function file\n     import { removeTask, findTaskById, taskExists } from '../../../../scripts/modules/task-manager.js';\n     ```\n\n2. **Parameter Verification and Completeness**:\n   - ✅ **DO**: Verify the signature of core functions you're calling and ensure all required parameters are provided\n   - ✅ **DO**: Pass explicit values for required parameters rather than relying on defaults\n   - ✅ **DO**: Double-check parameter order against function definition\n   - ❌ **DON'T**: Omit parameters assuming they have default values\n   - **Example**:\n     ```javascript\n     // Correct parameter handling in direct function\n     async function generateTaskFilesDirect(args, log) {\n       const tasksPath = findTasksJsonPath(args, log);\n       const outputDir = args.output || path.dirname(tasksPath);\n       \n       try {\n         // Pass all required parameters\n         const result = await generateTaskFiles(tasksPath, outputDir);\n         return { success: true, data: result, fromCache: false };\n       } catch (error) {\n         // Error handling...\n       }\n     }\n     ```\n\n3. **Consistent File Path Handling**:\n   - ✅ **DO**: Use `path.join()` instead of string concatenation for file paths\n   - ✅ **DO**: Follow established file naming conventions (`task_001.txt` not `1.md`)\n   - ✅ **DO**: Use `path.dirname()` and other path utilities for manipulating paths\n   - ✅ **DO**: When paths relate to task files, follow the standard format: `task_${id.toString().padStart(3, '0')}.txt`\n   - ❌ **DON'T**: Create custom file path handling logic that diverges from established patterns\n   - **Example**:\n     ```javascript\n     // Correct file path handling\n     const taskFilePath = path.join(\n       path.dirname(tasksPath),\n       `task_${taskId.toString().padStart(3, '0')}.txt`\n     );\n     ```\n\n4. **Comprehensive Error Handling**:\n   - ✅ **DO**: Wrap core function calls *and AI calls* in try/catch blocks\n   - ✅ **DO**: Log errors with appropriate severity and context\n   - ✅ **DO**: Return standardized error objects with code and message (`{ success: false, error: { code: '...', message: '...' } }`)\n   - ✅ **DO**: Handle file system errors, AI client errors, AI processing errors, and core function errors distinctly with appropriate codes.\n   - **Example**:\n     ```javascript\n     try {\n       // Core function call or AI logic\n     } catch (error) {\n       log.error(`Failed to execute direct function logic: ${error.message}`);\n       return {\n         success: false,\n         error: {\n           code: error.code || 'DIRECT_FUNCTION_ERROR', // Use specific codes like AI_CLIENT_ERROR, etc.\n           message: error.message,\n           details: error.stack // Optional: Include stack in debug mode\n         },\n         fromCache: false // Ensure this is included if applicable\n       };\n     }\n     ```\n\n5. **Handling Logging Context (`mcpLog`)**:\n   - **Requirement**: Core functions (like those in `task-manager.js`) may accept an `options` object containing an optional `mcpLog` property. If provided, the core function expects this object to have methods like `mcpLog.info(...)`, `mcpLog.error(...)`.\n   - **Solution: The Logger Wrapper Pattern**: When calling a core function from a direct function, pass the `log` object provided by FastMCP *wrapped* in the standard `logWrapper` object. This ensures the core function receives a logger with the expected method structure.\n     ```javascript\n     // Standard logWrapper pattern within a Direct Function\n     const logWrapper = {\n       info: (message, ...args) => log.info(message, ...args),\n       warn: (message, ...args) => log.warn(message, ...args),\n       error: (message, ...args) => log.error(message, ...args),\n       debug: (message, ...args) => log.debug && log.debug(message, ...args),\n       success: (message, ...args) => log.info(message, ...args)\n     };\n\n     // ... later when calling the core function ...\n     await coreFunction(\n       // ... other arguments ...\n       { \n         mcpLog: logWrapper, // Pass the wrapper object\n         session // Also pass session if needed by core logic or AI service\n       },\n       'json' // Pass 'json' output format if supported by core function\n     );\n     ```\n   - **JSON Output**: Passing `mcpLog` (via the wrapper) often triggers the core function to use a JSON-friendly output format, suppressing spinners/boxes.\n   - ✅ **DO**: Implement this pattern in direct functions calling core functions that might use `mcpLog`.\n\n6. **Silent Mode Implementation**:\n    - ✅ **DO**: Import silent mode utilities: `import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';`\n    - ✅ **DO**: Wrap core function calls *within direct functions* using `enableSilentMode()` / `disableSilentMode()` in a `try/finally` block if the core function might produce console output (spinners, boxes, direct `console.log`) that isn't reliably controlled by passing `{ mcpLog }` or an `outputFormat` parameter.\n    - ✅ **DO**: Always disable silent mode in the `finally` block.\n    - ❌ **DON'T**: Wrap calls to the unified AI service (`generateTextService`, `generateObjectService`) in silent mode; their logging is handled internally.\n    - **Example (Direct Function Guaranteeing Silence & using Log Wrapper)**:\n      ```javascript\n      export async function coreWrapperDirect(args, log, context = {}) {\n        const { session } = context;\n        const tasksPath = findTasksJsonPath(args, log);\n        const logWrapper = { /* ... */ };\n\n        enableSilentMode(); // Ensure silence for direct console output\n        try {\n          const result = await coreFunction(\n             tasksPath,\n             args.param1,\n             { mcpLog: logWrapper, session }, // Pass context\n             'json' // Request JSON format if supported\n          );\n          return { success: true, data: result };\n        } catch (error) {\n           log.error(`Error: ${error.message}`);\n           return { success: false, error: { /* ... */ } };\n        } finally {\n           disableSilentMode(); // Critical: Always disable in finally\n        }\n      }\n      ```\n\n7. **Debugging MCP/Core Logic Interaction**:\n    - ✅ **DO**: If an MCP tool fails with unclear errors (like JSON parsing failures), run the equivalent `task-master` CLI command in the terminal. The CLI often provides more detailed error messages originating from the core logic (e.g., `ReferenceError`, stack traces) that are obscured by the MCP layer.\n\n## Tool Definition and Execution\n\n### Tool Structure\n\nMCP tools must follow a specific structure to properly interact with the FastMCP framework:\n\n```javascript\nserver.addTool({\n  name: \"tool_name\",  // Use snake_case for tool names\n  description: \"Description of what the tool does\",\n  parameters: z.object({\n    // Define parameters using Zod\n    param1: z.string().describe(\"Parameter description\"),\n    param2: z.number().optional().describe(\"Optional parameter description\"),\n    // IMPORTANT: For file operations, always include these optional parameters\n    file: z.string().optional().describe(\"Path to the tasks file\"),\n    projectRoot: z.string().optional().describe(\"Root directory of the project (typically derived from session)\")\n  }),\n\n  // The execute function is the core of the tool implementation\n  execute: async (args, context) => {\n    // Implementation goes here\n    // Return response in the appropriate format\n  }\n});\n```\n\n### Execute Function Signature\n\nThe `execute` function receives validated arguments and the FastMCP context:\n\n```javascript\n// Destructured signature (recommended)\nexecute: async (args, { log, session }) => {\n  // Tool implementation\n}\n```\n\n- **args**: Validated parameters.\n- **context**: Contains `{ log, session }` from FastMCP. (Removed `reportProgress`).\n\n### Standard Tool Execution Pattern with Path Normalization (Updated)\n\nTo ensure consistent handling of project paths across different client environments (Windows, macOS, Linux, WSL) and input formats (e.g., `file:///...`, URI encoded paths), all MCP tool `execute` methods that require access to the project root **MUST** be wrapped with the `withNormalizedProjectRoot` Higher-Order Function (HOF).\n\nThis HOF, defined in [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js), performs the following before calling the tool's core logic:\n\n1.  **Determines the Raw Root:** It prioritizes `args.projectRoot` if provided by the client, otherwise it calls `getRawProjectRootFromSession` to extract the path from the session.\n2.  **Normalizes the Path:** It uses the `normalizeProjectRoot` helper to decode URIs, strip `file://` prefixes, fix potential Windows drive letter prefixes (e.g., `/C:/`), convert backslashes (`\\`) to forward slashes (`/`), and resolve the path to an absolute path suitable for the server's OS.\n3.  **Injects Normalized Path:** It updates the `args` object by replacing the original `projectRoot` (or adding it) with the normalized, absolute path.\n4.  **Executes Original Logic:** It calls the original `execute` function body, passing the updated `args` object.\n\n**Implementation Example:**\n\n```javascript\n// In mcp-server/src/tools/your-tool.js\nimport {\n    handleApiResult,\n    createErrorResponse,\n    withNormalizedProjectRoot // <<< Import HOF\n} from './utils.js';\nimport { yourDirectFunction } from '../core/task-master-core.js';\nimport { findTasksJsonPath } from '../core/utils/path-utils.js'; // If needed\n\nexport function registerYourTool(server) {\n    server.addTool({\n        name: \"your_tool\",\n        description: \"...\".\n        parameters: z.object({\n            // ... other parameters ...\n            projectRoot: z.string().optional().describe('...') // projectRoot is optional here, HOF handles fallback\n        }),\n        // Wrap the entire execute function\n        execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n            // args.projectRoot is now guaranteed to be normalized and absolute\n            const { /* other args */, projectRoot } = args;\n\n            try {\n                log.info(`Executing your_tool with normalized root: ${projectRoot}`);\n\n                // Resolve paths using the normalized projectRoot\n                let tasksPath = findTasksJsonPath({ projectRoot, file: args.file }, log);\n\n                // Call direct function, passing normalized projectRoot if needed by direct func\n                const result = await yourDirectFunction(\n                    {\n                        /* other args */,\n                        projectRoot // Pass it if direct function needs it\n                    },\n                    log,\n                    { session }\n                );\n\n                return handleApiResult(result, log);\n            } catch (error) {\n                log.error(`Error in your_tool: ${error.message}`);\n                return createErrorResponse(error.message);\n            }\n        }) // End HOF wrap\n    });\n}\n```\n\nBy using this HOF, the core logic within the `execute` method and any downstream functions (like `findTasksJsonPath` or direct functions) can reliably expect `args.projectRoot` to be a clean, absolute path suitable for the server environment.\n\n### Project Initialization Tool\n\nThe `initialize_project` tool allows integrated clients like Cursor to set up a new Task Master project:\n\n```javascript\n// In initialize-project.js\nimport { z } from \"zod\";\nimport { initializeProjectDirect } from \"../core/task-master-core.js\";\nimport { handleApiResult, createErrorResponse } from \"./utils.js\";\n\nexport function registerInitializeProjectTool(server) {\n  server.addTool({\n    name: \"initialize_project\",\n    description: \"Initialize a new Task Master project\",\n    parameters: z.object({\n      projectName: z.string().optional().describe(\"The name for the new project\"),\n      projectDescription: z.string().optional().describe(\"A brief description\"),\n      projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n      authorName: z.string().optional().describe(\"The author's name\"),\n      skipInstall: z.boolean().optional().describe(\"Skip installing dependencies\"),\n      addAliases: z.boolean().optional().describe(\"Add shell aliases\"),\n      yes: z.boolean().optional().describe(\"Skip prompts and use defaults\")\n    }),\n    execute: async (args, { log, reportProgress }) => {\n      try {\n        // Since we're initializing, we don't need project root\n        const result = await initializeProjectDirect(args, log);\n        return handleApiResult(result, log, 'Error initializing project');\n      } catch (error) {\n        log.error(`Error in initialize_project: ${error.message}`);\n        return createErrorResponse(`Failed to initialize project: ${error.message}`);\n      }\n    }\n  });\n}\n```\n\n### Logging Convention\n\nThe `log` object (destructured from `context`) provides standardized logging methods. Use it within both the `execute` method and the `*Direct` functions. **If progress indication is needed within a direct function, use `log.info()` instead of `reportProgress`**.\n\n```javascript\n// Proper logging usage\nlog.info(`Starting ${toolName} with parameters: ${JSON.stringify(sanitizedArgs)}`);\nlog.debug(\"Detailed operation info\", { data });\nlog.warn(\"Potential issue detected\");\nlog.error(`Error occurred: ${error.message}`, { stack: error.stack });\nlog.info('Progress: 50% - AI call initiated...'); // Example progress logging\n```\n\n## Session Usage Convention\n\nThe `session` object (destructured from `context`) contains authenticated session data and client information.\n\n- **Authentication**: Access user-specific data (`session.userId`, etc.) if authentication is implemented.\n- **Project Root**: The primary use in Task Master is accessing `session.roots` to determine the client's project root directory via the `getProjectRootFromSession` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)). See the Standard Tool Execution Pattern above.\n- **Environment Variables**: The `session.env` object provides access to environment variables set in the MCP client configuration (e.g., `.cursor/mcp.json`). This is the **primary mechanism** for the unified AI service layer (`ai-services-unified.js`) to securely access **API keys** when called from MCP context.\n- **Capabilities**: Can be used to check client capabilities (`session.clientCapabilities`).\n\n## Direct Function Wrappers (`*Direct`)\n\nThese functions, located in `mcp-server/src/core/direct-functions/`, form the core logic execution layer for MCP tools.\n\n- **Purpose**: Bridge MCP tools and core Task Master modules (`scripts/modules/*`). Handle AI interactions if applicable.\n- **Responsibilities**:\n  - Receive `args` (including `projectRoot`), `log`, and optionally `{ session }` context.\n  - Find `tasks.json` using `findTasksJsonPath`.\n  - Validate arguments.\n  - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n  - **Call Core Logic**: Invoke function from `scripts/modules/*`.\n    - Pass `outputFormat: 'json'` if applicable.\n    - Wrap with `enableSilentMode/disableSilentMode` if needed.\n    - Pass `{ mcpLog: logWrapper, session }` context if core logic needs it.\n  - Handle errors.\n  - Return standardized result object.\n  - ❌ **DON'T**: Call `reportProgress`.\n  - ❌ **DON'T**: Initialize AI clients or call AI services directly.\n\n## Key Principles\n\n- **Prefer Direct Function Calls**: MCP tools should always call `*Direct` wrappers instead of `executeTaskMasterCommand`.\n- **Standardized Execution Flow**: Follow the pattern: MCP Tool -> `getProjectRootFromSession` -> `*Direct` Function -> Core Logic / AI Logic.\n- **Path Resolution via Direct Functions**: The `*Direct` function is responsible for finding the exact `tasks.json` path using `findTasksJsonPath`, relying on the `projectRoot` passed in `args`.\n- **AI Logic in Core Modules**: AI interactions (prompt building, calling unified service) reside within the core logic functions (`scripts/modules/*`), not direct functions.\n- **Silent Mode in Direct Functions**: Wrap *core function* calls (from `scripts/modules`) with `enableSilentMode()` and `disableSilentMode()` if they produce console output not handled by `outputFormat`. Do not wrap AI calls.\n- **Selective Async Processing**: Use `AsyncOperationManager` in the *MCP Tool layer* for operations involving multiple steps or long waits beyond a single AI call (e.g., file processing + AI call + file writing). Simple AI calls handled entirely within the `*Direct` function (like `addTaskDirect`) may not need it at the tool layer.\n- **No `reportProgress` in Direct Functions**: Do not pass or use `reportProgress` within `*Direct` functions. Use `log.info()` for internal progress or report progress from the `AsyncOperationManager` callback in the MCP tool layer.\n- **Output Formatting**: Ensure core functions called by `*Direct` functions can suppress CLI output, ideally via an `outputFormat` parameter.\n- **Project Initialization**: Use the initialize_project tool for setting up new projects in integrated environments.\n- **Centralized Utilities**: Use helpers from `mcp-server/src/tools/utils.js`, `mcp-server/src/core/utils/path-utils.js`, and `mcp-server/src/core/utils/ai-client-utils.js`. See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).\n- **Caching in Direct Functions**: Caching logic resides *within* the `*Direct` functions using `getCachedOrExecute`.\n\n## Resources and Resource Templates\n\nResources provide LLMs with static or dynamic data without executing tools.\n\n- **Implementation**: Use `@mcp.resource()` decorator pattern or `server.addResource`/`server.addResourceTemplate` in `mcp-server/src/core/resources/`.\n- **Registration**: Register resources during server initialization in [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js).\n- **Best Practices**: Organize resources, validate parameters, use consistent URIs, handle errors. See [`fastmcp-core.txt`](docs/fastmcp-core.txt) for underlying SDK details.\n\n*(Self-correction: Removed detailed Resource implementation examples as they were less relevant to the current user focus on tool execution flow and project roots. Kept the overview.)*\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`. Ensure the core function can suppress console output (e.g., via an `outputFormat` parameter).\n\n2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, `findTasksJsonPath`, silent mode utilities, and potentially AI client/prompt utilities.\n    - Implement `async function yourCommandDirect(args, log, context = {})` using **camelCase** with `Direct` suffix. **Remember `context` should only contain `{ session }` if needed (for AI keys/config).**\n        - **Path Resolution**: Obtain `tasksPath` using `findTasksJsonPath(args, log)`.\n        - Parse other `args` and perform necessary validation.\n        - **Handle AI (if applicable)**: Initialize clients using `get*ClientForMCP(session, log)`, build prompts, call AI, parse response. Handle AI-specific errors.\n        - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n        - **Call Core Logic**:\n            - Wrap with `enableSilentMode/disableSilentMode` if necessary.\n            - Pass `outputFormat: 'json'` (or similar) if applicable.\n            - Handle errors from the core function.\n        - Format the return as `{ success: true/false, data/error, fromCache?: boolean }`.\n        - ❌ **DON'T**: Call `reportProgress`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, `createErrorResponse`, `getProjectRootFromSession`, and your `yourCommandDirect` function. Import `AsyncOperationManager` if needed.\n    - Implement `registerYourCommandTool(server)`.\n    - Define the tool `name` using **snake_case** (e.g., `your_command`).\n    - Define the `parameters` using `zod`. Include `projectRoot: z.string().optional()`.\n    - Implement the `async execute(args, { log, session })` method (omitting `reportProgress` from destructuring).\n        - Get `rootFolder` using `getProjectRootFromSession(session, log)`.\n        - **Determine Execution Strategy**:\n            - **If using `AsyncOperationManager`**: Create the operation, call the `*Direct` function from within the async task callback (passing `log` and `{ session }`), report progress *from the callback*, and return the initial `ACCEPTED` response.\n            - **If calling `*Direct` function synchronously** (like `add-task`): Call `await yourCommandDirect({ ...args, projectRoot }, log, { session });`. Handle the result with `handleApiResult`.\n        - ❌ **DON'T**: Pass `reportProgress` down to the direct function in either case.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Handling Responses\n\n- MCP tools should return the object generated by `handleApiResult`.\n- `handleApiResult` uses `createContentResponse` or `createErrorResponse` internally.\n- `handleApiResult` also uses `processMCPResponseData` by default to filter potentially large fields (`details`, `testStrategy`) from task data. Provide a custom processor function to `handleApiResult` if different filtering is needed.\n- The final JSON response sent to the MCP client will include the `fromCache` boolean flag (obtained from the `*Direct` function's result) alongside the actual data (e.g., `{ \"fromCache\": true, \"data\": { ... } }` or `{ \"fromCache\": false, \"data\": { ... } }`).\n\n## Parameter Type Handling\n\n- **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n- **Standard Tool Execution Pattern**:\n    - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should:\n        1.  Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger.\n        2.  Receive the result object (typically `{ success, data/error, fromCache }`).\n        3.  Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized response formatting and error handling.\n        4.  Return the formatted response object provided by `handleApiResult`.\n- **CLI Execution as Fallback**: The `executeTaskMasterCommand` utility in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) allows executing commands via the CLI (`task-master ...`). This should **only** be used as a fallback if a direct function wrapper is not yet implemented or if a specific command intrinsically requires CLI execution.\n- **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n    - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently.\n    - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation:\n        - `getProjectRoot`: Normalizes project paths.\n        - `handleApiResult`: Takes the raw result from a `*Direct` function and formats it into a standard MCP success or error response, automatically handling data processing via `processMCPResponseData`. This is called by the tool's `execute` method.\n        - `createContentResponse`/`createErrorResponse`: Used by `handleApiResult` to format successful/error MCP responses.\n        - `processMCPResponseData`: Filters/cleans data (e.g., removing `details`, `testStrategy`) before it's sent in the MCP response. Called by `handleApiResult`.\n        - `getCachedOrExecute`: **Used inside `*Direct` functions** in `task-master-core.js` to implement caching logic.\n        - `executeTaskMasterCommand`: Fallback for executing CLI commands.\n- **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented.\n    - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) using the `getCachedOrExecute` utility from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    - Generate unique cache keys based on function arguments that define a distinct call (e.g., file path, filters).\n    - The `getCachedOrExecute` utility handles checking the cache, executing the core logic function on a cache miss, storing the result, and returning the data along with a `fromCache` flag.\n    - Cache statistics can be monitored using the `cacheStats` MCP tool (implemented via `getCacheStatsDirect`).\n    - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data.\n\n**MCP Tool Implementation Checklist**:\n\n1. **Core Logic Verification**:\n   - [ ] Confirm the core function is properly exported from its module (e.g., `task-manager.js`)\n   - [ ] Identify all required parameters and their types\n\n2. **Direct Function Wrapper**:\n   - [ ] Create the `*Direct` function in the appropriate file in `mcp-server/src/core/direct-functions/`\n   - [ ] Import silent mode utilities and implement them around core function calls\n   - [ ] Handle all parameter validations and type conversions\n   - [ ] Implement path resolving for relative paths\n   - [ ] Add appropriate error handling with standardized error codes\n   - [ ] Add to imports/exports in `task-master-core.js`\n\n3. **MCP Tool Implementation**:\n   - [ ] Create new file in `mcp-server/src/tools/` with kebab-case naming\n   - [ ] Define zod schema for all parameters\n   - [ ] Implement the `execute` method following the standard pattern\n   - [ ] Consider using AsyncOperationManager for long-running operations\n   - [ ] Register tool in `mcp-server/src/tools/index.js`\n\n4. **Testing**:\n   - [ ] Write unit tests for the direct function wrapper\n   - [ ] Write integration tests for the MCP tool\n\n## Standard Error Codes\n\n- **Standard Error Codes**: Use consistent error codes across direct function wrappers\n  - `INPUT_VALIDATION_ERROR`: For missing or invalid required parameters\n  - `FILE_NOT_FOUND_ERROR`: For file system path issues\n  - `CORE_FUNCTION_ERROR`: For errors thrown by the core function\n  - `UNEXPECTED_ERROR`: For all other unexpected errors\n\n- **Error Object Structure**:\n  ```javascript\n  {\n    success: false,\n    error: {\n      code: 'ERROR_CODE',\n      message: 'Human-readable error message'\n    },\n    fromCache: false\n  }\n  ```\n\n- **MCP Tool Logging Pattern**:\n  - ✅ DO: Log the start of execution with arguments (sanitized if sensitive)\n  - ✅ DO: Log successful completion with result summary\n  - ✅ DO: Log all error conditions with appropriate log levels\n  - ✅ DO: Include the cache status in result logs\n  - ❌ DON'T: Log entire large data structures or sensitive information\n\n- The MCP server integrates with Task Master core functions through three layers:\n  1. Tool Definitions (`mcp-server/src/tools/*.js`) - Define parameters and validation\n  2. Direct Functions (`mcp-server/src/core/direct-functions/*.js`) - Handle core logic integration\n  3. Core Functions (`scripts/modules/*.js`) - Implement the actual functionality\n\n- This layered approach provides:\n  - Clear separation of concerns\n  - Consistent parameter validation\n  - Centralized error handling\n  - Performance optimization through caching (for read operations)\n  - Standardized response formatting\n\n## MCP Naming Conventions\n\n- **Files and Directories**:\n  - ✅ DO: Use **kebab-case** for all file names: `list-tasks.js`, `set-task-status.js`\n  - ✅ DO: Use consistent directory structure: `mcp-server/src/tools/` for tool definitions, `mcp-server/src/core/direct-functions/` for direct function implementations\n\n- **JavaScript Functions**:\n  - ✅ DO: Use **camelCase** with `Direct` suffix for direct function implementations: `listTasksDirect`, `setTaskStatusDirect`\n  - ✅ DO: Use **camelCase** with `Tool` suffix for tool registration functions: `registerListTasksTool`, `registerSetTaskStatusTool`\n  - ✅ DO: Use consistent action function naming inside direct functions: `coreActionFn` or similar descriptive name\n\n- **MCP Tool Names**:\n  - ✅ DO: Use **snake_case** for tool names exposed to MCP clients: `list_tasks`, `set_task_status`, `parse_prd_document`\n  - ✅ DO: Include the core action in the tool name without redundant words: Use `list_tasks` instead of `list_all_tasks`\n\n- **Examples**:\n  - File: `list-tasks.js` \n  - Direct Function: `listTasksDirect`\n  - Tool Registration: `registerListTasksTool`\n  - MCP Tool Name: `list_tasks`\n\n- **Mapping**:\n  - The `directFunctions` map in `task-master-core.js` maps the core function name (in camelCase) to its direct implementation:\n    ```javascript\n    export const directFunctions = {\n      list: listTasksDirect,\n      setStatus: setTaskStatusDirect,\n      // Add more functions as implemented\n    };\n    ```\n\n## Telemetry Integration\n\n- Direct functions calling core logic that involves AI should receive and pass through `telemetryData` within their successful `data` payload. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the standard pattern.\n- MCP tools use `handleApiResult`, which ensures the `data` object (potentially including `telemetryData`) from the direct function is correctly included in the final response.\n",".cursor/rules/new_features.mdc":"---\ndescription: Guidelines for integrating new features into the Task Master CLI\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Task Master Feature Integration Guidelines\n\n## Feature Placement Decision Process\n\n- **Identify Feature Type** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module details):\n  - **Data Manipulation**: Features that create, read, update, or delete tasks belong in [`task-manager.js`](mdc:scripts/modules/task-manager.js). Follow guidelines in [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc).\n  - **Dependency Management**: Features that handle task relationships belong in [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js). Follow guidelines in [`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc).\n  - **User Interface**: Features that display information to users belong in [`ui.js`](mdc:scripts/modules/ui.js). Follow guidelines in [`ui.mdc`](mdc:.cursor/rules/ui.mdc).\n  - **AI Integration**: Features that use AI models belong in [`ai-services.js`](mdc:scripts/modules/ai-services.js).\n  - **Cross-Cutting**: Features that don't fit one category may need components in multiple modules\n\n- **Command-Line Interface** (See [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n  - All new user-facing commands should be added to [`commands.js`](mdc:scripts/modules/commands.js)\n  - Use consistent patterns for option naming and help text\n  - Follow the Commander.js model for subcommand structure\n\n## Implementation Pattern\n\nThe standard pattern for adding a feature follows this workflow:\n\n1. **Core Logic**: Implement the business logic in the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2. **Context Gathering (If Applicable)**: \n   - For AI-powered commands that benefit from project context, use the standardized context gathering patterns from [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc).\n   - Import `ContextGatherer` and `FuzzyTaskSearch` utilities for reusable context extraction.\n   - Support multiple context types: tasks, files, custom text, project tree.\n   - Implement detailed token breakdown display for transparency.\n3. **AI Integration (If Applicable)**: \n   - Import necessary service functions (e.g., `generateTextService`, `streamTextService`) from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n   - Prepare parameters (`role`, `session`, `systemPrompt`, `prompt`).\n   - Call the service function.\n   - Handle the response (direct text or stream object).\n   - **Important**: Prefer `generateTextService` for calls sending large context (like stringified JSON) where incremental display is not needed. See [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc) for detailed usage patterns and cautions.\n4. **UI Components**: Add any display functions to [`ui.js`](mdc:scripts/modules/ui.js) following [`ui.mdc`](mdc:.cursor/rules/ui.mdc). Consider enhanced formatting with syntax highlighting for code blocks.\n5. **Command Integration**: Add the CLI command to [`commands.js`](mdc:scripts/modules/commands.js) following [`commands.mdc`](mdc:.cursor/rules/commands.mdc).\n6. **Testing**: Write tests for all components of the feature (following [`tests.mdc`](mdc:.cursor/rules/tests.mdc))\n7. **Configuration**: Update configuration settings or add new ones in [`config-manager.js`](mdc:scripts/modules/config-manager.js) and ensure getters/setters are appropriate. Update documentation in [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc). Update the `.taskmasterconfig` structure if needed.\n8. **Documentation**: Update help text and documentation in [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n\n## Critical Checklist for New Features\n\n- **Comprehensive Function Exports**:\n  - ✅ **DO**: Export **all core functions, helper functions (like `generateSubtaskPrompt`), and utility methods** needed by your new function or command from their respective modules.\n  - ✅ **DO**: **Explicitly review the module's `export { ... }` block** at the bottom of the file to ensure every required dependency (even seemingly minor helpers like `findTaskById`, `taskExists`, specific prompt generators, AI call handlers, etc.) is included.\n  - ❌ **DON'T**: Assume internal functions are already exported - **always verify**. A missing export will cause runtime errors (e.g., `ReferenceError: generateSubtaskPrompt is not defined`).\n  - **Example**: If implementing a feature that checks task existence, ensure the helper function is in exports:\n  ```javascript\n  // At the bottom of your module file:\n  export {\n    // ... existing exports ...\n    yourNewFunction,\n    taskExists,  // Helper function used by yourNewFunction\n    findTaskById, // Helper function used by yourNewFunction\n    generateSubtaskPrompt, // Helper needed by expand/add features\n    getSubtasksFromAI,     // Helper needed by expand/add features\n  };\n  ```\n\n- **Parameter Completeness and Matching**:\n  - ✅ **DO**: Pass all required parameters to functions you call within your implementation\n  - ✅ **DO**: Check function signatures before implementing calls to them\n  - ✅ **DO**: Verify that direct function parameters match their core function counterparts\n  - ✅ **DO**: When implementing a direct function for MCP, ensure it only accepts parameters that exist in the core function\n  - ✅ **DO**: Verify the expected *internal structure* of complex object parameters (like the `mcpLog` object, see mcp.mdc for the required logger wrapper pattern)\n  - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n  - ❌ **DON'T**: Assume default parameter values will handle missing arguments\n  - ❌ **DON'T**: Assume object parameters will work without verifying their required internal structure or methods.\n  - **Example**: When calling file generation, pass all required parameters:\n  ```javascript\n  // ✅ DO: Pass all required parameters\n  await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n  \n  // ❌ DON'T: Omit required parameters\n  await generateTaskFiles(tasksPath); // Error - missing outputDir parameter\n  ```\n  \n  **Example**: Properly match direct function parameters to core function:\n  ```javascript\n  // Core function signature\n  async function expandTask(tasksPath, taskId, numSubtasks, useResearch = false, additionalContext = '', options = {}) {\n    // Implementation...\n  }\n  \n  // ✅ DO: Match direct function parameters to core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // Extract only parameters that exist in the core function\n    const taskId = parseInt(args.id, 10);\n    const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n    const useResearch = args.research === true;\n    const additionalContext = args.prompt || '';\n    \n    // Call core function with matched parameters\n    const result = await expandTask(\n      tasksPath,\n      taskId,\n      numSubtasks,\n      useResearch,\n      additionalContext,\n      { mcpLog: log, session: context.session }\n    );\n    \n    // Return result\n    return { success: true, data: result, fromCache: false };\n  }\n  \n  // ❌ DON'T: Use parameters that don't exist in the core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // DON'T extract parameters that don't exist in the core function!\n    const force = args.force === true; // ❌ WRONG - 'force' doesn't exist in core function\n    \n    // DON'T pass non-existent parameters to core functions\n    const result = await expandTask(\n      tasksPath,\n      args.id,\n      args.num,\n      args.research,\n      args.prompt,\n      force, // ❌ WRONG - this parameter doesn't exist in the core function\n      { mcpLog: log }\n    );\n  }\n  ```\n\n- **Consistent File Path Handling**:\n  - ✅ DO: Use consistent file naming conventions: `task_${id.toString().padStart(3, '0')}.txt`\n  - ✅ DO: Use `path.join()` for composing file paths\n  - ✅ DO: Use appropriate file extensions (.txt for tasks, .json for data)\n  - ❌ DON'T: Hardcode path separators or inconsistent file extensions\n  - **Example**: Creating file paths for tasks:\n  ```javascript\n  // ✅ DO: Use consistent file naming and path.join\n  const taskFileName = path.join(\n    path.dirname(tasksPath), \n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ❌ DON'T: Use inconsistent naming or string concatenation \n  const taskFileName = path.dirname(tasksPath) + '/' + taskId + '.md';\n  ```\n\n- **Error Handling and Reporting**:\n  - ✅ DO: Use structured error objects with code and message properties\n  - ✅ DO: Include clear error messages identifying the specific problem\n  - ✅ DO: Handle both function-specific errors and potential file system errors\n  - ✅ DO: Log errors at appropriate severity levels\n  - **Example**: Structured error handling in core functions:\n  ```javascript\n  try {\n    // Implementation...\n  } catch (error) {\n    log('error', `Error removing task: ${error.message}`);\n    throw {\n      code: 'REMOVE_TASK_ERROR',\n      message: error.message,\n      details: error.stack\n    };\n  }\n  ```\n\n- **Silent Mode Implementation**:\n  - ✅ **DO**: Import all silent mode utilities together:\n    ```javascript\n    import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n    ```\n  - ✅ **DO**: Always use `isSilentMode()` function to check global silent mode status, never reference global variables.\n  - ✅ **DO**: Wrap core function calls **within direct functions** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block if the core function might produce console output (like banners, spinners, direct `console.log`s) that isn't reliably controlled by an `outputFormat` parameter.\n    ```javascript\n    // Direct Function Example:\n    try {\n      // Prefer passing 'json' if the core function reliably handles it\n      const result = await coreFunction(...args, 'json'); \n      // OR, if outputFormat is not enough/unreliable:\n      // enableSilentMode(); // Enable *before* the call\n      // const result = await coreFunction(...args);\n      // disableSilentMode(); // Disable *after* the call (typically in finally)\n\n      return { success: true, data: result };\n    } catch (error) {\n       log.error(`Error: ${error.message}`);\n       return { success: false, error: { message: error.message } };\n    } finally {\n       // If you used enable/disable, ensure disable is called here\n       // disableSilentMode(); \n    }\n    ```\n  - ✅ **DO**: Core functions themselves *should* ideally check `outputFormat === 'text'` before displaying UI elements (banners, spinners, boxes) and use internal logging (`log`/`report`) that respects silent mode. The `enable/disableSilentMode` wrapper in the direct function is a safety net.\n  - ✅ **DO**: Handle mixed parameter/global silent mode correctly for functions accepting both (less common now, prefer `outputFormat`):\n    ```javascript\n    // Check both the passed parameter and global silent mode\n    const isSilent = silentMode || (typeof silentMode === 'undefined' && isSilentMode());\n    ```\n  - ❌ **DON'T**: Forget to disable silent mode in a `finally` block if you enabled it.\n  - ❌ **DON'T**: Access the global `silentMode` flag directly.\n\n- **Debugging Strategy**:\n  - ✅ **DO**: If an MCP tool fails with vague errors (e.g., JSON parsing issues like `Unexpected token ... is not valid JSON`), **try running the equivalent CLI command directly in the terminal** (e.g., `task-master expand --all`). CLI output often provides much more specific error messages (like missing function definitions or stack traces from the core logic) that pinpoint the root cause.\n  - ❌ **DON'T**: Rely solely on MCP logs if the error is unclear; use the CLI as a complementary debugging tool for core logic issues.\n\n- **Telemetry Integration**: Ensure AI calls correctly handle and propagate `telemetryData` as described in [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc).\n\n```javascript\n// 1. CORE LOGIC: Add function to appropriate module (example in task-manager.js)\n/**\n * Archives completed tasks to archive.json\n * @param {string} tasksPath - Path to the tasks.json file\n * @param {string} archivePath - Path to the archive.json file\n * @returns {number} Number of tasks archived\n */\nasync function archiveTasks(tasksPath, archivePath = 'tasks/archive.json') {\n  // Implementation...\n  return archivedCount;\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  archiveTasks,\n};\n```\n\n```javascript\n// 2. AI Integration: Add import and use necessary service functions\nimport { generateTextService } from './ai-services-unified.js';\n\n// Example usage:\nasync function handleAIInteraction() {\n  const role = 'user';\n  const session = 'exampleSession';\n  const systemPrompt = 'You are a helpful assistant.';\n  const prompt = 'What is the capital of France?';\n\n  const result = await generateTextService(role, session, systemPrompt, prompt);\n  console.log(result);\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  handleAIInteraction,\n};\n```\n\n```javascript\n// 3. UI COMPONENTS: Add display function to ui.js\n/**\n * Display archive operation results\n * @param {string} archivePath - Path to the archive file\n * @param {number} count - Number of tasks archived\n */\nfunction displayArchiveResults(archivePath, count) {\n  console.log(boxen(\n    chalk.green(`Successfully archived ${count} tasks to ${archivePath}`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round' }\n  ));\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  displayArchiveResults,\n};\n```\n\n```javascript\n// 4. COMMAND INTEGRATION: Add to commands.js\nimport { archiveTasks } from './task-manager.js';\nimport { displayArchiveResults } from './ui.js';\n\n// In registerCommands function\nprogramInstance\n  .command('archive')\n  .description('Archive completed tasks to separate file')\n  .option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <file>', 'Archive output file', 'tasks/archive.json')\n  .action(async (options) => {\n    const tasksPath = options.file;\n    const archivePath = options.output;\n    \n    console.log(chalk.blue(`Archiving completed tasks from ${tasksPath} to ${archivePath}...`));\n    \n    const archivedCount = await archiveTasks(tasksPath, archivePath);\n    displayArchiveResults(archivePath, archivedCount);\n  });\n```\n\n## Cross-Module Features\n\nFor features requiring components in multiple modules:\n\n- ✅ **DO**: Create a clear unidirectional flow of dependencies\n  ```javascript\n  // In task-manager.js\n  function analyzeTasksDifficulty(tasks) {\n    // Implementation...\n    return difficultyScores;\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasksDifficulty } from './task-manager.js';\n  \n  function displayDifficultyReport(tasks) {\n    const scores = analyzeTasksDifficulty(tasks);\n    // Render the scores...\n  }\n  ```\n\n- ❌ **DON'T**: Create circular dependencies between modules\n  ```javascript\n  // In task-manager.js - depends on ui.js\n  import { displayDifficultyReport } from './ui.js';\n  \n  function analyzeTasks() {\n    // Implementation...\n    displayDifficultyReport(tasks); // WRONG! Don't call UI functions from task-manager\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasks } from './task-manager.js';\n  ```\n\n## Command-Line Interface Standards\n\n- **Naming Conventions**:\n  - Use kebab-case for command names (`analyze-complexity`, not `analyzeComplexity`)\n  - Use kebab-case for option names (`--output-format`, not `--outputFormat`) \n  - Use the same option names across commands when they represent the same concept\n\n- **Command Structure**:\n  ```javascript\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-s, --short-option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n## Utility Function Guidelines\n\nWhen adding utilities to [`utils.js`](mdc:scripts/modules/utils.js):\n\n- Only add functions that could be used by multiple modules\n- Keep utilities single-purpose and purely functional\n- Document parameters and return values\n\n```javascript\n/**\n * Formats a duration in milliseconds to a human-readable string\n * @param {number} ms - Duration in milliseconds\n * @returns {string} Formatted duration string (e.g., \"2h 30m 15s\")\n */\nfunction formatDuration(ms) {\n  // Implementation...\n  return formatted;\n}\n```\n\n## Writing Testable Code\n\nWhen implementing new features, follow these guidelines to ensure your code is testable:\n\n- **Dependency Injection**\n  - Design functions to accept dependencies as parameters\n  - Avoid hard-coded dependencies that are difficult to mock\n  ```javascript\n  // ✅ DO: Accept dependencies as parameters\n  function processTask(task, fileSystem, logger) {\n    fileSystem.writeFile('task.json', JSON.stringify(task));\n    logger.info('Task processed');\n  }\n  \n  // ❌ DON'T: Use hard-coded dependencies\n  function processTask(task) {\n    fs.writeFile('task.json', JSON.stringify(task));\n    console.log('Task processed');\n  }\n  ```\n\n- **Separate Logic from Side Effects**\n  - Keep pure logic separate from I/O operations or UI rendering\n  - This allows testing the logic without mocking complex dependencies\n  ```javascript\n  // ✅ DO: Separate logic from side effects\n  function calculateTaskPriority(task, dependencies) {\n    // Pure logic that returns a value\n    return computedPriority;\n  }\n  \n  function displayTaskPriority(task, dependencies) {\n    const priority = calculateTaskPriority(task, dependencies);\n    console.log(`Task priority: ${priority}`);\n  }\n  ```\n\n- **Callback Functions and Testing**\n  - When using callbacks (like in Commander.js commands), define them separately\n  - This allows testing the callback logic independently\n  ```javascript\n  // ✅ DO: Define callbacks separately for testing\n  function getVersionString() {\n    // Logic to determine version\n    return version;\n  }\n  \n  // In setupCLI\n  programInstance.version(getVersionString);\n  \n  // In tests\n  test('getVersionString returns correct version', () => {\n    expect(getVersionString()).toBe('1.5.0');\n  });\n  ```\n\n- **UI Output Testing**\n  - For UI components, focus on testing conditional logic rather than exact output\n  - Use string pattern matching (like `expect(result).toContain('text')`)\n  - Pay attention to emojis and formatting which can make exact string matching difficult\n  ```javascript\n  // ✅ DO: Test the essence of the output, not exact formatting\n  test('statusFormatter shows done status correctly', () => {\n    const result = formatStatus('done');\n    expect(result).toContain('done');\n    expect(result).toContain('✅');\n  });\n  ```\n\n## Testing Requirements\n\nEvery new feature **must** include comprehensive tests following the guidelines in [`tests.mdc`](mdc:.cursor/rules/tests.mdc). Testing should include:\n\n1. **Unit Tests**: Test individual functions and components in isolation\n   ```javascript\n   // Example unit test for a new utility function\n   describe('newFeatureUtil', () => {\n     test('should perform expected operation with valid input', () => {\n       expect(newFeatureUtil('valid input')).toBe('expected result');\n     });\n     \n     test('should handle edge cases appropriately', () => {\n       expect(newFeatureUtil('')).toBeNull();\n     });\n   });\n   ```\n\n2. **Integration Tests**: Verify the feature works correctly with other components\n   ```javascript\n   // Example integration test for a new command\n   describe('newCommand integration', () => {\n     test('should call the correct service functions with parsed arguments', () => {\n       const mockService = jest.fn().mockResolvedValue('success');\n       // Set up test with mocked dependencies\n       // Call the command handler\n       // Verify service was called with expected arguments\n     });\n   });\n   ```\n\n3. **Edge Cases**: Test boundary conditions and error handling\n   - Invalid inputs\n   - Missing dependencies\n   - File system errors\n   - API failures\n\n4. **Test Coverage**: Aim for at least 80% coverage for all new code\n\n5. **Jest Mocking Best Practices**\n   - Follow the mock-first-then-import pattern as described in [`tests.mdc`](mdc:.cursor/rules/tests.mdc)\n   - Use jest.spyOn() to create spy functions for testing\n   - Clear mocks between tests to prevent interference\n   - See the Jest Module Mocking Best Practices section in [`tests.mdc`](mdc:.cursor/rules/tests.mdc) for details\n\nWhen submitting a new feature, always run the full test suite to ensure nothing was broken:\n\n```bash\nnpm test\n```\n\n## Documentation Requirements\n\nFor each new feature:\n\n1. Add help text to the command definition\n2. Update [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) with command reference\n3. Consider updating [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) if the feature significantly changes module responsibilities.\n\nFollow the existing command reference format:\n```markdown\n- **Command Reference: your-command**\n  - CLI Syntax: `task-master your-command [options]`\n  - Description: Brief explanation of what the command does\n  - Parameters:\n    - `--option1=<value>`: Description of option1 (default: 'default')\n    - `--option2=<value>`: Description of option2 (required)\n  - Example: `task-master your-command --option1=value --option2=value2`\n  - Notes: Additional details, limitations, or special considerations\n```\n\nFor more information on module structure, see [`MODULE_PLAN.md`](mdc:scripts/modules/MODULE_PLAN.md) and follow [`self_improve.mdc`](mdc:scripts/modules/self_improve.mdc) for best practices on updating documentation.\n\n## Adding MCP Server Support for Commands\n\nIntegrating Task Master commands with the MCP server (for use by tools like Cursor) follows a specific pattern distinct from the CLI command implementation, prioritizing performance and reliability.\n\n- **Goal**: Leverage direct function calls to core logic, avoiding CLI overhead.\n- **Reference**: See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for full details.\n\n**MCP Integration Workflow**:\n\n1.  **Core Logic**: Ensure the command's core logic exists and is exported from the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2.  **Direct Function Wrapper (`mcp-server/src/core/direct-functions/`)**:\n    - Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.\n    - Import the core logic function, necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**: `import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js';`\n    - Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.\n    - **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` (derived from the session) being passed correctly.\n    - Perform validation on other arguments received in `args`.\n    - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()` to prevent logs from interfering with JSON responses.\n    - **If Caching**: Implement caching using `getCachedOrExecute` from `../../tools/utils.js`.\n    - **If Not Caching**: Directly call the core logic function within a try/catch block.\n    - Format the return as `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`withNormalizedProjectRoot` HOF**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters**: Make `projectRoot` optional (`z.string().optional().describe(...)`) as the HOF handles fallback.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method **wrapped with `withNormalizedProjectRoot`**:\n      ```javascript\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n          // args.projectRoot is now normalized\n          const { projectRoot /*, other args */ } = args;\n          // ... resolve tasks path if needed using normalized projectRoot ...\n          const result = await yourCommandDirect(\n              { /* other args */, projectRoot /* if needed by direct func */ }, \n              log, \n              { session }\n          );\n          return handleApiResult(result, log);\n      })\n      ```\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Implementing Background Operations\n\nFor long-running operations that should not block the client, use the AsyncOperationManager:\n\n1. **Identify Background-Appropriate Operations**:\n   - ✅ **DO**: Use async operations for CPU-intensive tasks like task expansion or PRD parsing\n   - ✅ **DO**: Consider async operations for tasks that may take more than 1-2 seconds\n   - ❌ **DON'T**: Use async operations for quick read/status operations\n   - ❌ **DON'T**: Use async operations when immediate feedback is critical\n\n2. **Use AsyncOperationManager in MCP Tools**:\n   ```javascript\n   import { asyncOperationManager } from '../core/utils/async-manager.js';\n   \n   // In execute method:\n   const operationId = asyncOperationManager.addOperation(\n     expandTaskDirect, // The direct function to run in background\n     { ...args, projectRoot: rootFolder }, // Args to pass to the function\n     { log, reportProgress, session } // Context to preserve for the operation\n   );\n   \n   // Return immediate response with operation ID\n   return createContentResponse({\n     message: \"Operation started successfully\",\n     operationId,\n     status: \"pending\"\n   });\n   ```\n\n3. **Implement Progress Reporting**:\n   - ✅ **DO**: Use the reportProgress function in direct functions:\n   ```javascript\n   // In your direct function:\n   if (reportProgress) {\n     await reportProgress({ progress: 50 }); // 50% complete\n   }\n   ```\n   - AsyncOperationManager will forward progress updates to the client\n\n4. **Check Operation Status**:\n   - Implement a way for clients to check status using the `get_operation_status` MCP tool\n   - Return appropriate status codes and messages\n\n## Project Initialization\n\nWhen implementing project initialization commands:\n\n1. **Support Programmatic Initialization**:\n   - ✅ **DO**: Design initialization to work with both CLI and MCP\n   - ✅ **DO**: Support non-interactive modes with sensible defaults\n   - ✅ **DO**: Handle project metadata like name, description, version\n   - ✅ **DO**: Create necessary files and directories\n\n2. **In MCP Tool Implementation**:\n   ```javascript\n   // In initialize-project.js MCP tool:\n   import { z } from \"zod\";\n   import { initializeProjectDirect } from \"../core/task-master-core.js\";\n   \n   export function registerInitializeProjectTool(server) {\n     server.addTool({\n       name: \"initialize_project\",\n       description: \"Initialize a new Task Master project\",\n       parameters: z.object({\n         projectName: z.string().optional().describe(\"The name for the new project\"),\n         projectDescription: z.string().optional().describe(\"A brief description\"),\n         projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n         // Add other parameters as needed\n       }),\n       execute: async (args, { log, reportProgress, session }) => {\n         try {\n           // No need for project root since we're creating a new project\n           const result = await initializeProjectDirect(args, log);\n           return handleApiResult(result, log, 'Error initializing project');\n         } catch (error) {\n           log.error(`Error in initialize_project: ${error.message}`);\n           return createErrorResponse(`Failed to initialize project: ${error.message}`);\n         }\n       }\n     });\n   }\n   ```\n\n## Feature Planning\n\n- **Core Logic First**:\n  - ✅ DO: Implement core logic in `scripts/modules/` before CLI or MCP interfaces\n  - ✅ DO: Consider tagged task lists system compatibility from the start\n  - ✅ DO: Design functions to work with both legacy and tagged data formats\n  - ✅ DO: Use tag resolution functions (`getTasksForTag`, `setTasksForTag`) for task data access\n  - ❌ DON'T: Directly manipulate tagged data structure in new features\n\n  ```javascript\n  // ✅ DO: Design tagged-aware core functions\n  async function newFeatureCore(tasksPath, featureParams, options = {}) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Perform feature logic on tasks array\n    const result = performFeatureLogic(tasks, featureParams);\n    \n    // Save back using tag resolution\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n    \n    return result;\n  }\n  ```\n\n- **Backward Compatibility**:\n  - ✅ DO: Ensure new features work with existing projects seamlessly\n  - ✅ DO: Test with both legacy and tagged task data formats\n  - ✅ DO: Support silent migration during feature usage\n  - ❌ DON'T: Break existing workflows when adding tagged system features\n\n## CLI Command Implementation\n\n- **Command Structure**:\n  - ✅ DO: Follow the established pattern in [`commands.js`](mdc:scripts/modules/commands.js)\n  - ✅ DO: Use Commander.js for argument parsing\n  - ✅ DO: Include comprehensive help text and examples\n  - ✅ DO: Support tagged task context awareness\n\n  ```javascript\n  // ✅ DO: Implement CLI commands with tagged system awareness\n  program\n    .command('new-feature')\n    .description('Description of the new feature with tagged task lists support')\n    .option('-t, --tag <tag>', 'Specify tag context (defaults to current tag)')\n    .option('-p, --param <value>', 'Feature-specific parameter')\n    .option('--force', 'Force operation without confirmation')\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot();\n        if (!projectRoot) {\n          console.error('Not in a Task Master project directory');\n          process.exit(1);\n        }\n        \n        // Use specified tag or current tag\n        const targetTag = options.tag || getCurrentTag() || 'master';\n        \n        const result = await newFeatureCore(\n          path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'),\n          { param: options.param },\n          { \n            force: options.force,\n            targetTag: targetTag,\n            outputFormat: 'text'\n          }\n        );\n        \n        console.log('Feature executed successfully');\n      } catch (error) {\n        console.error(`Error: ${error.message}`);\n        process.exit(1);\n      }\n    });\n  ```\n\n- **Error Handling**:\n  - ✅ DO: Provide clear error messages for common failures\n  - ✅ DO: Handle tagged system migration errors gracefully\n  - ✅ DO: Include suggestion for resolution when possible\n  - ✅ DO: Exit with appropriate codes for scripting\n\n## MCP Tool Implementation\n\n- **Direct Function Pattern**:\n  - ✅ DO: Create direct function wrappers in `mcp-server/src/core/direct-functions/`\n  - ✅ DO: Follow silent mode patterns to prevent console output interference\n  - ✅ DO: Use `findTasksJsonPath` for consistent path resolution\n  - ✅ DO: Ensure tagged system compatibility\n\n  ```javascript\n  // ✅ DO: Implement MCP direct functions with tagged awareness\n  export async function newFeatureDirect(args, log, context = {}) {\n    try {\n      const tasksPath = findTasksJsonPath(args, log);\n      \n      // Enable silent mode for clean MCP responses\n      enableSilentMode();\n      \n      try {\n        const result = await newFeatureCore(\n          tasksPath,\n          { param: args.param },\n          { \n            force: args.force,\n            targetTag: args.tag || 'master', // Support tag specification\n            mcpLog: log,\n            session: context.session,\n            outputFormat: 'json'\n          }\n        );\n        \n        return {\n          success: true,\n          data: result,\n          fromCache: false\n        };\n      } finally {\n        disableSilentMode();\n      }\n    } catch (error) {\n      log.error(`Error in newFeatureDirect: ${error.message}`);\n      return {\n        success: false,\n        error: { code: 'FEATURE_ERROR', message: error.message },\n        fromCache: false\n      };\n    }\n  }\n  ```\n\n- **Tool Registration**:\n  - ✅ DO: Create tool definitions in `mcp-server/src/tools/`\n  - ✅ DO: Use Zod for parameter validation\n  - ✅ DO: Include optional tag parameter for multi-context support\n  - ✅ DO: Follow established naming conventions\n\n  ```javascript\n  // ✅ DO: Register MCP tools with tagged system support\n  export function registerNewFeatureTool(server) {\n    server.addTool({\n      name: \"new_feature\",\n      description: \"Description of the new feature with tagged task lists support\",\n      inputSchema: z.object({\n        param: z.string().describe(\"Feature-specific parameter\"),\n        tag: z.string().optional().describe(\"Target tag context (defaults to current tag)\"),\n        force: z.boolean().optional().describe(\"Force operation without confirmation\"),\n        projectRoot: z.string().optional().describe(\"Project root directory\")\n      }),\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const result = await newFeatureDirect(\n            { ...args, projectRoot: args.projectRoot },\n            log,\n            { session }\n          );\n          return handleApiResult(result, log);\n        } catch (error) {\n          return handleApiResult({\n            success: false,\n            error: { code: 'EXECUTION_ERROR', message: error.message }\n          }, log);\n        }\n      })\n    });\n  }\n  ```\n\n## Testing Strategy\n\n- **Unit Tests**:\n  - ✅ DO: Test core logic independently with both data formats\n  - ✅ DO: Mock file system operations appropriately\n  - ✅ DO: Test tag resolution behavior\n  - ✅ DO: Verify migration compatibility\n\n  ```javascript\n  // ✅ DO: Test new features with tagged system awareness\n  describe('newFeature', () => {\n    beforeEach(() => {\n      jest.clearAllMocks();\n    });\n    \n    it('should work with legacy task format', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test legacy format handling\n    });\n    \n    it('should work with tagged task format', async () => {\n      const taggedData = { \n        master: { tasks: [/* test data */] },\n        feature: { tasks: [/* test data */] }\n      };\n      fs.readFileSync.mockReturnValue(JSON.stringify(taggedData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test tagged format handling\n    });\n    \n    it('should handle tag migration during feature usage', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      // Verify migration occurred\n      expect(fs.writeFileSync).toHaveBeenCalledWith(\n        '/test/tasks.json',\n        expect.stringContaining('\"master\"')\n      );\n    });\n  });\n  ```\n\n- **Integration Tests**:\n  - ✅ DO: Test CLI and MCP interfaces with real task data\n  - ✅ DO: Verify end-to-end workflows across tag contexts\n  - ✅ DO: Test error scenarios and recovery\n\n## Documentation Updates\n\n- **Rule Updates**:\n  - ✅ DO: Update relevant `.cursor/rules/*.mdc` files\n  - ✅ DO: Include tagged system considerations in architecture docs\n  - ✅ DO: Add examples showing multi-context usage\n  - ✅ DO: Update workflow documentation as needed\n\n- **User Documentation**:\n  - ✅ DO: Add feature documentation to `/docs` folder\n  - ✅ DO: Include tagged system usage examples\n  - ✅ DO: Update command reference documentation\n  - ✅ DO: Provide migration notes if relevant\n\n## Migration Considerations\n\n- **Silent Migration Support**:\n  - ✅ DO: Ensure new features trigger migration when needed\n  - ✅ DO: Handle migration errors gracefully in feature code\n  - ✅ DO: Test feature behavior with pre-migration projects\n  - ❌ DON'T: Assume projects are already migrated\n\n- **Tag Context Handling**:\n  - ✅ DO: Default to current tag when not specified\n  - ✅ DO: Support explicit tag selection in advanced features\n  - ✅ DO: Validate tag existence before operations\n  - ✅ DO: Provide clear messaging about tag context\n\n## Performance Considerations\n\n- **Efficient Tag Operations**:\n  - ✅ DO: Minimize file I/O operations per feature execution\n  - ✅ DO: Cache tag resolution results when appropriate\n  - ✅ DO: Use streaming for large task datasets\n  - ❌ DON'T: Load all tags when only one is needed\n\n- **Memory Management**:\n  - ✅ DO: Process large task lists efficiently\n  - ✅ DO: Clean up temporary data structures\n  - ✅ DO: Avoid keeping all tag data in memory simultaneously\n\n## Deployment and Versioning\n\n- **Changesets**:\n  - ✅ DO: Create appropriate changesets for new features\n  - ✅ DO: Use semantic versioning (minor for new features)\n  - ✅ DO: Include tagged system information in release notes\n  - ✅ DO: Document breaking changes if any\n\n- **Feature Flags**:\n  - ✅ DO: Consider feature flags for experimental functionality\n  - ✅ DO: Ensure tagged system features work with flags\n  - ✅ DO: Provide clear documentation about flag usage\n\nBy following these guidelines, new features will integrate smoothly with the Task Master ecosystem while supporting the enhanced tagged task lists system for multi-context development workflows.\n",".cursor/rules/self_improve.mdc":"---\ndescription: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\nglobs: **/*\nalwaysApply: true\n---\n\n- **Rule Improvement Triggers:**\n  - New code patterns not covered by existing rules\n  - Repeated similar implementations across files\n  - Common error patterns that could be prevented\n  - New libraries or tools being used consistently\n  - Emerging best practices in the codebase\n\n- **Analysis Process:**\n  - Compare new code with existing rules\n  - Identify patterns that should be standardized\n  - Look for references to external documentation\n  - Check for consistent error handling patterns\n  - Monitor test patterns and coverage\n\n- **Rule Updates:**\n  - **Add New Rules When:**\n    - A new technology/pattern is used in 3+ files\n    - Common bugs could be prevented by a rule\n    - Code reviews repeatedly mention the same feedback\n    - New security or performance patterns emerge\n\n  - **Modify Existing Rules When:**\n    - Better examples exist in the codebase\n    - Additional edge cases are discovered\n    - Related rules have been updated\n    - Implementation details have changed\n\n- **Example Pattern Recognition:**\n  ```typescript\n  // If you see repeated patterns like:\n  const data = await prisma.user.findMany({\n    select: { id: true, email: true },\n    where: { status: 'ACTIVE' }\n  });\n  \n  // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc):\n  // - Standard select fields\n  // - Common where conditions\n  // - Performance optimization patterns\n  ```\n\n- **Rule Quality Checks:**\n  - Rules should be actionable and specific\n  - Examples should come from actual code\n  - References should be up to date\n  - Patterns should be consistently enforced\n\n- **Continuous Improvement:**\n  - Monitor code review comments\n  - Track common development questions\n  - Update rules after major refactors\n  - Add links to relevant documentation\n  - Cross-reference related rules\n\n- **Rule Deprecation:**\n  - Mark outdated patterns as deprecated\n  - Remove rules that no longer apply\n  - Update references to deprecated rules\n  - Document migration paths for old patterns\n\n- **Documentation Updates:**\n  - Keep examples synchronized with code\n  - Update references to external docs\n  - Maintain links between related rules\n  - Document breaking changes\nFollow [cursor_rules.mdc](mdc:.cursor/rules/cursor_rules.mdc) for proper rule formatting and structure.\n",".cursor/rules/tags.mdc":"---\ndescription: \nglobs: scripts/modules/*\nalwaysApply: false\n---\n# Tagged Task Lists Command Patterns\n\nThis document outlines the standardized patterns that **ALL** Task Master commands must follow to properly support the tagged task lists system.\n\n## Core Principles\n\n- **Every command** that reads or writes tasks.json must be tag-aware\n- **Consistent tag resolution** across all commands using `getCurrentTag(projectRoot)`\n- **Proper context passing** to core functions with `{ projectRoot, tag }`\n- **Standardized CLI options** with `--tag <tag>` flag\n\n## Required Imports\n\nAll command files must import `getCurrentTag`:\n\n```javascript\n// ✅ DO: Import getCurrentTag in commands.js\nimport { \n  log, \n  readJSON, \n  writeJSON, \n  findProjectRoot, \n  getCurrentTag \n} from './utils.js';\n\n// ✅ DO: Import getCurrentTag in task-manager files\nimport { \n  readJSON, \n  writeJSON, \n  getCurrentTag \n} from '../utils.js';\n```\n\n## CLI Command Pattern\n\nEvery CLI command that operates on tasks must follow this exact pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware CLI command pattern\nprogramInstance\n  .command('command-name')\n  .description('Command description')\n  .option('-f, --file <file>', 'Path to the tasks file', TASKMASTER_TASKS_FILE)\n  .option('--tag <tag>', 'Specify tag context for task operations') // REQUIRED\n  .action(async (options) => {\n    // 1. Find project root\n    const projectRoot = findProjectRoot();\n    if (!projectRoot) {\n      console.error(chalk.red('Error: Could not find project root.'));\n      process.exit(1);\n    }\n\n    // 2. Resolve tag using standard pattern\n    const tag = options.tag || getCurrentTag(projectRoot) || 'master';\n\n    // 3. Call core function with proper context\n    await coreFunction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag } // REQUIRED context object\n    );\n  });\n```\n\n## Core Function Pattern\n\nAll core functions in `scripts/modules/task-manager/` must follow this pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware core function pattern\nasync function coreFunction(\n  tasksPath,\n  // ... other parameters ...\n  context = {} // REQUIRED context parameter\n) {\n  const { projectRoot, tag } = context;\n  \n  // Use tag-aware readJSON/writeJSON\n  const data = readJSON(tasksPath, projectRoot, tag);\n  \n  // ... function logic ...\n  \n  writeJSON(tasksPath, data, projectRoot, tag);\n}\n```\n\n## Tag Resolution Priority\n\nThe tag resolution follows this exact priority order:\n\n1. **Explicit `--tag` flag**: `options.tag`\n2. **Current active tag**: `getCurrentTag(projectRoot)`  \n3. **Default fallback**: `'master'`\n\n```javascript\n// ✅ DO: Standard tag resolution pattern\nconst tag = options.tag || getCurrentTag(projectRoot) || 'master';\n```\n\n## Commands Requiring Updates\n\n### High Priority (Core Task Operations)\n- [x] `add-task` - ✅ Fixed\n- [x] `list` - ✅ Fixed  \n- [x] `update-task` - ✅ Fixed\n- [x] `update-subtask` - ✅ Fixed\n- [x] `set-status` - ✅ Already correct\n- [x] `remove-task` - ✅ Already correct\n- [x] `remove-subtask` - ✅ Fixed\n- [x] `add-subtask` - ✅ Already correct\n- [x] `clear-subtasks` - ✅ Fixed\n- [x] `move-task` - ✅ Already correct\n\n### Medium Priority (Analysis & Expansion)\n- [x] `expand` - ✅ Fixed\n- [ ] `next` - ✅ Fixed\n- [ ] `show` (get-task) - Needs checking\n- [ ] `analyze-complexity` - Needs checking\n- [ ] `generate` - ✅ Fixed\n\n### Lower Priority (Utilities)\n- [ ] `research` - Needs checking\n- [ ] `complexity-report` - Needs checking\n- [ ] `validate-dependencies` - ✅ Fixed\n- [ ] `fix-dependencies` - ✅ Fixed\n- [ ] `add-dependency` - ✅ Fixed\n- [ ] `remove-dependency` - ✅ Fixed\n\n## MCP Integration Pattern\n\nMCP direct functions must also follow the tag-aware pattern:\n\n```javascript\n// ✅ DO: Tag-aware MCP direct function\nexport async function coreActionDirect(args, log, context = {}) {\n  const { session } = context;\n  const { projectRoot, tag } = args; // MCP passes these in args\n  \n  try {\n    const result = await coreAction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag, session, mcpLog: logWrapper }\n    );\n    \n    return { success: true, data: result };\n  } catch (error) {\n    return { success: false, error: { code: 'ERROR_CODE', message: error.message } };\n  }\n}\n```\n\n## File Generation Tag-Aware Naming\n\nThe `generate` command must use tag-aware file naming:\n\n```javascript\n// ✅ DO: Tag-aware file naming\nconst taskFileName = targetTag === 'master' \n  ? `task_${task.id.toString().padStart(3, '0')}.txt`\n  : `task_${task.id.toString().padStart(3, '0')}_${targetTag}.txt`;\n```\n\n**Examples:**\n- Master tag: `task_001.txt`, `task_002.txt`\n- Other tags: `task_001_feature.txt`, `task_002_feature.txt`\n\n## Common Anti-Patterns\n\n```javascript\n// ❌ DON'T: Missing getCurrentTag import\nimport { readJSON, writeJSON } from '../utils.js'; // Missing getCurrentTag\n\n// ❌ DON'T: Hard-coded tag resolution\nconst tag = options.tag || 'master'; // Missing getCurrentTag\n\n// ❌ DON'T: Missing --tag option\n.option('-f, --file <file>', 'Path to tasks file') // Missing --tag option\n\n// ❌ DON'T: Missing context parameter\nawait coreFunction(tasksPath, param1, param2); // Missing { projectRoot, tag }\n\n// ❌ DON'T: Incorrect readJSON/writeJSON calls\nconst data = readJSON(tasksPath); // Missing projectRoot and tag\nwriteJSON(tasksPath, data); // Missing projectRoot and tag\n```\n\n## Validation Checklist\n\nFor each command, verify:\n\n- [ ] Imports `getCurrentTag` from utils.js\n- [ ] Has `--tag <tag>` CLI option\n- [ ] Uses standard tag resolution: `options.tag || getCurrentTag(projectRoot) || 'master'`\n- [ ] Finds `projectRoot` with error handling\n- [ ] Passes `{ projectRoot, tag }` context to core functions\n- [ ] Core functions accept and use context parameter\n- [ ] Uses `readJSON(tasksPath, projectRoot, tag)` and `writeJSON(tasksPath, data, projectRoot, tag)`\n\n## Testing Tag Resolution\n\nTest each command with:\n\n```bash\n# Test with explicit tag\nnode bin/task-master command-name --tag test-tag\n\n# Test with active tag (should use current active tag)\nnode bin/task-master use-tag test-tag\nnode bin/task-master command-name\n\n# Test with master tag (default)\nnode bin/task-master use-tag master  \nnode bin/task-master command-name\n```\n\n## Migration Strategy\n\n1. **Audit Phase**: Systematically check each command against the checklist\n2. **Fix Phase**: Apply the standard patterns to non-compliant commands\n3. **Test Phase**: Verify tag resolution works correctly\n4. **Document Phase**: Update command documentation with tag support\n\nThis ensures consistent, predictable behavior across all Task Master commands and prevents tag deletion bugs.\n",".cursor/rules/taskmaster.mdc":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `--no-git`: `Skip initializing a Git repository entirely.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `noGit`: `Skip initializing a Git repository entirely. Default is false.` (CLI: `--no-git`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [Development Workflow Guide](mdc:.cursor/rules/dev_workflow.mdc).",".cursor/rules/taskmaster/dev_workflow.mdc":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see @`taskmaster.mdc`) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see @`taskmaster.mdc`) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see @`taskmaster.mdc`)\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`)\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see @`taskmaster.mdc`) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see @`taskmaster.mdc`) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see @`taskmaster.mdc`)\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see @`taskmaster.mdc`)\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to @`mcp.mdc` for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in @`taskmaster.mdc`.\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to @`taskmaster.mdc` for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to @`taskmaster.mdc` for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see @`taskmaster.mdc`) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*",".cursor/rules/taskmaster/taskmaster.mdc":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [dev_workflow.mdc](mdc:.cursor/rules/taskmaster/dev_workflow.mdc).",".cursor/rules/tasks.mdc":"---\ndescription: Guidelines for implementing task management operations\nglobs: scripts/modules/task-manager.js\nalwaysApply: false\n---\n# Task Management Guidelines\n\n## Tagged Task Lists System\n\nTask Master now uses a **tagged task lists system** for multi-context task management:\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) within `tasks.json`\n- **Legacy Format**: `{\"tasks\": [...]}`\n- **Tagged Format**: `{\"master\": {\"tasks\": [...]}, \"feature-branch\": {\"tasks\": [...]}}`\n- **Silent Migration**: Legacy format automatically converts to tagged format on first use\n- **Tag Resolution**: Core functions receive legacy format for 100% backward compatibility\n- **Default Tag**: \"master\" is used for all existing and new tasks unless otherwise specified\n\n## Task Structure Standards\n\n- **Core Task Properties**:\n  - ✅ DO: Include all required properties in each task object\n  - ✅ DO: Provide default values for optional properties\n  - ❌ DON'T: Add extra properties that aren't in the standard schema\n\n  ```javascript\n  // ✅ DO: Follow this structure for task objects\n  const task = {\n    id: nextId,\n    title: \"Task title\",\n    description: \"Brief task description\",\n    status: \"pending\", // \"pending\", \"in-progress\", \"done\", etc.\n    dependencies: [], // Array of task IDs\n    priority: \"medium\", // \"high\", \"medium\", \"low\"\n    details: \"Detailed implementation instructions\",\n    testStrategy: \"Verification approach\",\n    subtasks: [] // Array of subtask objects\n  };\n  ```\n\n- **Tagged Data Structure**:\n  - ✅ DO: Access tasks through tag resolution layer\n  - ✅ DO: Use `getTasksForTag(data, tagName)` to retrieve tasks for a specific tag\n  - ✅ DO: Use `setTasksForTag(data, tagName, tasks)` to update tasks for a specific tag\n  - ❌ DON'T: Directly manipulate the tagged structure in core functions\n\n  ```javascript\n  // ✅ DO: Use tag resolution functions\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Manipulate tasks as normal...\n  \n  // Save back to the tagged structure\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n- **Subtask Structure**:\n  - ✅ DO: Use consistent properties across subtasks\n  - ✅ DO: Maintain simple numeric IDs within parent tasks\n  - ❌ DON'T: Duplicate parent task properties in subtasks\n\n  ```javascript\n  // ✅ DO: Structure subtasks consistently\n  const subtask = {\n    id: nextSubtaskId, // Simple numeric ID, unique within the parent task\n    title: \"Subtask title\",\n    description: \"Brief subtask description\",\n    status: \"pending\",\n    dependencies: [], // Can include numeric IDs (other subtasks) or full task IDs\n    details: \"Detailed implementation instructions\"\n  };\n  ```\n\n## Task Creation and Parsing\n\n- **ID Management**:\n  - ✅ DO: Assign unique sequential IDs to tasks within each tag context\n  - ✅ DO: Calculate the next ID based on existing tasks in the current tag\n  - ❌ DON'T: Hardcode or reuse IDs within the same tag\n\n  ```javascript\n  // ✅ DO: Calculate the next available ID within the current tag\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  const highestId = Math.max(...tasks.map(t => t.id));\n  const nextTaskId = highestId + 1;\n  ```\n\n- **PRD Parsing**:\n  - ✅ DO: Extract tasks from PRD documents using AI\n  - ✅ DO: Create tasks in the current tag context (defaults to \"master\")\n  - ✅ DO: Provide clear prompts to guide AI task generation\n  - ✅ DO: Validate and clean up AI-generated tasks\n\n  ```javascript\n  // ✅ DO: Parse into current tag context\n  const tasksData = readJSON(tasksPath) || {};\n  const currentTag = getCurrentTag() || 'master';\n  \n  // Parse tasks and add to current tag\n  const newTasks = await parseTasksFromPRD(prdContent);\n  setTasksForTag(tasksData, currentTag, newTasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task Updates and Modifications\n\n- **Status Management**:\n  - ✅ DO: Provide functions for updating task status within current tag context\n  - ✅ DO: Handle both individual tasks and subtasks\n  - ✅ DO: Consider subtask status when updating parent tasks\n\n  ```javascript\n  // ✅ DO: Handle status updates within tagged context\n  async function setTaskStatus(tasksPath, taskIdInput, newStatus) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Check if it's a subtask (e.g., \"1.2\")\n    if (taskIdInput.includes('.')) {\n      const [parentId, subtaskId] = taskIdInput.split('.').map(id => parseInt(id, 10));\n      \n      // Find the parent task and subtask\n      const parentTask = tasks.find(t => t.id === parentId);\n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      \n      // Update subtask status\n      subtask.status = newStatus;\n      \n      // Check if all subtasks are done\n      if (newStatus === 'done') {\n        const allSubtasksDone = parentTask.subtasks.every(st => st.status === 'done');\n        if (allSubtasksDone) {\n          // Suggest updating parent task\n        }\n      }\n    } else {\n      // Handle regular task\n      const task = tasks.find(t => t.id === parseInt(taskIdInput, 10));\n      task.status = newStatus;\n      \n      // If marking as done, also mark subtasks\n      if (newStatus === 'done' && task.subtasks && task.subtasks.length > 0) {\n        task.subtasks.forEach(subtask => {\n          subtask.status = newStatus;\n        });\n      }\n    }\n    \n    // Save updated tasks back to tagged structure\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n  }\n  ```\n\n- **Task Expansion**:\n  - ✅ DO: Use AI to generate detailed subtasks within current tag context\n  - ✅ DO: Consider complexity analysis for subtask counts\n  - ✅ DO: Ensure proper IDs for newly created subtasks\n\n  ```javascript\n  // ✅ DO: Generate appropriate subtasks based on complexity\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  if (taskAnalysis) {\n    log('info', `Found complexity analysis for task ${taskId}: Score ${taskAnalysis.complexityScore}/10`);\n    \n    // Use recommended number of subtasks if available\n    if (taskAnalysis.recommendedSubtasks && numSubtasks === CONFIG.defaultSubtasks) {\n      numSubtasks = taskAnalysis.recommendedSubtasks;\n      log('info', `Using recommended number of subtasks: ${numSubtasks}`);\n    }\n  }\n  \n  // Generate subtasks and save back\n  // ... subtask generation logic ...\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task File Generation\n\n- **File Formatting**:\n  - ✅ DO: Use consistent formatting for task files\n  - ✅ DO: Include all task properties in text files\n  - ✅ DO: Format dependencies with status indicators\n\n  ```javascript\n  // ✅ DO: Use consistent file formatting\n  let content = `# Task ID: ${task.id}\\n`;\n  content += `# Title: ${task.title}\\n`;\n  content += `# Status: ${task.status || 'pending'}\\n`;\n  \n  // Format dependencies with their status\n  if (task.dependencies && task.dependencies.length > 0) {\n    content += `# Dependencies: ${formatDependenciesWithStatus(task.dependencies, tasks)}\\n`;\n  } else {\n    content += '# Dependencies: None\\n';\n  }\n  ```\n\n- **Tagged Context Awareness**:\n  - ✅ DO: Generate task files from current tag context\n  - ✅ DO: Include tag information in generated files\n  - ❌ DON'T: Mix tasks from different tags in file generation\n\n  ```javascript\n  // ✅ DO: Generate files for current tag context\n  async function generateTaskFiles(tasksPath, outputDir) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Add tag context to file header\n    let content = `# Tag Context: ${currentTag}\\n`;\n    content += `# Task ID: ${task.id}\\n`;\n    // ... rest of file generation\n  }\n  ```\n\n## Task Listing and Display\n\n- **Filtering and Organization**:\n  - ✅ DO: Allow filtering tasks by status within current tag context\n  - ✅ DO: Handle subtask display in lists\n  - ✅ DO: Use consistent table formats\n\n  ```javascript\n  // ✅ DO: Implement clear filtering within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Filter tasks by status if specified\n  const filteredTasks = statusFilter \n    ? tasks.filter(task => \n        task.status && task.status.toLowerCase() === statusFilter.toLowerCase())\n    : tasks;\n  ```\n\n- **Progress Tracking**:\n  - ✅ DO: Calculate and display completion statistics for current tag\n  - ✅ DO: Track both task and subtask completion\n  - ✅ DO: Use visual progress indicators\n\n  ```javascript\n  // ✅ DO: Track and display progress within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Calculate completion statistics\n  const totalTasks = tasks.length;\n  const completedTasks = tasks.filter(task => \n    task.status === 'done' || task.status === 'completed').length;\n  const completionPercentage = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0;\n  \n  // Count subtasks\n  let totalSubtasks = 0;\n  let completedSubtasks = 0;\n  \n  tasks.forEach(task => {\n    if (task.subtasks && task.subtasks.length > 0) {\n      totalSubtasks += task.subtasks.length;\n      completedSubtasks += task.subtasks.filter(st => \n        st.status === 'done' || st.status === 'completed').length;\n    }\n  });\n  ```\n\n## Migration and Compatibility\n\n- **Silent Migration Handling**:\n  - ✅ DO: Implement silent migration in `readJSON()` function\n  - ✅ DO: Detect legacy format and convert automatically\n  - ✅ DO: Preserve all existing task data during migration\n\n  ```javascript\n  // ✅ DO: Handle silent migration (implemented in utils.js)\n  function readJSON(filepath) {\n    let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n    \n    // Silent migration for tasks.json files\n    if (data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n      const migratedData = {\n        master: {\n          tasks: data.tasks\n        }\n      };\n      writeJSON(filepath, migratedData);\n      data = migratedData;\n    }\n    \n    return data;\n  }\n  ```\n\n- **Tag Resolution**:\n  - ✅ DO: Use tag resolution functions to maintain backward compatibility\n  - ✅ DO: Return legacy format to core functions\n  - ❌ DON'T: Expose tagged structure to existing core logic\n\n  ```javascript\n  // ✅ DO: Use tag resolution layer\n  function getTasksForTag(data, tagName) {\n    if (data.tasks && Array.isArray(data.tasks)) {\n      // Legacy format - return as-is\n      return data.tasks;\n    }\n    \n    if (data[tagName] && data[tagName].tasks) {\n      // Tagged format - return tasks for specified tag\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  ```\n\nRefer to [`task-manager.js`](mdc:scripts/modules/task-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/telemetry.mdc":"---\ndescription: Guidelines for integrating AI usage telemetry across Task Master.\nglobs: scripts/modules/**/*.js,mcp-server/src/**/*.js\nalwaysApply: true\n---\n\n# AI Usage Telemetry Integration\n\nThis document outlines the standard pattern for capturing, propagating, and handling AI usage telemetry data (cost, tokens, model, etc.) across the Task Master stack. This ensures consistent telemetry for both CLI and MCP interactions.\n\n## Overview\n\nTelemetry data is generated within the unified AI service layer ([`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)) and then passed upwards through the calling functions.\n\n- **Data Source**: [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js) (specifically its `generateTextService`, `generateObjectService`, etc.) returns an object like `{ mainResult: AI_CALL_OUTPUT, telemetryData: TELEMETRY_OBJECT }`.\n- **`telemetryData` Object Structure**:\n  ```json\n  {\n    \"timestamp\": \"ISO_STRING_DATE\",\n    \"userId\": \"USER_ID_FROM_CONFIG\",\n    \"commandName\": \"invoking_command_or_tool_name\",\n    \"modelUsed\": \"ai_model_id\",\n    \"providerName\": \"ai_provider_name\",\n    \"inputTokens\": NUMBER,\n    \"outputTokens\": NUMBER,\n    \"totalTokens\": NUMBER,\n    \"totalCost\": NUMBER, // e.g., 0.012414\n    \"currency\": \"USD\" // e.g., \"USD\"\n  }\n  ```\n\n## Integration Pattern by Layer\n\nThe key principle is that each layer receives telemetry data from the layer below it (if applicable) and passes it to the layer above it, or handles it for display in the case of the CLI.\n\n### 1. Core Logic Functions (e.g., in `scripts/modules/task-manager/`)\n\nFunctions in this layer that invoke AI services are responsible for handling the `telemetryData` they receive from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n\n- **Actions**:\n    1.  Call the appropriate AI service function (e.g., `generateObjectService`).\n        -   Pass `commandName` (e.g., `add-task`, `expand-task`) and `outputType` (e.g., `cli` or `mcp`) in the `params` object to the AI service. The `outputType` can be derived from context (e.g., presence of `mcpLog`).\n    2.  The AI service returns an object, e.g., `aiServiceResponse = { mainResult: {/*AI output*/}, telemetryData: {/*telemetry data*/} }`.\n    3.  Extract `aiServiceResponse.mainResult` for the core processing.\n    4.  **Must return an object that includes `aiServiceResponse.telemetryData`**.\n        Example: `return { operationSpecificData: /*...*/, telemetryData: aiServiceResponse.telemetryData };`\n\n- **CLI Output Handling (If Applicable)**:\n    -   If the core function also handles CLI output (e.g., it has an `outputFormat` parameter that can be `'text'` or `'cli'`):\n        1.  Check if `outputFormat === 'text'` (or `'cli'`).\n        2.  If so, and if `aiServiceResponse.telemetryData` is available, call `displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli')` from [`scripts/modules/ui.js`](mdc:scripts/modules/ui.js).\n        - This ensures telemetry is displayed directly to CLI users after the main command output.\n\n- **Example Snippet (Core Logic in `scripts/modules/task-manager/someAiAction.js`)**:\n  ```javascript\n  import { generateObjectService } from '../ai-services-unified.js';\n  import { displayAiUsageSummary } from '../ui.js';\n\n  async function performAiRelatedAction(params, context, outputFormat = 'text') {\n    const { commandNameFromContext, /* other context vars */ } = context;\n    let aiServiceResponse = null;\n\n    try {\n      aiServiceResponse = await generateObjectService({\n        // ... other parameters for AI service ...\n        commandName: commandNameFromContext || 'default-action-name',\n        outputType: context.mcpLog ? 'mcp' : 'cli' // Derive outputType\n      });\n\n      const usefulAiOutput = aiServiceResponse.mainResult.object;\n      // ... do work with usefulAiOutput ...\n\n      if (outputFormat === 'text' && aiServiceResponse.telemetryData) {\n        displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli');\n      }\n\n      return {\n        actionData: /* results of processing */,\n        telemetryData: aiServiceResponse.telemetryData\n      };\n    } catch (error) {\n      // ... handle error ...\n      throw error;\n    }\n  }\n  ```\n\n### 2. Direct Function Wrappers (in `mcp-server/src/core/direct-functions/`)\n\nThese functions adapt core logic for the MCP server, ensuring structured responses.\n\n- **Actions**:\n    1.  Call the corresponding core logic function.\n        -   Pass necessary context (e.g., `session`, `mcpLog`, `projectRoot`).\n        -   Provide the `commandName` (typically derived from the MCP tool name) and `outputType: 'mcp'` in the context object passed to the core function.\n        -   If the core function supports an `outputFormat` parameter, pass `'json'` to suppress CLI-specific UI.\n    2.  The core logic function returns an object (e.g., `coreResult = { actionData: ..., telemetryData: ... }`).\n    3.  Include `coreResult.telemetryData` as a field within the `data` object of the successful response returned by the direct function.\n\n- **Example Snippet (Direct Function `someAiActionDirect.js`)**:\n  ```javascript\n  import { performAiRelatedAction } from '../../../../scripts/modules/task-manager/someAiAction.js'; // Core function\n  import { createLogWrapper } from '../../tools/utils.js'; // MCP Log wrapper\n\n  export async function someAiActionDirect(args, log, context = {}) {\n    const { session } = context;\n    // ... prepare arguments for core function from args, including args.projectRoot ...\n\n    try {\n      const coreResult = await performAiRelatedAction(\n        { /* parameters for core function */ },\n        { // Context for core function\n          session,\n          mcpLog: createLogWrapper(log),\n          projectRoot: args.projectRoot,\n          commandNameFromContext: 'mcp_tool_some_ai_action', // Example command name\n          outputType: 'mcp'\n        },\n        'json' // Request 'json' output format from core function\n      );\n\n      return {\n        success: true,\n        data: {\n          operationSpecificData: coreResult.actionData,\n          telemetryData: coreResult.telemetryData // Pass telemetry through\n        }\n      };\n    } catch (error) {\n      // ... error handling, return { success: false, error: ... } ...\n    }\n  }\n  ```\n\n### 3. MCP Tools (in `mcp-server/src/tools/`)\n\nThese are the exposed endpoints for MCP clients.\n\n- **Actions**:\n    1.  Call the corresponding direct function wrapper.\n    2.  The direct function returns an object structured like `{ success: true, data: { operationSpecificData: ..., telemetryData: ... } }` (or an error object).\n    3.  Pass this entire result object to `handleApiResult(result, log)` from [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    4.  `handleApiResult` ensures that the `data` field from the direct function's response (which correctly includes `telemetryData`) is part of the final MCP response.\n\n- **Example Snippet (MCP Tool `some_ai_action.js`)**:\n  ```javascript\n  import { someAiActionDirect } from '../core/task-master-core.js';\n  import { handleApiResult, withNormalizedProjectRoot } from './utils.js';\n  // ... zod for parameters ...\n\n  export function registerSomeAiActionTool(server) {\n    server.addTool({\n      name: \"some_ai_action\",\n      // ... description, parameters ...\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const resultFromDirectFunction = await someAiActionDirect(\n            { /* args including projectRoot */ },\n            log,\n            { session }\n          );\n          return handleApiResult(resultFromDirectFunction, log); // This passes the nested telemetryData through\n        } catch (error) {\n          // ... error handling ...\n        }\n      })\n    });\n  }\n  ```\n\n### 4. CLI Commands (`scripts/modules/commands.js`)\n\nThese define the command-line interface.\n\n- **Actions**:\n    1.  Call the appropriate core logic function.\n    2.  Pass `outputFormat: 'text'` (or ensure the core function defaults to text-based output for CLI).\n    3.  The core logic function (as per Section 1) is responsible for calling `displayAiUsageSummary` if telemetry data is available and it's in CLI mode.\n    4.  The command action itself **should not** call `displayAiUsageSummary` if the core logic function already handles this. This avoids duplicate display.\n\n- **Example Snippet (CLI Command in `commands.js`)**:\n  ```javascript\n  // In scripts/modules/commands.js\n  import { performAiRelatedAction } from './task-manager/someAiAction.js'; // Core function\n\n  programInstance\n    .command('some-cli-ai-action')\n    // ... .option() ...\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot() || '.'; // Example root finding\n        // ... prepare parameters for core function from command options ...\n        await performAiRelatedAction(\n          { /* parameters for core function */ },\n          { // Context for core function\n            projectRoot,\n            commandNameFromContext: 'some-cli-ai-action',\n            outputType: 'cli'\n          },\n          'text' // Explicitly request text output format for CLI\n        );\n        // Core function handles displayAiUsageSummary internally for 'text' outputFormat\n      } catch (error) {\n        // ... error handling ...\n      }\n    });\n  ```\n\n## Summary Flow\n\nThe telemetry data flows as follows:\n\n1.  **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)**: Generates `telemetryData` and returns `{ mainResult, telemetryData }`.\n2.  **Core Logic Function**:\n    *   Receives `{ mainResult, telemetryData }`.\n    *   Uses `mainResult`.\n    *   If CLI (`outputFormat: 'text'`), calls `displayAiUsageSummary(telemetryData)`.\n    *   Returns `{ operationSpecificData, telemetryData }`.\n3.  **Direct Function Wrapper**:\n    *   Receives `{ operationSpecificData, telemetryData }` from core logic.\n    *   Returns `{ success: true, data: { operationSpecificData, telemetryData } }`.\n4.  **MCP Tool**:\n    *   Receives direct function response.\n    *   `handleApiResult` ensures the final MCP response to the client is `{ success: true, data: { operationSpecificData, telemetryData } }`.\n5.  **CLI Command**:\n    *   Calls core logic with `outputFormat: 'text'`. Display is handled by core logic.\n\nThis pattern ensures telemetry is captured and appropriately handled/exposed across all interaction modes.\n",".cursor/rules/test_workflow.mdc":"---\ndescription: \nglobs: \nalwaysApply: true\n---\n# Test Workflow & Development Process\n\n## **Initial Testing Framework Setup**\n\nBefore implementing the TDD workflow, ensure your project has a proper testing framework configured. This section covers setup for different technology stacks.\n\n### **Detecting Project Type & Framework Needs**\n\n**AI Agent Assessment Checklist:**\n1. **Language Detection**: Check for `package.json` (Node.js/JavaScript), `requirements.txt` (Python), `Cargo.toml` (Rust), etc.\n2. **Existing Tests**: Look for test files (`.test.`, `.spec.`, `_test.`) or test directories\n3. **Framework Detection**: Check for existing test runners in dependencies\n4. **Project Structure**: Analyze directory structure for testing patterns\n\n### **JavaScript/Node.js Projects (Jest Setup)**\n\n#### **Prerequisites Check**\n```bash\n# Verify Node.js project\nls package.json  # Should exist\n\n# Check for existing testing setup\nls jest.config.js jest.config.ts  # Check for Jest config\ngrep -E \"(jest|vitest|mocha)\" package.json  # Check for test runners\n```\n\n#### **Jest Installation & Configuration**\n\n**Step 1: Install Dependencies**\n```bash\n# Core Jest dependencies\nnpm install --save-dev jest\n\n# TypeScript support (if using TypeScript)\nnpm install --save-dev ts-jest @types/jest\n\n# Additional useful packages\nnpm install --save-dev supertest @types/supertest  # For API testing\nnpm install --save-dev jest-watch-typeahead  # Enhanced watch mode\n```\n\n**Step 2: Create Jest Configuration**\n\nCreate `jest.config.js` with the following production-ready configuration:\n\n```javascript\n/** @type {import('jest').Config} */\nmodule.exports = {\n  // Use ts-jest preset for TypeScript support\n  preset: 'ts-jest',\n\n  // Test environment\n  testEnvironment: 'node',\n\n  // Roots for test discovery\n  roots: ['<rootDir>/src', '<rootDir>/tests'],\n\n  // Test file patterns\n  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],\n\n  // Transform files\n  transform: {\n    '^.+\\\\.ts$': [\n      'ts-jest',\n      {\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          skipLibCheck: true,\n          strict: false,\n          noImplicitAny: false,\n        },\n      },\n    ],\n    '^.+\\\\.js$': [\n      'ts-jest',\n      {\n        useESM: false,\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          allowJs: true,\n        },\n      },\n    ],\n  },\n\n  // Module file extensions\n  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n\n  // Transform ignore patterns - adjust for ES modules\n  transformIgnorePatterns: ['node_modules/(?!(your-es-module-deps|.*\\\\.mjs$))'],\n\n  // Coverage configuration\n  collectCoverage: true,\n  coverageDirectory: 'coverage',\n  coverageReporters: [\n    'text', // Console output\n    'text-summary', // Brief summary\n    'lcov', // For IDE integration\n    'html', // Detailed HTML report\n  ],\n\n  // Files to collect coverage from\n  collectCoverageFrom: [\n    'src/**/*.ts',\n    '!src/**/*.d.ts',\n    '!src/**/*.test.ts',\n    '!src/**/index.ts', // Often just exports\n    '!src/generated/**', // Generated code\n    '!src/config/database.ts', // Database config (tested via integration)\n  ],\n\n  // Coverage thresholds - TaskMaster standards\n  coverageThreshold: {\n    global: {\n      branches: 70,\n      functions: 80,\n      lines: 80,\n      statements: 80,\n    },\n    // Higher standards for critical business logic\n    './src/utils/': {\n      branches: 85,\n      functions: 90,\n      lines: 90,\n      statements: 90,\n    },\n    './src/middleware/': {\n      branches: 80,\n      functions: 85,\n      lines: 85,\n      statements: 85,\n    },\n  },\n\n  // Setup files\n  setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],\n\n  // Global teardown to prevent worker process leaks\n  globalTeardown: '<rootDir>/tests/teardown.ts',\n\n  // Module path mapping (if needed)\n  moduleNameMapper: {\n    '^@/(.*)$': '<rootDir>/src/$1',\n  },\n\n  // Clear mocks between tests\n  clearMocks: true,\n\n  // Restore mocks after each test\n  restoreMocks: true,\n\n  // Global test timeout\n  testTimeout: 10000,\n\n  // Projects for different test types\n  projects: [\n    // Unit tests - for pure functions only\n    {\n      displayName: 'unit',\n      testMatch: ['<rootDir>/src/**/*.test.ts'],\n      testPathIgnorePatterns: ['.*\\\\.integration\\\\.test\\\\.ts$', '/tests/'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      collectCoverageFrom: [\n        'src/**/*.ts',\n        '!src/**/*.d.ts',\n        '!src/**/*.test.ts',\n        '!src/**/*.integration.test.ts',\n      ],\n      coverageThreshold: {\n        global: {\n          branches: 70,\n          functions: 80,\n          lines: 80,\n          statements: 80,\n        },\n      },\n    },\n    // Integration tests - real database/services\n    {\n      displayName: 'integration',\n      testMatch: [\n        '<rootDir>/src/**/*.integration.test.ts',\n        '<rootDir>/tests/integration/**/*.test.ts',\n      ],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/integration.ts'],\n      testTimeout: 10000,\n    },\n    // E2E tests - full workflows\n    {\n      displayName: 'e2e',\n      testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/e2e.ts'],\n      testTimeout: 30000,\n    },\n  ],\n\n  // Verbose output for better debugging\n  verbose: true,\n\n  // Run projects sequentially to avoid conflicts\n  maxWorkers: 1,\n\n  // Enable watch mode plugins\n  watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],\n};\n```\n\n**Step 3: Update package.json Scripts**\n\nAdd these scripts to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:coverage\": \"jest --coverage\",\n    \"test:unit\": \"jest --selectProjects unit\",\n    \"test:integration\": \"jest --selectProjects integration\", \n    \"test:e2e\": \"jest --selectProjects e2e\",\n    \"test:ci\": \"jest --ci --coverage --watchAll=false\"\n  }\n}\n```\n\n**Step 4: Create Test Setup Files**\n\nCreate essential test setup files:\n\n```typescript\n// tests/setup.ts - Global setup\nimport { jest } from '@jest/globals';\n\n// Global test configuration\nbeforeAll(() => {\n  // Set test timeout\n  jest.setTimeout(10000);\n});\n\nafterEach(() => {\n  // Clean up mocks after each test\n  jest.clearAllMocks();\n});\n```\n\n```typescript\n// tests/setup/integration.ts - Integration test setup\nimport { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nbeforeAll(async () => {\n  // Connect to test database\n  await prisma.$connect();\n});\n\nafterAll(async () => {\n  // Cleanup and disconnect\n  await prisma.$disconnect();\n});\n\nbeforeEach(async () => {\n  // Clean test data before each test\n  // Add your cleanup logic here\n});\n```\n\n```typescript\n// tests/teardown.ts - Global teardown\nexport default async () => {\n  // Global cleanup after all tests\n  console.log('Global test teardown complete');\n};\n```\n\n**Step 5: Create Initial Test Structure**\n\n```bash\n# Create test directories\nmkdir -p tests/{setup,fixtures,unit,integration,e2e}\nmkdir -p tests/unit/src/{utils,services,middleware}\n\n# Create sample test fixtures\nmkdir tests/fixtures\n```\n\n### **Generic Testing Framework Setup (Any Language)**\n\n#### **Framework Selection Guide**\n\n**Python Projects:**\n- **pytest**: Recommended for most Python projects\n- **unittest**: Built-in, suitable for simple projects\n- **Coverage**: Use `coverage.py` for code coverage\n\n```bash\n# Python setup example\npip install pytest pytest-cov\necho \"[tool:pytest]\" > pytest.ini\necho \"testpaths = tests\" >> pytest.ini\necho \"addopts = --cov=src --cov-report=html --cov-report=term\" >> pytest.ini\n```\n\n**Go Projects:**\n- **Built-in testing**: Use Go's built-in `testing` package\n- **Coverage**: Built-in with `go test -cover`\n\n```bash\n# Go setup example\ngo mod init your-project\nmkdir -p tests\n# Tests are typically *_test.go files alongside source\n```\n\n**Rust Projects:**\n- **Built-in testing**: Use Rust's built-in test framework\n- **cargo-tarpaulin**: For coverage analysis\n\n```bash\n# Rust setup example\ncargo new your-project\ncd your-project\ncargo install cargo-tarpaulin  # For coverage\n```\n\n**Java Projects:**\n- **JUnit 5**: Modern testing framework\n- **Maven/Gradle**: Build tools with testing integration\n\n```xml\n<!-- Maven pom.xml example -->\n<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter</artifactId>\n    <version>5.9.2</version>\n    <scope>test</scope>\n</dependency>\n```\n\n#### **Universal Testing Principles**\n\n**Coverage Standards (Adapt to Your Language):**\n- **Global Minimum**: 70-80% line coverage\n- **Critical Code**: 85-90% coverage\n- **New Features**: Must meet or exceed standards\n- **Legacy Code**: Gradual improvement strategy\n\n**Test Organization:**\n- **Unit Tests**: Fast, isolated, no external dependencies\n- **Integration Tests**: Test component interactions\n- **E2E Tests**: Test complete user workflows\n- **Performance Tests**: Load and stress testing (if applicable)\n\n**Naming Conventions:**\n- **Test Files**: `*.test.*`, `*_test.*`, or language-specific patterns\n- **Test Functions**: Descriptive names (e.g., `should_return_error_for_invalid_input`)\n- **Test Directories**: Organized by test type and mirroring source structure\n\n#### **TaskMaster Integration for Any Framework**\n\n**Document Testing Setup in Subtasks:**\n```bash\n# Update subtask with testing framework setup\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework setup:\n- Installed [Framework Name] with coverage support\n- Configured [Coverage Tool] with thresholds: 80% lines, 70% branches\n- Created test directory structure: unit/, integration/, e2e/\n- Added test scripts to build configuration\n- All setup tests passing\"\n```\n\n**Testing Framework Verification:**\n```bash\n# Verify setup works\n[test-command]  # e.g., npm test, pytest, go test, cargo test\n\n# Check coverage reporting\n[coverage-command]  # e.g., npm run test:coverage\n\n# Update task with verification\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework verified:\n- Sample tests running successfully\n- Coverage reporting functional\n- CI/CD integration ready\n- Ready to begin TDD workflow\"\n```\n\n## **Test-Driven Development (TDD) Integration**\n\n### **Core TDD Cycle with Jest**\n```bash\n# 1. Start development with watch mode\nnpm run test:watch\n\n# 2. Write failing test first\n# Create test file: src/utils/newFeature.test.ts\n# Write test that describes expected behavior\n\n# 3. Implement minimum code to make test pass\n# 4. Refactor while keeping tests green\n# 5. Add edge cases and error scenarios\n```\n\n### **TDD Workflow Per Subtask**\n```bash\n# When starting a new subtask:\ntask-master set-status --id=4.1 --status=in-progress\n\n# Begin TDD cycle:\nnpm run test:watch  # Keep running during development\n\n# Document TDD progress in subtask:\ntask-master update-subtask --id=4.1 --prompt=\"TDD Progress:\n- Written 3 failing tests for core functionality\n- Implemented basic feature, tests now passing\n- Adding edge case tests for error handling\"\n\n# Complete subtask with test summary:\ntask-master update-subtask --id=4.1 --prompt=\"Implementation complete:\n- Feature implemented with 8 unit tests\n- Coverage: 95% statements, 88% branches  \n- All tests passing, TDD cycle complete\"\n```\n\n## **Testing Commands & Usage**\n\n### **Development Commands**\n```bash\n# Primary development command - use during coding\nnpm run test:watch              # Watch mode with Jest\nnpm run test:watch -- --testNamePattern=\"auth\"  # Watch specific tests\n\n# Targeted testing during development\nnpm run test:unit               # Run only unit tests\nnpm run test:unit -- --coverage # Unit tests with coverage\n\n# Integration testing when APIs are ready\nnpm run test:integration        # Run integration tests\nnpm run test:integration -- --detectOpenHandles  # Debug hanging tests\n\n# End-to-end testing for workflows\nnpm run test:e2e               # Run E2E tests\nnpm run test:e2e -- --timeout=30000  # Extended timeout for E2E\n```\n\n### **Quality Assurance Commands**\n```bash\n# Full test suite with coverage (before commits)\nnpm run test:coverage          # Complete coverage analysis\n\n# All tests (CI/CD pipeline)\nnpm test                       # Run all test projects\n\n# Specific test file execution\nnpm test -- auth.test.ts       # Run specific test file\nnpm test -- --testNamePattern=\"should handle errors\"  # Run specific tests\n```\n\n## **Test Implementation Patterns**\n\n### **Unit Test Development**\n```typescript\n// ✅ DO: Follow established patterns from auth.test.ts\ndescribe('FeatureName', () => {\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Setup mocks with proper typing\n  });\n\n  describe('functionName', () => {\n    it('should handle normal case', () => {\n      // Test implementation with specific assertions\n    });\n    \n    it('should throw error for invalid input', async () => {\n      // Error scenario testing\n      await expect(functionName(invalidInput))\n        .rejects.toThrow('Specific error message');\n    });\n  });\n});\n```\n\n### **Integration Test Development**  \n```typescript\n// ✅ DO: Use supertest for API endpoint testing\nimport request from 'supertest';\nimport { app } from '../../src/app';\n\ndescribe('POST /api/auth/register', () => {\n  beforeEach(async () => {\n    await integrationTestUtils.cleanupTestData();\n  });\n  \n  it('should register user successfully', async () => {\n    const userData = createTestUser();\n    \n    const response = await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n      \n    expect(response.body).toMatchObject({\n      id: expect.any(String),\n      email: userData.email\n    });\n    \n    // Verify database state\n    const user = await prisma.user.findUnique({\n      where: { email: userData.email }\n    });\n    expect(user).toBeTruthy();\n  });\n});\n```\n\n### **E2E Test Development**\n```typescript\n// ✅ DO: Test complete user workflows\ndescribe('User Authentication Flow', () => {\n  it('should complete registration → login → protected access', async () => {\n    // Step 1: Register\n    const userData = createTestUser();\n    await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n    \n    // Step 2: Login\n    const loginResponse = await request(app)\n      .post('/api/auth/login')\n      .send({ email: userData.email, password: userData.password })\n      .expect(200);\n    \n    const { token } = loginResponse.body;\n    \n    // Step 3: Access protected resource\n    await request(app)\n      .get('/api/profile')\n      .set('Authorization', `Bearer ${token}`)\n      .expect(200);\n  }, 30000); // Extended timeout for E2E\n});\n```\n\n## **Mocking & Test Utilities**\n\n### **Established Mocking Patterns**\n```typescript\n// ✅ DO: Use established bcrypt mocking pattern\njest.mock('bcrypt');\nimport bcrypt from 'bcrypt';\nconst mockHash = bcrypt.hash as jest.MockedFunction<typeof bcrypt.hash>;\nconst mockCompare = bcrypt.compare as jest.MockedFunction<typeof bcrypt.compare>;\n\n// ✅ DO: Use Prisma mocking for unit tests\njest.mock('@prisma/client', () => ({\n  PrismaClient: jest.fn().mockImplementation(() => ({\n    user: {\n      create: jest.fn(),\n      findUnique: jest.fn(),\n    },\n    $connect: jest.fn(),\n    $disconnect: jest.fn(),\n  })),\n}));\n```\n\n### **Test Fixtures Usage**\n```typescript\n// ✅ DO: Use centralized test fixtures\nimport { createTestUser, adminUser, invalidUser } from '../fixtures/users';\n\ndescribe('User Service', () => {\n  it('should handle admin user creation', async () => {\n    const userData = createTestUser(adminUser);\n    // Test implementation\n  });\n  \n  it('should reject invalid user data', async () => {\n    const userData = createTestUser(invalidUser);\n    // Error testing\n  });\n});\n```\n\n## **Coverage Standards & Monitoring**\n\n### **Coverage Thresholds**\n- **Global Standards**: 80% lines/functions, 70% branches\n- **Critical Code**: 90% utils, 85% middleware\n- **New Features**: Must meet or exceed global thresholds\n- **Legacy Code**: Gradual improvement with each change\n\n### **Coverage Reporting & Analysis**\n```bash\n# Generate coverage reports\nnpm run test:coverage\n\n# View detailed HTML report\nopen coverage/lcov-report/index.html\n\n# Coverage files generated:\n# - coverage/lcov-report/index.html  # Detailed HTML report\n# - coverage/lcov.info               # LCOV format for IDE integration  \n# - coverage/coverage-final.json     # JSON format for tooling\n```\n\n### **Coverage Quality Checks**\n```typescript\n// ✅ DO: Test all code paths\ndescribe('validateInput', () => {\n  it('should return true for valid input', () => {\n    expect(validateInput('valid')).toBe(true);\n  });\n  \n  it('should return false for various invalid inputs', () => {\n    expect(validateInput('')).toBe(false);      // Empty string\n    expect(validateInput(null)).toBe(false);    // Null value\n    expect(validateInput(undefined)).toBe(false); // Undefined\n  });\n  \n  it('should throw for unexpected input types', () => {\n    expect(() => validateInput(123)).toThrow('Invalid input type');\n  });\n});\n```\n\n## **Testing During Development Phases**\n\n### **Feature Development Phase**\n```bash\n# 1. Start feature development\ntask-master set-status --id=X.Y --status=in-progress\n\n# 2. Begin TDD cycle  \nnpm run test:watch\n\n# 3. Document test progress in subtask\ntask-master update-subtask --id=X.Y --prompt=\"Test development:\n- Created test file with 5 failing tests\n- Implemented core functionality\n- Tests passing, adding error scenarios\"\n\n# 4. Verify coverage before completion\nnpm run test:coverage\n\n# 5. Update subtask with final test status\ntask-master update-subtask --id=X.Y --prompt=\"Testing complete:\n- 12 unit tests with full coverage\n- All edge cases and error scenarios covered\n- Ready for integration testing\"\n```\n\n### **Integration Testing Phase**\n```bash\n# After API endpoints are implemented\nnpm run test:integration\n\n# Update integration test templates\n# Replace placeholder tests with real endpoint calls\n\n# Document integration test results\ntask-master update-subtask --id=X.Y --prompt=\"Integration tests:\n- Updated auth endpoint tests  \n- Database integration verified\n- All HTTP status codes and responses tested\"\n```\n\n### **Pre-Commit Testing Phase**\n```bash\n# Before committing code\nnpm run test:coverage         # Verify all tests pass with coverage\nnpm run test:unit            # Quick unit test verification\nnpm run test:integration     # Integration test verification (if applicable)\n\n# Commit pattern for test updates\ngit add tests/ src/**/*.test.ts\ngit commit -m \"test(task-X): Add comprehensive tests for Feature Y\n\n- Unit tests with 95% coverage (exceeds 90% threshold)\n- Integration tests for API endpoints\n- Test fixtures for data generation\n- Proper mocking patterns established\n\nTask X: Feature Y - Testing complete\"\n```\n\n## **Error Handling & Debugging**\n\n### **Test Debugging Techniques**\n```typescript\n// ✅ DO: Use test utilities for debugging\nimport { testUtils } from '../setup';\n\nit('should debug complex operation', () => {\n  testUtils.withConsole(() => {\n    // Console output visible only for this test\n    console.log('Debug info:', complexData);\n    service.complexOperation();\n  });\n});\n\n// ✅ DO: Use proper async debugging\nit('should handle async operations', async () => {\n  const promise = service.asyncOperation();\n  \n  // Test intermediate state\n  expect(service.isProcessing()).toBe(true);\n  \n  const result = await promise;\n  expect(result).toBe('expected');\n  expect(service.isProcessing()).toBe(false);\n});\n```\n\n### **Common Test Issues & Solutions**\n```bash\n# Hanging tests (common with database connections)\nnpm run test:integration -- --detectOpenHandles\n\n# Memory leaks in tests\nnpm run test:unit -- --logHeapUsage\n\n# Slow tests identification\nnpm run test:coverage -- --verbose\n\n# Mock not working properly\n# Check: mock is declared before imports\n# Check: jest.clearAllMocks() in beforeEach\n# Check: TypeScript typing is correct\n```\n\n## **Continuous Integration Integration**\n\n### **CI/CD Pipeline Testing**\n```yaml\n# Example GitHub Actions integration\n- name: Run tests\n  run: |\n    npm ci\n    npm run test:coverage\n    \n- name: Upload coverage reports\n  uses: codecov/codecov-action@v3\n  with:\n    file: ./coverage/lcov.info\n```\n\n### **Pre-commit Hooks**\n```bash\n# Setup pre-commit testing (recommended)\n# In package.json scripts:\n\"pre-commit\": \"npm run test:unit && npm run test:integration\"\n\n# Husky integration example:\nnpx husky add .husky/pre-commit \"npm run test:unit\"\n```\n\n## **Test Maintenance & Evolution**\n\n### **Adding Tests for New Features**\n1. **Create test file** alongside source code or in `tests/unit/`\n2. **Follow established patterns** from `src/utils/auth.test.ts`\n3. **Use existing fixtures** from `tests/fixtures/`\n4. **Apply proper mocking** patterns for dependencies\n5. **Meet coverage thresholds** for the module\n\n### **Updating Integration/E2E Tests**\n1. **Update templates** in `tests/integration/` when APIs change\n2. **Modify E2E workflows** in `tests/e2e/` for new user journeys  \n3. **Update test fixtures** for new data requirements\n4. **Maintain database cleanup** utilities\n\n### **Test Performance Optimization**\n- **Parallel execution**: Jest runs tests in parallel by default\n- **Test isolation**: Use proper setup/teardown for independence\n- **Mock optimization**: Mock heavy dependencies appropriately  \n- **Database efficiency**: Use transaction rollbacks where possible\n\n---\n\n**Key References:**\n- [Testing Standards](mdc:.cursor/rules/tests.mdc)\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc)\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Jest Configuration](mdc:jest.config.js)",".cursor/rules/tests.mdc":"---\ndescription: Guidelines for implementing and maintaining tests for Task Master CLI\nglobs: \"**/*.test.js,tests/**/*\"\n---\n\n# Testing Guidelines for Task Master CLI\n\n*Note:* Never use asynchronous operations in tests. Always mock tests properly based on the way the tested functions are defined and used. Do not arbitrarily create tests. Based them on the low-level details and execution of the underlying code being tested. \n\n## Test Organization Structure\n\n- **Unit Tests** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module breakdown)\n  - Located in `tests/unit/`\n  - Test individual functions and utilities in isolation\n  - Mock all external dependencies\n  - Keep tests small, focused, and fast\n  - Example naming: `utils.test.js`, `task-manager.test.js`\n\n- **Integration Tests**\n  - Located in `tests/integration/`\n  - Test interactions between modules\n  - Focus on component interfaces rather than implementation details\n  - Use more realistic but still controlled test environments\n  - Example naming: `task-workflow.test.js`, `command-integration.test.js`\n\n- **End-to-End Tests**\n  - Located in `tests/e2e/`\n  - Test complete workflows from a user perspective\n  - Focus on CLI commands as they would be used by users\n  - Example naming: `create-task.e2e.test.js`, `expand-task.e2e.test.js`\n\n- **Test Fixtures**\n  - Located in `tests/fixtures/`\n  - Provide reusable test data\n  - Keep fixtures small and representative\n  - Export fixtures as named exports for reuse\n\n## Test File Organization\n\n```javascript\n// 1. Imports\nimport { jest } from '@jest/globals';\n\n// 2. Mock setup (MUST come before importing the modules under test)\njest.mock('fs');\njest.mock('@anthropic-ai/sdk');\njest.mock('../../scripts/modules/utils.js', () => ({\n  CONFIG: {\n    projectVersion: '1.5.0'\n  },\n  log: jest.fn()\n}));\n\n// 3. Import modules AFTER all mocks are defined\nimport { functionToTest } from '../../scripts/modules/module-name.js';\nimport { testFixture } from '../fixtures/fixture-name.js';\nimport fs from 'fs';\n\n// 4. Set up spies on mocked modules (if needed)\nconst mockReadFileSync = jest.spyOn(fs, 'readFileSync');\n\n// 5. Test suite with descriptive name\ndescribe('Feature or Function Name', () => {\n  // 6. Setup and teardown (if needed)\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Additional setup code\n  });\n  \n  afterEach(() => {\n    // Cleanup code\n  });\n  \n  // 7. Grouped tests for related functionality\n  describe('specific functionality', () => {\n    // 8. Individual test cases with clear descriptions\n    test('should behave in expected way when given specific input', () => {\n      // Arrange - set up test data\n      const input = testFixture.sampleInput;\n      mockReadFileSync.mockReturnValue('mocked content');\n      \n      // Act - call the function being tested\n      const result = functionToTest(input);\n      \n      // Assert - verify the result\n      expect(result).toBe(expectedOutput);\n      expect(mockReadFileSync).toHaveBeenCalledWith(expect.stringContaining('path'));\n    });\n  });\n});\n```\n\n## Commander.js Command Testing Best Practices\n\nWhen testing CLI commands built with Commander.js, several special considerations must be made to avoid common pitfalls:\n\n- **Direct Action Handler Testing**\n  - ✅ **DO**: Test the command action handlers directly rather than trying to mock the entire Commander.js chain\n  - ✅ **DO**: Create simplified test-specific implementations of command handlers that match the original behavior\n  - ✅ **DO**: Explicitly handle all options, including defaults and shorthand flags (e.g., `-p` for `--prompt`)\n  - ✅ **DO**: Include null/undefined checks in test implementations for parameters that might be optional\n  - ✅ **DO**: Use fixtures from `tests/fixtures/` for consistent sample data across tests\n  \n  ```javascript\n  // ✅ DO: Create a simplified test version of the command handler\n  const testAddTaskAction = async (options) => {\n    options = options || {}; // Ensure options aren't undefined\n    \n    // Validate parameters\n    const isManualCreation = options.title && options.description;\n    const prompt = options.prompt || options.p; // Handle shorthand flags\n    \n    if (!prompt && !isManualCreation) {\n      throw new Error('Expected error message');\n    }\n    \n    // Call the mocked task manager\n    return mockTaskManager.addTask(/* parameters */);\n  };\n  \n  test('should handle required parameters correctly', async () => {\n    // Call the test implementation directly\n    await expect(async () => {\n      await testAddTaskAction({ file: 'tasks.json' });\n    }).rejects.toThrow('Expected error message');\n  });\n  ```\n\n- **Commander Chain Mocking (If Necessary)**\n  - ✅ **DO**: Mock ALL chainable methods (`option`, `argument`, `action`, `on`, etc.)\n  - ✅ **DO**: Return `this` (or the mock object) from all chainable method mocks\n  - ✅ **DO**: Remember to mock not only the initial object but also all objects returned by methods\n  - ✅ **DO**: Implement a mechanism to capture the action handler for direct testing\n  \n  ```javascript\n  // If you must mock the Commander.js chain:\n  const mockCommand = {\n    command: jest.fn().mockReturnThis(),\n    description: jest.fn().mockReturnThis(),\n    option: jest.fn().mockReturnThis(),\n    argument: jest.fn().mockReturnThis(), // Don't forget this one\n    action: jest.fn(fn => { \n      actionHandler = fn; // Capture the handler for testing\n      return mockCommand; \n    }),\n    on: jest.fn().mockReturnThis() // Don't forget this one\n  };\n  ```\n\n- **Parameter Handling**\n  - ✅ **DO**: Check for both main flag and shorthand flags (e.g., `prompt` and `p`)\n  - ✅ **DO**: Handle parameters like Commander would (comma-separated lists, etc.)\n  - ✅ **DO**: Set proper default values as defined in the command\n  - ✅ **DO**: Validate that required parameters are actually required in tests\n  \n  ```javascript\n  // Parse dependencies like Commander would\n  const dependencies = options.dependencies \n    ? options.dependencies.split(',').map(id => id.trim())\n    : [];\n  ```\n\n- **Environment and Session Handling**\n  - ✅ **DO**: Properly mock session objects when required by functions\n  - ✅ **DO**: Reset environment variables between tests if modified\n  - ✅ **DO**: Use a consistent pattern for environment-dependent tests\n  \n  ```javascript\n  // Session parameter mock pattern\n  const sessionMock = { session: process.env };\n  \n  // In test:\n  expect(mockAddTask).toHaveBeenCalledWith(\n    expect.any(String),\n    'Test prompt',\n    [],\n    'medium',\n    sessionMock,\n    false,\n    null,\n    null\n  );\n  ```\n\n- **Common Pitfalls to Avoid**\n  - ❌ **DON'T**: Try to use the real action implementation without proper mocking\n  - ❌ **DON'T**: Mock Commander partially - either mock it completely or test the action directly\n  - ❌ **DON'T**: Forget to handle optional parameters that may be undefined\n  - ❌ **DON'T**: Neglect to test shorthand flag functionality (e.g., `-p`, `-r`)\n  - ❌ **DON'T**: Create circular dependencies in your test mocks\n  - ❌ **DON'T**: Access variables before initialization in your test implementations\n  - ❌ **DON'T**: Include actual command execution in unit tests\n  - ❌ **DON'T**: Overwrite the same file path in multiple tests\n  \n  ```javascript\n  // ❌ DON'T: Create circular references in mocks\n  const badMock = {\n    method: jest.fn().mockImplementation(() => badMock.method())\n  };\n  \n  // ❌ DON'T: Access uninitialized variables\n  const badImplementation = () => {\n    const result = uninitialized;\n    let uninitialized = 'value';\n    return result;\n  };\n  ```\n\n## Jest Module Mocking Best Practices\n\n- **Mock Hoisting Behavior**\n  - Jest hoists `jest.mock()` calls to the top of the file, even above imports\n  - Always declare mocks before importing the modules being tested\n  - Use the factory pattern for complex mocks that need access to other variables\n\n  ```javascript\n  // ✅ DO: Place mocks before imports\n  jest.mock('commander');\n  import { program } from 'commander';\n  \n  // ❌ DON'T: Define variables and then try to use them in mocks\n  const mockFn = jest.fn();\n  jest.mock('module', () => ({\n    func: mockFn // This won't work due to hoisting!\n  }));\n  ```\n\n- **Mocking Modules with Function References**\n  - Use `jest.spyOn()` after imports to create spies on mock functions\n  - Reference these spies in test assertions\n  \n  ```javascript\n  // Mock the module first\n  jest.mock('fs');\n  \n  // Import the mocked module\n  import fs from 'fs';\n  \n  // Create spies on the mock functions\n  const mockExistsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(true);\n  \n  test('should call existsSync', () => {\n    // Call function that uses fs.existsSync\n    const result = functionUnderTest();\n    \n    // Verify the mock was called correctly\n    expect(mockExistsSync).toHaveBeenCalled();\n  });\n  ```\n\n- **Testing Functions with Callbacks**\n  - Get the callback from your mock's call arguments\n  - Execute it directly with test inputs\n  - Verify the results match expectations\n  \n  ```javascript\n  jest.mock('commander');\n  import { program } from 'commander';\n  import { setupCLI } from '../../scripts/modules/commands.js';\n  \n  const mockVersion = jest.spyOn(program, 'version').mockReturnValue(program);\n  \n  test('version callback should return correct version', () => {\n    // Call the function that registers the callback\n    setupCLI();\n    \n    // Extract the callback function\n    const versionCallback = mockVersion.mock.calls[0][0];\n    expect(typeof versionCallback).toBe('function');\n    \n    // Execute the callback and verify results\n    const result = versionCallback();\n    expect(result).toBe('1.5.0');\n  });\n  ```\n\n## ES Module Testing Strategies\n\nWhen testing ES modules (`\"type\": \"module\"` in package.json), traditional mocking approaches require special handling to avoid reference and scoping issues.\n\n- **Module Import Challenges**\n  - Functions imported from ES modules may still reference internal module-scoped variables\n  - Imported functions may not use your mocked dependencies even with proper jest.mock() setup\n  - ES module exports are read-only properties (cannot be reassigned during tests)\n\n- **Mocking Modules Statically Imported**\n  - For modules imported with standard `import` statements at the top level:\n    - Use `jest.mock('path/to/module', factory)` **before** any imports.\n    - Jest hoists these mocks.\n    - Ensure the factory function returns the mocked structure correctly.\n\n- **Mocking Dependencies for Dynamically Imported Modules**\n  - **Problem**: Standard `jest.mock()` often fails for dependencies of modules loaded later using dynamic `import('path/to/module')`. The mocks aren't applied correctly when the dynamic import resolves.\n  - **Solution**: Use `jest.unstable_mockModule(modulePath, factory)` **before** the dynamic `import()` call.\n  ```javascript\n  // 1. Define mock function instances\n  const mockExistsSync = jest.fn();\n  const mockReadFileSync = jest.fn();\n  // ... other mocks\n\n  // 2. Mock the dependency module *before* the dynamic import\n  jest.unstable_mockModule('fs', () => ({\n    __esModule: true, // Important for ES module mocks\n    // Mock named exports\n    existsSync: mockExistsSync,\n    readFileSync: mockReadFileSync,\n    // Mock default export if necessary\n    // default: { ... }\n  }));\n\n  // 3. Dynamically import the module under test (e.g., in beforeAll or test case)\n  let moduleUnderTest;\n  beforeAll(async () => {\n    // Ensure mocks are reset if needed before import\n    mockExistsSync.mockReset();\n    mockReadFileSync.mockReset();\n    // ... reset other mocks ...\n\n    // Import *after* unstable_mockModule is called\n    moduleUnderTest = await import('../../scripts/modules/module-using-fs.js');\n  });\n\n  // 4. Now tests can use moduleUnderTest, and its 'fs' calls will hit the mocks\n  test('should use mocked fs.readFileSync', () => {\n    mockReadFileSync.mockReturnValue('mock data');\n    moduleUnderTest.readFileAndProcess();\n    expect(mockReadFileSync).toHaveBeenCalled();\n    // ... other assertions\n  });\n  ```\n  - ✅ **DO**: Call `jest.unstable_mockModule()` before `await import()`.\n  - ✅ **DO**: Include `__esModule: true` in the mock factory for ES modules.\n  - ✅ **DO**: Mock named and default exports as needed within the factory.\n  - ✅ **DO**: Reset mock functions (`mockFn.mockReset()`) before the dynamic import if they might have been called previously.\n\n- **Mocking Entire Modules (Static Import)**\n  ```javascript\n  // Mock the entire module with custom implementation for static imports\n  // ... (existing example remains valid) ...\n  ```\n\n- **Direct Implementation Testing**\n  - Instead of calling the actual function which may have module-scope reference issues:\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Avoiding Module Property Assignment**\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Handling Mock Verification Failures**\n  - If verification like `expect(mockFn).toHaveBeenCalled()` fails:\n    1.  Check that your mock setup (`jest.mock` or `jest.unstable_mockModule`) is correctly placed **before** imports (static or dynamic).\n    2.  Ensure you're using the right mock instance and it's properly passed to the module.\n    3.  Verify your test invokes behavior that *should* call the mock.\n    4.  Use `jest.clearAllMocks()` or specific `mockFn.mockReset()` in `beforeEach` to prevent state leakage between tests.\n    5.  **Check Console Assertions**: If verifying `console.log`, `console.warn`, or `console.error` calls, ensure your assertion matches the *actual* arguments passed. If the code logs a single formatted string, assert against that single string (using `expect.stringContaining` or exact match), not multiple `expect.stringContaining` arguments.\n        ```javascript\n        // Example: Code logs console.error(`Error: ${message}. Details: ${details}`)\n        // ❌ DON'T: Assert multiple arguments if only one is logged\n        // expect(console.error).toHaveBeenCalledWith(\n        //   expect.stringContaining('Error:'),\n        //   expect.stringContaining('Details:')\n        // );\n        // ✅ DO: Assert the single string argument\n        expect(console.error).toHaveBeenCalledWith(\n           expect.stringContaining('Error: Specific message. Details: More details')\n        );\n        // or for exact match:\n        expect(console.error).toHaveBeenCalledWith(\n           'Error: Specific message. Details: More details'\n        );\n        ```\n    6.  Consider implementing a simpler test that *only* verifies the mock behavior in isolation.\n\n## Mocking Guidelines\n\n- **File System Operations**\n  ```javascript\n  import mockFs from 'mock-fs';\n  \n  beforeEach(() => {\n    mockFs({\n      'tasks': {\n        'tasks.json': JSON.stringify({\n          meta: { projectName: 'Test Project' },\n          tasks: []\n        })\n      }\n    });\n  });\n  \n  afterEach(() => {\n    mockFs.restore();\n  });\n  ```\n\n- **API Calls (Anthropic/Claude)**\n  ```javascript\n  import { Anthropic } from '@anthropic-ai/sdk';\n  \n  jest.mock('@anthropic-ai/sdk');\n  \n  beforeEach(() => {\n    Anthropic.mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ text: 'Mocked response' }]\n        })\n      }\n    }));\n  });\n  ```\n\n- **Environment Variables**\n  ```javascript\n  const originalEnv = process.env;\n  \n  beforeEach(() => {\n    jest.resetModules();\n    process.env = { ...originalEnv };\n    process.env.MODEL = 'test-model';\n  });\n  \n  afterEach(() => {\n    process.env = originalEnv;\n  });\n  ```\n\n## Testing Common Components\n\n- **CLI Commands**\n  - Mock the action handlers (defined in [`commands.js`](mdc:scripts/modules/commands.js)) and verify they're called with correct arguments\n  - Test command registration and option parsing\n  - Use `commander` test utilities or custom mocks\n\n- **Task Operations**\n  - Use sample task fixtures for consistent test data\n  - Mock file system operations\n  - Test both success and error paths\n\n- **UI Functions**\n  - Mock console output and verify correct formatting\n  - Test conditional output logic\n  - When testing strings with emojis or formatting, use `toContain()` or `toMatch()` rather than exact `toBe()` comparisons\n  - For functions with different behavior modes (e.g., `forConsole`, `forTable` parameters), create separate tests for each mode\n  - Test the structure of formatted output (e.g., check that it's a comma-separated list with the right number of items) rather than exact string matching\n  - When testing chalk-formatted output, remember that strict equality comparison (`toBe()`) can fail even when the visible output looks identical\n  - Consider using more flexible assertions like checking for the presence of key elements when working with styled text\n  - Mock chalk functions to return the input text to make testing easier while still verifying correct function calls\n\n## Test Quality Guidelines\n\n- ✅ **DO**: Write tests before implementing features (TDD approach when possible)\n- ✅ **DO**: Test edge cases and error conditions, not just happy paths\n- ✅ **DO**: Keep tests independent and isolated from each other\n- ✅ **DO**: Use descriptive test names that explain the expected behavior\n- ✅ **DO**: Maintain test fixtures separate from test logic\n- ✅ **DO**: Aim for 80%+ code coverage, with critical paths at 100%\n- ✅ **DO**: Follow the mock-first-then-import pattern for all Jest mocks\n\n- ❌ **DON'T**: Test implementation details that might change\n- ❌ **DON'T**: Write brittle tests that depend on specific output formatting\n- ❌ **DON'T**: Skip testing error handling and validation\n- ❌ **DON'T**: Duplicate test fixtures across multiple test files\n- ❌ **DON'T**: Write tests that depend on execution order\n- ❌ **DON'T**: Define mock variables before `jest.mock()` calls (they won't be accessible due to hoisting)\n\n\n- **Task File Operations**\n  - ✅ DO: Use test-specific file paths (e.g., 'test-tasks.json') for all operations\n  - ✅ DO: Mock `readJSON` and `writeJSON` to avoid real file system interactions\n  - ✅ DO: Verify file operations use the correct paths in `expect` statements\n  - ✅ DO: Use different paths for each test to avoid test interdependence\n  - ✅ DO: Verify modifications on the in-memory task objects passed to `writeJSON`\n  - ❌ DON'T: Modify real task files (tasks.json) during tests\n  - ❌ DON'T: Skip testing file operations because they're \"just I/O\"\n  \n  ```javascript\n  // ✅ DO: Test file operations without real file system changes\n  test('should update task status in tasks.json', async () => {\n    // Setup mock to return sample data\n    readJSON.mockResolvedValue(JSON.parse(JSON.stringify(sampleTasks)));\n    \n    // Use test-specific file path\n    await setTaskStatus('test-tasks.json', '2', 'done');\n    \n    // Verify correct file path was read\n    expect(readJSON).toHaveBeenCalledWith('test-tasks.json');\n    \n    // Verify correct file path was written with updated content\n    expect(writeJSON).toHaveBeenCalledWith(\n      'test-tasks.json',\n      expect.objectContaining({\n        tasks: expect.arrayContaining([\n          expect.objectContaining({\n            id: 2,\n            status: 'done'\n          })\n        ])\n      })\n    );\n  });\n  ```\n\n## Running Tests\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Run tests with coverage reporting\nnpm run test:coverage\n\n# Run a specific test file\nnpm test -- tests/unit/specific-file.test.js\n\n# Run tests matching a pattern\nnpm test -- -t \"pattern to match\"\n```\n\n## Troubleshooting Test Issues\n\n- **Mock Functions Not Called**\n  - Ensure mocks are defined before imports (Jest hoists `jest.mock()` calls)\n  - Check that you're referencing the correct mock instance\n  - Verify the import paths match exactly\n\n- **Unexpected Mock Behavior**\n  - Clear mocks between tests with `jest.clearAllMocks()` in `beforeEach`\n  - Check mock implementation for conditional behavior\n  - Ensure mock return values are correctly configured for each test\n\n- **Tests Affecting Each Other**\n  - Isolate tests by properly mocking shared resources\n  - Reset state in `beforeEach` and `afterEach` hooks\n  - Avoid global state modifications\n\n## Common Testing Pitfalls and Solutions\n\n- **Complex Library Mocking**\n  - **Problem**: Trying to create full mocks of complex libraries like Commander.js can be error-prone\n  - **Solution**: Instead of mocking the entire library, test the command handlers directly by calling your action handlers with the expected arguments\n  ```javascript\n  // ❌ DON'T: Create complex mocks of Commander.js\n  class MockCommand {\n    constructor() { /* Complex mock implementation */ }\n    option() { /* ... */ }\n    action() { /* ... */ }\n    // Many methods to implement\n  }\n  \n  // ✅ DO: Test the command handlers directly\n  test('should use default PRD path when no arguments provided', async () => {\n    // Call the action handler directly with the right params\n    await parsePrdAction(undefined, { numTasks: '10', output: 'tasks/tasks.json' });\n    \n    // Assert on behavior\n    expect(mockParsePRD).toHaveBeenCalledWith('scripts/prd.txt', 'tasks/tasks.json', 10);\n  });\n  ```\n\n- **ES Module Mocking Challenges**\n  - **Problem**: ES modules don't support `require()` and imports are read-only\n  - **Solution**: Use Jest's module factory pattern and ensure mocks are defined before imports\n  ```javascript\n  // ❌ DON'T: Try to modify imported modules\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  detectCamelCaseFlags = jest.fn(); // Error: Assignment to constant variable\n  \n  // ❌ DON'T: Try to use require with ES modules\n  const utils = require('../../scripts/modules/utils.js'); // Error in ES modules\n  \n  // ✅ DO: Use Jest module factory pattern\n  jest.mock('../../scripts/modules/utils.js', () => ({\n    detectCamelCaseFlags: jest.fn(),\n    toKebabCase: jest.fn()\n  }));\n  \n  // Import after mocks are defined\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  ```\n\n- **Function Redeclaration Errors**\n  - **Problem**: Declaring the same function twice in a test file causes errors\n  - **Solution**: Use different function names or create local test-specific implementations\n  ```javascript\n  // ❌ DON'T: Redefine imported functions with the same name\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  \n  function detectCamelCaseFlags() { /* Test implementation */ }\n  // Error: Identifier has already been declared\n  \n  // ✅ DO: Use a different name for test implementations\n  function testDetectCamelCaseFlags() { /* Test implementation */ }\n  ```\n\n- **Console.log Circular References**\n  - **Problem**: Creating infinite recursion by spying on console.log while also allowing it to log\n  - **Solution**: Implement a mock that doesn't call the original function\n  ```javascript\n  // ❌ DON'T: Create circular references with console.log\n  const mockConsoleLog = jest.spyOn(console, 'log');\n  mockConsoleLog.mockImplementation(console.log); // Creates infinite recursion\n  \n  // ✅ DO: Use a non-recursive mock implementation\n  const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => {});\n  ```\n\n- **Mock Function Method Issues**\n  - **Problem**: Trying to use jest.fn() methods on imported functions that aren't properly mocked\n  - **Solution**: Create explicit jest.fn() mocks for functions you need to call jest methods on\n  ```javascript\n  // ❌ DON'T: Try to use jest methods on imported functions without proper mocking\n  import { parsePRD } from '../../scripts/modules/task-manager.js';\n  parsePRD.mockClear(); // Error: parsePRD.mockClear is not a function\n  \n  // ✅ DO: Create proper jest.fn() mocks\n  const mockParsePRD = jest.fn().mockResolvedValue(undefined);\n  jest.mock('../../scripts/modules/task-manager.js', () => ({\n    parsePRD: mockParsePRD\n  }));\n  // Now you can use:\n  mockParsePRD.mockClear();\n  ```\n\n- **EventEmitter Max Listeners Warning**\n  - **Problem**: Commander.js adds many listeners in complex mocks, causing warnings\n  - **Solution**: Either increase the max listeners limit or avoid deep mocking\n  ```javascript\n  // Option 1: Increase max listeners if you must mock Commander\n  class MockCommand extends EventEmitter {\n    constructor() {\n      super();\n      this.setMaxListeners(20); // Avoid MaxListenersExceededWarning\n    }\n  }\n  \n  // Option 2 (preferred): Test command handlers directly instead\n  // (as shown in the first example)\n  ```\n\n- **Test Isolation Issues**\n  - **Problem**: Tests affecting each other due to shared mock state\n  - **Solution**: Reset all mocks in beforeEach and use separate test-specific mocks\n  ```javascript\n  // ❌ DON'T: Allow mock state to persist between tests\n  const globalMock = jest.fn().mockReturnValue('test');\n  \n  // ✅ DO: Clear mocks before each test\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Set up test-specific mock behavior\n    mockFunction.mockReturnValue('test-specific value');\n  });\n  ```\n\n## Testing AI Service Integrations\n\n- **DO NOT import real AI service clients**\n  - ❌ DON'T: Import actual AI clients from their libraries\n  - ✅ DO: Create fully mocked versions that return predictable responses\n\n  ```javascript\n  // ❌ DON'T: Import and instantiate real AI clients\n  import { Anthropic } from '@anthropic-ai/sdk';\n  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n\n  // ✅ DO: Mock the entire module with controlled behavior\n  jest.mock('@anthropic-ai/sdk', () => ({\n    Anthropic: jest.fn().mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ type: 'text', text: 'Mocked AI response' }]\n        })\n      }\n    }))\n  }));\n  ```\n\n- **DO NOT rely on environment variables for API keys**\n  - ❌ DON'T: Assume environment variables are set in tests\n  - ✅ DO: Set mock environment variables in test setup\n\n  ```javascript\n  // In tests/setup.js or at the top of test file\n  process.env.ANTHROPIC_API_KEY = 'test-mock-api-key-for-tests';\n  process.env.PERPLEXITY_API_KEY = 'test-mock-perplexity-key-for-tests';\n  ```\n\n- **DO NOT use real AI client initialization logic**\n  - ❌ DON'T: Use code that attempts to initialize or validate real AI clients\n  - ✅ DO: Create test-specific paths that bypass client initialization\n\n  ```javascript\n  // ❌ DON'T: Test functions that require valid AI client initialization\n  // This will fail without proper API keys or network access\n  test('should use AI client', async () => {\n    const result = await functionThatInitializesAIClient();\n    expect(result).toBeDefined();\n  });\n\n  // ✅ DO: Test with bypassed initialization or manual task paths\n  test('should handle manual task creation without AI', () => {\n    // Using a path that doesn't require AI client initialization\n    const result = addTaskDirect({ \n      title: 'Manual Task', \n      description: 'Test Description'\n    }, mockLogger);\n    \n    expect(result.success).toBe(true);\n  });\n  ```\n\n## Testing Asynchronous Code\n\n- **DO NOT rely on asynchronous operations in tests**\n  - ❌ DON'T: Use real async/await or Promise resolution in tests\n  - ✅ DO: Make all mocks return synchronous values when possible\n\n  ```javascript\n  // ❌ DON'T: Use real async functions that might fail unpredictably\n  test('should handle async operation', async () => {\n    const result = await realAsyncFunction(); // Can time out or fail for external reasons\n    expect(result).toBe(expectedValue);\n  });\n\n  // ✅ DO: Make async operations synchronous in tests\n  test('should handle operation', () => {\n    mockAsyncFunction.mockReturnValue({ success: true, data: 'test' });\n    const result = functionUnderTest();\n    expect(result).toEqual({ success: true, data: 'test' });\n  });\n  ```\n\n- **DO NOT test exact error messages**\n  - ❌ DON'T: Assert on exact error message text that might change\n  - ✅ DO: Test for error presence and general properties\n\n  ```javascript\n  // ❌ DON'T: Test for exact error message text\n  expect(result.error).toBe('Could not connect to API: Network error');\n\n  // ✅ DO: Test for general error properties or message patterns\n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Could not connect');\n  // Or even better:\n  expect(result).toMatchObject({ \n    success: false,\n    error: expect.stringContaining('connect')\n  });\n  ```\n\n## Reliable Testing Techniques\n\n- **Create Simplified Test Functions**\n  - Create simplified versions of complex functions that focus only on core logic\n  - Remove file system operations, API calls, and other external dependencies\n  - Pass all dependencies as parameters to make testing easier\n  \n  ```javascript\n  // Original function (hard to test)\n  const setTaskStatus = async (taskId, newStatus) => {\n    const tasksPath = 'tasks/tasks.json';\n    const data = await readJSON(tasksPath);\n    // [implementation]\n    await writeJSON(tasksPath, data);\n    return { success: true };\n  };\n  \n  // Test-friendly version (easier to test)\n  const updateTaskStatus = (tasks, taskId, newStatus) => {\n    // Pure logic without side effects\n    const updatedTasks = [...tasks];\n    const taskIndex = findTaskById(updatedTasks, taskId);\n    if (taskIndex === -1) return { success: false, error: 'Task not found' };\n    updatedTasks[taskIndex].status = newStatus;\n    return { success: true, tasks: updatedTasks };\n  };\n  ```\n\nSee [tests/README.md](mdc:tests/README.md) for more details on the testing approach.\n\nRefer to [jest.config.js](mdc:jest.config.js) for Jest configuration options.\n\n## Variable Hoisting and Module Initialization Issues\n\nWhen testing ES modules or working with complex module imports, you may encounter variable hoisting and initialization issues. These can be particularly tricky to debug and often appear as \"Cannot access 'X' before initialization\" errors.\n\n- **Understanding Module Initialization Order**\n  - ✅ **DO**: Declare and initialize global variables at the top of modules\n  - ✅ **DO**: Use proper function declarations to avoid hoisting issues\n  - ✅ **DO**: Initialize variables before they are referenced, especially in imported modules\n  - ✅ **DO**: Be aware that imports are hoisted to the top of the file\n  \n  ```javascript\n  // ✅ DO: Define global state variables at the top of the module\n  let silentMode = false; // Declare and initialize first\n  \n  const CONFIG = { /* configuration */ };\n  \n  function isSilentMode() {\n    return silentMode; // Reference variable after it's initialized\n  }\n  \n  function log(level, message) {\n    if (isSilentMode()) return; // Use the function instead of accessing variable directly\n    // ...\n  }\n  ```\n\n- **Testing Modules with Initialization-Dependent Functions**\n  - ✅ **DO**: Create test-specific implementations that initialize all variables correctly\n  - ✅ **DO**: Use factory functions in mocks to ensure proper initialization order\n  - ✅ **DO**: Be careful with how you mock or stub functions that depend on module state\n  \n  ```javascript\n  // ✅ DO: Test-specific implementation that avoids initialization issues\n  const testLog = (level, ...args) => {\n    // Local implementation with proper initialization\n    const isSilent = false; // Explicit initialization\n    if (isSilent) return;\n    // Test implementation...\n  };\n  ```\n\n- **Common Hoisting-Related Errors to Avoid**\n  - ❌ **DON'T**: Reference variables before their declaration in module scope\n  - ❌ **DON'T**: Create circular dependencies between modules\n  - ❌ **DON'T**: Rely on variable initialization order across module boundaries\n  - ❌ **DON'T**: Define functions that use hoisted variables before they're initialized\n  \n  ```javascript\n  // ❌ DON'T: Create reference-before-initialization patterns\n  function badFunction() {\n    if (silentMode) { /* ... */ } // ReferenceError if silentMode is declared later\n  }\n  \n  let silentMode = false;\n  \n  // ❌ DON'T: Create cross-module references that depend on initialization order\n  // module-a.js\n  import { getSetting } from './module-b.js';\n  export const config = { value: getSetting() };\n  \n  // module-b.js\n  import { config } from './module-a.js';\n  export function getSetting() {\n    return config.value; // Circular dependency causing initialization issues\n  }\n  ```\n\n- **Dynamic Imports as a Solution**\n  - ✅ **DO**: Use dynamic imports (`import()`) to avoid initialization order issues\n  - ✅ **DO**: Structure modules to avoid circular dependencies that cause initialization issues\n  - ✅ **DO**: Consider factory functions for modules with complex state\n  \n  ```javascript\n  // ✅ DO: Use dynamic imports to avoid initialization issues\n  async function getTaskManager() {\n    return import('./task-manager.js');\n  }\n  \n  async function someFunction() {\n    const taskManager = await getTaskManager();\n    return taskManager.someMethod();\n  }\n  ```\n\n- **Testing Approach for Modules with Initialization Issues**\n  - ✅ **DO**: Create self-contained test implementations rather than using real implementations\n  - ✅ **DO**: Mock dependencies at module boundaries instead of trying to mock deep dependencies\n  - ✅ **DO**: Isolate module-specific state in tests\n  \n  ```javascript\n  // ✅ DO: Create isolated test implementation instead of reusing module code\n  test('should log messages when not in silent mode', () => {\n    // Local test implementation instead of importing from module\n    const testLog = (level, message) => {\n      if (false) return; // Always non-silent for this test\n      mockConsole(level, message);\n    };\n    \n    testLog('info', 'test message');\n    expect(mockConsole).toHaveBeenCalledWith('info', 'test message');\n  });\n  ``` ",".cursor/rules/ui.mdc":"---\ndescription: Guidelines for implementing and maintaining user interface components\nglobs: scripts/modules/ui.js\nalwaysApply: false\n---\n\n# User Interface Implementation Guidelines\n\n## Core UI Component Principles\n\n- **Function Scope Separation**:\n  - ✅ DO: Keep display logic separate from business logic\n  - ✅ DO: Import data processing functions from other modules\n  - ❌ DON'T: Include task manipulations within UI functions\n  - ❌ DON'T: Create circular dependencies with other modules\n\n- **Standard Display Pattern**:\n  ```javascript\n  // ✅ DO: Follow this pattern for display functions\n  /**\n   * Display information about a task\n   * @param {Object} task - The task to display\n   */\n  function displayTaskInfo(task) {\n    console.log(boxen(\n      chalk.white.bold(`Task: #${task.id} - ${task.title}`),\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n## Visual Styling Standards\n\n- **Color Scheme**:\n  - Use `chalk.blue` for informational messages\n  - Use `chalk.green` for success messages\n  - Use `chalk.yellow` for warnings\n  - Use `chalk.red` for errors\n  - Use `chalk.cyan` for prompts and highlights\n  - Use `chalk.magenta` for subtask-related information\n\n- **Box Styling**:\n  ```javascript\n  // ✅ DO: Use consistent box styles by content type\n  // For success messages:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'green', \n    borderStyle: 'round', \n    margin: { top: 1 } \n  })\n\n  // For errors:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'red', \n    borderStyle: 'round'\n  })\n\n  // For information:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'blue', \n    borderStyle: 'round', \n    margin: { top: 1, bottom: 1 } \n  })\n  ```\n\n## Table Display Guidelines\n\n- **Table Structure**:\n  - Use [`cli-table3`](mdc:node_modules/cli-table3/README.md) for consistent table rendering\n  - Include colored headers with bold formatting\n  - Use appropriate column widths for readability\n\n  ```javascript\n  // ✅ DO: Create well-structured tables\n  const table = new Table({\n    head: [\n      chalk.cyan.bold('ID'),\n      chalk.cyan.bold('Title'),\n      chalk.cyan.bold('Status'),\n      chalk.cyan.bold('Priority'),\n      chalk.cyan.bold('Dependencies')\n    ],\n    colWidths: [5, 40, 15, 10, 20]\n  });\n  \n  // Add content rows\n  table.push([\n    task.id,\n    truncate(task.title, 37),\n    getStatusWithColor(task.status),\n    chalk.white(task.priority || 'medium'),\n    formatDependenciesWithStatus(task.dependencies, allTasks, true)\n  ]);\n  \n  console.log(table.toString());\n  ```\n\n## Loading Indicators\n\n- **Animation Standards**:\n  - Use [`ora`](mdc:node_modules/ora/readme.md) for spinner animations\n  - Create and stop loading indicators correctly\n\n  ```javascript\n  // ✅ DO: Properly manage loading state\n  const loadingIndicator = startLoadingIndicator('Processing task data...');\n  try {\n    // Do async work...\n    stopLoadingIndicator(loadingIndicator);\n    // Show success message\n  } catch (error) {\n    stopLoadingIndicator(loadingIndicator);\n    // Show error message\n  }\n  ```\n\n## Helper Functions\n\n- **Status Formatting**:\n  - Use `getStatusWithColor` for consistent status display\n  - Use `formatDependenciesWithStatus` for dependency lists\n  - Use `truncate` to handle text that may overflow display\n\n- **Progress Reporting**:\n  - Use visual indicators for progress (bars, percentages)\n  - Include both numeric and visual representations\n  \n  ```javascript\n  // ✅ DO: Show clear progress indicators\n  console.log(`${chalk.cyan('Tasks:')} ${completedTasks}/${totalTasks} (${completionPercentage.toFixed(1)}%)`);\n  console.log(`${chalk.cyan('Progress:')} ${createProgressBar(completionPercentage)}`);\n  ```\n\n## Command Suggestions\n\n- **Action Recommendations**:\n  - Provide next step suggestions after command completion\n  - Use a consistent format for suggested commands\n\n  ```javascript\n  // ✅ DO: Show suggested next actions\n  console.log(boxen(\n    chalk.white.bold('Next Steps:') + '\\n\\n' +\n    `${chalk.cyan('1.')} Run ${chalk.yellow('task-master list')} to view all tasks\\n` +\n    `${chalk.cyan('2.')} Run ${chalk.yellow('task-master show --id=' + newTaskId)} to view details`,\n    { padding: 1, borderColor: 'cyan', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Enhanced Display Patterns\n\n### **Token Breakdown Display**\n- Use detailed, granular token breakdowns for AI-powered commands\n- Display context sources with individual token counts\n- Show both token count and character count for transparency\n\n  ```javascript\n  // ✅ DO: Display detailed token breakdown\n  function displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    if (tokenBreakdown.tasks?.length > 0) {\n      const taskDetails = tokenBreakdown.tasks.map(task => \n        `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n      ).join('\\n');\n      sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n      title: chalk.cyan('Token Usage'),\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      borderStyle: 'round',\n      borderColor: 'cyan'\n    }));\n  }\n  ```\n\n### **Code Block Syntax Highlighting**\n- Use `cli-highlight` library for syntax highlighting in terminal output\n- Process code blocks in AI responses for better readability\n\n  ```javascript\n  // ✅ DO: Enhance code blocks with syntax highlighting\n  import { highlight } from 'cli-highlight';\n  \n  function processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n      try {\n        const highlighted = highlight(code.trim(), { \n          language: language || 'javascript',\n          theme: 'default'\n        });\n        return `\\n${highlighted}\\n`;\n      } catch (error) {\n        return `\\n${code.trim()}\\n`;\n      }\n    });\n  }\n  ```\n\n### **Multi-Section Result Display**\n- Use separate boxes for headers, content, and metadata\n- Maintain consistent styling across different result types\n\n  ```javascript\n  // ✅ DO: Use structured result display\n  function displayResults(result, query, detailLevel) {\n    // Header with query info\n    const header = boxen(\n      chalk.green.bold('Research Results') + '\\n\\n' +\n      chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n      chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n      {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 1, bottom: 0 },\n        borderStyle: 'round',\n        borderColor: 'green'\n      }\n    );\n    console.log(header);\n    \n    // Process and display main content\n    const processedResult = processCodeBlocks(result);\n    const contentBox = boxen(processedResult, {\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      margin: { top: 0, bottom: 1 },\n      borderStyle: 'single',\n      borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Operation complete'));\n  }\n  ```\n\nRefer to [`ui.js`](mdc:scripts/modules/ui.js) for implementation examples, [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for context display patterns, and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/utilities.mdc":"---\ndescription: \nglobs: \nalwaysApply: false\n---\n# Utility Function Guidelines\n\n## General Principles\n\n- **Function Scope**:\n  - ✅ DO: Create utility functions that serve multiple modules\n  - ✅ DO: Keep functions single-purpose and focused\n  - ❌ DON'T: Include business logic in utility functions\n  - ❌ DON'T: Create utilities with side effects\n\n  ```javascript\n  // ✅ DO: Create focused, reusable utilities\n  /**\n   * Truncates text to a specified length\n   * @param {string} text - The text to truncate\n   * @param {number} maxLength - The maximum length\n   * @returns {string} The truncated text\n   */\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n  ```javascript\n  // ❌ DON'T: Add side effects to utilities\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    \n    // Side effect - modifying global state or logging\n    console.log(`Truncating text from ${text.length} to ${maxLength} chars`);\n    \n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n- **Location**:\n    - **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).\n    - **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.\n        - Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils) (e.g., `path-utils.js`).\n        - Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n\n## Documentation Standards\n\n- **JSDoc Format**:\n  - ✅ DO: Document all parameters and return values\n  - ✅ DO: Include descriptions for complex logic\n  - ✅ DO: Add examples for non-obvious usage\n  - ❌ DON'T: Skip documentation for \"simple\" functions\n\n  ```javascript\n  // ✅ DO: Provide complete JSDoc documentation\n  /**\n   * Reads and parses a JSON file\n   * @param {string} filepath - Path to the JSON file\n   * @returns {Object|null} Parsed JSON data or null if error occurs\n   */\n  function readJSON(filepath) {\n    try {\n      const rawData = fs.readFileSync(filepath, 'utf8');\n      return JSON.parse(rawData);\n    } catch (error) {\n      log('error', `Error reading JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n      return null;\n    }\n  }\n  ```\n\n## Configuration Management (via `config-manager.js`)\n\nTaskmaster configuration (excluding API keys) is primarily managed through the `.taskmasterconfig` file located in the project root and accessed via getters in [`scripts/modules/config-manager.js`](mdc:scripts/modules/config-manager.js).\n\n- **`.taskmasterconfig` File**:\n  - ✅ DO: Use this JSON file to store settings like AI model selections (main, research, fallback), parameters (temperature, maxTokens), logging level, default priority/subtasks, etc.\n  - ✅ DO: Manage this file using the `task-master models --setup` CLI command or the `models` MCP tool.\n  - ✅ DO: Rely on [`config-manager.js`](mdc:scripts/modules/config-manager.js) to load this file (using the correct project root passed from MCP or found via CLI utils), merge with defaults, and provide validated settings.\n  - ❌ DON'T: Store API keys in this file.\n  - ❌ DON'T: Manually edit this file unless necessary.\n\n- **Configuration Getters (`config-manager.js`)**:\n  - ✅ DO: Import and use specific getters from `config-manager.js` (e.g., `getMainProvider()`, `getLogLevel()`, `getMainMaxTokens()`) to access configuration values *needed for application logic* (like `getDefaultSubtasks`).\n  - ✅ DO: Pass the `explicitRoot` parameter to getters if calling from MCP direct functions to ensure the correct project's config is loaded.\n  - ❌ DON'T: Call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions (`scripts/modules/task-manager/*`). Instead, pass the `role` to the unified AI service.\n  - ❌ DON'T: Access configuration values directly from environment variables (except API keys).\n\n- **API Key Handling (`utils.js` & `ai-services-unified.js`)**:\n  - ✅ DO: Store API keys **only** in `.env` (for CLI, loaded by `dotenv` in `scripts/dev.js`) or `.cursor/mcp.json` (for MCP, accessed via `session.env`).\n  - ✅ DO: Use `isApiKeySet(providerName, session)` from `config-manager.js` to check if a provider's key is available *before* potentially attempting an AI call if needed, but note the unified service performs its own internal check.\n  - ✅ DO: Understand that the unified service layer (`ai-services-unified.js`) internally resolves API keys using `resolveEnvVariable(key, session)` from `utils.js`.\n\n- **Error Handling**:\n  - ✅ DO: Handle potential `ConfigurationError` if the `.taskmasterconfig` file is missing or invalid when accessed via `getConfig` (e.g., in `commands.js` or direct functions).\n\n## Logging Utilities (in `scripts/modules/utils.js`)\n\n- **Log Levels**:\n  - ✅ DO: Support multiple log levels (debug, info, warn, error)\n  - ✅ DO: Use appropriate icons for different log levels\n  - ✅ DO: Respect the configured log level\n  - ❌ DON'T: Add direct console.log calls outside the logging utility\n  - **Note on Passed Loggers**: When a logger object (like the FastMCP `log` object) is passed *as a parameter* (e.g., as `mcpLog`) into core Task Master functions, the receiving function often expects specific methods (`.info`, `.warn`, `.error`, etc.) to be directly callable on that object (e.g., `mcpLog[level](mdc:...)`). If the passed logger doesn't have this exact structure, a wrapper object may be needed. See the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for the standard pattern used in direct functions.\n\n- **Logger Wrapper Pattern**: \n  - ✅ DO: Use the logger wrapper pattern when passing loggers to prevent `mcpLog[level] is not a function` errors:\n  ```javascript\n  // Standard logWrapper pattern to wrap FastMCP's log object\n  const logWrapper = {\n    info: (message, ...args) => log.info(message, ...args),\n    warn: (message, ...args) => log.warn(message, ...args),\n    error: (message, ...args) => log.error(message, ...args),\n    debug: (message, ...args) => log.debug && log.debug(message, ...args),\n    success: (message, ...args) => log.info(message, ...args) // Map success to info\n  };\n  \n  // Pass this wrapper as mcpLog to ensure consistent method availability\n  // This also ensures output format is set to 'json' in many core functions\n  const options = { mcpLog: logWrapper, session };\n  ```\n  - ✅ DO: Implement this pattern in any direct function that calls core functions expecting `mcpLog`\n  - ✅ DO: Use this solution in conjunction with silent mode for complete output control\n  - ❌ DON'T: Pass the FastMCP `log` object directly as `mcpLog` to core functions\n  - **Important**: This pattern has successfully fixed multiple issues in MCP tools (e.g., `update-task`, `update-subtask`) where using or omitting `mcpLog` incorrectly led to runtime errors or JSON parsing failures.\n  - For complete implementation details, see the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc).\n\n  ```javascript\n  // ✅ DO: Implement a proper logging utility\n  const LOG_LEVELS = {\n    debug: 0,\n    info: 1,\n    warn: 2,\n    error: 3\n  };\n  \n  function log(level, ...args) {\n    const icons = {\n      debug: chalk.gray('🔍'),\n      info: chalk.blue('ℹ️'),\n      warn: chalk.yellow('⚠️'),\n      error: chalk.red('❌'),\n      success: chalk.green('✅')\n    };\n    \n    if (LOG_LEVELS[level] >= LOG_LEVELS[CONFIG.logLevel]) {\n      const icon = icons[level] || '';\n      console.log(`${icon} ${args.join(' ')}`);\n    }\n  }\n  ```\n\n## Silent Mode Utilities (in `scripts/modules/utils.js`)\n\n- **Silent Mode Control**:\n  - ✅ DO: Use the exported silent mode functions rather than accessing global variables\n  - ✅ DO: Always use `isSilentMode()` to check the current silent mode state\n  - ✅ DO: Ensure silent mode is disabled in a `finally` block to prevent it from staying enabled\n  - ❌ DON'T: Access the global `silentMode` variable directly\n  - ❌ DON'T: Forget to disable silent mode after enabling it\n\n  ```javascript\n  // ✅ DO: Use the silent mode control functions properly\n  \n  // Example of proper implementation in utils.js:\n  \n  // Global silent mode flag (private to the module)\n  let silentMode = false;\n  \n  // Enable silent mode\n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  // Disable silent mode\n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  // Check if silent mode is enabled\n  function isSilentMode() {\n    return silentMode;\n  }\n  \n  // Example of proper usage in another module:\n  import { enableSilentMode, disableSilentMode, isSilentMode } from './utils.js';\n  \n  // Check current status\n  if (!isSilentMode()) {\n    console.log('Silent mode is not enabled');\n  }\n  \n  // Use try/finally pattern to ensure silent mode is disabled\n  try {\n    enableSilentMode();\n    // Do something that should suppress console output\n    performOperation();\n  } finally {\n    disableSilentMode();\n  }\n  ```\n\n- **Integration with Logging**:\n  - ✅ DO: Make the `log` function respect silent mode\n  ```javascript\n  function log(level, ...args) {\n    // Skip logging if silent mode is enabled\n    if (isSilentMode()) {\n      return;\n    }\n    \n    // Rest of logging logic...\n  }\n  ```\n\n- **Common Patterns for Silent Mode**:\n  - ✅ DO: In **direct functions** (`mcp-server/src/core/direct-functions/*`) that call **core functions** (`scripts/modules/*`), ensure console output from the core function is suppressed to avoid breaking MCP JSON responses.\n    - **Preferred Method**: Update the core function to accept an `outputFormat` parameter (e.g., `outputFormat = 'text'`) and make it check `outputFormat === 'text'` before displaying any UI elements (banners, spinners, boxes, direct `console.log`s). Pass `'json'` from the direct function.\n    - **Necessary Fallback/Guarantee**: If the core function *cannot* be modified or its output suppression via `outputFormat` is unreliable, **wrap the core function call within the direct function** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block. This acts as a safety net.\n  ```javascript\n  // Example in a direct function\n  export async function someOperationDirect(args, log) {\n    let result;\n    const tasksPath = findTasksJsonPath(args, log); // Get path first\n    \n    // Option 1: Core function handles 'json' format (Preferred)\n    try {\n      result = await coreFunction(tasksPath, ...otherArgs, 'json'); // Pass 'json'\n      return { success: true, data: result, fromCache: false };\n    } catch (error) {\n      // Handle error...\n    }\n\n    // Option 2: Core function output unreliable (Fallback/Guarantee)\n    try {\n      enableSilentMode(); // Enable before call\n      result = await coreFunction(tasksPath, ...otherArgs); // Call without format param\n    } catch (error) {\n      // Handle error...\n      log.error(`Failed: ${error.message}`);\n      return { success: false, error: { /* ... */ } };\n    } finally {\n      disableSilentMode(); // ALWAYS disable in finally\n    }\n    return { success: true, data: result, fromCache: false }; // Assuming success if no error caught\n  }\n  ```\n  - ✅ DO: For functions that accept a silent mode parameter but also need to check global state (less common):\n  ```javascript\n  // Check both the passed parameter and global silent mode\n  const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n  ```\n\n## File Operations (in `scripts/modules/utils.js`)\n\n- **Error Handling**:\n  - ✅ DO: Use try/catch blocks for all file operations\n  - ✅ DO: Return null or a default value on failure\n  - ✅ DO: Log detailed error information using the `log` utility\n  - ❌ DON'T: Allow exceptions to propagate unhandled from simple file reads/writes\n\n  ```javascript\n  // ✅ DO: Handle file operation errors properly in core utils\n  function writeJSON(filepath, data) {\n    try {\n      // Ensure directory exists (example)\n      const dir = path.dirname(filepath);\n      if (!fs.existsSync(dir)) {\n        fs.mkdirSync(dir, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Error writing JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n    }\n  }\n  ```\n\n## Task-Specific Utilities (in `scripts/modules/utils.js`)\n\n- **Task ID Formatting**:\n  - ✅ DO: Create utilities for consistent ID handling\n  - ✅ DO: Support different ID formats (numeric, string, dot notation)\n  - ❌ DON'T: Duplicate formatting logic across modules\n\n  ```javascript\n  // ✅ DO: Create utilities for common operations\n  /**\n   * Formats a task ID as a string\n   * @param {string|number} id - The task ID to format\n   * @returns {string} The formatted task ID\n   */\n  function formatTaskId(id) {\n    if (typeof id === 'string' && id.includes('.')) {\n      return id; // Already formatted as a string with a dot (e.g., \"1.2\")\n    }\n    \n    if (typeof id === 'number') {\n      return id.toString();\n    }\n    \n    return id;\n  }\n  ```\n\n- **Task Search**:\n  - ✅ DO: Implement reusable task finding utilities\n  - ✅ DO: Support both task and subtask lookups\n  - ✅ DO: Add context to subtask results\n\n  ```javascript\n  // ✅ DO: Create comprehensive search utilities\n  /**\n   * Finds a task by ID in the tasks array\n   * @param {Array} tasks - The tasks array\n   * @param {string|number} taskId - The task ID to find\n   * @returns {Object|null} The task object or null if not found\n   */\n  function findTaskById(tasks, taskId) {\n    if (!taskId || !tasks || !Array.isArray(tasks)) {\n      return null;\n    }\n    \n    // Check if it's a subtask ID (e.g., \"1.2\")\n    if (typeof taskId === 'string' && taskId.includes('.')) {\n      const [parentId, subtaskId] = taskId.split('.').map(id => parseInt(id, 10));\n      const parentTask = tasks.find(t => t.id === parentId);\n      \n      if (!parentTask || !parentTask.subtasks) {\n        return null;\n      }\n      \n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      if (subtask) {\n        // Add reference to parent task for context\n        subtask.parentTask = { \n          id: parentTask.id, \n          title: parentTask.title,\n          status: parentTask.status\n        };\n        subtask.isSubtask = true;\n      }\n      \n      return subtask || null;\n    }\n    \n    const id = parseInt(taskId, 10);\n    return tasks.find(t => t.id === id) || null;\n  }\n  ```\n\n## Cycle Detection (in `scripts/modules/utils.js`)\n\n- **Graph Algorithms**:\n  - ✅ DO: Implement cycle detection using graph traversal\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Return specific information about cycles\n\n  ```javascript\n  // ✅ DO: Implement proper cycle detection\n  /**\n   * Find cycles in a dependency graph using DFS\n   * @param {string} subtaskId - Current subtask ID\n   * @param {Map} dependencyMap - Map of subtask IDs to their dependencies\n   * @param {Set} visited - Set of visited nodes\n   * @param {Set} recursionStack - Set of nodes in current recursion stack\n   * @returns {Array} - List of dependency edges that need to be removed to break cycles\n   */\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set(), path = []) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    path.push(subtaskId);\n    \n    const cyclesToBreak = [];\n    \n    // Get all dependencies of the current subtask\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    // For each dependency\n    for (const depId of dependencies) {\n      // If not visited, recursively check for cycles\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack, [...path]);\n        cyclesToBreak.push(...cycles);\n      } \n      // If the dependency is in the recursion stack, we found a cycle\n      else if (recursionStack.has(depId)) {\n        // The last edge in the cycle is what we want to remove\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\n## MCP Server Core Utilities (`mcp-server/src/core/utils/`)\n\n### Project Root and Task File Path Detection (`path-utils.js`)\n\n- **Purpose**: This module ([`mcp-server/src/core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) provides the mechanism for locating the user's `tasks.json` file, used by direct functions.\n- **`findTasksJsonPath(args, log)`**:\n    - ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.\n    - Pass the *entire `args` object* received by the MCP tool (which should include `projectRoot` derived from the session) and the `log` object.\n    - Implements a **simplified precedence system** for finding the `tasks.json` path:\n        1.  Explicit `projectRoot` passed in `args` (Expected from MCP tools).\n        2.  Cached `lastFoundProjectRoot` (CLI fallback).\n        3.  Search upwards from `process.cwd()` (CLI fallback).\n    - Throws a specific error if the `tasks.json` file cannot be located.\n    - Updates the `lastFoundProjectRoot` cache on success.\n- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the CLI fallback search.\n- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself (potentially removable).\n\n## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)\n\nThese utilities specifically support the implementation and execution of MCP tools.\n\n- **`normalizeProjectRoot(rawPath, log)`**:\n    - **Purpose**: Takes a raw project root path (potentially URI encoded, with `file://` prefix, Windows slashes) and returns a normalized, absolute path suitable for the server's OS.\n    - **Logic**: Decodes URI, strips `file://`, handles Windows drive prefix (`/C:/`), replaces `\\` with `/`, uses `path.resolve()`.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF.\n\n- **`getRawProjectRootFromSession(session, log)`**:\n    - **Purpose**: Extracts the *raw* project root URI string from the session object (`session.roots[0].uri` or `session.roots.roots[0].uri`) without performing normalization.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF as a fallback if `args.projectRoot` isn't provided.\n\n- **`withNormalizedProjectRoot(executeFn)`**:\n    - **Purpose**: A Higher-Order Function (HOF) designed to wrap a tool's `execute` method.\n    - **Logic**: \n        1. Determines the raw project root (from `args.projectRoot` or `getRawProjectRootFromSession`).\n        2. Normalizes the raw path using `normalizeProjectRoot`.\n        3. Injects the normalized, absolute path back into the `args` object as `args.projectRoot`.\n        4. Calls the original `executeFn` with the updated `args`.\n    - **Usage**: Should wrap the `execute` function of *every* MCP tool that needs a reliable, normalized project root path.\n    - **Example**:\n      ```javascript\n      // In mcp-server/src/tools/your-tool.js\n      import { withNormalizedProjectRoot } from './utils.js';\n      \n      export function registerYourTool(server) {\n          server.addTool({\n              // ... name, description, parameters ...\n              execute: withNormalizedProjectRoot(async (args, context) => {\n                  // args.projectRoot is now normalized here\n                  const { projectRoot /*, other args */ } = args;\n                  // ... rest of tool logic using normalized projectRoot ...\n              })\n          });\n      }\n      ```\n\n- **`handleApiResult(result, log, errorPrefix, processFunction)`**:\n    - **Purpose**: Standardizes the formatting of responses returned by direct functions (`{ success, data/error, fromCache }`) into the MCP response format.\n    - **Usage**: Call this at the end of the tool's `execute` method, passing the result from the direct function call.\n\n- **`createContentResponse(content)` / `createErrorResponse(errorMessage)`**:\n    - **Purpose**: Helper functions to create the basic MCP response structure for success or error messages.\n    - **Usage**: Used internally by `handleApiResult` and potentially directly for simple responses.\n\n- **`createLogWrapper(log)`**:\n    - **Purpose**: Creates a logger object wrapper with standard methods (`info`, `warn`, `error`, `debug`, `success`) mapping to the passed MCP `log` object's methods. Ensures compatibility when passing loggers to core functions.\n    - **Usage**: Used within direct functions before passing the `log` object down to core logic that expects the standard method names.\n\n- **`getCachedOrExecute({ cacheKey, actionFn, log })`**:\n    - **Purpose**: Utility for implementing caching within direct functions. Checks cache for `cacheKey`; if miss, executes `actionFn`, caches successful result, and returns.\n    - **Usage**: Wrap the core logic execution within a direct function call.\n\n- **`processMCPResponseData(taskOrData, fieldsToRemove)`**:\n    - **Purpose**: Utility to filter potentially sensitive or large fields (like `details`, `testStrategy`) from task objects before sending the response back via MCP.\n    - **Usage**: Passed as the default `processFunction` to `handleApiResult`.\n\n- **`getProjectRootFromSession(session, log)`**:\n    - **Purpose**: Legacy function to extract *and normalize* the project root from the session. Replaced by the HOF pattern but potentially still used.\n    - **Recommendation**: Prefer using the `withNormalizedProjectRoot` HOF in tools instead of calling this directly.\n\n- **`executeTaskMasterCommand(...)`**: \n    - **Purpose**: Executes `task-master` CLI command as a fallback. \n    - **Recommendation**: Deprecated for most uses; prefer direct function calls.\n\n## Export Organization\n\n- **Grouping Related Functions**:\n  - ✅ DO: Keep utilities relevant to their location (e.g., core CLI utils in `scripts/modules/utils.js`, MCP path utils in `mcp-server/src/core/utils/path-utils.js`, MCP tool utils in `mcp-server/src/tools/utils.js`).\n  - ✅ DO: Export all utility functions in a single statement per file.\n  - ✅ DO: Group related exports together.\n  - ✅ DO: Export configuration constants (from `scripts/modules/utils.js`).\n  - ❌ DON'T: Use default exports.\n  - ❌ DON'T: Create circular dependencies (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)).\n\n```javascript\n// Example export from scripts/modules/utils.js\nexport {\n  // Configuration\n  CONFIG,\n  LOG_LEVELS,\n  \n  // Logging\n  log,\n  \n  // File operations\n  readJSON,\n  writeJSON,\n  \n  // String manipulation\n  sanitizePrompt,\n  truncate,\n  \n  // Task utilities\n  // ... (taskExists, formatTaskId, findTaskById, etc.)\n  \n  // Graph algorithms\n  findCycles,\n};\n\n// Example export from mcp-server/src/core/utils/path-utils.js\nexport {\n  findTasksJsonPath,\n  getPackagePath,\n  PROJECT_MARKERS,\n  lastFoundProjectRoot // Exporting for potential direct use/reset if needed\n};\n\n// Example export from mcp-server/src/tools/utils.js\nexport {\n  getProjectRoot,\n  getProjectRootFromSession,\n  handleApiResult,\n  executeTaskMasterCommand,\n  processMCPResponseData,\n  createContentResponse,\n  createErrorResponse,\n  getCachedOrExecute\n};\n```\n\n## Context Gathering Utilities\n\n### **ContextGatherer** (`scripts/modules/utils/contextGatherer.js`)\n\n- **Multi-Source Context Extraction**:\n  - ✅ DO: Use for AI-powered commands that need project context\n  - ✅ DO: Support tasks, files, custom text, and project tree context\n  - ✅ DO: Implement detailed token counting with `gpt-tokens` library\n  - ✅ DO: Provide multiple output formats (research, chat, system-prompt)\n\n  ```javascript\n  // ✅ DO: Use ContextGatherer for consistent context extraction\n  import { ContextGatherer } from '../utils/contextGatherer.js';\n  \n  const gatherer = new ContextGatherer(projectRoot, tasksPath);\n  const result = await gatherer.gather({\n    tasks: ['15', '16.2'],\n    files: ['src/api.js'],\n    customContext: 'Additional context',\n    includeProjectTree: true,\n    format: 'research',\n    includeTokenCounts: true\n  });\n  ```\n\n### **FuzzyTaskSearch** (`scripts/modules/utils/fuzzyTaskSearch.js`)\n\n- **Intelligent Task Discovery**:\n  - ✅ DO: Use for automatic task relevance detection\n  - ✅ DO: Configure search parameters based on use case context\n  - ✅ DO: Implement purpose-based categorization for better matching\n  - ✅ DO: Sort results by relevance score and task ID\n\n  ```javascript\n  // ✅ DO: Use FuzzyTaskSearch for intelligent task discovery\n  import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n  \n  const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n  const searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n  });\n  const taskIds = fuzzySearch.getTaskIds(searchResults);\n  ```\n\n- **Integration Guidelines**:\n  - ✅ DO: Use fuzzy search to supplement user-provided task IDs\n  - ✅ DO: Display discovered task IDs to users for transparency\n  - ✅ DO: Sort discovered task IDs numerically for better readability\n  - ❌ DON'T: Replace explicit user task selections with fuzzy results\n\nRefer to [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for detailed implementation patterns, [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for more context on MCP server architecture and integration. \n\n## File System Operations\n\n- **JSON File Handling**:\n  - ✅ DO: Use `readJSON` and `writeJSON` for all JSON operations\n  - ✅ DO: Include error handling for file operations\n  - ✅ DO: Validate JSON structure after reading\n  - ❌ DON'T: Use raw `fs.readFileSync` or `fs.writeFileSync` for JSON\n\n  ```javascript\n  // ✅ DO: Use utility functions with error handling\n  function readJSON(filepath) {\n    try {\n      if (!fs.existsSync(filepath)) {\n        return null; // or appropriate default\n      }\n      \n      let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n      \n      // Silent migration for tasks.json files: Transform old format to tagged format\n      const isTasksFile = filepath.includes('tasks.json') || path.basename(filepath) === 'tasks.json';\n      \n      if (data && data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n        // Migrate from old format { \"tasks\": [...] } to new format { \"master\": { \"tasks\": [...] } }\n        const migratedData = {\n          master: {\n            tasks: data.tasks\n          }\n        };\n        \n        writeJSON(filepath, migratedData);\n        \n        // Set global flag for CLI notice and perform complete migration\n        global.taskMasterMigrationOccurred = true;\n        performCompleteTagMigration(filepath);\n        \n        data = migratedData;\n      }\n      \n      return data;\n    } catch (error) {\n      log('error', `Failed to read JSON from ${filepath}: ${error.message}`);\n      return null;\n    }\n  }\n  \n  function writeJSON(filepath, data) {\n    try {\n      const dirPath = path.dirname(filepath);\n      if (!fs.existsSync(dirPath)) {\n        fs.mkdirSync(dirPath, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Failed to write JSON to ${filepath}: ${error.message}`);\n      throw error;\n    }\n  }\n  ```\n\n- **Path Resolution**:\n  - ✅ DO: Use `path.join()` for cross-platform path construction\n  - ✅ DO: Use `path.resolve()` for absolute paths\n  - ✅ DO: Validate paths before file operations\n\n  ```javascript\n  // ✅ DO: Handle paths correctly\n  function findProjectRoot(startPath = process.cwd()) {\n    let currentPath = path.resolve(startPath);\n    const rootPath = path.parse(currentPath).root;\n    \n    while (currentPath !== rootPath) {\n      const taskMasterPath = path.join(currentPath, '.taskmaster');\n      if (fs.existsSync(taskMasterPath)) {\n        return currentPath;\n      }\n      currentPath = path.dirname(currentPath);\n    }\n    \n    return null; // Not found\n  }\n  ```\n\n## Tagged Task Lists System Utilities\n\n- **Tag Resolution Functions**:\n  - ✅ DO: Use tag resolution layer for all task data access\n  - ✅ DO: Provide backward compatibility with legacy format\n  - ✅ DO: Default to \"master\" tag when no tag is specified\n\n  ```javascript\n  // ✅ DO: Implement tag resolution functions\n  function getTasksForTag(data, tagName = 'master') {\n    if (!data) {\n      return [];\n    }\n    \n    // Handle legacy format - direct tasks array\n    if (data.tasks && Array.isArray(data.tasks)) {\n      return data.tasks;\n    }\n    \n    // Handle tagged format - tasks under specific tag\n    if (data[tagName] && data[tagName].tasks && Array.isArray(data[tagName].tasks)) {\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  \n  function setTasksForTag(data, tagName = 'master', tasks) {\n    // Ensure data object exists\n    if (!data) {\n      data = {};\n    }\n    \n    // Create tag structure if it doesn't exist\n    if (!data[tagName]) {\n      data[tagName] = {};\n    }\n    \n    // Set tasks for the tag\n    data[tagName].tasks = tasks;\n    \n    return data;\n  }\n  \n  function getCurrentTag() {\n    // Get current tag from state.json or default to 'master'\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return 'master';\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (fs.existsSync(statePath)) {\n        const state = readJSON(statePath);\n        return state.currentTag || 'master';\n      }\n    } catch (error) {\n      log('debug', `Error reading current tag: ${error.message}`);\n    }\n    \n    return 'master';\n  }\n  ```\n\n- **Migration Functions**:\n  - ✅ DO: Implement complete migration for all related files\n  - ✅ DO: Handle configuration and state file creation\n  - ✅ DO: Provide migration status tracking\n\n  ```javascript\n  // ✅ DO: Implement complete migration system\n  function performCompleteTagMigration(tasksJsonPath) {\n    try {\n      // Derive project root from tasks.json path\n      const projectRoot = findProjectRoot(path.dirname(tasksJsonPath)) || path.dirname(tasksJsonPath);\n      \n      // 1. Migrate config.json - add defaultTag and tags section\n      const configPath = path.join(projectRoot, '.taskmaster', 'config.json');\n      if (fs.existsSync(configPath)) {\n        migrateConfigJson(configPath);\n      }\n      \n      // 2. Create state.json if it doesn't exist\n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (!fs.existsSync(statePath)) {\n        createStateJson(statePath);\n      }\n      \n      if (getDebugFlag()) {\n        log('debug', 'Completed tagged task lists migration for project');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error during complete tag migration: ${error.message}`);\n      }\n    }\n  }\n  \n  function migrateConfigJson(configPath) {\n    try {\n      const config = readJSON(configPath);\n      if (!config) return;\n      \n      let modified = false;\n      \n      // Add global.defaultTag if missing\n      if (!config.global) {\n        config.global = {};\n      }\n      if (!config.global.defaultTag) {\n        config.global.defaultTag = 'master';\n        modified = true;\n      }\n      \n      // Add tags section if missing\n      if (!config.tags) {\n        config.tags = {\n                  // Git integration settings removed - now manual only\n        };\n        modified = true;\n      }\n      \n      if (modified) {\n        writeJSON(configPath, config);\n        if (getDebugFlag()) {\n          log('debug', 'Updated config.json with tagged task system settings');\n        }\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error migrating config.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function createStateJson(statePath) {\n    try {\n      const initialState = {\n        currentTag: 'master',\n        lastSwitched: new Date().toISOString(),\n        migrationNoticeShown: false\n      };\n      \n      writeJSON(statePath, initialState);\n      if (getDebugFlag()) {\n        log('debug', 'Created initial state.json for tagged task system');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error creating state.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function markMigrationForNotice() {\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return;\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      const state = readJSON(statePath) || {};\n      \n      state.migrationNoticeShown = false; // Reset to show notice\n      writeJSON(statePath, state);\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error marking migration for notice: ${error.message}`);\n      }\n    }\n  }\n  ```\n\n## Logging Functions\n\n- **Consistent Logging**:\n  - ✅ DO: Use the central `log` function for all output\n  - ✅ DO: Use appropriate log levels (info, warn, error, debug)\n  - ✅ DO: Support silent mode for programmatic usage\n\n  ```javascript\n  // ✅ DO: Implement consistent logging with silent mode\n  let silentMode = false;\n  \n  function log(level, ...messages) {\n    if (silentMode && level !== 'error') {\n      return; // Suppress non-error logs in silent mode\n    }\n    \n    const timestamp = new Date().toISOString();\n    const formattedMessage = messages.join(' ');\n    \n    switch (level) {\n      case 'error':\n        console.error(`[ERROR] ${formattedMessage}`);\n        break;\n      case 'warn':\n        console.warn(`[WARN] ${formattedMessage}`);\n        break;\n      case 'info':\n        console.log(`[INFO] ${formattedMessage}`);\n        break;\n      case 'debug':\n        if (getDebugFlag()) {\n          console.log(`[DEBUG] ${formattedMessage}`);\n        }\n        break;\n      default:\n        console.log(formattedMessage);\n    }\n  }\n  \n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  function isSilentMode() {\n    return silentMode;\n  }\n  ```\n\n## Task Utilities\n\n- **Task Finding and Manipulation**:\n  - ✅ DO: Use tagged task system aware functions\n  - ✅ DO: Handle both task and subtask operations\n  - ✅ DO: Validate task IDs before operations\n\n  ```javascript\n  // ✅ DO: Implement tag-aware task utilities\n  function findTaskById(tasks, taskId) {\n    if (!Array.isArray(tasks)) {\n      return null;\n    }\n    return tasks.find(task => task.id === taskId) || null;\n  }\n  \n  function findSubtaskById(tasks, parentId, subtaskId) {\n    const parentTask = findTaskById(tasks, parentId);\n    if (!parentTask || !parentTask.subtasks) {\n      return null;\n    }\n    \n    return parentTask.subtasks.find(subtask => subtask.id === subtaskId) || null;\n  }\n  \n  function getNextTaskId(tasks) {\n    if (!Array.isArray(tasks) || tasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...tasks.map(task => task.id));\n    return maxId + 1;\n  }\n  \n  function getNextSubtaskId(parentTask) {\n    if (!parentTask.subtasks || parentTask.subtasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...parentTask.subtasks.map(subtask => subtask.id));\n    return maxId + 1;\n  }\n  ```\n\n## String Utilities\n\n- **Text Processing**:\n  - ✅ DO: Handle text truncation appropriately\n  - ✅ DO: Provide consistent formatting functions\n  - ✅ DO: Support different output formats\n\n  ```javascript\n  // ✅ DO: Implement useful string utilities\n  function truncate(str, maxLength = 50) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    if (str.length <= maxLength) {\n      return str;\n    }\n    \n    return str.substring(0, maxLength - 3) + '...';\n  }\n  \n  function formatDuration(ms) {\n    const seconds = Math.floor(ms / 1000);\n    const minutes = Math.floor(seconds / 60);\n    const hours = Math.floor(minutes / 60);\n    \n    if (hours > 0) {\n      return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n    } else if (minutes > 0) {\n      return `${minutes}m ${seconds % 60}s`;\n    } else {\n      return `${seconds}s`;\n    }\n  }\n  \n  function capitalizeFirst(str) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n  }\n  ```\n\n## Dependency Management Utilities\n\n- **Dependency Analysis**:\n  - ✅ DO: Detect circular dependencies\n  - ✅ DO: Validate dependency references\n  - ✅ DO: Support cross-tag dependency checking (future enhancement)\n\n  ```javascript\n  // ✅ DO: Implement dependency utilities\n  function findCycles(tasks) {\n    const cycles = [];\n    const visited = new Set();\n    const recStack = new Set();\n    \n    function dfs(taskId, path = []) {\n      if (recStack.has(taskId)) {\n        // Found a cycle\n        const cycleStart = path.indexOf(taskId);\n        const cycle = path.slice(cycleStart).concat([taskId]);\n        cycles.push(cycle);\n        return;\n      }\n      \n      if (visited.has(taskId)) {\n        return;\n      }\n      \n      visited.add(taskId);\n      recStack.add(taskId);\n      \n      const task = findTaskById(tasks, taskId);\n      if (task && task.dependencies) {\n        task.dependencies.forEach(depId => {\n          dfs(depId, path.concat([taskId]));\n        });\n      }\n      \n      recStack.delete(taskId);\n    }\n    \n    tasks.forEach(task => {\n      if (!visited.has(task.id)) {\n        dfs(task.id);\n      }\n    });\n    \n    return cycles;\n  }\n  \n  function validateDependencies(tasks) {\n    const validationErrors = [];\n    const taskIds = new Set(tasks.map(task => task.id));\n    \n    tasks.forEach(task => {\n      if (task.dependencies) {\n        task.dependencies.forEach(depId => {\n          if (!taskIds.has(depId)) {\n            validationErrors.push({\n              taskId: task.id,\n              invalidDependency: depId,\n              message: `Task ${task.id} depends on non-existent task ${depId}`\n            });\n          }\n        });\n      }\n    });\n    \n    return validationErrors;\n  }\n  ```\n\n## Environment and Configuration Utilities\n\n- **Environment Variable Resolution**:\n  - ✅ DO: Support both `.env` files and MCP session environment\n  - ✅ DO: Provide fallbacks for missing values\n  - ✅ DO: Handle API key resolution correctly\n\n  ```javascript\n  // ✅ DO: Implement flexible environment resolution\n  function resolveEnvVariable(key, sessionEnv = null) {\n    // First check session environment (for MCP)\n    if (sessionEnv && sessionEnv[key]) {\n      return sessionEnv[key];\n    }\n    \n    // Then check process environment\n    if (process.env[key]) {\n      return process.env[key];\n    }\n    \n    // Finally try .env file if in project root\n    try {\n      const projectRoot = findProjectRoot();\n      if (projectRoot) {\n        const envPath = path.join(projectRoot, '.env');\n        if (fs.existsSync(envPath)) {\n          const envContent = fs.readFileSync(envPath, 'utf8');\n          const lines = envContent.split('\\n');\n          \n          for (const line of lines) {\n            const [envKey, envValue] = line.split('=');\n            if (envKey && envKey.trim() === key) {\n              return envValue ? envValue.trim().replace(/^[\"']|[\"']$/g, '') : undefined;\n            }\n          }\n        }\n      }\n    } catch (error) {\n      log('debug', `Error reading .env file: ${error.message}`);\n    }\n    \n    return undefined;\n  }\n  \n  function getDebugFlag() {\n    const debugFlag = resolveEnvVariable('TASKMASTER_DEBUG') || \n                     resolveEnvVariable('DEBUG') || \n                     'false';\n    return debugFlag.toLowerCase() === 'true';\n  }\n  ```\n\n## Export Pattern\n\n- **Module Exports**:\n  - ✅ DO: Export all utility functions explicitly\n  - ✅ DO: Group related functions logically\n  - ✅ DO: Include new tagged system utilities\n\n  ```javascript\n  // ✅ DO: Export utilities in logical groups\n  module.exports = {\n    // File system utilities\n    readJSON,\n    writeJSON,\n    findProjectRoot,\n    \n    // Tagged task system utilities\n    getTasksForTag,\n    setTasksForTag,\n    getCurrentTag,\n    performCompleteTagMigration,\n    migrateConfigJson,\n    createStateJson,\n    markMigrationForNotice,\n    \n    // Logging utilities\n    log,\n    enableSilentMode,\n    disableSilentMode,\n    isSilentMode,\n    \n    // Task utilities\n    findTaskById,\n    findSubtaskById,\n    getNextTaskId,\n    getNextSubtaskId,\n    \n    // String utilities\n    truncate,\n    formatDuration,\n    capitalizeFirst,\n    \n    // Dependency utilities\n    findCycles,\n    validateDependencies,\n    \n    // Environment utilities\n    resolveEnvVariable,\n    getDebugFlag,\n    \n    // Legacy utilities (maintained for compatibility)\n    aggregateTelemetry\n  };\n  ```\n\nRefer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for integration patterns.\n",".taskmaster/CLAUDE.md":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nTask Master uses tiered tool loading to optimize context window usage:\n\n| Tier | Tools | Use Case |\n|------|-------|----------|\n| `core` | 7 | Minimal daily workflow tools (default) |\n| `standard` | 14 | Common task management |\n| `all` | 42+ | Full suite with research, autopilot, dependencies |\n\n**Core tools (7):** `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task`\n\n**Standard adds (7 more):** `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report`\n\n**All tier adds:** Dependency management, tag management, research, autopilot TDD workflow, scope up/down, models, rules\n\n**To upgrade tiers:** Change `TASK_MASTER_TOOLS` in `.mcp.json` from `\"core\"` to `\"standard\"` or `\"all\"` and restart the MCP connection.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","CLAUDE.md":"# Claude Code Instructions\n\n## Task Master AI Instructions\n\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n@./.taskmaster/CLAUDE.md\n\n## Test Guidelines\n\n### Test File Placement\n\n- **Package & tests**: Place in `packages/<package-name>/src/<module>/<file>.spec.ts` or `apps/<app-name>/src/<module>/<file.spec.ts>` alongside source\n- **Package integration tests**: Place in `packages/<package-name>/tests/integration/<module>/<file>.test.ts` or `apps/<app-name>/tests/integration/<module>/<file>.test.ts` alongside source\n- **Isolated unit tests**: Use `tests/unit/packages/<package-name>/` only when parallel placement isn't possible\n- **Test extension**: Always use `.ts` for TypeScript tests, never `.js`\n\n### Synchronous Tests\n\n- **NEVER use async/await in test functions** unless testing actual asynchronous operations\n- Use synchronous top-level imports instead of dynamic `await import()`\n- Test bodies should be synchronous whenever possible\n- Example:\n\n  ```typescript\n  // ✅ CORRECT - Synchronous imports with .ts extension\n  import { MyClass } from '../src/my-class.js';\n\n  it('should verify behavior', () => {\n    expect(new MyClass().property).toBe(value);\n  });\n\n  // ❌ INCORRECT - Async imports\n  it('should verify behavior', async () => {\n    const { MyClass } = await import('../src/my-class.js');\n    expect(new MyClass().property).toBe(value);\n  });\n  ```\n\n### When to Write Tests\n\n**ALWAYS write tests for:**\n\n- **Bug fixes**: Add a regression test that would have caught the bug\n- **Business logic**: Complex calculations, validations, transformations\n- **Edge cases**: Boundary conditions, error handling, null/undefined cases\n- **Public APIs**: Methods other code depends on\n- **Integration points**: Database, file system, external APIs\n\n**SKIP tests for:**\n\n- Simple getters/setters: `getX() { return this.x; }`\n- Trivial pass-through functions with no logic\n- Pure configuration objects\n- Code that just delegates to another tested function\n\n**Examples:**\n\n```javascript\n// ✅ WRITE A TEST - Bug fix with regression prevention\nit('should use correct baseURL from defaultBaseURL config', () => {\n  const provider = new ZAIProvider();\n  expect(provider.defaultBaseURL).toBe('https://api.z.ai/api/paas/v4/');\n});\n\n// ✅ WRITE A TEST - Business logic with edge cases\nit('should parse subtask IDs correctly', () => {\n  expect(parseTaskId('1.2.3')).toEqual({ taskId: 1, subtaskId: 2, subSubtaskId: 3 });\n  expect(parseTaskId('invalid')).toBeNull();\n});\n\n// ❌ SKIP TEST - Trivial getter\nclass Task {\n  get id() { return this._id; } // No test needed\n}\n\n// ❌ SKIP TEST - Pure delegation\nfunction getTasks() {\n  return taskManager.getTasks(); // Already tested in taskManager\n}\n```\n\n**Bug Fix Workflow:**\n\n1. Encounter a bug\n2. Write a failing test that reproduces it\n3. Fix the bug\n4. Verify test now passes\n5. Commit both fix and test together\n\n### Testing Guidelines\n\n**Principles**: FIRST (Fast, Independent, Repeatable, Self-validating, Timely)\n**Structure**: AAA (Arrange, Act, Assert)\n**Coverage**: Right-BICEP (Right results, Boundary, Inverse, Cross-check, Error conditions, Performance)\n\n#### What to Mock\n\n**Unit tests** (`.spec.ts` - test single unit in isolation):\n- **@tm/core**: Mock only external I/O (Supabase, APIs, filesystem). Use real internal services.\n- **apps/cli**: Mock tm-core responses. Use real Commander/chalk/inquirer/other npm packages (test display logic).\n- **apps/mcp**: Mock tm-core responses. Use real MCP framework (test response formatting).\n\n**Integration tests** (`tests/integration/` - test multiple units together):\n- **All packages**: Use real tm-core, mock only external boundaries (APIs, DB, filesystem).\n\n**Never mock**:\n- Internal utilities/helpers in the same package\n- Standard frameworks (Commander, Express) - let them run\n- Standard library\n\n**Rule of thumb**: Mock what you're NOT testing. CLI unit tests test display → mock tm-core. Core unit tests test logic → mock I/O. Integration tests test full flow → mock only external APIs.\n\n**Red flag**: Mocking 3+ dependencies in a unit test means code is doing too much or is in the wrong layer.\n\n**Anti-pattern**: Heavily mocked tests don't verify real behavior—they verify that you wired up mocks correctly. You end up writing orchestration code to satisfy tests, rather than tests that validate your actual implementation. If testing is hard, move the logic to where it's naturally testable.\n\n## Architecture Guidelines\n\n### Business Logic Separation\n\n**CRITICAL RULE**: ALL business logic must live in `@tm/core`, NOT in presentation layers.\n\n- **`@tm/core`** (packages/tm-core/):\n  - Contains ALL business logic, domain models, services, and utilities\n  - Provides clean facade APIs through domain objects (tasks, auth, workflow, git, config)\n  - Houses all complexity - parsing, validation, transformations, calculations, etc.\n  - Example: Task ID parsing, subtask extraction, status validation, dependency resolution\n\n- **`@tm/cli`** (apps/cli/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays results\n  - Handles CLI-specific concerns: argument parsing, output formatting, user prompts\n  - NO business logic, NO data transformations, NO calculations\n\n- **`@tm/mcp`** (apps/mcp/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and returns MCP-formatted responses\n  - Handles MCP-specific concerns: tool schemas, parameter validation, response formatting\n  - NO business logic, NO data transformations, NO calculations\n\n- **`apps/extension`** (future):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays in VS Code UI\n  - NO business logic\n\n**Examples of violations to avoid:**\n\n- ❌ Creating helper functions in CLI/MCP to parse task IDs → Move to tm-core\n- ❌ Data transformation logic in CLI/MCP → Move to tm-core\n- ❌ Validation logic in CLI/MCP → Move to tm-core\n- ❌ Duplicating logic across CLI and MCP → Implement once in tm-core\n\n**Correct approach:**\n\n- ✅ Add method to TasksDomain: `tasks.get(taskId)` (automatically handles task and subtask IDs)\n- ✅ CLI calls: `await tmCore.tasks.get(taskId)` (supports \"1\", \"1.2\", \"HAM-123\", \"HAM-123.2\")\n- ✅ MCP calls: `await tmCore.tasks.get(taskId)` (same intelligent ID parsing)\n- ✅ Single source of truth in tm-core\n\n## Code Quality & Reusability Guidelines\n\nApply standard software engineering principles:\n\n- **DRY (Don't Repeat Yourself)**: Extract patterns that appear 2+ times into reusable components or utilities\n- **YAGNI (You Aren't Gonna Need It)**: Don't over-engineer. Create abstractions when duplication appears, not before\n- **Maintainable**: Single source of truth. Change once, update everywhere\n- **Readable**: Clear naming, proper structure, export from index files\n- **Flexible**: Accept configuration options with sensible defaults\n\n## Documentation Guidelines\n\n- **Documentation location**: Write docs in `apps/docs/` (Mintlify site source), not `docs/`\n- **Documentation URL**: Reference docs at <https://tryhamster.com/docs/taskmaster>, not local file paths\n\n## Changeset Guidelines\n\n- **Add a changeset for code changes** - Run `npx changeset` after making code changes (not needed for docs-only PRs)\n- When creating changesets, remember that it's user-facing, meaning we don't have to get into the specifics of the code, but rather mention what the end-user is getting or fixing from this changeset\n- Run `npm run turbo:typecheck` before pushing to ensure TypeScript type checks pass\n- Run `npm run test -w <package-name>` to test a package\n","assets/AGENTS.md":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\ntask-master generate                                         # Update task markdown files (usually auto-called)\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nDefault: `core` (7 tools). Set via `TASK_MASTER_TOOLS` env var.\n\n| Tier | Count | Tools |\n|------|-------|-------|\n| `core` | 7 | `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task` |\n| `standard` | 14 | core + `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report` |\n| `all` | 44+ | standard + dependencies, tags, research, autopilot, scoping, models, rules |\n\n**Upgrade when tool unavailable:** Edit MCP config, change `TASK_MASTER_TOOLS` from `\"core\"` to `\"standard\"` or `\"all\"`, restart MCP.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Regenerate task files from tasks.json\ntask-master generate\n\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n- Task markdown files in `tasks/` are auto-generated\n- Run `task-master generate` after manual changes to tasks.json\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","packages/ai-sdk-provider-grok-cli/README.md":"# AI SDK Provider for Grok CLI\n\nA provider for the [AI SDK](https://sdk.vercel.ai) that integrates with [Grok CLI](https://docs.x.ai/api) for accessing xAI's Grok language models.\n\n## Features\n\n- ✅ **AI SDK v5 Compatible** - Full support for the latest AI SDK interfaces\n- ✅ **Streaming & Non-streaming** - Both generation modes supported\n- ✅ **Error Handling** - Comprehensive error handling with retry logic\n- ✅ **Type Safety** - Full TypeScript support with proper type definitions\n- ✅ **JSON Mode** - Automatic JSON extraction from responses\n- ✅ **Abort Signals** - Proper cancellation support\n\n## Installation\n\n```bash\nnpm install @tm/ai-sdk-provider-grok-cli\n# or\nyarn add @tm/ai-sdk-provider-grok-cli\n```\n\n## Prerequisites\n\n1. Install the Grok CLI:\n\n   ```bash\n   npm install -g grok-cli\n   # or follow xAI's installation instructions\n   ```\n\n2. Set up authentication:\n\n   ```bash\n   export GROK_CLI_API_KEY=\"your-api-key\"\n   # or configure via grok CLI: grok config set api-key your-key\n   ```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: grokCli('grok-3-latest'),\n  prompt: 'Write a haiku about TypeScript'\n});\n\nconsole.log(result.text);\n```\n\n### Streaming\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { streamText } from 'ai';\n\nconst { textStream } = await streamText({\n  model: grokCli('grok-4-latest'),\n  prompt: 'Explain quantum computing'\n});\n\nfor await (const delta of textStream) {\n  process.stdout.write(delta);\n}\n```\n\n### JSON Mode\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateObject } from 'ai';\nimport { z } from 'zod';\n\nconst result = await generateObject({\n  model: grokCli('grok-3-latest'),\n  schema: z.object({\n    name: z.string(),\n    age: z.number(),\n    hobbies: z.array(z.string())\n  }),\n  prompt: 'Generate a person profile'\n});\n\nconsole.log(result.object);\n```\n\n## Supported Models\n\n- `grok-3-latest` - Grok 3 (latest version)\n- `grok-4-latest` - Grok 4 (latest version)\n- `grok-4` - Grok 4 (stable)\n- Custom model strings supported\n\n## Configuration\n\n### Provider Settings\n\n```typescript\nimport { createGrokCli } from '@tm/ai-sdk-provider-grok-cli';\n\nconst grok = createGrokCli({\n  apiKey: 'your-api-key', // Optional if set via env/CLI\n  timeout: 120000, // 2 minutes default\n  workingDirectory: '/path/to/project', // Optional\n  baseURL: 'https://api.x.ai' // Optional\n});\n```\n\n### Model Settings\n\n```typescript\nconst model = grok('grok-4-latest', {\n  timeout: 300000, // 5 minutes for grok-4\n  // Other CLI-specific settings\n});\n```\n\n## Error Handling\n\nThe provider includes comprehensive error handling:\n\n```typescript\nimport {\n  isAuthenticationError,\n  isTimeoutError,\n  isInstallationError\n} from '@tm/ai-sdk-provider-grok-cli';\n\ntry {\n  const result = await generateText({\n    model: grokCli('grok-4-latest'),\n    prompt: 'Hello!'\n  });\n} catch (error) {\n  if (isAuthenticationError(error)) {\n    console.error('Authentication failed:', error.message);\n  } else if (isTimeoutError(error)) {\n    console.error('Request timed out:', error.message);\n  } else if (isInstallationError(error)) {\n    console.error('Grok CLI not installed or not found in PATH');\n  }\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start development mode (keep running during development)\nnpm run dev\n\n# Type check\nnpm run typecheck\n\n# Run tests (requires build first)\nNODE_ENV=production npm run build\nnpm test\n```\n\n**Important**: Always run `npm run dev` and keep it running during development. This ensures proper compilation and hot-reloading of TypeScript files.\n","packages/claude-code-plugin/.claude-plugin/plugin.json":"{\n\t\"name\": \"taskmaster\",\n\t\"description\": \"A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.\",\n\t\"author\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"url\": \"https://github.com/eyaltoledano/claude-task-master\"\n\t},\n\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master#readme\",\n\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\"license\": \"MIT WITH Commons-Clause\",\n\t\"keywords\": [\n\t\t\"task-management\",\n\t\t\"ai\",\n\t\t\"workflow\",\n\t\t\"orchestration\",\n\t\t\"automation\",\n\t\t\"mcp\",\n\t\t\"development\",\n\t\t\"productivity\"\n\t]\n}\n","packages/claude-code-plugin/commands/sync-readme.md":"Export tasks to README.md with professional formatting.\n\nArguments: $ARGUMENTS\n\nGenerate a well-formatted README with current task information.\n\n## README Synchronization\n\nCreates or updates README.md with beautifully formatted task information.\n\n## Argument Parsing\n\nOptional filters:\n- \"pending\" → Only pending tasks\n- \"with-subtasks\" → Include subtask details\n- \"by-priority\" → Group by priority\n- \"sprint\" → Current sprint only\n\n## Execution\n\n```bash\ntask-master sync-readme [--with-subtasks] [--status=<status>]\n```\n\n## README Generation\n\n### 1. **Project Header**\n```markdown\n# Project Name\n\n## 📋 Task Progress\n\nLast Updated: 2024-01-15 10:30 AM\n\n### Summary\n- Total Tasks: 45\n- Completed: 15 (33%)\n- In Progress: 5 (11%)\n- Pending: 25 (56%)\n```\n\n### 2. **Task Sections**\nOrganized by status or priority:\n- Progress indicators\n- Task descriptions\n- Dependencies noted\n- Time estimates\n\n### 3. **Visual Elements**\n- Progress bars\n- Status badges\n- Priority indicators\n- Completion checkmarks\n\n## Smart Features\n\n1. **Intelligent Grouping**\n   - By feature area\n   - By sprint/milestone\n   - By assigned developer\n   - By priority\n\n2. **Progress Tracking**\n   - Overall completion\n   - Sprint velocity\n   - Burndown indication\n   - Time tracking\n\n3. **Formatting Options**\n   - GitHub-flavored markdown\n   - Task checkboxes\n   - Collapsible sections\n   - Table format available\n\n## Example Output\n\n```markdown\n## 🚀 Current Sprint\n\n### In Progress\n- [ ] 🔄 #5 **Implement user authentication** (60% complete)\n  - Dependencies: API design (#3 ✅)\n  - Subtasks: 4 (2 completed)\n  - Est: 8h / Spent: 5h\n\n### Pending (High Priority)\n- [ ] ⚡ #8 **Create dashboard UI**\n  - Blocked by: #5\n  - Complexity: High\n  - Est: 12h\n```\n\n## Customization\n\nBased on arguments:\n- Include/exclude sections\n- Detail level control\n- Custom grouping\n- Filter by criteria\n\n## Post-Sync\n\nAfter generation:\n1. Show diff preview\n2. Backup existing README\n3. Write new content\n4. Commit reminder\n5. Update timestamp\n\n## Integration\n\nWorks well with:\n- Git workflows\n- CI/CD pipelines\n- Project documentation\n- Team updates\n- Client reports","packages/tm-bridge/README.md":"# @tm/bridge\n\n> ⚠️ **TEMPORARY PACKAGE - DELETE WHEN LEGACY CODE IS REMOVED** ⚠️\n\nThis package exists solely as a bridge between legacy scripts (`scripts/modules/task-manager/`) and the new tm-core architecture. It provides shared functionality that both CLI and MCP direct functions can use during the migration period.\n\n## Why does this exist?\n\nDuring the transition from legacy scripts to tm-core, we need a single source of truth for bridge logic that handles:\n- API vs file storage detection\n- Remote AI service delegation\n- Consistent behavior across CLI and MCP interfaces\n\n## When to delete this\n\nDelete this entire package when:\n1. ✅ Legacy scripts in `scripts/modules/task-manager/` are removed\n2. ✅ MCP direct functions in `mcp-server/src/core/direct-functions/` are removed\n3. ✅ All functionality has moved to tm-core\n4. ✅ CLI and MCP use tm-core directly via TasksDomain\n\n## Migration path\n\n```text\nCurrent:   CLI → legacy scripts → @tm/bridge → @tm/core\n          MCP → direct functions → legacy scripts → @tm/bridge → @tm/core\n\nFuture:    CLI → @tm/core (TasksDomain)\n          MCP → @tm/core (TasksDomain)\n\nDELETE:    legacy scripts, direct functions, @tm/bridge\n```\n\n## Usage\n\n```typescript\nimport { tryUpdateViaRemote } from '@tm/bridge';\n\nconst result = await tryUpdateViaRemote({\n  taskId: '1.2',\n  prompt: 'Update task...',\n  projectRoot: '/path/to/project',\n  // ... other params\n});\n```\n\n## Contents\n\n- `update-bridge.ts` - Shared update bridge logic for task/subtask updates\n\n---\n\n**Remember:** This package should NOT accumulate new features. It's a temporary migration aid only.\n","packages/tm-core/README.md":"# @task-master/tm-core\n\nCore library for Task Master AI - providing task management and orchestration capabilities with TypeScript support.\n\n## Overview\n\n`tm-core` is the foundational library that powers Task Master AI's task management system. It provides a comprehensive set of tools for creating, managing, and orchestrating tasks with AI integration.\n\n## Features\n\n- **TypeScript-first**: Built with full TypeScript support and strict type checking\n- **Dual Format**: Supports both ESM and CommonJS with automatic format detection\n- **Modular Architecture**: Clean separation of concerns with dedicated modules for different functionality\n- **AI Provider Integration**: Pluggable AI provider system for task generation and management\n- **Flexible Storage**: Abstracted storage layer supporting different persistence strategies\n- **Task Parsing**: Advanced parsing capabilities for various task definition formats\n- **Error Handling**: Comprehensive error system with specific error types\n- **Testing**: Complete test coverage with Jest and TypeScript support\n\n## Installation\n\n```bash\nnpm install @task-master/tm-core\n```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { generateTaskId, PlaceholderTask } from '@task-master/tm-core';\n\n// Generate a unique task ID\nconst taskId = generateTaskId();\n\n// Create a task (coming soon - full implementation)\nconst task: PlaceholderTask = {\n  id: taskId,\n  title: 'My Task',\n  status: 'pending',\n  priority: 'medium'\n};\n```\n\n### Modular Imports\n\nYou can import specific modules to reduce bundle size:\n\n```typescript\n// Import types only\nimport type { TaskId, TaskStatus } from '@task-master/tm-core/types';\n\n// Import utilities\nimport { generateTaskId, formatDate } from '@task-master/tm-core/utils';\n\n// Import providers (AI providers coming soon)\n// import { AIProvider } from '@task-master/tm-core/providers';\n\n// Import storage\nimport { PlaceholderStorage } from '@task-master/tm-core/storage';\n\n// Import parsers\nimport { PlaceholderParser } from '@task-master/tm-core/parser';\n\n// Import errors\nimport { TmCoreError, TaskNotFoundError } from '@task-master/tm-core/errors';\n```\n\n## Architecture\n\nThe library is organized into several key modules:\n\n- **types/**: TypeScript type definitions and interfaces\n- **providers/**: AI provider implementations for task generation\n- **storage/**: Storage adapters for different persistence strategies\n- **parser/**: Task parsing utilities for various formats\n- **utils/**: Common utility functions and helpers\n- **errors/**: Custom error classes and error handling\n\n## Development\n\n### Prerequisites\n\n- Node.js >= 20.0.0\n- npm or yarn\n\n### Setup\n\n```bash\n# Install dependencies\nnpm install\n\n# Build the library\nnpm run build\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Lint code\nnpm run lint\n\n# Format code\nnpm run format\n```\n\n### Scripts\n\n- `build`: Build the library for both ESM and CJS formats\n- `build:watch`: Build in watch mode for development\n- `test`: Run the test suite\n- `test:watch`: Run tests in watch mode\n- `test:coverage`: Run tests with coverage reporting\n- `lint`: Lint TypeScript files\n- `lint:fix`: Lint and auto-fix issues\n- `format`: Format code with Prettier\n- `format:check`: Check code formatting\n- `typecheck`: Type-check without emitting files\n- `clean`: Clean build artifacts\n- `dev`: Development mode with watch\n\n## ESM and CommonJS Support\n\nThis package supports both ESM and CommonJS formats automatically:\n\n```javascript\n// ESM\nimport { generateTaskId } from '@task-master/tm-core';\n\n// CommonJS\nconst { generateTaskId } = require('@task-master/tm-core');\n```\n\n## Roadmap\n\nThis is the initial package structure. The following features are planned for implementation:\n\n### Task 116: TypeScript Types\n- [ ] Complete type definitions for tasks, projects, and configurations\n- [ ] Zod schema validation\n- [ ] Generic type utilities\n\n### Task 117: AI Provider System\n- [ ] Base provider interface\n- [ ] Anthropic Claude integration\n- [ ] OpenAI integration\n- [ ] Perplexity integration\n- [ ] Provider factory and registry\n\n### Task 118: Storage Layer\n- [ ] File system storage adapter\n- [ ] Memory storage adapter\n- [ ] Storage interface and factory\n\n### Task 119: Task Parser\n- [ ] PRD parser implementation\n- [ ] Markdown parser\n- [ ] JSON task format parser\n- [ ] Validation utilities\n\n### Task 120: Utility Functions\n- [ ] Task ID generation\n- [ ] Date formatting\n- [ ] Validation helpers\n- [ ] File system utilities\n\n### Task 121: Error Handling\n- [ ] Task-specific errors\n- [ ] Storage errors\n- [ ] Provider errors\n- [ ] Validation errors\n\n### Task 122: Configuration System\n- [ ] Configuration schema\n- [ ] Default configurations\n- [ ] Environment variable support\n\n### Task 123: Testing Infrastructure\n- [ ] Unit test coverage\n- [ ] Integration tests\n- [ ] Mock utilities\n\n### Task 124: Documentation\n- [ ] API documentation\n- [ ] Usage examples\n- [ ] Migration guides\n\n### Task 125: Package Finalization\n- [ ] Final testing and validation\n- [ ] Release preparation\n- [ ] CI/CD integration\n\n## Implementation Checklist\n\n### ✅ Task 115: Initialize tm-core Package Structure (COMPLETED)\n- [x] Create tm-core directory structure and base configuration files\n- [x] Configure build and test infrastructure \n- [x] Create barrel export files for all directories\n- [x] Add development tooling and documentation\n- [x] Validate package structure and prepare for development\n\n### 🚧 Remaining Implementation Tasks\n- [ ] **Task 116**: TypeScript Types - Complete type definitions for tasks, projects, and configurations\n- [ ] **Task 117**: AI Provider System - Base provider interface and integrations\n- [ ] **Task 118**: Storage Layer - File system and memory storage adapters\n- [ ] **Task 119**: Task Parser - PRD, Markdown, and JSON parsers\n- [ ] **Task 120**: Utility Functions - Task ID generation, validation helpers\n- [ ] **Task 121**: Error Handling - Task-specific and validation errors\n- [ ] **Task 122**: Configuration System - Schema and environment support\n- [ ] **Task 123**: Testing Infrastructure - Complete unit and integration tests\n- [ ] **Task 124**: Documentation - API docs and usage examples\n- [ ] **Task 125**: Package Finalization - Release preparation and CI/CD\n\n## Contributing\n\nThis package is part of the Task Master AI project. Please refer to the main project's contributing guidelines.\n\n## License\n\nMIT - See the main project's LICENSE file for details.\n\n## Support\n\nFor questions and support, please refer to the main Task Master AI documentation.","packages/tm-core/docs/listTasks-architecture.md":"# ListTasks Architecture - End-to-End POC\n\n## Current Implementation Structure\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                         CLI Layer                            │\n│  scripts/modules/task-manager/list-tasks.js                 │\n│  - Complex UI rendering (tables, progress bars)             │\n│  - Multiple output formats (json, text, markdown, compact)  │\n│  - Status filtering and statistics                          │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              │ Currently reads directly\n                              │ from files (needs integration)\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                      tm-core Package                         │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            TaskMasterCore (Facade)                   │   │\n│  │  src/task-master-core.ts                            │   │\n│  │                                                      │   │\n│  │  - listTasks(options)                               │   │\n│  │    • tag filtering                                  │   │\n│  │    • status filtering                               │   │\n│  │    • include/exclude subtasks                       │   │\n│  │  - getTask(id)                                      │   │\n│  │  - getTasksByStatus(status)                         │   │\n│  │  - getTaskStats()                                   │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                              │                               │\n│                              ▼                               │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │              Storage Layer (IStorage)                │   │\n│  │                                                      │   │\n│  │  ┌──────────────┐        ┌──────────────┐          │   │\n│  │  │ FileStorage  │        │ ApiStorage   │          │   │\n│  │  │              │        │ (Hamster)    │          │   │\n│  │  └──────────────┘        └──────────────┘          │   │\n│  │                                                      │   │\n│  │  StorageFactory.create() selects based on config    │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            Domain Layer (Entities)                   │   │\n│  │                                                      │   │\n│  │  TaskEntity                                         │   │\n│  │  - Business logic                                   │   │\n│  │  - Validation                                       │   │\n│  │  - Status transitions                               │   │\n│  └─────────────────────────────────────────────────────┘   │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## ListTasks Data Flow\n\n### 1. CLI Request\n```javascript\n// Current CLI (needs update to use tm-core)\nlistTasks(tasksPath, statusFilter, reportPath, withSubtasks, outputFormat, context)\n```\n\n### 2. TaskMasterCore Processing\n```typescript\n// Our new implementation\nconst tmCore = createTaskMasterCore(projectPath, { \n  storage: { \n    type: 'api',  // or 'file'\n    apiEndpoint: 'https://tryhamster.com',\n    apiAccessToken: 'xxx'\n  }\n});\n\nconst result = await tmCore.listTasks({\n  tag: 'feature-branch',\n  filter: {\n    status: ['pending', 'in-progress'],\n    priority: 'high',\n    search: 'authentication'\n  },\n  includeSubtasks: true\n});\n```\n\n### 3. Storage Selection\n```typescript\n// StorageFactory automatically selects storage\nconst storage = StorageFactory.create(config, projectPath);\n// Returns either FileStorage or ApiStorage based on config\n```\n\n### 4. Data Loading\n```typescript\n// FileStorage\n- Reads from .taskmaster/tasks/tasks.json (or tag-specific file)\n- Local file system operations\n\n// ApiStorage (Hamster)\n- Makes HTTP requests to Hamster API\n- Uses access token from config\n- Handles retries and rate limiting\n```\n\n### 5. Entity Processing\n```typescript\n// Convert raw data to TaskEntity for business logic\nconst taskEntities = TaskEntity.fromArray(rawTasks);\n\n// Apply filters\nconst filtered = applyFilters(taskEntities, filter);\n\n// Convert back to plain objects\nconst tasks = filtered.map(entity => entity.toJSON());\n```\n\n### 6. Response Structure\n```typescript\ninterface ListTasksResult {\n  tasks: Task[];        // Filtered tasks\n  total: number;        // Total task count\n  filtered: number;     // Filtered task count  \n  tag?: string;         // Tag context if applicable\n}\n```\n\n## Integration Points Needed\n\n### 1. CLI Integration\n- [ ] Update `scripts/modules/task-manager/list-tasks.js` to use tm-core\n- [ ] Map CLI options to TaskMasterCore options\n- [ ] Handle output formatting in CLI layer\n\n### 2. Configuration Loading\n- [ ] Load `.taskmaster/config.json` for storage settings\n- [ ] Support environment variables for API tokens\n- [ ] Handle storage type selection\n\n### 3. Testing Requirements\n- [x] Unit tests for TaskEntity\n- [x] Unit tests for BaseProvider\n- [x] Integration tests for listTasks with FileStorage\n- [ ] Integration tests for listTasks with ApiStorage (mock API)\n- [ ] E2E tests with real Hamster API (optional)\n\n## Benefits of This Architecture\n\n1. **Storage Abstraction**: Switch between file and API storage without changing business logic\n2. **Clean Separation**: UI (CLI) separate from business logic (tm-core)\n3. **Testability**: Each layer can be tested independently\n4. **Extensibility**: Easy to add new storage types (database, cloud, etc.)\n5. **Type Safety**: Full TypeScript support throughout\n6. **Error Handling**: Consistent error handling with TaskMasterError\n\n## Next Steps\n\n1. Create a simple CLI wrapper that uses tm-core\n2. Test with file storage (existing functionality)\n3. Test with mock API storage\n4. Integrate with actual Hamster API when available\n5. Migrate other commands (addTask, updateTask, etc.) following same pattern","tests/unit/scripts/modules/commands/README.md":"# Mock System Documentation\n\n## Overview\n\nThe `move-cross-tag.test.js` file has been refactored to use a focused, maintainable mock system that addresses the brittleness and complexity of the original implementation.\n\n## Key Improvements\n\n### 1. **Focused Mocking**\n\n- **Before**: Mocked 20+ modules, many irrelevant to cross-tag functionality\n- **After**: Only mocks 5 core modules actually used in cross-tag moves\n\n### 2. **Configuration-Driven Mocking**\n\n```javascript\nconst mockConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true,\n    initTaskMaster: true,\n    findProjectRoot: true\n  }\n};\n```\n\n### 3. **Reusable Mock Factory**\n\n```javascript\nfunction createMockFactory(config = mockConfig) {\n  const mocks = {};\n  \n  if (config.core?.moveTasksBetweenTags) {\n    mocks.moveTasksBetweenTags = createMock('moveTasksBetweenTags');\n  }\n  // ... other mocks\n  \n  return mocks;\n}\n```\n\n## Mock Configuration\n\n### Core Mocks (Required for Cross-Tag Functionality)\n\n- `moveTasksBetweenTags`: Core move functionality\n- `generateTaskFiles`: File generation after moves\n- `readJSON`: Reading task data\n- `initTaskMaster`: TaskMaster initialization\n- `findProjectRoot`: Project path resolution\n\n### Optional Mocks\n\n- Console methods: `error`, `log`, `exit`\n- TaskMaster instance methods: `getCurrentTag`, `getTasksPath`, `getProjectRoot`\n\n## Usage Examples\n\n### Default Configuration\n\n```javascript\nconst mocks = setupMocks(); // Uses default mockConfig\n```\n\n### Minimal Configuration\n\n```javascript\nconst minimalConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(minimalConfig);\n```\n\n### Selective Mocking\n\n```javascript\nconst selectiveConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: false, // Disabled\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(selectiveConfig);\n```\n\n## Benefits\n\n1. **Reduced Complexity**: From 150+ lines of mock setup to 50 lines\n2. **Better Maintainability**: Clear configuration object shows dependencies\n3. **Focused Testing**: Only mocks what's actually used\n4. **Flexible Configuration**: Easy to enable/disable specific mocks\n5. **Consistent Naming**: All mocks use `createMock()` with descriptive names\n\n## Migration Guide\n\n### For Other Test Files\n\n1. Identify actual module dependencies\n2. Create configuration object for required mocks\n3. Use `createMockFactory()` and `setupMocks()`\n4. Remove unnecessary mocks\n\n### Example Migration\n\n```javascript\n// Before: 20+ jest.mock() calls\njest.mock('module1', () => ({ ... }));\njest.mock('module2', () => ({ ... }));\n// ... many more\n\n// After: Configuration-driven\nconst mockConfig = {\n  core: {\n    requiredFunction1: true,\n    requiredFunction2: true\n  }\n};\nconst mocks = setupMocks(mockConfig);\n```\n\n## Testing the Mock System\n\nThe test suite includes validation tests:\n\n- `should work with minimal mock configuration`\n- `should allow disabling specific mocks`\n\nThese ensure the mock factory works correctly and can be configured flexibly.\n"},"files":{".claude-plugin/marketplace.json":"{\n\t\"name\": \"taskmaster\",\n\t\"owner\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"email\": \"ralph@tryhamster.com\"\n\t},\n\t\"metadata\": {\n\t\t\"description\": \"Official marketplace for Taskmaster AI - AI-powered task management for ambitious development\",\n\t\t\"version\": \"1.0.0\"\n\t},\n\t\"plugins\": [\n\t\t{\n\t\t\t\"name\": \"taskmaster\",\n\t\t\t\"source\": \"./packages/claude-code-plugin\",\n\t\t\t\"description\": \"AI-powered task management system for ambitious development workflows with intelligent orchestration, complexity analysis, and automated coordination\",\n\t\t\t\"author\": {\n\t\t\t\t\"name\": \"Hamster\"\n\t\t\t},\n\t\t\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"keywords\": [\n\t\t\t\t\"task-management\",\n\t\t\t\t\"ai\",\n\t\t\t\t\"workflow\",\n\t\t\t\t\"orchestration\",\n\t\t\t\t\"automation\",\n\t\t\t\t\"mcp\"\n\t\t\t],\n\t\t\t\"category\": \"productivity\"\n\t\t}\n\t]\n}\n",".claude/commands/dedupe.md":"---\nallowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)\ndescription: Find duplicate GitHub issues\n---\n\nFind up to 3 likely duplicate issues for a given GitHub issue.\n\nTo do this, follow these steps precisely:\n\n1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.\n2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue\n3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1\n4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.\n5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)\n\nNotes (be sure to tell this to your agents, too):\n\n- Use `gh` to interact with Github, rather than web fetch\n- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)\n- Make a todo list first\n- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):\n\n---\n\nFound 3 possible duplicate issues:\n\n1. <link to issue>\n2. <link to issue>\n3. <link to issue>\n\nThis issue will be automatically closed as a duplicate in 3 days.\n\n- If your issue is a duplicate, please close it and 👍 the existing issue instead\n- To prevent auto-closure, add a comment or 👎 this comment\n\n🤖 Generated with \\[Task Master Bot\\]\n\n---",".claude/commands/go/ham.md":"# Hamster (Go ham!) Run Task Workflow\n\nThis command initiates the HAM (Hamster Automated Management) workflow for task execution.\n\n## Usage\n\n```\n/go:ham [task-id]\n```\n\n- `task-id` (optional): Specific task identifier to work on (e.g., \"1\", \"1.2\", \"2.3.1\")\n  - If provided, start working on that specific task immediately\n  - If omitted, automatically identify the next available task\n\n## Process\n\nWhen the user invokes this command, follow these steps:\n\n### 1. Task Selection\n\n#### If task-id is provided ($ARGUMENTS is not empty):\n```bash\ntm show $ARGUMENTS\n```\nStart working on the specified task immediately, skipping to step 3.\n\n#### If no task-id is provided ($ARGUMENTS is empty):\n```bash\ntm list\n```\nDisplay all tasks with their current status to provide context.\n\n### 2. Identify Next Task (only if no task-id provided)\nDetermine which task should be worked on next based on:\n- Dependencies\n- Priority\n- Current status (pending tasks only)\n\n### 3. Show Task Details (only if task wasn't specified in step 1)\n```bash\ntm show <task-id>\n```\nDisplay the full details of the identified task including:\n- Title and description\n- Dependencies\n- Test strategy\n- Subtasks (if any)\n\n### 4. Kickoff Workflow\n\nBased on the task type, follow the appropriate workflow:\n\n#### For Main Tasks (e.g., \"1\", \"2\", \"3\")\n- Review the task's subtasks\n- If no subtasks exist, suggest expanding the task first\n- Identify the first pending subtask\n- Begin implementation following the subtask's requirements\n\n#### For Subtasks (e.g., \"1.1\", \"2.3\")\n- Mark the subtask as in-progress:\n  ```bash\n  tm set-status --id=<subtask-id> --status=in-progress\n  ```\n- Review the task details and requirements\n- Check for related code files or dependencies\n- Create an implementation plan\n- Begin implementation following project conventions\n\n### 5. Implementation Guidelines\n\nFollow these principles during implementation:\n\n1. **Understand First**: Read related files and understand the current architecture\n2. **Plan**: Create a mental model or brief plan before coding\n3. **Follow Conventions**: Adhere to project structure and coding standards\n4. **Test As You Go**: Validate changes incrementally\n5. **Stay Focused**: Complete the current subtask before moving to the next\n\n### 6. Task Completion\n\nWhen the subtask is complete:\n```bash\ntm set-status --id=<subtask-id> --status=done\n```\n\nThen automatically check for the next available task by repeating from step 2.\n\n## Example Flows\n\n### With Specific Task ID\n```\nUser: \"/go:ham 1.2\"\n\n1. Claude runs: tm show 1.2\n   → Displays full task details\n2. Claude analyzes the task and creates an implementation plan\n3. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n4. Claude begins implementation following the task requirements\n5. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n6. Claude automatically identifies next task with tm list\n```\n\n### Without Specific Task ID (Auto-discovery)\n```\nUser: \"/go:ham\"\n\n1. Claude runs: tm list\n2. Claude identifies next available task (e.g., 1.2)\n3. Claude runs: tm show 1.2\n   → Displays full task details\n4. Claude analyzes the task and creates an implementation plan\n5. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n6. Claude begins implementation following the task requirements\n7. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n8. Claude automatically identifies next task with tm list\n```\n\n## Notes\n\n- Always verify task dependencies are complete before starting\n- If a task is blocked, mark it as such and move to the next available task\n- Keep the user informed of progress at each major step\n- Ask for clarification if task requirements are unclear\n- Follow the project's CLAUDE.md and .cursor/rules/* guidelines at all times\n- Unlike the usual Taskmaster process, do not bother using update-task nor update-subtask as they do not work with Hamster tasks yet.\n\n- Use only `tm list`, `tm show <sub/task id>` and `tm set status` - other commands don't yet work with it.\n- Do not use the MCP tools when connected with Hamster briefs - that is not yet up to date.\n- Use `.cursor/rules/git_workflow.mdc` as a guide for the workflow\n- When starting a task, mark it as in-progress. You can mark multiple task statuses at once with comma separation (i.e. `tm set-status -i 1,1.1 -s in-progress`)\n- Read the task, then if it has subtasks, begin implementing the subtasks one at a time.\n- When the subtask is done, run lint and typecheck, mark the task as done if it passes, and commit.\n- Continue until all subtasks are done, then run a final lint and typecheck (`npm lint` and `npm typecheck`) and create a PR using `gh` cli for that Task.\n- Keep committing to the same PR as long as the scope is maintained. An entire task list (brief) might fit into a single PR but not if it ends up being huge. It is preferred for everything to land in one PR if it is possible, otherwise commit to different PRs that build on top of the previous ones. Confirm with the human when doing this.\n- When the parent task is completed, ensure you mark is as done.\n- When the first task is done, repeat this process for all tasks until all tasks are done.\n- If you run into an issue where the JWT seems expired or commands don't work, ensure you use `tm auth refresh` to refresh the token and if that does not work, use `tm context <brief url>` to reconnect the context. If you do not have the brief url, ask the user for it (perhaps use it at the beginning)\n\nYou're a fast hamster. Go go go.",".claude/commands/go/pr-comments.md":"Fix PR review comments: PR # $ARGUMENTS\n\nThis command collects all review comments from a GitHub PR (including CodeRabbit, human reviewers, and other bots), consolidates them by author and severity, shows them to you for approval, then implements the approved fixes.\n\nSteps:\n\n1. **Collect PR comments**\n   - Run: `gh pr view $ARGUMENTS --comments` to get ALL comments (no truncation)\n   - Parse and extract all review comments from:\n     - PR review comments (file-level)\n     - General comments\n     - Review threads\n   - Include author information for each comment\n   - IMPORTANT: Do NOT use `head`, `tail`, or any truncation - we need complete comment history\n\n2. **Consolidate comments**\n   - Group comments by:\n     - Author (CodeRabbit, human reviewers, other bots)\n     - Severity (🚨 Critical, ⚠️ Important, 💡 Suggestion, ℹ️ Info)\n     - Category (Security, Performance, Best Practices, Style, etc.)\n   - Remove duplicates and group similar issues\n   - Present in a clear, numbered list format showing author for each\n\n3. **Show consolidated issues for approval**\n   - Display the organized list with:\n     - Issue number for reference\n     - Severity indicator\n     - File location\n     - Description\n     - Suggested fix\n   - Ask: \"Which issues would you like me to fix? (Enter numbers separated by commas, or 'all' for everything)\"\n   - Wait for user confirmation\n\n4. **Implement approved fixes**\n   - For each approved issue:\n     - Read the relevant file(s)\n     - Implement the suggested fix\n     - Log what was changed\n\n5. **Validate changes**\n   - Run: `pnpm typecheck`\n   - If fails: review errors, fix them, retry\n   - Run: `pnpm lint`\n   - If fails: review errors, fix them, retry\n   - Continue until both pass\n\n6. **Commit and push**\n   - Stage changes: `git add .`\n   - Create commit: `git commit -m \"fix: address review comments from PR #$ARGUMENTS\"`\n   - Push: `git push`\n   - Confirm completion with summary of fixes applied\n\nNotes:\n- If no review comments found, inform user and exit\n- If typecheck/lint fails after fixes, show errors and ask for guidance\n- Keep fixes focused on reviewers' specific suggestions\n- Preserve existing code style and patterns\n- Group related fixes in the commit message if many changes\n- Treat all reviewers equally - human and bot feedback both matter\n\nYou previously got all the PR comments in a temporary JSON file and then ran something like this;\n\ncat > /tmp/parse_comments.js << 'EOF'\nconst fs = require('fs');\nconst comments = JSON.parse(fs.readFileSync('/tmp/all-pr-comments.json', 'utf8'));\n\nconst byFile = {};\nconst bySeverity = {\n  critical: [],\n  important: [],\n  suggestion: [],\n  info: []\n};\n\ncomments.forEach((c, idx) => {\n  const file = c.path;\n  const author = c.user.login;\n  const line = c.line || c.original_line || 'N/A';\n  const body = c.body;\n  \n  if (!byFile[file]) byFile[file] = [];\n  \n  const comment = {\n    num: idx + 1,\n    author,\n    line,\n    body: body.substring(0, 200) + (body.length > 200 ? '...' : ''),\n    fullBody: body\n  };\n  \n  byFile[file].push(comment);\n  \n  // Categorize by severity\n  const lower = body.toLowerCase();\n  if (lower.includes('critical') || lower.includes('security') || lower.includes('bug:')) {\n    bySeverity.critical.push({...comment, file});\n  } else if (lower.includes('important') || lower.includes('error') || lower.includes('fail')) {\n    bySeverity.important.push({...comment, file});\n  } else if (lower.includes('suggestion') || lower.includes('consider') || lower.includes('recommend')) {\n    bySeverity.suggestion.push({...comment, file});\n  } else {\n    bySeverity.info.push({...comment, file});\n  }\n});\n\nconsole.log('\\n=== SUMMARY BY SEVERITY ===\\n');\nconsole.log(`🚨 Critical: ${bySeverity.critical.length}`);\nconsole.log(`⚠️  Important: ${bySeverity.important.length}`);\nconsole.log(`💡 Suggestion: ${bySeverity.suggestion.length}`);\nconsole.log(`ℹ️  Info: ${bySeverity.info.length}`);\n\nconsole.log('\\n=== SUMMARY BY FILE ===\\n');\nObject.entries(byFile)\n  .sort((a, b) => b[1].length - a[1].length)\n  .forEach(([file, comments]) => {\n    console.log(`${file}: ${comments.length} comments`);\n  });\n\nconsole.log('\\n=== CRITICAL ISSUES ===\\n');\nbySeverity.critical.forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\n\nconsole.log('\\n=== IMPORTANT ISSUES ===\\n');\nbySeverity.important.slice(0, 10).forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\nEOF\nnode /tmp/parse_comments.js\n\nAnd got a nice report you could act on.",".cursor/commands/goham.md":"# Start Working with Hamster Brief\n\nEnd-to-end workflow for working on tasks from a connected Hamster brief. All tasks from the brief are worked on in a single branch, with one PR created at the end.\n\n## Step 1: Verify Connection & Authentication\n\n```bash\n# Check current context and authentication status\ntm context\n```\n\nIf not connected or authentication fails:\n- Get brief URL from user if not available\n- Connect: `tm context <brief url>`\n- Refresh token if needed: `tm auth refresh`\n\n## Step 2: List Available Tasks\n\n```bash\n# View all tasks from the brief\ntm list\n```\n\nReview the task list to understand what needs to be done. Note the total number of tasks.\n\n## Step 3: Initialize Git Branch for Brief\n\n```bash\n# Ensure you're on dev branch and pull latest\ngit checkout dev\ngit pull origin dev\n\n# Create a single branch for the entire brief (e.g., hamster-brief-YYYY-MM-DD or brief-specific name)\ngit checkout -b hamster-brief\n\n# Verify branch creation\ngit branch\n```\n\n**Note**: This branch will be used for ALL tasks in the brief. Do not create separate branches per task.\n\n## Step 4: Task Loop (Repeat for Each Task)\n\nWork through all tasks sequentially in the same branch:\n\n### 4.1: Read Task Details\n\n```bash\n# Get detailed information about the task\ntm show 1\n\n# If task has subtasks, examine them all\ntm show 1,1.1,1.2,1.3  # Adjust IDs as needed\n```\n\n### 4.2: Log Initial Context\n\n```bash\n# Document task understanding and initial findings\ntm update-task -i 1 --append --prompt=\"Starting task implementation.\n\nInitial context:\n- Task requirements: [summarize key requirements]\n- Dependencies identified: [list any dependencies]\n- Files that may need modification: [list relevant files]\n- Approach planned: [brief implementation approach]\"\n```\n\n### 4.3: Mark Task as In-Progress\n\n```bash\n# Mark task and first subtask (if exists) as in-progress\ntm set-status -i 1,1.1 -s in-progress\n```\n\n### 4.4: Subtask Implementation Loop\n\nFor each subtask (1.1, 1.2, 1.3, etc.):\n\n#### 4.4.1: Read Subtask Details\n```bash\ntm show 1.1  # Replace with current subtask ID\n```\n\n#### 4.4.2: Log Research & Context Gathering\n```bash\n# Document findings during implementation\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Context gathered:\n\n- Code exploration findings: [what you discovered]\n- Implementation approach: [how you plan to implement]\n- Key decisions made: [important choices]\n- Challenges encountered: [any blockers or issues]\"\n```\n\n#### 4.4.3: Implement Subtask\n- Write code following the subtask requirements\n- Make necessary changes to files\n\n#### 4.4.4: Quality Verification\n```bash\n# Run linting\npnpm lint\n\n# Run type checking\npnpm typecheck\n\n# If either fails, fix issues and re-run until both pass\n```\n\n#### 4.4.5: CodeRabbit Review\n```bash\n# Generate code review (wait for plain text results)\ncoderabbit --prompt-only\n\n# Review the output and address any critical issues if needed\n```\n\n#### 4.4.6: Log Implementation Completion\n```bash\n# Document what was completed\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Implementation complete:\n\n- Files modified: [list files changed]\n- Key changes: [summary of implementation]\n- CodeRabbit feedback addressed: [if any issues were fixed]\n- Ready for commit\"\n```\n\n#### 4.4.7: Commit Subtask Work\n```bash\n# Stage changes\ngit add .\n\n# Commit with detailed message following git_workflow.mdc format\ngit commit -m \"feat(task-1): Complete subtask 1.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Files modified: [list files]\n- CodeRabbit review completed\n\nSubtask 1.1: [Brief description of what was accomplished]\nRelates to Task 1: [Main task title]\"\n```\n\n#### 4.4.8: Mark Subtask as Done\n```bash\ntm set-status -i 1.1 -s done\n```\n\n#### 4.4.9: Move to Next Subtask\nRepeat steps 4.4.1 through 4.4.8 for the next subtask (1.2, 1.3, etc.)\n\n### 4.5: Complete Parent Task\n\nAfter all subtasks are complete:\n\n#### 4.5.1: Final Quality Checks\n```bash\n# Final linting\npnpm lint\n\n# Final type checking\npnpm typecheck\n\n# Final CodeRabbit review\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n#### 4.5.2: Log Task Completion\n```bash\n# Document final task completion\ntm update-task -i 1 --append --prompt=\"Task 1 - Complete:\n\n- All subtasks completed: [list all subtasks]\n- Final verification passed: lint, typecheck, CodeRabbit review\n- Files changed: [comprehensive list]\n- Committed to brief branch\"\n```\n\n#### 4.5.3: Mark Parent Task as Done\n```bash\ntm set-status -i 1 -s done\n```\n\n**Note**: Do NOT push or create PR yet. Continue to next task in the same branch.\n\n### 4.6: Move to Next Task\n\n```bash\n# Verify remaining tasks\ntm list\n\n# Continue with next task (e.g., Task 2)\n# Repeat steps 4.1 through 4.5 for Task 2, then Task 3, etc.\n```\n\n## Step 5: Complete All Tasks\n\nContinue working through all tasks (Steps 4.1-4.6) until all tasks in the brief are complete. All work is committed to the same `hamster-brief` branch.\n\n## Step 6: Final Verification & PR Creation\n\nAfter ALL tasks are complete:\n\n### 6.1: Verify All Tasks Complete\n```bash\n# Verify all tasks are done\ntm list\n\n# Should show all tasks with status 'done'\n```\n\n### 6.2: Final Quality Checks\n```bash\n# Final comprehensive checks\npnpm lint\npnpm typecheck\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n### 6.3: Push Branch\n```bash\n# Push the brief branch to remote\ngit push origin hamster-brief\n```\n\n### 6.4: Create Pull Request to Dev\n```bash\n# Get all task titles (adjust task IDs as needed)\n# Create comprehensive PR description\n\ngh pr create \\\n  --base dev \\\n  --title \"Hamster Brief: Complete Implementation\" \\\n  --body \"## Brief Overview\nCompleted all tasks from Hamster brief.\n\n## Tasks Completed\n- [x] Task 1: [Task 1 title]\n  - Subtasks: 1.1, 1.2, 1.3\n- [x] Task 2: [Task 2 title]\n  - Subtasks: 2.1, 2.2\n- [x] Task 3: [Task 3 title]\n  - [Continue listing all tasks]\n\n## Implementation Summary\n- Total tasks: [number]\n- Total subtasks: [number]\n- Files modified: [comprehensive list]\n- All quality checks passed\n\n## Quality Checks\n- ✅ Linting passed (pnpm lint)\n- ✅ Type checking passed (pnpm typecheck)\n- ✅ CodeRabbit review completed for all changes\n\n## Testing\n- [ ] Manual testing completed\n- [ ] All checks passing\n\nComplete implementation of Hamster brief tasks\"\n```\n\n## Step 7: Cleanup\n\n```bash\n# After PR is merged, switch back to dev\ngit checkout dev\ngit pull origin dev\n\n# Delete local branch (optional)\ngit branch -d hamster-brief\n```\n\n## Important Notes\n\n- **Use ONLY**: `tm list`, `tm show <id>`, `tm set-status`, `tm update-task`, `tm auth refresh`, `tm context <brief url>`\n- **DON'T use MCP tools** - not compatible with Hamster integration\n- **Single branch per brief**: All tasks work in the same branch (`hamster-brief`)\n- **Single PR per brief**: One PR created after all tasks are complete\n- **Always target dev branch** - never main branch\n- **Regular logging**: Use `tm update-task -i <id> --append` frequently to document:\n  - Context gathered during exploration\n  - Implementation decisions made\n  - Challenges encountered\n  - Completion status\n- **Quality gates**: Never skip lint, typecheck, or CodeRabbit review\n- **Commit format**: Follow git_workflow.mdc commit message standards\n- **PR format**: Always use `--base dev` when creating PRs\n\n## Workflow Summary\n\n```\n1. Verify connection → tm context\n2. List tasks → tm list\n3. Create single branch → git checkout -b hamster-brief\n4. For each task (in same branch):\n   a. Read task → tm show X\n   b. Log context → tm update-task -i X --append\n   c. Mark in-progress → tm set-status -i X,X.Y -s in-progress\n   d. For each subtask:\n      - Read → tm show X.Y\n      - Log context → tm update-task -i X --append\n      - Implement code\n      - Verify → pnpm lint && pnpm typecheck\n      - Review → coderabbit --prompt-only\n      - Log completion → tm update-task -i X --append\n      - Commit → git commit (following git_workflow.mdc format)\n      - Mark done → tm set-status -i X.Y -s done\n   e. Final checks → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   f. Log completion → tm update-task -i X --append\n   g. Mark task done → tm set-status -i X -s done\n   h. Continue to next task (same branch)\n5. After ALL tasks complete:\n   a. Final verification → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   b. Push branch → git push origin hamster-brief\n   c. Create PR → gh pr create --base dev\n```\n\n## References\n\n- Full guidelines: [hamster.mdc](mdc:.cursor/rules/hamster.mdc)\n- Git workflow: [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc)\n",".cursor/mcp.json":"{\n\t\"mcpServers\": {\n\t\t\"task-master-ai\": {\n\t\t\t\"command\": \"node\",\n\t\t\t\"args\": [\"./dist/mcp-server.js\"],\n\t\t\t\"env\": {\n\t\t\t\t\"ANTHROPIC_API_KEY\": \"ANTHROPIC_API_KEY_HERE\",\n\t\t\t\t\"PERPLEXITY_API_KEY\": \"PERPLEXITY_API_KEY_HERE\",\n\t\t\t\t\"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n\t\t\t\t\"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n\t\t\t\t\"GROQ_API_KEY\": \"GROQ_API_KEY_HERE\",\n\t\t\t\t\"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n\t\t\t\t\"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n\t\t\t\t\"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n\t\t\t\t\"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n\t\t\t\t\"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\",\n\t\t\t\t\"GITHUB_API_KEY\": \"GITHUB_API_KEY_HERE\"\n\t\t\t}\n\t\t}\n\t}\n}\n",".cursor/rules/ai_providers.mdc":"---\ndescription: Guidelines for managing Task Master AI providers and models.\nglobs: \nalwaysApply: false\n---\n# Task Master AI Provider Management\n\nThis rule guides AI assistants on how to view, configure, and interact with the different AI providers and models supported by Task Master. For internal implementation details of the service layer, see [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc).\n\n-   **Primary Interaction:**\n    -   Use the `models` MCP tool or the `task-master models` CLI command to manage AI configurations. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for detailed command/tool usage.\n\n-   **Configuration Roles:**\n    -   Task Master uses three roles for AI models:\n        -   `main`: Primary model for general tasks (generation, updates).\n        -   `research`: Model used when the `--research` flag or `research: true` parameter is used (typically models with web access or specialized knowledge).\n        -   `fallback`: Model used if the primary (`main`) model fails.\n    -   Each role is configured with a specific `provider:modelId` pair (e.g., `openai:gpt-4o`).\n\n-   **Viewing Configuration & Available Models:**\n    -   To see the current model assignments for each role and list all models available for assignment:\n        -   **MCP Tool:** `models` (call with no arguments or `listAvailableModels: true`)\n        -   **CLI Command:** `task-master models`\n    -   The output will show currently assigned models and a list of others, prefixed with their provider (e.g., `google:gemini-2.5-pro-exp-03-25`).\n\n-   **Setting Models for Roles:**\n    -   To assign a model to a role:\n        -   **MCP Tool:** `models` with `setMain`, `setResearch`, or `setFallback` parameters.\n        -   **CLI Command:** `task-master models` with `--set-main`, `--set-research`, or `--set-fallback` flags.\n    -   **Crucially:** When providing the model ID to *set*, **DO NOT include the `provider:` prefix**. Use only the model ID itself.\n        -   ✅ **DO:** `models(setMain='gpt-4o')` or `task-master models --set-main=gpt-4o`\n        -   ❌ **DON'T:** `models(setMain='openai:gpt-4o')` or `task-master models --set-main=openai:gpt-4o`\n    -   The tool/command will automatically determine the provider based on the model ID.\n\n-   **Setting Custom Models (Ollama/OpenRouter):**\n    -   To set a model ID not in the internal list for Ollama or OpenRouter:\n        -   **MCP Tool:** Use `models` with `set<Role>` and **also** `ollama: true` or `openrouter: true`.\n            -   Example: `models(setMain='my-custom-ollama-model', ollama=true)`\n            -   Example: `models(setMain='some-openrouter-model', openrouter=true)`\n        -   **CLI Command:** Use `task-master models` with `--set-<role>` and **also** `--ollama` or `--openrouter`.\n            -   Example: `task-master models --set-main=my-custom-ollama-model --ollama`\n            -   Example: `task-master models --set-main=some-openrouter-model --openrouter`\n        -   **Interactive Setup:** Use `task-master models --setup` and select the `Ollama (Enter Custom ID)` or `OpenRouter (Enter Custom ID)` options.\n    -   **OpenRouter Validation:** When setting a custom OpenRouter model, Taskmaster attempts to validate the ID against the live OpenRouter API.\n    -   **Ollama:** No live validation occurs for custom Ollama models; ensure the model is available on your Ollama server.\n\n-   **Supported Providers & Required API Keys:**\n    -   Task Master integrates with various providers via the Vercel AI SDK.\n    -   **API keys are essential** for most providers and must be configured correctly.\n    -   **Key Locations** (See [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) - Configuration Management):\n        -   **MCP/Cursor:** Set keys in the `env` section of `.cursor/mcp.json`.\n        -   **CLI:** Set keys in a `.env` file in the project root.\n    -   **Provider List & Keys:**\n        -   **`anthropic`**: Requires `ANTHROPIC_API_KEY`.\n        -   **`google`**: Requires `GOOGLE_API_KEY`.\n        -   **`openai`**: Requires `OPENAI_API_KEY`.\n        -   **`perplexity`**: Requires `PERPLEXITY_API_KEY`.\n        -   **`xai`**: Requires `XAI_API_KEY`.\n        -   **`mistral`**: Requires `MISTRAL_API_KEY`.\n        -   **`azure`**: Requires `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT`.\n        -   **`openrouter`**: Requires `OPENROUTER_API_KEY`.\n        -   **`ollama`**: Might require `OLLAMA_API_KEY` (not currently supported) *and* `OLLAMA_BASE_URL` (default: `http://localhost:11434/api`). *Check specific setup.*\n\n-   **Troubleshooting:**\n    -   If AI commands fail (especially in MCP context):\n        1.  **Verify API Key:** Ensure the correct API key for the *selected provider* (check `models` output) exists in the appropriate location (`.cursor/mcp.json` env or `.env`).\n        2.  **Check Model ID:** Ensure the model ID set for the role is valid (use `models` listAvailableModels/`task-master models`).\n        3.  **Provider Status:** Check the status of the external AI provider's service.\n        4.  **Restart MCP:** If changes were made to configuration or provider code, restart the MCP server.\n\n## Adding a New AI Provider (Vercel AI SDK Method)\n\nFollow these steps to integrate a new AI provider that has an official Vercel AI SDK adapter (`@ai-sdk/<provider>`):\n\n1.  **Install Dependency:**\n    -   Install the provider-specific package:\n        ```bash\n        npm install @ai-sdk/<provider-name>\n        ```\n\n2.  **Create Provider Module:**\n    -   Create a new file in `src/ai-providers/` named `<provider-name>.js`.\n    -   Use existing modules (`openai.js`, `anthropic.js`, etc.) as a template.\n    -   **Import:**\n        -   Import the provider's `create<ProviderName>` function from `@ai-sdk/<provider-name>`.\n        -   Import `generateText`, `streamText`, `generateObject` from the core `ai` package.\n        -   Import the `log` utility from `../../scripts/modules/utils.js`.\n    -   **Implement Core Functions:**\n        -   `generate<ProviderName>Text(params)`:\n            -   Accepts `params` (apiKey, modelId, messages, etc.).\n            -   Instantiate the client: `const client = create<ProviderName>({ apiKey });`\n            -   Call `generateText({ model: client(modelId), ... })`.\n            -   Return `result.text`.\n            -   Include basic validation and try/catch error handling.\n        -   `stream<ProviderName>Text(params)`:\n            -   Similar structure to `generateText`.\n            -   Call `streamText({ model: client(modelId), ... })`.\n            -   Return the full stream result object.\n            -   Include basic validation and try/catch.\n        -   `generate<ProviderName>Object(params)`:\n            -   Similar structure.\n            -   Call `generateObject({ model: client(modelId), schema, messages, ... })`.\n            -   Return `result.object`.\n            -   Include basic validation and try/catch.\n    -   **Export Functions:** Export the three implemented functions (`generate<ProviderName>Text`, `stream<ProviderName>Text`, `generate<ProviderName>Object`).\n\n3.  **Integrate with Unified Service:**\n    -   Open `scripts/modules/ai-services-unified.js`.\n    -   **Import:** Add `import * as <providerName> from '../../src/ai-providers/<provider-name>.js';`\n    -   **Map:** Add an entry to the `PROVIDER_FUNCTIONS` map:\n        ```javascript\n        '<provider-name>': {\n            generateText: <providerName>.generate<ProviderName>Text,\n            streamText: <providerName>.stream<ProviderName>Text,\n            generateObject: <providerName>.generate<ProviderName>Object\n        },\n        ```\n\n4.  **Update Configuration Management:**\n    -   Open `scripts/modules/config-manager.js`.\n    -   **`MODEL_MAP`:** Add the new `<provider-name>` key to the `MODEL_MAP` loaded from `supported-models.json` (or ensure the loading handles new providers dynamically if `supported-models.json` is updated first).\n    -   **`VALID_PROVIDERS`:** Ensure the new `<provider-name>` is included in the `VALID_PROVIDERS` array (this should happen automatically if derived from `MODEL_MAP` keys).\n    -   **API Key Handling:**\n        -   Update the `keyMap` in `_resolveApiKey` and `isApiKeySet` with the correct environment variable name (e.g., `PROVIDER_API_KEY`).\n        -   Update the `switch` statement in `getMcpApiKeyStatus` to check the corresponding key in `mcp.json` and its placeholder value.\n        -   Add a case to the `switch` statement in `getMcpApiKeyStatus` for the new provider, including its placeholder string if applicable.\n    -   **Ollama Exception:** If adding Ollama or another provider *not* requiring an API key, add a specific check at the beginning of `isApiKeySet` and `getMcpApiKeyStatus` to return `true` immediately for that provider.\n\n5.  **Update Supported Models List:**\n    -   Edit `scripts/modules/supported-models.json`.\n    -   Add a new key for the `<provider-name>`.\n    -   Add an array of model objects under the provider key, each including:\n        -   `id`: The specific model identifier (e.g., `claude-3-opus-20240229`).\n        -   `name`: A user-friendly name (optional).\n        -   `swe_score`, `cost_per_1m_tokens`: (Optional) Add performance/cost data if available.\n        -   `allowed_roles`: An array of roles (`\"main\"`, `\"research\"`, `\"fallback\"`) the model is suitable for.\n        -   `max_tokens`: (Optional but recommended) The maximum token limit for the model.\n\n6.  **Update Environment Examples:**\n    -   Add the new `PROVIDER_API_KEY` to `.env.example`.\n    -   Add the new `PROVIDER_API_KEY` with its placeholder (`YOUR_PROVIDER_API_KEY_HERE`) to the `env` section for `taskmaster-ai` in `.cursor/mcp.json.example` (if it exists) or update instructions.\n\n7.  **Add Unit Tests:**\n    -   Create `tests/unit/ai-providers/<provider-name>.test.js`.\n    -   Mock the `@ai-sdk/<provider-name>` module and the core `ai` module functions (`generateText`, `streamText`, `generateObject`).\n    -   Write tests for each exported function (`generate<ProviderName>Text`, etc.) to verify:\n        -   Correct client instantiation.\n        -   Correct parameters passed to the mocked Vercel AI SDK functions.\n        -   Correct handling of results.\n        -   Error handling (missing API key, SDK errors).\n\n8.  **Documentation:**\n    -   Update any relevant documentation (like `README.md` or other rules) mentioning supported providers or configuration.\n\n*(Note: For providers **without** an official Vercel AI SDK adapter, the process would involve directly using the provider's own SDK or API within the `src/ai-providers/<provider-name>.js` module and manually constructing responses compatible with the unified service layer, which is significantly more complex.)*",".cursor/rules/ai_services.mdc":"---\ndescription: Guidelines for interacting with the unified AI service layer.\nglobs: scripts/modules/ai-services-unified.js, scripts/modules/task-manager/*.js, scripts/modules/commands.js\n---\n\n# AI Services Layer Guidelines\n\nThis document outlines the architecture and usage patterns for interacting with Large Language Models (LLMs) via Task Master's unified AI service layer (`ai-services-unified.js`). The goal is to centralize configuration, provider selection, API key management, fallback logic, and error handling.\n\n**Core Components:**\n\n*   **Configuration (`.taskmasterconfig` & [`config-manager.js`](mdc:scripts/modules/config-manager.js)):**\n    *   Defines the AI provider and model ID for different **roles** (`main`, `research`, `fallback`).\n    *   Stores parameters like `maxTokens` and `temperature` per role.\n    *   Managed via the `task-master models --setup` CLI command.\n    *   [`config-manager.js`](mdc:scripts/modules/config-manager.js) provides **getters** (e.g., `getMainProvider()`, `getParametersForRole()`) to access these settings. Core logic should **only** use these getters for *non-AI related application logic* (e.g., `getDefaultSubtasks`). The unified service fetches necessary AI parameters internally based on the `role`.\n    *   **API keys** are **NOT** stored here; they are resolved via `resolveEnvVariable` (in [`utils.js`](mdc:scripts/modules/utils.js)) from `.env` (for CLI) or the MCP `session.env` object (for MCP calls). See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc).\n\n*   **Unified Service (`ai-services-unified.js`):**\n    *   Exports primary interaction functions: `generateTextService`, `generateObjectService`. (Note: `streamTextService` exists but has known reliability issues with some providers/payloads).\n    *   Contains the core `_unifiedServiceRunner` logic.\n    *   Internally uses `config-manager.js` getters to determine the provider/model/parameters based on the requested `role`.\n    *   Implements the **fallback sequence** (e.g., main -> fallback -> research) if the primary provider/model fails.\n    *   Constructs the `messages` array required by the Vercel AI SDK.\n    *   Implements **retry logic** for specific API errors (`_attemptProviderCallWithRetries`).\n    *   Resolves API keys automatically via `_resolveApiKey` (using `resolveEnvVariable`).\n    *   Maps requests to the correct provider implementation (in `src/ai-providers/`) via `PROVIDER_FUNCTIONS`.\n    *   Returns a structured object containing the primary AI result (`mainResult`) and telemetry data (`telemetryData`). See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for details on how this telemetry data is propagated and handled.\n\n*   **Provider Implementations (`src/ai-providers/*.js`):**\n    *   Contain provider-specific wrappers around Vercel AI SDK functions (`generateText`, `generateObject`).\n\n**Usage Pattern (from Core Logic like `task-manager/*.js`):**\n\n1.  **Import Service:** Import `generateTextService` or `generateObjectService` from `../ai-services-unified.js`.\n    ```javascript\n    // Preferred for most tasks (especially with complex JSON)\n    import { generateTextService } from '../ai-services-unified.js';\n\n    // Use if structured output is reliable for the specific use case\n    // import { generateObjectService } from '../ai-services-unified.js';\n    ```\n\n2.  **Prepare Parameters:** Construct the parameters object for the service call.\n    *   `role`: **Required.** `'main'`, `'research'`, or `'fallback'`. Determines the initial provider/model/parameters used by the unified service.\n    *   `session`: **Required if called from MCP context.** Pass the `session` object received by the direct function wrapper. The unified service uses `session.env` to find API keys.\n    *   `systemPrompt`: Your system instruction string.\n    *   `prompt`: The user message string (can be long, include stringified data, etc.).\n    *   (For `generateObjectService` only): `schema` (Zod schema), `objectName`.\n\n3.  **Call Service:** Use `await` to call the service function.\n    ```javascript\n    // Example using generateTextService (most common)\n    try {\n        const resultText = await generateTextService({\n            role: useResearch ? 'research' : 'main', // Determine role based on logic\n            session: context.session, // Pass session from context object\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // Process the raw text response (e.g., parse JSON, use directly)\n        // ...\n    } catch (error) {\n        // Handle errors thrown by the unified service (if all fallbacks/retries fail)\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n\n    // Example using generateObjectService (use cautiously)\n    try {\n        const resultObject = await generateObjectService({\n            role: 'main',\n            session: context.session,\n            schema: myZodSchema,\n            objectName: 'myDataObject',\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // resultObject is already a validated JS object\n        // ...\n    } catch (error) {\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n    ```\n\n4.  **Handle Results/Errors:** Process the returned text/object or handle errors thrown by the unified service layer.\n\n**Key Implementation Rules & Gotchas:**\n\n*   ✅ **DO**: Centralize **all** LLM calls through `generateTextService` or `generateObjectService`.\n*   ✅ **DO**: Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.\n*   ✅ **DO**: Pass the `session` object (received in the `context` parameter, especially from direct function wrappers) to the service call when in MCP context.\n*   ✅ **DO**: Ensure API keys are correctly configured in `.env` (for CLI) or `.cursor/mcp.json` (for MCP).\n*   ✅ **DO**: Ensure `.taskmasterconfig` exists and has valid provider/model IDs for the roles you intend to use (manage via `task-master models --setup`).\n*   ✅ **DO**: Use `generateTextService` and implement robust manual JSON parsing (with Zod validation *after* parsing) when structured output is needed, as `generateObjectService` has shown unreliability with some providers/schemas.\n*   ❌ **DON'T**: Import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.\n*   ❌ **DON'T**: Initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (`task-manager/`) or MCP direct functions.\n*   ❌ **DON'T**: Fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters *for the AI call*. Pass the `role` instead.\n*   ❌ **DON'T**: Implement fallback or retry logic outside `ai-services-unified.js`.\n*   ❌ **DON'T**: Handle API key resolution outside the service layer (it uses `utils.js` internally).\n*   ⚠️ **generateObjectService Caution**: Be aware of potential reliability issues with `generateObjectService` across different providers and complex schemas. Prefer `generateTextService` + manual parsing as a more robust alternative for structured data needs.\n",".cursor/rules/architecture.mdc":"---\ndescription: Describes the high-level architecture of the Task Master CLI application.\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Application Architecture Overview\n\n- **Modular Structure**: The Task Master CLI is built using a modular architecture, with distinct modules responsible for different aspects of the application. This promotes separation of concerns, maintainability, and testability.\n\n- **Main Modules and Responsibilities**:\n\n  - **[`commands.js`](mdc:scripts/modules/commands.js): Command Handling**\n    - **Purpose**: Defines and registers all CLI commands using Commander.js.\n    - **Responsibilities** (See also: [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n      - Parses command-line arguments and options.\n      - Invokes appropriate core logic functions from `scripts/modules/`.\n      - Handles user input/output for CLI.\n      - Implements CLI-specific validation.\n\n  - **[`task-manager.js`](mdc:scripts/modules/task-manager.js) & `task-manager/` directory: Task Data & Core Logic**\n    - **Purpose**: Contains core functions for task data manipulation (CRUD), AI interactions, and related logic.\n    - **Responsibilities**:\n      - Reading/writing `tasks.json` with tagged task lists support.\n      - Implementing functions for task CRUD, parsing PRDs, expanding tasks, updating status, etc.\n      - **Tagged Task Lists**: Handles task organization across multiple contexts (tags) like \"master\", branch names, or project phases.\n      - **Tag Resolution**: Provides backward compatibility by resolving tagged format to legacy format transparently.\n      - **Delegating AI interactions** to the `ai-services-unified.js` layer.\n      - Accessing non-AI configuration via `config-manager.js` getters.\n    - **Key Files**: Individual files within `scripts/modules/task-manager/` handle specific actions (e.g., `add-task.js`, `expand-task.js`).\n\n  - **[`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js): Dependency Management**\n    - **Purpose**: Manages task dependencies.\n    - **Responsibilities**: Add/remove/validate/fix dependencies across tagged task contexts.\n\n  - **[`ui.js`](mdc:scripts/modules/ui.js): User Interface Components**\n    - **Purpose**: Handles CLI output formatting (tables, colors, boxes, spinners).\n    - **Responsibilities**: Displaying tasks, reports, progress, suggestions, and migration notices for tagged systems.\n\n  - **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js): Unified AI Service Layer**\n    - **Purpose**: Centralized interface for all LLM interactions using Vercel AI SDK.\n    - **Responsibilities** (See also: [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc)):\n      - Exports `generateTextService`, `generateObjectService`.\n      - Handles provider/model selection based on `role` and `.taskmasterconfig`.\n      - Resolves API keys (from `.env` or `session.env`).\n      - Implements fallback and retry logic.\n      - Orchestrates calls to provider-specific implementations (`src/ai-providers/`).\n    - Telemetry data generated by the AI service layer is propagated upwards through core logic, direct functions, and MCP tools. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the detailed integration pattern.\n\n  - **[`src/ai-providers/*.js`](mdc:src/ai-providers/): Provider-Specific Implementations**\n    - **Purpose**: Provider-specific wrappers for Vercel AI SDK functions.\n    - **Responsibilities**: Interact directly with Vercel AI SDK adapters.\n\n  - **[`config-manager.js`](mdc:scripts/modules/config-manager.js): Configuration Management**\n    - **Purpose**: Loads, validates, and provides access to configuration.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Reads and merges `.taskmasterconfig` with defaults.\n      - Provides getters (e.g., `getMainProvider`, `getLogLevel`, `getDefaultSubtasks`) for accessing settings.\n      - **Tag Configuration**: Manages `global.defaultTag` and `tags` section for tag system settings.\n      - **Note**: Does **not** store or directly handle API keys (keys are in `.env` or MCP `session.env`).\n\n  - **[`utils.js`](mdc:scripts/modules/utils.js): Core Utility Functions**\n    - **Purpose**: Low-level, reusable CLI utilities.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Logging (`log` function), File I/O (`readJSON`, `writeJSON`), String utils (`truncate`).\n      - Task utils (`findTaskById`), Dependency utils (`findCycles`).\n      - API Key Resolution (`resolveEnvVariable`).\n      - Silent Mode Control (`enableSilentMode`, `disableSilentMode`).\n      - **Tagged Task Lists**: Silent migration system, tag resolution, current tag management.\n      - **Migration System**: `performCompleteTagMigration`, `migrateConfigJson`, `createStateJson`.\n\n  - **[`mcp-server/`](mdc:mcp-server/): MCP Server Integration**\n    - **Purpose**: Provides MCP interface using FastMCP.\n    - **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):\n      - Registers tools (`mcp-server/src/tools/*.js`). Tool `execute` methods **should be wrapped** with the `withNormalizedProjectRoot` HOF (from `tools/utils.js`) to ensure consistent path handling.\n      - The HOF provides a normalized `args.projectRoot` to the `execute` method.\n      - Tool `execute` methods call **direct function wrappers** (`mcp-server/src/core/direct-functions/*.js`), passing the normalized `projectRoot` and other args.\n      - Direct functions use path utilities (`mcp-server/src/core/utils/`) to resolve paths based on `projectRoot` from session.\n      - Direct functions implement silent mode, logger wrappers, and call core logic functions from `scripts/modules/`.\n      - **Tagged Task Lists**: MCP tools fully support the tagged format with complete tag management capabilities.\n      - Manages MCP caching and response formatting.\n\n  - **[`init.js`](mdc:scripts/init.js): Project Initialization Logic**\n    - **Purpose**: Sets up new Task Master project structure.\n    - **Responsibilities**: Creates directories, copies templates, manages `package.json`, sets up `.cursor/mcp.json`, initializes state.json for tagged system.\n\n## Tagged Task Lists System Architecture\n\n**Data Structure**: Task Master now uses a tagged task lists system where the `tasks.json` file contains multiple named task lists as top-level keys:\n\n```json\n{\n  \"master\": {\n    \"tasks\": [/* standard task objects */]\n  },\n  \"feature-branch\": {\n    \"tasks\": [/* separate task context */]\n  }\n}\n```\n\n**Key Components:**\n\n- **Silent Migration**: Automatically transforms legacy `{\"tasks\": [...]}` format to tagged format `{\"master\": {\"tasks\": [...]}}` on first read\n- **Tag Resolution Layer**: Provides 100% backward compatibility by intercepting tagged format and returning legacy format to existing code\n- **Configuration Integration**: `global.defaultTag` and `tags` section in config.json manage tag system settings\n- **State Management**: `.taskmaster/state.json` tracks current tag, migration status, and tag-branch mappings\n- **Migration Notice**: User-friendly notification system for seamless migration experience\n\n**Backward Compatibility**: All existing CLI commands and MCP tools continue to work unchanged. The tag resolution layer ensures that existing code receives the expected legacy format while the underlying storage uses the new tagged structure.\n\n- **Data Flow and Module Dependencies (Updated)**:\n\n  - **CLI**: `bin/task-master.js` -> `scripts/dev.js` (loads `.env`) -> `scripts/modules/commands.js` -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **MCP**: External Tool -> `mcp-server/server.js` -> Tool (`mcp-server/src/tools/*`) -> Direct Function (`mcp-server/src/core/direct-functions/*`) -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **Configuration**: Core logic needing non-AI settings calls `config-manager.js` getters (passing `session.env` via `explicitRoot` if from MCP). Unified AI Service internally calls `config-manager.js` getters (using `role`) for AI params and `utils.js` (`resolveEnvVariable` with `session.env`) for API keys.\n\n## Silent Mode Implementation Pattern in MCP Direct Functions\n\nDirect functions (the `*Direct` functions in `mcp-server/src/core/direct-functions/`) need to carefully implement silent mode to prevent console logs from interfering with the structured JSON responses required by MCP. This involves both using `enableSilentMode`/`disableSilentMode` around core function calls AND passing the MCP logger via the standard wrapper pattern (see mcp.mdc). Here's the standard pattern for correct implementation:\n\n1. **Import Silent Mode Utilities**:\n   ```javascript\n   import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n   ```\n\n2. **Parameter Matching with Core Functions**:\n   - ✅ **DO**: Ensure direct function parameters match the core function parameters\n   - ✅ **DO**: Check the original core function signature before implementing\n   - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n   ```javascript\n   // Example: Core function signature\n   // async function expandTask(tasksPath, taskId, numSubtasks, useResearch, additionalContext, options)\n   \n   // Direct function implementation - extract only parameters that exist in core\n   export async function expandTaskDirect(args, log, context = {}) {\n     // Extract parameters that match the core function\n     const taskId = parseInt(args.id, 10);\n     const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n     const useResearch = args.research === true;\n     const additionalContext = args.prompt || '';\n     \n     // Later pass these parameters in the correct order to the core function\n     const result = await expandTask(\n       tasksPath, \n       taskId, \n       numSubtasks, \n       useResearch, \n       additionalContext,\n       { mcpLog: log, session: context.session }\n     );\n   }\n   ```\n\n3. **Checking Silent Mode State**:\n   - ✅ **DO**: Always use `isSilentMode()` function to check current status\n   - ❌ **DON'T**: Directly access the global `silentMode` variable or `global.silentMode`\n   ```javascript\n   // CORRECT: Use the function to check current state\n   if (!isSilentMode()) {\n     // Only create a loading indicator if not in silent mode\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   \n   // INCORRECT: Don't access global variables directly\n   if (!silentMode) { // ❌ WRONG\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   ```\n\n4. **Wrapping Core Function Calls**:\n   - ✅ **DO**: Use a try/finally block pattern to ensure silent mode is always restored\n   - ✅ **DO**: Enable silent mode before calling core functions that produce console output\n   - ✅ **DO**: Disable silent mode in a finally block to ensure it runs even if errors occur\n   - ❌ **DON'T**: Enable silent mode without ensuring it gets disabled\n   ```javascript\n   export async function someDirectFunction(args, log) {\n     try {\n       // Argument preparation\n       const tasksPath = findTasksJsonPath(args, log);\n       const someArg = args.someArg;\n       \n       // Enable silent mode to prevent console logs\n       enableSilentMode();\n       \n       try {\n         // Call core function which might produce console output\n         const result = await someCoreFunction(tasksPath, someArg);\n         \n         // Return standardized result object\n         return { \n           success: true, \n           data: result, \n           fromCache: false \n         };\n       } finally {\n         // ALWAYS disable silent mode in finally block\n         disableSilentMode();\n       }\n     } catch (error) {\n       // Standard error handling\n       log.error(`Error in direct function: ${error.message}`);\n       return { \n         success: false, \n         error: { code: 'OPERATION_ERROR', message: error.message }, \n         fromCache: false \n       };\n     }\n   }\n   ```\n\n5. **Mixed Parameter and Global Silent Mode Handling**:\n   - For functions that need to handle both a passed `silentMode` parameter and check global state:\n   ```javascript\n   // Check both the function parameter and global state\n   const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n   \n   if (!isSilent) {\n     console.log('Operation starting...');\n   }\n   ```\n\nBy following these patterns consistently, direct functions will properly manage console output suppression while ensuring that silent mode is always properly reset, even when errors occur. This creates a more robust system that helps prevent unexpected silent mode states that could cause logging problems in subsequent operations.\n\n- **Testing Architecture**:\n\n  - **Test Organization Structure** (See also: [`tests.mdc`](mdc:.cursor/rules/tests.mdc)):\n    - **Unit Tests**: Located in `tests/unit/`, reflect the module structure with one test file per module\n    - **Integration Tests**: Located in `tests/integration/`, test interactions between modules\n    - **End-to-End Tests**: Located in `tests/e2e/`, test complete workflows from a user perspective\n    - **Test Fixtures**: Located in `tests/fixtures/`, provide reusable test data\n    - **Tagged System Tests**: Test migration, tag resolution, and multi-context functionality\n\n  - **Module Design for Testability**:\n    - **Explicit Dependencies**: Functions accept their dependencies as parameters rather than using globals\n    - **Functional Style**: Pure functions with minimal side effects make testing deterministic\n    - **Separate Logic from I/O**: Core business logic is separated from file system operations\n    - **Clear Module Interfaces**: Each module has well-defined exports that can be mocked in tests\n    - **Callback Isolation**: Callbacks are defined as separate functions for easier testing\n    - **Stateless Design**: Modules avoid maintaining internal state where possible\n    - **Tag Resolution Testing**: Test both tagged and legacy format handling\n\n  - **Mock Integration Patterns**:\n    - **External Libraries**: Libraries like `fs`, `commander`, and `@anthropic-ai/sdk` are mocked at module level\n    - **Internal Modules**: Application modules are mocked with appropriate spy functions\n    - **Testing Function Callbacks**: Callbacks are extracted from mock call arguments and tested in isolation\n    - **UI Elements**: Output functions from `ui.js` are mocked to verify display calls\n    - **Tagged Data Mocking**: Test both legacy and tagged task data structures\n\n  - **Testing Flow**:\n    - Module dependencies are mocked (following Jest's hoisting behavior)\n    - Test modules are imported after mocks are established\n    - Spy functions are set up on module methods\n    - Tests call the functions under test and verify behavior\n    - Mocks are reset between test cases to maintain isolation\n    - Tagged system behavior is tested for both migration and normal operation\n\n- **Benefits of this Architecture**:\n\n  - **Maintainability**: Modules are self-contained and focused, making it easier to understand, modify, and debug specific features.\n  - **Testability**:  Each module can be tested in isolation (unit testing), and interactions between modules can be tested (integration testing).\n    - **Mocking Support**: The clear dependency boundaries make mocking straightforward\n    - **Test Isolation**: Each component can be tested without affecting others\n    - **Callback Testing**: Function callbacks can be extracted and tested independently\n    - **Multi-Context Testing**: Tagged system enables testing different task contexts independently\n  - **Reusability**: Utility functions and UI components can be reused across different parts of the application.\n  - **Scalability**:  New features can be added as new modules or by extending existing ones without significantly impacting other parts of the application.\n  - **Multi-Context Support**: Tagged task lists enable working across different contexts (branches, environments, phases) without conflicts.\n  - **Backward Compatibility**: Seamless migration and tag resolution ensure existing workflows continue unchanged.\n  - **Clarity**: The modular structure provides a clear separation of concerns, making the codebase easier to navigate and understand for developers.\n\nThis architectural overview should help AI models understand the structure and organization of the Task Master CLI codebase, enabling them to more effectively assist with code generation, modification, and understanding.\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.\n\n2.  **Create Direct Function File in `mcp-server/src/core/direct-functions/`:**\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**.\n    - Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:\n        - **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` being provided.\n        - Parse other `args` and perform necessary validation.\n        - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()`.\n        - Implement caching with `getCachedOrExecute` if applicable.\n        - Call core logic.\n        - Return `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n    - **Note**: Tag-aware MCP tools are fully implemented with complete tag management support.\n\n3.  **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method:\n      - Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).\n      - Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)` or use `asyncOperationManager.addOperation`.\n      - Pass the result to `handleApiResult`.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition.\n\n## Project Initialization\n\nThe `initialize_project` command provides a way to set up a new Task Master project:\n\n- **CLI Command**: `task-master init`\n- **MCP Tool**: `initialize_project`\n- **Functionality**:\n  - Creates necessary directories and files for a new project\n  - Sets up `tasks.json` with tagged structure and initial task files\n  - Configures project metadata (name, description, version)\n  - Initializes state.json for tag system\n  - Handles shell alias creation if requested\n  - Works in both interactive and non-interactive modes",".cursor/rules/changeset.mdc":"---\ndescription: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\nalwaysApply: true\n---\n\n# Changesets Workflow Guidelines\n\nChangesets is used to manage package versioning and generate accurate `CHANGELOG.md` files automatically. It's crucial to use it correctly after making meaningful changes that affect the package from an external perspective or significantly impact internal development workflow documented elsewhere.\n\n## When to Run Changeset\n\n- Run `npm run changeset` (or `npx changeset add`) **after** you have staged (`git add .`) a logical set of changes that should be communicated in the next release's `CHANGELOG.md`.\n- This typically includes:\n    - **New Features** (Backward-compatible additions)\n    - **Bug Fixes** (Fixes to existing functionality)\n    - **Breaking Changes** (Changes that are not backward-compatible)\n    - **Performance Improvements** (Enhancements to speed or resource usage)\n    - **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability) - *Such as reorganizing the MCP server's direct function implementations into separate files*\n    - **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)\n    - **Dependency Updates** (Especially if they fix known issues or introduce significant changes)\n    - **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)\n- **Every Pull Request** containing one or more of the above change types **should include a changeset file**.\n\n## What NOT to Add a Changeset For\n\nAvoid creating changesets for changes that have **no impact or relevance to external consumers** of the `task-master` package or contributors following **public-facing documentation**. Examples include:\n\n- **Internal Documentation Updates:** Changes *only* to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.\n- **Trivial Chores:** Very minor code cleanup, adding comments that don't clarify behavior, typo fixes in non-user-facing code or internal docs.\n- **Non-Impactful Test Updates:** Minor refactoring of tests, adding tests for existing functionality without fixing bugs.\n- **Local Configuration Changes:** Updates to personal editor settings, local `.env` files, etc.\n\n**Rule of Thumb:** If a user installing or using the `task-master` package wouldn't care about the change, or if a contributor following the main README wouldn't need to know about it for their workflow, you likely don't need a changeset.\n\n## How to Run and What It Asks\n\n1.  **Run the command**:\n    ```bash\n    npm run changeset\n    # or\n    npx changeset add\n    ```\n2.  **Select Packages**: It will prompt you to select the package(s) affected by your changes using arrow keys and spacebar. If this is not a monorepo, select the main package.\n3.  **Select Bump Type**: Choose the appropriate semantic version bump for **each** selected package:\n    *   **`Major`**: For **breaking changes**. Use sparingly.\n    *   **`Minor`**: For **new features**.\n    *   **`Patch`**: For **bug fixes**, performance improvements, **user-facing documentation changes**, significant refactoring, relevant dependency updates, or impactful build/tooling changes.\n4.  **Enter Summary**: Provide a concise summary of the changes **for the `CHANGELOG.md`**.\n    *   **Purpose**: This message is user-facing and explains *what* changed in the release.\n    *   **Format**: Use the imperative mood (e.g., \"Add feature X\", \"Fix bug Y\", \"Update README setup instructions\"). Keep it brief, typically a single line.\n    *   **Audience**: Think about users installing/updating the package or developers consuming its public API/CLI.\n    *   **Not a Git Commit Message**: This summary is *different* from your detailed Git commit message.\n\n## Changeset Summary vs. Git Commit Message\n\n- **Changeset Summary**:\n    - **Audience**: Users/Consumers of the package (reads `CHANGELOG.md`).\n    - **Purpose**: Briefly describe *what* changed in the released version that is relevant to them.\n    - **Format**: Concise, imperative mood, single line usually sufficient.\n    - **Example**: `Fix dependency resolution bug in 'next' command.`\n- **Git Commit Message**:\n    - **Audience**: Developers browsing the Git history of *this* repository.\n    - **Purpose**: Explain *why* the change was made, the context, and the implementation details (can include internal context).\n    - **Format**: Follows commit conventions (e.g., Conventional Commits), can be multi-line with a subject and body.\n    - **Example**:\n      ```\n      fix(deps): Correct dependency lookup in 'next' command\n\n      The logic previously failed to account for subtask dependencies when\n      determining the next available task. This commit refactors the\n      dependency check in `findNextTask` within `task-manager.js` to\n      correctly traverse both direct and subtask dependencies. Added\n      unit tests to cover this specific scenario.\n      ```\n- ✅ **DO**: Provide *both* a concise changeset summary (when appropriate) *and* a detailed Git commit message.\n- ❌ **DON'T**: Use your detailed Git commit message body as the changeset summary.\n- ❌ **DON'T**: Skip running `changeset` for user-relevant changes just because you wrote a good commit message.\n\n## The `.changeset` File\n\n- Running the command creates a unique markdown file in the `.changeset/` directory (e.g., `.changeset/random-name.md`).\n- This file contains the bump type information and the summary you provided.\n- **This file MUST be staged and committed** along with your relevant code changes.\n\n## Standard Workflow Sequence (When a Changeset is Needed)\n\n1.  Make your code or relevant documentation changes.\n2.  Stage your changes: `git add .`\n3.  Run changeset: `npm run changeset`\n    *   Select package(s).\n    *   Select bump type (`Patch`, `Minor`, `Major`).\n    *   Enter the **concise summary** for the changelog.\n4.  Stage the generated changeset file: `git add .changeset/*.md`\n5.  Commit all staged changes (code + changeset file) using your **detailed Git commit message**:\n    ```bash\n    git commit -m \"feat(module): Add new feature X...\"\n    ```\n\n## Release Process (Context)\n\n- The generated `.changeset/*.md` files are consumed later during the release process.\n- Commands like `changeset version` read these files, update `package.json` versions, update the `CHANGELOG.md`, and delete the individual changeset files.\n- Commands like `changeset publish` then publish the new versions to npm.\n\nFollowing this workflow ensures that versioning is consistent and changelogs are automatically and accurately generated based on the contributions made.\n",".cursor/rules/commands.mdc":"---\ndescription: Guidelines for implementing CLI commands using Commander.js\nglobs: scripts/modules/commands.js\nalwaysApply: false\n---\n\n# Command-Line Interface Implementation Guidelines\n\n**Note on Interaction Method:**\n\nWhile this document details the implementation of Task Master's **CLI commands**, the **preferred method for interacting with Task Master in integrated environments (like Cursor) is through the MCP server tools**. \n\n- **Use MCP Tools First**: Always prefer using the MCP tools (e.g., `get_tasks`, `add_task`) when interacting programmatically or via an integrated tool. They offer better performance, structured data, and richer error handling. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a comprehensive list of MCP tools and their corresponding CLI commands.\n- **CLI as Fallback/User Interface**: The `task-master` CLI commands described here are primarily intended for:\n    - Direct user interaction in the terminal.\n    - A fallback mechanism if the MCP server is unavailable or a specific functionality is not exposed via an MCP tool.\n- **Implementation Context**: This document (`commands.mdc`) focuses on the standards for *implementing* the CLI commands using Commander.js within the [`commands.js`](mdc:scripts/modules/commands.js) module.\n\n## Command Structure Standards\n\n- **Basic Command Template**:\n  ```javascript\n  // ✅ DO: Follow this structure for all commands\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-o, --option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n- **Command Handler Organization**:\n  - ✅ DO: Keep action handlers concise and focused\n  - ✅ DO: Extract core functionality to appropriate modules\n  - ✅ DO: Have the action handler import and call the relevant functions from core modules, like `task-manager.js` or `init.js`, passing the parsed `options`.\n  - ✅ DO: Perform basic parameter validation, such as checking for required options, within the action handler or at the start of the called core function.\n  - ❌ DON'T: Implement business logic in command handlers\n\n## Best Practices for Removal/Delete Commands\n\nWhen implementing commands that delete or remove data (like `remove-task` or `remove-subtask`), follow these specific guidelines:\n\n- **Confirmation Prompts**:\n  - ✅ **DO**: Include a confirmation prompt by default for destructive operations\n  - ✅ **DO**: Provide a `--yes` or `-y` flag to skip confirmation, useful for scripting or automation\n  - ✅ **DO**: Show what will be deleted in the confirmation message\n  - ❌ **DON'T**: Perform destructive operations without user confirmation unless explicitly overridden\n\n  ```javascript\n  // ✅ DO: Include confirmation for destructive operations\n  programInstance\n    .command('remove-task')\n    .description('Remove a task or subtask permanently')\n    .option('-i, --id <id>', 'ID of the task to remove')\n    .option('-y, --yes', 'Skip confirmation prompt', false)\n    .action(async (options) => {\n      // Validation code...\n      \n      if (!options.yes) {\n        const confirm = await inquirer.prompt([{\n          type: 'confirm',\n          name: 'proceed',\n          message: `Are you sure you want to permanently delete task ${taskId}? This cannot be undone.`,\n          default: false\n        }]);\n        \n        if (!confirm.proceed) {\n          console.log(chalk.yellow('Operation cancelled.'));\n          return;\n        }\n      }\n      \n      // Proceed with removal...\n    });\n  ```\n\n- **File Path Handling**:\n  - ✅ **DO**: Use `path.join()` to construct file paths\n  - ✅ **DO**: Follow established naming conventions for tasks, like `task_001.txt`\n  - ✅ **DO**: Check if files exist before attempting to delete them\n  - ✅ **DO**: Handle file deletion errors gracefully\n  - ❌ **DON'T**: Construct paths with string concatenation\n\n  ```javascript\n  // ✅ DO: Properly construct file paths\n  const taskFilePath = path.join(\n    path.dirname(tasksPath),\n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ✅ DO: Check existence before deletion\n  if (fs.existsSync(taskFilePath)) {\n    try {\n      fs.unlinkSync(taskFilePath);\n      console.log(chalk.green(`Task file deleted: ${taskFilePath}`));\n    } catch (error) {\n      console.warn(chalk.yellow(`Could not delete task file: ${error.message}`));\n    }\n  }\n  ```\n\n- **Clean Up References**:\n  - ✅ **DO**: Clean up references to the deleted item in other parts of the data\n  - ✅ **DO**: Handle both direct and indirect references\n  - ✅ **DO**: Explain what related data is being updated\n  - ❌ **DON'T**: Leave dangling references\n\n  ```javascript\n  // ✅ DO: Clean up references when deleting items\n  console.log(chalk.blue('Cleaning up task dependencies...'));\n  let referencesRemoved = 0;\n  \n  // Update dependencies in other tasks\n  data.tasks.forEach(task => {\n    if (task.dependencies && task.dependencies.includes(taskId)) {\n      task.dependencies = task.dependencies.filter(depId => depId !== taskId);\n      referencesRemoved++;\n    }\n  });\n  \n  if (referencesRemoved > 0) {\n    console.log(chalk.green(`Removed ${referencesRemoved} references to task ${taskId} from other tasks`));\n  }\n  ```\n\n- **Task File Regeneration**:\n  - ✅ **DO**: Regenerate task files after destructive operations\n  - ✅ **DO**: Pass all required parameters to generation functions\n  - ✅ **DO**: Provide an option to skip regeneration if needed\n  - ❌ **DON'T**: Assume default parameters will work\n\n  ```javascript\n  // ✅ DO: Properly regenerate files after deletion\n  if (!options.skipGenerate) {\n    console.log(chalk.blue('Regenerating task files...'));\n    try {\n      // Note both parameters are explicitly provided\n      await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n      console.log(chalk.green('Task files regenerated successfully'));\n    } catch (error) {\n      console.warn(chalk.yellow(`Warning: Could not regenerate task files: ${error.message}`));\n    }\n  }\n  ```\n\n- **Alternative Suggestions**:\n  - ✅ **DO**: Suggest non-destructive alternatives when appropriate\n  - ✅ **DO**: Explain the difference between deletion and status changes\n  - ✅ **DO**: Include examples of alternative commands\n\n  ```javascript\n  // ✅ DO: Suggest alternatives for destructive operations\n  console.log(chalk.yellow('Note: If you just want to exclude this task from active work, consider:'));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='cancelled'`));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='deferred'`));\n  console.log('This preserves the task and its history for reference.');\n  ```\n\n## Option Naming Conventions\n\n- **Command Names**:\n  - ✅ DO: Use kebab-case for command names (`analyze-complexity`)\n  - ❌ DON'T: Use camelCase for command names (`analyzeComplexity`)\n  - ✅ DO: Use descriptive, action-oriented names\n\n- **Option Names**:\n  - ✅ DO: Use kebab-case for long-form option names, like `--output-format`\n  - ✅ DO: Provide single-letter shortcuts when appropriate, like `-f, --file`\n  - ✅ DO: Use consistent option names across similar commands\n  - ❌ DON'T: Use different names for the same concept, such as `--file` in one command and `--path` in another\n\n  ```javascript\n  // ✅ DO: Use consistent option naming\n  .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <dir>', 'Output directory', 'tasks')\n  \n  // ❌ DON'T: Use inconsistent naming\n  .option('-f, --file <path>', 'Path to the tasks file')\n  .option('-p, --path <dir>', 'Output directory') // Should be --output\n  ```\n\n  > **Note**: Although options are defined with kebab-case, like `--num-tasks`, Commander.js stores them internally as camelCase properties. Access them in code as `options.numTasks`, not `options['num-tasks']`.\n\n- **Boolean Flag Conventions**:\n  - ✅ DO: Use positive flags with `--skip-` prefix for disabling behavior\n  - ❌ DON'T: Use negated boolean flags with `--no-` prefix\n  - ✅ DO: Use consistent flag handling across all commands\n\n  ```javascript\n  // ✅ DO: Use positive flag with skip- prefix \n  .option('--skip-generate', 'Skip generating task files')\n  \n  // ❌ DON'T: Use --no- prefix \n  .option('--no-generate', 'Skip generating task files')\n  ```\n\n  > **Important**: When handling boolean flags in the code, make your intent clear:\n  ```javascript\n  // ✅ DO: Use clear variable naming that matches the flag's intent\n  const generateFiles = !options.skipGenerate;\n  \n  // ❌ DON'T: Use confusing double negatives\n  const dontSkipGenerate = !options.skipGenerate;\n  ```\n\n## Input Validation\n\n- **Required Parameters**:\n  - ✅ DO: Check that required parameters are provided\n  - ✅ DO: Provide clear error messages when parameters are missing\n  - ✅ DO: Use early returns with `process.exit(1)` for validation failures\n\n  ```javascript\n  // ✅ DO: Validate required parameters early\n  if (!prompt) {\n    console.error(chalk.red('Error: --prompt parameter is required. Please provide a task description.'));\n    process.exit(1);\n  }\n  ```\n\n- **Parameter Type Conversion**:\n  - ✅ DO: Convert string inputs to appropriate types, such as numbers or booleans\n  - ✅ DO: Handle conversion errors gracefully\n\n  ```javascript\n  // ✅ DO: Parse numeric parameters properly\n  const fromId = parseInt(options.from, 10);\n  if (isNaN(fromId)) {\n    console.error(chalk.red('Error: --from must be a valid number'));\n    process.exit(1);\n  }\n  ```\n\n- **Enhanced Input Validation**:\n  - ✅ DO: Validate file existence for critical file operations\n  - ✅ DO: Provide context-specific validation for identifiers\n  - ✅ DO: Check required API keys for features that depend on them\n\n  ```javascript\n  // ✅ DO: Validate file existence\n  if (!fs.existsSync(tasksPath)) {\n    console.error(chalk.red(`Error: Tasks file not found at path: ${tasksPath}`));\n    if (tasksPath === 'tasks/tasks.json') {\n      console.log(chalk.yellow('Hint: Run task-master init or task-master parse-prd to create tasks.json first'));\n    } else {\n      console.log(chalk.yellow(`Hint: Check if the file path is correct: ${tasksPath}`));\n    }\n    process.exit(1);\n  }\n  \n  // ✅ DO: Validate task ID\n  const taskId = parseInt(options.id, 10);\n  if (isNaN(taskId) || taskId <= 0) {\n    console.error(chalk.red(`Error: Invalid task ID: ${options.id}. Task ID must be a positive integer.`));\n    console.log(chalk.yellow(\"Usage example: task-master update-task --id='23' --prompt='Update with new information.\\\\nEnsure proper error handling.'\"));\n    process.exit(1);\n  }\n  \n  // ✅ DO: Check for required API keys\n  if (useResearch && !process.env.PERPLEXITY_API_KEY) {\n    console.log(chalk.yellow('Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'));\n    console.log(chalk.yellow('Falling back to Claude AI for task update.'));\n  }\n  ```\n\n## User Feedback\n\n- **Operation Status**:\n  - ✅ DO: Provide clear feedback about the operation being performed\n  - ✅ DO: Display success or error messages after completion\n  - ✅ DO: Use colored output to distinguish between different message types\n\n  ```javascript\n  // ✅ DO: Show operation status\n  console.log(chalk.blue(`Parsing PRD file: ${file}`));\n  console.log(chalk.blue(`Generating ${numTasks} tasks...`));\n  \n  try {\n    await parsePRD(file, outputPath, numTasks);\n    console.log(chalk.green('Successfully generated tasks from PRD'));\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    process.exit(1);\n  }\n  ```\n\n- **Success Messages with Next Steps**:\n  - ✅ DO: Use boxen for important success messages with clear formatting\n  - ✅ DO: Provide suggested next steps after command completion\n  - ✅ DO: Include ready-to-use commands for follow-up actions\n\n  ```javascript\n  // ✅ DO: Display success with next steps\n  console.log(boxen(\n    chalk.white.bold(`Subtask ${parentId}.${subtask.id} Added Successfully`) + '\\n\\n' +\n    chalk.white(`Title: ${subtask.title}`) + '\\n' +\n    chalk.white(`Status: ${getStatusWithColor(subtask.status)}`) + '\\n' +\n    (dependencies.length > 0 ? chalk.white(`Dependencies: ${dependencies.join(', ')}`) + '\\n' : '') +\n    '\\n' +\n    chalk.white.bold('Next Steps:') + '\\n' +\n    chalk.cyan(`1. Run ${chalk.yellow(`task-master show '${parentId}'`)} to see the parent task with all subtasks`) + '\\n' +\n    chalk.cyan(`2. Run ${chalk.yellow(`task-master set-status --id='${parentId}.${subtask.id}' --status='in-progress'`)} to start working on it`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Command Registration\n\n- **Command Grouping**:\n  - ✅ DO: Group related commands together in the code\n  - ✅ DO: Add related commands in a logical order\n  - ✅ DO: Use comments to delineate command groups\n\n- **Command Export**:\n  - ✅ DO: Export the registerCommands function\n  - ✅ DO: Keep the CLI setup code clean and maintainable\n\n  ```javascript\n  // ✅ DO: Follow this export pattern\n  export {\n    registerCommands,\n    setupCLI,\n    runCLI,\n    checkForUpdate, // Include version checking functions\n    compareVersions,\n    displayUpgradeNotification\n  };\n  ```\n\n## Context-Aware Command Pattern\n\nFor AI-powered commands that benefit from project context, follow the research command pattern:\n\n- **Context Integration**:\n  - ✅ DO: Use `ContextGatherer` utility for multi-source context extraction\n  - ✅ DO: Support task IDs, file paths, custom context, and project tree\n  - ✅ DO: Implement fuzzy search for automatic task discovery\n  - ✅ DO: Display detailed token breakdown for transparency\n\n  ```javascript\n  // ✅ DO: Follow this pattern for context-aware commands\n  programInstance\n    .command('research')\n    .description('Perform AI-powered research queries with project context')\n    .argument('<prompt>', 'Research prompt to investigate')\n    .option('-i, --id <ids>', 'Comma-separated task/subtask IDs to include as context')\n    .option('-f, --files <paths>', 'Comma-separated file paths to include as context')\n    .option('-c, --context <text>', 'Additional custom context')\n    .option('--tree', 'Include project file tree structure')\n    .option('-d, --detail <level>', 'Output detail level: low, medium, high', 'medium')\n    .action(async (prompt, options) => {\n      // 1. Parameter validation and parsing\n      const taskIds = options.id ? parseTaskIds(options.id) : [];\n      const filePaths = options.files ? parseFilePaths(options.files) : [];\n      \n      // 2. Initialize context gatherer\n      const projectRoot = findProjectRoot() || '.';\n      const gatherer = new ContextGatherer(projectRoot, tasksPath);\n      \n      // 3. Auto-discover relevant tasks if none specified\n      if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n          fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n      }\n      \n      // 4. Gather context with token breakdown\n      const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n      });\n      \n      // 5. Display token breakdown and execute AI call\n      // Implementation continues...\n    });\n  ```\n\n## Error Handling\n\n- **Exception Management**:\n  - ✅ DO: Wrap async operations in try/catch blocks\n  - ✅ DO: Display user-friendly error messages\n  - ✅ DO: Include detailed error information in debug mode\n\n  ```javascript\n  // ✅ DO: Handle errors properly\n  try {\n    // Command implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n- **Unknown Options Handling**:\n  - ✅ DO: Provide clear error messages for unknown options\n  - ✅ DO: Show available options when an unknown option is used\n  - ✅ DO: Include command-specific help displays for common errors\n  - ❌ DON'T: Allow unknown options with `.allowUnknownOption()`\n\n  ```javascript\n  // ✅ DO: Register global error handlers for unknown options\n  programInstance.on('option:unknown', function(unknownOption) {\n    const commandName = this._name || 'unknown';\n    console.error(chalk.red(`Error: Unknown option '${unknownOption}'`));\n    console.error(chalk.yellow(`Run 'task-master ${commandName} --help' to see available options`));\n    process.exit(1);\n  });\n  \n  // ✅ DO: Add command-specific help displays\n  function showCommandHelp() {\n    console.log(boxen(\n      chalk.white.bold('Command Help') + '\\n\\n' +\n      chalk.cyan('Usage:') + '\\n' +\n      `  task-master command --option1=<value> [options]\\n\\n` +\n      chalk.cyan('Options:') + '\\n' +\n      '  --option1 <value>    Description of option1 (required)\\n' +\n      '  --option2 <value>    Description of option2\\n\\n' +\n      chalk.cyan('Examples:') + '\\n' +\n      '  task-master command --option1=\\'value1\\' --option2=\\'value2\\'',\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n- **Global Error Handling**:\n  - ✅ DO: Set up global error handlers for uncaught exceptions\n  - ✅ DO: Detect and format Commander-specific errors\n  - ✅ DO: Provide suitable guidance for fixing common errors\n\n  ```javascript\n  // ✅ DO: Set up global error handlers with helpful messages\n  process.on('uncaughtException', (err) => {\n    // Handle Commander-specific errors\n    if (err.code === 'commander.unknownOption') {\n      const option = err.message.match(/'([^']+)'/)?.[1]; // Safely extract option name\n      console.error(chalk.red(`Error: Unknown option '${option}'`));\n      console.error(chalk.yellow(\"Run 'task-master <command> --help' to see available options\"));\n      process.exit(1);\n    }\n    \n    // Handle other error types...\n    console.error(chalk.red(`Error: ${err.message}`));\n    process.exit(1);\n  });\n  ```\n\n- **Contextual Error Handling**:\n  - ✅ DO: Provide specific error handling for common issues\n  - ✅ DO: Include troubleshooting hints for each error type\n  - ✅ DO: Use consistent error formatting across all commands\n\n  ```javascript\n  // ✅ DO: Provide specific error handling with guidance\n  try {\n    // Implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    // Provide more helpful error messages for common issues\n    if (error.message.includes('task') && error.message.includes('not found')) {\n      console.log(chalk.yellow('\\nTo fix this issue:'));\n      console.log('  1. Run \\'task-master list\\' to see all available task IDs');\n      console.log('  2. Use a valid task ID with the --id parameter');\n    } else if (error.message.includes('API key')) {\n      console.log(chalk.yellow('\\nThis error is related to API keys. Check your environment variables.'));\n    }\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n## Integration with Other Modules\n\n- **Import Organization**:\n  - ✅ DO: Group imports by module/functionality\n  - ✅ DO: Import only what's needed, not entire modules\n  - ❌ DON'T: Create circular dependencies\n\n  ```javascript\n  // ✅ DO: Organize imports by module\n  import { program } from 'commander';\n  import path from 'path';\n  import chalk from 'chalk';\n  import https from 'https';\n  \n  import { CONFIG, log, readJSON } from './utils.js';\n  import { displayBanner, displayHelp } from './ui.js';\n  import { parsePRD, listTasks } from './task-manager.js';\n  import { addDependency } from './dependency-manager.js';\n  ```\n\n## Subtask Management Commands\n\n- **Add Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for adding subtasks\n  programInstance\n    .command('add-subtask')\n    .description('Add a new subtask to a parent task or convert an existing task to a subtask')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-p, --parent <id>', 'ID of the parent task (required)')\n    .option('-i, --task-id <id>', 'Existing task ID to convert to subtask')\n    .option('-t, --title <title>', 'Title for the new subtask, required if not converting')\n    .option('-d, --description <description>', 'Description for the new subtask, optional')\n    .option('--details <details>', 'Implementation details for the new subtask, optional')\n    .option('--dependencies <ids>', 'Comma-separated list of subtask IDs this subtask depends on')\n    .option('--status <status>', 'Initial status for the subtask', 'pending')\n    .option('--generate', 'Regenerate task files after adding subtask')\n    .action(async (options) => {\n      // Validate required parameters\n      if (!options.parent) {\n        console.error(chalk.red('Error: --parent parameter is required'));\n        showAddSubtaskHelp(); // Show contextual help\n        process.exit(1);\n      }\n      \n      // Implementation with detailed error handling\n    });\n  ```\n\n- **Remove Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for removing subtasks\n  programInstance\n    .command('remove-subtask')\n    .description('Remove a subtask from its parent task, optionally converting it to a standalone task')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-i, --id <id>', 'ID of the subtask to remove in format parentId.subtaskId, required')\n    .option('-c, --convert', 'Convert the subtask to a standalone task instead of deleting')\n    .option('--generate', 'Regenerate task files after removing subtask')\n    .action(async (options) => {\n      // Implementation with detailed error handling\n    })\n    .on('error', function(err) {\n      console.error(chalk.red(`Error: ${err.message}`));\n      showRemoveSubtaskHelp(); // Show contextual help\n      process.exit(1);\n    });\n  ```\n\n## Version Checking and Updates\n\n- **Automatic Version Checking**:\n  - ✅ DO: Implement version checking to notify users of available updates\n  - ✅ DO: Use non-blocking version checks that don't delay command execution\n  - ✅ DO: Display update notifications after command completion\n\n  ```javascript\n  // ✅ DO: Implement version checking function\n  async function checkForUpdate() {\n    // Implementation details...\n    // Example return structure:\n    return { currentVersion, latestVersion, updateAvailable };\n  }\n  \n  // ✅ DO: Implement semantic version comparison\n  function compareVersions(v1, v2) {\n    const v1Parts = v1.split('.').map(p => parseInt(p, 10));\n    const v2Parts = v2.split('.').map(p => parseInt(p, 10));\n    \n    // Implementation details...\n    return result; // -1, 0, or 1\n  }\n  \n  // ✅ DO: Display attractive update notifications\n  function displayUpgradeNotification(currentVersion, latestVersion) {\n    const message = boxen(\n      `${chalk.blue.bold('Update Available!')} ${chalk.dim(currentVersion)} → ${chalk.green(latestVersion)}\\n\\n` +\n      `Run ${chalk.cyan('npm i task-master-ai@latest -g')} to update to the latest version with new features and bug fixes.`,\n      {\n        padding: 1,\n        margin: { top: 1, bottom: 1 },\n        borderColor: 'yellow',\n        borderStyle: 'round'\n      }\n    );\n    \n    console.log(message);\n  }\n  \n  // ✅ DO: Integrate version checking in CLI run function\n  async function runCLI(argv = process.argv) {\n    try {\n      // Start the update check in the background - don't await yet\n      const updateCheckPromise = checkForUpdate();\n      \n      // Setup and parse\n      const programInstance = setupCLI();\n      await programInstance.parseAsync(argv);\n      \n      // After command execution, check if an update is available\n      const updateInfo = await updateCheckPromise;\n      if (updateInfo.updateAvailable) {\n        displayUpgradeNotification(updateInfo.currentVersion, updateInfo.latestVersion);\n      }\n    } catch (error) {\n      // Error handling...\n    }\n  }\n  ```\n\nRefer to [`commands.js`](mdc:scripts/modules/commands.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. \n// Helper function to show add-subtask command help\nfunction showAddSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Add Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master add-subtask --parent=<id> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -p, --parent <id>         Parent task ID (required)\\n' +\n    '  -i, --task-id <id>        Existing task ID to convert to subtask\\n' +\n    '  -t, --title <title>       Title for the new subtask\\n' +\n    '  -d, --description <text>  Description for the new subtask\\n' +\n    '  --details <text>          Implementation details for the new subtask\\n' +\n    '  --dependencies <ids>      Comma-separated list of dependency IDs\\n' +\n    '  -s, --status <status>     Status for the new subtask (default: \"pending\")\\n' +\n    '  -f, --file <file>         Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate                Regenerate task files after adding subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master add-subtask --parent=\\'5\\' --task-id=\\'8\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Implement login UI\\' -d \\'Create the login form\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Handle API Errors\\' --details \"Handle 401 Unauthorized.\\\\nHandle 500 Server Error.\" --generate',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n}\n\n// Helper function to show remove-subtask command help\nfunction showRemoveSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Remove Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master remove-subtask --id=<parentId.subtaskId> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -i, --id <id>       Subtask ID(s) to remove in format \"parentId.subtaskId\" (can be comma-separated, required)\\n' +\n    '  -c, --convert       Convert the subtask to a standalone task instead of deleting it\\n' +\n    '  -f, --file <file>   Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate          Regenerate task files after removing subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2,6.3,7.1\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\' --convert',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n} \n",".cursor/rules/context_gathering.mdc":"---\ndescription: Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\nglobs: \nalwaysApply: false\n---\n# Context Gathering Patterns and Utilities\n\nThis document outlines the standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\n\n## Core Context Gathering Utility\n\nThe `ContextGatherer` class (`scripts/modules/utils/contextGatherer.js`) provides a centralized, reusable utility for extracting context from multiple sources:\n\n### **Key Features**\n- **Multi-source Context**: Tasks, files, custom text, project file tree\n- **Token Counting**: Detailed breakdown using `gpt-tokens` library\n- **Format Support**: Different output formats (research, chat, system-prompt)\n- **Error Handling**: Graceful handling of missing files, invalid task IDs\n- **Performance**: File size limits, depth limits for tree generation\n\n### **Usage Pattern**\n```javascript\nimport { ContextGatherer } from '../utils/contextGatherer.js';\n\n// Initialize with project paths\nconst gatherer = new ContextGatherer(projectRoot, tasksPath);\n\n// Gather context with detailed token breakdown\nconst result = await gatherer.gather({\n    tasks: ['15', '16.2'],           // Task and subtask IDs\n    files: ['src/api.js', 'README.md'], // File paths\n    customContext: 'Additional context text',\n    includeProjectTree: true,        // Include file tree\n    format: 'research',              // Output format\n    includeTokenCounts: true         // Get detailed token breakdown\n});\n\n// Access results\nconst contextString = result.context;\nconst tokenBreakdown = result.tokenBreakdown;\n```\n\n### **Token Breakdown Structure**\n```javascript\n{\n    customContext: { tokens: 150, characters: 800 },\n    tasks: [\n        { id: '15', type: 'task', title: 'Task Title', tokens: 245, characters: 1200 },\n        { id: '16.2', type: 'subtask', title: 'Subtask Title', tokens: 180, characters: 900 }\n    ],\n    files: [\n        { path: 'src/api.js', tokens: 890, characters: 4500, size: '4.5 KB' }\n    ],\n    projectTree: { tokens: 320, characters: 1600 },\n    total: { tokens: 1785, characters: 8000 }\n}\n```\n\n## Fuzzy Search Integration\n\nThe `FuzzyTaskSearch` class (`scripts/modules/utils/fuzzyTaskSearch.js`) provides intelligent task discovery:\n\n### **Key Features**\n- **Semantic Matching**: Uses Fuse.js for similarity scoring\n- **Purpose Categories**: Pattern-based task categorization\n- **Relevance Scoring**: High/medium/low relevance thresholds\n- **Context-Aware**: Different search configurations for different use cases\n\n### **Usage Pattern**\n```javascript\nimport { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n\n// Initialize with tasks data and context\nconst fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n\n// Find relevant tasks\nconst searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n});\n\n// Get task IDs for context gathering\nconst taskIds = fuzzySearch.getTaskIds(searchResults);\n```\n\n## Implementation Patterns for Commands\n\n### **1. Context-Aware Command Structure**\n```javascript\n// In command action handler\nasync function commandAction(prompt, options) {\n    // 1. Parameter validation and parsing\n    const taskIds = options.id ? parseTaskIds(options.id) : [];\n    const filePaths = options.files ? parseFilePaths(options.files) : [];\n    \n    // 2. Initialize context gatherer\n    const projectRoot = findProjectRoot() || '.';\n    const tasksPath = path.join(projectRoot, 'tasks', 'tasks.json');\n    const gatherer = new ContextGatherer(projectRoot, tasksPath);\n    \n    // 3. Auto-discover relevant tasks if none specified\n    if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n            fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n    }\n    \n    // 4. Gather context with token breakdown\n    const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n    });\n    \n    // 5. Display token breakdown (for CLI)\n    if (outputFormat === 'text') {\n        displayDetailedTokenBreakdown(contextResult.tokenBreakdown);\n    }\n    \n    // 6. Use context in AI call\n    const aiResult = await generateTextService(role, session, systemPrompt, userPrompt);\n    \n    // 7. Display results with enhanced formatting\n    displayResults(aiResult, contextResult.tokenBreakdown);\n}\n```\n\n### **2. Token Display Pattern**\n```javascript\nfunction displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    // Build context breakdown\n    if (tokenBreakdown.tasks?.length > 0) {\n        const taskDetails = tokenBreakdown.tasks.map(task => \n            `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n        ).join('\\n');\n        sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    if (tokenBreakdown.files?.length > 0) {\n        const fileDetails = tokenBreakdown.files.map(file =>\n            `  ${file.path}: ${file.tokens.toLocaleString()} (${file.size})`\n        ).join('\\n');\n        sections.push(`Files (${tokenBreakdown.files.reduce((sum, f) => sum + f.tokens, 0).toLocaleString()}):\\n${fileDetails}`);\n    }\n    \n    // Add prompts breakdown\n    sections.push(`Prompts: system ${systemTokens.toLocaleString()}, user ${userTokens.toLocaleString()}`);\n    \n    // Display in clean box\n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n        title: chalk.cyan('Token Usage'),\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        borderStyle: 'round',\n        borderColor: 'cyan'\n    }));\n}\n```\n\n### **3. Enhanced Result Display Pattern**\n```javascript\nfunction displayResults(result, query, detailLevel, tokenBreakdown) {\n    // Header with query info\n    const header = boxen(\n        chalk.green.bold('Research Results') + '\\n\\n' +\n        chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n        chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n        {\n            padding: { top: 1, bottom: 1, left: 2, right: 2 },\n            margin: { top: 1, bottom: 0 },\n            borderStyle: 'round',\n            borderColor: 'green'\n        }\n    );\n    console.log(header);\n    \n    // Process and highlight code blocks\n    const processedResult = processCodeBlocks(result);\n    \n    // Main content in clean box\n    const contentBox = boxen(processedResult, {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 0, bottom: 1 },\n        borderStyle: 'single',\n        borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Research complete'));\n}\n```\n\n## Code Block Enhancement\n\n### **Syntax Highlighting Pattern**\n```javascript\nimport { highlight } from 'cli-highlight';\n\nfunction processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n        try {\n            const highlighted = highlight(code.trim(), { \n                language: language || 'javascript',\n                theme: 'default'\n            });\n            return `\\n${highlighted}\\n`;\n        } catch (error) {\n            return `\\n${code.trim()}\\n`;\n        }\n    });\n}\n```\n\n## Integration Guidelines\n\n### **When to Use Context Gathering**\n- ✅ **DO**: Use for AI-powered commands that benefit from project context\n- ✅ **DO**: Use when users might want to reference specific tasks or files\n- ✅ **DO**: Use for research, analysis, or generation commands\n- ❌ **DON'T**: Use for simple CRUD operations that don't need AI context\n\n### **Performance Considerations**\n- ✅ **DO**: Set reasonable file size limits (50KB default)\n- ✅ **DO**: Limit project tree depth (3-5 levels)\n- ✅ **DO**: Provide token counts to help users understand context size\n- ✅ **DO**: Allow users to control what context is included\n\n### **Error Handling**\n- ✅ **DO**: Gracefully handle missing files with warnings\n- ✅ **DO**: Validate task IDs and provide helpful error messages\n- ✅ **DO**: Continue processing even if some context sources fail\n- ✅ **DO**: Provide fallback behavior when context gathering fails\n\n### **Future Command Integration**\nCommands that should consider adopting this pattern:\n- `analyze-complexity` - Could benefit from file context\n- `expand-task` - Could use related task context\n- `update-task` - Could reference similar tasks for consistency\n- `add-task` - Could use project context for better task generation\n\n## Export Patterns\n\n### **Context Gatherer Module**\n```javascript\nexport {\n    ContextGatherer,\n    createContextGatherer  // Factory function\n};\n```\n\n### **Fuzzy Search Module**\n```javascript\nexport {\n    FuzzyTaskSearch,\n    PURPOSE_CATEGORIES,\n    RELEVANCE_THRESHOLDS\n};\n```\n\nThis context gathering system provides a foundation for building more intelligent, context-aware commands that can leverage project knowledge to provide better AI-powered assistance.\n",".cursor/rules/cursor_rules.mdc":"---\ndescription: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\nglobs: .cursor/rules/*.mdc\nalwaysApply: true\n---\n\n- **Required Rule Structure:**\n  ```markdown\n  ---\n  description: Clear, one-line description of what the rule enforces\n  globs: path/to/files/*.ext, other/path/**/*\n  alwaysApply: boolean\n  ---\n\n  - **Main Points in Bold**\n    - Sub-points with details\n    - Examples and explanations\n  ```\n\n- **File References:**\n  - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files\n  - Example: [prisma.mdc](mdc:.cursor/rules/prisma.mdc) for rule references\n  - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references\n\n- **Code Examples:**\n  - Use language-specific code blocks\n  ```typescript\n  // ✅ DO: Show good examples\n  const goodExample = true;\n  \n  // ❌ DON'T: Show anti-patterns\n  const badExample = false;\n  ```\n\n- **Rule Content Guidelines:**\n  - Start with high-level overview\n  - Include specific, actionable requirements\n  - Show examples of correct implementation\n  - Reference existing code when possible\n  - Keep rules DRY by referencing other rules\n\n- **Rule Maintenance:**\n  - Update rules when new patterns emerge\n  - Add examples from actual codebase\n  - Remove outdated patterns\n  - Cross-reference related rules\n\n- **Best Practices:**\n  - Use bullet points for clarity\n  - Keep descriptions concise\n  - Include both DO and DON'T examples\n  - Reference actual code over theoretical examples\n  - Use consistent formatting across rules ",".cursor/rules/dependencies.mdc":"---\ndescription: Guidelines for managing task dependencies and relationships\nglobs: scripts/modules/dependency-manager.js\nalwaysApply: false\n---\n\n# Dependency Management Guidelines\n\n## Dependency Structure Principles\n\n- **Dependency References**:\n  - ✅ DO: Represent task dependencies as arrays of task IDs\n  - ✅ DO: Use numeric IDs for direct task references\n  - ✅ DO: Use string IDs with dot notation (e.g., \"1.2\") for subtask references\n  - ❌ DON'T: Mix reference types without proper conversion\n\n  ```javascript\n  // ✅ DO: Use consistent dependency formats\n  // For main tasks\n  task.dependencies = [1, 2, 3]; // Dependencies on other main tasks\n  \n  // For subtasks\n  subtask.dependencies = [1, \"3.2\"]; // Dependency on main task 1 and subtask 2 of task 3\n  ```\n\n- **Subtask Dependencies**:\n  - ✅ DO: Allow numeric subtask IDs to reference other subtasks within the same parent\n  - ✅ DO: Convert between formats appropriately when needed\n  - ❌ DON'T: Create circular dependencies between subtasks\n\n  ```javascript\n  // ✅ DO: Properly normalize subtask dependencies\n  // When a subtask refers to another subtask in the same parent\n  if (typeof depId === 'number' && depId < 100) {\n    // It's likely a reference to another subtask in the same parent task\n    const fullSubtaskId = `${parentId}.${depId}`;\n    // Now use fullSubtaskId for validation\n  }\n  ```\n\n## Dependency Validation\n\n- **Existence Checking**:\n  - ✅ DO: Validate that referenced tasks exist before adding dependencies\n  - ✅ DO: Provide clear error messages for non-existent dependencies\n  - ✅ DO: Remove references to non-existent tasks during validation\n\n  ```javascript\n  // ✅ DO: Check if the dependency exists before adding\n  if (!taskExists(data.tasks, formattedDependencyId)) {\n    log('error', `Dependency target ${formattedDependencyId} does not exist in tasks.json`);\n    process.exit(1);\n  }\n  ```\n\n- **Circular Dependency Prevention**:\n  - ✅ DO: Check for circular dependencies before adding new relationships\n  - ✅ DO: Use graph traversal algorithms (DFS) to detect cycles\n  - ✅ DO: Provide clear error messages explaining the circular chain\n\n  ```javascript\n  // ✅ DO: Check for circular dependencies before adding\n  const dependencyChain = [formattedTaskId];\n  if (isCircularDependency(data.tasks, formattedDependencyId, dependencyChain)) {\n    log('error', `Cannot add dependency ${formattedDependencyId} to task ${formattedTaskId} as it would create a circular dependency.`);\n    process.exit(1);\n  }\n  ```\n\n- **Self-Dependency Prevention**:\n  - ✅ DO: Prevent tasks from depending on themselves\n  - ✅ DO: Handle both direct and indirect self-dependencies\n\n  ```javascript\n  // ✅ DO: Prevent self-dependencies\n  if (String(formattedTaskId) === String(formattedDependencyId)) {\n    log('error', `Task ${formattedTaskId} cannot depend on itself.`);\n    process.exit(1);\n  }\n  ```\n\n## Dependency Modification\n\n- **Adding Dependencies**:\n  - ✅ DO: Format task and dependency IDs consistently\n  - ✅ DO: Check for existing dependencies to prevent duplicates\n  - ✅ DO: Sort dependencies for better readability\n\n  ```javascript\n  // ✅ DO: Format IDs consistently when adding dependencies\n  const formattedTaskId = typeof taskId === 'string' && taskId.includes('.') \n    ? taskId : parseInt(taskId, 10);\n  \n  const formattedDependencyId = formatTaskId(dependencyId);\n  ```\n\n- **Removing Dependencies**:\n  - ✅ DO: Check if the dependency exists before removing\n  - ✅ DO: Handle different ID formats consistently\n  - ✅ DO: Provide feedback about the removal result\n\n  ```javascript\n  // ✅ DO: Properly handle dependency removal\n  const dependencyIndex = targetTask.dependencies.findIndex(dep => {\n    // Convert both to strings for comparison\n    let depStr = String(dep);\n    \n    // Handle relative subtask references\n    if (typeof dep === 'number' && dep < 100 && isSubtask) {\n      const [parentId] = formattedTaskId.split('.');\n      depStr = `${parentId}.${dep}`;\n    }\n    \n    return depStr === normalizedDependencyId;\n  });\n  \n  if (dependencyIndex === -1) {\n    log('info', `Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`);\n    return;\n  }\n  \n  // Remove the dependency\n  targetTask.dependencies.splice(dependencyIndex, 1);\n  ```\n\n## Dependency Cleanup\n\n- **Duplicate Removal**:\n  - ✅ DO: Use Set objects to identify and remove duplicates\n  - ✅ DO: Handle both numeric and string ID formats\n\n  ```javascript\n  // ✅ DO: Remove duplicate dependencies\n  const uniqueDeps = new Set();\n  const uniqueDependencies = task.dependencies.filter(depId => {\n    // Convert to string for comparison to handle both numeric and string IDs\n    const depIdStr = String(depId);\n    if (uniqueDeps.has(depIdStr)) {\n      log('warn', `Removing duplicate dependency from task ${task.id}: ${depId}`);\n      return false;\n    }\n    uniqueDeps.add(depIdStr);\n    return true;\n  });\n  ```\n\n- **Invalid Reference Cleanup**:\n  - ✅ DO: Check for and remove references to non-existent tasks\n  - ✅ DO: Check for and remove self-references\n  - ✅ DO: Track and report changes made during cleanup\n\n  ```javascript\n  // ✅ DO: Filter invalid task dependencies\n  task.dependencies = task.dependencies.filter(depId => {\n    const numericId = typeof depId === 'string' ? parseInt(depId, 10) : depId;\n    if (!validTaskIds.has(numericId)) {\n      log('warn', `Removing invalid task dependency from task ${task.id}: ${depId} (task does not exist)`);\n      return false;\n    }\n    return true;\n  });\n  ```\n\n## Dependency Visualization\n\n- **Status Indicators**:\n  - ✅ DO: Use visual indicators to show dependency status (✅/⏱️)\n  - ✅ DO: Format dependency lists consistently\n\n  ```javascript\n  // ✅ DO: Format dependencies with status indicators\n  function formatDependenciesWithStatus(dependencies, allTasks) {\n    if (!dependencies || dependencies.length === 0) {\n      return 'None';\n    }\n    \n    return dependencies.map(depId => {\n      const depTask = findTaskById(allTasks, depId);\n      if (!depTask) return `${depId} (Not found)`;\n      \n      const isDone = depTask.status === 'done' || depTask.status === 'completed';\n      const statusIcon = isDone ? '✅' : '⏱️';\n      \n      return `${statusIcon} ${depId} (${depTask.status})`;\n    }).join(', ');\n  }\n  ```\n\n## Cycle Detection\n\n- **Graph Traversal**:\n  - ✅ DO: Use depth-first search (DFS) for cycle detection\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Support both task and subtask dependencies\n\n  ```javascript\n  // ✅ DO: Use proper cycle detection algorithms\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set()) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    \n    const cyclesToBreak = [];\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    for (const depId of dependencies) {\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack);\n        cyclesToBreak.push(...cycles);\n      } \n      else if (recursionStack.has(depId)) {\n        // Found a cycle, add the edge to break\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\nRefer to [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/dev_workflow.mdc":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*",".cursor/rules/git_workflow.mdc":"---\ndescription: Git workflow integrated with Task Master for feature development and collaboration\nglobs: \"**/*\"\nalwaysApply: true\n---\n# Git Workflow with Task Master Integration\n\n## **Branch Strategy**\n\n### **Main Branch Protection**\n- **main** branch contains production-ready code\n- All feature development happens on task-specific branches\n- Direct commits to main are prohibited\n- All changes merge via Pull Requests\n\n### **Task Branch Naming**\n```bash\n# ✅ DO: Use consistent task branch naming\ntask-001  # For Task 1\ntask-004  # For Task 4\ntask-015  # For Task 15\n\n# ❌ DON'T: Use inconsistent naming\nfeature/user-auth\nfix-database-issue\nrandom-branch-name\n```\n\n## **Tagged Task Lists Integration**\n\nTask Master's **tagged task lists system** provides significant benefits for Git workflows:\n\n### **Multi-Context Development**\n- **Branch-Specific Tasks**: Each branch can have its own task context using tags\n- **Merge Conflict Prevention**: Tasks in different tags are completely isolated\n- **Context Switching**: Seamlessly switch between different development contexts\n- **Parallel Development**: Multiple team members can work on separate task contexts\n\n### **Migration and Compatibility**\n- **Seamless Migration**: Existing projects automatically migrate to use a \"master\" tag\n- **Zero Disruption**: All existing Git workflows continue unchanged\n- **Backward Compatibility**: Legacy projects work exactly as before\n\n### **Manual Git Integration**\n- **Manual Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Switching**: Explicitly switch tag contexts as needed for different branches\n- **Simplified Integration**: Focused on manual control rather than automatic workflows\n\n## **Workflow Overview**\n\n```mermaid\nflowchart TD\n    A[Start: On main branch] --> B[Pull latest changes]\n    B --> C[Create task branch<br/>git checkout -b task-XXX]\n    C --> D[Set task status: in-progress]\n    D --> E[Get task context & expand if needed<br/>Tasks automatically use current tag]\n    E --> F[Identify next subtask]\n    \n    F --> G[Set subtask: in-progress]\n    G --> H[Research & collect context<br/>update_subtask with findings]\n    H --> I[Implement subtask]\n    I --> J[Update subtask with completion]\n    J --> K[Set subtask: done]\n    K --> L[Git commit subtask]\n    \n    L --> M{More subtasks?}\n    M -->|Yes| F\n    M -->|No| N[Run final tests]\n    \n    N --> O[Commit tests if added]\n    O --> P[Push task branch]\n    P --> Q[Create Pull Request]\n    Q --> R[Human review & merge]\n    R --> S[Switch to main & pull]\n    S --> T[Delete task branch]\n    T --> U[Ready for next task]\n    \n    style A fill:#e1f5fe\n    style C fill:#f3e5f5\n    style G fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n    style R fill:#f1f8e9\n    style U fill:#e1f5fe\n```\n\n## **Complete Task Development Workflow**\n\n### **Phase 1: Task Preparation**\n```bash\n# 1. Ensure you're on main branch and pull latest\ngit checkout main\ngit pull origin main\n\n# 2. Check current branch status\ngit branch  # Verify you're on main\n\n# 3. Create task-specific branch\ngit checkout -b task-004  # For Task 4\n\n# 4. Set task status in Task Master (tasks automatically use current tag context)\n# Use: set_task_status tool or `task-master set-status --id=4 --status=in-progress`\n```\n\n### **Phase 2: Task Analysis & Planning**\n```bash\n# 5. Get task context and expand if needed (uses current tag automatically)\n# Use: get_task tool or `task-master show 4`\n# Use: expand_task tool or `task-master expand --id=4 --research --force` (if complex)\n\n# 6. Identify next subtask to work on\n# Use: next_task tool or `task-master next`\n```\n\n### **Phase 3: Subtask Implementation Loop**\nFor each subtask, follow this pattern:\n\n```bash\n# 7. Mark subtask as in-progress\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=in-progress`\n\n# 8. Gather context and research (if needed)\n# Use: update_subtask tool with research flag or:\n# `task-master update-subtask --id=4.1 --prompt=\"Research findings...\" --research`\n\n# 9. Collect code context through AI exploration\n# Document findings in subtask using update_subtask\n\n# 10. Implement the subtask\n# Write code, tests, documentation\n\n# 11. Update subtask with completion details\n# Use: update_subtask tool or:\n# `task-master update-subtask --id=4.1 --prompt=\"Implementation complete...\"`\n\n# 12. Mark subtask as done\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=done`\n\n# 13. Commit the subtask implementation\ngit add .\ngit commit -m \"feat(task-4): Complete subtask 4.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Any important notes\n\nSubtask 4.1: [Brief description of what was accomplished]\nRelates to Task 4: [Main task title]\"\n```\n\n### **Phase 4: Task Completion**\n```bash\n# 14. When all subtasks are complete, run final testing\n# Create test file if needed, ensure all tests pass\nnpm test  # or jest, or manual testing\n\n# 15. If tests were added/modified, commit them\ngit add .\ngit commit -m \"test(task-4): Add comprehensive tests for Task 4\n\n- Unit tests for core functionality\n- Integration tests for API endpoints\n- All tests passing\n\nTask 4: [Main task title] - Testing complete\"\n\n# 16. Push the task branch\ngit push origin task-004\n\n# 17. Create Pull Request\n# Title: \"Task 4: [Task Title]\"\n# Description should include:\n# - Task overview\n# - Subtasks completed\n# - Testing approach\n# - Any breaking changes or considerations\n```\n\n### **Phase 5: PR Merge & Cleanup**\n```bash\n# 18. Human reviews and merges PR into main\n\n# 19. Switch back to main and pull merged changes\ngit checkout main\ngit pull origin main\n\n# 20. Delete the feature branch (optional cleanup)\ngit branch -d task-004\ngit push origin --delete task-004\n```\n\n## **Commit Message Standards**\n\n### **Subtask Commits**\n```bash\n# ✅ DO: Consistent subtask commit format\ngit commit -m \"feat(task-4): Complete subtask 4.1 - Initialize Express server\n\n- Set up Express.js with TypeScript configuration\n- Added CORS and body parsing middleware\n- Implemented health check endpoints\n- Basic error handling middleware\n\nSubtask 4.1: Initialize project with npm and install dependencies\nRelates to Task 4: Setup Express.js Server Project\"\n\n# ❌ DON'T: Vague or inconsistent commits\ngit commit -m \"fixed stuff\"\ngit commit -m \"working on task\"\n```\n\n### **Test Commits**\n```bash\n# ✅ DO: Separate test commits when substantial\ngit commit -m \"test(task-4): Add comprehensive tests for Express server setup\n\n- Unit tests for middleware configuration\n- Integration tests for health check endpoints\n- Mock tests for database connection\n- All tests passing with 95% coverage\n\nTask 4: Setup Express.js Server Project - Testing complete\"\n```\n\n### **Commit Type Prefixes**\n- `feat(task-X):` - New feature implementation\n- `fix(task-X):` - Bug fixes\n- `test(task-X):` - Test additions/modifications\n- `docs(task-X):` - Documentation updates\n- `refactor(task-X):` - Code refactoring\n- `chore(task-X):` - Build/tooling changes\n\n## **Task Master Commands Integration**\n\n### **Essential Commands for Git Workflow**\n```bash\n# Task management (uses current tag context automatically)\ntask-master show <id>           # Get task/subtask details\ntask-master next                # Find next task to work on\ntask-master set-status --id=<id> --status=<status>\ntask-master update-subtask --id=<id> --prompt=\"...\" --research\n\n# Task expansion (for complex tasks)\ntask-master expand --id=<id> --research --force\n\n# Progress tracking\ntask-master list                # View all tasks and status\ntask-master list --status=in-progress  # View active tasks\n```\n\n### **MCP Tool Equivalents**\nWhen using Cursor or other MCP-integrated tools:\n- `get_task` instead of `task-master show`\n- `next_task` instead of `task-master next`\n- `set_task_status` instead of `task-master set-status`\n- `update_subtask` instead of `task-master update-subtask`\n\n## **Branch Management Rules**\n\n### **Branch Protection**\n```bash\n# ✅ DO: Always work on task branches\ngit checkout -b task-005\n# Make changes\ngit commit -m \"...\"\ngit push origin task-005\n\n# ❌ DON'T: Commit directly to main\ngit checkout main\ngit commit -m \"...\"  # NEVER do this\n```\n\n### **Keeping Branches Updated**\n```bash\n# ✅ DO: Regularly sync with main (for long-running tasks)\ngit checkout task-005\ngit fetch origin\ngit rebase origin/main  # or merge if preferred\n\n# Resolve any conflicts and continue\n```\n\n## **Pull Request Guidelines**\n\n### **PR Title Format**\n```\nTask <ID>: <Task Title>\n\nExamples:\nTask 4: Setup Express.js Server Project\nTask 7: Implement User Authentication\nTask 12: Add Stripe Payment Integration\n```\n\n### **PR Description Template**\n```markdown\n## Task Overview\nBrief description of the main task objective.\n\n## Subtasks Completed\n- [x] 4.1: Initialize project with npm and install dependencies\n- [x] 4.2: Configure TypeScript, ESLint and Prettier  \n- [x] 4.3: Create basic Express app with middleware and health check route\n\n## Implementation Details\n- Key architectural decisions made\n- Important code changes\n- Any deviations from original plan\n\n## Testing\n- [ ] Unit tests added/updated\n- [ ] Integration tests passing\n- [ ] Manual testing completed\n\n## Breaking Changes\nList any breaking changes or migration requirements.\n\n## Related Tasks\nMention any dependent tasks or follow-up work needed.\n```\n\n## **Conflict Resolution**\n\n### **Task Conflicts with Tagged System**\n```bash\n# With tagged task lists, merge conflicts are significantly reduced:\n# 1. Different branches can use different tag contexts\n# 2. Tasks in separate tags are completely isolated\n# 3. Use Task Master's move functionality to reorganize if needed\n\n# Manual git integration available:\n# - Use `task-master add-tag --from-branch` to create tags from current branch\n# - Manually switch contexts with `task-master use-tag <name>`\n# - Simple, predictable workflow without automatic behavior\n```\n\n### **Code Conflicts**\n```bash\n# Standard Git conflict resolution\ngit fetch origin\ngit rebase origin/main\n# Resolve conflicts in files\ngit add .\ngit rebase --continue\n```\n\n## **Emergency Procedures**\n\n### **Hotfixes**\n```bash\n# For urgent production fixes:\ngit checkout main\ngit pull origin main\ngit checkout -b hotfix-urgent-issue\n\n# Make minimal fix\ngit commit -m \"hotfix: Fix critical production issue\n\n- Specific fix description\n- Minimal impact change\n- Requires immediate deployment\"\n\ngit push origin hotfix-urgent-issue\n# Create emergency PR for immediate review\n```\n\n### **Task Abandonment**\n```bash\n# If task needs to be abandoned or significantly changed:\n# 1. Update task status\ntask-master set-status --id=<id> --status=cancelled\n\n# 2. Clean up branch\ngit checkout main\ngit branch -D task-<id>\ngit push origin --delete task-<id>\n\n# 3. Document reasoning in task\ntask-master update-task --id=<id> --prompt=\"Task cancelled due to...\"\n```\n\n## **Tagged System Benefits for Git Workflows**\n\n### **Multi-Team Development**\n- **Isolated Contexts**: Different teams can work on separate tag contexts without conflicts\n- **Feature Branches**: Each feature branch can have its own task context\n- **Release Management**: Separate tags for different release versions or environments\n\n### **Merge Conflict Prevention**\n- **Context Separation**: Tasks in different tags don't interfere with each other\n- **Clean Merges**: Reduced likelihood of task-related merge conflicts\n- **Parallel Development**: Multiple developers can work simultaneously without task conflicts\n\n### **Manual Git Integration**\n- **Branch-Based Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Management**: Explicitly switch tag contexts as needed\n- **Predictable Workflow**: Simple, manual control without automatic behavior\n\n---\n\n**References:**\n- [Task Master Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Architecture Guidelines](mdc:.cursor/rules/architecture.mdc)\n- [Task Master Commands](mdc:.cursor/rules/taskmaster.mdc)\n",".cursor/rules/glossary.mdc":"---\ndescription: Glossary of other Cursor rules\nglobs: **/*\nalwaysApply: true\n---\n# Glossary of Task Master Cursor Rules\n\nThis file provides a quick reference to the purpose of each rule file located in the `.cursor/rules` directory.\n\n- **[`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)**: Describes the high-level architecture of the Task Master CLI application, including the new tagged task lists system.\n- **[`changeset.mdc`](mdc:.cursor/rules/changeset.mdc)**: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\n- **[`commands.mdc`](mdc:.cursor/rules/commands.mdc)**: Guidelines for implementing CLI commands using Commander.js.\n- **[`cursor_rules.mdc`](mdc:.cursor/rules/cursor_rules.mdc)**: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\n- **[`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc)**: Guidelines for managing task dependencies and relationships across tagged task contexts.\n- **[`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc)**: Guide for using Task Master to manage task-driven development workflows with tagged task lists support.\n- **[`glossary.mdc`](mdc:.cursor/rules/glossary.mdc)**: This file; provides a glossary of other Cursor rules.\n- **[`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)**: Guidelines for implementing and interacting with the Task Master MCP Server.\n- **[`new_features.mdc`](mdc:.cursor/rules/new_features.mdc)**: Guidelines for integrating new features into the Task Master CLI with tagged system considerations.\n- **[`self_improve.mdc`](mdc:.cursor/rules/self_improve.mdc)**: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\n- **[`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)**: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information.\n- **[`tasks.mdc`](mdc:.cursor/rules/tasks.mdc)**: Guidelines for implementing task management operations with tagged task lists system support.\n- **[`tests.mdc`](mdc:.cursor/rules/tests.mdc)**: Guidelines for implementing and maintaining tests for Task Master CLI.\n- **[`ui.mdc`](mdc:.cursor/rules/ui.mdc)**: Guidelines for implementing and maintaining user interface components.\n- **[`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)**: Guidelines for implementing utility functions including tagged task lists utilities.\n- **[`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc)**: Guidelines for integrating AI usage telemetry across Task Master.\n\n",".cursor/rules/hamster.mdc":"---\ndescription: Guidelines for implementing tasks imported from Hamster using Task Master CLI\nglobs: \"**/*\"\nalwaysApply: true\n---\n\n# Hamster Integration Workflow\n\nThis guide outlines the process for working with tasks imported from Hamster briefs using Task Master. When connected to a Hamster brief, follow these specific guidelines to ensure proper task management and workflow execution.\n\n## **Command Restrictions**\n\n### **Supported Commands**\n- **✅ DO**: Use only these Task Master CLI commands when working with Hamster briefs:\n  ```bash\n  tm list                      # List all tasks\n  tm show <sub/task id> --json # Show task details\n  tm set-status                # Update task status\n  tm auth refresh              # Refresh authentication token\n  tm context <brief url>       # Reconnect to Hamster brief context\n  ```\n\n### **Unsupported Commands**\n- **❌ DON'T**: Use MCP tools when connected with Hamster briefs - they are not yet up to date with Hamster integration\n- **❌ DON'T**: Use other Task Master CLI commands that haven't been verified to work with Hamster integration\n\n## **Task Workflow Process**\n\n### **Starting a Task**\n```bash\n# ✅ DO: Mark task and subtasks as in-progress when starting\ntm set-status -i 1,1.1 -s in-progress\n\n# Multiple tasks/subtasks can be marked at once using comma separation\ntm set-status -i 1,1.1,1.2,2 -s in-progress\n```\n\n### **Task Implementation Flow**\n1. **Read the Task**: Use `tm show <id> --json` to understand the task requirements (json used to save tokens, gets you same information)\n2. **Check for Subtasks**: If the task has subtasks, implement them one at a time\n3. **Implement Subtask**: Complete the subtask implementation\n4. **Verify Quality**: Run lint and typecheck before marking as done\n   ```bash\n   npm lint\n   npm typecheck\n   ```\n5. **Mark Complete**: If verification passes, mark the subtask as done\n   ```bash\n   tm set-status -i 1.1 -s done\n   ```\n6. **Commit Changes**: Commit the completed subtask work\n7. **Repeat**: Continue until all subtasks are complete\n\n### **Parent Task Completion**\n- After all subtasks are done, run final verification:\n  ```bash\n  npm lint\n  npm typecheck\n  ```\n- Mark the parent task as done:\n  ```bash\n  tm set-status -i 1 -s done\n  ```\n- Move to the next task and repeat the process\n\n## **Multiple Task Context**\n\n### **Viewing Multiple Tasks**\n```bash\n# ✅ DO: Use comma-separated IDs to get context from multiple tasks\ntm show 1,1.1,2,2.1 --json\n\n# This is more efficient than calling tm show multiple times\n```\n\n### **Parallel Subtask Execution**\n- **When to Parallelize**: If a task has subtasks that can be completed in parallel\n- **Requirements**:\n  - Ensure work/files to adjust are **not the same** across subtasks\n  - Spawn sub-agents for each parallel subtask\n  - Verify clear separation of work before parallelizing\n- **Example**: If subtask 1.1 modifies `src/api.js` and subtask 1.2 modifies `src/utils.js`, these can run in parallel\n\n## **Pull Request Management**\n\n### **PR Creation Strategy**\n- **Preferred Approach**: Keep everything in one PR if scope remains manageable\n- **When to Split**: Create separate PRs if the work becomes too large\n- **Multi-PR Strategy**: If splitting is necessary:\n  - Create PRs that build on top of previous ones\n  - **Always confirm with the human** before creating multiple PRs\n- **PR Creation**: Use GitHub CLI after completing a task:\n  ```bash\n  gh pr create --title \"Task X: [Task Title]\" --body \"Description\"\n  ```\n\n### **Committing to PRs**\n- Keep committing to the same PR as long as the scope is maintained\n- An entire task list (brief) might fit into a single PR\n- If scope grows too large, discuss with human before creating new PRs\n\n## **Authentication & Context Management**\n\n### **Token Refresh**\n```bash\n# ✅ DO: Refresh token if JWT seems expired or commands don't work\ntm auth refresh\n\n# If refresh doesn't work, reconnect context\ntm context <brief url>\n```\n\n### **Context Reconnection**\n- **When Needed**: If commands stop working or authentication fails\n- **Required Information**: Brief URL (ask user if not available)\n- **Best Practice**: Store brief URL at the beginning of the session\n- **Command**: `tm context <brief url>`\n\n## **Integration with Git Workflow**\n\nWhen working with Hamster briefs, follow the standard Git workflow patterns outlined in [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc):\n\n- Create task-specific branches: `task-XXX`\n- Commit subtask work incrementally\n- Create PRs after task completion\n- Follow commit message standards\n\n## **Workflow Summary**\n\n```mermaid\nflowchart TD\n    A[Start: Connect to Hamster Brief] --> B[Get Brief URL]\n    B --> C[tm list - View Tasks]\n    C --> D[Select Task]\n    D --> E[tm show <id> --json - Read Task]\n    E --> F{Has Subtasks?}\n    F -->|Yes| G[Select First Subtask]\n    F -->|No| M[Implement Task]\n    G --> H[tm set-status -i X.Y -s in-progress]\n    H --> I[Implement Subtask]\n    I --> J[npm lint && npm typecheck]\n    J --> K{Passes?}\n    K -->|Yes| L[tm set-status -i X.Y -s done]\n    K -->|No| I\n    L --> N{More Subtasks?}\n    N -->|Yes| G\n    N -->|No| O[Final lint/typecheck]\n    M --> O\n    O --> P[tm set-status -i X -s done]\n    P --> Q[Commit & Create PR]\n    Q --> R{More Tasks?}\n    R -->|Yes| D\n    R -->|No| S[Complete]\n    \n    style A fill:#e1f5fe\n    style H fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n```\n\n## **Key Principles**\n\n- **Incremental Progress**: Work through subtasks one at a time\n- **Quality Gates**: Always run lint and typecheck before marking tasks as done\n- **Clear Communication**: Confirm with human before splitting work across multiple PRs\n- **Efficient Context Gathering**: Use comma-separated IDs when viewing multiple tasks\n- **Authentication Management**: Proactively refresh tokens and reconnect context when needed\n\n## **Related Rules**\n\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - Standard Git branching and PR practices\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - General Task Master development patterns\n- [Task Management](mdc:.cursor/rules/tasks.mdc) - Task structure and operations\n",".cursor/rules/mcp.mdc":"---\ndescription: Guidelines for implementing and interacting with the Task Master MCP Server\nglobs: mcp-server/src/**/*, scripts/modules/**/*\nalwaysApply: false\n---\n# Task Master MCP Server Guidelines\n\nThis document outlines the architecture and implementation patterns for the Task Master Model Context Protocol (MCP) server, designed for integration with tools like Cursor.\n\n## Architecture Overview (See also: [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc))\n\nThe MCP server acts as a bridge between external tools (like Cursor) and the core Task Master CLI logic. It leverages FastMCP for the server framework.\n\n- **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/direct-functions/*.js`, exported via `task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`)\n- **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation.\n\n## Direct Function Implementation Best Practices\n\nWhen implementing a new direct function in `mcp-server/src/core/direct-functions/`, follow these critical guidelines:\n\n1. **Verify Function Dependencies**:\n   - ✅ **DO**: Check that all helper functions your direct function needs are properly exported from their source modules\n   - ✅ **DO**: Import these dependencies explicitly at the top of your file\n   - ❌ **DON'T**: Assume helper functions like `findTaskById` or `taskExists` are automatically available\n   - **Example**:\n     ```javascript\n     // At top of direct-function file\n     import { removeTask, findTaskById, taskExists } from '../../../../scripts/modules/task-manager.js';\n     ```\n\n2. **Parameter Verification and Completeness**:\n   - ✅ **DO**: Verify the signature of core functions you're calling and ensure all required parameters are provided\n   - ✅ **DO**: Pass explicit values for required parameters rather than relying on defaults\n   - ✅ **DO**: Double-check parameter order against function definition\n   - ❌ **DON'T**: Omit parameters assuming they have default values\n   - **Example**:\n     ```javascript\n     // Correct parameter handling in direct function\n     async function generateTaskFilesDirect(args, log) {\n       const tasksPath = findTasksJsonPath(args, log);\n       const outputDir = args.output || path.dirname(tasksPath);\n       \n       try {\n         // Pass all required parameters\n         const result = await generateTaskFiles(tasksPath, outputDir);\n         return { success: true, data: result, fromCache: false };\n       } catch (error) {\n         // Error handling...\n       }\n     }\n     ```\n\n3. **Consistent File Path Handling**:\n   - ✅ **DO**: Use `path.join()` instead of string concatenation for file paths\n   - ✅ **DO**: Follow established file naming conventions (`task_001.txt` not `1.md`)\n   - ✅ **DO**: Use `path.dirname()` and other path utilities for manipulating paths\n   - ✅ **DO**: When paths relate to task files, follow the standard format: `task_${id.toString().padStart(3, '0')}.txt`\n   - ❌ **DON'T**: Create custom file path handling logic that diverges from established patterns\n   - **Example**:\n     ```javascript\n     // Correct file path handling\n     const taskFilePath = path.join(\n       path.dirname(tasksPath),\n       `task_${taskId.toString().padStart(3, '0')}.txt`\n     );\n     ```\n\n4. **Comprehensive Error Handling**:\n   - ✅ **DO**: Wrap core function calls *and AI calls* in try/catch blocks\n   - ✅ **DO**: Log errors with appropriate severity and context\n   - ✅ **DO**: Return standardized error objects with code and message (`{ success: false, error: { code: '...', message: '...' } }`)\n   - ✅ **DO**: Handle file system errors, AI client errors, AI processing errors, and core function errors distinctly with appropriate codes.\n   - **Example**:\n     ```javascript\n     try {\n       // Core function call or AI logic\n     } catch (error) {\n       log.error(`Failed to execute direct function logic: ${error.message}`);\n       return {\n         success: false,\n         error: {\n           code: error.code || 'DIRECT_FUNCTION_ERROR', // Use specific codes like AI_CLIENT_ERROR, etc.\n           message: error.message,\n           details: error.stack // Optional: Include stack in debug mode\n         },\n         fromCache: false // Ensure this is included if applicable\n       };\n     }\n     ```\n\n5. **Handling Logging Context (`mcpLog`)**:\n   - **Requirement**: Core functions (like those in `task-manager.js`) may accept an `options` object containing an optional `mcpLog` property. If provided, the core function expects this object to have methods like `mcpLog.info(...)`, `mcpLog.error(...)`.\n   - **Solution: The Logger Wrapper Pattern**: When calling a core function from a direct function, pass the `log` object provided by FastMCP *wrapped* in the standard `logWrapper` object. This ensures the core function receives a logger with the expected method structure.\n     ```javascript\n     // Standard logWrapper pattern within a Direct Function\n     const logWrapper = {\n       info: (message, ...args) => log.info(message, ...args),\n       warn: (message, ...args) => log.warn(message, ...args),\n       error: (message, ...args) => log.error(message, ...args),\n       debug: (message, ...args) => log.debug && log.debug(message, ...args),\n       success: (message, ...args) => log.info(message, ...args)\n     };\n\n     // ... later when calling the core function ...\n     await coreFunction(\n       // ... other arguments ...\n       { \n         mcpLog: logWrapper, // Pass the wrapper object\n         session // Also pass session if needed by core logic or AI service\n       },\n       'json' // Pass 'json' output format if supported by core function\n     );\n     ```\n   - **JSON Output**: Passing `mcpLog` (via the wrapper) often triggers the core function to use a JSON-friendly output format, suppressing spinners/boxes.\n   - ✅ **DO**: Implement this pattern in direct functions calling core functions that might use `mcpLog`.\n\n6. **Silent Mode Implementation**:\n    - ✅ **DO**: Import silent mode utilities: `import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';`\n    - ✅ **DO**: Wrap core function calls *within direct functions* using `enableSilentMode()` / `disableSilentMode()` in a `try/finally` block if the core function might produce console output (spinners, boxes, direct `console.log`) that isn't reliably controlled by passing `{ mcpLog }` or an `outputFormat` parameter.\n    - ✅ **DO**: Always disable silent mode in the `finally` block.\n    - ❌ **DON'T**: Wrap calls to the unified AI service (`generateTextService`, `generateObjectService`) in silent mode; their logging is handled internally.\n    - **Example (Direct Function Guaranteeing Silence & using Log Wrapper)**:\n      ```javascript\n      export async function coreWrapperDirect(args, log, context = {}) {\n        const { session } = context;\n        const tasksPath = findTasksJsonPath(args, log);\n        const logWrapper = { /* ... */ };\n\n        enableSilentMode(); // Ensure silence for direct console output\n        try {\n          const result = await coreFunction(\n             tasksPath,\n             args.param1,\n             { mcpLog: logWrapper, session }, // Pass context\n             'json' // Request JSON format if supported\n          );\n          return { success: true, data: result };\n        } catch (error) {\n           log.error(`Error: ${error.message}`);\n           return { success: false, error: { /* ... */ } };\n        } finally {\n           disableSilentMode(); // Critical: Always disable in finally\n        }\n      }\n      ```\n\n7. **Debugging MCP/Core Logic Interaction**:\n    - ✅ **DO**: If an MCP tool fails with unclear errors (like JSON parsing failures), run the equivalent `task-master` CLI command in the terminal. The CLI often provides more detailed error messages originating from the core logic (e.g., `ReferenceError`, stack traces) that are obscured by the MCP layer.\n\n## Tool Definition and Execution\n\n### Tool Structure\n\nMCP tools must follow a specific structure to properly interact with the FastMCP framework:\n\n```javascript\nserver.addTool({\n  name: \"tool_name\",  // Use snake_case for tool names\n  description: \"Description of what the tool does\",\n  parameters: z.object({\n    // Define parameters using Zod\n    param1: z.string().describe(\"Parameter description\"),\n    param2: z.number().optional().describe(\"Optional parameter description\"),\n    // IMPORTANT: For file operations, always include these optional parameters\n    file: z.string().optional().describe(\"Path to the tasks file\"),\n    projectRoot: z.string().optional().describe(\"Root directory of the project (typically derived from session)\")\n  }),\n\n  // The execute function is the core of the tool implementation\n  execute: async (args, context) => {\n    // Implementation goes here\n    // Return response in the appropriate format\n  }\n});\n```\n\n### Execute Function Signature\n\nThe `execute` function receives validated arguments and the FastMCP context:\n\n```javascript\n// Destructured signature (recommended)\nexecute: async (args, { log, session }) => {\n  // Tool implementation\n}\n```\n\n- **args**: Validated parameters.\n- **context**: Contains `{ log, session }` from FastMCP. (Removed `reportProgress`).\n\n### Standard Tool Execution Pattern with Path Normalization (Updated)\n\nTo ensure consistent handling of project paths across different client environments (Windows, macOS, Linux, WSL) and input formats (e.g., `file:///...`, URI encoded paths), all MCP tool `execute` methods that require access to the project root **MUST** be wrapped with the `withNormalizedProjectRoot` Higher-Order Function (HOF).\n\nThis HOF, defined in [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js), performs the following before calling the tool's core logic:\n\n1.  **Determines the Raw Root:** It prioritizes `args.projectRoot` if provided by the client, otherwise it calls `getRawProjectRootFromSession` to extract the path from the session.\n2.  **Normalizes the Path:** It uses the `normalizeProjectRoot` helper to decode URIs, strip `file://` prefixes, fix potential Windows drive letter prefixes (e.g., `/C:/`), convert backslashes (`\\`) to forward slashes (`/`), and resolve the path to an absolute path suitable for the server's OS.\n3.  **Injects Normalized Path:** It updates the `args` object by replacing the original `projectRoot` (or adding it) with the normalized, absolute path.\n4.  **Executes Original Logic:** It calls the original `execute` function body, passing the updated `args` object.\n\n**Implementation Example:**\n\n```javascript\n// In mcp-server/src/tools/your-tool.js\nimport {\n    handleApiResult,\n    createErrorResponse,\n    withNormalizedProjectRoot // <<< Import HOF\n} from './utils.js';\nimport { yourDirectFunction } from '../core/task-master-core.js';\nimport { findTasksJsonPath } from '../core/utils/path-utils.js'; // If needed\n\nexport function registerYourTool(server) {\n    server.addTool({\n        name: \"your_tool\",\n        description: \"...\".\n        parameters: z.object({\n            // ... other parameters ...\n            projectRoot: z.string().optional().describe('...') // projectRoot is optional here, HOF handles fallback\n        }),\n        // Wrap the entire execute function\n        execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n            // args.projectRoot is now guaranteed to be normalized and absolute\n            const { /* other args */, projectRoot } = args;\n\n            try {\n                log.info(`Executing your_tool with normalized root: ${projectRoot}`);\n\n                // Resolve paths using the normalized projectRoot\n                let tasksPath = findTasksJsonPath({ projectRoot, file: args.file }, log);\n\n                // Call direct function, passing normalized projectRoot if needed by direct func\n                const result = await yourDirectFunction(\n                    {\n                        /* other args */,\n                        projectRoot // Pass it if direct function needs it\n                    },\n                    log,\n                    { session }\n                );\n\n                return handleApiResult(result, log);\n            } catch (error) {\n                log.error(`Error in your_tool: ${error.message}`);\n                return createErrorResponse(error.message);\n            }\n        }) // End HOF wrap\n    });\n}\n```\n\nBy using this HOF, the core logic within the `execute` method and any downstream functions (like `findTasksJsonPath` or direct functions) can reliably expect `args.projectRoot` to be a clean, absolute path suitable for the server environment.\n\n### Project Initialization Tool\n\nThe `initialize_project` tool allows integrated clients like Cursor to set up a new Task Master project:\n\n```javascript\n// In initialize-project.js\nimport { z } from \"zod\";\nimport { initializeProjectDirect } from \"../core/task-master-core.js\";\nimport { handleApiResult, createErrorResponse } from \"./utils.js\";\n\nexport function registerInitializeProjectTool(server) {\n  server.addTool({\n    name: \"initialize_project\",\n    description: \"Initialize a new Task Master project\",\n    parameters: z.object({\n      projectName: z.string().optional().describe(\"The name for the new project\"),\n      projectDescription: z.string().optional().describe(\"A brief description\"),\n      projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n      authorName: z.string().optional().describe(\"The author's name\"),\n      skipInstall: z.boolean().optional().describe(\"Skip installing dependencies\"),\n      addAliases: z.boolean().optional().describe(\"Add shell aliases\"),\n      yes: z.boolean().optional().describe(\"Skip prompts and use defaults\")\n    }),\n    execute: async (args, { log, reportProgress }) => {\n      try {\n        // Since we're initializing, we don't need project root\n        const result = await initializeProjectDirect(args, log);\n        return handleApiResult(result, log, 'Error initializing project');\n      } catch (error) {\n        log.error(`Error in initialize_project: ${error.message}`);\n        return createErrorResponse(`Failed to initialize project: ${error.message}`);\n      }\n    }\n  });\n}\n```\n\n### Logging Convention\n\nThe `log` object (destructured from `context`) provides standardized logging methods. Use it within both the `execute` method and the `*Direct` functions. **If progress indication is needed within a direct function, use `log.info()` instead of `reportProgress`**.\n\n```javascript\n// Proper logging usage\nlog.info(`Starting ${toolName} with parameters: ${JSON.stringify(sanitizedArgs)}`);\nlog.debug(\"Detailed operation info\", { data });\nlog.warn(\"Potential issue detected\");\nlog.error(`Error occurred: ${error.message}`, { stack: error.stack });\nlog.info('Progress: 50% - AI call initiated...'); // Example progress logging\n```\n\n## Session Usage Convention\n\nThe `session` object (destructured from `context`) contains authenticated session data and client information.\n\n- **Authentication**: Access user-specific data (`session.userId`, etc.) if authentication is implemented.\n- **Project Root**: The primary use in Task Master is accessing `session.roots` to determine the client's project root directory via the `getProjectRootFromSession` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)). See the Standard Tool Execution Pattern above.\n- **Environment Variables**: The `session.env` object provides access to environment variables set in the MCP client configuration (e.g., `.cursor/mcp.json`). This is the **primary mechanism** for the unified AI service layer (`ai-services-unified.js`) to securely access **API keys** when called from MCP context.\n- **Capabilities**: Can be used to check client capabilities (`session.clientCapabilities`).\n\n## Direct Function Wrappers (`*Direct`)\n\nThese functions, located in `mcp-server/src/core/direct-functions/`, form the core logic execution layer for MCP tools.\n\n- **Purpose**: Bridge MCP tools and core Task Master modules (`scripts/modules/*`). Handle AI interactions if applicable.\n- **Responsibilities**:\n  - Receive `args` (including `projectRoot`), `log`, and optionally `{ session }` context.\n  - Find `tasks.json` using `findTasksJsonPath`.\n  - Validate arguments.\n  - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n  - **Call Core Logic**: Invoke function from `scripts/modules/*`.\n    - Pass `outputFormat: 'json'` if applicable.\n    - Wrap with `enableSilentMode/disableSilentMode` if needed.\n    - Pass `{ mcpLog: logWrapper, session }` context if core logic needs it.\n  - Handle errors.\n  - Return standardized result object.\n  - ❌ **DON'T**: Call `reportProgress`.\n  - ❌ **DON'T**: Initialize AI clients or call AI services directly.\n\n## Key Principles\n\n- **Prefer Direct Function Calls**: MCP tools should always call `*Direct` wrappers instead of `executeTaskMasterCommand`.\n- **Standardized Execution Flow**: Follow the pattern: MCP Tool -> `getProjectRootFromSession` -> `*Direct` Function -> Core Logic / AI Logic.\n- **Path Resolution via Direct Functions**: The `*Direct` function is responsible for finding the exact `tasks.json` path using `findTasksJsonPath`, relying on the `projectRoot` passed in `args`.\n- **AI Logic in Core Modules**: AI interactions (prompt building, calling unified service) reside within the core logic functions (`scripts/modules/*`), not direct functions.\n- **Silent Mode in Direct Functions**: Wrap *core function* calls (from `scripts/modules`) with `enableSilentMode()` and `disableSilentMode()` if they produce console output not handled by `outputFormat`. Do not wrap AI calls.\n- **Selective Async Processing**: Use `AsyncOperationManager` in the *MCP Tool layer* for operations involving multiple steps or long waits beyond a single AI call (e.g., file processing + AI call + file writing). Simple AI calls handled entirely within the `*Direct` function (like `addTaskDirect`) may not need it at the tool layer.\n- **No `reportProgress` in Direct Functions**: Do not pass or use `reportProgress` within `*Direct` functions. Use `log.info()` for internal progress or report progress from the `AsyncOperationManager` callback in the MCP tool layer.\n- **Output Formatting**: Ensure core functions called by `*Direct` functions can suppress CLI output, ideally via an `outputFormat` parameter.\n- **Project Initialization**: Use the initialize_project tool for setting up new projects in integrated environments.\n- **Centralized Utilities**: Use helpers from `mcp-server/src/tools/utils.js`, `mcp-server/src/core/utils/path-utils.js`, and `mcp-server/src/core/utils/ai-client-utils.js`. See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).\n- **Caching in Direct Functions**: Caching logic resides *within* the `*Direct` functions using `getCachedOrExecute`.\n\n## Resources and Resource Templates\n\nResources provide LLMs with static or dynamic data without executing tools.\n\n- **Implementation**: Use `@mcp.resource()` decorator pattern or `server.addResource`/`server.addResourceTemplate` in `mcp-server/src/core/resources/`.\n- **Registration**: Register resources during server initialization in [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js).\n- **Best Practices**: Organize resources, validate parameters, use consistent URIs, handle errors. See [`fastmcp-core.txt`](docs/fastmcp-core.txt) for underlying SDK details.\n\n*(Self-correction: Removed detailed Resource implementation examples as they were less relevant to the current user focus on tool execution flow and project roots. Kept the overview.)*\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`. Ensure the core function can suppress console output (e.g., via an `outputFormat` parameter).\n\n2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, `findTasksJsonPath`, silent mode utilities, and potentially AI client/prompt utilities.\n    - Implement `async function yourCommandDirect(args, log, context = {})` using **camelCase** with `Direct` suffix. **Remember `context` should only contain `{ session }` if needed (for AI keys/config).**\n        - **Path Resolution**: Obtain `tasksPath` using `findTasksJsonPath(args, log)`.\n        - Parse other `args` and perform necessary validation.\n        - **Handle AI (if applicable)**: Initialize clients using `get*ClientForMCP(session, log)`, build prompts, call AI, parse response. Handle AI-specific errors.\n        - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n        - **Call Core Logic**:\n            - Wrap with `enableSilentMode/disableSilentMode` if necessary.\n            - Pass `outputFormat: 'json'` (or similar) if applicable.\n            - Handle errors from the core function.\n        - Format the return as `{ success: true/false, data/error, fromCache?: boolean }`.\n        - ❌ **DON'T**: Call `reportProgress`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, `createErrorResponse`, `getProjectRootFromSession`, and your `yourCommandDirect` function. Import `AsyncOperationManager` if needed.\n    - Implement `registerYourCommandTool(server)`.\n    - Define the tool `name` using **snake_case** (e.g., `your_command`).\n    - Define the `parameters` using `zod`. Include `projectRoot: z.string().optional()`.\n    - Implement the `async execute(args, { log, session })` method (omitting `reportProgress` from destructuring).\n        - Get `rootFolder` using `getProjectRootFromSession(session, log)`.\n        - **Determine Execution Strategy**:\n            - **If using `AsyncOperationManager`**: Create the operation, call the `*Direct` function from within the async task callback (passing `log` and `{ session }`), report progress *from the callback*, and return the initial `ACCEPTED` response.\n            - **If calling `*Direct` function synchronously** (like `add-task`): Call `await yourCommandDirect({ ...args, projectRoot }, log, { session });`. Handle the result with `handleApiResult`.\n        - ❌ **DON'T**: Pass `reportProgress` down to the direct function in either case.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Handling Responses\n\n- MCP tools should return the object generated by `handleApiResult`.\n- `handleApiResult` uses `createContentResponse` or `createErrorResponse` internally.\n- `handleApiResult` also uses `processMCPResponseData` by default to filter potentially large fields (`details`, `testStrategy`) from task data. Provide a custom processor function to `handleApiResult` if different filtering is needed.\n- The final JSON response sent to the MCP client will include the `fromCache` boolean flag (obtained from the `*Direct` function's result) alongside the actual data (e.g., `{ \"fromCache\": true, \"data\": { ... } }` or `{ \"fromCache\": false, \"data\": { ... } }`).\n\n## Parameter Type Handling\n\n- **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n- **Standard Tool Execution Pattern**:\n    - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should:\n        1.  Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger.\n        2.  Receive the result object (typically `{ success, data/error, fromCache }`).\n        3.  Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized response formatting and error handling.\n        4.  Return the formatted response object provided by `handleApiResult`.\n- **CLI Execution as Fallback**: The `executeTaskMasterCommand` utility in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) allows executing commands via the CLI (`task-master ...`). This should **only** be used as a fallback if a direct function wrapper is not yet implemented or if a specific command intrinsically requires CLI execution.\n- **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n    - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently.\n    - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation:\n        - `getProjectRoot`: Normalizes project paths.\n        - `handleApiResult`: Takes the raw result from a `*Direct` function and formats it into a standard MCP success or error response, automatically handling data processing via `processMCPResponseData`. This is called by the tool's `execute` method.\n        - `createContentResponse`/`createErrorResponse`: Used by `handleApiResult` to format successful/error MCP responses.\n        - `processMCPResponseData`: Filters/cleans data (e.g., removing `details`, `testStrategy`) before it's sent in the MCP response. Called by `handleApiResult`.\n        - `getCachedOrExecute`: **Used inside `*Direct` functions** in `task-master-core.js` to implement caching logic.\n        - `executeTaskMasterCommand`: Fallback for executing CLI commands.\n- **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented.\n    - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) using the `getCachedOrExecute` utility from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    - Generate unique cache keys based on function arguments that define a distinct call (e.g., file path, filters).\n    - The `getCachedOrExecute` utility handles checking the cache, executing the core logic function on a cache miss, storing the result, and returning the data along with a `fromCache` flag.\n    - Cache statistics can be monitored using the `cacheStats` MCP tool (implemented via `getCacheStatsDirect`).\n    - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data.\n\n**MCP Tool Implementation Checklist**:\n\n1. **Core Logic Verification**:\n   - [ ] Confirm the core function is properly exported from its module (e.g., `task-manager.js`)\n   - [ ] Identify all required parameters and their types\n\n2. **Direct Function Wrapper**:\n   - [ ] Create the `*Direct` function in the appropriate file in `mcp-server/src/core/direct-functions/`\n   - [ ] Import silent mode utilities and implement them around core function calls\n   - [ ] Handle all parameter validations and type conversions\n   - [ ] Implement path resolving for relative paths\n   - [ ] Add appropriate error handling with standardized error codes\n   - [ ] Add to imports/exports in `task-master-core.js`\n\n3. **MCP Tool Implementation**:\n   - [ ] Create new file in `mcp-server/src/tools/` with kebab-case naming\n   - [ ] Define zod schema for all parameters\n   - [ ] Implement the `execute` method following the standard pattern\n   - [ ] Consider using AsyncOperationManager for long-running operations\n   - [ ] Register tool in `mcp-server/src/tools/index.js`\n\n4. **Testing**:\n   - [ ] Write unit tests for the direct function wrapper\n   - [ ] Write integration tests for the MCP tool\n\n## Standard Error Codes\n\n- **Standard Error Codes**: Use consistent error codes across direct function wrappers\n  - `INPUT_VALIDATION_ERROR`: For missing or invalid required parameters\n  - `FILE_NOT_FOUND_ERROR`: For file system path issues\n  - `CORE_FUNCTION_ERROR`: For errors thrown by the core function\n  - `UNEXPECTED_ERROR`: For all other unexpected errors\n\n- **Error Object Structure**:\n  ```javascript\n  {\n    success: false,\n    error: {\n      code: 'ERROR_CODE',\n      message: 'Human-readable error message'\n    },\n    fromCache: false\n  }\n  ```\n\n- **MCP Tool Logging Pattern**:\n  - ✅ DO: Log the start of execution with arguments (sanitized if sensitive)\n  - ✅ DO: Log successful completion with result summary\n  - ✅ DO: Log all error conditions with appropriate log levels\n  - ✅ DO: Include the cache status in result logs\n  - ❌ DON'T: Log entire large data structures or sensitive information\n\n- The MCP server integrates with Task Master core functions through three layers:\n  1. Tool Definitions (`mcp-server/src/tools/*.js`) - Define parameters and validation\n  2. Direct Functions (`mcp-server/src/core/direct-functions/*.js`) - Handle core logic integration\n  3. Core Functions (`scripts/modules/*.js`) - Implement the actual functionality\n\n- This layered approach provides:\n  - Clear separation of concerns\n  - Consistent parameter validation\n  - Centralized error handling\n  - Performance optimization through caching (for read operations)\n  - Standardized response formatting\n\n## MCP Naming Conventions\n\n- **Files and Directories**:\n  - ✅ DO: Use **kebab-case** for all file names: `list-tasks.js`, `set-task-status.js`\n  - ✅ DO: Use consistent directory structure: `mcp-server/src/tools/` for tool definitions, `mcp-server/src/core/direct-functions/` for direct function implementations\n\n- **JavaScript Functions**:\n  - ✅ DO: Use **camelCase** with `Direct` suffix for direct function implementations: `listTasksDirect`, `setTaskStatusDirect`\n  - ✅ DO: Use **camelCase** with `Tool` suffix for tool registration functions: `registerListTasksTool`, `registerSetTaskStatusTool`\n  - ✅ DO: Use consistent action function naming inside direct functions: `coreActionFn` or similar descriptive name\n\n- **MCP Tool Names**:\n  - ✅ DO: Use **snake_case** for tool names exposed to MCP clients: `list_tasks`, `set_task_status`, `parse_prd_document`\n  - ✅ DO: Include the core action in the tool name without redundant words: Use `list_tasks` instead of `list_all_tasks`\n\n- **Examples**:\n  - File: `list-tasks.js` \n  - Direct Function: `listTasksDirect`\n  - Tool Registration: `registerListTasksTool`\n  - MCP Tool Name: `list_tasks`\n\n- **Mapping**:\n  - The `directFunctions` map in `task-master-core.js` maps the core function name (in camelCase) to its direct implementation:\n    ```javascript\n    export const directFunctions = {\n      list: listTasksDirect,\n      setStatus: setTaskStatusDirect,\n      // Add more functions as implemented\n    };\n    ```\n\n## Telemetry Integration\n\n- Direct functions calling core logic that involves AI should receive and pass through `telemetryData` within their successful `data` payload. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the standard pattern.\n- MCP tools use `handleApiResult`, which ensures the `data` object (potentially including `telemetryData`) from the direct function is correctly included in the final response.\n",".cursor/rules/new_features.mdc":"---\ndescription: Guidelines for integrating new features into the Task Master CLI\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Task Master Feature Integration Guidelines\n\n## Feature Placement Decision Process\n\n- **Identify Feature Type** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module details):\n  - **Data Manipulation**: Features that create, read, update, or delete tasks belong in [`task-manager.js`](mdc:scripts/modules/task-manager.js). Follow guidelines in [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc).\n  - **Dependency Management**: Features that handle task relationships belong in [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js). Follow guidelines in [`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc).\n  - **User Interface**: Features that display information to users belong in [`ui.js`](mdc:scripts/modules/ui.js). Follow guidelines in [`ui.mdc`](mdc:.cursor/rules/ui.mdc).\n  - **AI Integration**: Features that use AI models belong in [`ai-services.js`](mdc:scripts/modules/ai-services.js).\n  - **Cross-Cutting**: Features that don't fit one category may need components in multiple modules\n\n- **Command-Line Interface** (See [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n  - All new user-facing commands should be added to [`commands.js`](mdc:scripts/modules/commands.js)\n  - Use consistent patterns for option naming and help text\n  - Follow the Commander.js model for subcommand structure\n\n## Implementation Pattern\n\nThe standard pattern for adding a feature follows this workflow:\n\n1. **Core Logic**: Implement the business logic in the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2. **Context Gathering (If Applicable)**: \n   - For AI-powered commands that benefit from project context, use the standardized context gathering patterns from [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc).\n   - Import `ContextGatherer` and `FuzzyTaskSearch` utilities for reusable context extraction.\n   - Support multiple context types: tasks, files, custom text, project tree.\n   - Implement detailed token breakdown display for transparency.\n3. **AI Integration (If Applicable)**: \n   - Import necessary service functions (e.g., `generateTextService`, `streamTextService`) from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n   - Prepare parameters (`role`, `session`, `systemPrompt`, `prompt`).\n   - Call the service function.\n   - Handle the response (direct text or stream object).\n   - **Important**: Prefer `generateTextService` for calls sending large context (like stringified JSON) where incremental display is not needed. See [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc) for detailed usage patterns and cautions.\n4. **UI Components**: Add any display functions to [`ui.js`](mdc:scripts/modules/ui.js) following [`ui.mdc`](mdc:.cursor/rules/ui.mdc). Consider enhanced formatting with syntax highlighting for code blocks.\n5. **Command Integration**: Add the CLI command to [`commands.js`](mdc:scripts/modules/commands.js) following [`commands.mdc`](mdc:.cursor/rules/commands.mdc).\n6. **Testing**: Write tests for all components of the feature (following [`tests.mdc`](mdc:.cursor/rules/tests.mdc))\n7. **Configuration**: Update configuration settings or add new ones in [`config-manager.js`](mdc:scripts/modules/config-manager.js) and ensure getters/setters are appropriate. Update documentation in [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc). Update the `.taskmasterconfig` structure if needed.\n8. **Documentation**: Update help text and documentation in [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n\n## Critical Checklist for New Features\n\n- **Comprehensive Function Exports**:\n  - ✅ **DO**: Export **all core functions, helper functions (like `generateSubtaskPrompt`), and utility methods** needed by your new function or command from their respective modules.\n  - ✅ **DO**: **Explicitly review the module's `export { ... }` block** at the bottom of the file to ensure every required dependency (even seemingly minor helpers like `findTaskById`, `taskExists`, specific prompt generators, AI call handlers, etc.) is included.\n  - ❌ **DON'T**: Assume internal functions are already exported - **always verify**. A missing export will cause runtime errors (e.g., `ReferenceError: generateSubtaskPrompt is not defined`).\n  - **Example**: If implementing a feature that checks task existence, ensure the helper function is in exports:\n  ```javascript\n  // At the bottom of your module file:\n  export {\n    // ... existing exports ...\n    yourNewFunction,\n    taskExists,  // Helper function used by yourNewFunction\n    findTaskById, // Helper function used by yourNewFunction\n    generateSubtaskPrompt, // Helper needed by expand/add features\n    getSubtasksFromAI,     // Helper needed by expand/add features\n  };\n  ```\n\n- **Parameter Completeness and Matching**:\n  - ✅ **DO**: Pass all required parameters to functions you call within your implementation\n  - ✅ **DO**: Check function signatures before implementing calls to them\n  - ✅ **DO**: Verify that direct function parameters match their core function counterparts\n  - ✅ **DO**: When implementing a direct function for MCP, ensure it only accepts parameters that exist in the core function\n  - ✅ **DO**: Verify the expected *internal structure* of complex object parameters (like the `mcpLog` object, see mcp.mdc for the required logger wrapper pattern)\n  - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n  - ❌ **DON'T**: Assume default parameter values will handle missing arguments\n  - ❌ **DON'T**: Assume object parameters will work without verifying their required internal structure or methods.\n  - **Example**: When calling file generation, pass all required parameters:\n  ```javascript\n  // ✅ DO: Pass all required parameters\n  await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n  \n  // ❌ DON'T: Omit required parameters\n  await generateTaskFiles(tasksPath); // Error - missing outputDir parameter\n  ```\n  \n  **Example**: Properly match direct function parameters to core function:\n  ```javascript\n  // Core function signature\n  async function expandTask(tasksPath, taskId, numSubtasks, useResearch = false, additionalContext = '', options = {}) {\n    // Implementation...\n  }\n  \n  // ✅ DO: Match direct function parameters to core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // Extract only parameters that exist in the core function\n    const taskId = parseInt(args.id, 10);\n    const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n    const useResearch = args.research === true;\n    const additionalContext = args.prompt || '';\n    \n    // Call core function with matched parameters\n    const result = await expandTask(\n      tasksPath,\n      taskId,\n      numSubtasks,\n      useResearch,\n      additionalContext,\n      { mcpLog: log, session: context.session }\n    );\n    \n    // Return result\n    return { success: true, data: result, fromCache: false };\n  }\n  \n  // ❌ DON'T: Use parameters that don't exist in the core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // DON'T extract parameters that don't exist in the core function!\n    const force = args.force === true; // ❌ WRONG - 'force' doesn't exist in core function\n    \n    // DON'T pass non-existent parameters to core functions\n    const result = await expandTask(\n      tasksPath,\n      args.id,\n      args.num,\n      args.research,\n      args.prompt,\n      force, // ❌ WRONG - this parameter doesn't exist in the core function\n      { mcpLog: log }\n    );\n  }\n  ```\n\n- **Consistent File Path Handling**:\n  - ✅ DO: Use consistent file naming conventions: `task_${id.toString().padStart(3, '0')}.txt`\n  - ✅ DO: Use `path.join()` for composing file paths\n  - ✅ DO: Use appropriate file extensions (.txt for tasks, .json for data)\n  - ❌ DON'T: Hardcode path separators or inconsistent file extensions\n  - **Example**: Creating file paths for tasks:\n  ```javascript\n  // ✅ DO: Use consistent file naming and path.join\n  const taskFileName = path.join(\n    path.dirname(tasksPath), \n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ❌ DON'T: Use inconsistent naming or string concatenation \n  const taskFileName = path.dirname(tasksPath) + '/' + taskId + '.md';\n  ```\n\n- **Error Handling and Reporting**:\n  - ✅ DO: Use structured error objects with code and message properties\n  - ✅ DO: Include clear error messages identifying the specific problem\n  - ✅ DO: Handle both function-specific errors and potential file system errors\n  - ✅ DO: Log errors at appropriate severity levels\n  - **Example**: Structured error handling in core functions:\n  ```javascript\n  try {\n    // Implementation...\n  } catch (error) {\n    log('error', `Error removing task: ${error.message}`);\n    throw {\n      code: 'REMOVE_TASK_ERROR',\n      message: error.message,\n      details: error.stack\n    };\n  }\n  ```\n\n- **Silent Mode Implementation**:\n  - ✅ **DO**: Import all silent mode utilities together:\n    ```javascript\n    import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n    ```\n  - ✅ **DO**: Always use `isSilentMode()` function to check global silent mode status, never reference global variables.\n  - ✅ **DO**: Wrap core function calls **within direct functions** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block if the core function might produce console output (like banners, spinners, direct `console.log`s) that isn't reliably controlled by an `outputFormat` parameter.\n    ```javascript\n    // Direct Function Example:\n    try {\n      // Prefer passing 'json' if the core function reliably handles it\n      const result = await coreFunction(...args, 'json'); \n      // OR, if outputFormat is not enough/unreliable:\n      // enableSilentMode(); // Enable *before* the call\n      // const result = await coreFunction(...args);\n      // disableSilentMode(); // Disable *after* the call (typically in finally)\n\n      return { success: true, data: result };\n    } catch (error) {\n       log.error(`Error: ${error.message}`);\n       return { success: false, error: { message: error.message } };\n    } finally {\n       // If you used enable/disable, ensure disable is called here\n       // disableSilentMode(); \n    }\n    ```\n  - ✅ **DO**: Core functions themselves *should* ideally check `outputFormat === 'text'` before displaying UI elements (banners, spinners, boxes) and use internal logging (`log`/`report`) that respects silent mode. The `enable/disableSilentMode` wrapper in the direct function is a safety net.\n  - ✅ **DO**: Handle mixed parameter/global silent mode correctly for functions accepting both (less common now, prefer `outputFormat`):\n    ```javascript\n    // Check both the passed parameter and global silent mode\n    const isSilent = silentMode || (typeof silentMode === 'undefined' && isSilentMode());\n    ```\n  - ❌ **DON'T**: Forget to disable silent mode in a `finally` block if you enabled it.\n  - ❌ **DON'T**: Access the global `silentMode` flag directly.\n\n- **Debugging Strategy**:\n  - ✅ **DO**: If an MCP tool fails with vague errors (e.g., JSON parsing issues like `Unexpected token ... is not valid JSON`), **try running the equivalent CLI command directly in the terminal** (e.g., `task-master expand --all`). CLI output often provides much more specific error messages (like missing function definitions or stack traces from the core logic) that pinpoint the root cause.\n  - ❌ **DON'T**: Rely solely on MCP logs if the error is unclear; use the CLI as a complementary debugging tool for core logic issues.\n\n- **Telemetry Integration**: Ensure AI calls correctly handle and propagate `telemetryData` as described in [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc).\n\n```javascript\n// 1. CORE LOGIC: Add function to appropriate module (example in task-manager.js)\n/**\n * Archives completed tasks to archive.json\n * @param {string} tasksPath - Path to the tasks.json file\n * @param {string} archivePath - Path to the archive.json file\n * @returns {number} Number of tasks archived\n */\nasync function archiveTasks(tasksPath, archivePath = 'tasks/archive.json') {\n  // Implementation...\n  return archivedCount;\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  archiveTasks,\n};\n```\n\n```javascript\n// 2. AI Integration: Add import and use necessary service functions\nimport { generateTextService } from './ai-services-unified.js';\n\n// Example usage:\nasync function handleAIInteraction() {\n  const role = 'user';\n  const session = 'exampleSession';\n  const systemPrompt = 'You are a helpful assistant.';\n  const prompt = 'What is the capital of France?';\n\n  const result = await generateTextService(role, session, systemPrompt, prompt);\n  console.log(result);\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  handleAIInteraction,\n};\n```\n\n```javascript\n// 3. UI COMPONENTS: Add display function to ui.js\n/**\n * Display archive operation results\n * @param {string} archivePath - Path to the archive file\n * @param {number} count - Number of tasks archived\n */\nfunction displayArchiveResults(archivePath, count) {\n  console.log(boxen(\n    chalk.green(`Successfully archived ${count} tasks to ${archivePath}`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round' }\n  ));\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  displayArchiveResults,\n};\n```\n\n```javascript\n// 4. COMMAND INTEGRATION: Add to commands.js\nimport { archiveTasks } from './task-manager.js';\nimport { displayArchiveResults } from './ui.js';\n\n// In registerCommands function\nprogramInstance\n  .command('archive')\n  .description('Archive completed tasks to separate file')\n  .option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <file>', 'Archive output file', 'tasks/archive.json')\n  .action(async (options) => {\n    const tasksPath = options.file;\n    const archivePath = options.output;\n    \n    console.log(chalk.blue(`Archiving completed tasks from ${tasksPath} to ${archivePath}...`));\n    \n    const archivedCount = await archiveTasks(tasksPath, archivePath);\n    displayArchiveResults(archivePath, archivedCount);\n  });\n```\n\n## Cross-Module Features\n\nFor features requiring components in multiple modules:\n\n- ✅ **DO**: Create a clear unidirectional flow of dependencies\n  ```javascript\n  // In task-manager.js\n  function analyzeTasksDifficulty(tasks) {\n    // Implementation...\n    return difficultyScores;\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasksDifficulty } from './task-manager.js';\n  \n  function displayDifficultyReport(tasks) {\n    const scores = analyzeTasksDifficulty(tasks);\n    // Render the scores...\n  }\n  ```\n\n- ❌ **DON'T**: Create circular dependencies between modules\n  ```javascript\n  // In task-manager.js - depends on ui.js\n  import { displayDifficultyReport } from './ui.js';\n  \n  function analyzeTasks() {\n    // Implementation...\n    displayDifficultyReport(tasks); // WRONG! Don't call UI functions from task-manager\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasks } from './task-manager.js';\n  ```\n\n## Command-Line Interface Standards\n\n- **Naming Conventions**:\n  - Use kebab-case for command names (`analyze-complexity`, not `analyzeComplexity`)\n  - Use kebab-case for option names (`--output-format`, not `--outputFormat`) \n  - Use the same option names across commands when they represent the same concept\n\n- **Command Structure**:\n  ```javascript\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-s, --short-option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n## Utility Function Guidelines\n\nWhen adding utilities to [`utils.js`](mdc:scripts/modules/utils.js):\n\n- Only add functions that could be used by multiple modules\n- Keep utilities single-purpose and purely functional\n- Document parameters and return values\n\n```javascript\n/**\n * Formats a duration in milliseconds to a human-readable string\n * @param {number} ms - Duration in milliseconds\n * @returns {string} Formatted duration string (e.g., \"2h 30m 15s\")\n */\nfunction formatDuration(ms) {\n  // Implementation...\n  return formatted;\n}\n```\n\n## Writing Testable Code\n\nWhen implementing new features, follow these guidelines to ensure your code is testable:\n\n- **Dependency Injection**\n  - Design functions to accept dependencies as parameters\n  - Avoid hard-coded dependencies that are difficult to mock\n  ```javascript\n  // ✅ DO: Accept dependencies as parameters\n  function processTask(task, fileSystem, logger) {\n    fileSystem.writeFile('task.json', JSON.stringify(task));\n    logger.info('Task processed');\n  }\n  \n  // ❌ DON'T: Use hard-coded dependencies\n  function processTask(task) {\n    fs.writeFile('task.json', JSON.stringify(task));\n    console.log('Task processed');\n  }\n  ```\n\n- **Separate Logic from Side Effects**\n  - Keep pure logic separate from I/O operations or UI rendering\n  - This allows testing the logic without mocking complex dependencies\n  ```javascript\n  // ✅ DO: Separate logic from side effects\n  function calculateTaskPriority(task, dependencies) {\n    // Pure logic that returns a value\n    return computedPriority;\n  }\n  \n  function displayTaskPriority(task, dependencies) {\n    const priority = calculateTaskPriority(task, dependencies);\n    console.log(`Task priority: ${priority}`);\n  }\n  ```\n\n- **Callback Functions and Testing**\n  - When using callbacks (like in Commander.js commands), define them separately\n  - This allows testing the callback logic independently\n  ```javascript\n  // ✅ DO: Define callbacks separately for testing\n  function getVersionString() {\n    // Logic to determine version\n    return version;\n  }\n  \n  // In setupCLI\n  programInstance.version(getVersionString);\n  \n  // In tests\n  test('getVersionString returns correct version', () => {\n    expect(getVersionString()).toBe('1.5.0');\n  });\n  ```\n\n- **UI Output Testing**\n  - For UI components, focus on testing conditional logic rather than exact output\n  - Use string pattern matching (like `expect(result).toContain('text')`)\n  - Pay attention to emojis and formatting which can make exact string matching difficult\n  ```javascript\n  // ✅ DO: Test the essence of the output, not exact formatting\n  test('statusFormatter shows done status correctly', () => {\n    const result = formatStatus('done');\n    expect(result).toContain('done');\n    expect(result).toContain('✅');\n  });\n  ```\n\n## Testing Requirements\n\nEvery new feature **must** include comprehensive tests following the guidelines in [`tests.mdc`](mdc:.cursor/rules/tests.mdc). Testing should include:\n\n1. **Unit Tests**: Test individual functions and components in isolation\n   ```javascript\n   // Example unit test for a new utility function\n   describe('newFeatureUtil', () => {\n     test('should perform expected operation with valid input', () => {\n       expect(newFeatureUtil('valid input')).toBe('expected result');\n     });\n     \n     test('should handle edge cases appropriately', () => {\n       expect(newFeatureUtil('')).toBeNull();\n     });\n   });\n   ```\n\n2. **Integration Tests**: Verify the feature works correctly with other components\n   ```javascript\n   // Example integration test for a new command\n   describe('newCommand integration', () => {\n     test('should call the correct service functions with parsed arguments', () => {\n       const mockService = jest.fn().mockResolvedValue('success');\n       // Set up test with mocked dependencies\n       // Call the command handler\n       // Verify service was called with expected arguments\n     });\n   });\n   ```\n\n3. **Edge Cases**: Test boundary conditions and error handling\n   - Invalid inputs\n   - Missing dependencies\n   - File system errors\n   - API failures\n\n4. **Test Coverage**: Aim for at least 80% coverage for all new code\n\n5. **Jest Mocking Best Practices**\n   - Follow the mock-first-then-import pattern as described in [`tests.mdc`](mdc:.cursor/rules/tests.mdc)\n   - Use jest.spyOn() to create spy functions for testing\n   - Clear mocks between tests to prevent interference\n   - See the Jest Module Mocking Best Practices section in [`tests.mdc`](mdc:.cursor/rules/tests.mdc) for details\n\nWhen submitting a new feature, always run the full test suite to ensure nothing was broken:\n\n```bash\nnpm test\n```\n\n## Documentation Requirements\n\nFor each new feature:\n\n1. Add help text to the command definition\n2. Update [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) with command reference\n3. Consider updating [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) if the feature significantly changes module responsibilities.\n\nFollow the existing command reference format:\n```markdown\n- **Command Reference: your-command**\n  - CLI Syntax: `task-master your-command [options]`\n  - Description: Brief explanation of what the command does\n  - Parameters:\n    - `--option1=<value>`: Description of option1 (default: 'default')\n    - `--option2=<value>`: Description of option2 (required)\n  - Example: `task-master your-command --option1=value --option2=value2`\n  - Notes: Additional details, limitations, or special considerations\n```\n\nFor more information on module structure, see [`MODULE_PLAN.md`](mdc:scripts/modules/MODULE_PLAN.md) and follow [`self_improve.mdc`](mdc:scripts/modules/self_improve.mdc) for best practices on updating documentation.\n\n## Adding MCP Server Support for Commands\n\nIntegrating Task Master commands with the MCP server (for use by tools like Cursor) follows a specific pattern distinct from the CLI command implementation, prioritizing performance and reliability.\n\n- **Goal**: Leverage direct function calls to core logic, avoiding CLI overhead.\n- **Reference**: See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for full details.\n\n**MCP Integration Workflow**:\n\n1.  **Core Logic**: Ensure the command's core logic exists and is exported from the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2.  **Direct Function Wrapper (`mcp-server/src/core/direct-functions/`)**:\n    - Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.\n    - Import the core logic function, necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**: `import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js';`\n    - Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.\n    - **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` (derived from the session) being passed correctly.\n    - Perform validation on other arguments received in `args`.\n    - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()` to prevent logs from interfering with JSON responses.\n    - **If Caching**: Implement caching using `getCachedOrExecute` from `../../tools/utils.js`.\n    - **If Not Caching**: Directly call the core logic function within a try/catch block.\n    - Format the return as `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`withNormalizedProjectRoot` HOF**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters**: Make `projectRoot` optional (`z.string().optional().describe(...)`) as the HOF handles fallback.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method **wrapped with `withNormalizedProjectRoot`**:\n      ```javascript\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n          // args.projectRoot is now normalized\n          const { projectRoot /*, other args */ } = args;\n          // ... resolve tasks path if needed using normalized projectRoot ...\n          const result = await yourCommandDirect(\n              { /* other args */, projectRoot /* if needed by direct func */ }, \n              log, \n              { session }\n          );\n          return handleApiResult(result, log);\n      })\n      ```\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Implementing Background Operations\n\nFor long-running operations that should not block the client, use the AsyncOperationManager:\n\n1. **Identify Background-Appropriate Operations**:\n   - ✅ **DO**: Use async operations for CPU-intensive tasks like task expansion or PRD parsing\n   - ✅ **DO**: Consider async operations for tasks that may take more than 1-2 seconds\n   - ❌ **DON'T**: Use async operations for quick read/status operations\n   - ❌ **DON'T**: Use async operations when immediate feedback is critical\n\n2. **Use AsyncOperationManager in MCP Tools**:\n   ```javascript\n   import { asyncOperationManager } from '../core/utils/async-manager.js';\n   \n   // In execute method:\n   const operationId = asyncOperationManager.addOperation(\n     expandTaskDirect, // The direct function to run in background\n     { ...args, projectRoot: rootFolder }, // Args to pass to the function\n     { log, reportProgress, session } // Context to preserve for the operation\n   );\n   \n   // Return immediate response with operation ID\n   return createContentResponse({\n     message: \"Operation started successfully\",\n     operationId,\n     status: \"pending\"\n   });\n   ```\n\n3. **Implement Progress Reporting**:\n   - ✅ **DO**: Use the reportProgress function in direct functions:\n   ```javascript\n   // In your direct function:\n   if (reportProgress) {\n     await reportProgress({ progress: 50 }); // 50% complete\n   }\n   ```\n   - AsyncOperationManager will forward progress updates to the client\n\n4. **Check Operation Status**:\n   - Implement a way for clients to check status using the `get_operation_status` MCP tool\n   - Return appropriate status codes and messages\n\n## Project Initialization\n\nWhen implementing project initialization commands:\n\n1. **Support Programmatic Initialization**:\n   - ✅ **DO**: Design initialization to work with both CLI and MCP\n   - ✅ **DO**: Support non-interactive modes with sensible defaults\n   - ✅ **DO**: Handle project metadata like name, description, version\n   - ✅ **DO**: Create necessary files and directories\n\n2. **In MCP Tool Implementation**:\n   ```javascript\n   // In initialize-project.js MCP tool:\n   import { z } from \"zod\";\n   import { initializeProjectDirect } from \"../core/task-master-core.js\";\n   \n   export function registerInitializeProjectTool(server) {\n     server.addTool({\n       name: \"initialize_project\",\n       description: \"Initialize a new Task Master project\",\n       parameters: z.object({\n         projectName: z.string().optional().describe(\"The name for the new project\"),\n         projectDescription: z.string().optional().describe(\"A brief description\"),\n         projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n         // Add other parameters as needed\n       }),\n       execute: async (args, { log, reportProgress, session }) => {\n         try {\n           // No need for project root since we're creating a new project\n           const result = await initializeProjectDirect(args, log);\n           return handleApiResult(result, log, 'Error initializing project');\n         } catch (error) {\n           log.error(`Error in initialize_project: ${error.message}`);\n           return createErrorResponse(`Failed to initialize project: ${error.message}`);\n         }\n       }\n     });\n   }\n   ```\n\n## Feature Planning\n\n- **Core Logic First**:\n  - ✅ DO: Implement core logic in `scripts/modules/` before CLI or MCP interfaces\n  - ✅ DO: Consider tagged task lists system compatibility from the start\n  - ✅ DO: Design functions to work with both legacy and tagged data formats\n  - ✅ DO: Use tag resolution functions (`getTasksForTag`, `setTasksForTag`) for task data access\n  - ❌ DON'T: Directly manipulate tagged data structure in new features\n\n  ```javascript\n  // ✅ DO: Design tagged-aware core functions\n  async function newFeatureCore(tasksPath, featureParams, options = {}) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Perform feature logic on tasks array\n    const result = performFeatureLogic(tasks, featureParams);\n    \n    // Save back using tag resolution\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n    \n    return result;\n  }\n  ```\n\n- **Backward Compatibility**:\n  - ✅ DO: Ensure new features work with existing projects seamlessly\n  - ✅ DO: Test with both legacy and tagged task data formats\n  - ✅ DO: Support silent migration during feature usage\n  - ❌ DON'T: Break existing workflows when adding tagged system features\n\n## CLI Command Implementation\n\n- **Command Structure**:\n  - ✅ DO: Follow the established pattern in [`commands.js`](mdc:scripts/modules/commands.js)\n  - ✅ DO: Use Commander.js for argument parsing\n  - ✅ DO: Include comprehensive help text and examples\n  - ✅ DO: Support tagged task context awareness\n\n  ```javascript\n  // ✅ DO: Implement CLI commands with tagged system awareness\n  program\n    .command('new-feature')\n    .description('Description of the new feature with tagged task lists support')\n    .option('-t, --tag <tag>', 'Specify tag context (defaults to current tag)')\n    .option('-p, --param <value>', 'Feature-specific parameter')\n    .option('--force', 'Force operation without confirmation')\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot();\n        if (!projectRoot) {\n          console.error('Not in a Task Master project directory');\n          process.exit(1);\n        }\n        \n        // Use specified tag or current tag\n        const targetTag = options.tag || getCurrentTag() || 'master';\n        \n        const result = await newFeatureCore(\n          path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'),\n          { param: options.param },\n          { \n            force: options.force,\n            targetTag: targetTag,\n            outputFormat: 'text'\n          }\n        );\n        \n        console.log('Feature executed successfully');\n      } catch (error) {\n        console.error(`Error: ${error.message}`);\n        process.exit(1);\n      }\n    });\n  ```\n\n- **Error Handling**:\n  - ✅ DO: Provide clear error messages for common failures\n  - ✅ DO: Handle tagged system migration errors gracefully\n  - ✅ DO: Include suggestion for resolution when possible\n  - ✅ DO: Exit with appropriate codes for scripting\n\n## MCP Tool Implementation\n\n- **Direct Function Pattern**:\n  - ✅ DO: Create direct function wrappers in `mcp-server/src/core/direct-functions/`\n  - ✅ DO: Follow silent mode patterns to prevent console output interference\n  - ✅ DO: Use `findTasksJsonPath` for consistent path resolution\n  - ✅ DO: Ensure tagged system compatibility\n\n  ```javascript\n  // ✅ DO: Implement MCP direct functions with tagged awareness\n  export async function newFeatureDirect(args, log, context = {}) {\n    try {\n      const tasksPath = findTasksJsonPath(args, log);\n      \n      // Enable silent mode for clean MCP responses\n      enableSilentMode();\n      \n      try {\n        const result = await newFeatureCore(\n          tasksPath,\n          { param: args.param },\n          { \n            force: args.force,\n            targetTag: args.tag || 'master', // Support tag specification\n            mcpLog: log,\n            session: context.session,\n            outputFormat: 'json'\n          }\n        );\n        \n        return {\n          success: true,\n          data: result,\n          fromCache: false\n        };\n      } finally {\n        disableSilentMode();\n      }\n    } catch (error) {\n      log.error(`Error in newFeatureDirect: ${error.message}`);\n      return {\n        success: false,\n        error: { code: 'FEATURE_ERROR', message: error.message },\n        fromCache: false\n      };\n    }\n  }\n  ```\n\n- **Tool Registration**:\n  - ✅ DO: Create tool definitions in `mcp-server/src/tools/`\n  - ✅ DO: Use Zod for parameter validation\n  - ✅ DO: Include optional tag parameter for multi-context support\n  - ✅ DO: Follow established naming conventions\n\n  ```javascript\n  // ✅ DO: Register MCP tools with tagged system support\n  export function registerNewFeatureTool(server) {\n    server.addTool({\n      name: \"new_feature\",\n      description: \"Description of the new feature with tagged task lists support\",\n      inputSchema: z.object({\n        param: z.string().describe(\"Feature-specific parameter\"),\n        tag: z.string().optional().describe(\"Target tag context (defaults to current tag)\"),\n        force: z.boolean().optional().describe(\"Force operation without confirmation\"),\n        projectRoot: z.string().optional().describe(\"Project root directory\")\n      }),\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const result = await newFeatureDirect(\n            { ...args, projectRoot: args.projectRoot },\n            log,\n            { session }\n          );\n          return handleApiResult(result, log);\n        } catch (error) {\n          return handleApiResult({\n            success: false,\n            error: { code: 'EXECUTION_ERROR', message: error.message }\n          }, log);\n        }\n      })\n    });\n  }\n  ```\n\n## Testing Strategy\n\n- **Unit Tests**:\n  - ✅ DO: Test core logic independently with both data formats\n  - ✅ DO: Mock file system operations appropriately\n  - ✅ DO: Test tag resolution behavior\n  - ✅ DO: Verify migration compatibility\n\n  ```javascript\n  // ✅ DO: Test new features with tagged system awareness\n  describe('newFeature', () => {\n    beforeEach(() => {\n      jest.clearAllMocks();\n    });\n    \n    it('should work with legacy task format', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test legacy format handling\n    });\n    \n    it('should work with tagged task format', async () => {\n      const taggedData = { \n        master: { tasks: [/* test data */] },\n        feature: { tasks: [/* test data */] }\n      };\n      fs.readFileSync.mockReturnValue(JSON.stringify(taggedData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test tagged format handling\n    });\n    \n    it('should handle tag migration during feature usage', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      // Verify migration occurred\n      expect(fs.writeFileSync).toHaveBeenCalledWith(\n        '/test/tasks.json',\n        expect.stringContaining('\"master\"')\n      );\n    });\n  });\n  ```\n\n- **Integration Tests**:\n  - ✅ DO: Test CLI and MCP interfaces with real task data\n  - ✅ DO: Verify end-to-end workflows across tag contexts\n  - ✅ DO: Test error scenarios and recovery\n\n## Documentation Updates\n\n- **Rule Updates**:\n  - ✅ DO: Update relevant `.cursor/rules/*.mdc` files\n  - ✅ DO: Include tagged system considerations in architecture docs\n  - ✅ DO: Add examples showing multi-context usage\n  - ✅ DO: Update workflow documentation as needed\n\n- **User Documentation**:\n  - ✅ DO: Add feature documentation to `/docs` folder\n  - ✅ DO: Include tagged system usage examples\n  - ✅ DO: Update command reference documentation\n  - ✅ DO: Provide migration notes if relevant\n\n## Migration Considerations\n\n- **Silent Migration Support**:\n  - ✅ DO: Ensure new features trigger migration when needed\n  - ✅ DO: Handle migration errors gracefully in feature code\n  - ✅ DO: Test feature behavior with pre-migration projects\n  - ❌ DON'T: Assume projects are already migrated\n\n- **Tag Context Handling**:\n  - ✅ DO: Default to current tag when not specified\n  - ✅ DO: Support explicit tag selection in advanced features\n  - ✅ DO: Validate tag existence before operations\n  - ✅ DO: Provide clear messaging about tag context\n\n## Performance Considerations\n\n- **Efficient Tag Operations**:\n  - ✅ DO: Minimize file I/O operations per feature execution\n  - ✅ DO: Cache tag resolution results when appropriate\n  - ✅ DO: Use streaming for large task datasets\n  - ❌ DON'T: Load all tags when only one is needed\n\n- **Memory Management**:\n  - ✅ DO: Process large task lists efficiently\n  - ✅ DO: Clean up temporary data structures\n  - ✅ DO: Avoid keeping all tag data in memory simultaneously\n\n## Deployment and Versioning\n\n- **Changesets**:\n  - ✅ DO: Create appropriate changesets for new features\n  - ✅ DO: Use semantic versioning (minor for new features)\n  - ✅ DO: Include tagged system information in release notes\n  - ✅ DO: Document breaking changes if any\n\n- **Feature Flags**:\n  - ✅ DO: Consider feature flags for experimental functionality\n  - ✅ DO: Ensure tagged system features work with flags\n  - ✅ DO: Provide clear documentation about flag usage\n\nBy following these guidelines, new features will integrate smoothly with the Task Master ecosystem while supporting the enhanced tagged task lists system for multi-context development workflows.\n",".cursor/rules/self_improve.mdc":"---\ndescription: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\nglobs: **/*\nalwaysApply: true\n---\n\n- **Rule Improvement Triggers:**\n  - New code patterns not covered by existing rules\n  - Repeated similar implementations across files\n  - Common error patterns that could be prevented\n  - New libraries or tools being used consistently\n  - Emerging best practices in the codebase\n\n- **Analysis Process:**\n  - Compare new code with existing rules\n  - Identify patterns that should be standardized\n  - Look for references to external documentation\n  - Check for consistent error handling patterns\n  - Monitor test patterns and coverage\n\n- **Rule Updates:**\n  - **Add New Rules When:**\n    - A new technology/pattern is used in 3+ files\n    - Common bugs could be prevented by a rule\n    - Code reviews repeatedly mention the same feedback\n    - New security or performance patterns emerge\n\n  - **Modify Existing Rules When:**\n    - Better examples exist in the codebase\n    - Additional edge cases are discovered\n    - Related rules have been updated\n    - Implementation details have changed\n\n- **Example Pattern Recognition:**\n  ```typescript\n  // If you see repeated patterns like:\n  const data = await prisma.user.findMany({\n    select: { id: true, email: true },\n    where: { status: 'ACTIVE' }\n  });\n  \n  // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc):\n  // - Standard select fields\n  // - Common where conditions\n  // - Performance optimization patterns\n  ```\n\n- **Rule Quality Checks:**\n  - Rules should be actionable and specific\n  - Examples should come from actual code\n  - References should be up to date\n  - Patterns should be consistently enforced\n\n- **Continuous Improvement:**\n  - Monitor code review comments\n  - Track common development questions\n  - Update rules after major refactors\n  - Add links to relevant documentation\n  - Cross-reference related rules\n\n- **Rule Deprecation:**\n  - Mark outdated patterns as deprecated\n  - Remove rules that no longer apply\n  - Update references to deprecated rules\n  - Document migration paths for old patterns\n\n- **Documentation Updates:**\n  - Keep examples synchronized with code\n  - Update references to external docs\n  - Maintain links between related rules\n  - Document breaking changes\nFollow [cursor_rules.mdc](mdc:.cursor/rules/cursor_rules.mdc) for proper rule formatting and structure.\n",".cursor/rules/tags.mdc":"---\ndescription: \nglobs: scripts/modules/*\nalwaysApply: false\n---\n# Tagged Task Lists Command Patterns\n\nThis document outlines the standardized patterns that **ALL** Task Master commands must follow to properly support the tagged task lists system.\n\n## Core Principles\n\n- **Every command** that reads or writes tasks.json must be tag-aware\n- **Consistent tag resolution** across all commands using `getCurrentTag(projectRoot)`\n- **Proper context passing** to core functions with `{ projectRoot, tag }`\n- **Standardized CLI options** with `--tag <tag>` flag\n\n## Required Imports\n\nAll command files must import `getCurrentTag`:\n\n```javascript\n// ✅ DO: Import getCurrentTag in commands.js\nimport { \n  log, \n  readJSON, \n  writeJSON, \n  findProjectRoot, \n  getCurrentTag \n} from './utils.js';\n\n// ✅ DO: Import getCurrentTag in task-manager files\nimport { \n  readJSON, \n  writeJSON, \n  getCurrentTag \n} from '../utils.js';\n```\n\n## CLI Command Pattern\n\nEvery CLI command that operates on tasks must follow this exact pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware CLI command pattern\nprogramInstance\n  .command('command-name')\n  .description('Command description')\n  .option('-f, --file <file>', 'Path to the tasks file', TASKMASTER_TASKS_FILE)\n  .option('--tag <tag>', 'Specify tag context for task operations') // REQUIRED\n  .action(async (options) => {\n    // 1. Find project root\n    const projectRoot = findProjectRoot();\n    if (!projectRoot) {\n      console.error(chalk.red('Error: Could not find project root.'));\n      process.exit(1);\n    }\n\n    // 2. Resolve tag using standard pattern\n    const tag = options.tag || getCurrentTag(projectRoot) || 'master';\n\n    // 3. Call core function with proper context\n    await coreFunction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag } // REQUIRED context object\n    );\n  });\n```\n\n## Core Function Pattern\n\nAll core functions in `scripts/modules/task-manager/` must follow this pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware core function pattern\nasync function coreFunction(\n  tasksPath,\n  // ... other parameters ...\n  context = {} // REQUIRED context parameter\n) {\n  const { projectRoot, tag } = context;\n  \n  // Use tag-aware readJSON/writeJSON\n  const data = readJSON(tasksPath, projectRoot, tag);\n  \n  // ... function logic ...\n  \n  writeJSON(tasksPath, data, projectRoot, tag);\n}\n```\n\n## Tag Resolution Priority\n\nThe tag resolution follows this exact priority order:\n\n1. **Explicit `--tag` flag**: `options.tag`\n2. **Current active tag**: `getCurrentTag(projectRoot)`  \n3. **Default fallback**: `'master'`\n\n```javascript\n// ✅ DO: Standard tag resolution pattern\nconst tag = options.tag || getCurrentTag(projectRoot) || 'master';\n```\n\n## Commands Requiring Updates\n\n### High Priority (Core Task Operations)\n- [x] `add-task` - ✅ Fixed\n- [x] `list` - ✅ Fixed  \n- [x] `update-task` - ✅ Fixed\n- [x] `update-subtask` - ✅ Fixed\n- [x] `set-status` - ✅ Already correct\n- [x] `remove-task` - ✅ Already correct\n- [x] `remove-subtask` - ✅ Fixed\n- [x] `add-subtask` - ✅ Already correct\n- [x] `clear-subtasks` - ✅ Fixed\n- [x] `move-task` - ✅ Already correct\n\n### Medium Priority (Analysis & Expansion)\n- [x] `expand` - ✅ Fixed\n- [ ] `next` - ✅ Fixed\n- [ ] `show` (get-task) - Needs checking\n- [ ] `analyze-complexity` - Needs checking\n- [ ] `generate` - ✅ Fixed\n\n### Lower Priority (Utilities)\n- [ ] `research` - Needs checking\n- [ ] `complexity-report` - Needs checking\n- [ ] `validate-dependencies` - ✅ Fixed\n- [ ] `fix-dependencies` - ✅ Fixed\n- [ ] `add-dependency` - ✅ Fixed\n- [ ] `remove-dependency` - ✅ Fixed\n\n## MCP Integration Pattern\n\nMCP direct functions must also follow the tag-aware pattern:\n\n```javascript\n// ✅ DO: Tag-aware MCP direct function\nexport async function coreActionDirect(args, log, context = {}) {\n  const { session } = context;\n  const { projectRoot, tag } = args; // MCP passes these in args\n  \n  try {\n    const result = await coreAction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag, session, mcpLog: logWrapper }\n    );\n    \n    return { success: true, data: result };\n  } catch (error) {\n    return { success: false, error: { code: 'ERROR_CODE', message: error.message } };\n  }\n}\n```\n\n## File Generation Tag-Aware Naming\n\nThe `generate` command must use tag-aware file naming:\n\n```javascript\n// ✅ DO: Tag-aware file naming\nconst taskFileName = targetTag === 'master' \n  ? `task_${task.id.toString().padStart(3, '0')}.txt`\n  : `task_${task.id.toString().padStart(3, '0')}_${targetTag}.txt`;\n```\n\n**Examples:**\n- Master tag: `task_001.txt`, `task_002.txt`\n- Other tags: `task_001_feature.txt`, `task_002_feature.txt`\n\n## Common Anti-Patterns\n\n```javascript\n// ❌ DON'T: Missing getCurrentTag import\nimport { readJSON, writeJSON } from '../utils.js'; // Missing getCurrentTag\n\n// ❌ DON'T: Hard-coded tag resolution\nconst tag = options.tag || 'master'; // Missing getCurrentTag\n\n// ❌ DON'T: Missing --tag option\n.option('-f, --file <file>', 'Path to tasks file') // Missing --tag option\n\n// ❌ DON'T: Missing context parameter\nawait coreFunction(tasksPath, param1, param2); // Missing { projectRoot, tag }\n\n// ❌ DON'T: Incorrect readJSON/writeJSON calls\nconst data = readJSON(tasksPath); // Missing projectRoot and tag\nwriteJSON(tasksPath, data); // Missing projectRoot and tag\n```\n\n## Validation Checklist\n\nFor each command, verify:\n\n- [ ] Imports `getCurrentTag` from utils.js\n- [ ] Has `--tag <tag>` CLI option\n- [ ] Uses standard tag resolution: `options.tag || getCurrentTag(projectRoot) || 'master'`\n- [ ] Finds `projectRoot` with error handling\n- [ ] Passes `{ projectRoot, tag }` context to core functions\n- [ ] Core functions accept and use context parameter\n- [ ] Uses `readJSON(tasksPath, projectRoot, tag)` and `writeJSON(tasksPath, data, projectRoot, tag)`\n\n## Testing Tag Resolution\n\nTest each command with:\n\n```bash\n# Test with explicit tag\nnode bin/task-master command-name --tag test-tag\n\n# Test with active tag (should use current active tag)\nnode bin/task-master use-tag test-tag\nnode bin/task-master command-name\n\n# Test with master tag (default)\nnode bin/task-master use-tag master  \nnode bin/task-master command-name\n```\n\n## Migration Strategy\n\n1. **Audit Phase**: Systematically check each command against the checklist\n2. **Fix Phase**: Apply the standard patterns to non-compliant commands\n3. **Test Phase**: Verify tag resolution works correctly\n4. **Document Phase**: Update command documentation with tag support\n\nThis ensures consistent, predictable behavior across all Task Master commands and prevents tag deletion bugs.\n",".cursor/rules/taskmaster.mdc":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `--no-git`: `Skip initializing a Git repository entirely.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `noGit`: `Skip initializing a Git repository entirely. Default is false.` (CLI: `--no-git`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [Development Workflow Guide](mdc:.cursor/rules/dev_workflow.mdc).",".cursor/rules/taskmaster/dev_workflow.mdc":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see @`taskmaster.mdc`) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see @`taskmaster.mdc`) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see @`taskmaster.mdc`)\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`)\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see @`taskmaster.mdc`) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see @`taskmaster.mdc`) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see @`taskmaster.mdc`)\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see @`taskmaster.mdc`)\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to @`mcp.mdc` for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in @`taskmaster.mdc`.\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to @`taskmaster.mdc` for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to @`taskmaster.mdc` for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see @`taskmaster.mdc`) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*",".cursor/rules/taskmaster/taskmaster.mdc":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [dev_workflow.mdc](mdc:.cursor/rules/taskmaster/dev_workflow.mdc).",".cursor/rules/tasks.mdc":"---\ndescription: Guidelines for implementing task management operations\nglobs: scripts/modules/task-manager.js\nalwaysApply: false\n---\n# Task Management Guidelines\n\n## Tagged Task Lists System\n\nTask Master now uses a **tagged task lists system** for multi-context task management:\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) within `tasks.json`\n- **Legacy Format**: `{\"tasks\": [...]}`\n- **Tagged Format**: `{\"master\": {\"tasks\": [...]}, \"feature-branch\": {\"tasks\": [...]}}`\n- **Silent Migration**: Legacy format automatically converts to tagged format on first use\n- **Tag Resolution**: Core functions receive legacy format for 100% backward compatibility\n- **Default Tag**: \"master\" is used for all existing and new tasks unless otherwise specified\n\n## Task Structure Standards\n\n- **Core Task Properties**:\n  - ✅ DO: Include all required properties in each task object\n  - ✅ DO: Provide default values for optional properties\n  - ❌ DON'T: Add extra properties that aren't in the standard schema\n\n  ```javascript\n  // ✅ DO: Follow this structure for task objects\n  const task = {\n    id: nextId,\n    title: \"Task title\",\n    description: \"Brief task description\",\n    status: \"pending\", // \"pending\", \"in-progress\", \"done\", etc.\n    dependencies: [], // Array of task IDs\n    priority: \"medium\", // \"high\", \"medium\", \"low\"\n    details: \"Detailed implementation instructions\",\n    testStrategy: \"Verification approach\",\n    subtasks: [] // Array of subtask objects\n  };\n  ```\n\n- **Tagged Data Structure**:\n  - ✅ DO: Access tasks through tag resolution layer\n  - ✅ DO: Use `getTasksForTag(data, tagName)` to retrieve tasks for a specific tag\n  - ✅ DO: Use `setTasksForTag(data, tagName, tasks)` to update tasks for a specific tag\n  - ❌ DON'T: Directly manipulate the tagged structure in core functions\n\n  ```javascript\n  // ✅ DO: Use tag resolution functions\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Manipulate tasks as normal...\n  \n  // Save back to the tagged structure\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n- **Subtask Structure**:\n  - ✅ DO: Use consistent properties across subtasks\n  - ✅ DO: Maintain simple numeric IDs within parent tasks\n  - ❌ DON'T: Duplicate parent task properties in subtasks\n\n  ```javascript\n  // ✅ DO: Structure subtasks consistently\n  const subtask = {\n    id: nextSubtaskId, // Simple numeric ID, unique within the parent task\n    title: \"Subtask title\",\n    description: \"Brief subtask description\",\n    status: \"pending\",\n    dependencies: [], // Can include numeric IDs (other subtasks) or full task IDs\n    details: \"Detailed implementation instructions\"\n  };\n  ```\n\n## Task Creation and Parsing\n\n- **ID Management**:\n  - ✅ DO: Assign unique sequential IDs to tasks within each tag context\n  - ✅ DO: Calculate the next ID based on existing tasks in the current tag\n  - ❌ DON'T: Hardcode or reuse IDs within the same tag\n\n  ```javascript\n  // ✅ DO: Calculate the next available ID within the current tag\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  const highestId = Math.max(...tasks.map(t => t.id));\n  const nextTaskId = highestId + 1;\n  ```\n\n- **PRD Parsing**:\n  - ✅ DO: Extract tasks from PRD documents using AI\n  - ✅ DO: Create tasks in the current tag context (defaults to \"master\")\n  - ✅ DO: Provide clear prompts to guide AI task generation\n  - ✅ DO: Validate and clean up AI-generated tasks\n\n  ```javascript\n  // ✅ DO: Parse into current tag context\n  const tasksData = readJSON(tasksPath) || {};\n  const currentTag = getCurrentTag() || 'master';\n  \n  // Parse tasks and add to current tag\n  const newTasks = await parseTasksFromPRD(prdContent);\n  setTasksForTag(tasksData, currentTag, newTasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task Updates and Modifications\n\n- **Status Management**:\n  - ✅ DO: Provide functions for updating task status within current tag context\n  - ✅ DO: Handle both individual tasks and subtasks\n  - ✅ DO: Consider subtask status when updating parent tasks\n\n  ```javascript\n  // ✅ DO: Handle status updates within tagged context\n  async function setTaskStatus(tasksPath, taskIdInput, newStatus) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Check if it's a subtask (e.g., \"1.2\")\n    if (taskIdInput.includes('.')) {\n      const [parentId, subtaskId] = taskIdInput.split('.').map(id => parseInt(id, 10));\n      \n      // Find the parent task and subtask\n      const parentTask = tasks.find(t => t.id === parentId);\n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      \n      // Update subtask status\n      subtask.status = newStatus;\n      \n      // Check if all subtasks are done\n      if (newStatus === 'done') {\n        const allSubtasksDone = parentTask.subtasks.every(st => st.status === 'done');\n        if (allSubtasksDone) {\n          // Suggest updating parent task\n        }\n      }\n    } else {\n      // Handle regular task\n      const task = tasks.find(t => t.id === parseInt(taskIdInput, 10));\n      task.status = newStatus;\n      \n      // If marking as done, also mark subtasks\n      if (newStatus === 'done' && task.subtasks && task.subtasks.length > 0) {\n        task.subtasks.forEach(subtask => {\n          subtask.status = newStatus;\n        });\n      }\n    }\n    \n    // Save updated tasks back to tagged structure\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n  }\n  ```\n\n- **Task Expansion**:\n  - ✅ DO: Use AI to generate detailed subtasks within current tag context\n  - ✅ DO: Consider complexity analysis for subtask counts\n  - ✅ DO: Ensure proper IDs for newly created subtasks\n\n  ```javascript\n  // ✅ DO: Generate appropriate subtasks based on complexity\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  if (taskAnalysis) {\n    log('info', `Found complexity analysis for task ${taskId}: Score ${taskAnalysis.complexityScore}/10`);\n    \n    // Use recommended number of subtasks if available\n    if (taskAnalysis.recommendedSubtasks && numSubtasks === CONFIG.defaultSubtasks) {\n      numSubtasks = taskAnalysis.recommendedSubtasks;\n      log('info', `Using recommended number of subtasks: ${numSubtasks}`);\n    }\n  }\n  \n  // Generate subtasks and save back\n  // ... subtask generation logic ...\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task File Generation\n\n- **File Formatting**:\n  - ✅ DO: Use consistent formatting for task files\n  - ✅ DO: Include all task properties in text files\n  - ✅ DO: Format dependencies with status indicators\n\n  ```javascript\n  // ✅ DO: Use consistent file formatting\n  let content = `# Task ID: ${task.id}\\n`;\n  content += `# Title: ${task.title}\\n`;\n  content += `# Status: ${task.status || 'pending'}\\n`;\n  \n  // Format dependencies with their status\n  if (task.dependencies && task.dependencies.length > 0) {\n    content += `# Dependencies: ${formatDependenciesWithStatus(task.dependencies, tasks)}\\n`;\n  } else {\n    content += '# Dependencies: None\\n';\n  }\n  ```\n\n- **Tagged Context Awareness**:\n  - ✅ DO: Generate task files from current tag context\n  - ✅ DO: Include tag information in generated files\n  - ❌ DON'T: Mix tasks from different tags in file generation\n\n  ```javascript\n  // ✅ DO: Generate files for current tag context\n  async function generateTaskFiles(tasksPath, outputDir) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Add tag context to file header\n    let content = `# Tag Context: ${currentTag}\\n`;\n    content += `# Task ID: ${task.id}\\n`;\n    // ... rest of file generation\n  }\n  ```\n\n## Task Listing and Display\n\n- **Filtering and Organization**:\n  - ✅ DO: Allow filtering tasks by status within current tag context\n  - ✅ DO: Handle subtask display in lists\n  - ✅ DO: Use consistent table formats\n\n  ```javascript\n  // ✅ DO: Implement clear filtering within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Filter tasks by status if specified\n  const filteredTasks = statusFilter \n    ? tasks.filter(task => \n        task.status && task.status.toLowerCase() === statusFilter.toLowerCase())\n    : tasks;\n  ```\n\n- **Progress Tracking**:\n  - ✅ DO: Calculate and display completion statistics for current tag\n  - ✅ DO: Track both task and subtask completion\n  - ✅ DO: Use visual progress indicators\n\n  ```javascript\n  // ✅ DO: Track and display progress within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Calculate completion statistics\n  const totalTasks = tasks.length;\n  const completedTasks = tasks.filter(task => \n    task.status === 'done' || task.status === 'completed').length;\n  const completionPercentage = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0;\n  \n  // Count subtasks\n  let totalSubtasks = 0;\n  let completedSubtasks = 0;\n  \n  tasks.forEach(task => {\n    if (task.subtasks && task.subtasks.length > 0) {\n      totalSubtasks += task.subtasks.length;\n      completedSubtasks += task.subtasks.filter(st => \n        st.status === 'done' || st.status === 'completed').length;\n    }\n  });\n  ```\n\n## Migration and Compatibility\n\n- **Silent Migration Handling**:\n  - ✅ DO: Implement silent migration in `readJSON()` function\n  - ✅ DO: Detect legacy format and convert automatically\n  - ✅ DO: Preserve all existing task data during migration\n\n  ```javascript\n  // ✅ DO: Handle silent migration (implemented in utils.js)\n  function readJSON(filepath) {\n    let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n    \n    // Silent migration for tasks.json files\n    if (data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n      const migratedData = {\n        master: {\n          tasks: data.tasks\n        }\n      };\n      writeJSON(filepath, migratedData);\n      data = migratedData;\n    }\n    \n    return data;\n  }\n  ```\n\n- **Tag Resolution**:\n  - ✅ DO: Use tag resolution functions to maintain backward compatibility\n  - ✅ DO: Return legacy format to core functions\n  - ❌ DON'T: Expose tagged structure to existing core logic\n\n  ```javascript\n  // ✅ DO: Use tag resolution layer\n  function getTasksForTag(data, tagName) {\n    if (data.tasks && Array.isArray(data.tasks)) {\n      // Legacy format - return as-is\n      return data.tasks;\n    }\n    \n    if (data[tagName] && data[tagName].tasks) {\n      // Tagged format - return tasks for specified tag\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  ```\n\nRefer to [`task-manager.js`](mdc:scripts/modules/task-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/telemetry.mdc":"---\ndescription: Guidelines for integrating AI usage telemetry across Task Master.\nglobs: scripts/modules/**/*.js,mcp-server/src/**/*.js\nalwaysApply: true\n---\n\n# AI Usage Telemetry Integration\n\nThis document outlines the standard pattern for capturing, propagating, and handling AI usage telemetry data (cost, tokens, model, etc.) across the Task Master stack. This ensures consistent telemetry for both CLI and MCP interactions.\n\n## Overview\n\nTelemetry data is generated within the unified AI service layer ([`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)) and then passed upwards through the calling functions.\n\n- **Data Source**: [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js) (specifically its `generateTextService`, `generateObjectService`, etc.) returns an object like `{ mainResult: AI_CALL_OUTPUT, telemetryData: TELEMETRY_OBJECT }`.\n- **`telemetryData` Object Structure**:\n  ```json\n  {\n    \"timestamp\": \"ISO_STRING_DATE\",\n    \"userId\": \"USER_ID_FROM_CONFIG\",\n    \"commandName\": \"invoking_command_or_tool_name\",\n    \"modelUsed\": \"ai_model_id\",\n    \"providerName\": \"ai_provider_name\",\n    \"inputTokens\": NUMBER,\n    \"outputTokens\": NUMBER,\n    \"totalTokens\": NUMBER,\n    \"totalCost\": NUMBER, // e.g., 0.012414\n    \"currency\": \"USD\" // e.g., \"USD\"\n  }\n  ```\n\n## Integration Pattern by Layer\n\nThe key principle is that each layer receives telemetry data from the layer below it (if applicable) and passes it to the layer above it, or handles it for display in the case of the CLI.\n\n### 1. Core Logic Functions (e.g., in `scripts/modules/task-manager/`)\n\nFunctions in this layer that invoke AI services are responsible for handling the `telemetryData` they receive from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n\n- **Actions**:\n    1.  Call the appropriate AI service function (e.g., `generateObjectService`).\n        -   Pass `commandName` (e.g., `add-task`, `expand-task`) and `outputType` (e.g., `cli` or `mcp`) in the `params` object to the AI service. The `outputType` can be derived from context (e.g., presence of `mcpLog`).\n    2.  The AI service returns an object, e.g., `aiServiceResponse = { mainResult: {/*AI output*/}, telemetryData: {/*telemetry data*/} }`.\n    3.  Extract `aiServiceResponse.mainResult` for the core processing.\n    4.  **Must return an object that includes `aiServiceResponse.telemetryData`**.\n        Example: `return { operationSpecificData: /*...*/, telemetryData: aiServiceResponse.telemetryData };`\n\n- **CLI Output Handling (If Applicable)**:\n    -   If the core function also handles CLI output (e.g., it has an `outputFormat` parameter that can be `'text'` or `'cli'`):\n        1.  Check if `outputFormat === 'text'` (or `'cli'`).\n        2.  If so, and if `aiServiceResponse.telemetryData` is available, call `displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli')` from [`scripts/modules/ui.js`](mdc:scripts/modules/ui.js).\n        - This ensures telemetry is displayed directly to CLI users after the main command output.\n\n- **Example Snippet (Core Logic in `scripts/modules/task-manager/someAiAction.js`)**:\n  ```javascript\n  import { generateObjectService } from '../ai-services-unified.js';\n  import { displayAiUsageSummary } from '../ui.js';\n\n  async function performAiRelatedAction(params, context, outputFormat = 'text') {\n    const { commandNameFromContext, /* other context vars */ } = context;\n    let aiServiceResponse = null;\n\n    try {\n      aiServiceResponse = await generateObjectService({\n        // ... other parameters for AI service ...\n        commandName: commandNameFromContext || 'default-action-name',\n        outputType: context.mcpLog ? 'mcp' : 'cli' // Derive outputType\n      });\n\n      const usefulAiOutput = aiServiceResponse.mainResult.object;\n      // ... do work with usefulAiOutput ...\n\n      if (outputFormat === 'text' && aiServiceResponse.telemetryData) {\n        displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli');\n      }\n\n      return {\n        actionData: /* results of processing */,\n        telemetryData: aiServiceResponse.telemetryData\n      };\n    } catch (error) {\n      // ... handle error ...\n      throw error;\n    }\n  }\n  ```\n\n### 2. Direct Function Wrappers (in `mcp-server/src/core/direct-functions/`)\n\nThese functions adapt core logic for the MCP server, ensuring structured responses.\n\n- **Actions**:\n    1.  Call the corresponding core logic function.\n        -   Pass necessary context (e.g., `session`, `mcpLog`, `projectRoot`).\n        -   Provide the `commandName` (typically derived from the MCP tool name) and `outputType: 'mcp'` in the context object passed to the core function.\n        -   If the core function supports an `outputFormat` parameter, pass `'json'` to suppress CLI-specific UI.\n    2.  The core logic function returns an object (e.g., `coreResult = { actionData: ..., telemetryData: ... }`).\n    3.  Include `coreResult.telemetryData` as a field within the `data` object of the successful response returned by the direct function.\n\n- **Example Snippet (Direct Function `someAiActionDirect.js`)**:\n  ```javascript\n  import { performAiRelatedAction } from '../../../../scripts/modules/task-manager/someAiAction.js'; // Core function\n  import { createLogWrapper } from '../../tools/utils.js'; // MCP Log wrapper\n\n  export async function someAiActionDirect(args, log, context = {}) {\n    const { session } = context;\n    // ... prepare arguments for core function from args, including args.projectRoot ...\n\n    try {\n      const coreResult = await performAiRelatedAction(\n        { /* parameters for core function */ },\n        { // Context for core function\n          session,\n          mcpLog: createLogWrapper(log),\n          projectRoot: args.projectRoot,\n          commandNameFromContext: 'mcp_tool_some_ai_action', // Example command name\n          outputType: 'mcp'\n        },\n        'json' // Request 'json' output format from core function\n      );\n\n      return {\n        success: true,\n        data: {\n          operationSpecificData: coreResult.actionData,\n          telemetryData: coreResult.telemetryData // Pass telemetry through\n        }\n      };\n    } catch (error) {\n      // ... error handling, return { success: false, error: ... } ...\n    }\n  }\n  ```\n\n### 3. MCP Tools (in `mcp-server/src/tools/`)\n\nThese are the exposed endpoints for MCP clients.\n\n- **Actions**:\n    1.  Call the corresponding direct function wrapper.\n    2.  The direct function returns an object structured like `{ success: true, data: { operationSpecificData: ..., telemetryData: ... } }` (or an error object).\n    3.  Pass this entire result object to `handleApiResult(result, log)` from [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    4.  `handleApiResult` ensures that the `data` field from the direct function's response (which correctly includes `telemetryData`) is part of the final MCP response.\n\n- **Example Snippet (MCP Tool `some_ai_action.js`)**:\n  ```javascript\n  import { someAiActionDirect } from '../core/task-master-core.js';\n  import { handleApiResult, withNormalizedProjectRoot } from './utils.js';\n  // ... zod for parameters ...\n\n  export function registerSomeAiActionTool(server) {\n    server.addTool({\n      name: \"some_ai_action\",\n      // ... description, parameters ...\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const resultFromDirectFunction = await someAiActionDirect(\n            { /* args including projectRoot */ },\n            log,\n            { session }\n          );\n          return handleApiResult(resultFromDirectFunction, log); // This passes the nested telemetryData through\n        } catch (error) {\n          // ... error handling ...\n        }\n      })\n    });\n  }\n  ```\n\n### 4. CLI Commands (`scripts/modules/commands.js`)\n\nThese define the command-line interface.\n\n- **Actions**:\n    1.  Call the appropriate core logic function.\n    2.  Pass `outputFormat: 'text'` (or ensure the core function defaults to text-based output for CLI).\n    3.  The core logic function (as per Section 1) is responsible for calling `displayAiUsageSummary` if telemetry data is available and it's in CLI mode.\n    4.  The command action itself **should not** call `displayAiUsageSummary` if the core logic function already handles this. This avoids duplicate display.\n\n- **Example Snippet (CLI Command in `commands.js`)**:\n  ```javascript\n  // In scripts/modules/commands.js\n  import { performAiRelatedAction } from './task-manager/someAiAction.js'; // Core function\n\n  programInstance\n    .command('some-cli-ai-action')\n    // ... .option() ...\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot() || '.'; // Example root finding\n        // ... prepare parameters for core function from command options ...\n        await performAiRelatedAction(\n          { /* parameters for core function */ },\n          { // Context for core function\n            projectRoot,\n            commandNameFromContext: 'some-cli-ai-action',\n            outputType: 'cli'\n          },\n          'text' // Explicitly request text output format for CLI\n        );\n        // Core function handles displayAiUsageSummary internally for 'text' outputFormat\n      } catch (error) {\n        // ... error handling ...\n      }\n    });\n  ```\n\n## Summary Flow\n\nThe telemetry data flows as follows:\n\n1.  **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)**: Generates `telemetryData` and returns `{ mainResult, telemetryData }`.\n2.  **Core Logic Function**:\n    *   Receives `{ mainResult, telemetryData }`.\n    *   Uses `mainResult`.\n    *   If CLI (`outputFormat: 'text'`), calls `displayAiUsageSummary(telemetryData)`.\n    *   Returns `{ operationSpecificData, telemetryData }`.\n3.  **Direct Function Wrapper**:\n    *   Receives `{ operationSpecificData, telemetryData }` from core logic.\n    *   Returns `{ success: true, data: { operationSpecificData, telemetryData } }`.\n4.  **MCP Tool**:\n    *   Receives direct function response.\n    *   `handleApiResult` ensures the final MCP response to the client is `{ success: true, data: { operationSpecificData, telemetryData } }`.\n5.  **CLI Command**:\n    *   Calls core logic with `outputFormat: 'text'`. Display is handled by core logic.\n\nThis pattern ensures telemetry is captured and appropriately handled/exposed across all interaction modes.\n",".cursor/rules/test_workflow.mdc":"---\ndescription: \nglobs: \nalwaysApply: true\n---\n# Test Workflow & Development Process\n\n## **Initial Testing Framework Setup**\n\nBefore implementing the TDD workflow, ensure your project has a proper testing framework configured. This section covers setup for different technology stacks.\n\n### **Detecting Project Type & Framework Needs**\n\n**AI Agent Assessment Checklist:**\n1. **Language Detection**: Check for `package.json` (Node.js/JavaScript), `requirements.txt` (Python), `Cargo.toml` (Rust), etc.\n2. **Existing Tests**: Look for test files (`.test.`, `.spec.`, `_test.`) or test directories\n3. **Framework Detection**: Check for existing test runners in dependencies\n4. **Project Structure**: Analyze directory structure for testing patterns\n\n### **JavaScript/Node.js Projects (Jest Setup)**\n\n#### **Prerequisites Check**\n```bash\n# Verify Node.js project\nls package.json  # Should exist\n\n# Check for existing testing setup\nls jest.config.js jest.config.ts  # Check for Jest config\ngrep -E \"(jest|vitest|mocha)\" package.json  # Check for test runners\n```\n\n#### **Jest Installation & Configuration**\n\n**Step 1: Install Dependencies**\n```bash\n# Core Jest dependencies\nnpm install --save-dev jest\n\n# TypeScript support (if using TypeScript)\nnpm install --save-dev ts-jest @types/jest\n\n# Additional useful packages\nnpm install --save-dev supertest @types/supertest  # For API testing\nnpm install --save-dev jest-watch-typeahead  # Enhanced watch mode\n```\n\n**Step 2: Create Jest Configuration**\n\nCreate `jest.config.js` with the following production-ready configuration:\n\n```javascript\n/** @type {import('jest').Config} */\nmodule.exports = {\n  // Use ts-jest preset for TypeScript support\n  preset: 'ts-jest',\n\n  // Test environment\n  testEnvironment: 'node',\n\n  // Roots for test discovery\n  roots: ['<rootDir>/src', '<rootDir>/tests'],\n\n  // Test file patterns\n  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],\n\n  // Transform files\n  transform: {\n    '^.+\\\\.ts$': [\n      'ts-jest',\n      {\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          skipLibCheck: true,\n          strict: false,\n          noImplicitAny: false,\n        },\n      },\n    ],\n    '^.+\\\\.js$': [\n      'ts-jest',\n      {\n        useESM: false,\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          allowJs: true,\n        },\n      },\n    ],\n  },\n\n  // Module file extensions\n  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n\n  // Transform ignore patterns - adjust for ES modules\n  transformIgnorePatterns: ['node_modules/(?!(your-es-module-deps|.*\\\\.mjs$))'],\n\n  // Coverage configuration\n  collectCoverage: true,\n  coverageDirectory: 'coverage',\n  coverageReporters: [\n    'text', // Console output\n    'text-summary', // Brief summary\n    'lcov', // For IDE integration\n    'html', // Detailed HTML report\n  ],\n\n  // Files to collect coverage from\n  collectCoverageFrom: [\n    'src/**/*.ts',\n    '!src/**/*.d.ts',\n    '!src/**/*.test.ts',\n    '!src/**/index.ts', // Often just exports\n    '!src/generated/**', // Generated code\n    '!src/config/database.ts', // Database config (tested via integration)\n  ],\n\n  // Coverage thresholds - TaskMaster standards\n  coverageThreshold: {\n    global: {\n      branches: 70,\n      functions: 80,\n      lines: 80,\n      statements: 80,\n    },\n    // Higher standards for critical business logic\n    './src/utils/': {\n      branches: 85,\n      functions: 90,\n      lines: 90,\n      statements: 90,\n    },\n    './src/middleware/': {\n      branches: 80,\n      functions: 85,\n      lines: 85,\n      statements: 85,\n    },\n  },\n\n  // Setup files\n  setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],\n\n  // Global teardown to prevent worker process leaks\n  globalTeardown: '<rootDir>/tests/teardown.ts',\n\n  // Module path mapping (if needed)\n  moduleNameMapper: {\n    '^@/(.*)$': '<rootDir>/src/$1',\n  },\n\n  // Clear mocks between tests\n  clearMocks: true,\n\n  // Restore mocks after each test\n  restoreMocks: true,\n\n  // Global test timeout\n  testTimeout: 10000,\n\n  // Projects for different test types\n  projects: [\n    // Unit tests - for pure functions only\n    {\n      displayName: 'unit',\n      testMatch: ['<rootDir>/src/**/*.test.ts'],\n      testPathIgnorePatterns: ['.*\\\\.integration\\\\.test\\\\.ts$', '/tests/'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      collectCoverageFrom: [\n        'src/**/*.ts',\n        '!src/**/*.d.ts',\n        '!src/**/*.test.ts',\n        '!src/**/*.integration.test.ts',\n      ],\n      coverageThreshold: {\n        global: {\n          branches: 70,\n          functions: 80,\n          lines: 80,\n          statements: 80,\n        },\n      },\n    },\n    // Integration tests - real database/services\n    {\n      displayName: 'integration',\n      testMatch: [\n        '<rootDir>/src/**/*.integration.test.ts',\n        '<rootDir>/tests/integration/**/*.test.ts',\n      ],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/integration.ts'],\n      testTimeout: 10000,\n    },\n    // E2E tests - full workflows\n    {\n      displayName: 'e2e',\n      testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/e2e.ts'],\n      testTimeout: 30000,\n    },\n  ],\n\n  // Verbose output for better debugging\n  verbose: true,\n\n  // Run projects sequentially to avoid conflicts\n  maxWorkers: 1,\n\n  // Enable watch mode plugins\n  watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],\n};\n```\n\n**Step 3: Update package.json Scripts**\n\nAdd these scripts to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:coverage\": \"jest --coverage\",\n    \"test:unit\": \"jest --selectProjects unit\",\n    \"test:integration\": \"jest --selectProjects integration\", \n    \"test:e2e\": \"jest --selectProjects e2e\",\n    \"test:ci\": \"jest --ci --coverage --watchAll=false\"\n  }\n}\n```\n\n**Step 4: Create Test Setup Files**\n\nCreate essential test setup files:\n\n```typescript\n// tests/setup.ts - Global setup\nimport { jest } from '@jest/globals';\n\n// Global test configuration\nbeforeAll(() => {\n  // Set test timeout\n  jest.setTimeout(10000);\n});\n\nafterEach(() => {\n  // Clean up mocks after each test\n  jest.clearAllMocks();\n});\n```\n\n```typescript\n// tests/setup/integration.ts - Integration test setup\nimport { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nbeforeAll(async () => {\n  // Connect to test database\n  await prisma.$connect();\n});\n\nafterAll(async () => {\n  // Cleanup and disconnect\n  await prisma.$disconnect();\n});\n\nbeforeEach(async () => {\n  // Clean test data before each test\n  // Add your cleanup logic here\n});\n```\n\n```typescript\n// tests/teardown.ts - Global teardown\nexport default async () => {\n  // Global cleanup after all tests\n  console.log('Global test teardown complete');\n};\n```\n\n**Step 5: Create Initial Test Structure**\n\n```bash\n# Create test directories\nmkdir -p tests/{setup,fixtures,unit,integration,e2e}\nmkdir -p tests/unit/src/{utils,services,middleware}\n\n# Create sample test fixtures\nmkdir tests/fixtures\n```\n\n### **Generic Testing Framework Setup (Any Language)**\n\n#### **Framework Selection Guide**\n\n**Python Projects:**\n- **pytest**: Recommended for most Python projects\n- **unittest**: Built-in, suitable for simple projects\n- **Coverage**: Use `coverage.py` for code coverage\n\n```bash\n# Python setup example\npip install pytest pytest-cov\necho \"[tool:pytest]\" > pytest.ini\necho \"testpaths = tests\" >> pytest.ini\necho \"addopts = --cov=src --cov-report=html --cov-report=term\" >> pytest.ini\n```\n\n**Go Projects:**\n- **Built-in testing**: Use Go's built-in `testing` package\n- **Coverage**: Built-in with `go test -cover`\n\n```bash\n# Go setup example\ngo mod init your-project\nmkdir -p tests\n# Tests are typically *_test.go files alongside source\n```\n\n**Rust Projects:**\n- **Built-in testing**: Use Rust's built-in test framework\n- **cargo-tarpaulin**: For coverage analysis\n\n```bash\n# Rust setup example\ncargo new your-project\ncd your-project\ncargo install cargo-tarpaulin  # For coverage\n```\n\n**Java Projects:**\n- **JUnit 5**: Modern testing framework\n- **Maven/Gradle**: Build tools with testing integration\n\n```xml\n<!-- Maven pom.xml example -->\n<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter</artifactId>\n    <version>5.9.2</version>\n    <scope>test</scope>\n</dependency>\n```\n\n#### **Universal Testing Principles**\n\n**Coverage Standards (Adapt to Your Language):**\n- **Global Minimum**: 70-80% line coverage\n- **Critical Code**: 85-90% coverage\n- **New Features**: Must meet or exceed standards\n- **Legacy Code**: Gradual improvement strategy\n\n**Test Organization:**\n- **Unit Tests**: Fast, isolated, no external dependencies\n- **Integration Tests**: Test component interactions\n- **E2E Tests**: Test complete user workflows\n- **Performance Tests**: Load and stress testing (if applicable)\n\n**Naming Conventions:**\n- **Test Files**: `*.test.*`, `*_test.*`, or language-specific patterns\n- **Test Functions**: Descriptive names (e.g., `should_return_error_for_invalid_input`)\n- **Test Directories**: Organized by test type and mirroring source structure\n\n#### **TaskMaster Integration for Any Framework**\n\n**Document Testing Setup in Subtasks:**\n```bash\n# Update subtask with testing framework setup\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework setup:\n- Installed [Framework Name] with coverage support\n- Configured [Coverage Tool] with thresholds: 80% lines, 70% branches\n- Created test directory structure: unit/, integration/, e2e/\n- Added test scripts to build configuration\n- All setup tests passing\"\n```\n\n**Testing Framework Verification:**\n```bash\n# Verify setup works\n[test-command]  # e.g., npm test, pytest, go test, cargo test\n\n# Check coverage reporting\n[coverage-command]  # e.g., npm run test:coverage\n\n# Update task with verification\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework verified:\n- Sample tests running successfully\n- Coverage reporting functional\n- CI/CD integration ready\n- Ready to begin TDD workflow\"\n```\n\n## **Test-Driven Development (TDD) Integration**\n\n### **Core TDD Cycle with Jest**\n```bash\n# 1. Start development with watch mode\nnpm run test:watch\n\n# 2. Write failing test first\n# Create test file: src/utils/newFeature.test.ts\n# Write test that describes expected behavior\n\n# 3. Implement minimum code to make test pass\n# 4. Refactor while keeping tests green\n# 5. Add edge cases and error scenarios\n```\n\n### **TDD Workflow Per Subtask**\n```bash\n# When starting a new subtask:\ntask-master set-status --id=4.1 --status=in-progress\n\n# Begin TDD cycle:\nnpm run test:watch  # Keep running during development\n\n# Document TDD progress in subtask:\ntask-master update-subtask --id=4.1 --prompt=\"TDD Progress:\n- Written 3 failing tests for core functionality\n- Implemented basic feature, tests now passing\n- Adding edge case tests for error handling\"\n\n# Complete subtask with test summary:\ntask-master update-subtask --id=4.1 --prompt=\"Implementation complete:\n- Feature implemented with 8 unit tests\n- Coverage: 95% statements, 88% branches  \n- All tests passing, TDD cycle complete\"\n```\n\n## **Testing Commands & Usage**\n\n### **Development Commands**\n```bash\n# Primary development command - use during coding\nnpm run test:watch              # Watch mode with Jest\nnpm run test:watch -- --testNamePattern=\"auth\"  # Watch specific tests\n\n# Targeted testing during development\nnpm run test:unit               # Run only unit tests\nnpm run test:unit -- --coverage # Unit tests with coverage\n\n# Integration testing when APIs are ready\nnpm run test:integration        # Run integration tests\nnpm run test:integration -- --detectOpenHandles  # Debug hanging tests\n\n# End-to-end testing for workflows\nnpm run test:e2e               # Run E2E tests\nnpm run test:e2e -- --timeout=30000  # Extended timeout for E2E\n```\n\n### **Quality Assurance Commands**\n```bash\n# Full test suite with coverage (before commits)\nnpm run test:coverage          # Complete coverage analysis\n\n# All tests (CI/CD pipeline)\nnpm test                       # Run all test projects\n\n# Specific test file execution\nnpm test -- auth.test.ts       # Run specific test file\nnpm test -- --testNamePattern=\"should handle errors\"  # Run specific tests\n```\n\n## **Test Implementation Patterns**\n\n### **Unit Test Development**\n```typescript\n// ✅ DO: Follow established patterns from auth.test.ts\ndescribe('FeatureName', () => {\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Setup mocks with proper typing\n  });\n\n  describe('functionName', () => {\n    it('should handle normal case', () => {\n      // Test implementation with specific assertions\n    });\n    \n    it('should throw error for invalid input', async () => {\n      // Error scenario testing\n      await expect(functionName(invalidInput))\n        .rejects.toThrow('Specific error message');\n    });\n  });\n});\n```\n\n### **Integration Test Development**  \n```typescript\n// ✅ DO: Use supertest for API endpoint testing\nimport request from 'supertest';\nimport { app } from '../../src/app';\n\ndescribe('POST /api/auth/register', () => {\n  beforeEach(async () => {\n    await integrationTestUtils.cleanupTestData();\n  });\n  \n  it('should register user successfully', async () => {\n    const userData = createTestUser();\n    \n    const response = await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n      \n    expect(response.body).toMatchObject({\n      id: expect.any(String),\n      email: userData.email\n    });\n    \n    // Verify database state\n    const user = await prisma.user.findUnique({\n      where: { email: userData.email }\n    });\n    expect(user).toBeTruthy();\n  });\n});\n```\n\n### **E2E Test Development**\n```typescript\n// ✅ DO: Test complete user workflows\ndescribe('User Authentication Flow', () => {\n  it('should complete registration → login → protected access', async () => {\n    // Step 1: Register\n    const userData = createTestUser();\n    await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n    \n    // Step 2: Login\n    const loginResponse = await request(app)\n      .post('/api/auth/login')\n      .send({ email: userData.email, password: userData.password })\n      .expect(200);\n    \n    const { token } = loginResponse.body;\n    \n    // Step 3: Access protected resource\n    await request(app)\n      .get('/api/profile')\n      .set('Authorization', `Bearer ${token}`)\n      .expect(200);\n  }, 30000); // Extended timeout for E2E\n});\n```\n\n## **Mocking & Test Utilities**\n\n### **Established Mocking Patterns**\n```typescript\n// ✅ DO: Use established bcrypt mocking pattern\njest.mock('bcrypt');\nimport bcrypt from 'bcrypt';\nconst mockHash = bcrypt.hash as jest.MockedFunction<typeof bcrypt.hash>;\nconst mockCompare = bcrypt.compare as jest.MockedFunction<typeof bcrypt.compare>;\n\n// ✅ DO: Use Prisma mocking for unit tests\njest.mock('@prisma/client', () => ({\n  PrismaClient: jest.fn().mockImplementation(() => ({\n    user: {\n      create: jest.fn(),\n      findUnique: jest.fn(),\n    },\n    $connect: jest.fn(),\n    $disconnect: jest.fn(),\n  })),\n}));\n```\n\n### **Test Fixtures Usage**\n```typescript\n// ✅ DO: Use centralized test fixtures\nimport { createTestUser, adminUser, invalidUser } from '../fixtures/users';\n\ndescribe('User Service', () => {\n  it('should handle admin user creation', async () => {\n    const userData = createTestUser(adminUser);\n    // Test implementation\n  });\n  \n  it('should reject invalid user data', async () => {\n    const userData = createTestUser(invalidUser);\n    // Error testing\n  });\n});\n```\n\n## **Coverage Standards & Monitoring**\n\n### **Coverage Thresholds**\n- **Global Standards**: 80% lines/functions, 70% branches\n- **Critical Code**: 90% utils, 85% middleware\n- **New Features**: Must meet or exceed global thresholds\n- **Legacy Code**: Gradual improvement with each change\n\n### **Coverage Reporting & Analysis**\n```bash\n# Generate coverage reports\nnpm run test:coverage\n\n# View detailed HTML report\nopen coverage/lcov-report/index.html\n\n# Coverage files generated:\n# - coverage/lcov-report/index.html  # Detailed HTML report\n# - coverage/lcov.info               # LCOV format for IDE integration  \n# - coverage/coverage-final.json     # JSON format for tooling\n```\n\n### **Coverage Quality Checks**\n```typescript\n// ✅ DO: Test all code paths\ndescribe('validateInput', () => {\n  it('should return true for valid input', () => {\n    expect(validateInput('valid')).toBe(true);\n  });\n  \n  it('should return false for various invalid inputs', () => {\n    expect(validateInput('')).toBe(false);      // Empty string\n    expect(validateInput(null)).toBe(false);    // Null value\n    expect(validateInput(undefined)).toBe(false); // Undefined\n  });\n  \n  it('should throw for unexpected input types', () => {\n    expect(() => validateInput(123)).toThrow('Invalid input type');\n  });\n});\n```\n\n## **Testing During Development Phases**\n\n### **Feature Development Phase**\n```bash\n# 1. Start feature development\ntask-master set-status --id=X.Y --status=in-progress\n\n# 2. Begin TDD cycle  \nnpm run test:watch\n\n# 3. Document test progress in subtask\ntask-master update-subtask --id=X.Y --prompt=\"Test development:\n- Created test file with 5 failing tests\n- Implemented core functionality\n- Tests passing, adding error scenarios\"\n\n# 4. Verify coverage before completion\nnpm run test:coverage\n\n# 5. Update subtask with final test status\ntask-master update-subtask --id=X.Y --prompt=\"Testing complete:\n- 12 unit tests with full coverage\n- All edge cases and error scenarios covered\n- Ready for integration testing\"\n```\n\n### **Integration Testing Phase**\n```bash\n# After API endpoints are implemented\nnpm run test:integration\n\n# Update integration test templates\n# Replace placeholder tests with real endpoint calls\n\n# Document integration test results\ntask-master update-subtask --id=X.Y --prompt=\"Integration tests:\n- Updated auth endpoint tests  \n- Database integration verified\n- All HTTP status codes and responses tested\"\n```\n\n### **Pre-Commit Testing Phase**\n```bash\n# Before committing code\nnpm run test:coverage         # Verify all tests pass with coverage\nnpm run test:unit            # Quick unit test verification\nnpm run test:integration     # Integration test verification (if applicable)\n\n# Commit pattern for test updates\ngit add tests/ src/**/*.test.ts\ngit commit -m \"test(task-X): Add comprehensive tests for Feature Y\n\n- Unit tests with 95% coverage (exceeds 90% threshold)\n- Integration tests for API endpoints\n- Test fixtures for data generation\n- Proper mocking patterns established\n\nTask X: Feature Y - Testing complete\"\n```\n\n## **Error Handling & Debugging**\n\n### **Test Debugging Techniques**\n```typescript\n// ✅ DO: Use test utilities for debugging\nimport { testUtils } from '../setup';\n\nit('should debug complex operation', () => {\n  testUtils.withConsole(() => {\n    // Console output visible only for this test\n    console.log('Debug info:', complexData);\n    service.complexOperation();\n  });\n});\n\n// ✅ DO: Use proper async debugging\nit('should handle async operations', async () => {\n  const promise = service.asyncOperation();\n  \n  // Test intermediate state\n  expect(service.isProcessing()).toBe(true);\n  \n  const result = await promise;\n  expect(result).toBe('expected');\n  expect(service.isProcessing()).toBe(false);\n});\n```\n\n### **Common Test Issues & Solutions**\n```bash\n# Hanging tests (common with database connections)\nnpm run test:integration -- --detectOpenHandles\n\n# Memory leaks in tests\nnpm run test:unit -- --logHeapUsage\n\n# Slow tests identification\nnpm run test:coverage -- --verbose\n\n# Mock not working properly\n# Check: mock is declared before imports\n# Check: jest.clearAllMocks() in beforeEach\n# Check: TypeScript typing is correct\n```\n\n## **Continuous Integration Integration**\n\n### **CI/CD Pipeline Testing**\n```yaml\n# Example GitHub Actions integration\n- name: Run tests\n  run: |\n    npm ci\n    npm run test:coverage\n    \n- name: Upload coverage reports\n  uses: codecov/codecov-action@v3\n  with:\n    file: ./coverage/lcov.info\n```\n\n### **Pre-commit Hooks**\n```bash\n# Setup pre-commit testing (recommended)\n# In package.json scripts:\n\"pre-commit\": \"npm run test:unit && npm run test:integration\"\n\n# Husky integration example:\nnpx husky add .husky/pre-commit \"npm run test:unit\"\n```\n\n## **Test Maintenance & Evolution**\n\n### **Adding Tests for New Features**\n1. **Create test file** alongside source code or in `tests/unit/`\n2. **Follow established patterns** from `src/utils/auth.test.ts`\n3. **Use existing fixtures** from `tests/fixtures/`\n4. **Apply proper mocking** patterns for dependencies\n5. **Meet coverage thresholds** for the module\n\n### **Updating Integration/E2E Tests**\n1. **Update templates** in `tests/integration/` when APIs change\n2. **Modify E2E workflows** in `tests/e2e/` for new user journeys  \n3. **Update test fixtures** for new data requirements\n4. **Maintain database cleanup** utilities\n\n### **Test Performance Optimization**\n- **Parallel execution**: Jest runs tests in parallel by default\n- **Test isolation**: Use proper setup/teardown for independence\n- **Mock optimization**: Mock heavy dependencies appropriately  \n- **Database efficiency**: Use transaction rollbacks where possible\n\n---\n\n**Key References:**\n- [Testing Standards](mdc:.cursor/rules/tests.mdc)\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc)\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Jest Configuration](mdc:jest.config.js)",".cursor/rules/tests.mdc":"---\ndescription: Guidelines for implementing and maintaining tests for Task Master CLI\nglobs: \"**/*.test.js,tests/**/*\"\n---\n\n# Testing Guidelines for Task Master CLI\n\n*Note:* Never use asynchronous operations in tests. Always mock tests properly based on the way the tested functions are defined and used. Do not arbitrarily create tests. Based them on the low-level details and execution of the underlying code being tested. \n\n## Test Organization Structure\n\n- **Unit Tests** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module breakdown)\n  - Located in `tests/unit/`\n  - Test individual functions and utilities in isolation\n  - Mock all external dependencies\n  - Keep tests small, focused, and fast\n  - Example naming: `utils.test.js`, `task-manager.test.js`\n\n- **Integration Tests**\n  - Located in `tests/integration/`\n  - Test interactions between modules\n  - Focus on component interfaces rather than implementation details\n  - Use more realistic but still controlled test environments\n  - Example naming: `task-workflow.test.js`, `command-integration.test.js`\n\n- **End-to-End Tests**\n  - Located in `tests/e2e/`\n  - Test complete workflows from a user perspective\n  - Focus on CLI commands as they would be used by users\n  - Example naming: `create-task.e2e.test.js`, `expand-task.e2e.test.js`\n\n- **Test Fixtures**\n  - Located in `tests/fixtures/`\n  - Provide reusable test data\n  - Keep fixtures small and representative\n  - Export fixtures as named exports for reuse\n\n## Test File Organization\n\n```javascript\n// 1. Imports\nimport { jest } from '@jest/globals';\n\n// 2. Mock setup (MUST come before importing the modules under test)\njest.mock('fs');\njest.mock('@anthropic-ai/sdk');\njest.mock('../../scripts/modules/utils.js', () => ({\n  CONFIG: {\n    projectVersion: '1.5.0'\n  },\n  log: jest.fn()\n}));\n\n// 3. Import modules AFTER all mocks are defined\nimport { functionToTest } from '../../scripts/modules/module-name.js';\nimport { testFixture } from '../fixtures/fixture-name.js';\nimport fs from 'fs';\n\n// 4. Set up spies on mocked modules (if needed)\nconst mockReadFileSync = jest.spyOn(fs, 'readFileSync');\n\n// 5. Test suite with descriptive name\ndescribe('Feature or Function Name', () => {\n  // 6. Setup and teardown (if needed)\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Additional setup code\n  });\n  \n  afterEach(() => {\n    // Cleanup code\n  });\n  \n  // 7. Grouped tests for related functionality\n  describe('specific functionality', () => {\n    // 8. Individual test cases with clear descriptions\n    test('should behave in expected way when given specific input', () => {\n      // Arrange - set up test data\n      const input = testFixture.sampleInput;\n      mockReadFileSync.mockReturnValue('mocked content');\n      \n      // Act - call the function being tested\n      const result = functionToTest(input);\n      \n      // Assert - verify the result\n      expect(result).toBe(expectedOutput);\n      expect(mockReadFileSync).toHaveBeenCalledWith(expect.stringContaining('path'));\n    });\n  });\n});\n```\n\n## Commander.js Command Testing Best Practices\n\nWhen testing CLI commands built with Commander.js, several special considerations must be made to avoid common pitfalls:\n\n- **Direct Action Handler Testing**\n  - ✅ **DO**: Test the command action handlers directly rather than trying to mock the entire Commander.js chain\n  - ✅ **DO**: Create simplified test-specific implementations of command handlers that match the original behavior\n  - ✅ **DO**: Explicitly handle all options, including defaults and shorthand flags (e.g., `-p` for `--prompt`)\n  - ✅ **DO**: Include null/undefined checks in test implementations for parameters that might be optional\n  - ✅ **DO**: Use fixtures from `tests/fixtures/` for consistent sample data across tests\n  \n  ```javascript\n  // ✅ DO: Create a simplified test version of the command handler\n  const testAddTaskAction = async (options) => {\n    options = options || {}; // Ensure options aren't undefined\n    \n    // Validate parameters\n    const isManualCreation = options.title && options.description;\n    const prompt = options.prompt || options.p; // Handle shorthand flags\n    \n    if (!prompt && !isManualCreation) {\n      throw new Error('Expected error message');\n    }\n    \n    // Call the mocked task manager\n    return mockTaskManager.addTask(/* parameters */);\n  };\n  \n  test('should handle required parameters correctly', async () => {\n    // Call the test implementation directly\n    await expect(async () => {\n      await testAddTaskAction({ file: 'tasks.json' });\n    }).rejects.toThrow('Expected error message');\n  });\n  ```\n\n- **Commander Chain Mocking (If Necessary)**\n  - ✅ **DO**: Mock ALL chainable methods (`option`, `argument`, `action`, `on`, etc.)\n  - ✅ **DO**: Return `this` (or the mock object) from all chainable method mocks\n  - ✅ **DO**: Remember to mock not only the initial object but also all objects returned by methods\n  - ✅ **DO**: Implement a mechanism to capture the action handler for direct testing\n  \n  ```javascript\n  // If you must mock the Commander.js chain:\n  const mockCommand = {\n    command: jest.fn().mockReturnThis(),\n    description: jest.fn().mockReturnThis(),\n    option: jest.fn().mockReturnThis(),\n    argument: jest.fn().mockReturnThis(), // Don't forget this one\n    action: jest.fn(fn => { \n      actionHandler = fn; // Capture the handler for testing\n      return mockCommand; \n    }),\n    on: jest.fn().mockReturnThis() // Don't forget this one\n  };\n  ```\n\n- **Parameter Handling**\n  - ✅ **DO**: Check for both main flag and shorthand flags (e.g., `prompt` and `p`)\n  - ✅ **DO**: Handle parameters like Commander would (comma-separated lists, etc.)\n  - ✅ **DO**: Set proper default values as defined in the command\n  - ✅ **DO**: Validate that required parameters are actually required in tests\n  \n  ```javascript\n  // Parse dependencies like Commander would\n  const dependencies = options.dependencies \n    ? options.dependencies.split(',').map(id => id.trim())\n    : [];\n  ```\n\n- **Environment and Session Handling**\n  - ✅ **DO**: Properly mock session objects when required by functions\n  - ✅ **DO**: Reset environment variables between tests if modified\n  - ✅ **DO**: Use a consistent pattern for environment-dependent tests\n  \n  ```javascript\n  // Session parameter mock pattern\n  const sessionMock = { session: process.env };\n  \n  // In test:\n  expect(mockAddTask).toHaveBeenCalledWith(\n    expect.any(String),\n    'Test prompt',\n    [],\n    'medium',\n    sessionMock,\n    false,\n    null,\n    null\n  );\n  ```\n\n- **Common Pitfalls to Avoid**\n  - ❌ **DON'T**: Try to use the real action implementation without proper mocking\n  - ❌ **DON'T**: Mock Commander partially - either mock it completely or test the action directly\n  - ❌ **DON'T**: Forget to handle optional parameters that may be undefined\n  - ❌ **DON'T**: Neglect to test shorthand flag functionality (e.g., `-p`, `-r`)\n  - ❌ **DON'T**: Create circular dependencies in your test mocks\n  - ❌ **DON'T**: Access variables before initialization in your test implementations\n  - ❌ **DON'T**: Include actual command execution in unit tests\n  - ❌ **DON'T**: Overwrite the same file path in multiple tests\n  \n  ```javascript\n  // ❌ DON'T: Create circular references in mocks\n  const badMock = {\n    method: jest.fn().mockImplementation(() => badMock.method())\n  };\n  \n  // ❌ DON'T: Access uninitialized variables\n  const badImplementation = () => {\n    const result = uninitialized;\n    let uninitialized = 'value';\n    return result;\n  };\n  ```\n\n## Jest Module Mocking Best Practices\n\n- **Mock Hoisting Behavior**\n  - Jest hoists `jest.mock()` calls to the top of the file, even above imports\n  - Always declare mocks before importing the modules being tested\n  - Use the factory pattern for complex mocks that need access to other variables\n\n  ```javascript\n  // ✅ DO: Place mocks before imports\n  jest.mock('commander');\n  import { program } from 'commander';\n  \n  // ❌ DON'T: Define variables and then try to use them in mocks\n  const mockFn = jest.fn();\n  jest.mock('module', () => ({\n    func: mockFn // This won't work due to hoisting!\n  }));\n  ```\n\n- **Mocking Modules with Function References**\n  - Use `jest.spyOn()` after imports to create spies on mock functions\n  - Reference these spies in test assertions\n  \n  ```javascript\n  // Mock the module first\n  jest.mock('fs');\n  \n  // Import the mocked module\n  import fs from 'fs';\n  \n  // Create spies on the mock functions\n  const mockExistsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(true);\n  \n  test('should call existsSync', () => {\n    // Call function that uses fs.existsSync\n    const result = functionUnderTest();\n    \n    // Verify the mock was called correctly\n    expect(mockExistsSync).toHaveBeenCalled();\n  });\n  ```\n\n- **Testing Functions with Callbacks**\n  - Get the callback from your mock's call arguments\n  - Execute it directly with test inputs\n  - Verify the results match expectations\n  \n  ```javascript\n  jest.mock('commander');\n  import { program } from 'commander';\n  import { setupCLI } from '../../scripts/modules/commands.js';\n  \n  const mockVersion = jest.spyOn(program, 'version').mockReturnValue(program);\n  \n  test('version callback should return correct version', () => {\n    // Call the function that registers the callback\n    setupCLI();\n    \n    // Extract the callback function\n    const versionCallback = mockVersion.mock.calls[0][0];\n    expect(typeof versionCallback).toBe('function');\n    \n    // Execute the callback and verify results\n    const result = versionCallback();\n    expect(result).toBe('1.5.0');\n  });\n  ```\n\n## ES Module Testing Strategies\n\nWhen testing ES modules (`\"type\": \"module\"` in package.json), traditional mocking approaches require special handling to avoid reference and scoping issues.\n\n- **Module Import Challenges**\n  - Functions imported from ES modules may still reference internal module-scoped variables\n  - Imported functions may not use your mocked dependencies even with proper jest.mock() setup\n  - ES module exports are read-only properties (cannot be reassigned during tests)\n\n- **Mocking Modules Statically Imported**\n  - For modules imported with standard `import` statements at the top level:\n    - Use `jest.mock('path/to/module', factory)` **before** any imports.\n    - Jest hoists these mocks.\n    - Ensure the factory function returns the mocked structure correctly.\n\n- **Mocking Dependencies for Dynamically Imported Modules**\n  - **Problem**: Standard `jest.mock()` often fails for dependencies of modules loaded later using dynamic `import('path/to/module')`. The mocks aren't applied correctly when the dynamic import resolves.\n  - **Solution**: Use `jest.unstable_mockModule(modulePath, factory)` **before** the dynamic `import()` call.\n  ```javascript\n  // 1. Define mock function instances\n  const mockExistsSync = jest.fn();\n  const mockReadFileSync = jest.fn();\n  // ... other mocks\n\n  // 2. Mock the dependency module *before* the dynamic import\n  jest.unstable_mockModule('fs', () => ({\n    __esModule: true, // Important for ES module mocks\n    // Mock named exports\n    existsSync: mockExistsSync,\n    readFileSync: mockReadFileSync,\n    // Mock default export if necessary\n    // default: { ... }\n  }));\n\n  // 3. Dynamically import the module under test (e.g., in beforeAll or test case)\n  let moduleUnderTest;\n  beforeAll(async () => {\n    // Ensure mocks are reset if needed before import\n    mockExistsSync.mockReset();\n    mockReadFileSync.mockReset();\n    // ... reset other mocks ...\n\n    // Import *after* unstable_mockModule is called\n    moduleUnderTest = await import('../../scripts/modules/module-using-fs.js');\n  });\n\n  // 4. Now tests can use moduleUnderTest, and its 'fs' calls will hit the mocks\n  test('should use mocked fs.readFileSync', () => {\n    mockReadFileSync.mockReturnValue('mock data');\n    moduleUnderTest.readFileAndProcess();\n    expect(mockReadFileSync).toHaveBeenCalled();\n    // ... other assertions\n  });\n  ```\n  - ✅ **DO**: Call `jest.unstable_mockModule()` before `await import()`.\n  - ✅ **DO**: Include `__esModule: true` in the mock factory for ES modules.\n  - ✅ **DO**: Mock named and default exports as needed within the factory.\n  - ✅ **DO**: Reset mock functions (`mockFn.mockReset()`) before the dynamic import if they might have been called previously.\n\n- **Mocking Entire Modules (Static Import)**\n  ```javascript\n  // Mock the entire module with custom implementation for static imports\n  // ... (existing example remains valid) ...\n  ```\n\n- **Direct Implementation Testing**\n  - Instead of calling the actual function which may have module-scope reference issues:\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Avoiding Module Property Assignment**\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Handling Mock Verification Failures**\n  - If verification like `expect(mockFn).toHaveBeenCalled()` fails:\n    1.  Check that your mock setup (`jest.mock` or `jest.unstable_mockModule`) is correctly placed **before** imports (static or dynamic).\n    2.  Ensure you're using the right mock instance and it's properly passed to the module.\n    3.  Verify your test invokes behavior that *should* call the mock.\n    4.  Use `jest.clearAllMocks()` or specific `mockFn.mockReset()` in `beforeEach` to prevent state leakage between tests.\n    5.  **Check Console Assertions**: If verifying `console.log`, `console.warn`, or `console.error` calls, ensure your assertion matches the *actual* arguments passed. If the code logs a single formatted string, assert against that single string (using `expect.stringContaining` or exact match), not multiple `expect.stringContaining` arguments.\n        ```javascript\n        // Example: Code logs console.error(`Error: ${message}. Details: ${details}`)\n        // ❌ DON'T: Assert multiple arguments if only one is logged\n        // expect(console.error).toHaveBeenCalledWith(\n        //   expect.stringContaining('Error:'),\n        //   expect.stringContaining('Details:')\n        // );\n        // ✅ DO: Assert the single string argument\n        expect(console.error).toHaveBeenCalledWith(\n           expect.stringContaining('Error: Specific message. Details: More details')\n        );\n        // or for exact match:\n        expect(console.error).toHaveBeenCalledWith(\n           'Error: Specific message. Details: More details'\n        );\n        ```\n    6.  Consider implementing a simpler test that *only* verifies the mock behavior in isolation.\n\n## Mocking Guidelines\n\n- **File System Operations**\n  ```javascript\n  import mockFs from 'mock-fs';\n  \n  beforeEach(() => {\n    mockFs({\n      'tasks': {\n        'tasks.json': JSON.stringify({\n          meta: { projectName: 'Test Project' },\n          tasks: []\n        })\n      }\n    });\n  });\n  \n  afterEach(() => {\n    mockFs.restore();\n  });\n  ```\n\n- **API Calls (Anthropic/Claude)**\n  ```javascript\n  import { Anthropic } from '@anthropic-ai/sdk';\n  \n  jest.mock('@anthropic-ai/sdk');\n  \n  beforeEach(() => {\n    Anthropic.mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ text: 'Mocked response' }]\n        })\n      }\n    }));\n  });\n  ```\n\n- **Environment Variables**\n  ```javascript\n  const originalEnv = process.env;\n  \n  beforeEach(() => {\n    jest.resetModules();\n    process.env = { ...originalEnv };\n    process.env.MODEL = 'test-model';\n  });\n  \n  afterEach(() => {\n    process.env = originalEnv;\n  });\n  ```\n\n## Testing Common Components\n\n- **CLI Commands**\n  - Mock the action handlers (defined in [`commands.js`](mdc:scripts/modules/commands.js)) and verify they're called with correct arguments\n  - Test command registration and option parsing\n  - Use `commander` test utilities or custom mocks\n\n- **Task Operations**\n  - Use sample task fixtures for consistent test data\n  - Mock file system operations\n  - Test both success and error paths\n\n- **UI Functions**\n  - Mock console output and verify correct formatting\n  - Test conditional output logic\n  - When testing strings with emojis or formatting, use `toContain()` or `toMatch()` rather than exact `toBe()` comparisons\n  - For functions with different behavior modes (e.g., `forConsole`, `forTable` parameters), create separate tests for each mode\n  - Test the structure of formatted output (e.g., check that it's a comma-separated list with the right number of items) rather than exact string matching\n  - When testing chalk-formatted output, remember that strict equality comparison (`toBe()`) can fail even when the visible output looks identical\n  - Consider using more flexible assertions like checking for the presence of key elements when working with styled text\n  - Mock chalk functions to return the input text to make testing easier while still verifying correct function calls\n\n## Test Quality Guidelines\n\n- ✅ **DO**: Write tests before implementing features (TDD approach when possible)\n- ✅ **DO**: Test edge cases and error conditions, not just happy paths\n- ✅ **DO**: Keep tests independent and isolated from each other\n- ✅ **DO**: Use descriptive test names that explain the expected behavior\n- ✅ **DO**: Maintain test fixtures separate from test logic\n- ✅ **DO**: Aim for 80%+ code coverage, with critical paths at 100%\n- ✅ **DO**: Follow the mock-first-then-import pattern for all Jest mocks\n\n- ❌ **DON'T**: Test implementation details that might change\n- ❌ **DON'T**: Write brittle tests that depend on specific output formatting\n- ❌ **DON'T**: Skip testing error handling and validation\n- ❌ **DON'T**: Duplicate test fixtures across multiple test files\n- ❌ **DON'T**: Write tests that depend on execution order\n- ❌ **DON'T**: Define mock variables before `jest.mock()` calls (they won't be accessible due to hoisting)\n\n\n- **Task File Operations**\n  - ✅ DO: Use test-specific file paths (e.g., 'test-tasks.json') for all operations\n  - ✅ DO: Mock `readJSON` and `writeJSON` to avoid real file system interactions\n  - ✅ DO: Verify file operations use the correct paths in `expect` statements\n  - ✅ DO: Use different paths for each test to avoid test interdependence\n  - ✅ DO: Verify modifications on the in-memory task objects passed to `writeJSON`\n  - ❌ DON'T: Modify real task files (tasks.json) during tests\n  - ❌ DON'T: Skip testing file operations because they're \"just I/O\"\n  \n  ```javascript\n  // ✅ DO: Test file operations without real file system changes\n  test('should update task status in tasks.json', async () => {\n    // Setup mock to return sample data\n    readJSON.mockResolvedValue(JSON.parse(JSON.stringify(sampleTasks)));\n    \n    // Use test-specific file path\n    await setTaskStatus('test-tasks.json', '2', 'done');\n    \n    // Verify correct file path was read\n    expect(readJSON).toHaveBeenCalledWith('test-tasks.json');\n    \n    // Verify correct file path was written with updated content\n    expect(writeJSON).toHaveBeenCalledWith(\n      'test-tasks.json',\n      expect.objectContaining({\n        tasks: expect.arrayContaining([\n          expect.objectContaining({\n            id: 2,\n            status: 'done'\n          })\n        ])\n      })\n    );\n  });\n  ```\n\n## Running Tests\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Run tests with coverage reporting\nnpm run test:coverage\n\n# Run a specific test file\nnpm test -- tests/unit/specific-file.test.js\n\n# Run tests matching a pattern\nnpm test -- -t \"pattern to match\"\n```\n\n## Troubleshooting Test Issues\n\n- **Mock Functions Not Called**\n  - Ensure mocks are defined before imports (Jest hoists `jest.mock()` calls)\n  - Check that you're referencing the correct mock instance\n  - Verify the import paths match exactly\n\n- **Unexpected Mock Behavior**\n  - Clear mocks between tests with `jest.clearAllMocks()` in `beforeEach`\n  - Check mock implementation for conditional behavior\n  - Ensure mock return values are correctly configured for each test\n\n- **Tests Affecting Each Other**\n  - Isolate tests by properly mocking shared resources\n  - Reset state in `beforeEach` and `afterEach` hooks\n  - Avoid global state modifications\n\n## Common Testing Pitfalls and Solutions\n\n- **Complex Library Mocking**\n  - **Problem**: Trying to create full mocks of complex libraries like Commander.js can be error-prone\n  - **Solution**: Instead of mocking the entire library, test the command handlers directly by calling your action handlers with the expected arguments\n  ```javascript\n  // ❌ DON'T: Create complex mocks of Commander.js\n  class MockCommand {\n    constructor() { /* Complex mock implementation */ }\n    option() { /* ... */ }\n    action() { /* ... */ }\n    // Many methods to implement\n  }\n  \n  // ✅ DO: Test the command handlers directly\n  test('should use default PRD path when no arguments provided', async () => {\n    // Call the action handler directly with the right params\n    await parsePrdAction(undefined, { numTasks: '10', output: 'tasks/tasks.json' });\n    \n    // Assert on behavior\n    expect(mockParsePRD).toHaveBeenCalledWith('scripts/prd.txt', 'tasks/tasks.json', 10);\n  });\n  ```\n\n- **ES Module Mocking Challenges**\n  - **Problem**: ES modules don't support `require()` and imports are read-only\n  - **Solution**: Use Jest's module factory pattern and ensure mocks are defined before imports\n  ```javascript\n  // ❌ DON'T: Try to modify imported modules\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  detectCamelCaseFlags = jest.fn(); // Error: Assignment to constant variable\n  \n  // ❌ DON'T: Try to use require with ES modules\n  const utils = require('../../scripts/modules/utils.js'); // Error in ES modules\n  \n  // ✅ DO: Use Jest module factory pattern\n  jest.mock('../../scripts/modules/utils.js', () => ({\n    detectCamelCaseFlags: jest.fn(),\n    toKebabCase: jest.fn()\n  }));\n  \n  // Import after mocks are defined\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  ```\n\n- **Function Redeclaration Errors**\n  - **Problem**: Declaring the same function twice in a test file causes errors\n  - **Solution**: Use different function names or create local test-specific implementations\n  ```javascript\n  // ❌ DON'T: Redefine imported functions with the same name\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  \n  function detectCamelCaseFlags() { /* Test implementation */ }\n  // Error: Identifier has already been declared\n  \n  // ✅ DO: Use a different name for test implementations\n  function testDetectCamelCaseFlags() { /* Test implementation */ }\n  ```\n\n- **Console.log Circular References**\n  - **Problem**: Creating infinite recursion by spying on console.log while also allowing it to log\n  - **Solution**: Implement a mock that doesn't call the original function\n  ```javascript\n  // ❌ DON'T: Create circular references with console.log\n  const mockConsoleLog = jest.spyOn(console, 'log');\n  mockConsoleLog.mockImplementation(console.log); // Creates infinite recursion\n  \n  // ✅ DO: Use a non-recursive mock implementation\n  const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => {});\n  ```\n\n- **Mock Function Method Issues**\n  - **Problem**: Trying to use jest.fn() methods on imported functions that aren't properly mocked\n  - **Solution**: Create explicit jest.fn() mocks for functions you need to call jest methods on\n  ```javascript\n  // ❌ DON'T: Try to use jest methods on imported functions without proper mocking\n  import { parsePRD } from '../../scripts/modules/task-manager.js';\n  parsePRD.mockClear(); // Error: parsePRD.mockClear is not a function\n  \n  // ✅ DO: Create proper jest.fn() mocks\n  const mockParsePRD = jest.fn().mockResolvedValue(undefined);\n  jest.mock('../../scripts/modules/task-manager.js', () => ({\n    parsePRD: mockParsePRD\n  }));\n  // Now you can use:\n  mockParsePRD.mockClear();\n  ```\n\n- **EventEmitter Max Listeners Warning**\n  - **Problem**: Commander.js adds many listeners in complex mocks, causing warnings\n  - **Solution**: Either increase the max listeners limit or avoid deep mocking\n  ```javascript\n  // Option 1: Increase max listeners if you must mock Commander\n  class MockCommand extends EventEmitter {\n    constructor() {\n      super();\n      this.setMaxListeners(20); // Avoid MaxListenersExceededWarning\n    }\n  }\n  \n  // Option 2 (preferred): Test command handlers directly instead\n  // (as shown in the first example)\n  ```\n\n- **Test Isolation Issues**\n  - **Problem**: Tests affecting each other due to shared mock state\n  - **Solution**: Reset all mocks in beforeEach and use separate test-specific mocks\n  ```javascript\n  // ❌ DON'T: Allow mock state to persist between tests\n  const globalMock = jest.fn().mockReturnValue('test');\n  \n  // ✅ DO: Clear mocks before each test\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Set up test-specific mock behavior\n    mockFunction.mockReturnValue('test-specific value');\n  });\n  ```\n\n## Testing AI Service Integrations\n\n- **DO NOT import real AI service clients**\n  - ❌ DON'T: Import actual AI clients from their libraries\n  - ✅ DO: Create fully mocked versions that return predictable responses\n\n  ```javascript\n  // ❌ DON'T: Import and instantiate real AI clients\n  import { Anthropic } from '@anthropic-ai/sdk';\n  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n\n  // ✅ DO: Mock the entire module with controlled behavior\n  jest.mock('@anthropic-ai/sdk', () => ({\n    Anthropic: jest.fn().mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ type: 'text', text: 'Mocked AI response' }]\n        })\n      }\n    }))\n  }));\n  ```\n\n- **DO NOT rely on environment variables for API keys**\n  - ❌ DON'T: Assume environment variables are set in tests\n  - ✅ DO: Set mock environment variables in test setup\n\n  ```javascript\n  // In tests/setup.js or at the top of test file\n  process.env.ANTHROPIC_API_KEY = 'test-mock-api-key-for-tests';\n  process.env.PERPLEXITY_API_KEY = 'test-mock-perplexity-key-for-tests';\n  ```\n\n- **DO NOT use real AI client initialization logic**\n  - ❌ DON'T: Use code that attempts to initialize or validate real AI clients\n  - ✅ DO: Create test-specific paths that bypass client initialization\n\n  ```javascript\n  // ❌ DON'T: Test functions that require valid AI client initialization\n  // This will fail without proper API keys or network access\n  test('should use AI client', async () => {\n    const result = await functionThatInitializesAIClient();\n    expect(result).toBeDefined();\n  });\n\n  // ✅ DO: Test with bypassed initialization or manual task paths\n  test('should handle manual task creation without AI', () => {\n    // Using a path that doesn't require AI client initialization\n    const result = addTaskDirect({ \n      title: 'Manual Task', \n      description: 'Test Description'\n    }, mockLogger);\n    \n    expect(result.success).toBe(true);\n  });\n  ```\n\n## Testing Asynchronous Code\n\n- **DO NOT rely on asynchronous operations in tests**\n  - ❌ DON'T: Use real async/await or Promise resolution in tests\n  - ✅ DO: Make all mocks return synchronous values when possible\n\n  ```javascript\n  // ❌ DON'T: Use real async functions that might fail unpredictably\n  test('should handle async operation', async () => {\n    const result = await realAsyncFunction(); // Can time out or fail for external reasons\n    expect(result).toBe(expectedValue);\n  });\n\n  // ✅ DO: Make async operations synchronous in tests\n  test('should handle operation', () => {\n    mockAsyncFunction.mockReturnValue({ success: true, data: 'test' });\n    const result = functionUnderTest();\n    expect(result).toEqual({ success: true, data: 'test' });\n  });\n  ```\n\n- **DO NOT test exact error messages**\n  - ❌ DON'T: Assert on exact error message text that might change\n  - ✅ DO: Test for error presence and general properties\n\n  ```javascript\n  // ❌ DON'T: Test for exact error message text\n  expect(result.error).toBe('Could not connect to API: Network error');\n\n  // ✅ DO: Test for general error properties or message patterns\n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Could not connect');\n  // Or even better:\n  expect(result).toMatchObject({ \n    success: false,\n    error: expect.stringContaining('connect')\n  });\n  ```\n\n## Reliable Testing Techniques\n\n- **Create Simplified Test Functions**\n  - Create simplified versions of complex functions that focus only on core logic\n  - Remove file system operations, API calls, and other external dependencies\n  - Pass all dependencies as parameters to make testing easier\n  \n  ```javascript\n  // Original function (hard to test)\n  const setTaskStatus = async (taskId, newStatus) => {\n    const tasksPath = 'tasks/tasks.json';\n    const data = await readJSON(tasksPath);\n    // [implementation]\n    await writeJSON(tasksPath, data);\n    return { success: true };\n  };\n  \n  // Test-friendly version (easier to test)\n  const updateTaskStatus = (tasks, taskId, newStatus) => {\n    // Pure logic without side effects\n    const updatedTasks = [...tasks];\n    const taskIndex = findTaskById(updatedTasks, taskId);\n    if (taskIndex === -1) return { success: false, error: 'Task not found' };\n    updatedTasks[taskIndex].status = newStatus;\n    return { success: true, tasks: updatedTasks };\n  };\n  ```\n\nSee [tests/README.md](mdc:tests/README.md) for more details on the testing approach.\n\nRefer to [jest.config.js](mdc:jest.config.js) for Jest configuration options.\n\n## Variable Hoisting and Module Initialization Issues\n\nWhen testing ES modules or working with complex module imports, you may encounter variable hoisting and initialization issues. These can be particularly tricky to debug and often appear as \"Cannot access 'X' before initialization\" errors.\n\n- **Understanding Module Initialization Order**\n  - ✅ **DO**: Declare and initialize global variables at the top of modules\n  - ✅ **DO**: Use proper function declarations to avoid hoisting issues\n  - ✅ **DO**: Initialize variables before they are referenced, especially in imported modules\n  - ✅ **DO**: Be aware that imports are hoisted to the top of the file\n  \n  ```javascript\n  // ✅ DO: Define global state variables at the top of the module\n  let silentMode = false; // Declare and initialize first\n  \n  const CONFIG = { /* configuration */ };\n  \n  function isSilentMode() {\n    return silentMode; // Reference variable after it's initialized\n  }\n  \n  function log(level, message) {\n    if (isSilentMode()) return; // Use the function instead of accessing variable directly\n    // ...\n  }\n  ```\n\n- **Testing Modules with Initialization-Dependent Functions**\n  - ✅ **DO**: Create test-specific implementations that initialize all variables correctly\n  - ✅ **DO**: Use factory functions in mocks to ensure proper initialization order\n  - ✅ **DO**: Be careful with how you mock or stub functions that depend on module state\n  \n  ```javascript\n  // ✅ DO: Test-specific implementation that avoids initialization issues\n  const testLog = (level, ...args) => {\n    // Local implementation with proper initialization\n    const isSilent = false; // Explicit initialization\n    if (isSilent) return;\n    // Test implementation...\n  };\n  ```\n\n- **Common Hoisting-Related Errors to Avoid**\n  - ❌ **DON'T**: Reference variables before their declaration in module scope\n  - ❌ **DON'T**: Create circular dependencies between modules\n  - ❌ **DON'T**: Rely on variable initialization order across module boundaries\n  - ❌ **DON'T**: Define functions that use hoisted variables before they're initialized\n  \n  ```javascript\n  // ❌ DON'T: Create reference-before-initialization patterns\n  function badFunction() {\n    if (silentMode) { /* ... */ } // ReferenceError if silentMode is declared later\n  }\n  \n  let silentMode = false;\n  \n  // ❌ DON'T: Create cross-module references that depend on initialization order\n  // module-a.js\n  import { getSetting } from './module-b.js';\n  export const config = { value: getSetting() };\n  \n  // module-b.js\n  import { config } from './module-a.js';\n  export function getSetting() {\n    return config.value; // Circular dependency causing initialization issues\n  }\n  ```\n\n- **Dynamic Imports as a Solution**\n  - ✅ **DO**: Use dynamic imports (`import()`) to avoid initialization order issues\n  - ✅ **DO**: Structure modules to avoid circular dependencies that cause initialization issues\n  - ✅ **DO**: Consider factory functions for modules with complex state\n  \n  ```javascript\n  // ✅ DO: Use dynamic imports to avoid initialization issues\n  async function getTaskManager() {\n    return import('./task-manager.js');\n  }\n  \n  async function someFunction() {\n    const taskManager = await getTaskManager();\n    return taskManager.someMethod();\n  }\n  ```\n\n- **Testing Approach for Modules with Initialization Issues**\n  - ✅ **DO**: Create self-contained test implementations rather than using real implementations\n  - ✅ **DO**: Mock dependencies at module boundaries instead of trying to mock deep dependencies\n  - ✅ **DO**: Isolate module-specific state in tests\n  \n  ```javascript\n  // ✅ DO: Create isolated test implementation instead of reusing module code\n  test('should log messages when not in silent mode', () => {\n    // Local test implementation instead of importing from module\n    const testLog = (level, message) => {\n      if (false) return; // Always non-silent for this test\n      mockConsole(level, message);\n    };\n    \n    testLog('info', 'test message');\n    expect(mockConsole).toHaveBeenCalledWith('info', 'test message');\n  });\n  ``` ",".cursor/rules/ui.mdc":"---\ndescription: Guidelines for implementing and maintaining user interface components\nglobs: scripts/modules/ui.js\nalwaysApply: false\n---\n\n# User Interface Implementation Guidelines\n\n## Core UI Component Principles\n\n- **Function Scope Separation**:\n  - ✅ DO: Keep display logic separate from business logic\n  - ✅ DO: Import data processing functions from other modules\n  - ❌ DON'T: Include task manipulations within UI functions\n  - ❌ DON'T: Create circular dependencies with other modules\n\n- **Standard Display Pattern**:\n  ```javascript\n  // ✅ DO: Follow this pattern for display functions\n  /**\n   * Display information about a task\n   * @param {Object} task - The task to display\n   */\n  function displayTaskInfo(task) {\n    console.log(boxen(\n      chalk.white.bold(`Task: #${task.id} - ${task.title}`),\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n## Visual Styling Standards\n\n- **Color Scheme**:\n  - Use `chalk.blue` for informational messages\n  - Use `chalk.green` for success messages\n  - Use `chalk.yellow` for warnings\n  - Use `chalk.red` for errors\n  - Use `chalk.cyan` for prompts and highlights\n  - Use `chalk.magenta` for subtask-related information\n\n- **Box Styling**:\n  ```javascript\n  // ✅ DO: Use consistent box styles by content type\n  // For success messages:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'green', \n    borderStyle: 'round', \n    margin: { top: 1 } \n  })\n\n  // For errors:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'red', \n    borderStyle: 'round'\n  })\n\n  // For information:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'blue', \n    borderStyle: 'round', \n    margin: { top: 1, bottom: 1 } \n  })\n  ```\n\n## Table Display Guidelines\n\n- **Table Structure**:\n  - Use [`cli-table3`](mdc:node_modules/cli-table3/README.md) for consistent table rendering\n  - Include colored headers with bold formatting\n  - Use appropriate column widths for readability\n\n  ```javascript\n  // ✅ DO: Create well-structured tables\n  const table = new Table({\n    head: [\n      chalk.cyan.bold('ID'),\n      chalk.cyan.bold('Title'),\n      chalk.cyan.bold('Status'),\n      chalk.cyan.bold('Priority'),\n      chalk.cyan.bold('Dependencies')\n    ],\n    colWidths: [5, 40, 15, 10, 20]\n  });\n  \n  // Add content rows\n  table.push([\n    task.id,\n    truncate(task.title, 37),\n    getStatusWithColor(task.status),\n    chalk.white(task.priority || 'medium'),\n    formatDependenciesWithStatus(task.dependencies, allTasks, true)\n  ]);\n  \n  console.log(table.toString());\n  ```\n\n## Loading Indicators\n\n- **Animation Standards**:\n  - Use [`ora`](mdc:node_modules/ora/readme.md) for spinner animations\n  - Create and stop loading indicators correctly\n\n  ```javascript\n  // ✅ DO: Properly manage loading state\n  const loadingIndicator = startLoadingIndicator('Processing task data...');\n  try {\n    // Do async work...\n    stopLoadingIndicator(loadingIndicator);\n    // Show success message\n  } catch (error) {\n    stopLoadingIndicator(loadingIndicator);\n    // Show error message\n  }\n  ```\n\n## Helper Functions\n\n- **Status Formatting**:\n  - Use `getStatusWithColor` for consistent status display\n  - Use `formatDependenciesWithStatus` for dependency lists\n  - Use `truncate` to handle text that may overflow display\n\n- **Progress Reporting**:\n  - Use visual indicators for progress (bars, percentages)\n  - Include both numeric and visual representations\n  \n  ```javascript\n  // ✅ DO: Show clear progress indicators\n  console.log(`${chalk.cyan('Tasks:')} ${completedTasks}/${totalTasks} (${completionPercentage.toFixed(1)}%)`);\n  console.log(`${chalk.cyan('Progress:')} ${createProgressBar(completionPercentage)}`);\n  ```\n\n## Command Suggestions\n\n- **Action Recommendations**:\n  - Provide next step suggestions after command completion\n  - Use a consistent format for suggested commands\n\n  ```javascript\n  // ✅ DO: Show suggested next actions\n  console.log(boxen(\n    chalk.white.bold('Next Steps:') + '\\n\\n' +\n    `${chalk.cyan('1.')} Run ${chalk.yellow('task-master list')} to view all tasks\\n` +\n    `${chalk.cyan('2.')} Run ${chalk.yellow('task-master show --id=' + newTaskId)} to view details`,\n    { padding: 1, borderColor: 'cyan', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Enhanced Display Patterns\n\n### **Token Breakdown Display**\n- Use detailed, granular token breakdowns for AI-powered commands\n- Display context sources with individual token counts\n- Show both token count and character count for transparency\n\n  ```javascript\n  // ✅ DO: Display detailed token breakdown\n  function displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    if (tokenBreakdown.tasks?.length > 0) {\n      const taskDetails = tokenBreakdown.tasks.map(task => \n        `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n      ).join('\\n');\n      sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n      title: chalk.cyan('Token Usage'),\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      borderStyle: 'round',\n      borderColor: 'cyan'\n    }));\n  }\n  ```\n\n### **Code Block Syntax Highlighting**\n- Use `cli-highlight` library for syntax highlighting in terminal output\n- Process code blocks in AI responses for better readability\n\n  ```javascript\n  // ✅ DO: Enhance code blocks with syntax highlighting\n  import { highlight } from 'cli-highlight';\n  \n  function processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n      try {\n        const highlighted = highlight(code.trim(), { \n          language: language || 'javascript',\n          theme: 'default'\n        });\n        return `\\n${highlighted}\\n`;\n      } catch (error) {\n        return `\\n${code.trim()}\\n`;\n      }\n    });\n  }\n  ```\n\n### **Multi-Section Result Display**\n- Use separate boxes for headers, content, and metadata\n- Maintain consistent styling across different result types\n\n  ```javascript\n  // ✅ DO: Use structured result display\n  function displayResults(result, query, detailLevel) {\n    // Header with query info\n    const header = boxen(\n      chalk.green.bold('Research Results') + '\\n\\n' +\n      chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n      chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n      {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 1, bottom: 0 },\n        borderStyle: 'round',\n        borderColor: 'green'\n      }\n    );\n    console.log(header);\n    \n    // Process and display main content\n    const processedResult = processCodeBlocks(result);\n    const contentBox = boxen(processedResult, {\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      margin: { top: 0, bottom: 1 },\n      borderStyle: 'single',\n      borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Operation complete'));\n  }\n  ```\n\nRefer to [`ui.js`](mdc:scripts/modules/ui.js) for implementation examples, [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for context display patterns, and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ",".cursor/rules/utilities.mdc":"---\ndescription: \nglobs: \nalwaysApply: false\n---\n# Utility Function Guidelines\n\n## General Principles\n\n- **Function Scope**:\n  - ✅ DO: Create utility functions that serve multiple modules\n  - ✅ DO: Keep functions single-purpose and focused\n  - ❌ DON'T: Include business logic in utility functions\n  - ❌ DON'T: Create utilities with side effects\n\n  ```javascript\n  // ✅ DO: Create focused, reusable utilities\n  /**\n   * Truncates text to a specified length\n   * @param {string} text - The text to truncate\n   * @param {number} maxLength - The maximum length\n   * @returns {string} The truncated text\n   */\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n  ```javascript\n  // ❌ DON'T: Add side effects to utilities\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    \n    // Side effect - modifying global state or logging\n    console.log(`Truncating text from ${text.length} to ${maxLength} chars`);\n    \n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n- **Location**:\n    - **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).\n    - **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.\n        - Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils) (e.g., `path-utils.js`).\n        - Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n\n## Documentation Standards\n\n- **JSDoc Format**:\n  - ✅ DO: Document all parameters and return values\n  - ✅ DO: Include descriptions for complex logic\n  - ✅ DO: Add examples for non-obvious usage\n  - ❌ DON'T: Skip documentation for \"simple\" functions\n\n  ```javascript\n  // ✅ DO: Provide complete JSDoc documentation\n  /**\n   * Reads and parses a JSON file\n   * @param {string} filepath - Path to the JSON file\n   * @returns {Object|null} Parsed JSON data or null if error occurs\n   */\n  function readJSON(filepath) {\n    try {\n      const rawData = fs.readFileSync(filepath, 'utf8');\n      return JSON.parse(rawData);\n    } catch (error) {\n      log('error', `Error reading JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n      return null;\n    }\n  }\n  ```\n\n## Configuration Management (via `config-manager.js`)\n\nTaskmaster configuration (excluding API keys) is primarily managed through the `.taskmasterconfig` file located in the project root and accessed via getters in [`scripts/modules/config-manager.js`](mdc:scripts/modules/config-manager.js).\n\n- **`.taskmasterconfig` File**:\n  - ✅ DO: Use this JSON file to store settings like AI model selections (main, research, fallback), parameters (temperature, maxTokens), logging level, default priority/subtasks, etc.\n  - ✅ DO: Manage this file using the `task-master models --setup` CLI command or the `models` MCP tool.\n  - ✅ DO: Rely on [`config-manager.js`](mdc:scripts/modules/config-manager.js) to load this file (using the correct project root passed from MCP or found via CLI utils), merge with defaults, and provide validated settings.\n  - ❌ DON'T: Store API keys in this file.\n  - ❌ DON'T: Manually edit this file unless necessary.\n\n- **Configuration Getters (`config-manager.js`)**:\n  - ✅ DO: Import and use specific getters from `config-manager.js` (e.g., `getMainProvider()`, `getLogLevel()`, `getMainMaxTokens()`) to access configuration values *needed for application logic* (like `getDefaultSubtasks`).\n  - ✅ DO: Pass the `explicitRoot` parameter to getters if calling from MCP direct functions to ensure the correct project's config is loaded.\n  - ❌ DON'T: Call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions (`scripts/modules/task-manager/*`). Instead, pass the `role` to the unified AI service.\n  - ❌ DON'T: Access configuration values directly from environment variables (except API keys).\n\n- **API Key Handling (`utils.js` & `ai-services-unified.js`)**:\n  - ✅ DO: Store API keys **only** in `.env` (for CLI, loaded by `dotenv` in `scripts/dev.js`) or `.cursor/mcp.json` (for MCP, accessed via `session.env`).\n  - ✅ DO: Use `isApiKeySet(providerName, session)` from `config-manager.js` to check if a provider's key is available *before* potentially attempting an AI call if needed, but note the unified service performs its own internal check.\n  - ✅ DO: Understand that the unified service layer (`ai-services-unified.js`) internally resolves API keys using `resolveEnvVariable(key, session)` from `utils.js`.\n\n- **Error Handling**:\n  - ✅ DO: Handle potential `ConfigurationError` if the `.taskmasterconfig` file is missing or invalid when accessed via `getConfig` (e.g., in `commands.js` or direct functions).\n\n## Logging Utilities (in `scripts/modules/utils.js`)\n\n- **Log Levels**:\n  - ✅ DO: Support multiple log levels (debug, info, warn, error)\n  - ✅ DO: Use appropriate icons for different log levels\n  - ✅ DO: Respect the configured log level\n  - ❌ DON'T: Add direct console.log calls outside the logging utility\n  - **Note on Passed Loggers**: When a logger object (like the FastMCP `log` object) is passed *as a parameter* (e.g., as `mcpLog`) into core Task Master functions, the receiving function often expects specific methods (`.info`, `.warn`, `.error`, etc.) to be directly callable on that object (e.g., `mcpLog[level](mdc:...)`). If the passed logger doesn't have this exact structure, a wrapper object may be needed. See the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for the standard pattern used in direct functions.\n\n- **Logger Wrapper Pattern**: \n  - ✅ DO: Use the logger wrapper pattern when passing loggers to prevent `mcpLog[level] is not a function` errors:\n  ```javascript\n  // Standard logWrapper pattern to wrap FastMCP's log object\n  const logWrapper = {\n    info: (message, ...args) => log.info(message, ...args),\n    warn: (message, ...args) => log.warn(message, ...args),\n    error: (message, ...args) => log.error(message, ...args),\n    debug: (message, ...args) => log.debug && log.debug(message, ...args),\n    success: (message, ...args) => log.info(message, ...args) // Map success to info\n  };\n  \n  // Pass this wrapper as mcpLog to ensure consistent method availability\n  // This also ensures output format is set to 'json' in many core functions\n  const options = { mcpLog: logWrapper, session };\n  ```\n  - ✅ DO: Implement this pattern in any direct function that calls core functions expecting `mcpLog`\n  - ✅ DO: Use this solution in conjunction with silent mode for complete output control\n  - ❌ DON'T: Pass the FastMCP `log` object directly as `mcpLog` to core functions\n  - **Important**: This pattern has successfully fixed multiple issues in MCP tools (e.g., `update-task`, `update-subtask`) where using or omitting `mcpLog` incorrectly led to runtime errors or JSON parsing failures.\n  - For complete implementation details, see the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc).\n\n  ```javascript\n  // ✅ DO: Implement a proper logging utility\n  const LOG_LEVELS = {\n    debug: 0,\n    info: 1,\n    warn: 2,\n    error: 3\n  };\n  \n  function log(level, ...args) {\n    const icons = {\n      debug: chalk.gray('🔍'),\n      info: chalk.blue('ℹ️'),\n      warn: chalk.yellow('⚠️'),\n      error: chalk.red('❌'),\n      success: chalk.green('✅')\n    };\n    \n    if (LOG_LEVELS[level] >= LOG_LEVELS[CONFIG.logLevel]) {\n      const icon = icons[level] || '';\n      console.log(`${icon} ${args.join(' ')}`);\n    }\n  }\n  ```\n\n## Silent Mode Utilities (in `scripts/modules/utils.js`)\n\n- **Silent Mode Control**:\n  - ✅ DO: Use the exported silent mode functions rather than accessing global variables\n  - ✅ DO: Always use `isSilentMode()` to check the current silent mode state\n  - ✅ DO: Ensure silent mode is disabled in a `finally` block to prevent it from staying enabled\n  - ❌ DON'T: Access the global `silentMode` variable directly\n  - ❌ DON'T: Forget to disable silent mode after enabling it\n\n  ```javascript\n  // ✅ DO: Use the silent mode control functions properly\n  \n  // Example of proper implementation in utils.js:\n  \n  // Global silent mode flag (private to the module)\n  let silentMode = false;\n  \n  // Enable silent mode\n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  // Disable silent mode\n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  // Check if silent mode is enabled\n  function isSilentMode() {\n    return silentMode;\n  }\n  \n  // Example of proper usage in another module:\n  import { enableSilentMode, disableSilentMode, isSilentMode } from './utils.js';\n  \n  // Check current status\n  if (!isSilentMode()) {\n    console.log('Silent mode is not enabled');\n  }\n  \n  // Use try/finally pattern to ensure silent mode is disabled\n  try {\n    enableSilentMode();\n    // Do something that should suppress console output\n    performOperation();\n  } finally {\n    disableSilentMode();\n  }\n  ```\n\n- **Integration with Logging**:\n  - ✅ DO: Make the `log` function respect silent mode\n  ```javascript\n  function log(level, ...args) {\n    // Skip logging if silent mode is enabled\n    if (isSilentMode()) {\n      return;\n    }\n    \n    // Rest of logging logic...\n  }\n  ```\n\n- **Common Patterns for Silent Mode**:\n  - ✅ DO: In **direct functions** (`mcp-server/src/core/direct-functions/*`) that call **core functions** (`scripts/modules/*`), ensure console output from the core function is suppressed to avoid breaking MCP JSON responses.\n    - **Preferred Method**: Update the core function to accept an `outputFormat` parameter (e.g., `outputFormat = 'text'`) and make it check `outputFormat === 'text'` before displaying any UI elements (banners, spinners, boxes, direct `console.log`s). Pass `'json'` from the direct function.\n    - **Necessary Fallback/Guarantee**: If the core function *cannot* be modified or its output suppression via `outputFormat` is unreliable, **wrap the core function call within the direct function** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block. This acts as a safety net.\n  ```javascript\n  // Example in a direct function\n  export async function someOperationDirect(args, log) {\n    let result;\n    const tasksPath = findTasksJsonPath(args, log); // Get path first\n    \n    // Option 1: Core function handles 'json' format (Preferred)\n    try {\n      result = await coreFunction(tasksPath, ...otherArgs, 'json'); // Pass 'json'\n      return { success: true, data: result, fromCache: false };\n    } catch (error) {\n      // Handle error...\n    }\n\n    // Option 2: Core function output unreliable (Fallback/Guarantee)\n    try {\n      enableSilentMode(); // Enable before call\n      result = await coreFunction(tasksPath, ...otherArgs); // Call without format param\n    } catch (error) {\n      // Handle error...\n      log.error(`Failed: ${error.message}`);\n      return { success: false, error: { /* ... */ } };\n    } finally {\n      disableSilentMode(); // ALWAYS disable in finally\n    }\n    return { success: true, data: result, fromCache: false }; // Assuming success if no error caught\n  }\n  ```\n  - ✅ DO: For functions that accept a silent mode parameter but also need to check global state (less common):\n  ```javascript\n  // Check both the passed parameter and global silent mode\n  const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n  ```\n\n## File Operations (in `scripts/modules/utils.js`)\n\n- **Error Handling**:\n  - ✅ DO: Use try/catch blocks for all file operations\n  - ✅ DO: Return null or a default value on failure\n  - ✅ DO: Log detailed error information using the `log` utility\n  - ❌ DON'T: Allow exceptions to propagate unhandled from simple file reads/writes\n\n  ```javascript\n  // ✅ DO: Handle file operation errors properly in core utils\n  function writeJSON(filepath, data) {\n    try {\n      // Ensure directory exists (example)\n      const dir = path.dirname(filepath);\n      if (!fs.existsSync(dir)) {\n        fs.mkdirSync(dir, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Error writing JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n    }\n  }\n  ```\n\n## Task-Specific Utilities (in `scripts/modules/utils.js`)\n\n- **Task ID Formatting**:\n  - ✅ DO: Create utilities for consistent ID handling\n  - ✅ DO: Support different ID formats (numeric, string, dot notation)\n  - ❌ DON'T: Duplicate formatting logic across modules\n\n  ```javascript\n  // ✅ DO: Create utilities for common operations\n  /**\n   * Formats a task ID as a string\n   * @param {string|number} id - The task ID to format\n   * @returns {string} The formatted task ID\n   */\n  function formatTaskId(id) {\n    if (typeof id === 'string' && id.includes('.')) {\n      return id; // Already formatted as a string with a dot (e.g., \"1.2\")\n    }\n    \n    if (typeof id === 'number') {\n      return id.toString();\n    }\n    \n    return id;\n  }\n  ```\n\n- **Task Search**:\n  - ✅ DO: Implement reusable task finding utilities\n  - ✅ DO: Support both task and subtask lookups\n  - ✅ DO: Add context to subtask results\n\n  ```javascript\n  // ✅ DO: Create comprehensive search utilities\n  /**\n   * Finds a task by ID in the tasks array\n   * @param {Array} tasks - The tasks array\n   * @param {string|number} taskId - The task ID to find\n   * @returns {Object|null} The task object or null if not found\n   */\n  function findTaskById(tasks, taskId) {\n    if (!taskId || !tasks || !Array.isArray(tasks)) {\n      return null;\n    }\n    \n    // Check if it's a subtask ID (e.g., \"1.2\")\n    if (typeof taskId === 'string' && taskId.includes('.')) {\n      const [parentId, subtaskId] = taskId.split('.').map(id => parseInt(id, 10));\n      const parentTask = tasks.find(t => t.id === parentId);\n      \n      if (!parentTask || !parentTask.subtasks) {\n        return null;\n      }\n      \n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      if (subtask) {\n        // Add reference to parent task for context\n        subtask.parentTask = { \n          id: parentTask.id, \n          title: parentTask.title,\n          status: parentTask.status\n        };\n        subtask.isSubtask = true;\n      }\n      \n      return subtask || null;\n    }\n    \n    const id = parseInt(taskId, 10);\n    return tasks.find(t => t.id === id) || null;\n  }\n  ```\n\n## Cycle Detection (in `scripts/modules/utils.js`)\n\n- **Graph Algorithms**:\n  - ✅ DO: Implement cycle detection using graph traversal\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Return specific information about cycles\n\n  ```javascript\n  // ✅ DO: Implement proper cycle detection\n  /**\n   * Find cycles in a dependency graph using DFS\n   * @param {string} subtaskId - Current subtask ID\n   * @param {Map} dependencyMap - Map of subtask IDs to their dependencies\n   * @param {Set} visited - Set of visited nodes\n   * @param {Set} recursionStack - Set of nodes in current recursion stack\n   * @returns {Array} - List of dependency edges that need to be removed to break cycles\n   */\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set(), path = []) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    path.push(subtaskId);\n    \n    const cyclesToBreak = [];\n    \n    // Get all dependencies of the current subtask\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    // For each dependency\n    for (const depId of dependencies) {\n      // If not visited, recursively check for cycles\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack, [...path]);\n        cyclesToBreak.push(...cycles);\n      } \n      // If the dependency is in the recursion stack, we found a cycle\n      else if (recursionStack.has(depId)) {\n        // The last edge in the cycle is what we want to remove\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\n## MCP Server Core Utilities (`mcp-server/src/core/utils/`)\n\n### Project Root and Task File Path Detection (`path-utils.js`)\n\n- **Purpose**: This module ([`mcp-server/src/core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) provides the mechanism for locating the user's `tasks.json` file, used by direct functions.\n- **`findTasksJsonPath(args, log)`**:\n    - ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.\n    - Pass the *entire `args` object* received by the MCP tool (which should include `projectRoot` derived from the session) and the `log` object.\n    - Implements a **simplified precedence system** for finding the `tasks.json` path:\n        1.  Explicit `projectRoot` passed in `args` (Expected from MCP tools).\n        2.  Cached `lastFoundProjectRoot` (CLI fallback).\n        3.  Search upwards from `process.cwd()` (CLI fallback).\n    - Throws a specific error if the `tasks.json` file cannot be located.\n    - Updates the `lastFoundProjectRoot` cache on success.\n- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the CLI fallback search.\n- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself (potentially removable).\n\n## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)\n\nThese utilities specifically support the implementation and execution of MCP tools.\n\n- **`normalizeProjectRoot(rawPath, log)`**:\n    - **Purpose**: Takes a raw project root path (potentially URI encoded, with `file://` prefix, Windows slashes) and returns a normalized, absolute path suitable for the server's OS.\n    - **Logic**: Decodes URI, strips `file://`, handles Windows drive prefix (`/C:/`), replaces `\\` with `/`, uses `path.resolve()`.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF.\n\n- **`getRawProjectRootFromSession(session, log)`**:\n    - **Purpose**: Extracts the *raw* project root URI string from the session object (`session.roots[0].uri` or `session.roots.roots[0].uri`) without performing normalization.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF as a fallback if `args.projectRoot` isn't provided.\n\n- **`withNormalizedProjectRoot(executeFn)`**:\n    - **Purpose**: A Higher-Order Function (HOF) designed to wrap a tool's `execute` method.\n    - **Logic**: \n        1. Determines the raw project root (from `args.projectRoot` or `getRawProjectRootFromSession`).\n        2. Normalizes the raw path using `normalizeProjectRoot`.\n        3. Injects the normalized, absolute path back into the `args` object as `args.projectRoot`.\n        4. Calls the original `executeFn` with the updated `args`.\n    - **Usage**: Should wrap the `execute` function of *every* MCP tool that needs a reliable, normalized project root path.\n    - **Example**:\n      ```javascript\n      // In mcp-server/src/tools/your-tool.js\n      import { withNormalizedProjectRoot } from './utils.js';\n      \n      export function registerYourTool(server) {\n          server.addTool({\n              // ... name, description, parameters ...\n              execute: withNormalizedProjectRoot(async (args, context) => {\n                  // args.projectRoot is now normalized here\n                  const { projectRoot /*, other args */ } = args;\n                  // ... rest of tool logic using normalized projectRoot ...\n              })\n          });\n      }\n      ```\n\n- **`handleApiResult(result, log, errorPrefix, processFunction)`**:\n    - **Purpose**: Standardizes the formatting of responses returned by direct functions (`{ success, data/error, fromCache }`) into the MCP response format.\n    - **Usage**: Call this at the end of the tool's `execute` method, passing the result from the direct function call.\n\n- **`createContentResponse(content)` / `createErrorResponse(errorMessage)`**:\n    - **Purpose**: Helper functions to create the basic MCP response structure for success or error messages.\n    - **Usage**: Used internally by `handleApiResult` and potentially directly for simple responses.\n\n- **`createLogWrapper(log)`**:\n    - **Purpose**: Creates a logger object wrapper with standard methods (`info`, `warn`, `error`, `debug`, `success`) mapping to the passed MCP `log` object's methods. Ensures compatibility when passing loggers to core functions.\n    - **Usage**: Used within direct functions before passing the `log` object down to core logic that expects the standard method names.\n\n- **`getCachedOrExecute({ cacheKey, actionFn, log })`**:\n    - **Purpose**: Utility for implementing caching within direct functions. Checks cache for `cacheKey`; if miss, executes `actionFn`, caches successful result, and returns.\n    - **Usage**: Wrap the core logic execution within a direct function call.\n\n- **`processMCPResponseData(taskOrData, fieldsToRemove)`**:\n    - **Purpose**: Utility to filter potentially sensitive or large fields (like `details`, `testStrategy`) from task objects before sending the response back via MCP.\n    - **Usage**: Passed as the default `processFunction` to `handleApiResult`.\n\n- **`getProjectRootFromSession(session, log)`**:\n    - **Purpose**: Legacy function to extract *and normalize* the project root from the session. Replaced by the HOF pattern but potentially still used.\n    - **Recommendation**: Prefer using the `withNormalizedProjectRoot` HOF in tools instead of calling this directly.\n\n- **`executeTaskMasterCommand(...)`**: \n    - **Purpose**: Executes `task-master` CLI command as a fallback. \n    - **Recommendation**: Deprecated for most uses; prefer direct function calls.\n\n## Export Organization\n\n- **Grouping Related Functions**:\n  - ✅ DO: Keep utilities relevant to their location (e.g., core CLI utils in `scripts/modules/utils.js`, MCP path utils in `mcp-server/src/core/utils/path-utils.js`, MCP tool utils in `mcp-server/src/tools/utils.js`).\n  - ✅ DO: Export all utility functions in a single statement per file.\n  - ✅ DO: Group related exports together.\n  - ✅ DO: Export configuration constants (from `scripts/modules/utils.js`).\n  - ❌ DON'T: Use default exports.\n  - ❌ DON'T: Create circular dependencies (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)).\n\n```javascript\n// Example export from scripts/modules/utils.js\nexport {\n  // Configuration\n  CONFIG,\n  LOG_LEVELS,\n  \n  // Logging\n  log,\n  \n  // File operations\n  readJSON,\n  writeJSON,\n  \n  // String manipulation\n  sanitizePrompt,\n  truncate,\n  \n  // Task utilities\n  // ... (taskExists, formatTaskId, findTaskById, etc.)\n  \n  // Graph algorithms\n  findCycles,\n};\n\n// Example export from mcp-server/src/core/utils/path-utils.js\nexport {\n  findTasksJsonPath,\n  getPackagePath,\n  PROJECT_MARKERS,\n  lastFoundProjectRoot // Exporting for potential direct use/reset if needed\n};\n\n// Example export from mcp-server/src/tools/utils.js\nexport {\n  getProjectRoot,\n  getProjectRootFromSession,\n  handleApiResult,\n  executeTaskMasterCommand,\n  processMCPResponseData,\n  createContentResponse,\n  createErrorResponse,\n  getCachedOrExecute\n};\n```\n\n## Context Gathering Utilities\n\n### **ContextGatherer** (`scripts/modules/utils/contextGatherer.js`)\n\n- **Multi-Source Context Extraction**:\n  - ✅ DO: Use for AI-powered commands that need project context\n  - ✅ DO: Support tasks, files, custom text, and project tree context\n  - ✅ DO: Implement detailed token counting with `gpt-tokens` library\n  - ✅ DO: Provide multiple output formats (research, chat, system-prompt)\n\n  ```javascript\n  // ✅ DO: Use ContextGatherer for consistent context extraction\n  import { ContextGatherer } from '../utils/contextGatherer.js';\n  \n  const gatherer = new ContextGatherer(projectRoot, tasksPath);\n  const result = await gatherer.gather({\n    tasks: ['15', '16.2'],\n    files: ['src/api.js'],\n    customContext: 'Additional context',\n    includeProjectTree: true,\n    format: 'research',\n    includeTokenCounts: true\n  });\n  ```\n\n### **FuzzyTaskSearch** (`scripts/modules/utils/fuzzyTaskSearch.js`)\n\n- **Intelligent Task Discovery**:\n  - ✅ DO: Use for automatic task relevance detection\n  - ✅ DO: Configure search parameters based on use case context\n  - ✅ DO: Implement purpose-based categorization for better matching\n  - ✅ DO: Sort results by relevance score and task ID\n\n  ```javascript\n  // ✅ DO: Use FuzzyTaskSearch for intelligent task discovery\n  import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n  \n  const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n  const searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n  });\n  const taskIds = fuzzySearch.getTaskIds(searchResults);\n  ```\n\n- **Integration Guidelines**:\n  - ✅ DO: Use fuzzy search to supplement user-provided task IDs\n  - ✅ DO: Display discovered task IDs to users for transparency\n  - ✅ DO: Sort discovered task IDs numerically for better readability\n  - ❌ DON'T: Replace explicit user task selections with fuzzy results\n\nRefer to [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for detailed implementation patterns, [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for more context on MCP server architecture and integration. \n\n## File System Operations\n\n- **JSON File Handling**:\n  - ✅ DO: Use `readJSON` and `writeJSON` for all JSON operations\n  - ✅ DO: Include error handling for file operations\n  - ✅ DO: Validate JSON structure after reading\n  - ❌ DON'T: Use raw `fs.readFileSync` or `fs.writeFileSync` for JSON\n\n  ```javascript\n  // ✅ DO: Use utility functions with error handling\n  function readJSON(filepath) {\n    try {\n      if (!fs.existsSync(filepath)) {\n        return null; // or appropriate default\n      }\n      \n      let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n      \n      // Silent migration for tasks.json files: Transform old format to tagged format\n      const isTasksFile = filepath.includes('tasks.json') || path.basename(filepath) === 'tasks.json';\n      \n      if (data && data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n        // Migrate from old format { \"tasks\": [...] } to new format { \"master\": { \"tasks\": [...] } }\n        const migratedData = {\n          master: {\n            tasks: data.tasks\n          }\n        };\n        \n        writeJSON(filepath, migratedData);\n        \n        // Set global flag for CLI notice and perform complete migration\n        global.taskMasterMigrationOccurred = true;\n        performCompleteTagMigration(filepath);\n        \n        data = migratedData;\n      }\n      \n      return data;\n    } catch (error) {\n      log('error', `Failed to read JSON from ${filepath}: ${error.message}`);\n      return null;\n    }\n  }\n  \n  function writeJSON(filepath, data) {\n    try {\n      const dirPath = path.dirname(filepath);\n      if (!fs.existsSync(dirPath)) {\n        fs.mkdirSync(dirPath, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Failed to write JSON to ${filepath}: ${error.message}`);\n      throw error;\n    }\n  }\n  ```\n\n- **Path Resolution**:\n  - ✅ DO: Use `path.join()` for cross-platform path construction\n  - ✅ DO: Use `path.resolve()` for absolute paths\n  - ✅ DO: Validate paths before file operations\n\n  ```javascript\n  // ✅ DO: Handle paths correctly\n  function findProjectRoot(startPath = process.cwd()) {\n    let currentPath = path.resolve(startPath);\n    const rootPath = path.parse(currentPath).root;\n    \n    while (currentPath !== rootPath) {\n      const taskMasterPath = path.join(currentPath, '.taskmaster');\n      if (fs.existsSync(taskMasterPath)) {\n        return currentPath;\n      }\n      currentPath = path.dirname(currentPath);\n    }\n    \n    return null; // Not found\n  }\n  ```\n\n## Tagged Task Lists System Utilities\n\n- **Tag Resolution Functions**:\n  - ✅ DO: Use tag resolution layer for all task data access\n  - ✅ DO: Provide backward compatibility with legacy format\n  - ✅ DO: Default to \"master\" tag when no tag is specified\n\n  ```javascript\n  // ✅ DO: Implement tag resolution functions\n  function getTasksForTag(data, tagName = 'master') {\n    if (!data) {\n      return [];\n    }\n    \n    // Handle legacy format - direct tasks array\n    if (data.tasks && Array.isArray(data.tasks)) {\n      return data.tasks;\n    }\n    \n    // Handle tagged format - tasks under specific tag\n    if (data[tagName] && data[tagName].tasks && Array.isArray(data[tagName].tasks)) {\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  \n  function setTasksForTag(data, tagName = 'master', tasks) {\n    // Ensure data object exists\n    if (!data) {\n      data = {};\n    }\n    \n    // Create tag structure if it doesn't exist\n    if (!data[tagName]) {\n      data[tagName] = {};\n    }\n    \n    // Set tasks for the tag\n    data[tagName].tasks = tasks;\n    \n    return data;\n  }\n  \n  function getCurrentTag() {\n    // Get current tag from state.json or default to 'master'\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return 'master';\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (fs.existsSync(statePath)) {\n        const state = readJSON(statePath);\n        return state.currentTag || 'master';\n      }\n    } catch (error) {\n      log('debug', `Error reading current tag: ${error.message}`);\n    }\n    \n    return 'master';\n  }\n  ```\n\n- **Migration Functions**:\n  - ✅ DO: Implement complete migration for all related files\n  - ✅ DO: Handle configuration and state file creation\n  - ✅ DO: Provide migration status tracking\n\n  ```javascript\n  // ✅ DO: Implement complete migration system\n  function performCompleteTagMigration(tasksJsonPath) {\n    try {\n      // Derive project root from tasks.json path\n      const projectRoot = findProjectRoot(path.dirname(tasksJsonPath)) || path.dirname(tasksJsonPath);\n      \n      // 1. Migrate config.json - add defaultTag and tags section\n      const configPath = path.join(projectRoot, '.taskmaster', 'config.json');\n      if (fs.existsSync(configPath)) {\n        migrateConfigJson(configPath);\n      }\n      \n      // 2. Create state.json if it doesn't exist\n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (!fs.existsSync(statePath)) {\n        createStateJson(statePath);\n      }\n      \n      if (getDebugFlag()) {\n        log('debug', 'Completed tagged task lists migration for project');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error during complete tag migration: ${error.message}`);\n      }\n    }\n  }\n  \n  function migrateConfigJson(configPath) {\n    try {\n      const config = readJSON(configPath);\n      if (!config) return;\n      \n      let modified = false;\n      \n      // Add global.defaultTag if missing\n      if (!config.global) {\n        config.global = {};\n      }\n      if (!config.global.defaultTag) {\n        config.global.defaultTag = 'master';\n        modified = true;\n      }\n      \n      // Add tags section if missing\n      if (!config.tags) {\n        config.tags = {\n                  // Git integration settings removed - now manual only\n        };\n        modified = true;\n      }\n      \n      if (modified) {\n        writeJSON(configPath, config);\n        if (getDebugFlag()) {\n          log('debug', 'Updated config.json with tagged task system settings');\n        }\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error migrating config.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function createStateJson(statePath) {\n    try {\n      const initialState = {\n        currentTag: 'master',\n        lastSwitched: new Date().toISOString(),\n        migrationNoticeShown: false\n      };\n      \n      writeJSON(statePath, initialState);\n      if (getDebugFlag()) {\n        log('debug', 'Created initial state.json for tagged task system');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error creating state.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function markMigrationForNotice() {\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return;\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      const state = readJSON(statePath) || {};\n      \n      state.migrationNoticeShown = false; // Reset to show notice\n      writeJSON(statePath, state);\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error marking migration for notice: ${error.message}`);\n      }\n    }\n  }\n  ```\n\n## Logging Functions\n\n- **Consistent Logging**:\n  - ✅ DO: Use the central `log` function for all output\n  - ✅ DO: Use appropriate log levels (info, warn, error, debug)\n  - ✅ DO: Support silent mode for programmatic usage\n\n  ```javascript\n  // ✅ DO: Implement consistent logging with silent mode\n  let silentMode = false;\n  \n  function log(level, ...messages) {\n    if (silentMode && level !== 'error') {\n      return; // Suppress non-error logs in silent mode\n    }\n    \n    const timestamp = new Date().toISOString();\n    const formattedMessage = messages.join(' ');\n    \n    switch (level) {\n      case 'error':\n        console.error(`[ERROR] ${formattedMessage}`);\n        break;\n      case 'warn':\n        console.warn(`[WARN] ${formattedMessage}`);\n        break;\n      case 'info':\n        console.log(`[INFO] ${formattedMessage}`);\n        break;\n      case 'debug':\n        if (getDebugFlag()) {\n          console.log(`[DEBUG] ${formattedMessage}`);\n        }\n        break;\n      default:\n        console.log(formattedMessage);\n    }\n  }\n  \n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  function isSilentMode() {\n    return silentMode;\n  }\n  ```\n\n## Task Utilities\n\n- **Task Finding and Manipulation**:\n  - ✅ DO: Use tagged task system aware functions\n  - ✅ DO: Handle both task and subtask operations\n  - ✅ DO: Validate task IDs before operations\n\n  ```javascript\n  // ✅ DO: Implement tag-aware task utilities\n  function findTaskById(tasks, taskId) {\n    if (!Array.isArray(tasks)) {\n      return null;\n    }\n    return tasks.find(task => task.id === taskId) || null;\n  }\n  \n  function findSubtaskById(tasks, parentId, subtaskId) {\n    const parentTask = findTaskById(tasks, parentId);\n    if (!parentTask || !parentTask.subtasks) {\n      return null;\n    }\n    \n    return parentTask.subtasks.find(subtask => subtask.id === subtaskId) || null;\n  }\n  \n  function getNextTaskId(tasks) {\n    if (!Array.isArray(tasks) || tasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...tasks.map(task => task.id));\n    return maxId + 1;\n  }\n  \n  function getNextSubtaskId(parentTask) {\n    if (!parentTask.subtasks || parentTask.subtasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...parentTask.subtasks.map(subtask => subtask.id));\n    return maxId + 1;\n  }\n  ```\n\n## String Utilities\n\n- **Text Processing**:\n  - ✅ DO: Handle text truncation appropriately\n  - ✅ DO: Provide consistent formatting functions\n  - ✅ DO: Support different output formats\n\n  ```javascript\n  // ✅ DO: Implement useful string utilities\n  function truncate(str, maxLength = 50) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    if (str.length <= maxLength) {\n      return str;\n    }\n    \n    return str.substring(0, maxLength - 3) + '...';\n  }\n  \n  function formatDuration(ms) {\n    const seconds = Math.floor(ms / 1000);\n    const minutes = Math.floor(seconds / 60);\n    const hours = Math.floor(minutes / 60);\n    \n    if (hours > 0) {\n      return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n    } else if (minutes > 0) {\n      return `${minutes}m ${seconds % 60}s`;\n    } else {\n      return `${seconds}s`;\n    }\n  }\n  \n  function capitalizeFirst(str) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n  }\n  ```\n\n## Dependency Management Utilities\n\n- **Dependency Analysis**:\n  - ✅ DO: Detect circular dependencies\n  - ✅ DO: Validate dependency references\n  - ✅ DO: Support cross-tag dependency checking (future enhancement)\n\n  ```javascript\n  // ✅ DO: Implement dependency utilities\n  function findCycles(tasks) {\n    const cycles = [];\n    const visited = new Set();\n    const recStack = new Set();\n    \n    function dfs(taskId, path = []) {\n      if (recStack.has(taskId)) {\n        // Found a cycle\n        const cycleStart = path.indexOf(taskId);\n        const cycle = path.slice(cycleStart).concat([taskId]);\n        cycles.push(cycle);\n        return;\n      }\n      \n      if (visited.has(taskId)) {\n        return;\n      }\n      \n      visited.add(taskId);\n      recStack.add(taskId);\n      \n      const task = findTaskById(tasks, taskId);\n      if (task && task.dependencies) {\n        task.dependencies.forEach(depId => {\n          dfs(depId, path.concat([taskId]));\n        });\n      }\n      \n      recStack.delete(taskId);\n    }\n    \n    tasks.forEach(task => {\n      if (!visited.has(task.id)) {\n        dfs(task.id);\n      }\n    });\n    \n    return cycles;\n  }\n  \n  function validateDependencies(tasks) {\n    const validationErrors = [];\n    const taskIds = new Set(tasks.map(task => task.id));\n    \n    tasks.forEach(task => {\n      if (task.dependencies) {\n        task.dependencies.forEach(depId => {\n          if (!taskIds.has(depId)) {\n            validationErrors.push({\n              taskId: task.id,\n              invalidDependency: depId,\n              message: `Task ${task.id} depends on non-existent task ${depId}`\n            });\n          }\n        });\n      }\n    });\n    \n    return validationErrors;\n  }\n  ```\n\n## Environment and Configuration Utilities\n\n- **Environment Variable Resolution**:\n  - ✅ DO: Support both `.env` files and MCP session environment\n  - ✅ DO: Provide fallbacks for missing values\n  - ✅ DO: Handle API key resolution correctly\n\n  ```javascript\n  // ✅ DO: Implement flexible environment resolution\n  function resolveEnvVariable(key, sessionEnv = null) {\n    // First check session environment (for MCP)\n    if (sessionEnv && sessionEnv[key]) {\n      return sessionEnv[key];\n    }\n    \n    // Then check process environment\n    if (process.env[key]) {\n      return process.env[key];\n    }\n    \n    // Finally try .env file if in project root\n    try {\n      const projectRoot = findProjectRoot();\n      if (projectRoot) {\n        const envPath = path.join(projectRoot, '.env');\n        if (fs.existsSync(envPath)) {\n          const envContent = fs.readFileSync(envPath, 'utf8');\n          const lines = envContent.split('\\n');\n          \n          for (const line of lines) {\n            const [envKey, envValue] = line.split('=');\n            if (envKey && envKey.trim() === key) {\n              return envValue ? envValue.trim().replace(/^[\"']|[\"']$/g, '') : undefined;\n            }\n          }\n        }\n      }\n    } catch (error) {\n      log('debug', `Error reading .env file: ${error.message}`);\n    }\n    \n    return undefined;\n  }\n  \n  function getDebugFlag() {\n    const debugFlag = resolveEnvVariable('TASKMASTER_DEBUG') || \n                     resolveEnvVariable('DEBUG') || \n                     'false';\n    return debugFlag.toLowerCase() === 'true';\n  }\n  ```\n\n## Export Pattern\n\n- **Module Exports**:\n  - ✅ DO: Export all utility functions explicitly\n  - ✅ DO: Group related functions logically\n  - ✅ DO: Include new tagged system utilities\n\n  ```javascript\n  // ✅ DO: Export utilities in logical groups\n  module.exports = {\n    // File system utilities\n    readJSON,\n    writeJSON,\n    findProjectRoot,\n    \n    // Tagged task system utilities\n    getTasksForTag,\n    setTasksForTag,\n    getCurrentTag,\n    performCompleteTagMigration,\n    migrateConfigJson,\n    createStateJson,\n    markMigrationForNotice,\n    \n    // Logging utilities\n    log,\n    enableSilentMode,\n    disableSilentMode,\n    isSilentMode,\n    \n    // Task utilities\n    findTaskById,\n    findSubtaskById,\n    getNextTaskId,\n    getNextSubtaskId,\n    \n    // String utilities\n    truncate,\n    formatDuration,\n    capitalizeFirst,\n    \n    // Dependency utilities\n    findCycles,\n    validateDependencies,\n    \n    // Environment utilities\n    resolveEnvVariable,\n    getDebugFlag,\n    \n    // Legacy utilities (maintained for compatibility)\n    aggregateTelemetry\n  };\n  ```\n\nRefer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for integration patterns.\n",".taskmaster/CLAUDE.md":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nTask Master uses tiered tool loading to optimize context window usage:\n\n| Tier | Tools | Use Case |\n|------|-------|----------|\n| `core` | 7 | Minimal daily workflow tools (default) |\n| `standard` | 14 | Common task management |\n| `all` | 42+ | Full suite with research, autopilot, dependencies |\n\n**Core tools (7):** `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task`\n\n**Standard adds (7 more):** `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report`\n\n**All tier adds:** Dependency management, tag management, research, autopilot TDD workflow, scope up/down, models, rules\n\n**To upgrade tiers:** Change `TASK_MASTER_TOOLS` in `.mcp.json` from `\"core\"` to `\"standard\"` or `\"all\"` and restart the MCP connection.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","CLAUDE.md":"# Claude Code Instructions\n\n## Task Master AI Instructions\n\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n@./.taskmaster/CLAUDE.md\n\n## Test Guidelines\n\n### Test File Placement\n\n- **Package & tests**: Place in `packages/<package-name>/src/<module>/<file>.spec.ts` or `apps/<app-name>/src/<module>/<file.spec.ts>` alongside source\n- **Package integration tests**: Place in `packages/<package-name>/tests/integration/<module>/<file>.test.ts` or `apps/<app-name>/tests/integration/<module>/<file>.test.ts` alongside source\n- **Isolated unit tests**: Use `tests/unit/packages/<package-name>/` only when parallel placement isn't possible\n- **Test extension**: Always use `.ts` for TypeScript tests, never `.js`\n\n### Synchronous Tests\n\n- **NEVER use async/await in test functions** unless testing actual asynchronous operations\n- Use synchronous top-level imports instead of dynamic `await import()`\n- Test bodies should be synchronous whenever possible\n- Example:\n\n  ```typescript\n  // ✅ CORRECT - Synchronous imports with .ts extension\n  import { MyClass } from '../src/my-class.js';\n\n  it('should verify behavior', () => {\n    expect(new MyClass().property).toBe(value);\n  });\n\n  // ❌ INCORRECT - Async imports\n  it('should verify behavior', async () => {\n    const { MyClass } = await import('../src/my-class.js');\n    expect(new MyClass().property).toBe(value);\n  });\n  ```\n\n### When to Write Tests\n\n**ALWAYS write tests for:**\n\n- **Bug fixes**: Add a regression test that would have caught the bug\n- **Business logic**: Complex calculations, validations, transformations\n- **Edge cases**: Boundary conditions, error handling, null/undefined cases\n- **Public APIs**: Methods other code depends on\n- **Integration points**: Database, file system, external APIs\n\n**SKIP tests for:**\n\n- Simple getters/setters: `getX() { return this.x; }`\n- Trivial pass-through functions with no logic\n- Pure configuration objects\n- Code that just delegates to another tested function\n\n**Examples:**\n\n```javascript\n// ✅ WRITE A TEST - Bug fix with regression prevention\nit('should use correct baseURL from defaultBaseURL config', () => {\n  const provider = new ZAIProvider();\n  expect(provider.defaultBaseURL).toBe('https://api.z.ai/api/paas/v4/');\n});\n\n// ✅ WRITE A TEST - Business logic with edge cases\nit('should parse subtask IDs correctly', () => {\n  expect(parseTaskId('1.2.3')).toEqual({ taskId: 1, subtaskId: 2, subSubtaskId: 3 });\n  expect(parseTaskId('invalid')).toBeNull();\n});\n\n// ❌ SKIP TEST - Trivial getter\nclass Task {\n  get id() { return this._id; } // No test needed\n}\n\n// ❌ SKIP TEST - Pure delegation\nfunction getTasks() {\n  return taskManager.getTasks(); // Already tested in taskManager\n}\n```\n\n**Bug Fix Workflow:**\n\n1. Encounter a bug\n2. Write a failing test that reproduces it\n3. Fix the bug\n4. Verify test now passes\n5. Commit both fix and test together\n\n### Testing Guidelines\n\n**Principles**: FIRST (Fast, Independent, Repeatable, Self-validating, Timely)\n**Structure**: AAA (Arrange, Act, Assert)\n**Coverage**: Right-BICEP (Right results, Boundary, Inverse, Cross-check, Error conditions, Performance)\n\n#### What to Mock\n\n**Unit tests** (`.spec.ts` - test single unit in isolation):\n- **@tm/core**: Mock only external I/O (Supabase, APIs, filesystem). Use real internal services.\n- **apps/cli**: Mock tm-core responses. Use real Commander/chalk/inquirer/other npm packages (test display logic).\n- **apps/mcp**: Mock tm-core responses. Use real MCP framework (test response formatting).\n\n**Integration tests** (`tests/integration/` - test multiple units together):\n- **All packages**: Use real tm-core, mock only external boundaries (APIs, DB, filesystem).\n\n**Never mock**:\n- Internal utilities/helpers in the same package\n- Standard frameworks (Commander, Express) - let them run\n- Standard library\n\n**Rule of thumb**: Mock what you're NOT testing. CLI unit tests test display → mock tm-core. Core unit tests test logic → mock I/O. Integration tests test full flow → mock only external APIs.\n\n**Red flag**: Mocking 3+ dependencies in a unit test means code is doing too much or is in the wrong layer.\n\n**Anti-pattern**: Heavily mocked tests don't verify real behavior—they verify that you wired up mocks correctly. You end up writing orchestration code to satisfy tests, rather than tests that validate your actual implementation. If testing is hard, move the logic to where it's naturally testable.\n\n## Architecture Guidelines\n\n### Business Logic Separation\n\n**CRITICAL RULE**: ALL business logic must live in `@tm/core`, NOT in presentation layers.\n\n- **`@tm/core`** (packages/tm-core/):\n  - Contains ALL business logic, domain models, services, and utilities\n  - Provides clean facade APIs through domain objects (tasks, auth, workflow, git, config)\n  - Houses all complexity - parsing, validation, transformations, calculations, etc.\n  - Example: Task ID parsing, subtask extraction, status validation, dependency resolution\n\n- **`@tm/cli`** (apps/cli/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays results\n  - Handles CLI-specific concerns: argument parsing, output formatting, user prompts\n  - NO business logic, NO data transformations, NO calculations\n\n- **`@tm/mcp`** (apps/mcp/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and returns MCP-formatted responses\n  - Handles MCP-specific concerns: tool schemas, parameter validation, response formatting\n  - NO business logic, NO data transformations, NO calculations\n\n- **`apps/extension`** (future):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays in VS Code UI\n  - NO business logic\n\n**Examples of violations to avoid:**\n\n- ❌ Creating helper functions in CLI/MCP to parse task IDs → Move to tm-core\n- ❌ Data transformation logic in CLI/MCP → Move to tm-core\n- ❌ Validation logic in CLI/MCP → Move to tm-core\n- ❌ Duplicating logic across CLI and MCP → Implement once in tm-core\n\n**Correct approach:**\n\n- ✅ Add method to TasksDomain: `tasks.get(taskId)` (automatically handles task and subtask IDs)\n- ✅ CLI calls: `await tmCore.tasks.get(taskId)` (supports \"1\", \"1.2\", \"HAM-123\", \"HAM-123.2\")\n- ✅ MCP calls: `await tmCore.tasks.get(taskId)` (same intelligent ID parsing)\n- ✅ Single source of truth in tm-core\n\n## Code Quality & Reusability Guidelines\n\nApply standard software engineering principles:\n\n- **DRY (Don't Repeat Yourself)**: Extract patterns that appear 2+ times into reusable components or utilities\n- **YAGNI (You Aren't Gonna Need It)**: Don't over-engineer. Create abstractions when duplication appears, not before\n- **Maintainable**: Single source of truth. Change once, update everywhere\n- **Readable**: Clear naming, proper structure, export from index files\n- **Flexible**: Accept configuration options with sensible defaults\n\n## Documentation Guidelines\n\n- **Documentation location**: Write docs in `apps/docs/` (Mintlify site source), not `docs/`\n- **Documentation URL**: Reference docs at <https://tryhamster.com/docs/taskmaster>, not local file paths\n\n## Changeset Guidelines\n\n- **Add a changeset for code changes** - Run `npx changeset` after making code changes (not needed for docs-only PRs)\n- When creating changesets, remember that it's user-facing, meaning we don't have to get into the specifics of the code, but rather mention what the end-user is getting or fixing from this changeset\n- Run `npm run turbo:typecheck` before pushing to ensure TypeScript type checks pass\n- Run `npm run test -w <package-name>` to test a package\n","assets/AGENTS.md":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\ntask-master generate                                         # Update task markdown files (usually auto-called)\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nDefault: `core` (7 tools). Set via `TASK_MASTER_TOOLS` env var.\n\n| Tier | Count | Tools |\n|------|-------|-------|\n| `core` | 7 | `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task` |\n| `standard` | 14 | core + `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report` |\n| `all` | 44+ | standard + dependencies, tags, research, autopilot, scoping, models, rules |\n\n**Upgrade when tool unavailable:** Edit MCP config, change `TASK_MASTER_TOOLS` from `\"core\"` to `\"standard\"` or `\"all\"`, restart MCP.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Regenerate task files from tasks.json\ntask-master generate\n\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n- Task markdown files in `tasks/` are auto-generated\n- Run `task-master generate` after manual changes to tasks.json\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","packages/ai-sdk-provider-grok-cli/README.md":"# AI SDK Provider for Grok CLI\n\nA provider for the [AI SDK](https://sdk.vercel.ai) that integrates with [Grok CLI](https://docs.x.ai/api) for accessing xAI's Grok language models.\n\n## Features\n\n- ✅ **AI SDK v5 Compatible** - Full support for the latest AI SDK interfaces\n- ✅ **Streaming & Non-streaming** - Both generation modes supported\n- ✅ **Error Handling** - Comprehensive error handling with retry logic\n- ✅ **Type Safety** - Full TypeScript support with proper type definitions\n- ✅ **JSON Mode** - Automatic JSON extraction from responses\n- ✅ **Abort Signals** - Proper cancellation support\n\n## Installation\n\n```bash\nnpm install @tm/ai-sdk-provider-grok-cli\n# or\nyarn add @tm/ai-sdk-provider-grok-cli\n```\n\n## Prerequisites\n\n1. Install the Grok CLI:\n\n   ```bash\n   npm install -g grok-cli\n   # or follow xAI's installation instructions\n   ```\n\n2. Set up authentication:\n\n   ```bash\n   export GROK_CLI_API_KEY=\"your-api-key\"\n   # or configure via grok CLI: grok config set api-key your-key\n   ```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: grokCli('grok-3-latest'),\n  prompt: 'Write a haiku about TypeScript'\n});\n\nconsole.log(result.text);\n```\n\n### Streaming\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { streamText } from 'ai';\n\nconst { textStream } = await streamText({\n  model: grokCli('grok-4-latest'),\n  prompt: 'Explain quantum computing'\n});\n\nfor await (const delta of textStream) {\n  process.stdout.write(delta);\n}\n```\n\n### JSON Mode\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateObject } from 'ai';\nimport { z } from 'zod';\n\nconst result = await generateObject({\n  model: grokCli('grok-3-latest'),\n  schema: z.object({\n    name: z.string(),\n    age: z.number(),\n    hobbies: z.array(z.string())\n  }),\n  prompt: 'Generate a person profile'\n});\n\nconsole.log(result.object);\n```\n\n## Supported Models\n\n- `grok-3-latest` - Grok 3 (latest version)\n- `grok-4-latest` - Grok 4 (latest version)\n- `grok-4` - Grok 4 (stable)\n- Custom model strings supported\n\n## Configuration\n\n### Provider Settings\n\n```typescript\nimport { createGrokCli } from '@tm/ai-sdk-provider-grok-cli';\n\nconst grok = createGrokCli({\n  apiKey: 'your-api-key', // Optional if set via env/CLI\n  timeout: 120000, // 2 minutes default\n  workingDirectory: '/path/to/project', // Optional\n  baseURL: 'https://api.x.ai' // Optional\n});\n```\n\n### Model Settings\n\n```typescript\nconst model = grok('grok-4-latest', {\n  timeout: 300000, // 5 minutes for grok-4\n  // Other CLI-specific settings\n});\n```\n\n## Error Handling\n\nThe provider includes comprehensive error handling:\n\n```typescript\nimport {\n  isAuthenticationError,\n  isTimeoutError,\n  isInstallationError\n} from '@tm/ai-sdk-provider-grok-cli';\n\ntry {\n  const result = await generateText({\n    model: grokCli('grok-4-latest'),\n    prompt: 'Hello!'\n  });\n} catch (error) {\n  if (isAuthenticationError(error)) {\n    console.error('Authentication failed:', error.message);\n  } else if (isTimeoutError(error)) {\n    console.error('Request timed out:', error.message);\n  } else if (isInstallationError(error)) {\n    console.error('Grok CLI not installed or not found in PATH');\n  }\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start development mode (keep running during development)\nnpm run dev\n\n# Type check\nnpm run typecheck\n\n# Run tests (requires build first)\nNODE_ENV=production npm run build\nnpm test\n```\n\n**Important**: Always run `npm run dev` and keep it running during development. This ensures proper compilation and hot-reloading of TypeScript files.\n","packages/claude-code-plugin/.claude-plugin/plugin.json":"{\n\t\"name\": \"taskmaster\",\n\t\"description\": \"A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.\",\n\t\"author\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"url\": \"https://github.com/eyaltoledano/claude-task-master\"\n\t},\n\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master#readme\",\n\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\"license\": \"MIT WITH Commons-Clause\",\n\t\"keywords\": [\n\t\t\"task-management\",\n\t\t\"ai\",\n\t\t\"workflow\",\n\t\t\"orchestration\",\n\t\t\"automation\",\n\t\t\"mcp\",\n\t\t\"development\",\n\t\t\"productivity\"\n\t]\n}\n","packages/claude-code-plugin/commands/sync-readme.md":"Export tasks to README.md with professional formatting.\n\nArguments: $ARGUMENTS\n\nGenerate a well-formatted README with current task information.\n\n## README Synchronization\n\nCreates or updates README.md with beautifully formatted task information.\n\n## Argument Parsing\n\nOptional filters:\n- \"pending\" → Only pending tasks\n- \"with-subtasks\" → Include subtask details\n- \"by-priority\" → Group by priority\n- \"sprint\" → Current sprint only\n\n## Execution\n\n```bash\ntask-master sync-readme [--with-subtasks] [--status=<status>]\n```\n\n## README Generation\n\n### 1. **Project Header**\n```markdown\n# Project Name\n\n## 📋 Task Progress\n\nLast Updated: 2024-01-15 10:30 AM\n\n### Summary\n- Total Tasks: 45\n- Completed: 15 (33%)\n- In Progress: 5 (11%)\n- Pending: 25 (56%)\n```\n\n### 2. **Task Sections**\nOrganized by status or priority:\n- Progress indicators\n- Task descriptions\n- Dependencies noted\n- Time estimates\n\n### 3. **Visual Elements**\n- Progress bars\n- Status badges\n- Priority indicators\n- Completion checkmarks\n\n## Smart Features\n\n1. **Intelligent Grouping**\n   - By feature area\n   - By sprint/milestone\n   - By assigned developer\n   - By priority\n\n2. **Progress Tracking**\n   - Overall completion\n   - Sprint velocity\n   - Burndown indication\n   - Time tracking\n\n3. **Formatting Options**\n   - GitHub-flavored markdown\n   - Task checkboxes\n   - Collapsible sections\n   - Table format available\n\n## Example Output\n\n```markdown\n## 🚀 Current Sprint\n\n### In Progress\n- [ ] 🔄 #5 **Implement user authentication** (60% complete)\n  - Dependencies: API design (#3 ✅)\n  - Subtasks: 4 (2 completed)\n  - Est: 8h / Spent: 5h\n\n### Pending (High Priority)\n- [ ] ⚡ #8 **Create dashboard UI**\n  - Blocked by: #5\n  - Complexity: High\n  - Est: 12h\n```\n\n## Customization\n\nBased on arguments:\n- Include/exclude sections\n- Detail level control\n- Custom grouping\n- Filter by criteria\n\n## Post-Sync\n\nAfter generation:\n1. Show diff preview\n2. Backup existing README\n3. Write new content\n4. Commit reminder\n5. Update timestamp\n\n## Integration\n\nWorks well with:\n- Git workflows\n- CI/CD pipelines\n- Project documentation\n- Team updates\n- Client reports","packages/tm-bridge/README.md":"# @tm/bridge\n\n> ⚠️ **TEMPORARY PACKAGE - DELETE WHEN LEGACY CODE IS REMOVED** ⚠️\n\nThis package exists solely as a bridge between legacy scripts (`scripts/modules/task-manager/`) and the new tm-core architecture. It provides shared functionality that both CLI and MCP direct functions can use during the migration period.\n\n## Why does this exist?\n\nDuring the transition from legacy scripts to tm-core, we need a single source of truth for bridge logic that handles:\n- API vs file storage detection\n- Remote AI service delegation\n- Consistent behavior across CLI and MCP interfaces\n\n## When to delete this\n\nDelete this entire package when:\n1. ✅ Legacy scripts in `scripts/modules/task-manager/` are removed\n2. ✅ MCP direct functions in `mcp-server/src/core/direct-functions/` are removed\n3. ✅ All functionality has moved to tm-core\n4. ✅ CLI and MCP use tm-core directly via TasksDomain\n\n## Migration path\n\n```text\nCurrent:   CLI → legacy scripts → @tm/bridge → @tm/core\n          MCP → direct functions → legacy scripts → @tm/bridge → @tm/core\n\nFuture:    CLI → @tm/core (TasksDomain)\n          MCP → @tm/core (TasksDomain)\n\nDELETE:    legacy scripts, direct functions, @tm/bridge\n```\n\n## Usage\n\n```typescript\nimport { tryUpdateViaRemote } from '@tm/bridge';\n\nconst result = await tryUpdateViaRemote({\n  taskId: '1.2',\n  prompt: 'Update task...',\n  projectRoot: '/path/to/project',\n  // ... other params\n});\n```\n\n## Contents\n\n- `update-bridge.ts` - Shared update bridge logic for task/subtask updates\n\n---\n\n**Remember:** This package should NOT accumulate new features. It's a temporary migration aid only.\n","packages/tm-core/README.md":"# @task-master/tm-core\n\nCore library for Task Master AI - providing task management and orchestration capabilities with TypeScript support.\n\n## Overview\n\n`tm-core` is the foundational library that powers Task Master AI's task management system. It provides a comprehensive set of tools for creating, managing, and orchestrating tasks with AI integration.\n\n## Features\n\n- **TypeScript-first**: Built with full TypeScript support and strict type checking\n- **Dual Format**: Supports both ESM and CommonJS with automatic format detection\n- **Modular Architecture**: Clean separation of concerns with dedicated modules for different functionality\n- **AI Provider Integration**: Pluggable AI provider system for task generation and management\n- **Flexible Storage**: Abstracted storage layer supporting different persistence strategies\n- **Task Parsing**: Advanced parsing capabilities for various task definition formats\n- **Error Handling**: Comprehensive error system with specific error types\n- **Testing**: Complete test coverage with Jest and TypeScript support\n\n## Installation\n\n```bash\nnpm install @task-master/tm-core\n```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { generateTaskId, PlaceholderTask } from '@task-master/tm-core';\n\n// Generate a unique task ID\nconst taskId = generateTaskId();\n\n// Create a task (coming soon - full implementation)\nconst task: PlaceholderTask = {\n  id: taskId,\n  title: 'My Task',\n  status: 'pending',\n  priority: 'medium'\n};\n```\n\n### Modular Imports\n\nYou can import specific modules to reduce bundle size:\n\n```typescript\n// Import types only\nimport type { TaskId, TaskStatus } from '@task-master/tm-core/types';\n\n// Import utilities\nimport { generateTaskId, formatDate } from '@task-master/tm-core/utils';\n\n// Import providers (AI providers coming soon)\n// import { AIProvider } from '@task-master/tm-core/providers';\n\n// Import storage\nimport { PlaceholderStorage } from '@task-master/tm-core/storage';\n\n// Import parsers\nimport { PlaceholderParser } from '@task-master/tm-core/parser';\n\n// Import errors\nimport { TmCoreError, TaskNotFoundError } from '@task-master/tm-core/errors';\n```\n\n## Architecture\n\nThe library is organized into several key modules:\n\n- **types/**: TypeScript type definitions and interfaces\n- **providers/**: AI provider implementations for task generation\n- **storage/**: Storage adapters for different persistence strategies\n- **parser/**: Task parsing utilities for various formats\n- **utils/**: Common utility functions and helpers\n- **errors/**: Custom error classes and error handling\n\n## Development\n\n### Prerequisites\n\n- Node.js >= 20.0.0\n- npm or yarn\n\n### Setup\n\n```bash\n# Install dependencies\nnpm install\n\n# Build the library\nnpm run build\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Lint code\nnpm run lint\n\n# Format code\nnpm run format\n```\n\n### Scripts\n\n- `build`: Build the library for both ESM and CJS formats\n- `build:watch`: Build in watch mode for development\n- `test`: Run the test suite\n- `test:watch`: Run tests in watch mode\n- `test:coverage`: Run tests with coverage reporting\n- `lint`: Lint TypeScript files\n- `lint:fix`: Lint and auto-fix issues\n- `format`: Format code with Prettier\n- `format:check`: Check code formatting\n- `typecheck`: Type-check without emitting files\n- `clean`: Clean build artifacts\n- `dev`: Development mode with watch\n\n## ESM and CommonJS Support\n\nThis package supports both ESM and CommonJS formats automatically:\n\n```javascript\n// ESM\nimport { generateTaskId } from '@task-master/tm-core';\n\n// CommonJS\nconst { generateTaskId } = require('@task-master/tm-core');\n```\n\n## Roadmap\n\nThis is the initial package structure. The following features are planned for implementation:\n\n### Task 116: TypeScript Types\n- [ ] Complete type definitions for tasks, projects, and configurations\n- [ ] Zod schema validation\n- [ ] Generic type utilities\n\n### Task 117: AI Provider System\n- [ ] Base provider interface\n- [ ] Anthropic Claude integration\n- [ ] OpenAI integration\n- [ ] Perplexity integration\n- [ ] Provider factory and registry\n\n### Task 118: Storage Layer\n- [ ] File system storage adapter\n- [ ] Memory storage adapter\n- [ ] Storage interface and factory\n\n### Task 119: Task Parser\n- [ ] PRD parser implementation\n- [ ] Markdown parser\n- [ ] JSON task format parser\n- [ ] Validation utilities\n\n### Task 120: Utility Functions\n- [ ] Task ID generation\n- [ ] Date formatting\n- [ ] Validation helpers\n- [ ] File system utilities\n\n### Task 121: Error Handling\n- [ ] Task-specific errors\n- [ ] Storage errors\n- [ ] Provider errors\n- [ ] Validation errors\n\n### Task 122: Configuration System\n- [ ] Configuration schema\n- [ ] Default configurations\n- [ ] Environment variable support\n\n### Task 123: Testing Infrastructure\n- [ ] Unit test coverage\n- [ ] Integration tests\n- [ ] Mock utilities\n\n### Task 124: Documentation\n- [ ] API documentation\n- [ ] Usage examples\n- [ ] Migration guides\n\n### Task 125: Package Finalization\n- [ ] Final testing and validation\n- [ ] Release preparation\n- [ ] CI/CD integration\n\n## Implementation Checklist\n\n### ✅ Task 115: Initialize tm-core Package Structure (COMPLETED)\n- [x] Create tm-core directory structure and base configuration files\n- [x] Configure build and test infrastructure \n- [x] Create barrel export files for all directories\n- [x] Add development tooling and documentation\n- [x] Validate package structure and prepare for development\n\n### 🚧 Remaining Implementation Tasks\n- [ ] **Task 116**: TypeScript Types - Complete type definitions for tasks, projects, and configurations\n- [ ] **Task 117**: AI Provider System - Base provider interface and integrations\n- [ ] **Task 118**: Storage Layer - File system and memory storage adapters\n- [ ] **Task 119**: Task Parser - PRD, Markdown, and JSON parsers\n- [ ] **Task 120**: Utility Functions - Task ID generation, validation helpers\n- [ ] **Task 121**: Error Handling - Task-specific and validation errors\n- [ ] **Task 122**: Configuration System - Schema and environment support\n- [ ] **Task 123**: Testing Infrastructure - Complete unit and integration tests\n- [ ] **Task 124**: Documentation - API docs and usage examples\n- [ ] **Task 125**: Package Finalization - Release preparation and CI/CD\n\n## Contributing\n\nThis package is part of the Task Master AI project. Please refer to the main project's contributing guidelines.\n\n## License\n\nMIT - See the main project's LICENSE file for details.\n\n## Support\n\nFor questions and support, please refer to the main Task Master AI documentation.","packages/tm-core/docs/listTasks-architecture.md":"# ListTasks Architecture - End-to-End POC\n\n## Current Implementation Structure\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                         CLI Layer                            │\n│  scripts/modules/task-manager/list-tasks.js                 │\n│  - Complex UI rendering (tables, progress bars)             │\n│  - Multiple output formats (json, text, markdown, compact)  │\n│  - Status filtering and statistics                          │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              │ Currently reads directly\n                              │ from files (needs integration)\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                      tm-core Package                         │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            TaskMasterCore (Facade)                   │   │\n│  │  src/task-master-core.ts                            │   │\n│  │                                                      │   │\n│  │  - listTasks(options)                               │   │\n│  │    • tag filtering                                  │   │\n│  │    • status filtering                               │   │\n│  │    • include/exclude subtasks                       │   │\n│  │  - getTask(id)                                      │   │\n│  │  - getTasksByStatus(status)                         │   │\n│  │  - getTaskStats()                                   │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                              │                               │\n│                              ▼                               │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │              Storage Layer (IStorage)                │   │\n│  │                                                      │   │\n│  │  ┌──────────────┐        ┌──────────────┐          │   │\n│  │  │ FileStorage  │        │ ApiStorage   │          │   │\n│  │  │              │        │ (Hamster)    │          │   │\n│  │  └──────────────┘        └──────────────┘          │   │\n│  │                                                      │   │\n│  │  StorageFactory.create() selects based on config    │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            Domain Layer (Entities)                   │   │\n│  │                                                      │   │\n│  │  TaskEntity                                         │   │\n│  │  - Business logic                                   │   │\n│  │  - Validation                                       │   │\n│  │  - Status transitions                               │   │\n│  └─────────────────────────────────────────────────────┘   │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## ListTasks Data Flow\n\n### 1. CLI Request\n```javascript\n// Current CLI (needs update to use tm-core)\nlistTasks(tasksPath, statusFilter, reportPath, withSubtasks, outputFormat, context)\n```\n\n### 2. TaskMasterCore Processing\n```typescript\n// Our new implementation\nconst tmCore = createTaskMasterCore(projectPath, { \n  storage: { \n    type: 'api',  // or 'file'\n    apiEndpoint: 'https://tryhamster.com',\n    apiAccessToken: 'xxx'\n  }\n});\n\nconst result = await tmCore.listTasks({\n  tag: 'feature-branch',\n  filter: {\n    status: ['pending', 'in-progress'],\n    priority: 'high',\n    search: 'authentication'\n  },\n  includeSubtasks: true\n});\n```\n\n### 3. Storage Selection\n```typescript\n// StorageFactory automatically selects storage\nconst storage = StorageFactory.create(config, projectPath);\n// Returns either FileStorage or ApiStorage based on config\n```\n\n### 4. Data Loading\n```typescript\n// FileStorage\n- Reads from .taskmaster/tasks/tasks.json (or tag-specific file)\n- Local file system operations\n\n// ApiStorage (Hamster)\n- Makes HTTP requests to Hamster API\n- Uses access token from config\n- Handles retries and rate limiting\n```\n\n### 5. Entity Processing\n```typescript\n// Convert raw data to TaskEntity for business logic\nconst taskEntities = TaskEntity.fromArray(rawTasks);\n\n// Apply filters\nconst filtered = applyFilters(taskEntities, filter);\n\n// Convert back to plain objects\nconst tasks = filtered.map(entity => entity.toJSON());\n```\n\n### 6. Response Structure\n```typescript\ninterface ListTasksResult {\n  tasks: Task[];        // Filtered tasks\n  total: number;        // Total task count\n  filtered: number;     // Filtered task count  \n  tag?: string;         // Tag context if applicable\n}\n```\n\n## Integration Points Needed\n\n### 1. CLI Integration\n- [ ] Update `scripts/modules/task-manager/list-tasks.js` to use tm-core\n- [ ] Map CLI options to TaskMasterCore options\n- [ ] Handle output formatting in CLI layer\n\n### 2. Configuration Loading\n- [ ] Load `.taskmaster/config.json` for storage settings\n- [ ] Support environment variables for API tokens\n- [ ] Handle storage type selection\n\n### 3. Testing Requirements\n- [x] Unit tests for TaskEntity\n- [x] Unit tests for BaseProvider\n- [x] Integration tests for listTasks with FileStorage\n- [ ] Integration tests for listTasks with ApiStorage (mock API)\n- [ ] E2E tests with real Hamster API (optional)\n\n## Benefits of This Architecture\n\n1. **Storage Abstraction**: Switch between file and API storage without changing business logic\n2. **Clean Separation**: UI (CLI) separate from business logic (tm-core)\n3. **Testability**: Each layer can be tested independently\n4. **Extensibility**: Easy to add new storage types (database, cloud, etc.)\n5. **Type Safety**: Full TypeScript support throughout\n6. **Error Handling**: Consistent error handling with TaskMasterError\n\n## Next Steps\n\n1. Create a simple CLI wrapper that uses tm-core\n2. Test with file storage (existing functionality)\n3. Test with mock API storage\n4. Integrate with actual Hamster API when available\n5. Migrate other commands (addTask, updateTask, etc.) following same pattern","tests/unit/scripts/modules/commands/README.md":"# Mock System Documentation\n\n## Overview\n\nThe `move-cross-tag.test.js` file has been refactored to use a focused, maintainable mock system that addresses the brittleness and complexity of the original implementation.\n\n## Key Improvements\n\n### 1. **Focused Mocking**\n\n- **Before**: Mocked 20+ modules, many irrelevant to cross-tag functionality\n- **After**: Only mocks 5 core modules actually used in cross-tag moves\n\n### 2. **Configuration-Driven Mocking**\n\n```javascript\nconst mockConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true,\n    initTaskMaster: true,\n    findProjectRoot: true\n  }\n};\n```\n\n### 3. **Reusable Mock Factory**\n\n```javascript\nfunction createMockFactory(config = mockConfig) {\n  const mocks = {};\n  \n  if (config.core?.moveTasksBetweenTags) {\n    mocks.moveTasksBetweenTags = createMock('moveTasksBetweenTags');\n  }\n  // ... other mocks\n  \n  return mocks;\n}\n```\n\n## Mock Configuration\n\n### Core Mocks (Required for Cross-Tag Functionality)\n\n- `moveTasksBetweenTags`: Core move functionality\n- `generateTaskFiles`: File generation after moves\n- `readJSON`: Reading task data\n- `initTaskMaster`: TaskMaster initialization\n- `findProjectRoot`: Project path resolution\n\n### Optional Mocks\n\n- Console methods: `error`, `log`, `exit`\n- TaskMaster instance methods: `getCurrentTag`, `getTasksPath`, `getProjectRoot`\n\n## Usage Examples\n\n### Default Configuration\n\n```javascript\nconst mocks = setupMocks(); // Uses default mockConfig\n```\n\n### Minimal Configuration\n\n```javascript\nconst minimalConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(minimalConfig);\n```\n\n### Selective Mocking\n\n```javascript\nconst selectiveConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: false, // Disabled\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(selectiveConfig);\n```\n\n## Benefits\n\n1. **Reduced Complexity**: From 150+ lines of mock setup to 50 lines\n2. **Better Maintainability**: Clear configuration object shows dependencies\n3. **Focused Testing**: Only mocks what's actually used\n4. **Flexible Configuration**: Easy to enable/disable specific mocks\n5. **Consistent Naming**: All mocks use `createMock()` with descriptive names\n\n## Migration Guide\n\n### For Other Test Files\n\n1. Identify actual module dependencies\n2. Create configuration object for required mocks\n3. Use `createMockFactory()` and `setupMocks()`\n4. Remove unnecessary mocks\n\n### Example Migration\n\n```javascript\n// Before: 20+ jest.mock() calls\njest.mock('module1', () => ({ ... }));\njest.mock('module2', () => ({ ... }));\n// ... many more\n\n// After: Configuration-driven\nconst mockConfig = {\n  core: {\n    requiredFunction1: true,\n    requiredFunction2: true\n  }\n};\nconst mocks = setupMocks(mockConfig);\n```\n\n## Testing the Mock System\n\nThe test suite includes validation tests:\n\n- `should work with minimal mock configuration`\n- `should allow disabling specific mocks`\n\nThese ensure the mock factory works correctly and can be configured flexibly.\n"},"items":[{"name":"AGENTS.md","path":"assets/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/assets/AGENTS.md","title":"assets - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\ntask-master generate                                         # Update task markdown files (usually auto-called)\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nDefault: `core` (7 tools). Set via `TASK_MASTER_TOOLS` env var.\n\n| Tier | Count | Tools |\n|------|-------|-------|\n| `core` | 7 | `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task` |\n| `standard` | 14 | core + `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report` |\n| `all` | 44+ | standard + dependencies, tags, research, autopilot, scoping, models, rules |\n\n**Upgrade when tool unavailable:** Edit MCP config, change `TASK_MASTER_TOOLS` from `\"core\"` to `\"standard\"` or `\"all\"`, restart MCP.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Regenerate task files from tasks.json\ntask-master generate\n\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n- Task markdown files in `tasks/` are auto-generated\n- Run `task-master generate` after manual changes to tasks.json\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","isInternal":false,"tokens":3510,"sizeBytes":14471},{"name":"CLAUDE.md","path":".taskmaster/CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.taskmaster/CLAUDE.md","title":".taskmaster - Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nTask Master uses tiered tool loading to optimize context window usage:\n\n| Tier | Tools | Use Case |\n|------|-------|----------|\n| `core` | 7 | Minimal daily workflow tools (default) |\n| `standard` | 14 | Common task management |\n| `all` | 42+ | Full suite with research, autopilot, dependencies |\n\n**Core tools (7):** `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task`\n\n**Standard adds (7 more):** `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report`\n\n**All tier adds:** Dependency management, tag management, research, autopilot TDD workflow, scope up/down, models, rules\n\n**To upgrade tiers:** Change `TASK_MASTER_TOOLS` in `.mcp.json` from `\"core\"` to `\"standard\"` or `\"all\"` and restart the MCP connection.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n","isInternal":false,"tokens":3495,"sizeBytes":14398},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# Claude Code Instructions\n\n## Task Master AI Instructions\n\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n@./.taskmaster/CLAUDE.md\n\n## Test Guidelines\n\n### Test File Placement\n\n- **Package & tests**: Place in `packages/<package-name>/src/<module>/<file>.spec.ts` or `apps/<app-name>/src/<module>/<file.spec.ts>` alongside source\n- **Package integration tests**: Place in `packages/<package-name>/tests/integration/<module>/<file>.test.ts` or `apps/<app-name>/tests/integration/<module>/<file>.test.ts` alongside source\n- **Isolated unit tests**: Use `tests/unit/packages/<package-name>/` only when parallel placement isn't possible\n- **Test extension**: Always use `.ts` for TypeScript tests, never `.js`\n\n### Synchronous Tests\n\n- **NEVER use async/await in test functions** unless testing actual asynchronous operations\n- Use synchronous top-level imports instead of dynamic `await import()`\n- Test bodies should be synchronous whenever possible\n- Example:\n\n  ```typescript\n  // ✅ CORRECT - Synchronous imports with .ts extension\n  import { MyClass } from '../src/my-class.js';\n\n  it('should verify behavior', () => {\n    expect(new MyClass().property).toBe(value);\n  });\n\n  // ❌ INCORRECT - Async imports\n  it('should verify behavior', async () => {\n    const { MyClass } = await import('../src/my-class.js');\n    expect(new MyClass().property).toBe(value);\n  });\n  ```\n\n### When to Write Tests\n\n**ALWAYS write tests for:**\n\n- **Bug fixes**: Add a regression test that would have caught the bug\n- **Business logic**: Complex calculations, validations, transformations\n- **Edge cases**: Boundary conditions, error handling, null/undefined cases\n- **Public APIs**: Methods other code depends on\n- **Integration points**: Database, file system, external APIs\n\n**SKIP tests for:**\n\n- Simple getters/setters: `getX() { return this.x; }`\n- Trivial pass-through functions with no logic\n- Pure configuration objects\n- Code that just delegates to another tested function\n\n**Examples:**\n\n```javascript\n// ✅ WRITE A TEST - Bug fix with regression prevention\nit('should use correct baseURL from defaultBaseURL config', () => {\n  const provider = new ZAIProvider();\n  expect(provider.defaultBaseURL).toBe('https://api.z.ai/api/paas/v4/');\n});\n\n// ✅ WRITE A TEST - Business logic with edge cases\nit('should parse subtask IDs correctly', () => {\n  expect(parseTaskId('1.2.3')).toEqual({ taskId: 1, subtaskId: 2, subSubtaskId: 3 });\n  expect(parseTaskId('invalid')).toBeNull();\n});\n\n// ❌ SKIP TEST - Trivial getter\nclass Task {\n  get id() { return this._id; } // No test needed\n}\n\n// ❌ SKIP TEST - Pure delegation\nfunction getTasks() {\n  return taskManager.getTasks(); // Already tested in taskManager\n}\n```\n\n**Bug Fix Workflow:**\n\n1. Encounter a bug\n2. Write a failing test that reproduces it\n3. Fix the bug\n4. Verify test now passes\n5. Commit both fix and test together\n\n### Testing Guidelines\n\n**Principles**: FIRST (Fast, Independent, Repeatable, Self-validating, Timely)\n**Structure**: AAA (Arrange, Act, Assert)\n**Coverage**: Right-BICEP (Right results, Boundary, Inverse, Cross-check, Error conditions, Performance)\n\n#### What to Mock\n\n**Unit tests** (`.spec.ts` - test single unit in isolation):\n- **@tm/core**: Mock only external I/O (Supabase, APIs, filesystem). Use real internal services.\n- **apps/cli**: Mock tm-core responses. Use real Commander/chalk/inquirer/other npm packages (test display logic).\n- **apps/mcp**: Mock tm-core responses. Use real MCP framework (test response formatting).\n\n**Integration tests** (`tests/integration/` - test multiple units together):\n- **All packages**: Use real tm-core, mock only external boundaries (APIs, DB, filesystem).\n\n**Never mock**:\n- Internal utilities/helpers in the same package\n- Standard frameworks (Commander, Express) - let them run\n- Standard library\n\n**Rule of thumb**: Mock what you're NOT testing. CLI unit tests test display → mock tm-core. Core unit tests test logic → mock I/O. Integration tests test full flow → mock only external APIs.\n\n**Red flag**: Mocking 3+ dependencies in a unit test means code is doing too much or is in the wrong layer.\n\n**Anti-pattern**: Heavily mocked tests don't verify real behavior—they verify that you wired up mocks correctly. You end up writing orchestration code to satisfy tests, rather than tests that validate your actual implementation. If testing is hard, move the logic to where it's naturally testable.\n\n## Architecture Guidelines\n\n### Business Logic Separation\n\n**CRITICAL RULE**: ALL business logic must live in `@tm/core`, NOT in presentation layers.\n\n- **`@tm/core`** (packages/tm-core/):\n  - Contains ALL business logic, domain models, services, and utilities\n  - Provides clean facade APIs through domain objects (tasks, auth, workflow, git, config)\n  - Houses all complexity - parsing, validation, transformations, calculations, etc.\n  - Example: Task ID parsing, subtask extraction, status validation, dependency resolution\n\n- **`@tm/cli`** (apps/cli/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays results\n  - Handles CLI-specific concerns: argument parsing, output formatting, user prompts\n  - NO business logic, NO data transformations, NO calculations\n\n- **`@tm/mcp`** (apps/mcp/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and returns MCP-formatted responses\n  - Handles MCP-specific concerns: tool schemas, parameter validation, response formatting\n  - NO business logic, NO data transformations, NO calculations\n\n- **`apps/extension`** (future):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays in VS Code UI\n  - NO business logic\n\n**Examples of violations to avoid:**\n\n- ❌ Creating helper functions in CLI/MCP to parse task IDs → Move to tm-core\n- ❌ Data transformation logic in CLI/MCP → Move to tm-core\n- ❌ Validation logic in CLI/MCP → Move to tm-core\n- ❌ Duplicating logic across CLI and MCP → Implement once in tm-core\n\n**Correct approach:**\n\n- ✅ Add method to TasksDomain: `tasks.get(taskId)` (automatically handles task and subtask IDs)\n- ✅ CLI calls: `await tmCore.tasks.get(taskId)` (supports \"1\", \"1.2\", \"HAM-123\", \"HAM-123.2\")\n- ✅ MCP calls: `await tmCore.tasks.get(taskId)` (same intelligent ID parsing)\n- ✅ Single source of truth in tm-core\n\n## Code Quality & Reusability Guidelines\n\nApply standard software engineering principles:\n\n- **DRY (Don't Repeat Yourself)**: Extract patterns that appear 2+ times into reusable components or utilities\n- **YAGNI (You Aren't Gonna Need It)**: Don't over-engineer. Create abstractions when duplication appears, not before\n- **Maintainable**: Single source of truth. Change once, update everywhere\n- **Readable**: Clear naming, proper structure, export from index files\n- **Flexible**: Accept configuration options with sensible defaults\n\n## Documentation Guidelines\n\n- **Documentation location**: Write docs in `apps/docs/` (Mintlify site source), not `docs/`\n- **Documentation URL**: Reference docs at <https://tryhamster.com/docs/taskmaster>, not local file paths\n\n## Changeset Guidelines\n\n- **Add a changeset for code changes** - Run `npx changeset` after making code changes (not needed for docs-only PRs)\n- When creating changesets, remember that it's user-facing, meaning we don't have to get into the specifics of the code, but rather mention what the end-user is getting or fixing from this changeset\n- Run `npm run turbo:typecheck` before pushing to ensure TypeScript type checks pass\n- Run `npm run test -w <package-name>` to test a package\n","isInternal":false,"tokens":1792,"sizeBytes":7610},{"name":"ai_providers.mdc","path":".cursor/rules/ai_providers.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/ai_providers.mdc","title":"Cursor Rule: ai_providers","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for managing Task Master AI providers and models.\nglobs: \nalwaysApply: false\n---\n# Task Master AI Provider Management\n\nThis rule guides AI assistants on how to view, configure, and interact with the different AI providers and models supported by Task Master. For internal implementation details of the service layer, see [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc).\n\n-   **Primary Interaction:**\n    -   Use the `models` MCP tool or the `task-master models` CLI command to manage AI configurations. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for detailed command/tool usage.\n\n-   **Configuration Roles:**\n    -   Task Master uses three roles for AI models:\n        -   `main`: Primary model for general tasks (generation, updates).\n        -   `research`: Model used when the `--research` flag or `research: true` parameter is used (typically models with web access or specialized knowledge).\n        -   `fallback`: Model used if the primary (`main`) model fails.\n    -   Each role is configured with a specific `provider:modelId` pair (e.g., `openai:gpt-4o`).\n\n-   **Viewing Configuration & Available Models:**\n    -   To see the current model assignments for each role and list all models available for assignment:\n        -   **MCP Tool:** `models` (call with no arguments or `listAvailableModels: true`)\n        -   **CLI Command:** `task-master models`\n    -   The output will show currently assigned models and a list of others, prefixed with their provider (e.g., `google:gemini-2.5-pro-exp-03-25`).\n\n-   **Setting Models for Roles:**\n    -   To assign a model to a role:\n        -   **MCP Tool:** `models` with `setMain`, `setResearch`, or `setFallback` parameters.\n        -   **CLI Command:** `task-master models` with `--set-main`, `--set-research`, or `--set-fallback` flags.\n    -   **Crucially:** When providing the model ID to *set*, **DO NOT include the `provider:` prefix**. Use only the model ID itself.\n        -   ✅ **DO:** `models(setMain='gpt-4o')` or `task-master models --set-main=gpt-4o`\n        -   ❌ **DON'T:** `models(setMain='openai:gpt-4o')` or `task-master models --set-main=openai:gpt-4o`\n    -   The tool/command will automatically determine the provider based on the model ID.\n\n-   **Setting Custom Models (Ollama/OpenRouter):**\n    -   To set a model ID not in the internal list for Ollama or OpenRouter:\n        -   **MCP Tool:** Use `models` with `set<Role>` and **also** `ollama: true` or `openrouter: true`.\n            -   Example: `models(setMain='my-custom-ollama-model', ollama=true)`\n            -   Example: `models(setMain='some-openrouter-model', openrouter=true)`\n        -   **CLI Command:** Use `task-master models` with `--set-<role>` and **also** `--ollama` or `--openrouter`.\n            -   Example: `task-master models --set-main=my-custom-ollama-model --ollama`\n            -   Example: `task-master models --set-main=some-openrouter-model --openrouter`\n        -   **Interactive Setup:** Use `task-master models --setup` and select the `Ollama (Enter Custom ID)` or `OpenRouter (Enter Custom ID)` options.\n    -   **OpenRouter Validation:** When setting a custom OpenRouter model, Taskmaster attempts to validate the ID against the live OpenRouter API.\n    -   **Ollama:** No live validation occurs for custom Ollama models; ensure the model is available on your Ollama server.\n\n-   **Supported Providers & Required API Keys:**\n    -   Task Master integrates with various providers via the Vercel AI SDK.\n    -   **API keys are essential** for most providers and must be configured correctly.\n    -   **Key Locations** (See [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) - Configuration Management):\n        -   **MCP/Cursor:** Set keys in the `env` section of `.cursor/mcp.json`.\n        -   **CLI:** Set keys in a `.env` file in the project root.\n    -   **Provider List & Keys:**\n        -   **`anthropic`**: Requires `ANTHROPIC_API_KEY`.\n        -   **`google`**: Requires `GOOGLE_API_KEY`.\n        -   **`openai`**: Requires `OPENAI_API_KEY`.\n        -   **`perplexity`**: Requires `PERPLEXITY_API_KEY`.\n        -   **`xai`**: Requires `XAI_API_KEY`.\n        -   **`mistral`**: Requires `MISTRAL_API_KEY`.\n        -   **`azure`**: Requires `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT`.\n        -   **`openrouter`**: Requires `OPENROUTER_API_KEY`.\n        -   **`ollama`**: Might require `OLLAMA_API_KEY` (not currently supported) *and* `OLLAMA_BASE_URL` (default: `http://localhost:11434/api`). *Check specific setup.*\n\n-   **Troubleshooting:**\n    -   If AI commands fail (especially in MCP context):\n        1.  **Verify API Key:** Ensure the correct API key for the *selected provider* (check `models` output) exists in the appropriate location (`.cursor/mcp.json` env or `.env`).\n        2.  **Check Model ID:** Ensure the model ID set for the role is valid (use `models` listAvailableModels/`task-master models`).\n        3.  **Provider Status:** Check the status of the external AI provider's service.\n        4.  **Restart MCP:** If changes were made to configuration or provider code, restart the MCP server.\n\n## Adding a New AI Provider (Vercel AI SDK Method)\n\nFollow these steps to integrate a new AI provider that has an official Vercel AI SDK adapter (`@ai-sdk/<provider>`):\n\n1.  **Install Dependency:**\n    -   Install the provider-specific package:\n        ```bash\n        npm install @ai-sdk/<provider-name>\n        ```\n\n2.  **Create Provider Module:**\n    -   Create a new file in `src/ai-providers/` named `<provider-name>.js`.\n    -   Use existing modules (`openai.js`, `anthropic.js`, etc.) as a template.\n    -   **Import:**\n        -   Import the provider's `create<ProviderName>` function from `@ai-sdk/<provider-name>`.\n        -   Import `generateText`, `streamText`, `generateObject` from the core `ai` package.\n        -   Import the `log` utility from `../../scripts/modules/utils.js`.\n    -   **Implement Core Functions:**\n        -   `generate<ProviderName>Text(params)`:\n            -   Accepts `params` (apiKey, modelId, messages, etc.).\n            -   Instantiate the client: `const client = create<ProviderName>({ apiKey });`\n            -   Call `generateText({ model: client(modelId), ... })`.\n            -   Return `result.text`.\n            -   Include basic validation and try/catch error handling.\n        -   `stream<ProviderName>Text(params)`:\n            -   Similar structure to `generateText`.\n            -   Call `streamText({ model: client(modelId), ... })`.\n            -   Return the full stream result object.\n            -   Include basic validation and try/catch.\n        -   `generate<ProviderName>Object(params)`:\n            -   Similar structure.\n            -   Call `generateObject({ model: client(modelId), schema, messages, ... })`.\n            -   Return `result.object`.\n            -   Include basic validation and try/catch.\n    -   **Export Functions:** Export the three implemented functions (`generate<ProviderName>Text`, `stream<ProviderName>Text`, `generate<ProviderName>Object`).\n\n3.  **Integrate with Unified Service:**\n    -   Open `scripts/modules/ai-services-unified.js`.\n    -   **Import:** Add `import * as <providerName> from '../../src/ai-providers/<provider-name>.js';`\n    -   **Map:** Add an entry to the `PROVIDER_FUNCTIONS` map:\n        ```javascript\n        '<provider-name>': {\n            generateText: <providerName>.generate<ProviderName>Text,\n            streamText: <providerName>.stream<ProviderName>Text,\n            generateObject: <providerName>.generate<ProviderName>Object\n        },\n        ```\n\n4.  **Update Configuration Management:**\n    -   Open `scripts/modules/config-manager.js`.\n    -   **`MODEL_MAP`:** Add the new `<provider-name>` key to the `MODEL_MAP` loaded from `supported-models.json` (or ensure the loading handles new providers dynamically if `supported-models.json` is updated first).\n    -   **`VALID_PROVIDERS`:** Ensure the new `<provider-name>` is included in the `VALID_PROVIDERS` array (this should happen automatically if derived from `MODEL_MAP` keys).\n    -   **API Key Handling:**\n        -   Update the `keyMap` in `_resolveApiKey` and `isApiKeySet` with the correct environment variable name (e.g., `PROVIDER_API_KEY`).\n        -   Update the `switch` statement in `getMcpApiKeyStatus` to check the corresponding key in `mcp.json` and its placeholder value.\n        -   Add a case to the `switch` statement in `getMcpApiKeyStatus` for the new provider, including its placeholder string if applicable.\n    -   **Ollama Exception:** If adding Ollama or another provider *not* requiring an API key, add a specific check at the beginning of `isApiKeySet` and `getMcpApiKeyStatus` to return `true` immediately for that provider.\n\n5.  **Update Supported Models List:**\n    -   Edit `scripts/modules/supported-models.json`.\n    -   Add a new key for the `<provider-name>`.\n    -   Add an array of model objects under the provider key, each including:\n        -   `id`: The specific model identifier (e.g., `claude-3-opus-20240229`).\n        -   `name`: A user-friendly name (optional).\n        -   `swe_score`, `cost_per_1m_tokens`: (Optional) Add performance/cost data if available.\n        -   `allowed_roles`: An array of roles (`\"main\"`, `\"research\"`, `\"fallback\"`) the model is suitable for.\n        -   `max_tokens`: (Optional but recommended) The maximum token limit for the model.\n\n6.  **Update Environment Examples:**\n    -   Add the new `PROVIDER_API_KEY` to `.env.example`.\n    -   Add the new `PROVIDER_API_KEY` with its placeholder (`YOUR_PROVIDER_API_KEY_HERE`) to the `env` section for `taskmaster-ai` in `.cursor/mcp.json.example` (if it exists) or update instructions.\n\n7.  **Add Unit Tests:**\n    -   Create `tests/unit/ai-providers/<provider-name>.test.js`.\n    -   Mock the `@ai-sdk/<provider-name>` module and the core `ai` module functions (`generateText`, `streamText`, `generateObject`).\n    -   Write tests for each exported function (`generate<ProviderName>Text`, etc.) to verify:\n        -   Correct client instantiation.\n        -   Correct parameters passed to the mocked Vercel AI SDK functions.\n        -   Correct handling of results.\n        -   Error handling (missing API key, SDK errors).\n\n8.  **Documentation:**\n    -   Update any relevant documentation (like `README.md` or other rules) mentioning supported providers or configuration.\n\n*(Note: For providers **without** an official Vercel AI SDK adapter, the process would involve directly using the provider's own SDK or API within the `src/ai-providers/<provider-name>.js` module and manually constructing responses compatible with the unified service layer, which is significantly more complex.)*","frontmatter":{"description":"Guidelines for managing Task Master AI providers and models.","globs":null,"alwaysApply":false},"isInternal":false,"tokens":2660,"sizeBytes":10747},{"name":"ai_services.mdc","path":".cursor/rules/ai_services.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/ai_services.mdc","title":"Cursor Rule: ai_services","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for interacting with the unified AI service layer.\nglobs: scripts/modules/ai-services-unified.js, scripts/modules/task-manager/*.js, scripts/modules/commands.js\n---\n\n# AI Services Layer Guidelines\n\nThis document outlines the architecture and usage patterns for interacting with Large Language Models (LLMs) via Task Master's unified AI service layer (`ai-services-unified.js`). The goal is to centralize configuration, provider selection, API key management, fallback logic, and error handling.\n\n**Core Components:**\n\n*   **Configuration (`.taskmasterconfig` & [`config-manager.js`](mdc:scripts/modules/config-manager.js)):**\n    *   Defines the AI provider and model ID for different **roles** (`main`, `research`, `fallback`).\n    *   Stores parameters like `maxTokens` and `temperature` per role.\n    *   Managed via the `task-master models --setup` CLI command.\n    *   [`config-manager.js`](mdc:scripts/modules/config-manager.js) provides **getters** (e.g., `getMainProvider()`, `getParametersForRole()`) to access these settings. Core logic should **only** use these getters for *non-AI related application logic* (e.g., `getDefaultSubtasks`). The unified service fetches necessary AI parameters internally based on the `role`.\n    *   **API keys** are **NOT** stored here; they are resolved via `resolveEnvVariable` (in [`utils.js`](mdc:scripts/modules/utils.js)) from `.env` (for CLI) or the MCP `session.env` object (for MCP calls). See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc).\n\n*   **Unified Service (`ai-services-unified.js`):**\n    *   Exports primary interaction functions: `generateTextService`, `generateObjectService`. (Note: `streamTextService` exists but has known reliability issues with some providers/payloads).\n    *   Contains the core `_unifiedServiceRunner` logic.\n    *   Internally uses `config-manager.js` getters to determine the provider/model/parameters based on the requested `role`.\n    *   Implements the **fallback sequence** (e.g., main -> fallback -> research) if the primary provider/model fails.\n    *   Constructs the `messages` array required by the Vercel AI SDK.\n    *   Implements **retry logic** for specific API errors (`_attemptProviderCallWithRetries`).\n    *   Resolves API keys automatically via `_resolveApiKey` (using `resolveEnvVariable`).\n    *   Maps requests to the correct provider implementation (in `src/ai-providers/`) via `PROVIDER_FUNCTIONS`.\n    *   Returns a structured object containing the primary AI result (`mainResult`) and telemetry data (`telemetryData`). See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for details on how this telemetry data is propagated and handled.\n\n*   **Provider Implementations (`src/ai-providers/*.js`):**\n    *   Contain provider-specific wrappers around Vercel AI SDK functions (`generateText`, `generateObject`).\n\n**Usage Pattern (from Core Logic like `task-manager/*.js`):**\n\n1.  **Import Service:** Import `generateTextService` or `generateObjectService` from `../ai-services-unified.js`.\n    ```javascript\n    // Preferred for most tasks (especially with complex JSON)\n    import { generateTextService } from '../ai-services-unified.js';\n\n    // Use if structured output is reliable for the specific use case\n    // import { generateObjectService } from '../ai-services-unified.js';\n    ```\n\n2.  **Prepare Parameters:** Construct the parameters object for the service call.\n    *   `role`: **Required.** `'main'`, `'research'`, or `'fallback'`. Determines the initial provider/model/parameters used by the unified service.\n    *   `session`: **Required if called from MCP context.** Pass the `session` object received by the direct function wrapper. The unified service uses `session.env` to find API keys.\n    *   `systemPrompt`: Your system instruction string.\n    *   `prompt`: The user message string (can be long, include stringified data, etc.).\n    *   (For `generateObjectService` only): `schema` (Zod schema), `objectName`.\n\n3.  **Call Service:** Use `await` to call the service function.\n    ```javascript\n    // Example using generateTextService (most common)\n    try {\n        const resultText = await generateTextService({\n            role: useResearch ? 'research' : 'main', // Determine role based on logic\n            session: context.session, // Pass session from context object\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // Process the raw text response (e.g., parse JSON, use directly)\n        // ...\n    } catch (error) {\n        // Handle errors thrown by the unified service (if all fallbacks/retries fail)\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n\n    // Example using generateObjectService (use cautiously)\n    try {\n        const resultObject = await generateObjectService({\n            role: 'main',\n            session: context.session,\n            schema: myZodSchema,\n            objectName: 'myDataObject',\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // resultObject is already a validated JS object\n        // ...\n    } catch (error) {\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n    ```\n\n4.  **Handle Results/Errors:** Process the returned text/object or handle errors thrown by the unified service layer.\n\n**Key Implementation Rules & Gotchas:**\n\n*   ✅ **DO**: Centralize **all** LLM calls through `generateTextService` or `generateObjectService`.\n*   ✅ **DO**: Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.\n*   ✅ **DO**: Pass the `session` object (received in the `context` parameter, especially from direct function wrappers) to the service call when in MCP context.\n*   ✅ **DO**: Ensure API keys are correctly configured in `.env` (for CLI) or `.cursor/mcp.json` (for MCP).\n*   ✅ **DO**: Ensure `.taskmasterconfig` exists and has valid provider/model IDs for the roles you intend to use (manage via `task-master models --setup`).\n*   ✅ **DO**: Use `generateTextService` and implement robust manual JSON parsing (with Zod validation *after* parsing) when structured output is needed, as `generateObjectService` has shown unreliability with some providers/schemas.\n*   ❌ **DON'T**: Import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.\n*   ❌ **DON'T**: Initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (`task-manager/`) or MCP direct functions.\n*   ❌ **DON'T**: Fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters *for the AI call*. Pass the `role` instead.\n*   ❌ **DON'T**: Implement fallback or retry logic outside `ai-services-unified.js`.\n*   ❌ **DON'T**: Handle API key resolution outside the service layer (it uses `utils.js` internally).\n*   ⚠️ **generateObjectService Caution**: Be aware of potential reliability issues with `generateObjectService` across different providers and complex schemas. Prefer `generateTextService` + manual parsing as a more robust alternative for structured data needs.\n","frontmatter":{"description":"Guidelines for interacting with the unified AI service layer.","globs":"scripts/modules/ai-services-unified.js, scripts/modules/task-manager/*.js, scripts/modules/commands.js"},"isInternal":false,"tokens":1668,"sizeBytes":7303},{"name":"architecture.mdc","path":".cursor/rules/architecture.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/architecture.mdc","title":"Cursor Rule: architecture","category":"cursor-rule","format":"mdc","content":"---\ndescription: Describes the high-level architecture of the Task Master CLI application.\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Application Architecture Overview\n\n- **Modular Structure**: The Task Master CLI is built using a modular architecture, with distinct modules responsible for different aspects of the application. This promotes separation of concerns, maintainability, and testability.\n\n- **Main Modules and Responsibilities**:\n\n  - **[`commands.js`](mdc:scripts/modules/commands.js): Command Handling**\n    - **Purpose**: Defines and registers all CLI commands using Commander.js.\n    - **Responsibilities** (See also: [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n      - Parses command-line arguments and options.\n      - Invokes appropriate core logic functions from `scripts/modules/`.\n      - Handles user input/output for CLI.\n      - Implements CLI-specific validation.\n\n  - **[`task-manager.js`](mdc:scripts/modules/task-manager.js) & `task-manager/` directory: Task Data & Core Logic**\n    - **Purpose**: Contains core functions for task data manipulation (CRUD), AI interactions, and related logic.\n    - **Responsibilities**:\n      - Reading/writing `tasks.json` with tagged task lists support.\n      - Implementing functions for task CRUD, parsing PRDs, expanding tasks, updating status, etc.\n      - **Tagged Task Lists**: Handles task organization across multiple contexts (tags) like \"master\", branch names, or project phases.\n      - **Tag Resolution**: Provides backward compatibility by resolving tagged format to legacy format transparently.\n      - **Delegating AI interactions** to the `ai-services-unified.js` layer.\n      - Accessing non-AI configuration via `config-manager.js` getters.\n    - **Key Files**: Individual files within `scripts/modules/task-manager/` handle specific actions (e.g., `add-task.js`, `expand-task.js`).\n\n  - **[`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js): Dependency Management**\n    - **Purpose**: Manages task dependencies.\n    - **Responsibilities**: Add/remove/validate/fix dependencies across tagged task contexts.\n\n  - **[`ui.js`](mdc:scripts/modules/ui.js): User Interface Components**\n    - **Purpose**: Handles CLI output formatting (tables, colors, boxes, spinners).\n    - **Responsibilities**: Displaying tasks, reports, progress, suggestions, and migration notices for tagged systems.\n\n  - **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js): Unified AI Service Layer**\n    - **Purpose**: Centralized interface for all LLM interactions using Vercel AI SDK.\n    - **Responsibilities** (See also: [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc)):\n      - Exports `generateTextService`, `generateObjectService`.\n      - Handles provider/model selection based on `role` and `.taskmasterconfig`.\n      - Resolves API keys (from `.env` or `session.env`).\n      - Implements fallback and retry logic.\n      - Orchestrates calls to provider-specific implementations (`src/ai-providers/`).\n    - Telemetry data generated by the AI service layer is propagated upwards through core logic, direct functions, and MCP tools. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the detailed integration pattern.\n\n  - **[`src/ai-providers/*.js`](mdc:src/ai-providers/): Provider-Specific Implementations**\n    - **Purpose**: Provider-specific wrappers for Vercel AI SDK functions.\n    - **Responsibilities**: Interact directly with Vercel AI SDK adapters.\n\n  - **[`config-manager.js`](mdc:scripts/modules/config-manager.js): Configuration Management**\n    - **Purpose**: Loads, validates, and provides access to configuration.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Reads and merges `.taskmasterconfig` with defaults.\n      - Provides getters (e.g., `getMainProvider`, `getLogLevel`, `getDefaultSubtasks`) for accessing settings.\n      - **Tag Configuration**: Manages `global.defaultTag` and `tags` section for tag system settings.\n      - **Note**: Does **not** store or directly handle API keys (keys are in `.env` or MCP `session.env`).\n\n  - **[`utils.js`](mdc:scripts/modules/utils.js): Core Utility Functions**\n    - **Purpose**: Low-level, reusable CLI utilities.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Logging (`log` function), File I/O (`readJSON`, `writeJSON`), String utils (`truncate`).\n      - Task utils (`findTaskById`), Dependency utils (`findCycles`).\n      - API Key Resolution (`resolveEnvVariable`).\n      - Silent Mode Control (`enableSilentMode`, `disableSilentMode`).\n      - **Tagged Task Lists**: Silent migration system, tag resolution, current tag management.\n      - **Migration System**: `performCompleteTagMigration`, `migrateConfigJson`, `createStateJson`.\n\n  - **[`mcp-server/`](mdc:mcp-server/): MCP Server Integration**\n    - **Purpose**: Provides MCP interface using FastMCP.\n    - **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):\n      - Registers tools (`mcp-server/src/tools/*.js`). Tool `execute` methods **should be wrapped** with the `withNormalizedProjectRoot` HOF (from `tools/utils.js`) to ensure consistent path handling.\n      - The HOF provides a normalized `args.projectRoot` to the `execute` method.\n      - Tool `execute` methods call **direct function wrappers** (`mcp-server/src/core/direct-functions/*.js`), passing the normalized `projectRoot` and other args.\n      - Direct functions use path utilities (`mcp-server/src/core/utils/`) to resolve paths based on `projectRoot` from session.\n      - Direct functions implement silent mode, logger wrappers, and call core logic functions from `scripts/modules/`.\n      - **Tagged Task Lists**: MCP tools fully support the tagged format with complete tag management capabilities.\n      - Manages MCP caching and response formatting.\n\n  - **[`init.js`](mdc:scripts/init.js): Project Initialization Logic**\n    - **Purpose**: Sets up new Task Master project structure.\n    - **Responsibilities**: Creates directories, copies templates, manages `package.json`, sets up `.cursor/mcp.json`, initializes state.json for tagged system.\n\n## Tagged Task Lists System Architecture\n\n**Data Structure**: Task Master now uses a tagged task lists system where the `tasks.json` file contains multiple named task lists as top-level keys:\n\n```json\n{\n  \"master\": {\n    \"tasks\": [/* standard task objects */]\n  },\n  \"feature-branch\": {\n    \"tasks\": [/* separate task context */]\n  }\n}\n```\n\n**Key Components:**\n\n- **Silent Migration**: Automatically transforms legacy `{\"tasks\": [...]}` format to tagged format `{\"master\": {\"tasks\": [...]}}` on first read\n- **Tag Resolution Layer**: Provides 100% backward compatibility by intercepting tagged format and returning legacy format to existing code\n- **Configuration Integration**: `global.defaultTag` and `tags` section in config.json manage tag system settings\n- **State Management**: `.taskmaster/state.json` tracks current tag, migration status, and tag-branch mappings\n- **Migration Notice**: User-friendly notification system for seamless migration experience\n\n**Backward Compatibility**: All existing CLI commands and MCP tools continue to work unchanged. The tag resolution layer ensures that existing code receives the expected legacy format while the underlying storage uses the new tagged structure.\n\n- **Data Flow and Module Dependencies (Updated)**:\n\n  - **CLI**: `bin/task-master.js` -> `scripts/dev.js` (loads `.env`) -> `scripts/modules/commands.js` -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **MCP**: External Tool -> `mcp-server/server.js` -> Tool (`mcp-server/src/tools/*`) -> Direct Function (`mcp-server/src/core/direct-functions/*`) -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **Configuration**: Core logic needing non-AI settings calls `config-manager.js` getters (passing `session.env` via `explicitRoot` if from MCP). Unified AI Service internally calls `config-manager.js` getters (using `role`) for AI params and `utils.js` (`resolveEnvVariable` with `session.env`) for API keys.\n\n## Silent Mode Implementation Pattern in MCP Direct Functions\n\nDirect functions (the `*Direct` functions in `mcp-server/src/core/direct-functions/`) need to carefully implement silent mode to prevent console logs from interfering with the structured JSON responses required by MCP. This involves both using `enableSilentMode`/`disableSilentMode` around core function calls AND passing the MCP logger via the standard wrapper pattern (see mcp.mdc). Here's the standard pattern for correct implementation:\n\n1. **Import Silent Mode Utilities**:\n   ```javascript\n   import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n   ```\n\n2. **Parameter Matching with Core Functions**:\n   - ✅ **DO**: Ensure direct function parameters match the core function parameters\n   - ✅ **DO**: Check the original core function signature before implementing\n   - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n   ```javascript\n   // Example: Core function signature\n   // async function expandTask(tasksPath, taskId, numSubtasks, useResearch, additionalContext, options)\n   \n   // Direct function implementation - extract only parameters that exist in core\n   export async function expandTaskDirect(args, log, context = {}) {\n     // Extract parameters that match the core function\n     const taskId = parseInt(args.id, 10);\n     const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n     const useResearch = args.research === true;\n     const additionalContext = args.prompt || '';\n     \n     // Later pass these parameters in the correct order to the core function\n     const result = await expandTask(\n       tasksPath, \n       taskId, \n       numSubtasks, \n       useResearch, \n       additionalContext,\n       { mcpLog: log, session: context.session }\n     );\n   }\n   ```\n\n3. **Checking Silent Mode State**:\n   - ✅ **DO**: Always use `isSilentMode()` function to check current status\n   - ❌ **DON'T**: Directly access the global `silentMode` variable or `global.silentMode`\n   ```javascript\n   // CORRECT: Use the function to check current state\n   if (!isSilentMode()) {\n     // Only create a loading indicator if not in silent mode\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   \n   // INCORRECT: Don't access global variables directly\n   if (!silentMode) { // ❌ WRONG\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   ```\n\n4. **Wrapping Core Function Calls**:\n   - ✅ **DO**: Use a try/finally block pattern to ensure silent mode is always restored\n   - ✅ **DO**: Enable silent mode before calling core functions that produce console output\n   - ✅ **DO**: Disable silent mode in a finally block to ensure it runs even if errors occur\n   - ❌ **DON'T**: Enable silent mode without ensuring it gets disabled\n   ```javascript\n   export async function someDirectFunction(args, log) {\n     try {\n       // Argument preparation\n       const tasksPath = findTasksJsonPath(args, log);\n       const someArg = args.someArg;\n       \n       // Enable silent mode to prevent console logs\n       enableSilentMode();\n       \n       try {\n         // Call core function which might produce console output\n         const result = await someCoreFunction(tasksPath, someArg);\n         \n         // Return standardized result object\n         return { \n           success: true, \n           data: result, \n           fromCache: false \n         };\n       } finally {\n         // ALWAYS disable silent mode in finally block\n         disableSilentMode();\n       }\n     } catch (error) {\n       // Standard error handling\n       log.error(`Error in direct function: ${error.message}`);\n       return { \n         success: false, \n         error: { code: 'OPERATION_ERROR', message: error.message }, \n         fromCache: false \n       };\n     }\n   }\n   ```\n\n5. **Mixed Parameter and Global Silent Mode Handling**:\n   - For functions that need to handle both a passed `silentMode` parameter and check global state:\n   ```javascript\n   // Check both the function parameter and global state\n   const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n   \n   if (!isSilent) {\n     console.log('Operation starting...');\n   }\n   ```\n\nBy following these patterns consistently, direct functions will properly manage console output suppression while ensuring that silent mode is always properly reset, even when errors occur. This creates a more robust system that helps prevent unexpected silent mode states that could cause logging problems in subsequent operations.\n\n- **Testing Architecture**:\n\n  - **Test Organization Structure** (See also: [`tests.mdc`](mdc:.cursor/rules/tests.mdc)):\n    - **Unit Tests**: Located in `tests/unit/`, reflect the module structure with one test file per module\n    - **Integration Tests**: Located in `tests/integration/`, test interactions between modules\n    - **End-to-End Tests**: Located in `tests/e2e/`, test complete workflows from a user perspective\n    - **Test Fixtures**: Located in `tests/fixtures/`, provide reusable test data\n    - **Tagged System Tests**: Test migration, tag resolution, and multi-context functionality\n\n  - **Module Design for Testability**:\n    - **Explicit Dependencies**: Functions accept their dependencies as parameters rather than using globals\n    - **Functional Style**: Pure functions with minimal side effects make testing deterministic\n    - **Separate Logic from I/O**: Core business logic is separated from file system operations\n    - **Clear Module Interfaces**: Each module has well-defined exports that can be mocked in tests\n    - **Callback Isolation**: Callbacks are defined as separate functions for easier testing\n    - **Stateless Design**: Modules avoid maintaining internal state where possible\n    - **Tag Resolution Testing**: Test both tagged and legacy format handling\n\n  - **Mock Integration Patterns**:\n    - **External Libraries**: Libraries like `fs`, `commander`, and `@anthropic-ai/sdk` are mocked at module level\n    - **Internal Modules**: Application modules are mocked with appropriate spy functions\n    - **Testing Function Callbacks**: Callbacks are extracted from mock call arguments and tested in isolation\n    - **UI Elements**: Output functions from `ui.js` are mocked to verify display calls\n    - **Tagged Data Mocking**: Test both legacy and tagged task data structures\n\n  - **Testing Flow**:\n    - Module dependencies are mocked (following Jest's hoisting behavior)\n    - Test modules are imported after mocks are established\n    - Spy functions are set up on module methods\n    - Tests call the functions under test and verify behavior\n    - Mocks are reset between test cases to maintain isolation\n    - Tagged system behavior is tested for both migration and normal operation\n\n- **Benefits of this Architecture**:\n\n  - **Maintainability**: Modules are self-contained and focused, making it easier to understand, modify, and debug specific features.\n  - **Testability**:  Each module can be tested in isolation (unit testing), and interactions between modules can be tested (integration testing).\n    - **Mocking Support**: The clear dependency boundaries make mocking straightforward\n    - **Test Isolation**: Each component can be tested without affecting others\n    - **Callback Testing**: Function callbacks can be extracted and tested independently\n    - **Multi-Context Testing**: Tagged system enables testing different task contexts independently\n  - **Reusability**: Utility functions and UI components can be reused across different parts of the application.\n  - **Scalability**:  New features can be added as new modules or by extending existing ones without significantly impacting other parts of the application.\n  - **Multi-Context Support**: Tagged task lists enable working across different contexts (branches, environments, phases) without conflicts.\n  - **Backward Compatibility**: Seamless migration and tag resolution ensure existing workflows continue unchanged.\n  - **Clarity**: The modular structure provides a clear separation of concerns, making the codebase easier to navigate and understand for developers.\n\nThis architectural overview should help AI models understand the structure and organization of the Task Master CLI codebase, enabling them to more effectively assist with code generation, modification, and understanding.\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.\n\n2.  **Create Direct Function File in `mcp-server/src/core/direct-functions/`:**\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**.\n    - Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:\n        - **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` being provided.\n        - Parse other `args` and perform necessary validation.\n        - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()`.\n        - Implement caching with `getCachedOrExecute` if applicable.\n        - Call core logic.\n        - Return `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n    - **Note**: Tag-aware MCP tools are fully implemented with complete tag management support.\n\n3.  **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method:\n      - Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).\n      - Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)` or use `asyncOperationManager.addOperation`.\n      - Pass the result to `handleApiResult`.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition.\n\n## Project Initialization\n\nThe `initialize_project` command provides a way to set up a new Task Master project:\n\n- **CLI Command**: `task-master init`\n- **MCP Tool**: `initialize_project`\n- **Functionality**:\n  - Creates necessary directories and files for a new project\n  - Sets up `tasks.json` with tagged structure and initial task files\n  - Configures project metadata (name, description, version)\n  - Initializes state.json for tag system\n  - Handles shell alias creation if requested\n  - Works in both interactive and non-interactive modes","frontmatter":{"description":"Describes the high-level architecture of the Task Master CLI application.","globs":"scripts/modules/*.js","alwaysApply":false},"isInternal":false,"tokens":4303,"sizeBytes":19753},{"name":"changeset.mdc","path":".cursor/rules/changeset.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/changeset.mdc","title":"Cursor Rule: changeset","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\nalwaysApply: true\n---\n\n# Changesets Workflow Guidelines\n\nChangesets is used to manage package versioning and generate accurate `CHANGELOG.md` files automatically. It's crucial to use it correctly after making meaningful changes that affect the package from an external perspective or significantly impact internal development workflow documented elsewhere.\n\n## When to Run Changeset\n\n- Run `npm run changeset` (or `npx changeset add`) **after** you have staged (`git add .`) a logical set of changes that should be communicated in the next release's `CHANGELOG.md`.\n- This typically includes:\n    - **New Features** (Backward-compatible additions)\n    - **Bug Fixes** (Fixes to existing functionality)\n    - **Breaking Changes** (Changes that are not backward-compatible)\n    - **Performance Improvements** (Enhancements to speed or resource usage)\n    - **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability) - *Such as reorganizing the MCP server's direct function implementations into separate files*\n    - **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)\n    - **Dependency Updates** (Especially if they fix known issues or introduce significant changes)\n    - **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)\n- **Every Pull Request** containing one or more of the above change types **should include a changeset file**.\n\n## What NOT to Add a Changeset For\n\nAvoid creating changesets for changes that have **no impact or relevance to external consumers** of the `task-master` package or contributors following **public-facing documentation**. Examples include:\n\n- **Internal Documentation Updates:** Changes *only* to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.\n- **Trivial Chores:** Very minor code cleanup, adding comments that don't clarify behavior, typo fixes in non-user-facing code or internal docs.\n- **Non-Impactful Test Updates:** Minor refactoring of tests, adding tests for existing functionality without fixing bugs.\n- **Local Configuration Changes:** Updates to personal editor settings, local `.env` files, etc.\n\n**Rule of Thumb:** If a user installing or using the `task-master` package wouldn't care about the change, or if a contributor following the main README wouldn't need to know about it for their workflow, you likely don't need a changeset.\n\n## How to Run and What It Asks\n\n1.  **Run the command**:\n    ```bash\n    npm run changeset\n    # or\n    npx changeset add\n    ```\n2.  **Select Packages**: It will prompt you to select the package(s) affected by your changes using arrow keys and spacebar. If this is not a monorepo, select the main package.\n3.  **Select Bump Type**: Choose the appropriate semantic version bump for **each** selected package:\n    *   **`Major`**: For **breaking changes**. Use sparingly.\n    *   **`Minor`**: For **new features**.\n    *   **`Patch`**: For **bug fixes**, performance improvements, **user-facing documentation changes**, significant refactoring, relevant dependency updates, or impactful build/tooling changes.\n4.  **Enter Summary**: Provide a concise summary of the changes **for the `CHANGELOG.md`**.\n    *   **Purpose**: This message is user-facing and explains *what* changed in the release.\n    *   **Format**: Use the imperative mood (e.g., \"Add feature X\", \"Fix bug Y\", \"Update README setup instructions\"). Keep it brief, typically a single line.\n    *   **Audience**: Think about users installing/updating the package or developers consuming its public API/CLI.\n    *   **Not a Git Commit Message**: This summary is *different* from your detailed Git commit message.\n\n## Changeset Summary vs. Git Commit Message\n\n- **Changeset Summary**:\n    - **Audience**: Users/Consumers of the package (reads `CHANGELOG.md`).\n    - **Purpose**: Briefly describe *what* changed in the released version that is relevant to them.\n    - **Format**: Concise, imperative mood, single line usually sufficient.\n    - **Example**: `Fix dependency resolution bug in 'next' command.`\n- **Git Commit Message**:\n    - **Audience**: Developers browsing the Git history of *this* repository.\n    - **Purpose**: Explain *why* the change was made, the context, and the implementation details (can include internal context).\n    - **Format**: Follows commit conventions (e.g., Conventional Commits), can be multi-line with a subject and body.\n    - **Example**:\n      ```\n      fix(deps): Correct dependency lookup in 'next' command\n\n      The logic previously failed to account for subtask dependencies when\n      determining the next available task. This commit refactors the\n      dependency check in `findNextTask` within `task-manager.js` to\n      correctly traverse both direct and subtask dependencies. Added\n      unit tests to cover this specific scenario.\n      ```\n- ✅ **DO**: Provide *both* a concise changeset summary (when appropriate) *and* a detailed Git commit message.\n- ❌ **DON'T**: Use your detailed Git commit message body as the changeset summary.\n- ❌ **DON'T**: Skip running `changeset` for user-relevant changes just because you wrote a good commit message.\n\n## The `.changeset` File\n\n- Running the command creates a unique markdown file in the `.changeset/` directory (e.g., `.changeset/random-name.md`).\n- This file contains the bump type information and the summary you provided.\n- **This file MUST be staged and committed** along with your relevant code changes.\n\n## Standard Workflow Sequence (When a Changeset is Needed)\n\n1.  Make your code or relevant documentation changes.\n2.  Stage your changes: `git add .`\n3.  Run changeset: `npm run changeset`\n    *   Select package(s).\n    *   Select bump type (`Patch`, `Minor`, `Major`).\n    *   Enter the **concise summary** for the changelog.\n4.  Stage the generated changeset file: `git add .changeset/*.md`\n5.  Commit all staged changes (code + changeset file) using your **detailed Git commit message**:\n    ```bash\n    git commit -m \"feat(module): Add new feature X...\"\n    ```\n\n## Release Process (Context)\n\n- The generated `.changeset/*.md` files are consumed later during the release process.\n- Commands like `changeset version` read these files, update `package.json` versions, update the `CHANGELOG.md`, and delete the individual changeset files.\n- Commands like `changeset publish` then publish the new versions to npm.\n\nFollowing this workflow ensures that versioning is consistent and changelogs are automatically and accurately generated based on the contributions made.\n","frontmatter":{"description":"Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.","alwaysApply":true},"isInternal":false,"tokens":1491,"sizeBytes":6762},{"name":"commands.mdc","path":".cursor/rules/commands.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/commands.mdc","title":"Cursor Rule: commands","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing CLI commands using Commander.js\nglobs: scripts/modules/commands.js\nalwaysApply: false\n---\n\n# Command-Line Interface Implementation Guidelines\n\n**Note on Interaction Method:**\n\nWhile this document details the implementation of Task Master's **CLI commands**, the **preferred method for interacting with Task Master in integrated environments (like Cursor) is through the MCP server tools**. \n\n- **Use MCP Tools First**: Always prefer using the MCP tools (e.g., `get_tasks`, `add_task`) when interacting programmatically or via an integrated tool. They offer better performance, structured data, and richer error handling. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a comprehensive list of MCP tools and their corresponding CLI commands.\n- **CLI as Fallback/User Interface**: The `task-master` CLI commands described here are primarily intended for:\n    - Direct user interaction in the terminal.\n    - A fallback mechanism if the MCP server is unavailable or a specific functionality is not exposed via an MCP tool.\n- **Implementation Context**: This document (`commands.mdc`) focuses on the standards for *implementing* the CLI commands using Commander.js within the [`commands.js`](mdc:scripts/modules/commands.js) module.\n\n## Command Structure Standards\n\n- **Basic Command Template**:\n  ```javascript\n  // ✅ DO: Follow this structure for all commands\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-o, --option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n- **Command Handler Organization**:\n  - ✅ DO: Keep action handlers concise and focused\n  - ✅ DO: Extract core functionality to appropriate modules\n  - ✅ DO: Have the action handler import and call the relevant functions from core modules, like `task-manager.js` or `init.js`, passing the parsed `options`.\n  - ✅ DO: Perform basic parameter validation, such as checking for required options, within the action handler or at the start of the called core function.\n  - ❌ DON'T: Implement business logic in command handlers\n\n## Best Practices for Removal/Delete Commands\n\nWhen implementing commands that delete or remove data (like `remove-task` or `remove-subtask`), follow these specific guidelines:\n\n- **Confirmation Prompts**:\n  - ✅ **DO**: Include a confirmation prompt by default for destructive operations\n  - ✅ **DO**: Provide a `--yes` or `-y` flag to skip confirmation, useful for scripting or automation\n  - ✅ **DO**: Show what will be deleted in the confirmation message\n  - ❌ **DON'T**: Perform destructive operations without user confirmation unless explicitly overridden\n\n  ```javascript\n  // ✅ DO: Include confirmation for destructive operations\n  programInstance\n    .command('remove-task')\n    .description('Remove a task or subtask permanently')\n    .option('-i, --id <id>', 'ID of the task to remove')\n    .option('-y, --yes', 'Skip confirmation prompt', false)\n    .action(async (options) => {\n      // Validation code...\n      \n      if (!options.yes) {\n        const confirm = await inquirer.prompt([{\n          type: 'confirm',\n          name: 'proceed',\n          message: `Are you sure you want to permanently delete task ${taskId}? This cannot be undone.`,\n          default: false\n        }]);\n        \n        if (!confirm.proceed) {\n          console.log(chalk.yellow('Operation cancelled.'));\n          return;\n        }\n      }\n      \n      // Proceed with removal...\n    });\n  ```\n\n- **File Path Handling**:\n  - ✅ **DO**: Use `path.join()` to construct file paths\n  - ✅ **DO**: Follow established naming conventions for tasks, like `task_001.txt`\n  - ✅ **DO**: Check if files exist before attempting to delete them\n  - ✅ **DO**: Handle file deletion errors gracefully\n  - ❌ **DON'T**: Construct paths with string concatenation\n\n  ```javascript\n  // ✅ DO: Properly construct file paths\n  const taskFilePath = path.join(\n    path.dirname(tasksPath),\n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ✅ DO: Check existence before deletion\n  if (fs.existsSync(taskFilePath)) {\n    try {\n      fs.unlinkSync(taskFilePath);\n      console.log(chalk.green(`Task file deleted: ${taskFilePath}`));\n    } catch (error) {\n      console.warn(chalk.yellow(`Could not delete task file: ${error.message}`));\n    }\n  }\n  ```\n\n- **Clean Up References**:\n  - ✅ **DO**: Clean up references to the deleted item in other parts of the data\n  - ✅ **DO**: Handle both direct and indirect references\n  - ✅ **DO**: Explain what related data is being updated\n  - ❌ **DON'T**: Leave dangling references\n\n  ```javascript\n  // ✅ DO: Clean up references when deleting items\n  console.log(chalk.blue('Cleaning up task dependencies...'));\n  let referencesRemoved = 0;\n  \n  // Update dependencies in other tasks\n  data.tasks.forEach(task => {\n    if (task.dependencies && task.dependencies.includes(taskId)) {\n      task.dependencies = task.dependencies.filter(depId => depId !== taskId);\n      referencesRemoved++;\n    }\n  });\n  \n  if (referencesRemoved > 0) {\n    console.log(chalk.green(`Removed ${referencesRemoved} references to task ${taskId} from other tasks`));\n  }\n  ```\n\n- **Task File Regeneration**:\n  - ✅ **DO**: Regenerate task files after destructive operations\n  - ✅ **DO**: Pass all required parameters to generation functions\n  - ✅ **DO**: Provide an option to skip regeneration if needed\n  - ❌ **DON'T**: Assume default parameters will work\n\n  ```javascript\n  // ✅ DO: Properly regenerate files after deletion\n  if (!options.skipGenerate) {\n    console.log(chalk.blue('Regenerating task files...'));\n    try {\n      // Note both parameters are explicitly provided\n      await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n      console.log(chalk.green('Task files regenerated successfully'));\n    } catch (error) {\n      console.warn(chalk.yellow(`Warning: Could not regenerate task files: ${error.message}`));\n    }\n  }\n  ```\n\n- **Alternative Suggestions**:\n  - ✅ **DO**: Suggest non-destructive alternatives when appropriate\n  - ✅ **DO**: Explain the difference between deletion and status changes\n  - ✅ **DO**: Include examples of alternative commands\n\n  ```javascript\n  // ✅ DO: Suggest alternatives for destructive operations\n  console.log(chalk.yellow('Note: If you just want to exclude this task from active work, consider:'));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='cancelled'`));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='deferred'`));\n  console.log('This preserves the task and its history for reference.');\n  ```\n\n## Option Naming Conventions\n\n- **Command Names**:\n  - ✅ DO: Use kebab-case for command names (`analyze-complexity`)\n  - ❌ DON'T: Use camelCase for command names (`analyzeComplexity`)\n  - ✅ DO: Use descriptive, action-oriented names\n\n- **Option Names**:\n  - ✅ DO: Use kebab-case for long-form option names, like `--output-format`\n  - ✅ DO: Provide single-letter shortcuts when appropriate, like `-f, --file`\n  - ✅ DO: Use consistent option names across similar commands\n  - ❌ DON'T: Use different names for the same concept, such as `--file` in one command and `--path` in another\n\n  ```javascript\n  // ✅ DO: Use consistent option naming\n  .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <dir>', 'Output directory', 'tasks')\n  \n  // ❌ DON'T: Use inconsistent naming\n  .option('-f, --file <path>', 'Path to the tasks file')\n  .option('-p, --path <dir>', 'Output directory') // Should be --output\n  ```\n\n  > **Note**: Although options are defined with kebab-case, like `--num-tasks`, Commander.js stores them internally as camelCase properties. Access them in code as `options.numTasks`, not `options['num-tasks']`.\n\n- **Boolean Flag Conventions**:\n  - ✅ DO: Use positive flags with `--skip-` prefix for disabling behavior\n  - ❌ DON'T: Use negated boolean flags with `--no-` prefix\n  - ✅ DO: Use consistent flag handling across all commands\n\n  ```javascript\n  // ✅ DO: Use positive flag with skip- prefix \n  .option('--skip-generate', 'Skip generating task files')\n  \n  // ❌ DON'T: Use --no- prefix \n  .option('--no-generate', 'Skip generating task files')\n  ```\n\n  > **Important**: When handling boolean flags in the code, make your intent clear:\n  ```javascript\n  // ✅ DO: Use clear variable naming that matches the flag's intent\n  const generateFiles = !options.skipGenerate;\n  \n  // ❌ DON'T: Use confusing double negatives\n  const dontSkipGenerate = !options.skipGenerate;\n  ```\n\n## Input Validation\n\n- **Required Parameters**:\n  - ✅ DO: Check that required parameters are provided\n  - ✅ DO: Provide clear error messages when parameters are missing\n  - ✅ DO: Use early returns with `process.exit(1)` for validation failures\n\n  ```javascript\n  // ✅ DO: Validate required parameters early\n  if (!prompt) {\n    console.error(chalk.red('Error: --prompt parameter is required. Please provide a task description.'));\n    process.exit(1);\n  }\n  ```\n\n- **Parameter Type Conversion**:\n  - ✅ DO: Convert string inputs to appropriate types, such as numbers or booleans\n  - ✅ DO: Handle conversion errors gracefully\n\n  ```javascript\n  // ✅ DO: Parse numeric parameters properly\n  const fromId = parseInt(options.from, 10);\n  if (isNaN(fromId)) {\n    console.error(chalk.red('Error: --from must be a valid number'));\n    process.exit(1);\n  }\n  ```\n\n- **Enhanced Input Validation**:\n  - ✅ DO: Validate file existence for critical file operations\n  - ✅ DO: Provide context-specific validation for identifiers\n  - ✅ DO: Check required API keys for features that depend on them\n\n  ```javascript\n  // ✅ DO: Validate file existence\n  if (!fs.existsSync(tasksPath)) {\n    console.error(chalk.red(`Error: Tasks file not found at path: ${tasksPath}`));\n    if (tasksPath === 'tasks/tasks.json') {\n      console.log(chalk.yellow('Hint: Run task-master init or task-master parse-prd to create tasks.json first'));\n    } else {\n      console.log(chalk.yellow(`Hint: Check if the file path is correct: ${tasksPath}`));\n    }\n    process.exit(1);\n  }\n  \n  // ✅ DO: Validate task ID\n  const taskId = parseInt(options.id, 10);\n  if (isNaN(taskId) || taskId <= 0) {\n    console.error(chalk.red(`Error: Invalid task ID: ${options.id}. Task ID must be a positive integer.`));\n    console.log(chalk.yellow(\"Usage example: task-master update-task --id='23' --prompt='Update with new information.\\\\nEnsure proper error handling.'\"));\n    process.exit(1);\n  }\n  \n  // ✅ DO: Check for required API keys\n  if (useResearch && !process.env.PERPLEXITY_API_KEY) {\n    console.log(chalk.yellow('Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'));\n    console.log(chalk.yellow('Falling back to Claude AI for task update.'));\n  }\n  ```\n\n## User Feedback\n\n- **Operation Status**:\n  - ✅ DO: Provide clear feedback about the operation being performed\n  - ✅ DO: Display success or error messages after completion\n  - ✅ DO: Use colored output to distinguish between different message types\n\n  ```javascript\n  // ✅ DO: Show operation status\n  console.log(chalk.blue(`Parsing PRD file: ${file}`));\n  console.log(chalk.blue(`Generating ${numTasks} tasks...`));\n  \n  try {\n    await parsePRD(file, outputPath, numTasks);\n    console.log(chalk.green('Successfully generated tasks from PRD'));\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    process.exit(1);\n  }\n  ```\n\n- **Success Messages with Next Steps**:\n  - ✅ DO: Use boxen for important success messages with clear formatting\n  - ✅ DO: Provide suggested next steps after command completion\n  - ✅ DO: Include ready-to-use commands for follow-up actions\n\n  ```javascript\n  // ✅ DO: Display success with next steps\n  console.log(boxen(\n    chalk.white.bold(`Subtask ${parentId}.${subtask.id} Added Successfully`) + '\\n\\n' +\n    chalk.white(`Title: ${subtask.title}`) + '\\n' +\n    chalk.white(`Status: ${getStatusWithColor(subtask.status)}`) + '\\n' +\n    (dependencies.length > 0 ? chalk.white(`Dependencies: ${dependencies.join(', ')}`) + '\\n' : '') +\n    '\\n' +\n    chalk.white.bold('Next Steps:') + '\\n' +\n    chalk.cyan(`1. Run ${chalk.yellow(`task-master show '${parentId}'`)} to see the parent task with all subtasks`) + '\\n' +\n    chalk.cyan(`2. Run ${chalk.yellow(`task-master set-status --id='${parentId}.${subtask.id}' --status='in-progress'`)} to start working on it`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Command Registration\n\n- **Command Grouping**:\n  - ✅ DO: Group related commands together in the code\n  - ✅ DO: Add related commands in a logical order\n  - ✅ DO: Use comments to delineate command groups\n\n- **Command Export**:\n  - ✅ DO: Export the registerCommands function\n  - ✅ DO: Keep the CLI setup code clean and maintainable\n\n  ```javascript\n  // ✅ DO: Follow this export pattern\n  export {\n    registerCommands,\n    setupCLI,\n    runCLI,\n    checkForUpdate, // Include version checking functions\n    compareVersions,\n    displayUpgradeNotification\n  };\n  ```\n\n## Context-Aware Command Pattern\n\nFor AI-powered commands that benefit from project context, follow the research command pattern:\n\n- **Context Integration**:\n  - ✅ DO: Use `ContextGatherer` utility for multi-source context extraction\n  - ✅ DO: Support task IDs, file paths, custom context, and project tree\n  - ✅ DO: Implement fuzzy search for automatic task discovery\n  - ✅ DO: Display detailed token breakdown for transparency\n\n  ```javascript\n  // ✅ DO: Follow this pattern for context-aware commands\n  programInstance\n    .command('research')\n    .description('Perform AI-powered research queries with project context')\n    .argument('<prompt>', 'Research prompt to investigate')\n    .option('-i, --id <ids>', 'Comma-separated task/subtask IDs to include as context')\n    .option('-f, --files <paths>', 'Comma-separated file paths to include as context')\n    .option('-c, --context <text>', 'Additional custom context')\n    .option('--tree', 'Include project file tree structure')\n    .option('-d, --detail <level>', 'Output detail level: low, medium, high', 'medium')\n    .action(async (prompt, options) => {\n      // 1. Parameter validation and parsing\n      const taskIds = options.id ? parseTaskIds(options.id) : [];\n      const filePaths = options.files ? parseFilePaths(options.files) : [];\n      \n      // 2. Initialize context gatherer\n      const projectRoot = findProjectRoot() || '.';\n      const gatherer = new ContextGatherer(projectRoot, tasksPath);\n      \n      // 3. Auto-discover relevant tasks if none specified\n      if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n          fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n      }\n      \n      // 4. Gather context with token breakdown\n      const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n      });\n      \n      // 5. Display token breakdown and execute AI call\n      // Implementation continues...\n    });\n  ```\n\n## Error Handling\n\n- **Exception Management**:\n  - ✅ DO: Wrap async operations in try/catch blocks\n  - ✅ DO: Display user-friendly error messages\n  - ✅ DO: Include detailed error information in debug mode\n\n  ```javascript\n  // ✅ DO: Handle errors properly\n  try {\n    // Command implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n- **Unknown Options Handling**:\n  - ✅ DO: Provide clear error messages for unknown options\n  - ✅ DO: Show available options when an unknown option is used\n  - ✅ DO: Include command-specific help displays for common errors\n  - ❌ DON'T: Allow unknown options with `.allowUnknownOption()`\n\n  ```javascript\n  // ✅ DO: Register global error handlers for unknown options\n  programInstance.on('option:unknown', function(unknownOption) {\n    const commandName = this._name || 'unknown';\n    console.error(chalk.red(`Error: Unknown option '${unknownOption}'`));\n    console.error(chalk.yellow(`Run 'task-master ${commandName} --help' to see available options`));\n    process.exit(1);\n  });\n  \n  // ✅ DO: Add command-specific help displays\n  function showCommandHelp() {\n    console.log(boxen(\n      chalk.white.bold('Command Help') + '\\n\\n' +\n      chalk.cyan('Usage:') + '\\n' +\n      `  task-master command --option1=<value> [options]\\n\\n` +\n      chalk.cyan('Options:') + '\\n' +\n      '  --option1 <value>    Description of option1 (required)\\n' +\n      '  --option2 <value>    Description of option2\\n\\n' +\n      chalk.cyan('Examples:') + '\\n' +\n      '  task-master command --option1=\\'value1\\' --option2=\\'value2\\'',\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n- **Global Error Handling**:\n  - ✅ DO: Set up global error handlers for uncaught exceptions\n  - ✅ DO: Detect and format Commander-specific errors\n  - ✅ DO: Provide suitable guidance for fixing common errors\n\n  ```javascript\n  // ✅ DO: Set up global error handlers with helpful messages\n  process.on('uncaughtException', (err) => {\n    // Handle Commander-specific errors\n    if (err.code === 'commander.unknownOption') {\n      const option = err.message.match(/'([^']+)'/)?.[1]; // Safely extract option name\n      console.error(chalk.red(`Error: Unknown option '${option}'`));\n      console.error(chalk.yellow(\"Run 'task-master <command> --help' to see available options\"));\n      process.exit(1);\n    }\n    \n    // Handle other error types...\n    console.error(chalk.red(`Error: ${err.message}`));\n    process.exit(1);\n  });\n  ```\n\n- **Contextual Error Handling**:\n  - ✅ DO: Provide specific error handling for common issues\n  - ✅ DO: Include troubleshooting hints for each error type\n  - ✅ DO: Use consistent error formatting across all commands\n\n  ```javascript\n  // ✅ DO: Provide specific error handling with guidance\n  try {\n    // Implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    // Provide more helpful error messages for common issues\n    if (error.message.includes('task') && error.message.includes('not found')) {\n      console.log(chalk.yellow('\\nTo fix this issue:'));\n      console.log('  1. Run \\'task-master list\\' to see all available task IDs');\n      console.log('  2. Use a valid task ID with the --id parameter');\n    } else if (error.message.includes('API key')) {\n      console.log(chalk.yellow('\\nThis error is related to API keys. Check your environment variables.'));\n    }\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n## Integration with Other Modules\n\n- **Import Organization**:\n  - ✅ DO: Group imports by module/functionality\n  - ✅ DO: Import only what's needed, not entire modules\n  - ❌ DON'T: Create circular dependencies\n\n  ```javascript\n  // ✅ DO: Organize imports by module\n  import { program } from 'commander';\n  import path from 'path';\n  import chalk from 'chalk';\n  import https from 'https';\n  \n  import { CONFIG, log, readJSON } from './utils.js';\n  import { displayBanner, displayHelp } from './ui.js';\n  import { parsePRD, listTasks } from './task-manager.js';\n  import { addDependency } from './dependency-manager.js';\n  ```\n\n## Subtask Management Commands\n\n- **Add Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for adding subtasks\n  programInstance\n    .command('add-subtask')\n    .description('Add a new subtask to a parent task or convert an existing task to a subtask')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-p, --parent <id>', 'ID of the parent task (required)')\n    .option('-i, --task-id <id>', 'Existing task ID to convert to subtask')\n    .option('-t, --title <title>', 'Title for the new subtask, required if not converting')\n    .option('-d, --description <description>', 'Description for the new subtask, optional')\n    .option('--details <details>', 'Implementation details for the new subtask, optional')\n    .option('--dependencies <ids>', 'Comma-separated list of subtask IDs this subtask depends on')\n    .option('--status <status>', 'Initial status for the subtask', 'pending')\n    .option('--generate', 'Regenerate task files after adding subtask')\n    .action(async (options) => {\n      // Validate required parameters\n      if (!options.parent) {\n        console.error(chalk.red('Error: --parent parameter is required'));\n        showAddSubtaskHelp(); // Show contextual help\n        process.exit(1);\n      }\n      \n      // Implementation with detailed error handling\n    });\n  ```\n\n- **Remove Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for removing subtasks\n  programInstance\n    .command('remove-subtask')\n    .description('Remove a subtask from its parent task, optionally converting it to a standalone task')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-i, --id <id>', 'ID of the subtask to remove in format parentId.subtaskId, required')\n    .option('-c, --convert', 'Convert the subtask to a standalone task instead of deleting')\n    .option('--generate', 'Regenerate task files after removing subtask')\n    .action(async (options) => {\n      // Implementation with detailed error handling\n    })\n    .on('error', function(err) {\n      console.error(chalk.red(`Error: ${err.message}`));\n      showRemoveSubtaskHelp(); // Show contextual help\n      process.exit(1);\n    });\n  ```\n\n## Version Checking and Updates\n\n- **Automatic Version Checking**:\n  - ✅ DO: Implement version checking to notify users of available updates\n  - ✅ DO: Use non-blocking version checks that don't delay command execution\n  - ✅ DO: Display update notifications after command completion\n\n  ```javascript\n  // ✅ DO: Implement version checking function\n  async function checkForUpdate() {\n    // Implementation details...\n    // Example return structure:\n    return { currentVersion, latestVersion, updateAvailable };\n  }\n  \n  // ✅ DO: Implement semantic version comparison\n  function compareVersions(v1, v2) {\n    const v1Parts = v1.split('.').map(p => parseInt(p, 10));\n    const v2Parts = v2.split('.').map(p => parseInt(p, 10));\n    \n    // Implementation details...\n    return result; // -1, 0, or 1\n  }\n  \n  // ✅ DO: Display attractive update notifications\n  function displayUpgradeNotification(currentVersion, latestVersion) {\n    const message = boxen(\n      `${chalk.blue.bold('Update Available!')} ${chalk.dim(currentVersion)} → ${chalk.green(latestVersion)}\\n\\n` +\n      `Run ${chalk.cyan('npm i task-master-ai@latest -g')} to update to the latest version with new features and bug fixes.`,\n      {\n        padding: 1,\n        margin: { top: 1, bottom: 1 },\n        borderColor: 'yellow',\n        borderStyle: 'round'\n      }\n    );\n    \n    console.log(message);\n  }\n  \n  // ✅ DO: Integrate version checking in CLI run function\n  async function runCLI(argv = process.argv) {\n    try {\n      // Start the update check in the background - don't await yet\n      const updateCheckPromise = checkForUpdate();\n      \n      // Setup and parse\n      const programInstance = setupCLI();\n      await programInstance.parseAsync(argv);\n      \n      // After command execution, check if an update is available\n      const updateInfo = await updateCheckPromise;\n      if (updateInfo.updateAvailable) {\n        displayUpgradeNotification(updateInfo.currentVersion, updateInfo.latestVersion);\n      }\n    } catch (error) {\n      // Error handling...\n    }\n  }\n  ```\n\nRefer to [`commands.js`](mdc:scripts/modules/commands.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. \n// Helper function to show add-subtask command help\nfunction showAddSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Add Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master add-subtask --parent=<id> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -p, --parent <id>         Parent task ID (required)\\n' +\n    '  -i, --task-id <id>        Existing task ID to convert to subtask\\n' +\n    '  -t, --title <title>       Title for the new subtask\\n' +\n    '  -d, --description <text>  Description for the new subtask\\n' +\n    '  --details <text>          Implementation details for the new subtask\\n' +\n    '  --dependencies <ids>      Comma-separated list of dependency IDs\\n' +\n    '  -s, --status <status>     Status for the new subtask (default: \"pending\")\\n' +\n    '  -f, --file <file>         Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate                Regenerate task files after adding subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master add-subtask --parent=\\'5\\' --task-id=\\'8\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Implement login UI\\' -d \\'Create the login form\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Handle API Errors\\' --details \"Handle 401 Unauthorized.\\\\nHandle 500 Server Error.\" --generate',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n}\n\n// Helper function to show remove-subtask command help\nfunction showRemoveSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Remove Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master remove-subtask --id=<parentId.subtaskId> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -i, --id <id>       Subtask ID(s) to remove in format \"parentId.subtaskId\" (can be comma-separated, required)\\n' +\n    '  -c, --convert       Convert the subtask to a standalone task instead of deleting it\\n' +\n    '  -f, --file <file>   Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate          Regenerate task files after removing subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2,6.3,7.1\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\' --convert',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n} \n","frontmatter":{"description":"Guidelines for implementing CLI commands using Commander.js","globs":"scripts/modules/commands.js","alwaysApply":false},"isInternal":false,"tokens":6525,"sizeBytes":26852},{"name":"context_gathering.mdc","path":".cursor/rules/context_gathering.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/context_gathering.mdc","title":"Cursor Rule: context_gathering","category":"cursor-rule","format":"mdc","content":"---\ndescription: Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\nglobs: \nalwaysApply: false\n---\n# Context Gathering Patterns and Utilities\n\nThis document outlines the standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\n\n## Core Context Gathering Utility\n\nThe `ContextGatherer` class (`scripts/modules/utils/contextGatherer.js`) provides a centralized, reusable utility for extracting context from multiple sources:\n\n### **Key Features**\n- **Multi-source Context**: Tasks, files, custom text, project file tree\n- **Token Counting**: Detailed breakdown using `gpt-tokens` library\n- **Format Support**: Different output formats (research, chat, system-prompt)\n- **Error Handling**: Graceful handling of missing files, invalid task IDs\n- **Performance**: File size limits, depth limits for tree generation\n\n### **Usage Pattern**\n```javascript\nimport { ContextGatherer } from '../utils/contextGatherer.js';\n\n// Initialize with project paths\nconst gatherer = new ContextGatherer(projectRoot, tasksPath);\n\n// Gather context with detailed token breakdown\nconst result = await gatherer.gather({\n    tasks: ['15', '16.2'],           // Task and subtask IDs\n    files: ['src/api.js', 'README.md'], // File paths\n    customContext: 'Additional context text',\n    includeProjectTree: true,        // Include file tree\n    format: 'research',              // Output format\n    includeTokenCounts: true         // Get detailed token breakdown\n});\n\n// Access results\nconst contextString = result.context;\nconst tokenBreakdown = result.tokenBreakdown;\n```\n\n### **Token Breakdown Structure**\n```javascript\n{\n    customContext: { tokens: 150, characters: 800 },\n    tasks: [\n        { id: '15', type: 'task', title: 'Task Title', tokens: 245, characters: 1200 },\n        { id: '16.2', type: 'subtask', title: 'Subtask Title', tokens: 180, characters: 900 }\n    ],\n    files: [\n        { path: 'src/api.js', tokens: 890, characters: 4500, size: '4.5 KB' }\n    ],\n    projectTree: { tokens: 320, characters: 1600 },\n    total: { tokens: 1785, characters: 8000 }\n}\n```\n\n## Fuzzy Search Integration\n\nThe `FuzzyTaskSearch` class (`scripts/modules/utils/fuzzyTaskSearch.js`) provides intelligent task discovery:\n\n### **Key Features**\n- **Semantic Matching**: Uses Fuse.js for similarity scoring\n- **Purpose Categories**: Pattern-based task categorization\n- **Relevance Scoring**: High/medium/low relevance thresholds\n- **Context-Aware**: Different search configurations for different use cases\n\n### **Usage Pattern**\n```javascript\nimport { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n\n// Initialize with tasks data and context\nconst fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n\n// Find relevant tasks\nconst searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n});\n\n// Get task IDs for context gathering\nconst taskIds = fuzzySearch.getTaskIds(searchResults);\n```\n\n## Implementation Patterns for Commands\n\n### **1. Context-Aware Command Structure**\n```javascript\n// In command action handler\nasync function commandAction(prompt, options) {\n    // 1. Parameter validation and parsing\n    const taskIds = options.id ? parseTaskIds(options.id) : [];\n    const filePaths = options.files ? parseFilePaths(options.files) : [];\n    \n    // 2. Initialize context gatherer\n    const projectRoot = findProjectRoot() || '.';\n    const tasksPath = path.join(projectRoot, 'tasks', 'tasks.json');\n    const gatherer = new ContextGatherer(projectRoot, tasksPath);\n    \n    // 3. Auto-discover relevant tasks if none specified\n    if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n            fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n    }\n    \n    // 4. Gather context with token breakdown\n    const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n    });\n    \n    // 5. Display token breakdown (for CLI)\n    if (outputFormat === 'text') {\n        displayDetailedTokenBreakdown(contextResult.tokenBreakdown);\n    }\n    \n    // 6. Use context in AI call\n    const aiResult = await generateTextService(role, session, systemPrompt, userPrompt);\n    \n    // 7. Display results with enhanced formatting\n    displayResults(aiResult, contextResult.tokenBreakdown);\n}\n```\n\n### **2. Token Display Pattern**\n```javascript\nfunction displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    // Build context breakdown\n    if (tokenBreakdown.tasks?.length > 0) {\n        const taskDetails = tokenBreakdown.tasks.map(task => \n            `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n        ).join('\\n');\n        sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    if (tokenBreakdown.files?.length > 0) {\n        const fileDetails = tokenBreakdown.files.map(file =>\n            `  ${file.path}: ${file.tokens.toLocaleString()} (${file.size})`\n        ).join('\\n');\n        sections.push(`Files (${tokenBreakdown.files.reduce((sum, f) => sum + f.tokens, 0).toLocaleString()}):\\n${fileDetails}`);\n    }\n    \n    // Add prompts breakdown\n    sections.push(`Prompts: system ${systemTokens.toLocaleString()}, user ${userTokens.toLocaleString()}`);\n    \n    // Display in clean box\n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n        title: chalk.cyan('Token Usage'),\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        borderStyle: 'round',\n        borderColor: 'cyan'\n    }));\n}\n```\n\n### **3. Enhanced Result Display Pattern**\n```javascript\nfunction displayResults(result, query, detailLevel, tokenBreakdown) {\n    // Header with query info\n    const header = boxen(\n        chalk.green.bold('Research Results') + '\\n\\n' +\n        chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n        chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n        {\n            padding: { top: 1, bottom: 1, left: 2, right: 2 },\n            margin: { top: 1, bottom: 0 },\n            borderStyle: 'round',\n            borderColor: 'green'\n        }\n    );\n    console.log(header);\n    \n    // Process and highlight code blocks\n    const processedResult = processCodeBlocks(result);\n    \n    // Main content in clean box\n    const contentBox = boxen(processedResult, {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 0, bottom: 1 },\n        borderStyle: 'single',\n        borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Research complete'));\n}\n```\n\n## Code Block Enhancement\n\n### **Syntax Highlighting Pattern**\n```javascript\nimport { highlight } from 'cli-highlight';\n\nfunction processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n        try {\n            const highlighted = highlight(code.trim(), { \n                language: language || 'javascript',\n                theme: 'default'\n            });\n            return `\\n${highlighted}\\n`;\n        } catch (error) {\n            return `\\n${code.trim()}\\n`;\n        }\n    });\n}\n```\n\n## Integration Guidelines\n\n### **When to Use Context Gathering**\n- ✅ **DO**: Use for AI-powered commands that benefit from project context\n- ✅ **DO**: Use when users might want to reference specific tasks or files\n- ✅ **DO**: Use for research, analysis, or generation commands\n- ❌ **DON'T**: Use for simple CRUD operations that don't need AI context\n\n### **Performance Considerations**\n- ✅ **DO**: Set reasonable file size limits (50KB default)\n- ✅ **DO**: Limit project tree depth (3-5 levels)\n- ✅ **DO**: Provide token counts to help users understand context size\n- ✅ **DO**: Allow users to control what context is included\n\n### **Error Handling**\n- ✅ **DO**: Gracefully handle missing files with warnings\n- ✅ **DO**: Validate task IDs and provide helpful error messages\n- ✅ **DO**: Continue processing even if some context sources fail\n- ✅ **DO**: Provide fallback behavior when context gathering fails\n\n### **Future Command Integration**\nCommands that should consider adopting this pattern:\n- `analyze-complexity` - Could benefit from file context\n- `expand-task` - Could use related task context\n- `update-task` - Could reference similar tasks for consistency\n- `add-task` - Could use project context for better task generation\n\n## Export Patterns\n\n### **Context Gatherer Module**\n```javascript\nexport {\n    ContextGatherer,\n    createContextGatherer  // Factory function\n};\n```\n\n### **Fuzzy Search Module**\n```javascript\nexport {\n    FuzzyTaskSearch,\n    PURPOSE_CATEGORIES,\n    RELEVANCE_THRESHOLDS\n};\n```\n\nThis context gathering system provides a foundation for building more intelligent, context-aware commands that can leverage project knowledge to provide better AI-powered assistance.\n","frontmatter":{"description":"Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.","globs":null,"alwaysApply":false},"isInternal":false,"tokens":2178,"sizeBytes":9393},{"name":"cursor_rules.mdc","path":".cursor/rules/cursor_rules.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/cursor_rules.mdc","title":"Cursor Rule: cursor_rules","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\nglobs: .cursor/rules/*.mdc\nalwaysApply: true\n---\n\n- **Required Rule Structure:**\n  ```markdown\n  ---\n  description: Clear, one-line description of what the rule enforces\n  globs: path/to/files/*.ext, other/path/**/*\n  alwaysApply: boolean\n  ---\n\n  - **Main Points in Bold**\n    - Sub-points with details\n    - Examples and explanations\n  ```\n\n- **File References:**\n  - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files\n  - Example: [prisma.mdc](mdc:.cursor/rules/prisma.mdc) for rule references\n  - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references\n\n- **Code Examples:**\n  - Use language-specific code blocks\n  ```typescript\n  // ✅ DO: Show good examples\n  const goodExample = true;\n  \n  // ❌ DON'T: Show anti-patterns\n  const badExample = false;\n  ```\n\n- **Rule Content Guidelines:**\n  - Start with high-level overview\n  - Include specific, actionable requirements\n  - Show examples of correct implementation\n  - Reference existing code when possible\n  - Keep rules DRY by referencing other rules\n\n- **Rule Maintenance:**\n  - Update rules when new patterns emerge\n  - Add examples from actual codebase\n  - Remove outdated patterns\n  - Cross-reference related rules\n\n- **Best Practices:**\n  - Use bullet points for clarity\n  - Keep descriptions concise\n  - Include both DO and DON'T examples\n  - Reference actual code over theoretical examples\n  - Use consistent formatting across rules ","frontmatter":{"description":"Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.","globs":".cursor/rules/*.mdc","alwaysApply":true},"isInternal":false,"tokens":377,"sizeBytes":1555},{"name":"dependencies.mdc","path":".cursor/rules/dependencies.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/dependencies.mdc","title":"Cursor Rule: dependencies","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for managing task dependencies and relationships\nglobs: scripts/modules/dependency-manager.js\nalwaysApply: false\n---\n\n# Dependency Management Guidelines\n\n## Dependency Structure Principles\n\n- **Dependency References**:\n  - ✅ DO: Represent task dependencies as arrays of task IDs\n  - ✅ DO: Use numeric IDs for direct task references\n  - ✅ DO: Use string IDs with dot notation (e.g., \"1.2\") for subtask references\n  - ❌ DON'T: Mix reference types without proper conversion\n\n  ```javascript\n  // ✅ DO: Use consistent dependency formats\n  // For main tasks\n  task.dependencies = [1, 2, 3]; // Dependencies on other main tasks\n  \n  // For subtasks\n  subtask.dependencies = [1, \"3.2\"]; // Dependency on main task 1 and subtask 2 of task 3\n  ```\n\n- **Subtask Dependencies**:\n  - ✅ DO: Allow numeric subtask IDs to reference other subtasks within the same parent\n  - ✅ DO: Convert between formats appropriately when needed\n  - ❌ DON'T: Create circular dependencies between subtasks\n\n  ```javascript\n  // ✅ DO: Properly normalize subtask dependencies\n  // When a subtask refers to another subtask in the same parent\n  if (typeof depId === 'number' && depId < 100) {\n    // It's likely a reference to another subtask in the same parent task\n    const fullSubtaskId = `${parentId}.${depId}`;\n    // Now use fullSubtaskId for validation\n  }\n  ```\n\n## Dependency Validation\n\n- **Existence Checking**:\n  - ✅ DO: Validate that referenced tasks exist before adding dependencies\n  - ✅ DO: Provide clear error messages for non-existent dependencies\n  - ✅ DO: Remove references to non-existent tasks during validation\n\n  ```javascript\n  // ✅ DO: Check if the dependency exists before adding\n  if (!taskExists(data.tasks, formattedDependencyId)) {\n    log('error', `Dependency target ${formattedDependencyId} does not exist in tasks.json`);\n    process.exit(1);\n  }\n  ```\n\n- **Circular Dependency Prevention**:\n  - ✅ DO: Check for circular dependencies before adding new relationships\n  - ✅ DO: Use graph traversal algorithms (DFS) to detect cycles\n  - ✅ DO: Provide clear error messages explaining the circular chain\n\n  ```javascript\n  // ✅ DO: Check for circular dependencies before adding\n  const dependencyChain = [formattedTaskId];\n  if (isCircularDependency(data.tasks, formattedDependencyId, dependencyChain)) {\n    log('error', `Cannot add dependency ${formattedDependencyId} to task ${formattedTaskId} as it would create a circular dependency.`);\n    process.exit(1);\n  }\n  ```\n\n- **Self-Dependency Prevention**:\n  - ✅ DO: Prevent tasks from depending on themselves\n  - ✅ DO: Handle both direct and indirect self-dependencies\n\n  ```javascript\n  // ✅ DO: Prevent self-dependencies\n  if (String(formattedTaskId) === String(formattedDependencyId)) {\n    log('error', `Task ${formattedTaskId} cannot depend on itself.`);\n    process.exit(1);\n  }\n  ```\n\n## Dependency Modification\n\n- **Adding Dependencies**:\n  - ✅ DO: Format task and dependency IDs consistently\n  - ✅ DO: Check for existing dependencies to prevent duplicates\n  - ✅ DO: Sort dependencies for better readability\n\n  ```javascript\n  // ✅ DO: Format IDs consistently when adding dependencies\n  const formattedTaskId = typeof taskId === 'string' && taskId.includes('.') \n    ? taskId : parseInt(taskId, 10);\n  \n  const formattedDependencyId = formatTaskId(dependencyId);\n  ```\n\n- **Removing Dependencies**:\n  - ✅ DO: Check if the dependency exists before removing\n  - ✅ DO: Handle different ID formats consistently\n  - ✅ DO: Provide feedback about the removal result\n\n  ```javascript\n  // ✅ DO: Properly handle dependency removal\n  const dependencyIndex = targetTask.dependencies.findIndex(dep => {\n    // Convert both to strings for comparison\n    let depStr = String(dep);\n    \n    // Handle relative subtask references\n    if (typeof dep === 'number' && dep < 100 && isSubtask) {\n      const [parentId] = formattedTaskId.split('.');\n      depStr = `${parentId}.${dep}`;\n    }\n    \n    return depStr === normalizedDependencyId;\n  });\n  \n  if (dependencyIndex === -1) {\n    log('info', `Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`);\n    return;\n  }\n  \n  // Remove the dependency\n  targetTask.dependencies.splice(dependencyIndex, 1);\n  ```\n\n## Dependency Cleanup\n\n- **Duplicate Removal**:\n  - ✅ DO: Use Set objects to identify and remove duplicates\n  - ✅ DO: Handle both numeric and string ID formats\n\n  ```javascript\n  // ✅ DO: Remove duplicate dependencies\n  const uniqueDeps = new Set();\n  const uniqueDependencies = task.dependencies.filter(depId => {\n    // Convert to string for comparison to handle both numeric and string IDs\n    const depIdStr = String(depId);\n    if (uniqueDeps.has(depIdStr)) {\n      log('warn', `Removing duplicate dependency from task ${task.id}: ${depId}`);\n      return false;\n    }\n    uniqueDeps.add(depIdStr);\n    return true;\n  });\n  ```\n\n- **Invalid Reference Cleanup**:\n  - ✅ DO: Check for and remove references to non-existent tasks\n  - ✅ DO: Check for and remove self-references\n  - ✅ DO: Track and report changes made during cleanup\n\n  ```javascript\n  // ✅ DO: Filter invalid task dependencies\n  task.dependencies = task.dependencies.filter(depId => {\n    const numericId = typeof depId === 'string' ? parseInt(depId, 10) : depId;\n    if (!validTaskIds.has(numericId)) {\n      log('warn', `Removing invalid task dependency from task ${task.id}: ${depId} (task does not exist)`);\n      return false;\n    }\n    return true;\n  });\n  ```\n\n## Dependency Visualization\n\n- **Status Indicators**:\n  - ✅ DO: Use visual indicators to show dependency status (✅/⏱️)\n  - ✅ DO: Format dependency lists consistently\n\n  ```javascript\n  // ✅ DO: Format dependencies with status indicators\n  function formatDependenciesWithStatus(dependencies, allTasks) {\n    if (!dependencies || dependencies.length === 0) {\n      return 'None';\n    }\n    \n    return dependencies.map(depId => {\n      const depTask = findTaskById(allTasks, depId);\n      if (!depTask) return `${depId} (Not found)`;\n      \n      const isDone = depTask.status === 'done' || depTask.status === 'completed';\n      const statusIcon = isDone ? '✅' : '⏱️';\n      \n      return `${statusIcon} ${depId} (${depTask.status})`;\n    }).join(', ');\n  }\n  ```\n\n## Cycle Detection\n\n- **Graph Traversal**:\n  - ✅ DO: Use depth-first search (DFS) for cycle detection\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Support both task and subtask dependencies\n\n  ```javascript\n  // ✅ DO: Use proper cycle detection algorithms\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set()) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    \n    const cyclesToBreak = [];\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    for (const depId of dependencies) {\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack);\n        cyclesToBreak.push(...cycles);\n      } \n      else if (recursionStack.has(depId)) {\n        // Found a cycle, add the edge to break\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\nRefer to [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ","frontmatter":{"description":"Guidelines for managing task dependencies and relationships","globs":"scripts/modules/dependency-manager.js","alwaysApply":false},"isInternal":false,"tokens":1827,"sizeBytes":7639},{"name":"dev_workflow.mdc","path":".cursor/rules/dev_workflow.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/dev_workflow.mdc","title":"Cursor Rule: dev_workflow","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*","isInternal":false,"tokens":6978,"sizeBytes":31163},{"name":"git_workflow.mdc","path":".cursor/rules/git_workflow.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/git_workflow.mdc","title":"Cursor Rule: git_workflow","category":"cursor-rule","format":"mdc","content":"---\ndescription: Git workflow integrated with Task Master for feature development and collaboration\nglobs: \"**/*\"\nalwaysApply: true\n---\n# Git Workflow with Task Master Integration\n\n## **Branch Strategy**\n\n### **Main Branch Protection**\n- **main** branch contains production-ready code\n- All feature development happens on task-specific branches\n- Direct commits to main are prohibited\n- All changes merge via Pull Requests\n\n### **Task Branch Naming**\n```bash\n# ✅ DO: Use consistent task branch naming\ntask-001  # For Task 1\ntask-004  # For Task 4\ntask-015  # For Task 15\n\n# ❌ DON'T: Use inconsistent naming\nfeature/user-auth\nfix-database-issue\nrandom-branch-name\n```\n\n## **Tagged Task Lists Integration**\n\nTask Master's **tagged task lists system** provides significant benefits for Git workflows:\n\n### **Multi-Context Development**\n- **Branch-Specific Tasks**: Each branch can have its own task context using tags\n- **Merge Conflict Prevention**: Tasks in different tags are completely isolated\n- **Context Switching**: Seamlessly switch between different development contexts\n- **Parallel Development**: Multiple team members can work on separate task contexts\n\n### **Migration and Compatibility**\n- **Seamless Migration**: Existing projects automatically migrate to use a \"master\" tag\n- **Zero Disruption**: All existing Git workflows continue unchanged\n- **Backward Compatibility**: Legacy projects work exactly as before\n\n### **Manual Git Integration**\n- **Manual Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Switching**: Explicitly switch tag contexts as needed for different branches\n- **Simplified Integration**: Focused on manual control rather than automatic workflows\n\n## **Workflow Overview**\n\n```mermaid\nflowchart TD\n    A[Start: On main branch] --> B[Pull latest changes]\n    B --> C[Create task branch<br/>git checkout -b task-XXX]\n    C --> D[Set task status: in-progress]\n    D --> E[Get task context & expand if needed<br/>Tasks automatically use current tag]\n    E --> F[Identify next subtask]\n    \n    F --> G[Set subtask: in-progress]\n    G --> H[Research & collect context<br/>update_subtask with findings]\n    H --> I[Implement subtask]\n    I --> J[Update subtask with completion]\n    J --> K[Set subtask: done]\n    K --> L[Git commit subtask]\n    \n    L --> M{More subtasks?}\n    M -->|Yes| F\n    M -->|No| N[Run final tests]\n    \n    N --> O[Commit tests if added]\n    O --> P[Push task branch]\n    P --> Q[Create Pull Request]\n    Q --> R[Human review & merge]\n    R --> S[Switch to main & pull]\n    S --> T[Delete task branch]\n    T --> U[Ready for next task]\n    \n    style A fill:#e1f5fe\n    style C fill:#f3e5f5\n    style G fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n    style R fill:#f1f8e9\n    style U fill:#e1f5fe\n```\n\n## **Complete Task Development Workflow**\n\n### **Phase 1: Task Preparation**\n```bash\n# 1. Ensure you're on main branch and pull latest\ngit checkout main\ngit pull origin main\n\n# 2. Check current branch status\ngit branch  # Verify you're on main\n\n# 3. Create task-specific branch\ngit checkout -b task-004  # For Task 4\n\n# 4. Set task status in Task Master (tasks automatically use current tag context)\n# Use: set_task_status tool or `task-master set-status --id=4 --status=in-progress`\n```\n\n### **Phase 2: Task Analysis & Planning**\n```bash\n# 5. Get task context and expand if needed (uses current tag automatically)\n# Use: get_task tool or `task-master show 4`\n# Use: expand_task tool or `task-master expand --id=4 --research --force` (if complex)\n\n# 6. Identify next subtask to work on\n# Use: next_task tool or `task-master next`\n```\n\n### **Phase 3: Subtask Implementation Loop**\nFor each subtask, follow this pattern:\n\n```bash\n# 7. Mark subtask as in-progress\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=in-progress`\n\n# 8. Gather context and research (if needed)\n# Use: update_subtask tool with research flag or:\n# `task-master update-subtask --id=4.1 --prompt=\"Research findings...\" --research`\n\n# 9. Collect code context through AI exploration\n# Document findings in subtask using update_subtask\n\n# 10. Implement the subtask\n# Write code, tests, documentation\n\n# 11. Update subtask with completion details\n# Use: update_subtask tool or:\n# `task-master update-subtask --id=4.1 --prompt=\"Implementation complete...\"`\n\n# 12. Mark subtask as done\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=done`\n\n# 13. Commit the subtask implementation\ngit add .\ngit commit -m \"feat(task-4): Complete subtask 4.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Any important notes\n\nSubtask 4.1: [Brief description of what was accomplished]\nRelates to Task 4: [Main task title]\"\n```\n\n### **Phase 4: Task Completion**\n```bash\n# 14. When all subtasks are complete, run final testing\n# Create test file if needed, ensure all tests pass\nnpm test  # or jest, or manual testing\n\n# 15. If tests were added/modified, commit them\ngit add .\ngit commit -m \"test(task-4): Add comprehensive tests for Task 4\n\n- Unit tests for core functionality\n- Integration tests for API endpoints\n- All tests passing\n\nTask 4: [Main task title] - Testing complete\"\n\n# 16. Push the task branch\ngit push origin task-004\n\n# 17. Create Pull Request\n# Title: \"Task 4: [Task Title]\"\n# Description should include:\n# - Task overview\n# - Subtasks completed\n# - Testing approach\n# - Any breaking changes or considerations\n```\n\n### **Phase 5: PR Merge & Cleanup**\n```bash\n# 18. Human reviews and merges PR into main\n\n# 19. Switch back to main and pull merged changes\ngit checkout main\ngit pull origin main\n\n# 20. Delete the feature branch (optional cleanup)\ngit branch -d task-004\ngit push origin --delete task-004\n```\n\n## **Commit Message Standards**\n\n### **Subtask Commits**\n```bash\n# ✅ DO: Consistent subtask commit format\ngit commit -m \"feat(task-4): Complete subtask 4.1 - Initialize Express server\n\n- Set up Express.js with TypeScript configuration\n- Added CORS and body parsing middleware\n- Implemented health check endpoints\n- Basic error handling middleware\n\nSubtask 4.1: Initialize project with npm and install dependencies\nRelates to Task 4: Setup Express.js Server Project\"\n\n# ❌ DON'T: Vague or inconsistent commits\ngit commit -m \"fixed stuff\"\ngit commit -m \"working on task\"\n```\n\n### **Test Commits**\n```bash\n# ✅ DO: Separate test commits when substantial\ngit commit -m \"test(task-4): Add comprehensive tests for Express server setup\n\n- Unit tests for middleware configuration\n- Integration tests for health check endpoints\n- Mock tests for database connection\n- All tests passing with 95% coverage\n\nTask 4: Setup Express.js Server Project - Testing complete\"\n```\n\n### **Commit Type Prefixes**\n- `feat(task-X):` - New feature implementation\n- `fix(task-X):` - Bug fixes\n- `test(task-X):` - Test additions/modifications\n- `docs(task-X):` - Documentation updates\n- `refactor(task-X):` - Code refactoring\n- `chore(task-X):` - Build/tooling changes\n\n## **Task Master Commands Integration**\n\n### **Essential Commands for Git Workflow**\n```bash\n# Task management (uses current tag context automatically)\ntask-master show <id>           # Get task/subtask details\ntask-master next                # Find next task to work on\ntask-master set-status --id=<id> --status=<status>\ntask-master update-subtask --id=<id> --prompt=\"...\" --research\n\n# Task expansion (for complex tasks)\ntask-master expand --id=<id> --research --force\n\n# Progress tracking\ntask-master list                # View all tasks and status\ntask-master list --status=in-progress  # View active tasks\n```\n\n### **MCP Tool Equivalents**\nWhen using Cursor or other MCP-integrated tools:\n- `get_task` instead of `task-master show`\n- `next_task` instead of `task-master next`\n- `set_task_status` instead of `task-master set-status`\n- `update_subtask` instead of `task-master update-subtask`\n\n## **Branch Management Rules**\n\n### **Branch Protection**\n```bash\n# ✅ DO: Always work on task branches\ngit checkout -b task-005\n# Make changes\ngit commit -m \"...\"\ngit push origin task-005\n\n# ❌ DON'T: Commit directly to main\ngit checkout main\ngit commit -m \"...\"  # NEVER do this\n```\n\n### **Keeping Branches Updated**\n```bash\n# ✅ DO: Regularly sync with main (for long-running tasks)\ngit checkout task-005\ngit fetch origin\ngit rebase origin/main  # or merge if preferred\n\n# Resolve any conflicts and continue\n```\n\n## **Pull Request Guidelines**\n\n### **PR Title Format**\n```\nTask <ID>: <Task Title>\n\nExamples:\nTask 4: Setup Express.js Server Project\nTask 7: Implement User Authentication\nTask 12: Add Stripe Payment Integration\n```\n\n### **PR Description Template**\n```markdown\n## Task Overview\nBrief description of the main task objective.\n\n## Subtasks Completed\n- [x] 4.1: Initialize project with npm and install dependencies\n- [x] 4.2: Configure TypeScript, ESLint and Prettier  \n- [x] 4.3: Create basic Express app with middleware and health check route\n\n## Implementation Details\n- Key architectural decisions made\n- Important code changes\n- Any deviations from original plan\n\n## Testing\n- [ ] Unit tests added/updated\n- [ ] Integration tests passing\n- [ ] Manual testing completed\n\n## Breaking Changes\nList any breaking changes or migration requirements.\n\n## Related Tasks\nMention any dependent tasks or follow-up work needed.\n```\n\n## **Conflict Resolution**\n\n### **Task Conflicts with Tagged System**\n```bash\n# With tagged task lists, merge conflicts are significantly reduced:\n# 1. Different branches can use different tag contexts\n# 2. Tasks in separate tags are completely isolated\n# 3. Use Task Master's move functionality to reorganize if needed\n\n# Manual git integration available:\n# - Use `task-master add-tag --from-branch` to create tags from current branch\n# - Manually switch contexts with `task-master use-tag <name>`\n# - Simple, predictable workflow without automatic behavior\n```\n\n### **Code Conflicts**\n```bash\n# Standard Git conflict resolution\ngit fetch origin\ngit rebase origin/main\n# Resolve conflicts in files\ngit add .\ngit rebase --continue\n```\n\n## **Emergency Procedures**\n\n### **Hotfixes**\n```bash\n# For urgent production fixes:\ngit checkout main\ngit pull origin main\ngit checkout -b hotfix-urgent-issue\n\n# Make minimal fix\ngit commit -m \"hotfix: Fix critical production issue\n\n- Specific fix description\n- Minimal impact change\n- Requires immediate deployment\"\n\ngit push origin hotfix-urgent-issue\n# Create emergency PR for immediate review\n```\n\n### **Task Abandonment**\n```bash\n# If task needs to be abandoned or significantly changed:\n# 1. Update task status\ntask-master set-status --id=<id> --status=cancelled\n\n# 2. Clean up branch\ngit checkout main\ngit branch -D task-<id>\ngit push origin --delete task-<id>\n\n# 3. Document reasoning in task\ntask-master update-task --id=<id> --prompt=\"Task cancelled due to...\"\n```\n\n## **Tagged System Benefits for Git Workflows**\n\n### **Multi-Team Development**\n- **Isolated Contexts**: Different teams can work on separate tag contexts without conflicts\n- **Feature Branches**: Each feature branch can have its own task context\n- **Release Management**: Separate tags for different release versions or environments\n\n### **Merge Conflict Prevention**\n- **Context Separation**: Tasks in different tags don't interfere with each other\n- **Clean Merges**: Reduced likelihood of task-related merge conflicts\n- **Parallel Development**: Multiple developers can work simultaneously without task conflicts\n\n### **Manual Git Integration**\n- **Branch-Based Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Management**: Explicitly switch tag contexts as needed\n- **Predictable Workflow**: Simple, manual control without automatic behavior\n\n---\n\n**References:**\n- [Task Master Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Architecture Guidelines](mdc:.cursor/rules/architecture.mdc)\n- [Task Master Commands](mdc:.cursor/rules/taskmaster.mdc)\n","frontmatter":{"description":"Git workflow integrated with Task Master for feature development and collaboration","globs":"**/*","alwaysApply":true},"isInternal":false,"tokens":2932,"sizeBytes":11973},{"name":"glossary.mdc","path":".cursor/rules/glossary.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/glossary.mdc","title":"Cursor Rule: glossary","category":"cursor-rule","format":"mdc","content":"---\ndescription: Glossary of other Cursor rules\nglobs: **/*\nalwaysApply: true\n---\n# Glossary of Task Master Cursor Rules\n\nThis file provides a quick reference to the purpose of each rule file located in the `.cursor/rules` directory.\n\n- **[`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)**: Describes the high-level architecture of the Task Master CLI application, including the new tagged task lists system.\n- **[`changeset.mdc`](mdc:.cursor/rules/changeset.mdc)**: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\n- **[`commands.mdc`](mdc:.cursor/rules/commands.mdc)**: Guidelines for implementing CLI commands using Commander.js.\n- **[`cursor_rules.mdc`](mdc:.cursor/rules/cursor_rules.mdc)**: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\n- **[`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc)**: Guidelines for managing task dependencies and relationships across tagged task contexts.\n- **[`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc)**: Guide for using Task Master to manage task-driven development workflows with tagged task lists support.\n- **[`glossary.mdc`](mdc:.cursor/rules/glossary.mdc)**: This file; provides a glossary of other Cursor rules.\n- **[`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)**: Guidelines for implementing and interacting with the Task Master MCP Server.\n- **[`new_features.mdc`](mdc:.cursor/rules/new_features.mdc)**: Guidelines for integrating new features into the Task Master CLI with tagged system considerations.\n- **[`self_improve.mdc`](mdc:.cursor/rules/self_improve.mdc)**: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\n- **[`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)**: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information.\n- **[`tasks.mdc`](mdc:.cursor/rules/tasks.mdc)**: Guidelines for implementing task management operations with tagged task lists system support.\n- **[`tests.mdc`](mdc:.cursor/rules/tests.mdc)**: Guidelines for implementing and maintaining tests for Task Master CLI.\n- **[`ui.mdc`](mdc:.cursor/rules/ui.mdc)**: Guidelines for implementing and maintaining user interface components.\n- **[`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)**: Guidelines for implementing utility functions including tagged task lists utilities.\n- **[`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc)**: Guidelines for integrating AI usage telemetry across Task Master.\n\n","isInternal":false,"tokens":569,"sizeBytes":2534},{"name":"hamster.mdc","path":".cursor/rules/hamster.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/hamster.mdc","title":"Cursor Rule: hamster","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing tasks imported from Hamster using Task Master CLI\nglobs: \"**/*\"\nalwaysApply: true\n---\n\n# Hamster Integration Workflow\n\nThis guide outlines the process for working with tasks imported from Hamster briefs using Task Master. When connected to a Hamster brief, follow these specific guidelines to ensure proper task management and workflow execution.\n\n## **Command Restrictions**\n\n### **Supported Commands**\n- **✅ DO**: Use only these Task Master CLI commands when working with Hamster briefs:\n  ```bash\n  tm list                      # List all tasks\n  tm show <sub/task id> --json # Show task details\n  tm set-status                # Update task status\n  tm auth refresh              # Refresh authentication token\n  tm context <brief url>       # Reconnect to Hamster brief context\n  ```\n\n### **Unsupported Commands**\n- **❌ DON'T**: Use MCP tools when connected with Hamster briefs - they are not yet up to date with Hamster integration\n- **❌ DON'T**: Use other Task Master CLI commands that haven't been verified to work with Hamster integration\n\n## **Task Workflow Process**\n\n### **Starting a Task**\n```bash\n# ✅ DO: Mark task and subtasks as in-progress when starting\ntm set-status -i 1,1.1 -s in-progress\n\n# Multiple tasks/subtasks can be marked at once using comma separation\ntm set-status -i 1,1.1,1.2,2 -s in-progress\n```\n\n### **Task Implementation Flow**\n1. **Read the Task**: Use `tm show <id> --json` to understand the task requirements (json used to save tokens, gets you same information)\n2. **Check for Subtasks**: If the task has subtasks, implement them one at a time\n3. **Implement Subtask**: Complete the subtask implementation\n4. **Verify Quality**: Run lint and typecheck before marking as done\n   ```bash\n   npm lint\n   npm typecheck\n   ```\n5. **Mark Complete**: If verification passes, mark the subtask as done\n   ```bash\n   tm set-status -i 1.1 -s done\n   ```\n6. **Commit Changes**: Commit the completed subtask work\n7. **Repeat**: Continue until all subtasks are complete\n\n### **Parent Task Completion**\n- After all subtasks are done, run final verification:\n  ```bash\n  npm lint\n  npm typecheck\n  ```\n- Mark the parent task as done:\n  ```bash\n  tm set-status -i 1 -s done\n  ```\n- Move to the next task and repeat the process\n\n## **Multiple Task Context**\n\n### **Viewing Multiple Tasks**\n```bash\n# ✅ DO: Use comma-separated IDs to get context from multiple tasks\ntm show 1,1.1,2,2.1 --json\n\n# This is more efficient than calling tm show multiple times\n```\n\n### **Parallel Subtask Execution**\n- **When to Parallelize**: If a task has subtasks that can be completed in parallel\n- **Requirements**:\n  - Ensure work/files to adjust are **not the same** across subtasks\n  - Spawn sub-agents for each parallel subtask\n  - Verify clear separation of work before parallelizing\n- **Example**: If subtask 1.1 modifies `src/api.js` and subtask 1.2 modifies `src/utils.js`, these can run in parallel\n\n## **Pull Request Management**\n\n### **PR Creation Strategy**\n- **Preferred Approach**: Keep everything in one PR if scope remains manageable\n- **When to Split**: Create separate PRs if the work becomes too large\n- **Multi-PR Strategy**: If splitting is necessary:\n  - Create PRs that build on top of previous ones\n  - **Always confirm with the human** before creating multiple PRs\n- **PR Creation**: Use GitHub CLI after completing a task:\n  ```bash\n  gh pr create --title \"Task X: [Task Title]\" --body \"Description\"\n  ```\n\n### **Committing to PRs**\n- Keep committing to the same PR as long as the scope is maintained\n- An entire task list (brief) might fit into a single PR\n- If scope grows too large, discuss with human before creating new PRs\n\n## **Authentication & Context Management**\n\n### **Token Refresh**\n```bash\n# ✅ DO: Refresh token if JWT seems expired or commands don't work\ntm auth refresh\n\n# If refresh doesn't work, reconnect context\ntm context <brief url>\n```\n\n### **Context Reconnection**\n- **When Needed**: If commands stop working or authentication fails\n- **Required Information**: Brief URL (ask user if not available)\n- **Best Practice**: Store brief URL at the beginning of the session\n- **Command**: `tm context <brief url>`\n\n## **Integration with Git Workflow**\n\nWhen working with Hamster briefs, follow the standard Git workflow patterns outlined in [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc):\n\n- Create task-specific branches: `task-XXX`\n- Commit subtask work incrementally\n- Create PRs after task completion\n- Follow commit message standards\n\n## **Workflow Summary**\n\n```mermaid\nflowchart TD\n    A[Start: Connect to Hamster Brief] --> B[Get Brief URL]\n    B --> C[tm list - View Tasks]\n    C --> D[Select Task]\n    D --> E[tm show <id> --json - Read Task]\n    E --> F{Has Subtasks?}\n    F -->|Yes| G[Select First Subtask]\n    F -->|No| M[Implement Task]\n    G --> H[tm set-status -i X.Y -s in-progress]\n    H --> I[Implement Subtask]\n    I --> J[npm lint && npm typecheck]\n    J --> K{Passes?}\n    K -->|Yes| L[tm set-status -i X.Y -s done]\n    K -->|No| I\n    L --> N{More Subtasks?}\n    N -->|Yes| G\n    N -->|No| O[Final lint/typecheck]\n    M --> O\n    O --> P[tm set-status -i X -s done]\n    P --> Q[Commit & Create PR]\n    Q --> R{More Tasks?}\n    R -->|Yes| D\n    R -->|No| S[Complete]\n    \n    style A fill:#e1f5fe\n    style H fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n```\n\n## **Key Principles**\n\n- **Incremental Progress**: Work through subtasks one at a time\n- **Quality Gates**: Always run lint and typecheck before marking tasks as done\n- **Clear Communication**: Confirm with human before splitting work across multiple PRs\n- **Efficient Context Gathering**: Use comma-separated IDs when viewing multiple tasks\n- **Authentication Management**: Proactively refresh tokens and reconnect context when needed\n\n## **Related Rules**\n\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - Standard Git branching and PR practices\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - General Task Master development patterns\n- [Task Management](mdc:.cursor/rules/tasks.mdc) - Task structure and operations\n","frontmatter":{"description":"Guidelines for implementing tasks imported from Hamster using Task Master CLI","globs":"**/*","alwaysApply":true},"isInternal":false,"tokens":1552,"sizeBytes":6148},{"name":"mcp.mdc","path":".cursor/rules/mcp.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/mcp.mdc","title":"Cursor Rule: mcp","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing and interacting with the Task Master MCP Server\nglobs: mcp-server/src/**/*, scripts/modules/**/*\nalwaysApply: false\n---\n# Task Master MCP Server Guidelines\n\nThis document outlines the architecture and implementation patterns for the Task Master Model Context Protocol (MCP) server, designed for integration with tools like Cursor.\n\n## Architecture Overview (See also: [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc))\n\nThe MCP server acts as a bridge between external tools (like Cursor) and the core Task Master CLI logic. It leverages FastMCP for the server framework.\n\n- **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/direct-functions/*.js`, exported via `task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`)\n- **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation.\n\n## Direct Function Implementation Best Practices\n\nWhen implementing a new direct function in `mcp-server/src/core/direct-functions/`, follow these critical guidelines:\n\n1. **Verify Function Dependencies**:\n   - ✅ **DO**: Check that all helper functions your direct function needs are properly exported from their source modules\n   - ✅ **DO**: Import these dependencies explicitly at the top of your file\n   - ❌ **DON'T**: Assume helper functions like `findTaskById` or `taskExists` are automatically available\n   - **Example**:\n     ```javascript\n     // At top of direct-function file\n     import { removeTask, findTaskById, taskExists } from '../../../../scripts/modules/task-manager.js';\n     ```\n\n2. **Parameter Verification and Completeness**:\n   - ✅ **DO**: Verify the signature of core functions you're calling and ensure all required parameters are provided\n   - ✅ **DO**: Pass explicit values for required parameters rather than relying on defaults\n   - ✅ **DO**: Double-check parameter order against function definition\n   - ❌ **DON'T**: Omit parameters assuming they have default values\n   - **Example**:\n     ```javascript\n     // Correct parameter handling in direct function\n     async function generateTaskFilesDirect(args, log) {\n       const tasksPath = findTasksJsonPath(args, log);\n       const outputDir = args.output || path.dirname(tasksPath);\n       \n       try {\n         // Pass all required parameters\n         const result = await generateTaskFiles(tasksPath, outputDir);\n         return { success: true, data: result, fromCache: false };\n       } catch (error) {\n         // Error handling...\n       }\n     }\n     ```\n\n3. **Consistent File Path Handling**:\n   - ✅ **DO**: Use `path.join()` instead of string concatenation for file paths\n   - ✅ **DO**: Follow established file naming conventions (`task_001.txt` not `1.md`)\n   - ✅ **DO**: Use `path.dirname()` and other path utilities for manipulating paths\n   - ✅ **DO**: When paths relate to task files, follow the standard format: `task_${id.toString().padStart(3, '0')}.txt`\n   - ❌ **DON'T**: Create custom file path handling logic that diverges from established patterns\n   - **Example**:\n     ```javascript\n     // Correct file path handling\n     const taskFilePath = path.join(\n       path.dirname(tasksPath),\n       `task_${taskId.toString().padStart(3, '0')}.txt`\n     );\n     ```\n\n4. **Comprehensive Error Handling**:\n   - ✅ **DO**: Wrap core function calls *and AI calls* in try/catch blocks\n   - ✅ **DO**: Log errors with appropriate severity and context\n   - ✅ **DO**: Return standardized error objects with code and message (`{ success: false, error: { code: '...', message: '...' } }`)\n   - ✅ **DO**: Handle file system errors, AI client errors, AI processing errors, and core function errors distinctly with appropriate codes.\n   - **Example**:\n     ```javascript\n     try {\n       // Core function call or AI logic\n     } catch (error) {\n       log.error(`Failed to execute direct function logic: ${error.message}`);\n       return {\n         success: false,\n         error: {\n           code: error.code || 'DIRECT_FUNCTION_ERROR', // Use specific codes like AI_CLIENT_ERROR, etc.\n           message: error.message,\n           details: error.stack // Optional: Include stack in debug mode\n         },\n         fromCache: false // Ensure this is included if applicable\n       };\n     }\n     ```\n\n5. **Handling Logging Context (`mcpLog`)**:\n   - **Requirement**: Core functions (like those in `task-manager.js`) may accept an `options` object containing an optional `mcpLog` property. If provided, the core function expects this object to have methods like `mcpLog.info(...)`, `mcpLog.error(...)`.\n   - **Solution: The Logger Wrapper Pattern**: When calling a core function from a direct function, pass the `log` object provided by FastMCP *wrapped* in the standard `logWrapper` object. This ensures the core function receives a logger with the expected method structure.\n     ```javascript\n     // Standard logWrapper pattern within a Direct Function\n     const logWrapper = {\n       info: (message, ...args) => log.info(message, ...args),\n       warn: (message, ...args) => log.warn(message, ...args),\n       error: (message, ...args) => log.error(message, ...args),\n       debug: (message, ...args) => log.debug && log.debug(message, ...args),\n       success: (message, ...args) => log.info(message, ...args)\n     };\n\n     // ... later when calling the core function ...\n     await coreFunction(\n       // ... other arguments ...\n       { \n         mcpLog: logWrapper, // Pass the wrapper object\n         session // Also pass session if needed by core logic or AI service\n       },\n       'json' // Pass 'json' output format if supported by core function\n     );\n     ```\n   - **JSON Output**: Passing `mcpLog` (via the wrapper) often triggers the core function to use a JSON-friendly output format, suppressing spinners/boxes.\n   - ✅ **DO**: Implement this pattern in direct functions calling core functions that might use `mcpLog`.\n\n6. **Silent Mode Implementation**:\n    - ✅ **DO**: Import silent mode utilities: `import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';`\n    - ✅ **DO**: Wrap core function calls *within direct functions* using `enableSilentMode()` / `disableSilentMode()` in a `try/finally` block if the core function might produce console output (spinners, boxes, direct `console.log`) that isn't reliably controlled by passing `{ mcpLog }` or an `outputFormat` parameter.\n    - ✅ **DO**: Always disable silent mode in the `finally` block.\n    - ❌ **DON'T**: Wrap calls to the unified AI service (`generateTextService`, `generateObjectService`) in silent mode; their logging is handled internally.\n    - **Example (Direct Function Guaranteeing Silence & using Log Wrapper)**:\n      ```javascript\n      export async function coreWrapperDirect(args, log, context = {}) {\n        const { session } = context;\n        const tasksPath = findTasksJsonPath(args, log);\n        const logWrapper = { /* ... */ };\n\n        enableSilentMode(); // Ensure silence for direct console output\n        try {\n          const result = await coreFunction(\n             tasksPath,\n             args.param1,\n             { mcpLog: logWrapper, session }, // Pass context\n             'json' // Request JSON format if supported\n          );\n          return { success: true, data: result };\n        } catch (error) {\n           log.error(`Error: ${error.message}`);\n           return { success: false, error: { /* ... */ } };\n        } finally {\n           disableSilentMode(); // Critical: Always disable in finally\n        }\n      }\n      ```\n\n7. **Debugging MCP/Core Logic Interaction**:\n    - ✅ **DO**: If an MCP tool fails with unclear errors (like JSON parsing failures), run the equivalent `task-master` CLI command in the terminal. The CLI often provides more detailed error messages originating from the core logic (e.g., `ReferenceError`, stack traces) that are obscured by the MCP layer.\n\n## Tool Definition and Execution\n\n### Tool Structure\n\nMCP tools must follow a specific structure to properly interact with the FastMCP framework:\n\n```javascript\nserver.addTool({\n  name: \"tool_name\",  // Use snake_case for tool names\n  description: \"Description of what the tool does\",\n  parameters: z.object({\n    // Define parameters using Zod\n    param1: z.string().describe(\"Parameter description\"),\n    param2: z.number().optional().describe(\"Optional parameter description\"),\n    // IMPORTANT: For file operations, always include these optional parameters\n    file: z.string().optional().describe(\"Path to the tasks file\"),\n    projectRoot: z.string().optional().describe(\"Root directory of the project (typically derived from session)\")\n  }),\n\n  // The execute function is the core of the tool implementation\n  execute: async (args, context) => {\n    // Implementation goes here\n    // Return response in the appropriate format\n  }\n});\n```\n\n### Execute Function Signature\n\nThe `execute` function receives validated arguments and the FastMCP context:\n\n```javascript\n// Destructured signature (recommended)\nexecute: async (args, { log, session }) => {\n  // Tool implementation\n}\n```\n\n- **args**: Validated parameters.\n- **context**: Contains `{ log, session }` from FastMCP. (Removed `reportProgress`).\n\n### Standard Tool Execution Pattern with Path Normalization (Updated)\n\nTo ensure consistent handling of project paths across different client environments (Windows, macOS, Linux, WSL) and input formats (e.g., `file:///...`, URI encoded paths), all MCP tool `execute` methods that require access to the project root **MUST** be wrapped with the `withNormalizedProjectRoot` Higher-Order Function (HOF).\n\nThis HOF, defined in [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js), performs the following before calling the tool's core logic:\n\n1.  **Determines the Raw Root:** It prioritizes `args.projectRoot` if provided by the client, otherwise it calls `getRawProjectRootFromSession` to extract the path from the session.\n2.  **Normalizes the Path:** It uses the `normalizeProjectRoot` helper to decode URIs, strip `file://` prefixes, fix potential Windows drive letter prefixes (e.g., `/C:/`), convert backslashes (`\\`) to forward slashes (`/`), and resolve the path to an absolute path suitable for the server's OS.\n3.  **Injects Normalized Path:** It updates the `args` object by replacing the original `projectRoot` (or adding it) with the normalized, absolute path.\n4.  **Executes Original Logic:** It calls the original `execute` function body, passing the updated `args` object.\n\n**Implementation Example:**\n\n```javascript\n// In mcp-server/src/tools/your-tool.js\nimport {\n    handleApiResult,\n    createErrorResponse,\n    withNormalizedProjectRoot // <<< Import HOF\n} from './utils.js';\nimport { yourDirectFunction } from '../core/task-master-core.js';\nimport { findTasksJsonPath } from '../core/utils/path-utils.js'; // If needed\n\nexport function registerYourTool(server) {\n    server.addTool({\n        name: \"your_tool\",\n        description: \"...\".\n        parameters: z.object({\n            // ... other parameters ...\n            projectRoot: z.string().optional().describe('...') // projectRoot is optional here, HOF handles fallback\n        }),\n        // Wrap the entire execute function\n        execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n            // args.projectRoot is now guaranteed to be normalized and absolute\n            const { /* other args */, projectRoot } = args;\n\n            try {\n                log.info(`Executing your_tool with normalized root: ${projectRoot}`);\n\n                // Resolve paths using the normalized projectRoot\n                let tasksPath = findTasksJsonPath({ projectRoot, file: args.file }, log);\n\n                // Call direct function, passing normalized projectRoot if needed by direct func\n                const result = await yourDirectFunction(\n                    {\n                        /* other args */,\n                        projectRoot // Pass it if direct function needs it\n                    },\n                    log,\n                    { session }\n                );\n\n                return handleApiResult(result, log);\n            } catch (error) {\n                log.error(`Error in your_tool: ${error.message}`);\n                return createErrorResponse(error.message);\n            }\n        }) // End HOF wrap\n    });\n}\n```\n\nBy using this HOF, the core logic within the `execute` method and any downstream functions (like `findTasksJsonPath` or direct functions) can reliably expect `args.projectRoot` to be a clean, absolute path suitable for the server environment.\n\n### Project Initialization Tool\n\nThe `initialize_project` tool allows integrated clients like Cursor to set up a new Task Master project:\n\n```javascript\n// In initialize-project.js\nimport { z } from \"zod\";\nimport { initializeProjectDirect } from \"../core/task-master-core.js\";\nimport { handleApiResult, createErrorResponse } from \"./utils.js\";\n\nexport function registerInitializeProjectTool(server) {\n  server.addTool({\n    name: \"initialize_project\",\n    description: \"Initialize a new Task Master project\",\n    parameters: z.object({\n      projectName: z.string().optional().describe(\"The name for the new project\"),\n      projectDescription: z.string().optional().describe(\"A brief description\"),\n      projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n      authorName: z.string().optional().describe(\"The author's name\"),\n      skipInstall: z.boolean().optional().describe(\"Skip installing dependencies\"),\n      addAliases: z.boolean().optional().describe(\"Add shell aliases\"),\n      yes: z.boolean().optional().describe(\"Skip prompts and use defaults\")\n    }),\n    execute: async (args, { log, reportProgress }) => {\n      try {\n        // Since we're initializing, we don't need project root\n        const result = await initializeProjectDirect(args, log);\n        return handleApiResult(result, log, 'Error initializing project');\n      } catch (error) {\n        log.error(`Error in initialize_project: ${error.message}`);\n        return createErrorResponse(`Failed to initialize project: ${error.message}`);\n      }\n    }\n  });\n}\n```\n\n### Logging Convention\n\nThe `log` object (destructured from `context`) provides standardized logging methods. Use it within both the `execute` method and the `*Direct` functions. **If progress indication is needed within a direct function, use `log.info()` instead of `reportProgress`**.\n\n```javascript\n// Proper logging usage\nlog.info(`Starting ${toolName} with parameters: ${JSON.stringify(sanitizedArgs)}`);\nlog.debug(\"Detailed operation info\", { data });\nlog.warn(\"Potential issue detected\");\nlog.error(`Error occurred: ${error.message}`, { stack: error.stack });\nlog.info('Progress: 50% - AI call initiated...'); // Example progress logging\n```\n\n## Session Usage Convention\n\nThe `session` object (destructured from `context`) contains authenticated session data and client information.\n\n- **Authentication**: Access user-specific data (`session.userId`, etc.) if authentication is implemented.\n- **Project Root**: The primary use in Task Master is accessing `session.roots` to determine the client's project root directory via the `getProjectRootFromSession` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)). See the Standard Tool Execution Pattern above.\n- **Environment Variables**: The `session.env` object provides access to environment variables set in the MCP client configuration (e.g., `.cursor/mcp.json`). This is the **primary mechanism** for the unified AI service layer (`ai-services-unified.js`) to securely access **API keys** when called from MCP context.\n- **Capabilities**: Can be used to check client capabilities (`session.clientCapabilities`).\n\n## Direct Function Wrappers (`*Direct`)\n\nThese functions, located in `mcp-server/src/core/direct-functions/`, form the core logic execution layer for MCP tools.\n\n- **Purpose**: Bridge MCP tools and core Task Master modules (`scripts/modules/*`). Handle AI interactions if applicable.\n- **Responsibilities**:\n  - Receive `args` (including `projectRoot`), `log`, and optionally `{ session }` context.\n  - Find `tasks.json` using `findTasksJsonPath`.\n  - Validate arguments.\n  - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n  - **Call Core Logic**: Invoke function from `scripts/modules/*`.\n    - Pass `outputFormat: 'json'` if applicable.\n    - Wrap with `enableSilentMode/disableSilentMode` if needed.\n    - Pass `{ mcpLog: logWrapper, session }` context if core logic needs it.\n  - Handle errors.\n  - Return standardized result object.\n  - ❌ **DON'T**: Call `reportProgress`.\n  - ❌ **DON'T**: Initialize AI clients or call AI services directly.\n\n## Key Principles\n\n- **Prefer Direct Function Calls**: MCP tools should always call `*Direct` wrappers instead of `executeTaskMasterCommand`.\n- **Standardized Execution Flow**: Follow the pattern: MCP Tool -> `getProjectRootFromSession` -> `*Direct` Function -> Core Logic / AI Logic.\n- **Path Resolution via Direct Functions**: The `*Direct` function is responsible for finding the exact `tasks.json` path using `findTasksJsonPath`, relying on the `projectRoot` passed in `args`.\n- **AI Logic in Core Modules**: AI interactions (prompt building, calling unified service) reside within the core logic functions (`scripts/modules/*`), not direct functions.\n- **Silent Mode in Direct Functions**: Wrap *core function* calls (from `scripts/modules`) with `enableSilentMode()` and `disableSilentMode()` if they produce console output not handled by `outputFormat`. Do not wrap AI calls.\n- **Selective Async Processing**: Use `AsyncOperationManager` in the *MCP Tool layer* for operations involving multiple steps or long waits beyond a single AI call (e.g., file processing + AI call + file writing). Simple AI calls handled entirely within the `*Direct` function (like `addTaskDirect`) may not need it at the tool layer.\n- **No `reportProgress` in Direct Functions**: Do not pass or use `reportProgress` within `*Direct` functions. Use `log.info()` for internal progress or report progress from the `AsyncOperationManager` callback in the MCP tool layer.\n- **Output Formatting**: Ensure core functions called by `*Direct` functions can suppress CLI output, ideally via an `outputFormat` parameter.\n- **Project Initialization**: Use the initialize_project tool for setting up new projects in integrated environments.\n- **Centralized Utilities**: Use helpers from `mcp-server/src/tools/utils.js`, `mcp-server/src/core/utils/path-utils.js`, and `mcp-server/src/core/utils/ai-client-utils.js`. See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).\n- **Caching in Direct Functions**: Caching logic resides *within* the `*Direct` functions using `getCachedOrExecute`.\n\n## Resources and Resource Templates\n\nResources provide LLMs with static or dynamic data without executing tools.\n\n- **Implementation**: Use `@mcp.resource()` decorator pattern or `server.addResource`/`server.addResourceTemplate` in `mcp-server/src/core/resources/`.\n- **Registration**: Register resources during server initialization in [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js).\n- **Best Practices**: Organize resources, validate parameters, use consistent URIs, handle errors. See [`fastmcp-core.txt`](docs/fastmcp-core.txt) for underlying SDK details.\n\n*(Self-correction: Removed detailed Resource implementation examples as they were less relevant to the current user focus on tool execution flow and project roots. Kept the overview.)*\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`. Ensure the core function can suppress console output (e.g., via an `outputFormat` parameter).\n\n2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, `findTasksJsonPath`, silent mode utilities, and potentially AI client/prompt utilities.\n    - Implement `async function yourCommandDirect(args, log, context = {})` using **camelCase** with `Direct` suffix. **Remember `context` should only contain `{ session }` if needed (for AI keys/config).**\n        - **Path Resolution**: Obtain `tasksPath` using `findTasksJsonPath(args, log)`.\n        - Parse other `args` and perform necessary validation.\n        - **Handle AI (if applicable)**: Initialize clients using `get*ClientForMCP(session, log)`, build prompts, call AI, parse response. Handle AI-specific errors.\n        - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n        - **Call Core Logic**:\n            - Wrap with `enableSilentMode/disableSilentMode` if necessary.\n            - Pass `outputFormat: 'json'` (or similar) if applicable.\n            - Handle errors from the core function.\n        - Format the return as `{ success: true/false, data/error, fromCache?: boolean }`.\n        - ❌ **DON'T**: Call `reportProgress`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, `createErrorResponse`, `getProjectRootFromSession`, and your `yourCommandDirect` function. Import `AsyncOperationManager` if needed.\n    - Implement `registerYourCommandTool(server)`.\n    - Define the tool `name` using **snake_case** (e.g., `your_command`).\n    - Define the `parameters` using `zod`. Include `projectRoot: z.string().optional()`.\n    - Implement the `async execute(args, { log, session })` method (omitting `reportProgress` from destructuring).\n        - Get `rootFolder` using `getProjectRootFromSession(session, log)`.\n        - **Determine Execution Strategy**:\n            - **If using `AsyncOperationManager`**: Create the operation, call the `*Direct` function from within the async task callback (passing `log` and `{ session }`), report progress *from the callback*, and return the initial `ACCEPTED` response.\n            - **If calling `*Direct` function synchronously** (like `add-task`): Call `await yourCommandDirect({ ...args, projectRoot }, log, { session });`. Handle the result with `handleApiResult`.\n        - ❌ **DON'T**: Pass `reportProgress` down to the direct function in either case.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Handling Responses\n\n- MCP tools should return the object generated by `handleApiResult`.\n- `handleApiResult` uses `createContentResponse` or `createErrorResponse` internally.\n- `handleApiResult` also uses `processMCPResponseData` by default to filter potentially large fields (`details`, `testStrategy`) from task data. Provide a custom processor function to `handleApiResult` if different filtering is needed.\n- The final JSON response sent to the MCP client will include the `fromCache` boolean flag (obtained from the `*Direct` function's result) alongside the actual data (e.g., `{ \"fromCache\": true, \"data\": { ... } }` or `{ \"fromCache\": false, \"data\": { ... } }`).\n\n## Parameter Type Handling\n\n- **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n- **Standard Tool Execution Pattern**:\n    - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should:\n        1.  Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger.\n        2.  Receive the result object (typically `{ success, data/error, fromCache }`).\n        3.  Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized response formatting and error handling.\n        4.  Return the formatted response object provided by `handleApiResult`.\n- **CLI Execution as Fallback**: The `executeTaskMasterCommand` utility in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) allows executing commands via the CLI (`task-master ...`). This should **only** be used as a fallback if a direct function wrapper is not yet implemented or if a specific command intrinsically requires CLI execution.\n- **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n    - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently.\n    - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation:\n        - `getProjectRoot`: Normalizes project paths.\n        - `handleApiResult`: Takes the raw result from a `*Direct` function and formats it into a standard MCP success or error response, automatically handling data processing via `processMCPResponseData`. This is called by the tool's `execute` method.\n        - `createContentResponse`/`createErrorResponse`: Used by `handleApiResult` to format successful/error MCP responses.\n        - `processMCPResponseData`: Filters/cleans data (e.g., removing `details`, `testStrategy`) before it's sent in the MCP response. Called by `handleApiResult`.\n        - `getCachedOrExecute`: **Used inside `*Direct` functions** in `task-master-core.js` to implement caching logic.\n        - `executeTaskMasterCommand`: Fallback for executing CLI commands.\n- **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented.\n    - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) using the `getCachedOrExecute` utility from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    - Generate unique cache keys based on function arguments that define a distinct call (e.g., file path, filters).\n    - The `getCachedOrExecute` utility handles checking the cache, executing the core logic function on a cache miss, storing the result, and returning the data along with a `fromCache` flag.\n    - Cache statistics can be monitored using the `cacheStats` MCP tool (implemented via `getCacheStatsDirect`).\n    - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data.\n\n**MCP Tool Implementation Checklist**:\n\n1. **Core Logic Verification**:\n   - [ ] Confirm the core function is properly exported from its module (e.g., `task-manager.js`)\n   - [ ] Identify all required parameters and their types\n\n2. **Direct Function Wrapper**:\n   - [ ] Create the `*Direct` function in the appropriate file in `mcp-server/src/core/direct-functions/`\n   - [ ] Import silent mode utilities and implement them around core function calls\n   - [ ] Handle all parameter validations and type conversions\n   - [ ] Implement path resolving for relative paths\n   - [ ] Add appropriate error handling with standardized error codes\n   - [ ] Add to imports/exports in `task-master-core.js`\n\n3. **MCP Tool Implementation**:\n   - [ ] Create new file in `mcp-server/src/tools/` with kebab-case naming\n   - [ ] Define zod schema for all parameters\n   - [ ] Implement the `execute` method following the standard pattern\n   - [ ] Consider using AsyncOperationManager for long-running operations\n   - [ ] Register tool in `mcp-server/src/tools/index.js`\n\n4. **Testing**:\n   - [ ] Write unit tests for the direct function wrapper\n   - [ ] Write integration tests for the MCP tool\n\n## Standard Error Codes\n\n- **Standard Error Codes**: Use consistent error codes across direct function wrappers\n  - `INPUT_VALIDATION_ERROR`: For missing or invalid required parameters\n  - `FILE_NOT_FOUND_ERROR`: For file system path issues\n  - `CORE_FUNCTION_ERROR`: For errors thrown by the core function\n  - `UNEXPECTED_ERROR`: For all other unexpected errors\n\n- **Error Object Structure**:\n  ```javascript\n  {\n    success: false,\n    error: {\n      code: 'ERROR_CODE',\n      message: 'Human-readable error message'\n    },\n    fromCache: false\n  }\n  ```\n\n- **MCP Tool Logging Pattern**:\n  - ✅ DO: Log the start of execution with arguments (sanitized if sensitive)\n  - ✅ DO: Log successful completion with result summary\n  - ✅ DO: Log all error conditions with appropriate log levels\n  - ✅ DO: Include the cache status in result logs\n  - ❌ DON'T: Log entire large data structures or sensitive information\n\n- The MCP server integrates with Task Master core functions through three layers:\n  1. Tool Definitions (`mcp-server/src/tools/*.js`) - Define parameters and validation\n  2. Direct Functions (`mcp-server/src/core/direct-functions/*.js`) - Handle core logic integration\n  3. Core Functions (`scripts/modules/*.js`) - Implement the actual functionality\n\n- This layered approach provides:\n  - Clear separation of concerns\n  - Consistent parameter validation\n  - Centralized error handling\n  - Performance optimization through caching (for read operations)\n  - Standardized response formatting\n\n## MCP Naming Conventions\n\n- **Files and Directories**:\n  - ✅ DO: Use **kebab-case** for all file names: `list-tasks.js`, `set-task-status.js`\n  - ✅ DO: Use consistent directory structure: `mcp-server/src/tools/` for tool definitions, `mcp-server/src/core/direct-functions/` for direct function implementations\n\n- **JavaScript Functions**:\n  - ✅ DO: Use **camelCase** with `Direct` suffix for direct function implementations: `listTasksDirect`, `setTaskStatusDirect`\n  - ✅ DO: Use **camelCase** with `Tool` suffix for tool registration functions: `registerListTasksTool`, `registerSetTaskStatusTool`\n  - ✅ DO: Use consistent action function naming inside direct functions: `coreActionFn` or similar descriptive name\n\n- **MCP Tool Names**:\n  - ✅ DO: Use **snake_case** for tool names exposed to MCP clients: `list_tasks`, `set_task_status`, `parse_prd_document`\n  - ✅ DO: Include the core action in the tool name without redundant words: Use `list_tasks` instead of `list_all_tasks`\n\n- **Examples**:\n  - File: `list-tasks.js` \n  - Direct Function: `listTasksDirect`\n  - Tool Registration: `registerListTasksTool`\n  - MCP Tool Name: `list_tasks`\n\n- **Mapping**:\n  - The `directFunctions` map in `task-master-core.js` maps the core function name (in camelCase) to its direct implementation:\n    ```javascript\n    export const directFunctions = {\n      list: listTasksDirect,\n      setStatus: setTaskStatusDirect,\n      // Add more functions as implemented\n    };\n    ```\n\n## Telemetry Integration\n\n- Direct functions calling core logic that involves AI should receive and pass through `telemetryData` within their successful `data` payload. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the standard pattern.\n- MCP tools use `handleApiResult`, which ensures the `data` object (potentially including `telemetryData`) from the direct function is correctly included in the final response.\n","frontmatter":{"description":"Guidelines for implementing and interacting with the Task Master MCP Server","globs":"mcp-server/src/**/*, scripts/modules/**/*","alwaysApply":false},"isInternal":false,"tokens":7200,"sizeBytes":32146},{"name":"new_features.mdc","path":".cursor/rules/new_features.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/new_features.mdc","title":"Cursor Rule: new_features","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for integrating new features into the Task Master CLI\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Task Master Feature Integration Guidelines\n\n## Feature Placement Decision Process\n\n- **Identify Feature Type** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module details):\n  - **Data Manipulation**: Features that create, read, update, or delete tasks belong in [`task-manager.js`](mdc:scripts/modules/task-manager.js). Follow guidelines in [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc).\n  - **Dependency Management**: Features that handle task relationships belong in [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js). Follow guidelines in [`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc).\n  - **User Interface**: Features that display information to users belong in [`ui.js`](mdc:scripts/modules/ui.js). Follow guidelines in [`ui.mdc`](mdc:.cursor/rules/ui.mdc).\n  - **AI Integration**: Features that use AI models belong in [`ai-services.js`](mdc:scripts/modules/ai-services.js).\n  - **Cross-Cutting**: Features that don't fit one category may need components in multiple modules\n\n- **Command-Line Interface** (See [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n  - All new user-facing commands should be added to [`commands.js`](mdc:scripts/modules/commands.js)\n  - Use consistent patterns for option naming and help text\n  - Follow the Commander.js model for subcommand structure\n\n## Implementation Pattern\n\nThe standard pattern for adding a feature follows this workflow:\n\n1. **Core Logic**: Implement the business logic in the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2. **Context Gathering (If Applicable)**: \n   - For AI-powered commands that benefit from project context, use the standardized context gathering patterns from [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc).\n   - Import `ContextGatherer` and `FuzzyTaskSearch` utilities for reusable context extraction.\n   - Support multiple context types: tasks, files, custom text, project tree.\n   - Implement detailed token breakdown display for transparency.\n3. **AI Integration (If Applicable)**: \n   - Import necessary service functions (e.g., `generateTextService`, `streamTextService`) from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n   - Prepare parameters (`role`, `session`, `systemPrompt`, `prompt`).\n   - Call the service function.\n   - Handle the response (direct text or stream object).\n   - **Important**: Prefer `generateTextService` for calls sending large context (like stringified JSON) where incremental display is not needed. See [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc) for detailed usage patterns and cautions.\n4. **UI Components**: Add any display functions to [`ui.js`](mdc:scripts/modules/ui.js) following [`ui.mdc`](mdc:.cursor/rules/ui.mdc). Consider enhanced formatting with syntax highlighting for code blocks.\n5. **Command Integration**: Add the CLI command to [`commands.js`](mdc:scripts/modules/commands.js) following [`commands.mdc`](mdc:.cursor/rules/commands.mdc).\n6. **Testing**: Write tests for all components of the feature (following [`tests.mdc`](mdc:.cursor/rules/tests.mdc))\n7. **Configuration**: Update configuration settings or add new ones in [`config-manager.js`](mdc:scripts/modules/config-manager.js) and ensure getters/setters are appropriate. Update documentation in [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc). Update the `.taskmasterconfig` structure if needed.\n8. **Documentation**: Update help text and documentation in [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n\n## Critical Checklist for New Features\n\n- **Comprehensive Function Exports**:\n  - ✅ **DO**: Export **all core functions, helper functions (like `generateSubtaskPrompt`), and utility methods** needed by your new function or command from their respective modules.\n  - ✅ **DO**: **Explicitly review the module's `export { ... }` block** at the bottom of the file to ensure every required dependency (even seemingly minor helpers like `findTaskById`, `taskExists`, specific prompt generators, AI call handlers, etc.) is included.\n  - ❌ **DON'T**: Assume internal functions are already exported - **always verify**. A missing export will cause runtime errors (e.g., `ReferenceError: generateSubtaskPrompt is not defined`).\n  - **Example**: If implementing a feature that checks task existence, ensure the helper function is in exports:\n  ```javascript\n  // At the bottom of your module file:\n  export {\n    // ... existing exports ...\n    yourNewFunction,\n    taskExists,  // Helper function used by yourNewFunction\n    findTaskById, // Helper function used by yourNewFunction\n    generateSubtaskPrompt, // Helper needed by expand/add features\n    getSubtasksFromAI,     // Helper needed by expand/add features\n  };\n  ```\n\n- **Parameter Completeness and Matching**:\n  - ✅ **DO**: Pass all required parameters to functions you call within your implementation\n  - ✅ **DO**: Check function signatures before implementing calls to them\n  - ✅ **DO**: Verify that direct function parameters match their core function counterparts\n  - ✅ **DO**: When implementing a direct function for MCP, ensure it only accepts parameters that exist in the core function\n  - ✅ **DO**: Verify the expected *internal structure* of complex object parameters (like the `mcpLog` object, see mcp.mdc for the required logger wrapper pattern)\n  - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n  - ❌ **DON'T**: Assume default parameter values will handle missing arguments\n  - ❌ **DON'T**: Assume object parameters will work without verifying their required internal structure or methods.\n  - **Example**: When calling file generation, pass all required parameters:\n  ```javascript\n  // ✅ DO: Pass all required parameters\n  await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n  \n  // ❌ DON'T: Omit required parameters\n  await generateTaskFiles(tasksPath); // Error - missing outputDir parameter\n  ```\n  \n  **Example**: Properly match direct function parameters to core function:\n  ```javascript\n  // Core function signature\n  async function expandTask(tasksPath, taskId, numSubtasks, useResearch = false, additionalContext = '', options = {}) {\n    // Implementation...\n  }\n  \n  // ✅ DO: Match direct function parameters to core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // Extract only parameters that exist in the core function\n    const taskId = parseInt(args.id, 10);\n    const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n    const useResearch = args.research === true;\n    const additionalContext = args.prompt || '';\n    \n    // Call core function with matched parameters\n    const result = await expandTask(\n      tasksPath,\n      taskId,\n      numSubtasks,\n      useResearch,\n      additionalContext,\n      { mcpLog: log, session: context.session }\n    );\n    \n    // Return result\n    return { success: true, data: result, fromCache: false };\n  }\n  \n  // ❌ DON'T: Use parameters that don't exist in the core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // DON'T extract parameters that don't exist in the core function!\n    const force = args.force === true; // ❌ WRONG - 'force' doesn't exist in core function\n    \n    // DON'T pass non-existent parameters to core functions\n    const result = await expandTask(\n      tasksPath,\n      args.id,\n      args.num,\n      args.research,\n      args.prompt,\n      force, // ❌ WRONG - this parameter doesn't exist in the core function\n      { mcpLog: log }\n    );\n  }\n  ```\n\n- **Consistent File Path Handling**:\n  - ✅ DO: Use consistent file naming conventions: `task_${id.toString().padStart(3, '0')}.txt`\n  - ✅ DO: Use `path.join()` for composing file paths\n  - ✅ DO: Use appropriate file extensions (.txt for tasks, .json for data)\n  - ❌ DON'T: Hardcode path separators or inconsistent file extensions\n  - **Example**: Creating file paths for tasks:\n  ```javascript\n  // ✅ DO: Use consistent file naming and path.join\n  const taskFileName = path.join(\n    path.dirname(tasksPath), \n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ❌ DON'T: Use inconsistent naming or string concatenation \n  const taskFileName = path.dirname(tasksPath) + '/' + taskId + '.md';\n  ```\n\n- **Error Handling and Reporting**:\n  - ✅ DO: Use structured error objects with code and message properties\n  - ✅ DO: Include clear error messages identifying the specific problem\n  - ✅ DO: Handle both function-specific errors and potential file system errors\n  - ✅ DO: Log errors at appropriate severity levels\n  - **Example**: Structured error handling in core functions:\n  ```javascript\n  try {\n    // Implementation...\n  } catch (error) {\n    log('error', `Error removing task: ${error.message}`);\n    throw {\n      code: 'REMOVE_TASK_ERROR',\n      message: error.message,\n      details: error.stack\n    };\n  }\n  ```\n\n- **Silent Mode Implementation**:\n  - ✅ **DO**: Import all silent mode utilities together:\n    ```javascript\n    import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n    ```\n  - ✅ **DO**: Always use `isSilentMode()` function to check global silent mode status, never reference global variables.\n  - ✅ **DO**: Wrap core function calls **within direct functions** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block if the core function might produce console output (like banners, spinners, direct `console.log`s) that isn't reliably controlled by an `outputFormat` parameter.\n    ```javascript\n    // Direct Function Example:\n    try {\n      // Prefer passing 'json' if the core function reliably handles it\n      const result = await coreFunction(...args, 'json'); \n      // OR, if outputFormat is not enough/unreliable:\n      // enableSilentMode(); // Enable *before* the call\n      // const result = await coreFunction(...args);\n      // disableSilentMode(); // Disable *after* the call (typically in finally)\n\n      return { success: true, data: result };\n    } catch (error) {\n       log.error(`Error: ${error.message}`);\n       return { success: false, error: { message: error.message } };\n    } finally {\n       // If you used enable/disable, ensure disable is called here\n       // disableSilentMode(); \n    }\n    ```\n  - ✅ **DO**: Core functions themselves *should* ideally check `outputFormat === 'text'` before displaying UI elements (banners, spinners, boxes) and use internal logging (`log`/`report`) that respects silent mode. The `enable/disableSilentMode` wrapper in the direct function is a safety net.\n  - ✅ **DO**: Handle mixed parameter/global silent mode correctly for functions accepting both (less common now, prefer `outputFormat`):\n    ```javascript\n    // Check both the passed parameter and global silent mode\n    const isSilent = silentMode || (typeof silentMode === 'undefined' && isSilentMode());\n    ```\n  - ❌ **DON'T**: Forget to disable silent mode in a `finally` block if you enabled it.\n  - ❌ **DON'T**: Access the global `silentMode` flag directly.\n\n- **Debugging Strategy**:\n  - ✅ **DO**: If an MCP tool fails with vague errors (e.g., JSON parsing issues like `Unexpected token ... is not valid JSON`), **try running the equivalent CLI command directly in the terminal** (e.g., `task-master expand --all`). CLI output often provides much more specific error messages (like missing function definitions or stack traces from the core logic) that pinpoint the root cause.\n  - ❌ **DON'T**: Rely solely on MCP logs if the error is unclear; use the CLI as a complementary debugging tool for core logic issues.\n\n- **Telemetry Integration**: Ensure AI calls correctly handle and propagate `telemetryData` as described in [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc).\n\n```javascript\n// 1. CORE LOGIC: Add function to appropriate module (example in task-manager.js)\n/**\n * Archives completed tasks to archive.json\n * @param {string} tasksPath - Path to the tasks.json file\n * @param {string} archivePath - Path to the archive.json file\n * @returns {number} Number of tasks archived\n */\nasync function archiveTasks(tasksPath, archivePath = 'tasks/archive.json') {\n  // Implementation...\n  return archivedCount;\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  archiveTasks,\n};\n```\n\n```javascript\n// 2. AI Integration: Add import and use necessary service functions\nimport { generateTextService } from './ai-services-unified.js';\n\n// Example usage:\nasync function handleAIInteraction() {\n  const role = 'user';\n  const session = 'exampleSession';\n  const systemPrompt = 'You are a helpful assistant.';\n  const prompt = 'What is the capital of France?';\n\n  const result = await generateTextService(role, session, systemPrompt, prompt);\n  console.log(result);\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  handleAIInteraction,\n};\n```\n\n```javascript\n// 3. UI COMPONENTS: Add display function to ui.js\n/**\n * Display archive operation results\n * @param {string} archivePath - Path to the archive file\n * @param {number} count - Number of tasks archived\n */\nfunction displayArchiveResults(archivePath, count) {\n  console.log(boxen(\n    chalk.green(`Successfully archived ${count} tasks to ${archivePath}`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round' }\n  ));\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  displayArchiveResults,\n};\n```\n\n```javascript\n// 4. COMMAND INTEGRATION: Add to commands.js\nimport { archiveTasks } from './task-manager.js';\nimport { displayArchiveResults } from './ui.js';\n\n// In registerCommands function\nprogramInstance\n  .command('archive')\n  .description('Archive completed tasks to separate file')\n  .option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <file>', 'Archive output file', 'tasks/archive.json')\n  .action(async (options) => {\n    const tasksPath = options.file;\n    const archivePath = options.output;\n    \n    console.log(chalk.blue(`Archiving completed tasks from ${tasksPath} to ${archivePath}...`));\n    \n    const archivedCount = await archiveTasks(tasksPath, archivePath);\n    displayArchiveResults(archivePath, archivedCount);\n  });\n```\n\n## Cross-Module Features\n\nFor features requiring components in multiple modules:\n\n- ✅ **DO**: Create a clear unidirectional flow of dependencies\n  ```javascript\n  // In task-manager.js\n  function analyzeTasksDifficulty(tasks) {\n    // Implementation...\n    return difficultyScores;\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasksDifficulty } from './task-manager.js';\n  \n  function displayDifficultyReport(tasks) {\n    const scores = analyzeTasksDifficulty(tasks);\n    // Render the scores...\n  }\n  ```\n\n- ❌ **DON'T**: Create circular dependencies between modules\n  ```javascript\n  // In task-manager.js - depends on ui.js\n  import { displayDifficultyReport } from './ui.js';\n  \n  function analyzeTasks() {\n    // Implementation...\n    displayDifficultyReport(tasks); // WRONG! Don't call UI functions from task-manager\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasks } from './task-manager.js';\n  ```\n\n## Command-Line Interface Standards\n\n- **Naming Conventions**:\n  - Use kebab-case for command names (`analyze-complexity`, not `analyzeComplexity`)\n  - Use kebab-case for option names (`--output-format`, not `--outputFormat`) \n  - Use the same option names across commands when they represent the same concept\n\n- **Command Structure**:\n  ```javascript\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-s, --short-option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n## Utility Function Guidelines\n\nWhen adding utilities to [`utils.js`](mdc:scripts/modules/utils.js):\n\n- Only add functions that could be used by multiple modules\n- Keep utilities single-purpose and purely functional\n- Document parameters and return values\n\n```javascript\n/**\n * Formats a duration in milliseconds to a human-readable string\n * @param {number} ms - Duration in milliseconds\n * @returns {string} Formatted duration string (e.g., \"2h 30m 15s\")\n */\nfunction formatDuration(ms) {\n  // Implementation...\n  return formatted;\n}\n```\n\n## Writing Testable Code\n\nWhen implementing new features, follow these guidelines to ensure your code is testable:\n\n- **Dependency Injection**\n  - Design functions to accept dependencies as parameters\n  - Avoid hard-coded dependencies that are difficult to mock\n  ```javascript\n  // ✅ DO: Accept dependencies as parameters\n  function processTask(task, fileSystem, logger) {\n    fileSystem.writeFile('task.json', JSON.stringify(task));\n    logger.info('Task processed');\n  }\n  \n  // ❌ DON'T: Use hard-coded dependencies\n  function processTask(task) {\n    fs.writeFile('task.json', JSON.stringify(task));\n    console.log('Task processed');\n  }\n  ```\n\n- **Separate Logic from Side Effects**\n  - Keep pure logic separate from I/O operations or UI rendering\n  - This allows testing the logic without mocking complex dependencies\n  ```javascript\n  // ✅ DO: Separate logic from side effects\n  function calculateTaskPriority(task, dependencies) {\n    // Pure logic that returns a value\n    return computedPriority;\n  }\n  \n  function displayTaskPriority(task, dependencies) {\n    const priority = calculateTaskPriority(task, dependencies);\n    console.log(`Task priority: ${priority}`);\n  }\n  ```\n\n- **Callback Functions and Testing**\n  - When using callbacks (like in Commander.js commands), define them separately\n  - This allows testing the callback logic independently\n  ```javascript\n  // ✅ DO: Define callbacks separately for testing\n  function getVersionString() {\n    // Logic to determine version\n    return version;\n  }\n  \n  // In setupCLI\n  programInstance.version(getVersionString);\n  \n  // In tests\n  test('getVersionString returns correct version', () => {\n    expect(getVersionString()).toBe('1.5.0');\n  });\n  ```\n\n- **UI Output Testing**\n  - For UI components, focus on testing conditional logic rather than exact output\n  - Use string pattern matching (like `expect(result).toContain('text')`)\n  - Pay attention to emojis and formatting which can make exact string matching difficult\n  ```javascript\n  // ✅ DO: Test the essence of the output, not exact formatting\n  test('statusFormatter shows done status correctly', () => {\n    const result = formatStatus('done');\n    expect(result).toContain('done');\n    expect(result).toContain('✅');\n  });\n  ```\n\n## Testing Requirements\n\nEvery new feature **must** include comprehensive tests following the guidelines in [`tests.mdc`](mdc:.cursor/rules/tests.mdc). Testing should include:\n\n1. **Unit Tests**: Test individual functions and components in isolation\n   ```javascript\n   // Example unit test for a new utility function\n   describe('newFeatureUtil', () => {\n     test('should perform expected operation with valid input', () => {\n       expect(newFeatureUtil('valid input')).toBe('expected result');\n     });\n     \n     test('should handle edge cases appropriately', () => {\n       expect(newFeatureUtil('')).toBeNull();\n     });\n   });\n   ```\n\n2. **Integration Tests**: Verify the feature works correctly with other components\n   ```javascript\n   // Example integration test for a new command\n   describe('newCommand integration', () => {\n     test('should call the correct service functions with parsed arguments', () => {\n       const mockService = jest.fn().mockResolvedValue('success');\n       // Set up test with mocked dependencies\n       // Call the command handler\n       // Verify service was called with expected arguments\n     });\n   });\n   ```\n\n3. **Edge Cases**: Test boundary conditions and error handling\n   - Invalid inputs\n   - Missing dependencies\n   - File system errors\n   - API failures\n\n4. **Test Coverage**: Aim for at least 80% coverage for all new code\n\n5. **Jest Mocking Best Practices**\n   - Follow the mock-first-then-import pattern as described in [`tests.mdc`](mdc:.cursor/rules/tests.mdc)\n   - Use jest.spyOn() to create spy functions for testing\n   - Clear mocks between tests to prevent interference\n   - See the Jest Module Mocking Best Practices section in [`tests.mdc`](mdc:.cursor/rules/tests.mdc) for details\n\nWhen submitting a new feature, always run the full test suite to ensure nothing was broken:\n\n```bash\nnpm test\n```\n\n## Documentation Requirements\n\nFor each new feature:\n\n1. Add help text to the command definition\n2. Update [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) with command reference\n3. Consider updating [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) if the feature significantly changes module responsibilities.\n\nFollow the existing command reference format:\n```markdown\n- **Command Reference: your-command**\n  - CLI Syntax: `task-master your-command [options]`\n  - Description: Brief explanation of what the command does\n  - Parameters:\n    - `--option1=<value>`: Description of option1 (default: 'default')\n    - `--option2=<value>`: Description of option2 (required)\n  - Example: `task-master your-command --option1=value --option2=value2`\n  - Notes: Additional details, limitations, or special considerations\n```\n\nFor more information on module structure, see [`MODULE_PLAN.md`](mdc:scripts/modules/MODULE_PLAN.md) and follow [`self_improve.mdc`](mdc:scripts/modules/self_improve.mdc) for best practices on updating documentation.\n\n## Adding MCP Server Support for Commands\n\nIntegrating Task Master commands with the MCP server (for use by tools like Cursor) follows a specific pattern distinct from the CLI command implementation, prioritizing performance and reliability.\n\n- **Goal**: Leverage direct function calls to core logic, avoiding CLI overhead.\n- **Reference**: See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for full details.\n\n**MCP Integration Workflow**:\n\n1.  **Core Logic**: Ensure the command's core logic exists and is exported from the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2.  **Direct Function Wrapper (`mcp-server/src/core/direct-functions/`)**:\n    - Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.\n    - Import the core logic function, necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**: `import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js';`\n    - Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.\n    - **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` (derived from the session) being passed correctly.\n    - Perform validation on other arguments received in `args`.\n    - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()` to prevent logs from interfering with JSON responses.\n    - **If Caching**: Implement caching using `getCachedOrExecute` from `../../tools/utils.js`.\n    - **If Not Caching**: Directly call the core logic function within a try/catch block.\n    - Format the return as `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`withNormalizedProjectRoot` HOF**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters**: Make `projectRoot` optional (`z.string().optional().describe(...)`) as the HOF handles fallback.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method **wrapped with `withNormalizedProjectRoot`**:\n      ```javascript\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n          // args.projectRoot is now normalized\n          const { projectRoot /*, other args */ } = args;\n          // ... resolve tasks path if needed using normalized projectRoot ...\n          const result = await yourCommandDirect(\n              { /* other args */, projectRoot /* if needed by direct func */ }, \n              log, \n              { session }\n          );\n          return handleApiResult(result, log);\n      })\n      ```\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Implementing Background Operations\n\nFor long-running operations that should not block the client, use the AsyncOperationManager:\n\n1. **Identify Background-Appropriate Operations**:\n   - ✅ **DO**: Use async operations for CPU-intensive tasks like task expansion or PRD parsing\n   - ✅ **DO**: Consider async operations for tasks that may take more than 1-2 seconds\n   - ❌ **DON'T**: Use async operations for quick read/status operations\n   - ❌ **DON'T**: Use async operations when immediate feedback is critical\n\n2. **Use AsyncOperationManager in MCP Tools**:\n   ```javascript\n   import { asyncOperationManager } from '../core/utils/async-manager.js';\n   \n   // In execute method:\n   const operationId = asyncOperationManager.addOperation(\n     expandTaskDirect, // The direct function to run in background\n     { ...args, projectRoot: rootFolder }, // Args to pass to the function\n     { log, reportProgress, session } // Context to preserve for the operation\n   );\n   \n   // Return immediate response with operation ID\n   return createContentResponse({\n     message: \"Operation started successfully\",\n     operationId,\n     status: \"pending\"\n   });\n   ```\n\n3. **Implement Progress Reporting**:\n   - ✅ **DO**: Use the reportProgress function in direct functions:\n   ```javascript\n   // In your direct function:\n   if (reportProgress) {\n     await reportProgress({ progress: 50 }); // 50% complete\n   }\n   ```\n   - AsyncOperationManager will forward progress updates to the client\n\n4. **Check Operation Status**:\n   - Implement a way for clients to check status using the `get_operation_status` MCP tool\n   - Return appropriate status codes and messages\n\n## Project Initialization\n\nWhen implementing project initialization commands:\n\n1. **Support Programmatic Initialization**:\n   - ✅ **DO**: Design initialization to work with both CLI and MCP\n   - ✅ **DO**: Support non-interactive modes with sensible defaults\n   - ✅ **DO**: Handle project metadata like name, description, version\n   - ✅ **DO**: Create necessary files and directories\n\n2. **In MCP Tool Implementation**:\n   ```javascript\n   // In initialize-project.js MCP tool:\n   import { z } from \"zod\";\n   import { initializeProjectDirect } from \"../core/task-master-core.js\";\n   \n   export function registerInitializeProjectTool(server) {\n     server.addTool({\n       name: \"initialize_project\",\n       description: \"Initialize a new Task Master project\",\n       parameters: z.object({\n         projectName: z.string().optional().describe(\"The name for the new project\"),\n         projectDescription: z.string().optional().describe(\"A brief description\"),\n         projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n         // Add other parameters as needed\n       }),\n       execute: async (args, { log, reportProgress, session }) => {\n         try {\n           // No need for project root since we're creating a new project\n           const result = await initializeProjectDirect(args, log);\n           return handleApiResult(result, log, 'Error initializing project');\n         } catch (error) {\n           log.error(`Error in initialize_project: ${error.message}`);\n           return createErrorResponse(`Failed to initialize project: ${error.message}`);\n         }\n       }\n     });\n   }\n   ```\n\n## Feature Planning\n\n- **Core Logic First**:\n  - ✅ DO: Implement core logic in `scripts/modules/` before CLI or MCP interfaces\n  - ✅ DO: Consider tagged task lists system compatibility from the start\n  - ✅ DO: Design functions to work with both legacy and tagged data formats\n  - ✅ DO: Use tag resolution functions (`getTasksForTag`, `setTasksForTag`) for task data access\n  - ❌ DON'T: Directly manipulate tagged data structure in new features\n\n  ```javascript\n  // ✅ DO: Design tagged-aware core functions\n  async function newFeatureCore(tasksPath, featureParams, options = {}) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Perform feature logic on tasks array\n    const result = performFeatureLogic(tasks, featureParams);\n    \n    // Save back using tag resolution\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n    \n    return result;\n  }\n  ```\n\n- **Backward Compatibility**:\n  - ✅ DO: Ensure new features work with existing projects seamlessly\n  - ✅ DO: Test with both legacy and tagged task data formats\n  - ✅ DO: Support silent migration during feature usage\n  - ❌ DON'T: Break existing workflows when adding tagged system features\n\n## CLI Command Implementation\n\n- **Command Structure**:\n  - ✅ DO: Follow the established pattern in [`commands.js`](mdc:scripts/modules/commands.js)\n  - ✅ DO: Use Commander.js for argument parsing\n  - ✅ DO: Include comprehensive help text and examples\n  - ✅ DO: Support tagged task context awareness\n\n  ```javascript\n  // ✅ DO: Implement CLI commands with tagged system awareness\n  program\n    .command('new-feature')\n    .description('Description of the new feature with tagged task lists support')\n    .option('-t, --tag <tag>', 'Specify tag context (defaults to current tag)')\n    .option('-p, --param <value>', 'Feature-specific parameter')\n    .option('--force', 'Force operation without confirmation')\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot();\n        if (!projectRoot) {\n          console.error('Not in a Task Master project directory');\n          process.exit(1);\n        }\n        \n        // Use specified tag or current tag\n        const targetTag = options.tag || getCurrentTag() || 'master';\n        \n        const result = await newFeatureCore(\n          path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'),\n          { param: options.param },\n          { \n            force: options.force,\n            targetTag: targetTag,\n            outputFormat: 'text'\n          }\n        );\n        \n        console.log('Feature executed successfully');\n      } catch (error) {\n        console.error(`Error: ${error.message}`);\n        process.exit(1);\n      }\n    });\n  ```\n\n- **Error Handling**:\n  - ✅ DO: Provide clear error messages for common failures\n  - ✅ DO: Handle tagged system migration errors gracefully\n  - ✅ DO: Include suggestion for resolution when possible\n  - ✅ DO: Exit with appropriate codes for scripting\n\n## MCP Tool Implementation\n\n- **Direct Function Pattern**:\n  - ✅ DO: Create direct function wrappers in `mcp-server/src/core/direct-functions/`\n  - ✅ DO: Follow silent mode patterns to prevent console output interference\n  - ✅ DO: Use `findTasksJsonPath` for consistent path resolution\n  - ✅ DO: Ensure tagged system compatibility\n\n  ```javascript\n  // ✅ DO: Implement MCP direct functions with tagged awareness\n  export async function newFeatureDirect(args, log, context = {}) {\n    try {\n      const tasksPath = findTasksJsonPath(args, log);\n      \n      // Enable silent mode for clean MCP responses\n      enableSilentMode();\n      \n      try {\n        const result = await newFeatureCore(\n          tasksPath,\n          { param: args.param },\n          { \n            force: args.force,\n            targetTag: args.tag || 'master', // Support tag specification\n            mcpLog: log,\n            session: context.session,\n            outputFormat: 'json'\n          }\n        );\n        \n        return {\n          success: true,\n          data: result,\n          fromCache: false\n        };\n      } finally {\n        disableSilentMode();\n      }\n    } catch (error) {\n      log.error(`Error in newFeatureDirect: ${error.message}`);\n      return {\n        success: false,\n        error: { code: 'FEATURE_ERROR', message: error.message },\n        fromCache: false\n      };\n    }\n  }\n  ```\n\n- **Tool Registration**:\n  - ✅ DO: Create tool definitions in `mcp-server/src/tools/`\n  - ✅ DO: Use Zod for parameter validation\n  - ✅ DO: Include optional tag parameter for multi-context support\n  - ✅ DO: Follow established naming conventions\n\n  ```javascript\n  // ✅ DO: Register MCP tools with tagged system support\n  export function registerNewFeatureTool(server) {\n    server.addTool({\n      name: \"new_feature\",\n      description: \"Description of the new feature with tagged task lists support\",\n      inputSchema: z.object({\n        param: z.string().describe(\"Feature-specific parameter\"),\n        tag: z.string().optional().describe(\"Target tag context (defaults to current tag)\"),\n        force: z.boolean().optional().describe(\"Force operation without confirmation\"),\n        projectRoot: z.string().optional().describe(\"Project root directory\")\n      }),\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const result = await newFeatureDirect(\n            { ...args, projectRoot: args.projectRoot },\n            log,\n            { session }\n          );\n          return handleApiResult(result, log);\n        } catch (error) {\n          return handleApiResult({\n            success: false,\n            error: { code: 'EXECUTION_ERROR', message: error.message }\n          }, log);\n        }\n      })\n    });\n  }\n  ```\n\n## Testing Strategy\n\n- **Unit Tests**:\n  - ✅ DO: Test core logic independently with both data formats\n  - ✅ DO: Mock file system operations appropriately\n  - ✅ DO: Test tag resolution behavior\n  - ✅ DO: Verify migration compatibility\n\n  ```javascript\n  // ✅ DO: Test new features with tagged system awareness\n  describe('newFeature', () => {\n    beforeEach(() => {\n      jest.clearAllMocks();\n    });\n    \n    it('should work with legacy task format', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test legacy format handling\n    });\n    \n    it('should work with tagged task format', async () => {\n      const taggedData = { \n        master: { tasks: [/* test data */] },\n        feature: { tasks: [/* test data */] }\n      };\n      fs.readFileSync.mockReturnValue(JSON.stringify(taggedData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test tagged format handling\n    });\n    \n    it('should handle tag migration during feature usage', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      // Verify migration occurred\n      expect(fs.writeFileSync).toHaveBeenCalledWith(\n        '/test/tasks.json',\n        expect.stringContaining('\"master\"')\n      );\n    });\n  });\n  ```\n\n- **Integration Tests**:\n  - ✅ DO: Test CLI and MCP interfaces with real task data\n  - ✅ DO: Verify end-to-end workflows across tag contexts\n  - ✅ DO: Test error scenarios and recovery\n\n## Documentation Updates\n\n- **Rule Updates**:\n  - ✅ DO: Update relevant `.cursor/rules/*.mdc` files\n  - ✅ DO: Include tagged system considerations in architecture docs\n  - ✅ DO: Add examples showing multi-context usage\n  - ✅ DO: Update workflow documentation as needed\n\n- **User Documentation**:\n  - ✅ DO: Add feature documentation to `/docs` folder\n  - ✅ DO: Include tagged system usage examples\n  - ✅ DO: Update command reference documentation\n  - ✅ DO: Provide migration notes if relevant\n\n## Migration Considerations\n\n- **Silent Migration Support**:\n  - ✅ DO: Ensure new features trigger migration when needed\n  - ✅ DO: Handle migration errors gracefully in feature code\n  - ✅ DO: Test feature behavior with pre-migration projects\n  - ❌ DON'T: Assume projects are already migrated\n\n- **Tag Context Handling**:\n  - ✅ DO: Default to current tag when not specified\n  - ✅ DO: Support explicit tag selection in advanced features\n  - ✅ DO: Validate tag existence before operations\n  - ✅ DO: Provide clear messaging about tag context\n\n## Performance Considerations\n\n- **Efficient Tag Operations**:\n  - ✅ DO: Minimize file I/O operations per feature execution\n  - ✅ DO: Cache tag resolution results when appropriate\n  - ✅ DO: Use streaming for large task datasets\n  - ❌ DON'T: Load all tags when only one is needed\n\n- **Memory Management**:\n  - ✅ DO: Process large task lists efficiently\n  - ✅ DO: Clean up temporary data structures\n  - ✅ DO: Avoid keeping all tag data in memory simultaneously\n\n## Deployment and Versioning\n\n- **Changesets**:\n  - ✅ DO: Create appropriate changesets for new features\n  - ✅ DO: Use semantic versioning (minor for new features)\n  - ✅ DO: Include tagged system information in release notes\n  - ✅ DO: Document breaking changes if any\n\n- **Feature Flags**:\n  - ✅ DO: Consider feature flags for experimental functionality\n  - ✅ DO: Ensure tagged system features work with flags\n  - ✅ DO: Provide clear documentation about flag usage\n\nBy following these guidelines, new features will integrate smoothly with the Task Master ecosystem while supporting the enhanced tagged task lists system for multi-context development workflows.\n","frontmatter":{"description":"Guidelines for integrating new features into the Task Master CLI","globs":"scripts/modules/*.js","alwaysApply":false},"isInternal":false,"tokens":8711,"sizeBytes":38649},{"name":"self_improve.mdc","path":".cursor/rules/self_improve.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/self_improve.mdc","title":"Cursor Rule: self_improve","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\nglobs: **/*\nalwaysApply: true\n---\n\n- **Rule Improvement Triggers:**\n  - New code patterns not covered by existing rules\n  - Repeated similar implementations across files\n  - Common error patterns that could be prevented\n  - New libraries or tools being used consistently\n  - Emerging best practices in the codebase\n\n- **Analysis Process:**\n  - Compare new code with existing rules\n  - Identify patterns that should be standardized\n  - Look for references to external documentation\n  - Check for consistent error handling patterns\n  - Monitor test patterns and coverage\n\n- **Rule Updates:**\n  - **Add New Rules When:**\n    - A new technology/pattern is used in 3+ files\n    - Common bugs could be prevented by a rule\n    - Code reviews repeatedly mention the same feedback\n    - New security or performance patterns emerge\n\n  - **Modify Existing Rules When:**\n    - Better examples exist in the codebase\n    - Additional edge cases are discovered\n    - Related rules have been updated\n    - Implementation details have changed\n\n- **Example Pattern Recognition:**\n  ```typescript\n  // If you see repeated patterns like:\n  const data = await prisma.user.findMany({\n    select: { id: true, email: true },\n    where: { status: 'ACTIVE' }\n  });\n  \n  // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc):\n  // - Standard select fields\n  // - Common where conditions\n  // - Performance optimization patterns\n  ```\n\n- **Rule Quality Checks:**\n  - Rules should be actionable and specific\n  - Examples should come from actual code\n  - References should be up to date\n  - Patterns should be consistently enforced\n\n- **Continuous Improvement:**\n  - Monitor code review comments\n  - Track common development questions\n  - Update rules after major refactors\n  - Add links to relevant documentation\n  - Cross-reference related rules\n\n- **Rule Deprecation:**\n  - Mark outdated patterns as deprecated\n  - Remove rules that no longer apply\n  - Update references to deprecated rules\n  - Document migration paths for old patterns\n\n- **Documentation Updates:**\n  - Keep examples synchronized with code\n  - Update references to external docs\n  - Maintain links between related rules\n  - Document breaking changes\nFollow [cursor_rules.mdc](mdc:.cursor/rules/cursor_rules.mdc) for proper rule formatting and structure.\n","isInternal":false,"tokens":529,"sizeBytes":2426},{"name":"tags.mdc","path":".cursor/rules/tags.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/tags.mdc","title":"Cursor Rule: tags","category":"cursor-rule","format":"mdc","content":"---\ndescription: \nglobs: scripts/modules/*\nalwaysApply: false\n---\n# Tagged Task Lists Command Patterns\n\nThis document outlines the standardized patterns that **ALL** Task Master commands must follow to properly support the tagged task lists system.\n\n## Core Principles\n\n- **Every command** that reads or writes tasks.json must be tag-aware\n- **Consistent tag resolution** across all commands using `getCurrentTag(projectRoot)`\n- **Proper context passing** to core functions with `{ projectRoot, tag }`\n- **Standardized CLI options** with `--tag <tag>` flag\n\n## Required Imports\n\nAll command files must import `getCurrentTag`:\n\n```javascript\n// ✅ DO: Import getCurrentTag in commands.js\nimport { \n  log, \n  readJSON, \n  writeJSON, \n  findProjectRoot, \n  getCurrentTag \n} from './utils.js';\n\n// ✅ DO: Import getCurrentTag in task-manager files\nimport { \n  readJSON, \n  writeJSON, \n  getCurrentTag \n} from '../utils.js';\n```\n\n## CLI Command Pattern\n\nEvery CLI command that operates on tasks must follow this exact pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware CLI command pattern\nprogramInstance\n  .command('command-name')\n  .description('Command description')\n  .option('-f, --file <file>', 'Path to the tasks file', TASKMASTER_TASKS_FILE)\n  .option('--tag <tag>', 'Specify tag context for task operations') // REQUIRED\n  .action(async (options) => {\n    // 1. Find project root\n    const projectRoot = findProjectRoot();\n    if (!projectRoot) {\n      console.error(chalk.red('Error: Could not find project root.'));\n      process.exit(1);\n    }\n\n    // 2. Resolve tag using standard pattern\n    const tag = options.tag || getCurrentTag(projectRoot) || 'master';\n\n    // 3. Call core function with proper context\n    await coreFunction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag } // REQUIRED context object\n    );\n  });\n```\n\n## Core Function Pattern\n\nAll core functions in `scripts/modules/task-manager/` must follow this pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware core function pattern\nasync function coreFunction(\n  tasksPath,\n  // ... other parameters ...\n  context = {} // REQUIRED context parameter\n) {\n  const { projectRoot, tag } = context;\n  \n  // Use tag-aware readJSON/writeJSON\n  const data = readJSON(tasksPath, projectRoot, tag);\n  \n  // ... function logic ...\n  \n  writeJSON(tasksPath, data, projectRoot, tag);\n}\n```\n\n## Tag Resolution Priority\n\nThe tag resolution follows this exact priority order:\n\n1. **Explicit `--tag` flag**: `options.tag`\n2. **Current active tag**: `getCurrentTag(projectRoot)`  \n3. **Default fallback**: `'master'`\n\n```javascript\n// ✅ DO: Standard tag resolution pattern\nconst tag = options.tag || getCurrentTag(projectRoot) || 'master';\n```\n\n## Commands Requiring Updates\n\n### High Priority (Core Task Operations)\n- [x] `add-task` - ✅ Fixed\n- [x] `list` - ✅ Fixed  \n- [x] `update-task` - ✅ Fixed\n- [x] `update-subtask` - ✅ Fixed\n- [x] `set-status` - ✅ Already correct\n- [x] `remove-task` - ✅ Already correct\n- [x] `remove-subtask` - ✅ Fixed\n- [x] `add-subtask` - ✅ Already correct\n- [x] `clear-subtasks` - ✅ Fixed\n- [x] `move-task` - ✅ Already correct\n\n### Medium Priority (Analysis & Expansion)\n- [x] `expand` - ✅ Fixed\n- [ ] `next` - ✅ Fixed\n- [ ] `show` (get-task) - Needs checking\n- [ ] `analyze-complexity` - Needs checking\n- [ ] `generate` - ✅ Fixed\n\n### Lower Priority (Utilities)\n- [ ] `research` - Needs checking\n- [ ] `complexity-report` - Needs checking\n- [ ] `validate-dependencies` - ✅ Fixed\n- [ ] `fix-dependencies` - ✅ Fixed\n- [ ] `add-dependency` - ✅ Fixed\n- [ ] `remove-dependency` - ✅ Fixed\n\n## MCP Integration Pattern\n\nMCP direct functions must also follow the tag-aware pattern:\n\n```javascript\n// ✅ DO: Tag-aware MCP direct function\nexport async function coreActionDirect(args, log, context = {}) {\n  const { session } = context;\n  const { projectRoot, tag } = args; // MCP passes these in args\n  \n  try {\n    const result = await coreAction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag, session, mcpLog: logWrapper }\n    );\n    \n    return { success: true, data: result };\n  } catch (error) {\n    return { success: false, error: { code: 'ERROR_CODE', message: error.message } };\n  }\n}\n```\n\n## File Generation Tag-Aware Naming\n\nThe `generate` command must use tag-aware file naming:\n\n```javascript\n// ✅ DO: Tag-aware file naming\nconst taskFileName = targetTag === 'master' \n  ? `task_${task.id.toString().padStart(3, '0')}.txt`\n  : `task_${task.id.toString().padStart(3, '0')}_${targetTag}.txt`;\n```\n\n**Examples:**\n- Master tag: `task_001.txt`, `task_002.txt`\n- Other tags: `task_001_feature.txt`, `task_002_feature.txt`\n\n## Common Anti-Patterns\n\n```javascript\n// ❌ DON'T: Missing getCurrentTag import\nimport { readJSON, writeJSON } from '../utils.js'; // Missing getCurrentTag\n\n// ❌ DON'T: Hard-coded tag resolution\nconst tag = options.tag || 'master'; // Missing getCurrentTag\n\n// ❌ DON'T: Missing --tag option\n.option('-f, --file <file>', 'Path to tasks file') // Missing --tag option\n\n// ❌ DON'T: Missing context parameter\nawait coreFunction(tasksPath, param1, param2); // Missing { projectRoot, tag }\n\n// ❌ DON'T: Incorrect readJSON/writeJSON calls\nconst data = readJSON(tasksPath); // Missing projectRoot and tag\nwriteJSON(tasksPath, data); // Missing projectRoot and tag\n```\n\n## Validation Checklist\n\nFor each command, verify:\n\n- [ ] Imports `getCurrentTag` from utils.js\n- [ ] Has `--tag <tag>` CLI option\n- [ ] Uses standard tag resolution: `options.tag || getCurrentTag(projectRoot) || 'master'`\n- [ ] Finds `projectRoot` with error handling\n- [ ] Passes `{ projectRoot, tag }` context to core functions\n- [ ] Core functions accept and use context parameter\n- [ ] Uses `readJSON(tasksPath, projectRoot, tag)` and `writeJSON(tasksPath, data, projectRoot, tag)`\n\n## Testing Tag Resolution\n\nTest each command with:\n\n```bash\n# Test with explicit tag\nnode bin/task-master command-name --tag test-tag\n\n# Test with active tag (should use current active tag)\nnode bin/task-master use-tag test-tag\nnode bin/task-master command-name\n\n# Test with master tag (default)\nnode bin/task-master use-tag master  \nnode bin/task-master command-name\n```\n\n## Migration Strategy\n\n1. **Audit Phase**: Systematically check each command against the checklist\n2. **Fix Phase**: Apply the standard patterns to non-compliant commands\n3. **Test Phase**: Verify tag resolution works correctly\n4. **Document Phase**: Update command documentation with tag support\n\nThis ensures consistent, predictable behavior across all Task Master commands and prevents tag deletion bugs.\n","frontmatter":{"description":null,"globs":"scripts/modules/*","alwaysApply":false},"isInternal":false,"tokens":1684,"sizeBytes":6649},{"name":"taskmaster.mdc","path":".cursor/rules/taskmaster.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/taskmaster.mdc","title":"Cursor Rule: taskmaster","category":"cursor-rule","format":"mdc","content":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `--no-git`: `Skip initializing a Git repository entirely.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `noGit`: `Skip initializing a Git repository entirely. Default is false.` (CLI: `--no-git`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [Development Workflow Guide](mdc:.cursor/rules/dev_workflow.mdc).","isInternal":false,"tokens":10945,"sizeBytes":42186},{"name":"dev_workflow.mdc","path":".cursor/rules/taskmaster/dev_workflow.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/taskmaster/dev_workflow.mdc","title":"Cursor Rule: dev_workflow","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see @`taskmaster.mdc`) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see @`taskmaster.mdc`) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see @`taskmaster.mdc`)\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`)\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see @`taskmaster.mdc`) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see @`taskmaster.mdc`) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see @`taskmaster.mdc`)\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see @`taskmaster.mdc`)\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to @`mcp.mdc` for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in @`taskmaster.mdc`.\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to @`taskmaster.mdc` for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to @`taskmaster.mdc` for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see @`taskmaster.mdc`) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*","isInternal":false,"tokens":6835,"sizeBytes":30610},{"name":"taskmaster.mdc","path":".cursor/rules/taskmaster/taskmaster.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/taskmaster/taskmaster.mdc","title":"Cursor Rule: taskmaster","category":"cursor-rule","format":"mdc","content":"---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [dev_workflow.mdc](mdc:.cursor/rules/taskmaster/dev_workflow.mdc).","isInternal":false,"tokens":10904,"sizeBytes":42021},{"name":"tasks.mdc","path":".cursor/rules/tasks.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/tasks.mdc","title":"Cursor Rule: tasks","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing task management operations\nglobs: scripts/modules/task-manager.js\nalwaysApply: false\n---\n# Task Management Guidelines\n\n## Tagged Task Lists System\n\nTask Master now uses a **tagged task lists system** for multi-context task management:\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) within `tasks.json`\n- **Legacy Format**: `{\"tasks\": [...]}`\n- **Tagged Format**: `{\"master\": {\"tasks\": [...]}, \"feature-branch\": {\"tasks\": [...]}}`\n- **Silent Migration**: Legacy format automatically converts to tagged format on first use\n- **Tag Resolution**: Core functions receive legacy format for 100% backward compatibility\n- **Default Tag**: \"master\" is used for all existing and new tasks unless otherwise specified\n\n## Task Structure Standards\n\n- **Core Task Properties**:\n  - ✅ DO: Include all required properties in each task object\n  - ✅ DO: Provide default values for optional properties\n  - ❌ DON'T: Add extra properties that aren't in the standard schema\n\n  ```javascript\n  // ✅ DO: Follow this structure for task objects\n  const task = {\n    id: nextId,\n    title: \"Task title\",\n    description: \"Brief task description\",\n    status: \"pending\", // \"pending\", \"in-progress\", \"done\", etc.\n    dependencies: [], // Array of task IDs\n    priority: \"medium\", // \"high\", \"medium\", \"low\"\n    details: \"Detailed implementation instructions\",\n    testStrategy: \"Verification approach\",\n    subtasks: [] // Array of subtask objects\n  };\n  ```\n\n- **Tagged Data Structure**:\n  - ✅ DO: Access tasks through tag resolution layer\n  - ✅ DO: Use `getTasksForTag(data, tagName)` to retrieve tasks for a specific tag\n  - ✅ DO: Use `setTasksForTag(data, tagName, tasks)` to update tasks for a specific tag\n  - ❌ DON'T: Directly manipulate the tagged structure in core functions\n\n  ```javascript\n  // ✅ DO: Use tag resolution functions\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Manipulate tasks as normal...\n  \n  // Save back to the tagged structure\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n- **Subtask Structure**:\n  - ✅ DO: Use consistent properties across subtasks\n  - ✅ DO: Maintain simple numeric IDs within parent tasks\n  - ❌ DON'T: Duplicate parent task properties in subtasks\n\n  ```javascript\n  // ✅ DO: Structure subtasks consistently\n  const subtask = {\n    id: nextSubtaskId, // Simple numeric ID, unique within the parent task\n    title: \"Subtask title\",\n    description: \"Brief subtask description\",\n    status: \"pending\",\n    dependencies: [], // Can include numeric IDs (other subtasks) or full task IDs\n    details: \"Detailed implementation instructions\"\n  };\n  ```\n\n## Task Creation and Parsing\n\n- **ID Management**:\n  - ✅ DO: Assign unique sequential IDs to tasks within each tag context\n  - ✅ DO: Calculate the next ID based on existing tasks in the current tag\n  - ❌ DON'T: Hardcode or reuse IDs within the same tag\n\n  ```javascript\n  // ✅ DO: Calculate the next available ID within the current tag\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  const highestId = Math.max(...tasks.map(t => t.id));\n  const nextTaskId = highestId + 1;\n  ```\n\n- **PRD Parsing**:\n  - ✅ DO: Extract tasks from PRD documents using AI\n  - ✅ DO: Create tasks in the current tag context (defaults to \"master\")\n  - ✅ DO: Provide clear prompts to guide AI task generation\n  - ✅ DO: Validate and clean up AI-generated tasks\n\n  ```javascript\n  // ✅ DO: Parse into current tag context\n  const tasksData = readJSON(tasksPath) || {};\n  const currentTag = getCurrentTag() || 'master';\n  \n  // Parse tasks and add to current tag\n  const newTasks = await parseTasksFromPRD(prdContent);\n  setTasksForTag(tasksData, currentTag, newTasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task Updates and Modifications\n\n- **Status Management**:\n  - ✅ DO: Provide functions for updating task status within current tag context\n  - ✅ DO: Handle both individual tasks and subtasks\n  - ✅ DO: Consider subtask status when updating parent tasks\n\n  ```javascript\n  // ✅ DO: Handle status updates within tagged context\n  async function setTaskStatus(tasksPath, taskIdInput, newStatus) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Check if it's a subtask (e.g., \"1.2\")\n    if (taskIdInput.includes('.')) {\n      const [parentId, subtaskId] = taskIdInput.split('.').map(id => parseInt(id, 10));\n      \n      // Find the parent task and subtask\n      const parentTask = tasks.find(t => t.id === parentId);\n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      \n      // Update subtask status\n      subtask.status = newStatus;\n      \n      // Check if all subtasks are done\n      if (newStatus === 'done') {\n        const allSubtasksDone = parentTask.subtasks.every(st => st.status === 'done');\n        if (allSubtasksDone) {\n          // Suggest updating parent task\n        }\n      }\n    } else {\n      // Handle regular task\n      const task = tasks.find(t => t.id === parseInt(taskIdInput, 10));\n      task.status = newStatus;\n      \n      // If marking as done, also mark subtasks\n      if (newStatus === 'done' && task.subtasks && task.subtasks.length > 0) {\n        task.subtasks.forEach(subtask => {\n          subtask.status = newStatus;\n        });\n      }\n    }\n    \n    // Save updated tasks back to tagged structure\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n  }\n  ```\n\n- **Task Expansion**:\n  - ✅ DO: Use AI to generate detailed subtasks within current tag context\n  - ✅ DO: Consider complexity analysis for subtask counts\n  - ✅ DO: Ensure proper IDs for newly created subtasks\n\n  ```javascript\n  // ✅ DO: Generate appropriate subtasks based on complexity\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  if (taskAnalysis) {\n    log('info', `Found complexity analysis for task ${taskId}: Score ${taskAnalysis.complexityScore}/10`);\n    \n    // Use recommended number of subtasks if available\n    if (taskAnalysis.recommendedSubtasks && numSubtasks === CONFIG.defaultSubtasks) {\n      numSubtasks = taskAnalysis.recommendedSubtasks;\n      log('info', `Using recommended number of subtasks: ${numSubtasks}`);\n    }\n  }\n  \n  // Generate subtasks and save back\n  // ... subtask generation logic ...\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task File Generation\n\n- **File Formatting**:\n  - ✅ DO: Use consistent formatting for task files\n  - ✅ DO: Include all task properties in text files\n  - ✅ DO: Format dependencies with status indicators\n\n  ```javascript\n  // ✅ DO: Use consistent file formatting\n  let content = `# Task ID: ${task.id}\\n`;\n  content += `# Title: ${task.title}\\n`;\n  content += `# Status: ${task.status || 'pending'}\\n`;\n  \n  // Format dependencies with their status\n  if (task.dependencies && task.dependencies.length > 0) {\n    content += `# Dependencies: ${formatDependenciesWithStatus(task.dependencies, tasks)}\\n`;\n  } else {\n    content += '# Dependencies: None\\n';\n  }\n  ```\n\n- **Tagged Context Awareness**:\n  - ✅ DO: Generate task files from current tag context\n  - ✅ DO: Include tag information in generated files\n  - ❌ DON'T: Mix tasks from different tags in file generation\n\n  ```javascript\n  // ✅ DO: Generate files for current tag context\n  async function generateTaskFiles(tasksPath, outputDir) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Add tag context to file header\n    let content = `# Tag Context: ${currentTag}\\n`;\n    content += `# Task ID: ${task.id}\\n`;\n    // ... rest of file generation\n  }\n  ```\n\n## Task Listing and Display\n\n- **Filtering and Organization**:\n  - ✅ DO: Allow filtering tasks by status within current tag context\n  - ✅ DO: Handle subtask display in lists\n  - ✅ DO: Use consistent table formats\n\n  ```javascript\n  // ✅ DO: Implement clear filtering within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Filter tasks by status if specified\n  const filteredTasks = statusFilter \n    ? tasks.filter(task => \n        task.status && task.status.toLowerCase() === statusFilter.toLowerCase())\n    : tasks;\n  ```\n\n- **Progress Tracking**:\n  - ✅ DO: Calculate and display completion statistics for current tag\n  - ✅ DO: Track both task and subtask completion\n  - ✅ DO: Use visual progress indicators\n\n  ```javascript\n  // ✅ DO: Track and display progress within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Calculate completion statistics\n  const totalTasks = tasks.length;\n  const completedTasks = tasks.filter(task => \n    task.status === 'done' || task.status === 'completed').length;\n  const completionPercentage = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0;\n  \n  // Count subtasks\n  let totalSubtasks = 0;\n  let completedSubtasks = 0;\n  \n  tasks.forEach(task => {\n    if (task.subtasks && task.subtasks.length > 0) {\n      totalSubtasks += task.subtasks.length;\n      completedSubtasks += task.subtasks.filter(st => \n        st.status === 'done' || st.status === 'completed').length;\n    }\n  });\n  ```\n\n## Migration and Compatibility\n\n- **Silent Migration Handling**:\n  - ✅ DO: Implement silent migration in `readJSON()` function\n  - ✅ DO: Detect legacy format and convert automatically\n  - ✅ DO: Preserve all existing task data during migration\n\n  ```javascript\n  // ✅ DO: Handle silent migration (implemented in utils.js)\n  function readJSON(filepath) {\n    let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n    \n    // Silent migration for tasks.json files\n    if (data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n      const migratedData = {\n        master: {\n          tasks: data.tasks\n        }\n      };\n      writeJSON(filepath, migratedData);\n      data = migratedData;\n    }\n    \n    return data;\n  }\n  ```\n\n- **Tag Resolution**:\n  - ✅ DO: Use tag resolution functions to maintain backward compatibility\n  - ✅ DO: Return legacy format to core functions\n  - ❌ DON'T: Expose tagged structure to existing core logic\n\n  ```javascript\n  // ✅ DO: Use tag resolution layer\n  function getTasksForTag(data, tagName) {\n    if (data.tasks && Array.isArray(data.tasks)) {\n      // Legacy format - return as-is\n      return data.tasks;\n    }\n    \n    if (data[tagName] && data[tagName].tasks) {\n      // Tagged format - return tasks for specified tag\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  ```\n\nRefer to [`task-manager.js`](mdc:scripts/modules/task-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ","frontmatter":{"description":"Guidelines for implementing task management operations","globs":"scripts/modules/task-manager.js","alwaysApply":false},"isInternal":false,"tokens":2781,"sizeBytes":11408},{"name":"telemetry.mdc","path":".cursor/rules/telemetry.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/telemetry.mdc","title":"Cursor Rule: telemetry","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for integrating AI usage telemetry across Task Master.\nglobs: scripts/modules/**/*.js,mcp-server/src/**/*.js\nalwaysApply: true\n---\n\n# AI Usage Telemetry Integration\n\nThis document outlines the standard pattern for capturing, propagating, and handling AI usage telemetry data (cost, tokens, model, etc.) across the Task Master stack. This ensures consistent telemetry for both CLI and MCP interactions.\n\n## Overview\n\nTelemetry data is generated within the unified AI service layer ([`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)) and then passed upwards through the calling functions.\n\n- **Data Source**: [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js) (specifically its `generateTextService`, `generateObjectService`, etc.) returns an object like `{ mainResult: AI_CALL_OUTPUT, telemetryData: TELEMETRY_OBJECT }`.\n- **`telemetryData` Object Structure**:\n  ```json\n  {\n    \"timestamp\": \"ISO_STRING_DATE\",\n    \"userId\": \"USER_ID_FROM_CONFIG\",\n    \"commandName\": \"invoking_command_or_tool_name\",\n    \"modelUsed\": \"ai_model_id\",\n    \"providerName\": \"ai_provider_name\",\n    \"inputTokens\": NUMBER,\n    \"outputTokens\": NUMBER,\n    \"totalTokens\": NUMBER,\n    \"totalCost\": NUMBER, // e.g., 0.012414\n    \"currency\": \"USD\" // e.g., \"USD\"\n  }\n  ```\n\n## Integration Pattern by Layer\n\nThe key principle is that each layer receives telemetry data from the layer below it (if applicable) and passes it to the layer above it, or handles it for display in the case of the CLI.\n\n### 1. Core Logic Functions (e.g., in `scripts/modules/task-manager/`)\n\nFunctions in this layer that invoke AI services are responsible for handling the `telemetryData` they receive from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n\n- **Actions**:\n    1.  Call the appropriate AI service function (e.g., `generateObjectService`).\n        -   Pass `commandName` (e.g., `add-task`, `expand-task`) and `outputType` (e.g., `cli` or `mcp`) in the `params` object to the AI service. The `outputType` can be derived from context (e.g., presence of `mcpLog`).\n    2.  The AI service returns an object, e.g., `aiServiceResponse = { mainResult: {/*AI output*/}, telemetryData: {/*telemetry data*/} }`.\n    3.  Extract `aiServiceResponse.mainResult` for the core processing.\n    4.  **Must return an object that includes `aiServiceResponse.telemetryData`**.\n        Example: `return { operationSpecificData: /*...*/, telemetryData: aiServiceResponse.telemetryData };`\n\n- **CLI Output Handling (If Applicable)**:\n    -   If the core function also handles CLI output (e.g., it has an `outputFormat` parameter that can be `'text'` or `'cli'`):\n        1.  Check if `outputFormat === 'text'` (or `'cli'`).\n        2.  If so, and if `aiServiceResponse.telemetryData` is available, call `displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli')` from [`scripts/modules/ui.js`](mdc:scripts/modules/ui.js).\n        - This ensures telemetry is displayed directly to CLI users after the main command output.\n\n- **Example Snippet (Core Logic in `scripts/modules/task-manager/someAiAction.js`)**:\n  ```javascript\n  import { generateObjectService } from '../ai-services-unified.js';\n  import { displayAiUsageSummary } from '../ui.js';\n\n  async function performAiRelatedAction(params, context, outputFormat = 'text') {\n    const { commandNameFromContext, /* other context vars */ } = context;\n    let aiServiceResponse = null;\n\n    try {\n      aiServiceResponse = await generateObjectService({\n        // ... other parameters for AI service ...\n        commandName: commandNameFromContext || 'default-action-name',\n        outputType: context.mcpLog ? 'mcp' : 'cli' // Derive outputType\n      });\n\n      const usefulAiOutput = aiServiceResponse.mainResult.object;\n      // ... do work with usefulAiOutput ...\n\n      if (outputFormat === 'text' && aiServiceResponse.telemetryData) {\n        displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli');\n      }\n\n      return {\n        actionData: /* results of processing */,\n        telemetryData: aiServiceResponse.telemetryData\n      };\n    } catch (error) {\n      // ... handle error ...\n      throw error;\n    }\n  }\n  ```\n\n### 2. Direct Function Wrappers (in `mcp-server/src/core/direct-functions/`)\n\nThese functions adapt core logic for the MCP server, ensuring structured responses.\n\n- **Actions**:\n    1.  Call the corresponding core logic function.\n        -   Pass necessary context (e.g., `session`, `mcpLog`, `projectRoot`).\n        -   Provide the `commandName` (typically derived from the MCP tool name) and `outputType: 'mcp'` in the context object passed to the core function.\n        -   If the core function supports an `outputFormat` parameter, pass `'json'` to suppress CLI-specific UI.\n    2.  The core logic function returns an object (e.g., `coreResult = { actionData: ..., telemetryData: ... }`).\n    3.  Include `coreResult.telemetryData` as a field within the `data` object of the successful response returned by the direct function.\n\n- **Example Snippet (Direct Function `someAiActionDirect.js`)**:\n  ```javascript\n  import { performAiRelatedAction } from '../../../../scripts/modules/task-manager/someAiAction.js'; // Core function\n  import { createLogWrapper } from '../../tools/utils.js'; // MCP Log wrapper\n\n  export async function someAiActionDirect(args, log, context = {}) {\n    const { session } = context;\n    // ... prepare arguments for core function from args, including args.projectRoot ...\n\n    try {\n      const coreResult = await performAiRelatedAction(\n        { /* parameters for core function */ },\n        { // Context for core function\n          session,\n          mcpLog: createLogWrapper(log),\n          projectRoot: args.projectRoot,\n          commandNameFromContext: 'mcp_tool_some_ai_action', // Example command name\n          outputType: 'mcp'\n        },\n        'json' // Request 'json' output format from core function\n      );\n\n      return {\n        success: true,\n        data: {\n          operationSpecificData: coreResult.actionData,\n          telemetryData: coreResult.telemetryData // Pass telemetry through\n        }\n      };\n    } catch (error) {\n      // ... error handling, return { success: false, error: ... } ...\n    }\n  }\n  ```\n\n### 3. MCP Tools (in `mcp-server/src/tools/`)\n\nThese are the exposed endpoints for MCP clients.\n\n- **Actions**:\n    1.  Call the corresponding direct function wrapper.\n    2.  The direct function returns an object structured like `{ success: true, data: { operationSpecificData: ..., telemetryData: ... } }` (or an error object).\n    3.  Pass this entire result object to `handleApiResult(result, log)` from [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    4.  `handleApiResult` ensures that the `data` field from the direct function's response (which correctly includes `telemetryData`) is part of the final MCP response.\n\n- **Example Snippet (MCP Tool `some_ai_action.js`)**:\n  ```javascript\n  import { someAiActionDirect } from '../core/task-master-core.js';\n  import { handleApiResult, withNormalizedProjectRoot } from './utils.js';\n  // ... zod for parameters ...\n\n  export function registerSomeAiActionTool(server) {\n    server.addTool({\n      name: \"some_ai_action\",\n      // ... description, parameters ...\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const resultFromDirectFunction = await someAiActionDirect(\n            { /* args including projectRoot */ },\n            log,\n            { session }\n          );\n          return handleApiResult(resultFromDirectFunction, log); // This passes the nested telemetryData through\n        } catch (error) {\n          // ... error handling ...\n        }\n      })\n    });\n  }\n  ```\n\n### 4. CLI Commands (`scripts/modules/commands.js`)\n\nThese define the command-line interface.\n\n- **Actions**:\n    1.  Call the appropriate core logic function.\n    2.  Pass `outputFormat: 'text'` (or ensure the core function defaults to text-based output for CLI).\n    3.  The core logic function (as per Section 1) is responsible for calling `displayAiUsageSummary` if telemetry data is available and it's in CLI mode.\n    4.  The command action itself **should not** call `displayAiUsageSummary` if the core logic function already handles this. This avoids duplicate display.\n\n- **Example Snippet (CLI Command in `commands.js`)**:\n  ```javascript\n  // In scripts/modules/commands.js\n  import { performAiRelatedAction } from './task-manager/someAiAction.js'; // Core function\n\n  programInstance\n    .command('some-cli-ai-action')\n    // ... .option() ...\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot() || '.'; // Example root finding\n        // ... prepare parameters for core function from command options ...\n        await performAiRelatedAction(\n          { /* parameters for core function */ },\n          { // Context for core function\n            projectRoot,\n            commandNameFromContext: 'some-cli-ai-action',\n            outputType: 'cli'\n          },\n          'text' // Explicitly request text output format for CLI\n        );\n        // Core function handles displayAiUsageSummary internally for 'text' outputFormat\n      } catch (error) {\n        // ... error handling ...\n      }\n    });\n  ```\n\n## Summary Flow\n\nThe telemetry data flows as follows:\n\n1.  **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)**: Generates `telemetryData` and returns `{ mainResult, telemetryData }`.\n2.  **Core Logic Function**:\n    *   Receives `{ mainResult, telemetryData }`.\n    *   Uses `mainResult`.\n    *   If CLI (`outputFormat: 'text'`), calls `displayAiUsageSummary(telemetryData)`.\n    *   Returns `{ operationSpecificData, telemetryData }`.\n3.  **Direct Function Wrapper**:\n    *   Receives `{ operationSpecificData, telemetryData }` from core logic.\n    *   Returns `{ success: true, data: { operationSpecificData, telemetryData } }`.\n4.  **MCP Tool**:\n    *   Receives direct function response.\n    *   `handleApiResult` ensures the final MCP response to the client is `{ success: true, data: { operationSpecificData, telemetryData } }`.\n5.  **CLI Command**:\n    *   Calls core logic with `outputFormat: 'text'`. Display is handled by core logic.\n\nThis pattern ensures telemetry is captured and appropriately handled/exposed across all interaction modes.\n","frontmatter":{"description":"Guidelines for integrating AI usage telemetry across Task Master.","globs":"scripts/modules/**/*.js,mcp-server/src/**/*.js","alwaysApply":true},"isInternal":false,"tokens":2469,"sizeBytes":10443},{"name":"test_workflow.mdc","path":".cursor/rules/test_workflow.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/test_workflow.mdc","title":"Cursor Rule: test_workflow","category":"cursor-rule","format":"mdc","content":"---\ndescription: \nglobs: \nalwaysApply: true\n---\n# Test Workflow & Development Process\n\n## **Initial Testing Framework Setup**\n\nBefore implementing the TDD workflow, ensure your project has a proper testing framework configured. This section covers setup for different technology stacks.\n\n### **Detecting Project Type & Framework Needs**\n\n**AI Agent Assessment Checklist:**\n1. **Language Detection**: Check for `package.json` (Node.js/JavaScript), `requirements.txt` (Python), `Cargo.toml` (Rust), etc.\n2. **Existing Tests**: Look for test files (`.test.`, `.spec.`, `_test.`) or test directories\n3. **Framework Detection**: Check for existing test runners in dependencies\n4. **Project Structure**: Analyze directory structure for testing patterns\n\n### **JavaScript/Node.js Projects (Jest Setup)**\n\n#### **Prerequisites Check**\n```bash\n# Verify Node.js project\nls package.json  # Should exist\n\n# Check for existing testing setup\nls jest.config.js jest.config.ts  # Check for Jest config\ngrep -E \"(jest|vitest|mocha)\" package.json  # Check for test runners\n```\n\n#### **Jest Installation & Configuration**\n\n**Step 1: Install Dependencies**\n```bash\n# Core Jest dependencies\nnpm install --save-dev jest\n\n# TypeScript support (if using TypeScript)\nnpm install --save-dev ts-jest @types/jest\n\n# Additional useful packages\nnpm install --save-dev supertest @types/supertest  # For API testing\nnpm install --save-dev jest-watch-typeahead  # Enhanced watch mode\n```\n\n**Step 2: Create Jest Configuration**\n\nCreate `jest.config.js` with the following production-ready configuration:\n\n```javascript\n/** @type {import('jest').Config} */\nmodule.exports = {\n  // Use ts-jest preset for TypeScript support\n  preset: 'ts-jest',\n\n  // Test environment\n  testEnvironment: 'node',\n\n  // Roots for test discovery\n  roots: ['<rootDir>/src', '<rootDir>/tests'],\n\n  // Test file patterns\n  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],\n\n  // Transform files\n  transform: {\n    '^.+\\\\.ts$': [\n      'ts-jest',\n      {\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          skipLibCheck: true,\n          strict: false,\n          noImplicitAny: false,\n        },\n      },\n    ],\n    '^.+\\\\.js$': [\n      'ts-jest',\n      {\n        useESM: false,\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          allowJs: true,\n        },\n      },\n    ],\n  },\n\n  // Module file extensions\n  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n\n  // Transform ignore patterns - adjust for ES modules\n  transformIgnorePatterns: ['node_modules/(?!(your-es-module-deps|.*\\\\.mjs$))'],\n\n  // Coverage configuration\n  collectCoverage: true,\n  coverageDirectory: 'coverage',\n  coverageReporters: [\n    'text', // Console output\n    'text-summary', // Brief summary\n    'lcov', // For IDE integration\n    'html', // Detailed HTML report\n  ],\n\n  // Files to collect coverage from\n  collectCoverageFrom: [\n    'src/**/*.ts',\n    '!src/**/*.d.ts',\n    '!src/**/*.test.ts',\n    '!src/**/index.ts', // Often just exports\n    '!src/generated/**', // Generated code\n    '!src/config/database.ts', // Database config (tested via integration)\n  ],\n\n  // Coverage thresholds - TaskMaster standards\n  coverageThreshold: {\n    global: {\n      branches: 70,\n      functions: 80,\n      lines: 80,\n      statements: 80,\n    },\n    // Higher standards for critical business logic\n    './src/utils/': {\n      branches: 85,\n      functions: 90,\n      lines: 90,\n      statements: 90,\n    },\n    './src/middleware/': {\n      branches: 80,\n      functions: 85,\n      lines: 85,\n      statements: 85,\n    },\n  },\n\n  // Setup files\n  setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],\n\n  // Global teardown to prevent worker process leaks\n  globalTeardown: '<rootDir>/tests/teardown.ts',\n\n  // Module path mapping (if needed)\n  moduleNameMapper: {\n    '^@/(.*)$': '<rootDir>/src/$1',\n  },\n\n  // Clear mocks between tests\n  clearMocks: true,\n\n  // Restore mocks after each test\n  restoreMocks: true,\n\n  // Global test timeout\n  testTimeout: 10000,\n\n  // Projects for different test types\n  projects: [\n    // Unit tests - for pure functions only\n    {\n      displayName: 'unit',\n      testMatch: ['<rootDir>/src/**/*.test.ts'],\n      testPathIgnorePatterns: ['.*\\\\.integration\\\\.test\\\\.ts$', '/tests/'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      collectCoverageFrom: [\n        'src/**/*.ts',\n        '!src/**/*.d.ts',\n        '!src/**/*.test.ts',\n        '!src/**/*.integration.test.ts',\n      ],\n      coverageThreshold: {\n        global: {\n          branches: 70,\n          functions: 80,\n          lines: 80,\n          statements: 80,\n        },\n      },\n    },\n    // Integration tests - real database/services\n    {\n      displayName: 'integration',\n      testMatch: [\n        '<rootDir>/src/**/*.integration.test.ts',\n        '<rootDir>/tests/integration/**/*.test.ts',\n      ],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/integration.ts'],\n      testTimeout: 10000,\n    },\n    // E2E tests - full workflows\n    {\n      displayName: 'e2e',\n      testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/e2e.ts'],\n      testTimeout: 30000,\n    },\n  ],\n\n  // Verbose output for better debugging\n  verbose: true,\n\n  // Run projects sequentially to avoid conflicts\n  maxWorkers: 1,\n\n  // Enable watch mode plugins\n  watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],\n};\n```\n\n**Step 3: Update package.json Scripts**\n\nAdd these scripts to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:coverage\": \"jest --coverage\",\n    \"test:unit\": \"jest --selectProjects unit\",\n    \"test:integration\": \"jest --selectProjects integration\", \n    \"test:e2e\": \"jest --selectProjects e2e\",\n    \"test:ci\": \"jest --ci --coverage --watchAll=false\"\n  }\n}\n```\n\n**Step 4: Create Test Setup Files**\n\nCreate essential test setup files:\n\n```typescript\n// tests/setup.ts - Global setup\nimport { jest } from '@jest/globals';\n\n// Global test configuration\nbeforeAll(() => {\n  // Set test timeout\n  jest.setTimeout(10000);\n});\n\nafterEach(() => {\n  // Clean up mocks after each test\n  jest.clearAllMocks();\n});\n```\n\n```typescript\n// tests/setup/integration.ts - Integration test setup\nimport { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nbeforeAll(async () => {\n  // Connect to test database\n  await prisma.$connect();\n});\n\nafterAll(async () => {\n  // Cleanup and disconnect\n  await prisma.$disconnect();\n});\n\nbeforeEach(async () => {\n  // Clean test data before each test\n  // Add your cleanup logic here\n});\n```\n\n```typescript\n// tests/teardown.ts - Global teardown\nexport default async () => {\n  // Global cleanup after all tests\n  console.log('Global test teardown complete');\n};\n```\n\n**Step 5: Create Initial Test Structure**\n\n```bash\n# Create test directories\nmkdir -p tests/{setup,fixtures,unit,integration,e2e}\nmkdir -p tests/unit/src/{utils,services,middleware}\n\n# Create sample test fixtures\nmkdir tests/fixtures\n```\n\n### **Generic Testing Framework Setup (Any Language)**\n\n#### **Framework Selection Guide**\n\n**Python Projects:**\n- **pytest**: Recommended for most Python projects\n- **unittest**: Built-in, suitable for simple projects\n- **Coverage**: Use `coverage.py` for code coverage\n\n```bash\n# Python setup example\npip install pytest pytest-cov\necho \"[tool:pytest]\" > pytest.ini\necho \"testpaths = tests\" >> pytest.ini\necho \"addopts = --cov=src --cov-report=html --cov-report=term\" >> pytest.ini\n```\n\n**Go Projects:**\n- **Built-in testing**: Use Go's built-in `testing` package\n- **Coverage**: Built-in with `go test -cover`\n\n```bash\n# Go setup example\ngo mod init your-project\nmkdir -p tests\n# Tests are typically *_test.go files alongside source\n```\n\n**Rust Projects:**\n- **Built-in testing**: Use Rust's built-in test framework\n- **cargo-tarpaulin**: For coverage analysis\n\n```bash\n# Rust setup example\ncargo new your-project\ncd your-project\ncargo install cargo-tarpaulin  # For coverage\n```\n\n**Java Projects:**\n- **JUnit 5**: Modern testing framework\n- **Maven/Gradle**: Build tools with testing integration\n\n```xml\n<!-- Maven pom.xml example -->\n<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter</artifactId>\n    <version>5.9.2</version>\n    <scope>test</scope>\n</dependency>\n```\n\n#### **Universal Testing Principles**\n\n**Coverage Standards (Adapt to Your Language):**\n- **Global Minimum**: 70-80% line coverage\n- **Critical Code**: 85-90% coverage\n- **New Features**: Must meet or exceed standards\n- **Legacy Code**: Gradual improvement strategy\n\n**Test Organization:**\n- **Unit Tests**: Fast, isolated, no external dependencies\n- **Integration Tests**: Test component interactions\n- **E2E Tests**: Test complete user workflows\n- **Performance Tests**: Load and stress testing (if applicable)\n\n**Naming Conventions:**\n- **Test Files**: `*.test.*`, `*_test.*`, or language-specific patterns\n- **Test Functions**: Descriptive names (e.g., `should_return_error_for_invalid_input`)\n- **Test Directories**: Organized by test type and mirroring source structure\n\n#### **TaskMaster Integration for Any Framework**\n\n**Document Testing Setup in Subtasks:**\n```bash\n# Update subtask with testing framework setup\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework setup:\n- Installed [Framework Name] with coverage support\n- Configured [Coverage Tool] with thresholds: 80% lines, 70% branches\n- Created test directory structure: unit/, integration/, e2e/\n- Added test scripts to build configuration\n- All setup tests passing\"\n```\n\n**Testing Framework Verification:**\n```bash\n# Verify setup works\n[test-command]  # e.g., npm test, pytest, go test, cargo test\n\n# Check coverage reporting\n[coverage-command]  # e.g., npm run test:coverage\n\n# Update task with verification\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework verified:\n- Sample tests running successfully\n- Coverage reporting functional\n- CI/CD integration ready\n- Ready to begin TDD workflow\"\n```\n\n## **Test-Driven Development (TDD) Integration**\n\n### **Core TDD Cycle with Jest**\n```bash\n# 1. Start development with watch mode\nnpm run test:watch\n\n# 2. Write failing test first\n# Create test file: src/utils/newFeature.test.ts\n# Write test that describes expected behavior\n\n# 3. Implement minimum code to make test pass\n# 4. Refactor while keeping tests green\n# 5. Add edge cases and error scenarios\n```\n\n### **TDD Workflow Per Subtask**\n```bash\n# When starting a new subtask:\ntask-master set-status --id=4.1 --status=in-progress\n\n# Begin TDD cycle:\nnpm run test:watch  # Keep running during development\n\n# Document TDD progress in subtask:\ntask-master update-subtask --id=4.1 --prompt=\"TDD Progress:\n- Written 3 failing tests for core functionality\n- Implemented basic feature, tests now passing\n- Adding edge case tests for error handling\"\n\n# Complete subtask with test summary:\ntask-master update-subtask --id=4.1 --prompt=\"Implementation complete:\n- Feature implemented with 8 unit tests\n- Coverage: 95% statements, 88% branches  \n- All tests passing, TDD cycle complete\"\n```\n\n## **Testing Commands & Usage**\n\n### **Development Commands**\n```bash\n# Primary development command - use during coding\nnpm run test:watch              # Watch mode with Jest\nnpm run test:watch -- --testNamePattern=\"auth\"  # Watch specific tests\n\n# Targeted testing during development\nnpm run test:unit               # Run only unit tests\nnpm run test:unit -- --coverage # Unit tests with coverage\n\n# Integration testing when APIs are ready\nnpm run test:integration        # Run integration tests\nnpm run test:integration -- --detectOpenHandles  # Debug hanging tests\n\n# End-to-end testing for workflows\nnpm run test:e2e               # Run E2E tests\nnpm run test:e2e -- --timeout=30000  # Extended timeout for E2E\n```\n\n### **Quality Assurance Commands**\n```bash\n# Full test suite with coverage (before commits)\nnpm run test:coverage          # Complete coverage analysis\n\n# All tests (CI/CD pipeline)\nnpm test                       # Run all test projects\n\n# Specific test file execution\nnpm test -- auth.test.ts       # Run specific test file\nnpm test -- --testNamePattern=\"should handle errors\"  # Run specific tests\n```\n\n## **Test Implementation Patterns**\n\n### **Unit Test Development**\n```typescript\n// ✅ DO: Follow established patterns from auth.test.ts\ndescribe('FeatureName', () => {\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Setup mocks with proper typing\n  });\n\n  describe('functionName', () => {\n    it('should handle normal case', () => {\n      // Test implementation with specific assertions\n    });\n    \n    it('should throw error for invalid input', async () => {\n      // Error scenario testing\n      await expect(functionName(invalidInput))\n        .rejects.toThrow('Specific error message');\n    });\n  });\n});\n```\n\n### **Integration Test Development**  \n```typescript\n// ✅ DO: Use supertest for API endpoint testing\nimport request from 'supertest';\nimport { app } from '../../src/app';\n\ndescribe('POST /api/auth/register', () => {\n  beforeEach(async () => {\n    await integrationTestUtils.cleanupTestData();\n  });\n  \n  it('should register user successfully', async () => {\n    const userData = createTestUser();\n    \n    const response = await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n      \n    expect(response.body).toMatchObject({\n      id: expect.any(String),\n      email: userData.email\n    });\n    \n    // Verify database state\n    const user = await prisma.user.findUnique({\n      where: { email: userData.email }\n    });\n    expect(user).toBeTruthy();\n  });\n});\n```\n\n### **E2E Test Development**\n```typescript\n// ✅ DO: Test complete user workflows\ndescribe('User Authentication Flow', () => {\n  it('should complete registration → login → protected access', async () => {\n    // Step 1: Register\n    const userData = createTestUser();\n    await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n    \n    // Step 2: Login\n    const loginResponse = await request(app)\n      .post('/api/auth/login')\n      .send({ email: userData.email, password: userData.password })\n      .expect(200);\n    \n    const { token } = loginResponse.body;\n    \n    // Step 3: Access protected resource\n    await request(app)\n      .get('/api/profile')\n      .set('Authorization', `Bearer ${token}`)\n      .expect(200);\n  }, 30000); // Extended timeout for E2E\n});\n```\n\n## **Mocking & Test Utilities**\n\n### **Established Mocking Patterns**\n```typescript\n// ✅ DO: Use established bcrypt mocking pattern\njest.mock('bcrypt');\nimport bcrypt from 'bcrypt';\nconst mockHash = bcrypt.hash as jest.MockedFunction<typeof bcrypt.hash>;\nconst mockCompare = bcrypt.compare as jest.MockedFunction<typeof bcrypt.compare>;\n\n// ✅ DO: Use Prisma mocking for unit tests\njest.mock('@prisma/client', () => ({\n  PrismaClient: jest.fn().mockImplementation(() => ({\n    user: {\n      create: jest.fn(),\n      findUnique: jest.fn(),\n    },\n    $connect: jest.fn(),\n    $disconnect: jest.fn(),\n  })),\n}));\n```\n\n### **Test Fixtures Usage**\n```typescript\n// ✅ DO: Use centralized test fixtures\nimport { createTestUser, adminUser, invalidUser } from '../fixtures/users';\n\ndescribe('User Service', () => {\n  it('should handle admin user creation', async () => {\n    const userData = createTestUser(adminUser);\n    // Test implementation\n  });\n  \n  it('should reject invalid user data', async () => {\n    const userData = createTestUser(invalidUser);\n    // Error testing\n  });\n});\n```\n\n## **Coverage Standards & Monitoring**\n\n### **Coverage Thresholds**\n- **Global Standards**: 80% lines/functions, 70% branches\n- **Critical Code**: 90% utils, 85% middleware\n- **New Features**: Must meet or exceed global thresholds\n- **Legacy Code**: Gradual improvement with each change\n\n### **Coverage Reporting & Analysis**\n```bash\n# Generate coverage reports\nnpm run test:coverage\n\n# View detailed HTML report\nopen coverage/lcov-report/index.html\n\n# Coverage files generated:\n# - coverage/lcov-report/index.html  # Detailed HTML report\n# - coverage/lcov.info               # LCOV format for IDE integration  \n# - coverage/coverage-final.json     # JSON format for tooling\n```\n\n### **Coverage Quality Checks**\n```typescript\n// ✅ DO: Test all code paths\ndescribe('validateInput', () => {\n  it('should return true for valid input', () => {\n    expect(validateInput('valid')).toBe(true);\n  });\n  \n  it('should return false for various invalid inputs', () => {\n    expect(validateInput('')).toBe(false);      // Empty string\n    expect(validateInput(null)).toBe(false);    // Null value\n    expect(validateInput(undefined)).toBe(false); // Undefined\n  });\n  \n  it('should throw for unexpected input types', () => {\n    expect(() => validateInput(123)).toThrow('Invalid input type');\n  });\n});\n```\n\n## **Testing During Development Phases**\n\n### **Feature Development Phase**\n```bash\n# 1. Start feature development\ntask-master set-status --id=X.Y --status=in-progress\n\n# 2. Begin TDD cycle  \nnpm run test:watch\n\n# 3. Document test progress in subtask\ntask-master update-subtask --id=X.Y --prompt=\"Test development:\n- Created test file with 5 failing tests\n- Implemented core functionality\n- Tests passing, adding error scenarios\"\n\n# 4. Verify coverage before completion\nnpm run test:coverage\n\n# 5. Update subtask with final test status\ntask-master update-subtask --id=X.Y --prompt=\"Testing complete:\n- 12 unit tests with full coverage\n- All edge cases and error scenarios covered\n- Ready for integration testing\"\n```\n\n### **Integration Testing Phase**\n```bash\n# After API endpoints are implemented\nnpm run test:integration\n\n# Update integration test templates\n# Replace placeholder tests with real endpoint calls\n\n# Document integration test results\ntask-master update-subtask --id=X.Y --prompt=\"Integration tests:\n- Updated auth endpoint tests  \n- Database integration verified\n- All HTTP status codes and responses tested\"\n```\n\n### **Pre-Commit Testing Phase**\n```bash\n# Before committing code\nnpm run test:coverage         # Verify all tests pass with coverage\nnpm run test:unit            # Quick unit test verification\nnpm run test:integration     # Integration test verification (if applicable)\n\n# Commit pattern for test updates\ngit add tests/ src/**/*.test.ts\ngit commit -m \"test(task-X): Add comprehensive tests for Feature Y\n\n- Unit tests with 95% coverage (exceeds 90% threshold)\n- Integration tests for API endpoints\n- Test fixtures for data generation\n- Proper mocking patterns established\n\nTask X: Feature Y - Testing complete\"\n```\n\n## **Error Handling & Debugging**\n\n### **Test Debugging Techniques**\n```typescript\n// ✅ DO: Use test utilities for debugging\nimport { testUtils } from '../setup';\n\nit('should debug complex operation', () => {\n  testUtils.withConsole(() => {\n    // Console output visible only for this test\n    console.log('Debug info:', complexData);\n    service.complexOperation();\n  });\n});\n\n// ✅ DO: Use proper async debugging\nit('should handle async operations', async () => {\n  const promise = service.asyncOperation();\n  \n  // Test intermediate state\n  expect(service.isProcessing()).toBe(true);\n  \n  const result = await promise;\n  expect(result).toBe('expected');\n  expect(service.isProcessing()).toBe(false);\n});\n```\n\n### **Common Test Issues & Solutions**\n```bash\n# Hanging tests (common with database connections)\nnpm run test:integration -- --detectOpenHandles\n\n# Memory leaks in tests\nnpm run test:unit -- --logHeapUsage\n\n# Slow tests identification\nnpm run test:coverage -- --verbose\n\n# Mock not working properly\n# Check: mock is declared before imports\n# Check: jest.clearAllMocks() in beforeEach\n# Check: TypeScript typing is correct\n```\n\n## **Continuous Integration Integration**\n\n### **CI/CD Pipeline Testing**\n```yaml\n# Example GitHub Actions integration\n- name: Run tests\n  run: |\n    npm ci\n    npm run test:coverage\n    \n- name: Upload coverage reports\n  uses: codecov/codecov-action@v3\n  with:\n    file: ./coverage/lcov.info\n```\n\n### **Pre-commit Hooks**\n```bash\n# Setup pre-commit testing (recommended)\n# In package.json scripts:\n\"pre-commit\": \"npm run test:unit && npm run test:integration\"\n\n# Husky integration example:\nnpx husky add .husky/pre-commit \"npm run test:unit\"\n```\n\n## **Test Maintenance & Evolution**\n\n### **Adding Tests for New Features**\n1. **Create test file** alongside source code or in `tests/unit/`\n2. **Follow established patterns** from `src/utils/auth.test.ts`\n3. **Use existing fixtures** from `tests/fixtures/`\n4. **Apply proper mocking** patterns for dependencies\n5. **Meet coverage thresholds** for the module\n\n### **Updating Integration/E2E Tests**\n1. **Update templates** in `tests/integration/` when APIs change\n2. **Modify E2E workflows** in `tests/e2e/` for new user journeys  \n3. **Update test fixtures** for new data requirements\n4. **Maintain database cleanup** utilities\n\n### **Test Performance Optimization**\n- **Parallel execution**: Jest runs tests in parallel by default\n- **Test isolation**: Use proper setup/teardown for independence\n- **Mock optimization**: Mock heavy dependencies appropriately  \n- **Database efficiency**: Use transaction rollbacks where possible\n\n---\n\n**Key References:**\n- [Testing Standards](mdc:.cursor/rules/tests.mdc)\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc)\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Jest Configuration](mdc:jest.config.js)","frontmatter":{"description":null,"globs":null,"alwaysApply":true},"isInternal":false,"tokens":5218,"sizeBytes":21838},{"name":"tests.mdc","path":".cursor/rules/tests.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/tests.mdc","title":"Cursor Rule: tests","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing and maintaining tests for Task Master CLI\nglobs: \"**/*.test.js,tests/**/*\"\n---\n\n# Testing Guidelines for Task Master CLI\n\n*Note:* Never use asynchronous operations in tests. Always mock tests properly based on the way the tested functions are defined and used. Do not arbitrarily create tests. Based them on the low-level details and execution of the underlying code being tested. \n\n## Test Organization Structure\n\n- **Unit Tests** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module breakdown)\n  - Located in `tests/unit/`\n  - Test individual functions and utilities in isolation\n  - Mock all external dependencies\n  - Keep tests small, focused, and fast\n  - Example naming: `utils.test.js`, `task-manager.test.js`\n\n- **Integration Tests**\n  - Located in `tests/integration/`\n  - Test interactions between modules\n  - Focus on component interfaces rather than implementation details\n  - Use more realistic but still controlled test environments\n  - Example naming: `task-workflow.test.js`, `command-integration.test.js`\n\n- **End-to-End Tests**\n  - Located in `tests/e2e/`\n  - Test complete workflows from a user perspective\n  - Focus on CLI commands as they would be used by users\n  - Example naming: `create-task.e2e.test.js`, `expand-task.e2e.test.js`\n\n- **Test Fixtures**\n  - Located in `tests/fixtures/`\n  - Provide reusable test data\n  - Keep fixtures small and representative\n  - Export fixtures as named exports for reuse\n\n## Test File Organization\n\n```javascript\n// 1. Imports\nimport { jest } from '@jest/globals';\n\n// 2. Mock setup (MUST come before importing the modules under test)\njest.mock('fs');\njest.mock('@anthropic-ai/sdk');\njest.mock('../../scripts/modules/utils.js', () => ({\n  CONFIG: {\n    projectVersion: '1.5.0'\n  },\n  log: jest.fn()\n}));\n\n// 3. Import modules AFTER all mocks are defined\nimport { functionToTest } from '../../scripts/modules/module-name.js';\nimport { testFixture } from '../fixtures/fixture-name.js';\nimport fs from 'fs';\n\n// 4. Set up spies on mocked modules (if needed)\nconst mockReadFileSync = jest.spyOn(fs, 'readFileSync');\n\n// 5. Test suite with descriptive name\ndescribe('Feature or Function Name', () => {\n  // 6. Setup and teardown (if needed)\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Additional setup code\n  });\n  \n  afterEach(() => {\n    // Cleanup code\n  });\n  \n  // 7. Grouped tests for related functionality\n  describe('specific functionality', () => {\n    // 8. Individual test cases with clear descriptions\n    test('should behave in expected way when given specific input', () => {\n      // Arrange - set up test data\n      const input = testFixture.sampleInput;\n      mockReadFileSync.mockReturnValue('mocked content');\n      \n      // Act - call the function being tested\n      const result = functionToTest(input);\n      \n      // Assert - verify the result\n      expect(result).toBe(expectedOutput);\n      expect(mockReadFileSync).toHaveBeenCalledWith(expect.stringContaining('path'));\n    });\n  });\n});\n```\n\n## Commander.js Command Testing Best Practices\n\nWhen testing CLI commands built with Commander.js, several special considerations must be made to avoid common pitfalls:\n\n- **Direct Action Handler Testing**\n  - ✅ **DO**: Test the command action handlers directly rather than trying to mock the entire Commander.js chain\n  - ✅ **DO**: Create simplified test-specific implementations of command handlers that match the original behavior\n  - ✅ **DO**: Explicitly handle all options, including defaults and shorthand flags (e.g., `-p` for `--prompt`)\n  - ✅ **DO**: Include null/undefined checks in test implementations for parameters that might be optional\n  - ✅ **DO**: Use fixtures from `tests/fixtures/` for consistent sample data across tests\n  \n  ```javascript\n  // ✅ DO: Create a simplified test version of the command handler\n  const testAddTaskAction = async (options) => {\n    options = options || {}; // Ensure options aren't undefined\n    \n    // Validate parameters\n    const isManualCreation = options.title && options.description;\n    const prompt = options.prompt || options.p; // Handle shorthand flags\n    \n    if (!prompt && !isManualCreation) {\n      throw new Error('Expected error message');\n    }\n    \n    // Call the mocked task manager\n    return mockTaskManager.addTask(/* parameters */);\n  };\n  \n  test('should handle required parameters correctly', async () => {\n    // Call the test implementation directly\n    await expect(async () => {\n      await testAddTaskAction({ file: 'tasks.json' });\n    }).rejects.toThrow('Expected error message');\n  });\n  ```\n\n- **Commander Chain Mocking (If Necessary)**\n  - ✅ **DO**: Mock ALL chainable methods (`option`, `argument`, `action`, `on`, etc.)\n  - ✅ **DO**: Return `this` (or the mock object) from all chainable method mocks\n  - ✅ **DO**: Remember to mock not only the initial object but also all objects returned by methods\n  - ✅ **DO**: Implement a mechanism to capture the action handler for direct testing\n  \n  ```javascript\n  // If you must mock the Commander.js chain:\n  const mockCommand = {\n    command: jest.fn().mockReturnThis(),\n    description: jest.fn().mockReturnThis(),\n    option: jest.fn().mockReturnThis(),\n    argument: jest.fn().mockReturnThis(), // Don't forget this one\n    action: jest.fn(fn => { \n      actionHandler = fn; // Capture the handler for testing\n      return mockCommand; \n    }),\n    on: jest.fn().mockReturnThis() // Don't forget this one\n  };\n  ```\n\n- **Parameter Handling**\n  - ✅ **DO**: Check for both main flag and shorthand flags (e.g., `prompt` and `p`)\n  - ✅ **DO**: Handle parameters like Commander would (comma-separated lists, etc.)\n  - ✅ **DO**: Set proper default values as defined in the command\n  - ✅ **DO**: Validate that required parameters are actually required in tests\n  \n  ```javascript\n  // Parse dependencies like Commander would\n  const dependencies = options.dependencies \n    ? options.dependencies.split(',').map(id => id.trim())\n    : [];\n  ```\n\n- **Environment and Session Handling**\n  - ✅ **DO**: Properly mock session objects when required by functions\n  - ✅ **DO**: Reset environment variables between tests if modified\n  - ✅ **DO**: Use a consistent pattern for environment-dependent tests\n  \n  ```javascript\n  // Session parameter mock pattern\n  const sessionMock = { session: process.env };\n  \n  // In test:\n  expect(mockAddTask).toHaveBeenCalledWith(\n    expect.any(String),\n    'Test prompt',\n    [],\n    'medium',\n    sessionMock,\n    false,\n    null,\n    null\n  );\n  ```\n\n- **Common Pitfalls to Avoid**\n  - ❌ **DON'T**: Try to use the real action implementation without proper mocking\n  - ❌ **DON'T**: Mock Commander partially - either mock it completely or test the action directly\n  - ❌ **DON'T**: Forget to handle optional parameters that may be undefined\n  - ❌ **DON'T**: Neglect to test shorthand flag functionality (e.g., `-p`, `-r`)\n  - ❌ **DON'T**: Create circular dependencies in your test mocks\n  - ❌ **DON'T**: Access variables before initialization in your test implementations\n  - ❌ **DON'T**: Include actual command execution in unit tests\n  - ❌ **DON'T**: Overwrite the same file path in multiple tests\n  \n  ```javascript\n  // ❌ DON'T: Create circular references in mocks\n  const badMock = {\n    method: jest.fn().mockImplementation(() => badMock.method())\n  };\n  \n  // ❌ DON'T: Access uninitialized variables\n  const badImplementation = () => {\n    const result = uninitialized;\n    let uninitialized = 'value';\n    return result;\n  };\n  ```\n\n## Jest Module Mocking Best Practices\n\n- **Mock Hoisting Behavior**\n  - Jest hoists `jest.mock()` calls to the top of the file, even above imports\n  - Always declare mocks before importing the modules being tested\n  - Use the factory pattern for complex mocks that need access to other variables\n\n  ```javascript\n  // ✅ DO: Place mocks before imports\n  jest.mock('commander');\n  import { program } from 'commander';\n  \n  // ❌ DON'T: Define variables and then try to use them in mocks\n  const mockFn = jest.fn();\n  jest.mock('module', () => ({\n    func: mockFn // This won't work due to hoisting!\n  }));\n  ```\n\n- **Mocking Modules with Function References**\n  - Use `jest.spyOn()` after imports to create spies on mock functions\n  - Reference these spies in test assertions\n  \n  ```javascript\n  // Mock the module first\n  jest.mock('fs');\n  \n  // Import the mocked module\n  import fs from 'fs';\n  \n  // Create spies on the mock functions\n  const mockExistsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(true);\n  \n  test('should call existsSync', () => {\n    // Call function that uses fs.existsSync\n    const result = functionUnderTest();\n    \n    // Verify the mock was called correctly\n    expect(mockExistsSync).toHaveBeenCalled();\n  });\n  ```\n\n- **Testing Functions with Callbacks**\n  - Get the callback from your mock's call arguments\n  - Execute it directly with test inputs\n  - Verify the results match expectations\n  \n  ```javascript\n  jest.mock('commander');\n  import { program } from 'commander';\n  import { setupCLI } from '../../scripts/modules/commands.js';\n  \n  const mockVersion = jest.spyOn(program, 'version').mockReturnValue(program);\n  \n  test('version callback should return correct version', () => {\n    // Call the function that registers the callback\n    setupCLI();\n    \n    // Extract the callback function\n    const versionCallback = mockVersion.mock.calls[0][0];\n    expect(typeof versionCallback).toBe('function');\n    \n    // Execute the callback and verify results\n    const result = versionCallback();\n    expect(result).toBe('1.5.0');\n  });\n  ```\n\n## ES Module Testing Strategies\n\nWhen testing ES modules (`\"type\": \"module\"` in package.json), traditional mocking approaches require special handling to avoid reference and scoping issues.\n\n- **Module Import Challenges**\n  - Functions imported from ES modules may still reference internal module-scoped variables\n  - Imported functions may not use your mocked dependencies even with proper jest.mock() setup\n  - ES module exports are read-only properties (cannot be reassigned during tests)\n\n- **Mocking Modules Statically Imported**\n  - For modules imported with standard `import` statements at the top level:\n    - Use `jest.mock('path/to/module', factory)` **before** any imports.\n    - Jest hoists these mocks.\n    - Ensure the factory function returns the mocked structure correctly.\n\n- **Mocking Dependencies for Dynamically Imported Modules**\n  - **Problem**: Standard `jest.mock()` often fails for dependencies of modules loaded later using dynamic `import('path/to/module')`. The mocks aren't applied correctly when the dynamic import resolves.\n  - **Solution**: Use `jest.unstable_mockModule(modulePath, factory)` **before** the dynamic `import()` call.\n  ```javascript\n  // 1. Define mock function instances\n  const mockExistsSync = jest.fn();\n  const mockReadFileSync = jest.fn();\n  // ... other mocks\n\n  // 2. Mock the dependency module *before* the dynamic import\n  jest.unstable_mockModule('fs', () => ({\n    __esModule: true, // Important for ES module mocks\n    // Mock named exports\n    existsSync: mockExistsSync,\n    readFileSync: mockReadFileSync,\n    // Mock default export if necessary\n    // default: { ... }\n  }));\n\n  // 3. Dynamically import the module under test (e.g., in beforeAll or test case)\n  let moduleUnderTest;\n  beforeAll(async () => {\n    // Ensure mocks are reset if needed before import\n    mockExistsSync.mockReset();\n    mockReadFileSync.mockReset();\n    // ... reset other mocks ...\n\n    // Import *after* unstable_mockModule is called\n    moduleUnderTest = await import('../../scripts/modules/module-using-fs.js');\n  });\n\n  // 4. Now tests can use moduleUnderTest, and its 'fs' calls will hit the mocks\n  test('should use mocked fs.readFileSync', () => {\n    mockReadFileSync.mockReturnValue('mock data');\n    moduleUnderTest.readFileAndProcess();\n    expect(mockReadFileSync).toHaveBeenCalled();\n    // ... other assertions\n  });\n  ```\n  - ✅ **DO**: Call `jest.unstable_mockModule()` before `await import()`.\n  - ✅ **DO**: Include `__esModule: true` in the mock factory for ES modules.\n  - ✅ **DO**: Mock named and default exports as needed within the factory.\n  - ✅ **DO**: Reset mock functions (`mockFn.mockReset()`) before the dynamic import if they might have been called previously.\n\n- **Mocking Entire Modules (Static Import)**\n  ```javascript\n  // Mock the entire module with custom implementation for static imports\n  // ... (existing example remains valid) ...\n  ```\n\n- **Direct Implementation Testing**\n  - Instead of calling the actual function which may have module-scope reference issues:\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Avoiding Module Property Assignment**\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Handling Mock Verification Failures**\n  - If verification like `expect(mockFn).toHaveBeenCalled()` fails:\n    1.  Check that your mock setup (`jest.mock` or `jest.unstable_mockModule`) is correctly placed **before** imports (static or dynamic).\n    2.  Ensure you're using the right mock instance and it's properly passed to the module.\n    3.  Verify your test invokes behavior that *should* call the mock.\n    4.  Use `jest.clearAllMocks()` or specific `mockFn.mockReset()` in `beforeEach` to prevent state leakage between tests.\n    5.  **Check Console Assertions**: If verifying `console.log`, `console.warn`, or `console.error` calls, ensure your assertion matches the *actual* arguments passed. If the code logs a single formatted string, assert against that single string (using `expect.stringContaining` or exact match), not multiple `expect.stringContaining` arguments.\n        ```javascript\n        // Example: Code logs console.error(`Error: ${message}. Details: ${details}`)\n        // ❌ DON'T: Assert multiple arguments if only one is logged\n        // expect(console.error).toHaveBeenCalledWith(\n        //   expect.stringContaining('Error:'),\n        //   expect.stringContaining('Details:')\n        // );\n        // ✅ DO: Assert the single string argument\n        expect(console.error).toHaveBeenCalledWith(\n           expect.stringContaining('Error: Specific message. Details: More details')\n        );\n        // or for exact match:\n        expect(console.error).toHaveBeenCalledWith(\n           'Error: Specific message. Details: More details'\n        );\n        ```\n    6.  Consider implementing a simpler test that *only* verifies the mock behavior in isolation.\n\n## Mocking Guidelines\n\n- **File System Operations**\n  ```javascript\n  import mockFs from 'mock-fs';\n  \n  beforeEach(() => {\n    mockFs({\n      'tasks': {\n        'tasks.json': JSON.stringify({\n          meta: { projectName: 'Test Project' },\n          tasks: []\n        })\n      }\n    });\n  });\n  \n  afterEach(() => {\n    mockFs.restore();\n  });\n  ```\n\n- **API Calls (Anthropic/Claude)**\n  ```javascript\n  import { Anthropic } from '@anthropic-ai/sdk';\n  \n  jest.mock('@anthropic-ai/sdk');\n  \n  beforeEach(() => {\n    Anthropic.mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ text: 'Mocked response' }]\n        })\n      }\n    }));\n  });\n  ```\n\n- **Environment Variables**\n  ```javascript\n  const originalEnv = process.env;\n  \n  beforeEach(() => {\n    jest.resetModules();\n    process.env = { ...originalEnv };\n    process.env.MODEL = 'test-model';\n  });\n  \n  afterEach(() => {\n    process.env = originalEnv;\n  });\n  ```\n\n## Testing Common Components\n\n- **CLI Commands**\n  - Mock the action handlers (defined in [`commands.js`](mdc:scripts/modules/commands.js)) and verify they're called with correct arguments\n  - Test command registration and option parsing\n  - Use `commander` test utilities or custom mocks\n\n- **Task Operations**\n  - Use sample task fixtures for consistent test data\n  - Mock file system operations\n  - Test both success and error paths\n\n- **UI Functions**\n  - Mock console output and verify correct formatting\n  - Test conditional output logic\n  - When testing strings with emojis or formatting, use `toContain()` or `toMatch()` rather than exact `toBe()` comparisons\n  - For functions with different behavior modes (e.g., `forConsole`, `forTable` parameters), create separate tests for each mode\n  - Test the structure of formatted output (e.g., check that it's a comma-separated list with the right number of items) rather than exact string matching\n  - When testing chalk-formatted output, remember that strict equality comparison (`toBe()`) can fail even when the visible output looks identical\n  - Consider using more flexible assertions like checking for the presence of key elements when working with styled text\n  - Mock chalk functions to return the input text to make testing easier while still verifying correct function calls\n\n## Test Quality Guidelines\n\n- ✅ **DO**: Write tests before implementing features (TDD approach when possible)\n- ✅ **DO**: Test edge cases and error conditions, not just happy paths\n- ✅ **DO**: Keep tests independent and isolated from each other\n- ✅ **DO**: Use descriptive test names that explain the expected behavior\n- ✅ **DO**: Maintain test fixtures separate from test logic\n- ✅ **DO**: Aim for 80%+ code coverage, with critical paths at 100%\n- ✅ **DO**: Follow the mock-first-then-import pattern for all Jest mocks\n\n- ❌ **DON'T**: Test implementation details that might change\n- ❌ **DON'T**: Write brittle tests that depend on specific output formatting\n- ❌ **DON'T**: Skip testing error handling and validation\n- ❌ **DON'T**: Duplicate test fixtures across multiple test files\n- ❌ **DON'T**: Write tests that depend on execution order\n- ❌ **DON'T**: Define mock variables before `jest.mock()` calls (they won't be accessible due to hoisting)\n\n\n- **Task File Operations**\n  - ✅ DO: Use test-specific file paths (e.g., 'test-tasks.json') for all operations\n  - ✅ DO: Mock `readJSON` and `writeJSON` to avoid real file system interactions\n  - ✅ DO: Verify file operations use the correct paths in `expect` statements\n  - ✅ DO: Use different paths for each test to avoid test interdependence\n  - ✅ DO: Verify modifications on the in-memory task objects passed to `writeJSON`\n  - ❌ DON'T: Modify real task files (tasks.json) during tests\n  - ❌ DON'T: Skip testing file operations because they're \"just I/O\"\n  \n  ```javascript\n  // ✅ DO: Test file operations without real file system changes\n  test('should update task status in tasks.json', async () => {\n    // Setup mock to return sample data\n    readJSON.mockResolvedValue(JSON.parse(JSON.stringify(sampleTasks)));\n    \n    // Use test-specific file path\n    await setTaskStatus('test-tasks.json', '2', 'done');\n    \n    // Verify correct file path was read\n    expect(readJSON).toHaveBeenCalledWith('test-tasks.json');\n    \n    // Verify correct file path was written with updated content\n    expect(writeJSON).toHaveBeenCalledWith(\n      'test-tasks.json',\n      expect.objectContaining({\n        tasks: expect.arrayContaining([\n          expect.objectContaining({\n            id: 2,\n            status: 'done'\n          })\n        ])\n      })\n    );\n  });\n  ```\n\n## Running Tests\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Run tests with coverage reporting\nnpm run test:coverage\n\n# Run a specific test file\nnpm test -- tests/unit/specific-file.test.js\n\n# Run tests matching a pattern\nnpm test -- -t \"pattern to match\"\n```\n\n## Troubleshooting Test Issues\n\n- **Mock Functions Not Called**\n  - Ensure mocks are defined before imports (Jest hoists `jest.mock()` calls)\n  - Check that you're referencing the correct mock instance\n  - Verify the import paths match exactly\n\n- **Unexpected Mock Behavior**\n  - Clear mocks between tests with `jest.clearAllMocks()` in `beforeEach`\n  - Check mock implementation for conditional behavior\n  - Ensure mock return values are correctly configured for each test\n\n- **Tests Affecting Each Other**\n  - Isolate tests by properly mocking shared resources\n  - Reset state in `beforeEach` and `afterEach` hooks\n  - Avoid global state modifications\n\n## Common Testing Pitfalls and Solutions\n\n- **Complex Library Mocking**\n  - **Problem**: Trying to create full mocks of complex libraries like Commander.js can be error-prone\n  - **Solution**: Instead of mocking the entire library, test the command handlers directly by calling your action handlers with the expected arguments\n  ```javascript\n  // ❌ DON'T: Create complex mocks of Commander.js\n  class MockCommand {\n    constructor() { /* Complex mock implementation */ }\n    option() { /* ... */ }\n    action() { /* ... */ }\n    // Many methods to implement\n  }\n  \n  // ✅ DO: Test the command handlers directly\n  test('should use default PRD path when no arguments provided', async () => {\n    // Call the action handler directly with the right params\n    await parsePrdAction(undefined, { numTasks: '10', output: 'tasks/tasks.json' });\n    \n    // Assert on behavior\n    expect(mockParsePRD).toHaveBeenCalledWith('scripts/prd.txt', 'tasks/tasks.json', 10);\n  });\n  ```\n\n- **ES Module Mocking Challenges**\n  - **Problem**: ES modules don't support `require()` and imports are read-only\n  - **Solution**: Use Jest's module factory pattern and ensure mocks are defined before imports\n  ```javascript\n  // ❌ DON'T: Try to modify imported modules\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  detectCamelCaseFlags = jest.fn(); // Error: Assignment to constant variable\n  \n  // ❌ DON'T: Try to use require with ES modules\n  const utils = require('../../scripts/modules/utils.js'); // Error in ES modules\n  \n  // ✅ DO: Use Jest module factory pattern\n  jest.mock('../../scripts/modules/utils.js', () => ({\n    detectCamelCaseFlags: jest.fn(),\n    toKebabCase: jest.fn()\n  }));\n  \n  // Import after mocks are defined\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  ```\n\n- **Function Redeclaration Errors**\n  - **Problem**: Declaring the same function twice in a test file causes errors\n  - **Solution**: Use different function names or create local test-specific implementations\n  ```javascript\n  // ❌ DON'T: Redefine imported functions with the same name\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  \n  function detectCamelCaseFlags() { /* Test implementation */ }\n  // Error: Identifier has already been declared\n  \n  // ✅ DO: Use a different name for test implementations\n  function testDetectCamelCaseFlags() { /* Test implementation */ }\n  ```\n\n- **Console.log Circular References**\n  - **Problem**: Creating infinite recursion by spying on console.log while also allowing it to log\n  - **Solution**: Implement a mock that doesn't call the original function\n  ```javascript\n  // ❌ DON'T: Create circular references with console.log\n  const mockConsoleLog = jest.spyOn(console, 'log');\n  mockConsoleLog.mockImplementation(console.log); // Creates infinite recursion\n  \n  // ✅ DO: Use a non-recursive mock implementation\n  const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => {});\n  ```\n\n- **Mock Function Method Issues**\n  - **Problem**: Trying to use jest.fn() methods on imported functions that aren't properly mocked\n  - **Solution**: Create explicit jest.fn() mocks for functions you need to call jest methods on\n  ```javascript\n  // ❌ DON'T: Try to use jest methods on imported functions without proper mocking\n  import { parsePRD } from '../../scripts/modules/task-manager.js';\n  parsePRD.mockClear(); // Error: parsePRD.mockClear is not a function\n  \n  // ✅ DO: Create proper jest.fn() mocks\n  const mockParsePRD = jest.fn().mockResolvedValue(undefined);\n  jest.mock('../../scripts/modules/task-manager.js', () => ({\n    parsePRD: mockParsePRD\n  }));\n  // Now you can use:\n  mockParsePRD.mockClear();\n  ```\n\n- **EventEmitter Max Listeners Warning**\n  - **Problem**: Commander.js adds many listeners in complex mocks, causing warnings\n  - **Solution**: Either increase the max listeners limit or avoid deep mocking\n  ```javascript\n  // Option 1: Increase max listeners if you must mock Commander\n  class MockCommand extends EventEmitter {\n    constructor() {\n      super();\n      this.setMaxListeners(20); // Avoid MaxListenersExceededWarning\n    }\n  }\n  \n  // Option 2 (preferred): Test command handlers directly instead\n  // (as shown in the first example)\n  ```\n\n- **Test Isolation Issues**\n  - **Problem**: Tests affecting each other due to shared mock state\n  - **Solution**: Reset all mocks in beforeEach and use separate test-specific mocks\n  ```javascript\n  // ❌ DON'T: Allow mock state to persist between tests\n  const globalMock = jest.fn().mockReturnValue('test');\n  \n  // ✅ DO: Clear mocks before each test\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Set up test-specific mock behavior\n    mockFunction.mockReturnValue('test-specific value');\n  });\n  ```\n\n## Testing AI Service Integrations\n\n- **DO NOT import real AI service clients**\n  - ❌ DON'T: Import actual AI clients from their libraries\n  - ✅ DO: Create fully mocked versions that return predictable responses\n\n  ```javascript\n  // ❌ DON'T: Import and instantiate real AI clients\n  import { Anthropic } from '@anthropic-ai/sdk';\n  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n\n  // ✅ DO: Mock the entire module with controlled behavior\n  jest.mock('@anthropic-ai/sdk', () => ({\n    Anthropic: jest.fn().mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ type: 'text', text: 'Mocked AI response' }]\n        })\n      }\n    }))\n  }));\n  ```\n\n- **DO NOT rely on environment variables for API keys**\n  - ❌ DON'T: Assume environment variables are set in tests\n  - ✅ DO: Set mock environment variables in test setup\n\n  ```javascript\n  // In tests/setup.js or at the top of test file\n  process.env.ANTHROPIC_API_KEY = 'test-mock-api-key-for-tests';\n  process.env.PERPLEXITY_API_KEY = 'test-mock-perplexity-key-for-tests';\n  ```\n\n- **DO NOT use real AI client initialization logic**\n  - ❌ DON'T: Use code that attempts to initialize or validate real AI clients\n  - ✅ DO: Create test-specific paths that bypass client initialization\n\n  ```javascript\n  // ❌ DON'T: Test functions that require valid AI client initialization\n  // This will fail without proper API keys or network access\n  test('should use AI client', async () => {\n    const result = await functionThatInitializesAIClient();\n    expect(result).toBeDefined();\n  });\n\n  // ✅ DO: Test with bypassed initialization or manual task paths\n  test('should handle manual task creation without AI', () => {\n    // Using a path that doesn't require AI client initialization\n    const result = addTaskDirect({ \n      title: 'Manual Task', \n      description: 'Test Description'\n    }, mockLogger);\n    \n    expect(result.success).toBe(true);\n  });\n  ```\n\n## Testing Asynchronous Code\n\n- **DO NOT rely on asynchronous operations in tests**\n  - ❌ DON'T: Use real async/await or Promise resolution in tests\n  - ✅ DO: Make all mocks return synchronous values when possible\n\n  ```javascript\n  // ❌ DON'T: Use real async functions that might fail unpredictably\n  test('should handle async operation', async () => {\n    const result = await realAsyncFunction(); // Can time out or fail for external reasons\n    expect(result).toBe(expectedValue);\n  });\n\n  // ✅ DO: Make async operations synchronous in tests\n  test('should handle operation', () => {\n    mockAsyncFunction.mockReturnValue({ success: true, data: 'test' });\n    const result = functionUnderTest();\n    expect(result).toEqual({ success: true, data: 'test' });\n  });\n  ```\n\n- **DO NOT test exact error messages**\n  - ❌ DON'T: Assert on exact error message text that might change\n  - ✅ DO: Test for error presence and general properties\n\n  ```javascript\n  // ❌ DON'T: Test for exact error message text\n  expect(result.error).toBe('Could not connect to API: Network error');\n\n  // ✅ DO: Test for general error properties or message patterns\n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Could not connect');\n  // Or even better:\n  expect(result).toMatchObject({ \n    success: false,\n    error: expect.stringContaining('connect')\n  });\n  ```\n\n## Reliable Testing Techniques\n\n- **Create Simplified Test Functions**\n  - Create simplified versions of complex functions that focus only on core logic\n  - Remove file system operations, API calls, and other external dependencies\n  - Pass all dependencies as parameters to make testing easier\n  \n  ```javascript\n  // Original function (hard to test)\n  const setTaskStatus = async (taskId, newStatus) => {\n    const tasksPath = 'tasks/tasks.json';\n    const data = await readJSON(tasksPath);\n    // [implementation]\n    await writeJSON(tasksPath, data);\n    return { success: true };\n  };\n  \n  // Test-friendly version (easier to test)\n  const updateTaskStatus = (tasks, taskId, newStatus) => {\n    // Pure logic without side effects\n    const updatedTasks = [...tasks];\n    const taskIndex = findTaskById(updatedTasks, taskId);\n    if (taskIndex === -1) return { success: false, error: 'Task not found' };\n    updatedTasks[taskIndex].status = newStatus;\n    return { success: true, tasks: updatedTasks };\n  };\n  ```\n\nSee [tests/README.md](mdc:tests/README.md) for more details on the testing approach.\n\nRefer to [jest.config.js](mdc:jest.config.js) for Jest configuration options.\n\n## Variable Hoisting and Module Initialization Issues\n\nWhen testing ES modules or working with complex module imports, you may encounter variable hoisting and initialization issues. These can be particularly tricky to debug and often appear as \"Cannot access 'X' before initialization\" errors.\n\n- **Understanding Module Initialization Order**\n  - ✅ **DO**: Declare and initialize global variables at the top of modules\n  - ✅ **DO**: Use proper function declarations to avoid hoisting issues\n  - ✅ **DO**: Initialize variables before they are referenced, especially in imported modules\n  - ✅ **DO**: Be aware that imports are hoisted to the top of the file\n  \n  ```javascript\n  // ✅ DO: Define global state variables at the top of the module\n  let silentMode = false; // Declare and initialize first\n  \n  const CONFIG = { /* configuration */ };\n  \n  function isSilentMode() {\n    return silentMode; // Reference variable after it's initialized\n  }\n  \n  function log(level, message) {\n    if (isSilentMode()) return; // Use the function instead of accessing variable directly\n    // ...\n  }\n  ```\n\n- **Testing Modules with Initialization-Dependent Functions**\n  - ✅ **DO**: Create test-specific implementations that initialize all variables correctly\n  - ✅ **DO**: Use factory functions in mocks to ensure proper initialization order\n  - ✅ **DO**: Be careful with how you mock or stub functions that depend on module state\n  \n  ```javascript\n  // ✅ DO: Test-specific implementation that avoids initialization issues\n  const testLog = (level, ...args) => {\n    // Local implementation with proper initialization\n    const isSilent = false; // Explicit initialization\n    if (isSilent) return;\n    // Test implementation...\n  };\n  ```\n\n- **Common Hoisting-Related Errors to Avoid**\n  - ❌ **DON'T**: Reference variables before their declaration in module scope\n  - ❌ **DON'T**: Create circular dependencies between modules\n  - ❌ **DON'T**: Rely on variable initialization order across module boundaries\n  - ❌ **DON'T**: Define functions that use hoisted variables before they're initialized\n  \n  ```javascript\n  // ❌ DON'T: Create reference-before-initialization patterns\n  function badFunction() {\n    if (silentMode) { /* ... */ } // ReferenceError if silentMode is declared later\n  }\n  \n  let silentMode = false;\n  \n  // ❌ DON'T: Create cross-module references that depend on initialization order\n  // module-a.js\n  import { getSetting } from './module-b.js';\n  export const config = { value: getSetting() };\n  \n  // module-b.js\n  import { config } from './module-a.js';\n  export function getSetting() {\n    return config.value; // Circular dependency causing initialization issues\n  }\n  ```\n\n- **Dynamic Imports as a Solution**\n  - ✅ **DO**: Use dynamic imports (`import()`) to avoid initialization order issues\n  - ✅ **DO**: Structure modules to avoid circular dependencies that cause initialization issues\n  - ✅ **DO**: Consider factory functions for modules with complex state\n  \n  ```javascript\n  // ✅ DO: Use dynamic imports to avoid initialization issues\n  async function getTaskManager() {\n    return import('./task-manager.js');\n  }\n  \n  async function someFunction() {\n    const taskManager = await getTaskManager();\n    return taskManager.someMethod();\n  }\n  ```\n\n- **Testing Approach for Modules with Initialization Issues**\n  - ✅ **DO**: Create self-contained test implementations rather than using real implementations\n  - ✅ **DO**: Mock dependencies at module boundaries instead of trying to mock deep dependencies\n  - ✅ **DO**: Isolate module-specific state in tests\n  \n  ```javascript\n  // ✅ DO: Create isolated test implementation instead of reusing module code\n  test('should log messages when not in silent mode', () => {\n    // Local test implementation instead of importing from module\n    const testLog = (level, message) => {\n      if (false) return; // Always non-silent for this test\n      mockConsole(level, message);\n    };\n    \n    testLog('info', 'test message');\n    expect(mockConsole).toHaveBeenCalledWith('info', 'test message');\n  });\n  ``` ","frontmatter":{"description":"Guidelines for implementing and maintaining tests for Task Master CLI","globs":"**/*.test.js,tests/**/*"},"isInternal":false,"tokens":7678,"sizeBytes":33780},{"name":"ui.mdc","path":".cursor/rules/ui.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/ui.mdc","title":"Cursor Rule: ui","category":"cursor-rule","format":"mdc","content":"---\ndescription: Guidelines for implementing and maintaining user interface components\nglobs: scripts/modules/ui.js\nalwaysApply: false\n---\n\n# User Interface Implementation Guidelines\n\n## Core UI Component Principles\n\n- **Function Scope Separation**:\n  - ✅ DO: Keep display logic separate from business logic\n  - ✅ DO: Import data processing functions from other modules\n  - ❌ DON'T: Include task manipulations within UI functions\n  - ❌ DON'T: Create circular dependencies with other modules\n\n- **Standard Display Pattern**:\n  ```javascript\n  // ✅ DO: Follow this pattern for display functions\n  /**\n   * Display information about a task\n   * @param {Object} task - The task to display\n   */\n  function displayTaskInfo(task) {\n    console.log(boxen(\n      chalk.white.bold(`Task: #${task.id} - ${task.title}`),\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n## Visual Styling Standards\n\n- **Color Scheme**:\n  - Use `chalk.blue` for informational messages\n  - Use `chalk.green` for success messages\n  - Use `chalk.yellow` for warnings\n  - Use `chalk.red` for errors\n  - Use `chalk.cyan` for prompts and highlights\n  - Use `chalk.magenta` for subtask-related information\n\n- **Box Styling**:\n  ```javascript\n  // ✅ DO: Use consistent box styles by content type\n  // For success messages:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'green', \n    borderStyle: 'round', \n    margin: { top: 1 } \n  })\n\n  // For errors:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'red', \n    borderStyle: 'round'\n  })\n\n  // For information:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'blue', \n    borderStyle: 'round', \n    margin: { top: 1, bottom: 1 } \n  })\n  ```\n\n## Table Display Guidelines\n\n- **Table Structure**:\n  - Use [`cli-table3`](mdc:node_modules/cli-table3/README.md) for consistent table rendering\n  - Include colored headers with bold formatting\n  - Use appropriate column widths for readability\n\n  ```javascript\n  // ✅ DO: Create well-structured tables\n  const table = new Table({\n    head: [\n      chalk.cyan.bold('ID'),\n      chalk.cyan.bold('Title'),\n      chalk.cyan.bold('Status'),\n      chalk.cyan.bold('Priority'),\n      chalk.cyan.bold('Dependencies')\n    ],\n    colWidths: [5, 40, 15, 10, 20]\n  });\n  \n  // Add content rows\n  table.push([\n    task.id,\n    truncate(task.title, 37),\n    getStatusWithColor(task.status),\n    chalk.white(task.priority || 'medium'),\n    formatDependenciesWithStatus(task.dependencies, allTasks, true)\n  ]);\n  \n  console.log(table.toString());\n  ```\n\n## Loading Indicators\n\n- **Animation Standards**:\n  - Use [`ora`](mdc:node_modules/ora/readme.md) for spinner animations\n  - Create and stop loading indicators correctly\n\n  ```javascript\n  // ✅ DO: Properly manage loading state\n  const loadingIndicator = startLoadingIndicator('Processing task data...');\n  try {\n    // Do async work...\n    stopLoadingIndicator(loadingIndicator);\n    // Show success message\n  } catch (error) {\n    stopLoadingIndicator(loadingIndicator);\n    // Show error message\n  }\n  ```\n\n## Helper Functions\n\n- **Status Formatting**:\n  - Use `getStatusWithColor` for consistent status display\n  - Use `formatDependenciesWithStatus` for dependency lists\n  - Use `truncate` to handle text that may overflow display\n\n- **Progress Reporting**:\n  - Use visual indicators for progress (bars, percentages)\n  - Include both numeric and visual representations\n  \n  ```javascript\n  // ✅ DO: Show clear progress indicators\n  console.log(`${chalk.cyan('Tasks:')} ${completedTasks}/${totalTasks} (${completionPercentage.toFixed(1)}%)`);\n  console.log(`${chalk.cyan('Progress:')} ${createProgressBar(completionPercentage)}`);\n  ```\n\n## Command Suggestions\n\n- **Action Recommendations**:\n  - Provide next step suggestions after command completion\n  - Use a consistent format for suggested commands\n\n  ```javascript\n  // ✅ DO: Show suggested next actions\n  console.log(boxen(\n    chalk.white.bold('Next Steps:') + '\\n\\n' +\n    `${chalk.cyan('1.')} Run ${chalk.yellow('task-master list')} to view all tasks\\n` +\n    `${chalk.cyan('2.')} Run ${chalk.yellow('task-master show --id=' + newTaskId)} to view details`,\n    { padding: 1, borderColor: 'cyan', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Enhanced Display Patterns\n\n### **Token Breakdown Display**\n- Use detailed, granular token breakdowns for AI-powered commands\n- Display context sources with individual token counts\n- Show both token count and character count for transparency\n\n  ```javascript\n  // ✅ DO: Display detailed token breakdown\n  function displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    if (tokenBreakdown.tasks?.length > 0) {\n      const taskDetails = tokenBreakdown.tasks.map(task => \n        `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n      ).join('\\n');\n      sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n      title: chalk.cyan('Token Usage'),\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      borderStyle: 'round',\n      borderColor: 'cyan'\n    }));\n  }\n  ```\n\n### **Code Block Syntax Highlighting**\n- Use `cli-highlight` library for syntax highlighting in terminal output\n- Process code blocks in AI responses for better readability\n\n  ```javascript\n  // ✅ DO: Enhance code blocks with syntax highlighting\n  import { highlight } from 'cli-highlight';\n  \n  function processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n      try {\n        const highlighted = highlight(code.trim(), { \n          language: language || 'javascript',\n          theme: 'default'\n        });\n        return `\\n${highlighted}\\n`;\n      } catch (error) {\n        return `\\n${code.trim()}\\n`;\n      }\n    });\n  }\n  ```\n\n### **Multi-Section Result Display**\n- Use separate boxes for headers, content, and metadata\n- Maintain consistent styling across different result types\n\n  ```javascript\n  // ✅ DO: Use structured result display\n  function displayResults(result, query, detailLevel) {\n    // Header with query info\n    const header = boxen(\n      chalk.green.bold('Research Results') + '\\n\\n' +\n      chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n      chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n      {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 1, bottom: 0 },\n        borderStyle: 'round',\n        borderColor: 'green'\n      }\n    );\n    console.log(header);\n    \n    // Process and display main content\n    const processedResult = processCodeBlocks(result);\n    const contentBox = boxen(processedResult, {\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      margin: { top: 0, bottom: 1 },\n      borderStyle: 'single',\n      borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Operation complete'));\n  }\n  ```\n\nRefer to [`ui.js`](mdc:scripts/modules/ui.js) for implementation examples, [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for context display patterns, and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. ","frontmatter":{"description":"Guidelines for implementing and maintaining user interface components","globs":"scripts/modules/ui.js","alwaysApply":false},"isInternal":false,"tokens":1839,"sizeBytes":7367},{"name":"utilities.mdc","path":".cursor/rules/utilities.mdc","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/rules/utilities.mdc","title":"Cursor Rule: utilities","category":"cursor-rule","format":"mdc","content":"---\ndescription: \nglobs: \nalwaysApply: false\n---\n# Utility Function Guidelines\n\n## General Principles\n\n- **Function Scope**:\n  - ✅ DO: Create utility functions that serve multiple modules\n  - ✅ DO: Keep functions single-purpose and focused\n  - ❌ DON'T: Include business logic in utility functions\n  - ❌ DON'T: Create utilities with side effects\n\n  ```javascript\n  // ✅ DO: Create focused, reusable utilities\n  /**\n   * Truncates text to a specified length\n   * @param {string} text - The text to truncate\n   * @param {number} maxLength - The maximum length\n   * @returns {string} The truncated text\n   */\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n  ```javascript\n  // ❌ DON'T: Add side effects to utilities\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    \n    // Side effect - modifying global state or logging\n    console.log(`Truncating text from ${text.length} to ${maxLength} chars`);\n    \n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n- **Location**:\n    - **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).\n    - **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.\n        - Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils) (e.g., `path-utils.js`).\n        - Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n\n## Documentation Standards\n\n- **JSDoc Format**:\n  - ✅ DO: Document all parameters and return values\n  - ✅ DO: Include descriptions for complex logic\n  - ✅ DO: Add examples for non-obvious usage\n  - ❌ DON'T: Skip documentation for \"simple\" functions\n\n  ```javascript\n  // ✅ DO: Provide complete JSDoc documentation\n  /**\n   * Reads and parses a JSON file\n   * @param {string} filepath - Path to the JSON file\n   * @returns {Object|null} Parsed JSON data or null if error occurs\n   */\n  function readJSON(filepath) {\n    try {\n      const rawData = fs.readFileSync(filepath, 'utf8');\n      return JSON.parse(rawData);\n    } catch (error) {\n      log('error', `Error reading JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n      return null;\n    }\n  }\n  ```\n\n## Configuration Management (via `config-manager.js`)\n\nTaskmaster configuration (excluding API keys) is primarily managed through the `.taskmasterconfig` file located in the project root and accessed via getters in [`scripts/modules/config-manager.js`](mdc:scripts/modules/config-manager.js).\n\n- **`.taskmasterconfig` File**:\n  - ✅ DO: Use this JSON file to store settings like AI model selections (main, research, fallback), parameters (temperature, maxTokens), logging level, default priority/subtasks, etc.\n  - ✅ DO: Manage this file using the `task-master models --setup` CLI command or the `models` MCP tool.\n  - ✅ DO: Rely on [`config-manager.js`](mdc:scripts/modules/config-manager.js) to load this file (using the correct project root passed from MCP or found via CLI utils), merge with defaults, and provide validated settings.\n  - ❌ DON'T: Store API keys in this file.\n  - ❌ DON'T: Manually edit this file unless necessary.\n\n- **Configuration Getters (`config-manager.js`)**:\n  - ✅ DO: Import and use specific getters from `config-manager.js` (e.g., `getMainProvider()`, `getLogLevel()`, `getMainMaxTokens()`) to access configuration values *needed for application logic* (like `getDefaultSubtasks`).\n  - ✅ DO: Pass the `explicitRoot` parameter to getters if calling from MCP direct functions to ensure the correct project's config is loaded.\n  - ❌ DON'T: Call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions (`scripts/modules/task-manager/*`). Instead, pass the `role` to the unified AI service.\n  - ❌ DON'T: Access configuration values directly from environment variables (except API keys).\n\n- **API Key Handling (`utils.js` & `ai-services-unified.js`)**:\n  - ✅ DO: Store API keys **only** in `.env` (for CLI, loaded by `dotenv` in `scripts/dev.js`) or `.cursor/mcp.json` (for MCP, accessed via `session.env`).\n  - ✅ DO: Use `isApiKeySet(providerName, session)` from `config-manager.js` to check if a provider's key is available *before* potentially attempting an AI call if needed, but note the unified service performs its own internal check.\n  - ✅ DO: Understand that the unified service layer (`ai-services-unified.js`) internally resolves API keys using `resolveEnvVariable(key, session)` from `utils.js`.\n\n- **Error Handling**:\n  - ✅ DO: Handle potential `ConfigurationError` if the `.taskmasterconfig` file is missing or invalid when accessed via `getConfig` (e.g., in `commands.js` or direct functions).\n\n## Logging Utilities (in `scripts/modules/utils.js`)\n\n- **Log Levels**:\n  - ✅ DO: Support multiple log levels (debug, info, warn, error)\n  - ✅ DO: Use appropriate icons for different log levels\n  - ✅ DO: Respect the configured log level\n  - ❌ DON'T: Add direct console.log calls outside the logging utility\n  - **Note on Passed Loggers**: When a logger object (like the FastMCP `log` object) is passed *as a parameter* (e.g., as `mcpLog`) into core Task Master functions, the receiving function often expects specific methods (`.info`, `.warn`, `.error`, etc.) to be directly callable on that object (e.g., `mcpLog[level](mdc:...)`). If the passed logger doesn't have this exact structure, a wrapper object may be needed. See the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for the standard pattern used in direct functions.\n\n- **Logger Wrapper Pattern**: \n  - ✅ DO: Use the logger wrapper pattern when passing loggers to prevent `mcpLog[level] is not a function` errors:\n  ```javascript\n  // Standard logWrapper pattern to wrap FastMCP's log object\n  const logWrapper = {\n    info: (message, ...args) => log.info(message, ...args),\n    warn: (message, ...args) => log.warn(message, ...args),\n    error: (message, ...args) => log.error(message, ...args),\n    debug: (message, ...args) => log.debug && log.debug(message, ...args),\n    success: (message, ...args) => log.info(message, ...args) // Map success to info\n  };\n  \n  // Pass this wrapper as mcpLog to ensure consistent method availability\n  // This also ensures output format is set to 'json' in many core functions\n  const options = { mcpLog: logWrapper, session };\n  ```\n  - ✅ DO: Implement this pattern in any direct function that calls core functions expecting `mcpLog`\n  - ✅ DO: Use this solution in conjunction with silent mode for complete output control\n  - ❌ DON'T: Pass the FastMCP `log` object directly as `mcpLog` to core functions\n  - **Important**: This pattern has successfully fixed multiple issues in MCP tools (e.g., `update-task`, `update-subtask`) where using or omitting `mcpLog` incorrectly led to runtime errors or JSON parsing failures.\n  - For complete implementation details, see the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc).\n\n  ```javascript\n  // ✅ DO: Implement a proper logging utility\n  const LOG_LEVELS = {\n    debug: 0,\n    info: 1,\n    warn: 2,\n    error: 3\n  };\n  \n  function log(level, ...args) {\n    const icons = {\n      debug: chalk.gray('🔍'),\n      info: chalk.blue('ℹ️'),\n      warn: chalk.yellow('⚠️'),\n      error: chalk.red('❌'),\n      success: chalk.green('✅')\n    };\n    \n    if (LOG_LEVELS[level] >= LOG_LEVELS[CONFIG.logLevel]) {\n      const icon = icons[level] || '';\n      console.log(`${icon} ${args.join(' ')}`);\n    }\n  }\n  ```\n\n## Silent Mode Utilities (in `scripts/modules/utils.js`)\n\n- **Silent Mode Control**:\n  - ✅ DO: Use the exported silent mode functions rather than accessing global variables\n  - ✅ DO: Always use `isSilentMode()` to check the current silent mode state\n  - ✅ DO: Ensure silent mode is disabled in a `finally` block to prevent it from staying enabled\n  - ❌ DON'T: Access the global `silentMode` variable directly\n  - ❌ DON'T: Forget to disable silent mode after enabling it\n\n  ```javascript\n  // ✅ DO: Use the silent mode control functions properly\n  \n  // Example of proper implementation in utils.js:\n  \n  // Global silent mode flag (private to the module)\n  let silentMode = false;\n  \n  // Enable silent mode\n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  // Disable silent mode\n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  // Check if silent mode is enabled\n  function isSilentMode() {\n    return silentMode;\n  }\n  \n  // Example of proper usage in another module:\n  import { enableSilentMode, disableSilentMode, isSilentMode } from './utils.js';\n  \n  // Check current status\n  if (!isSilentMode()) {\n    console.log('Silent mode is not enabled');\n  }\n  \n  // Use try/finally pattern to ensure silent mode is disabled\n  try {\n    enableSilentMode();\n    // Do something that should suppress console output\n    performOperation();\n  } finally {\n    disableSilentMode();\n  }\n  ```\n\n- **Integration with Logging**:\n  - ✅ DO: Make the `log` function respect silent mode\n  ```javascript\n  function log(level, ...args) {\n    // Skip logging if silent mode is enabled\n    if (isSilentMode()) {\n      return;\n    }\n    \n    // Rest of logging logic...\n  }\n  ```\n\n- **Common Patterns for Silent Mode**:\n  - ✅ DO: In **direct functions** (`mcp-server/src/core/direct-functions/*`) that call **core functions** (`scripts/modules/*`), ensure console output from the core function is suppressed to avoid breaking MCP JSON responses.\n    - **Preferred Method**: Update the core function to accept an `outputFormat` parameter (e.g., `outputFormat = 'text'`) and make it check `outputFormat === 'text'` before displaying any UI elements (banners, spinners, boxes, direct `console.log`s). Pass `'json'` from the direct function.\n    - **Necessary Fallback/Guarantee**: If the core function *cannot* be modified or its output suppression via `outputFormat` is unreliable, **wrap the core function call within the direct function** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block. This acts as a safety net.\n  ```javascript\n  // Example in a direct function\n  export async function someOperationDirect(args, log) {\n    let result;\n    const tasksPath = findTasksJsonPath(args, log); // Get path first\n    \n    // Option 1: Core function handles 'json' format (Preferred)\n    try {\n      result = await coreFunction(tasksPath, ...otherArgs, 'json'); // Pass 'json'\n      return { success: true, data: result, fromCache: false };\n    } catch (error) {\n      // Handle error...\n    }\n\n    // Option 2: Core function output unreliable (Fallback/Guarantee)\n    try {\n      enableSilentMode(); // Enable before call\n      result = await coreFunction(tasksPath, ...otherArgs); // Call without format param\n    } catch (error) {\n      // Handle error...\n      log.error(`Failed: ${error.message}`);\n      return { success: false, error: { /* ... */ } };\n    } finally {\n      disableSilentMode(); // ALWAYS disable in finally\n    }\n    return { success: true, data: result, fromCache: false }; // Assuming success if no error caught\n  }\n  ```\n  - ✅ DO: For functions that accept a silent mode parameter but also need to check global state (less common):\n  ```javascript\n  // Check both the passed parameter and global silent mode\n  const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n  ```\n\n## File Operations (in `scripts/modules/utils.js`)\n\n- **Error Handling**:\n  - ✅ DO: Use try/catch blocks for all file operations\n  - ✅ DO: Return null or a default value on failure\n  - ✅ DO: Log detailed error information using the `log` utility\n  - ❌ DON'T: Allow exceptions to propagate unhandled from simple file reads/writes\n\n  ```javascript\n  // ✅ DO: Handle file operation errors properly in core utils\n  function writeJSON(filepath, data) {\n    try {\n      // Ensure directory exists (example)\n      const dir = path.dirname(filepath);\n      if (!fs.existsSync(dir)) {\n        fs.mkdirSync(dir, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Error writing JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n    }\n  }\n  ```\n\n## Task-Specific Utilities (in `scripts/modules/utils.js`)\n\n- **Task ID Formatting**:\n  - ✅ DO: Create utilities for consistent ID handling\n  - ✅ DO: Support different ID formats (numeric, string, dot notation)\n  - ❌ DON'T: Duplicate formatting logic across modules\n\n  ```javascript\n  // ✅ DO: Create utilities for common operations\n  /**\n   * Formats a task ID as a string\n   * @param {string|number} id - The task ID to format\n   * @returns {string} The formatted task ID\n   */\n  function formatTaskId(id) {\n    if (typeof id === 'string' && id.includes('.')) {\n      return id; // Already formatted as a string with a dot (e.g., \"1.2\")\n    }\n    \n    if (typeof id === 'number') {\n      return id.toString();\n    }\n    \n    return id;\n  }\n  ```\n\n- **Task Search**:\n  - ✅ DO: Implement reusable task finding utilities\n  - ✅ DO: Support both task and subtask lookups\n  - ✅ DO: Add context to subtask results\n\n  ```javascript\n  // ✅ DO: Create comprehensive search utilities\n  /**\n   * Finds a task by ID in the tasks array\n   * @param {Array} tasks - The tasks array\n   * @param {string|number} taskId - The task ID to find\n   * @returns {Object|null} The task object or null if not found\n   */\n  function findTaskById(tasks, taskId) {\n    if (!taskId || !tasks || !Array.isArray(tasks)) {\n      return null;\n    }\n    \n    // Check if it's a subtask ID (e.g., \"1.2\")\n    if (typeof taskId === 'string' && taskId.includes('.')) {\n      const [parentId, subtaskId] = taskId.split('.').map(id => parseInt(id, 10));\n      const parentTask = tasks.find(t => t.id === parentId);\n      \n      if (!parentTask || !parentTask.subtasks) {\n        return null;\n      }\n      \n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      if (subtask) {\n        // Add reference to parent task for context\n        subtask.parentTask = { \n          id: parentTask.id, \n          title: parentTask.title,\n          status: parentTask.status\n        };\n        subtask.isSubtask = true;\n      }\n      \n      return subtask || null;\n    }\n    \n    const id = parseInt(taskId, 10);\n    return tasks.find(t => t.id === id) || null;\n  }\n  ```\n\n## Cycle Detection (in `scripts/modules/utils.js`)\n\n- **Graph Algorithms**:\n  - ✅ DO: Implement cycle detection using graph traversal\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Return specific information about cycles\n\n  ```javascript\n  // ✅ DO: Implement proper cycle detection\n  /**\n   * Find cycles in a dependency graph using DFS\n   * @param {string} subtaskId - Current subtask ID\n   * @param {Map} dependencyMap - Map of subtask IDs to their dependencies\n   * @param {Set} visited - Set of visited nodes\n   * @param {Set} recursionStack - Set of nodes in current recursion stack\n   * @returns {Array} - List of dependency edges that need to be removed to break cycles\n   */\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set(), path = []) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    path.push(subtaskId);\n    \n    const cyclesToBreak = [];\n    \n    // Get all dependencies of the current subtask\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    // For each dependency\n    for (const depId of dependencies) {\n      // If not visited, recursively check for cycles\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack, [...path]);\n        cyclesToBreak.push(...cycles);\n      } \n      // If the dependency is in the recursion stack, we found a cycle\n      else if (recursionStack.has(depId)) {\n        // The last edge in the cycle is what we want to remove\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\n## MCP Server Core Utilities (`mcp-server/src/core/utils/`)\n\n### Project Root and Task File Path Detection (`path-utils.js`)\n\n- **Purpose**: This module ([`mcp-server/src/core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) provides the mechanism for locating the user's `tasks.json` file, used by direct functions.\n- **`findTasksJsonPath(args, log)`**:\n    - ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.\n    - Pass the *entire `args` object* received by the MCP tool (which should include `projectRoot` derived from the session) and the `log` object.\n    - Implements a **simplified precedence system** for finding the `tasks.json` path:\n        1.  Explicit `projectRoot` passed in `args` (Expected from MCP tools).\n        2.  Cached `lastFoundProjectRoot` (CLI fallback).\n        3.  Search upwards from `process.cwd()` (CLI fallback).\n    - Throws a specific error if the `tasks.json` file cannot be located.\n    - Updates the `lastFoundProjectRoot` cache on success.\n- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the CLI fallback search.\n- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself (potentially removable).\n\n## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)\n\nThese utilities specifically support the implementation and execution of MCP tools.\n\n- **`normalizeProjectRoot(rawPath, log)`**:\n    - **Purpose**: Takes a raw project root path (potentially URI encoded, with `file://` prefix, Windows slashes) and returns a normalized, absolute path suitable for the server's OS.\n    - **Logic**: Decodes URI, strips `file://`, handles Windows drive prefix (`/C:/`), replaces `\\` with `/`, uses `path.resolve()`.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF.\n\n- **`getRawProjectRootFromSession(session, log)`**:\n    - **Purpose**: Extracts the *raw* project root URI string from the session object (`session.roots[0].uri` or `session.roots.roots[0].uri`) without performing normalization.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF as a fallback if `args.projectRoot` isn't provided.\n\n- **`withNormalizedProjectRoot(executeFn)`**:\n    - **Purpose**: A Higher-Order Function (HOF) designed to wrap a tool's `execute` method.\n    - **Logic**: \n        1. Determines the raw project root (from `args.projectRoot` or `getRawProjectRootFromSession`).\n        2. Normalizes the raw path using `normalizeProjectRoot`.\n        3. Injects the normalized, absolute path back into the `args` object as `args.projectRoot`.\n        4. Calls the original `executeFn` with the updated `args`.\n    - **Usage**: Should wrap the `execute` function of *every* MCP tool that needs a reliable, normalized project root path.\n    - **Example**:\n      ```javascript\n      // In mcp-server/src/tools/your-tool.js\n      import { withNormalizedProjectRoot } from './utils.js';\n      \n      export function registerYourTool(server) {\n          server.addTool({\n              // ... name, description, parameters ...\n              execute: withNormalizedProjectRoot(async (args, context) => {\n                  // args.projectRoot is now normalized here\n                  const { projectRoot /*, other args */ } = args;\n                  // ... rest of tool logic using normalized projectRoot ...\n              })\n          });\n      }\n      ```\n\n- **`handleApiResult(result, log, errorPrefix, processFunction)`**:\n    - **Purpose**: Standardizes the formatting of responses returned by direct functions (`{ success, data/error, fromCache }`) into the MCP response format.\n    - **Usage**: Call this at the end of the tool's `execute` method, passing the result from the direct function call.\n\n- **`createContentResponse(content)` / `createErrorResponse(errorMessage)`**:\n    - **Purpose**: Helper functions to create the basic MCP response structure for success or error messages.\n    - **Usage**: Used internally by `handleApiResult` and potentially directly for simple responses.\n\n- **`createLogWrapper(log)`**:\n    - **Purpose**: Creates a logger object wrapper with standard methods (`info`, `warn`, `error`, `debug`, `success`) mapping to the passed MCP `log` object's methods. Ensures compatibility when passing loggers to core functions.\n    - **Usage**: Used within direct functions before passing the `log` object down to core logic that expects the standard method names.\n\n- **`getCachedOrExecute({ cacheKey, actionFn, log })`**:\n    - **Purpose**: Utility for implementing caching within direct functions. Checks cache for `cacheKey`; if miss, executes `actionFn`, caches successful result, and returns.\n    - **Usage**: Wrap the core logic execution within a direct function call.\n\n- **`processMCPResponseData(taskOrData, fieldsToRemove)`**:\n    - **Purpose**: Utility to filter potentially sensitive or large fields (like `details`, `testStrategy`) from task objects before sending the response back via MCP.\n    - **Usage**: Passed as the default `processFunction` to `handleApiResult`.\n\n- **`getProjectRootFromSession(session, log)`**:\n    - **Purpose**: Legacy function to extract *and normalize* the project root from the session. Replaced by the HOF pattern but potentially still used.\n    - **Recommendation**: Prefer using the `withNormalizedProjectRoot` HOF in tools instead of calling this directly.\n\n- **`executeTaskMasterCommand(...)`**: \n    - **Purpose**: Executes `task-master` CLI command as a fallback. \n    - **Recommendation**: Deprecated for most uses; prefer direct function calls.\n\n## Export Organization\n\n- **Grouping Related Functions**:\n  - ✅ DO: Keep utilities relevant to their location (e.g., core CLI utils in `scripts/modules/utils.js`, MCP path utils in `mcp-server/src/core/utils/path-utils.js`, MCP tool utils in `mcp-server/src/tools/utils.js`).\n  - ✅ DO: Export all utility functions in a single statement per file.\n  - ✅ DO: Group related exports together.\n  - ✅ DO: Export configuration constants (from `scripts/modules/utils.js`).\n  - ❌ DON'T: Use default exports.\n  - ❌ DON'T: Create circular dependencies (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)).\n\n```javascript\n// Example export from scripts/modules/utils.js\nexport {\n  // Configuration\n  CONFIG,\n  LOG_LEVELS,\n  \n  // Logging\n  log,\n  \n  // File operations\n  readJSON,\n  writeJSON,\n  \n  // String manipulation\n  sanitizePrompt,\n  truncate,\n  \n  // Task utilities\n  // ... (taskExists, formatTaskId, findTaskById, etc.)\n  \n  // Graph algorithms\n  findCycles,\n};\n\n// Example export from mcp-server/src/core/utils/path-utils.js\nexport {\n  findTasksJsonPath,\n  getPackagePath,\n  PROJECT_MARKERS,\n  lastFoundProjectRoot // Exporting for potential direct use/reset if needed\n};\n\n// Example export from mcp-server/src/tools/utils.js\nexport {\n  getProjectRoot,\n  getProjectRootFromSession,\n  handleApiResult,\n  executeTaskMasterCommand,\n  processMCPResponseData,\n  createContentResponse,\n  createErrorResponse,\n  getCachedOrExecute\n};\n```\n\n## Context Gathering Utilities\n\n### **ContextGatherer** (`scripts/modules/utils/contextGatherer.js`)\n\n- **Multi-Source Context Extraction**:\n  - ✅ DO: Use for AI-powered commands that need project context\n  - ✅ DO: Support tasks, files, custom text, and project tree context\n  - ✅ DO: Implement detailed token counting with `gpt-tokens` library\n  - ✅ DO: Provide multiple output formats (research, chat, system-prompt)\n\n  ```javascript\n  // ✅ DO: Use ContextGatherer for consistent context extraction\n  import { ContextGatherer } from '../utils/contextGatherer.js';\n  \n  const gatherer = new ContextGatherer(projectRoot, tasksPath);\n  const result = await gatherer.gather({\n    tasks: ['15', '16.2'],\n    files: ['src/api.js'],\n    customContext: 'Additional context',\n    includeProjectTree: true,\n    format: 'research',\n    includeTokenCounts: true\n  });\n  ```\n\n### **FuzzyTaskSearch** (`scripts/modules/utils/fuzzyTaskSearch.js`)\n\n- **Intelligent Task Discovery**:\n  - ✅ DO: Use for automatic task relevance detection\n  - ✅ DO: Configure search parameters based on use case context\n  - ✅ DO: Implement purpose-based categorization for better matching\n  - ✅ DO: Sort results by relevance score and task ID\n\n  ```javascript\n  // ✅ DO: Use FuzzyTaskSearch for intelligent task discovery\n  import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n  \n  const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n  const searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n  });\n  const taskIds = fuzzySearch.getTaskIds(searchResults);\n  ```\n\n- **Integration Guidelines**:\n  - ✅ DO: Use fuzzy search to supplement user-provided task IDs\n  - ✅ DO: Display discovered task IDs to users for transparency\n  - ✅ DO: Sort discovered task IDs numerically for better readability\n  - ❌ DON'T: Replace explicit user task selections with fuzzy results\n\nRefer to [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for detailed implementation patterns, [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for more context on MCP server architecture and integration. \n\n## File System Operations\n\n- **JSON File Handling**:\n  - ✅ DO: Use `readJSON` and `writeJSON` for all JSON operations\n  - ✅ DO: Include error handling for file operations\n  - ✅ DO: Validate JSON structure after reading\n  - ❌ DON'T: Use raw `fs.readFileSync` or `fs.writeFileSync` for JSON\n\n  ```javascript\n  // ✅ DO: Use utility functions with error handling\n  function readJSON(filepath) {\n    try {\n      if (!fs.existsSync(filepath)) {\n        return null; // or appropriate default\n      }\n      \n      let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n      \n      // Silent migration for tasks.json files: Transform old format to tagged format\n      const isTasksFile = filepath.includes('tasks.json') || path.basename(filepath) === 'tasks.json';\n      \n      if (data && data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n        // Migrate from old format { \"tasks\": [...] } to new format { \"master\": { \"tasks\": [...] } }\n        const migratedData = {\n          master: {\n            tasks: data.tasks\n          }\n        };\n        \n        writeJSON(filepath, migratedData);\n        \n        // Set global flag for CLI notice and perform complete migration\n        global.taskMasterMigrationOccurred = true;\n        performCompleteTagMigration(filepath);\n        \n        data = migratedData;\n      }\n      \n      return data;\n    } catch (error) {\n      log('error', `Failed to read JSON from ${filepath}: ${error.message}`);\n      return null;\n    }\n  }\n  \n  function writeJSON(filepath, data) {\n    try {\n      const dirPath = path.dirname(filepath);\n      if (!fs.existsSync(dirPath)) {\n        fs.mkdirSync(dirPath, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Failed to write JSON to ${filepath}: ${error.message}`);\n      throw error;\n    }\n  }\n  ```\n\n- **Path Resolution**:\n  - ✅ DO: Use `path.join()` for cross-platform path construction\n  - ✅ DO: Use `path.resolve()` for absolute paths\n  - ✅ DO: Validate paths before file operations\n\n  ```javascript\n  // ✅ DO: Handle paths correctly\n  function findProjectRoot(startPath = process.cwd()) {\n    let currentPath = path.resolve(startPath);\n    const rootPath = path.parse(currentPath).root;\n    \n    while (currentPath !== rootPath) {\n      const taskMasterPath = path.join(currentPath, '.taskmaster');\n      if (fs.existsSync(taskMasterPath)) {\n        return currentPath;\n      }\n      currentPath = path.dirname(currentPath);\n    }\n    \n    return null; // Not found\n  }\n  ```\n\n## Tagged Task Lists System Utilities\n\n- **Tag Resolution Functions**:\n  - ✅ DO: Use tag resolution layer for all task data access\n  - ✅ DO: Provide backward compatibility with legacy format\n  - ✅ DO: Default to \"master\" tag when no tag is specified\n\n  ```javascript\n  // ✅ DO: Implement tag resolution functions\n  function getTasksForTag(data, tagName = 'master') {\n    if (!data) {\n      return [];\n    }\n    \n    // Handle legacy format - direct tasks array\n    if (data.tasks && Array.isArray(data.tasks)) {\n      return data.tasks;\n    }\n    \n    // Handle tagged format - tasks under specific tag\n    if (data[tagName] && data[tagName].tasks && Array.isArray(data[tagName].tasks)) {\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  \n  function setTasksForTag(data, tagName = 'master', tasks) {\n    // Ensure data object exists\n    if (!data) {\n      data = {};\n    }\n    \n    // Create tag structure if it doesn't exist\n    if (!data[tagName]) {\n      data[tagName] = {};\n    }\n    \n    // Set tasks for the tag\n    data[tagName].tasks = tasks;\n    \n    return data;\n  }\n  \n  function getCurrentTag() {\n    // Get current tag from state.json or default to 'master'\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return 'master';\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (fs.existsSync(statePath)) {\n        const state = readJSON(statePath);\n        return state.currentTag || 'master';\n      }\n    } catch (error) {\n      log('debug', `Error reading current tag: ${error.message}`);\n    }\n    \n    return 'master';\n  }\n  ```\n\n- **Migration Functions**:\n  - ✅ DO: Implement complete migration for all related files\n  - ✅ DO: Handle configuration and state file creation\n  - ✅ DO: Provide migration status tracking\n\n  ```javascript\n  // ✅ DO: Implement complete migration system\n  function performCompleteTagMigration(tasksJsonPath) {\n    try {\n      // Derive project root from tasks.json path\n      const projectRoot = findProjectRoot(path.dirname(tasksJsonPath)) || path.dirname(tasksJsonPath);\n      \n      // 1. Migrate config.json - add defaultTag and tags section\n      const configPath = path.join(projectRoot, '.taskmaster', 'config.json');\n      if (fs.existsSync(configPath)) {\n        migrateConfigJson(configPath);\n      }\n      \n      // 2. Create state.json if it doesn't exist\n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (!fs.existsSync(statePath)) {\n        createStateJson(statePath);\n      }\n      \n      if (getDebugFlag()) {\n        log('debug', 'Completed tagged task lists migration for project');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error during complete tag migration: ${error.message}`);\n      }\n    }\n  }\n  \n  function migrateConfigJson(configPath) {\n    try {\n      const config = readJSON(configPath);\n      if (!config) return;\n      \n      let modified = false;\n      \n      // Add global.defaultTag if missing\n      if (!config.global) {\n        config.global = {};\n      }\n      if (!config.global.defaultTag) {\n        config.global.defaultTag = 'master';\n        modified = true;\n      }\n      \n      // Add tags section if missing\n      if (!config.tags) {\n        config.tags = {\n                  // Git integration settings removed - now manual only\n        };\n        modified = true;\n      }\n      \n      if (modified) {\n        writeJSON(configPath, config);\n        if (getDebugFlag()) {\n          log('debug', 'Updated config.json with tagged task system settings');\n        }\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error migrating config.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function createStateJson(statePath) {\n    try {\n      const initialState = {\n        currentTag: 'master',\n        lastSwitched: new Date().toISOString(),\n        migrationNoticeShown: false\n      };\n      \n      writeJSON(statePath, initialState);\n      if (getDebugFlag()) {\n        log('debug', 'Created initial state.json for tagged task system');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error creating state.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function markMigrationForNotice() {\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return;\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      const state = readJSON(statePath) || {};\n      \n      state.migrationNoticeShown = false; // Reset to show notice\n      writeJSON(statePath, state);\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error marking migration for notice: ${error.message}`);\n      }\n    }\n  }\n  ```\n\n## Logging Functions\n\n- **Consistent Logging**:\n  - ✅ DO: Use the central `log` function for all output\n  - ✅ DO: Use appropriate log levels (info, warn, error, debug)\n  - ✅ DO: Support silent mode for programmatic usage\n\n  ```javascript\n  // ✅ DO: Implement consistent logging with silent mode\n  let silentMode = false;\n  \n  function log(level, ...messages) {\n    if (silentMode && level !== 'error') {\n      return; // Suppress non-error logs in silent mode\n    }\n    \n    const timestamp = new Date().toISOString();\n    const formattedMessage = messages.join(' ');\n    \n    switch (level) {\n      case 'error':\n        console.error(`[ERROR] ${formattedMessage}`);\n        break;\n      case 'warn':\n        console.warn(`[WARN] ${formattedMessage}`);\n        break;\n      case 'info':\n        console.log(`[INFO] ${formattedMessage}`);\n        break;\n      case 'debug':\n        if (getDebugFlag()) {\n          console.log(`[DEBUG] ${formattedMessage}`);\n        }\n        break;\n      default:\n        console.log(formattedMessage);\n    }\n  }\n  \n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  function isSilentMode() {\n    return silentMode;\n  }\n  ```\n\n## Task Utilities\n\n- **Task Finding and Manipulation**:\n  - ✅ DO: Use tagged task system aware functions\n  - ✅ DO: Handle both task and subtask operations\n  - ✅ DO: Validate task IDs before operations\n\n  ```javascript\n  // ✅ DO: Implement tag-aware task utilities\n  function findTaskById(tasks, taskId) {\n    if (!Array.isArray(tasks)) {\n      return null;\n    }\n    return tasks.find(task => task.id === taskId) || null;\n  }\n  \n  function findSubtaskById(tasks, parentId, subtaskId) {\n    const parentTask = findTaskById(tasks, parentId);\n    if (!parentTask || !parentTask.subtasks) {\n      return null;\n    }\n    \n    return parentTask.subtasks.find(subtask => subtask.id === subtaskId) || null;\n  }\n  \n  function getNextTaskId(tasks) {\n    if (!Array.isArray(tasks) || tasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...tasks.map(task => task.id));\n    return maxId + 1;\n  }\n  \n  function getNextSubtaskId(parentTask) {\n    if (!parentTask.subtasks || parentTask.subtasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...parentTask.subtasks.map(subtask => subtask.id));\n    return maxId + 1;\n  }\n  ```\n\n## String Utilities\n\n- **Text Processing**:\n  - ✅ DO: Handle text truncation appropriately\n  - ✅ DO: Provide consistent formatting functions\n  - ✅ DO: Support different output formats\n\n  ```javascript\n  // ✅ DO: Implement useful string utilities\n  function truncate(str, maxLength = 50) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    if (str.length <= maxLength) {\n      return str;\n    }\n    \n    return str.substring(0, maxLength - 3) + '...';\n  }\n  \n  function formatDuration(ms) {\n    const seconds = Math.floor(ms / 1000);\n    const minutes = Math.floor(seconds / 60);\n    const hours = Math.floor(minutes / 60);\n    \n    if (hours > 0) {\n      return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n    } else if (minutes > 0) {\n      return `${minutes}m ${seconds % 60}s`;\n    } else {\n      return `${seconds}s`;\n    }\n  }\n  \n  function capitalizeFirst(str) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n  }\n  ```\n\n## Dependency Management Utilities\n\n- **Dependency Analysis**:\n  - ✅ DO: Detect circular dependencies\n  - ✅ DO: Validate dependency references\n  - ✅ DO: Support cross-tag dependency checking (future enhancement)\n\n  ```javascript\n  // ✅ DO: Implement dependency utilities\n  function findCycles(tasks) {\n    const cycles = [];\n    const visited = new Set();\n    const recStack = new Set();\n    \n    function dfs(taskId, path = []) {\n      if (recStack.has(taskId)) {\n        // Found a cycle\n        const cycleStart = path.indexOf(taskId);\n        const cycle = path.slice(cycleStart).concat([taskId]);\n        cycles.push(cycle);\n        return;\n      }\n      \n      if (visited.has(taskId)) {\n        return;\n      }\n      \n      visited.add(taskId);\n      recStack.add(taskId);\n      \n      const task = findTaskById(tasks, taskId);\n      if (task && task.dependencies) {\n        task.dependencies.forEach(depId => {\n          dfs(depId, path.concat([taskId]));\n        });\n      }\n      \n      recStack.delete(taskId);\n    }\n    \n    tasks.forEach(task => {\n      if (!visited.has(task.id)) {\n        dfs(task.id);\n      }\n    });\n    \n    return cycles;\n  }\n  \n  function validateDependencies(tasks) {\n    const validationErrors = [];\n    const taskIds = new Set(tasks.map(task => task.id));\n    \n    tasks.forEach(task => {\n      if (task.dependencies) {\n        task.dependencies.forEach(depId => {\n          if (!taskIds.has(depId)) {\n            validationErrors.push({\n              taskId: task.id,\n              invalidDependency: depId,\n              message: `Task ${task.id} depends on non-existent task ${depId}`\n            });\n          }\n        });\n      }\n    });\n    \n    return validationErrors;\n  }\n  ```\n\n## Environment and Configuration Utilities\n\n- **Environment Variable Resolution**:\n  - ✅ DO: Support both `.env` files and MCP session environment\n  - ✅ DO: Provide fallbacks for missing values\n  - ✅ DO: Handle API key resolution correctly\n\n  ```javascript\n  // ✅ DO: Implement flexible environment resolution\n  function resolveEnvVariable(key, sessionEnv = null) {\n    // First check session environment (for MCP)\n    if (sessionEnv && sessionEnv[key]) {\n      return sessionEnv[key];\n    }\n    \n    // Then check process environment\n    if (process.env[key]) {\n      return process.env[key];\n    }\n    \n    // Finally try .env file if in project root\n    try {\n      const projectRoot = findProjectRoot();\n      if (projectRoot) {\n        const envPath = path.join(projectRoot, '.env');\n        if (fs.existsSync(envPath)) {\n          const envContent = fs.readFileSync(envPath, 'utf8');\n          const lines = envContent.split('\\n');\n          \n          for (const line of lines) {\n            const [envKey, envValue] = line.split('=');\n            if (envKey && envKey.trim() === key) {\n              return envValue ? envValue.trim().replace(/^[\"']|[\"']$/g, '') : undefined;\n            }\n          }\n        }\n      }\n    } catch (error) {\n      log('debug', `Error reading .env file: ${error.message}`);\n    }\n    \n    return undefined;\n  }\n  \n  function getDebugFlag() {\n    const debugFlag = resolveEnvVariable('TASKMASTER_DEBUG') || \n                     resolveEnvVariable('DEBUG') || \n                     'false';\n    return debugFlag.toLowerCase() === 'true';\n  }\n  ```\n\n## Export Pattern\n\n- **Module Exports**:\n  - ✅ DO: Export all utility functions explicitly\n  - ✅ DO: Group related functions logically\n  - ✅ DO: Include new tagged system utilities\n\n  ```javascript\n  // ✅ DO: Export utilities in logical groups\n  module.exports = {\n    // File system utilities\n    readJSON,\n    writeJSON,\n    findProjectRoot,\n    \n    // Tagged task system utilities\n    getTasksForTag,\n    setTasksForTag,\n    getCurrentTag,\n    performCompleteTagMigration,\n    migrateConfigJson,\n    createStateJson,\n    markMigrationForNotice,\n    \n    // Logging utilities\n    log,\n    enableSilentMode,\n    disableSilentMode,\n    isSilentMode,\n    \n    // Task utilities\n    findTaskById,\n    findSubtaskById,\n    getNextTaskId,\n    getNextSubtaskId,\n    \n    // String utilities\n    truncate,\n    formatDuration,\n    capitalizeFirst,\n    \n    // Dependency utilities\n    findCycles,\n    validateDependencies,\n    \n    // Environment utilities\n    resolveEnvVariable,\n    getDebugFlag,\n    \n    // Legacy utilities (maintained for compatibility)\n    aggregateTelemetry\n  };\n  ```\n\nRefer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for integration patterns.\n","frontmatter":{"description":null,"globs":null,"alwaysApply":false},"isInternal":false,"tokens":9975,"sizeBytes":41613},{"name":"listTasks-architecture.md","path":"packages/tm-core/docs/listTasks-architecture.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/tm-core/docs/listTasks-architecture.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"# ListTasks Architecture - End-to-End POC\n\n## Current Implementation Structure\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                         CLI Layer                            │\n│  scripts/modules/task-manager/list-tasks.js                 │\n│  - Complex UI rendering (tables, progress bars)             │\n│  - Multiple output formats (json, text, markdown, compact)  │\n│  - Status filtering and statistics                          │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              │ Currently reads directly\n                              │ from files (needs integration)\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                      tm-core Package                         │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            TaskMasterCore (Facade)                   │   │\n│  │  src/task-master-core.ts                            │   │\n│  │                                                      │   │\n│  │  - listTasks(options)                               │   │\n│  │    • tag filtering                                  │   │\n│  │    • status filtering                               │   │\n│  │    • include/exclude subtasks                       │   │\n│  │  - getTask(id)                                      │   │\n│  │  - getTasksByStatus(status)                         │   │\n│  │  - getTaskStats()                                   │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                              │                               │\n│                              ▼                               │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │              Storage Layer (IStorage)                │   │\n│  │                                                      │   │\n│  │  ┌──────────────┐        ┌──────────────┐          │   │\n│  │  │ FileStorage  │        │ ApiStorage   │          │   │\n│  │  │              │        │ (Hamster)    │          │   │\n│  │  └──────────────┘        └──────────────┘          │   │\n│  │                                                      │   │\n│  │  StorageFactory.create() selects based on config    │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            Domain Layer (Entities)                   │   │\n│  │                                                      │   │\n│  │  TaskEntity                                         │   │\n│  │  - Business logic                                   │   │\n│  │  - Validation                                       │   │\n│  │  - Status transitions                               │   │\n│  └─────────────────────────────────────────────────────┘   │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## ListTasks Data Flow\n\n### 1. CLI Request\n```javascript\n// Current CLI (needs update to use tm-core)\nlistTasks(tasksPath, statusFilter, reportPath, withSubtasks, outputFormat, context)\n```\n\n### 2. TaskMasterCore Processing\n```typescript\n// Our new implementation\nconst tmCore = createTaskMasterCore(projectPath, { \n  storage: { \n    type: 'api',  // or 'file'\n    apiEndpoint: 'https://tryhamster.com',\n    apiAccessToken: 'xxx'\n  }\n});\n\nconst result = await tmCore.listTasks({\n  tag: 'feature-branch',\n  filter: {\n    status: ['pending', 'in-progress'],\n    priority: 'high',\n    search: 'authentication'\n  },\n  includeSubtasks: true\n});\n```\n\n### 3. Storage Selection\n```typescript\n// StorageFactory automatically selects storage\nconst storage = StorageFactory.create(config, projectPath);\n// Returns either FileStorage or ApiStorage based on config\n```\n\n### 4. Data Loading\n```typescript\n// FileStorage\n- Reads from .taskmaster/tasks/tasks.json (or tag-specific file)\n- Local file system operations\n\n// ApiStorage (Hamster)\n- Makes HTTP requests to Hamster API\n- Uses access token from config\n- Handles retries and rate limiting\n```\n\n### 5. Entity Processing\n```typescript\n// Convert raw data to TaskEntity for business logic\nconst taskEntities = TaskEntity.fromArray(rawTasks);\n\n// Apply filters\nconst filtered = applyFilters(taskEntities, filter);\n\n// Convert back to plain objects\nconst tasks = filtered.map(entity => entity.toJSON());\n```\n\n### 6. Response Structure\n```typescript\ninterface ListTasksResult {\n  tasks: Task[];        // Filtered tasks\n  total: number;        // Total task count\n  filtered: number;     // Filtered task count  \n  tag?: string;         // Tag context if applicable\n}\n```\n\n## Integration Points Needed\n\n### 1. CLI Integration\n- [ ] Update `scripts/modules/task-manager/list-tasks.js` to use tm-core\n- [ ] Map CLI options to TaskMasterCore options\n- [ ] Handle output formatting in CLI layer\n\n### 2. Configuration Loading\n- [ ] Load `.taskmaster/config.json` for storage settings\n- [ ] Support environment variables for API tokens\n- [ ] Handle storage type selection\n\n### 3. Testing Requirements\n- [x] Unit tests for TaskEntity\n- [x] Unit tests for BaseProvider\n- [x] Integration tests for listTasks with FileStorage\n- [ ] Integration tests for listTasks with ApiStorage (mock API)\n- [ ] E2E tests with real Hamster API (optional)\n\n## Benefits of This Architecture\n\n1. **Storage Abstraction**: Switch between file and API storage without changing business logic\n2. **Clean Separation**: UI (CLI) separate from business logic (tm-core)\n3. **Testability**: Each layer can be tested independently\n4. **Extensibility**: Easy to add new storage types (database, cloud, etc.)\n5. **Type Safety**: Full TypeScript support throughout\n6. **Error Handling**: Consistent error handling with TaskMasterError\n\n## Next Steps\n\n1. Create a simple CLI wrapper that uses tm-core\n2. Test with file storage (existing functionality)\n3. Test with mock API storage\n4. Integrate with actual Hamster API when available\n5. Migrate other commands (addTask, updateTask, etc.) following same pattern","isInternal":false,"tokens":1369,"sizeBytes":7755},{"name":"dedupe.md","path":".claude/commands/dedupe.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.claude/commands/dedupe.md","title":"Command: /dedupe","category":"command-prompt","format":"markdown","content":"---\nallowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)\ndescription: Find duplicate GitHub issues\n---\n\nFind up to 3 likely duplicate issues for a given GitHub issue.\n\nTo do this, follow these steps precisely:\n\n1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.\n2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue\n3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1\n4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.\n5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)\n\nNotes (be sure to tell this to your agents, too):\n\n- Use `gh` to interact with Github, rather than web fetch\n- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)\n- Make a todo list first\n- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):\n\n---\n\nFound 3 possible duplicate issues:\n\n1. <link to issue>\n2. <link to issue>\n3. <link to issue>\n\nThis issue will be automatically closed as a duplicate in 3 days.\n\n- If your issue is a duplicate, please close it and 👍 the existing issue instead\n- To prevent auto-closure, add a comment or 👎 this comment\n\n🤖 Generated with \\[Task Master Bot\\]\n\n---","frontmatter":{"allowed-tools":"Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)","description":"Find duplicate GitHub issues","allowedTools":["Bash(gh","issue","view:*),","Bash(gh","search:*),","Bash(gh","issue","list:*),","Bash(gh","api:*),","Bash(gh","issue","comment:*)"]},"allowedTools":["Bash(gh","issue","view:*),","Bash(gh","search:*),","Bash(gh","issue","list:*),","Bash(gh","api:*),","Bash(gh","issue","comment:*)"],"isInternal":false,"tokens":442,"sizeBytes":1850},{"name":"ham.md","path":".claude/commands/go/ham.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.claude/commands/go/ham.md","title":"Command: /ham","category":"command-prompt","format":"markdown","content":"# Hamster (Go ham!) Run Task Workflow\n\nThis command initiates the HAM (Hamster Automated Management) workflow for task execution.\n\n## Usage\n\n```\n/go:ham [task-id]\n```\n\n- `task-id` (optional): Specific task identifier to work on (e.g., \"1\", \"1.2\", \"2.3.1\")\n  - If provided, start working on that specific task immediately\n  - If omitted, automatically identify the next available task\n\n## Process\n\nWhen the user invokes this command, follow these steps:\n\n### 1. Task Selection\n\n#### If task-id is provided ($ARGUMENTS is not empty):\n```bash\ntm show $ARGUMENTS\n```\nStart working on the specified task immediately, skipping to step 3.\n\n#### If no task-id is provided ($ARGUMENTS is empty):\n```bash\ntm list\n```\nDisplay all tasks with their current status to provide context.\n\n### 2. Identify Next Task (only if no task-id provided)\nDetermine which task should be worked on next based on:\n- Dependencies\n- Priority\n- Current status (pending tasks only)\n\n### 3. Show Task Details (only if task wasn't specified in step 1)\n```bash\ntm show <task-id>\n```\nDisplay the full details of the identified task including:\n- Title and description\n- Dependencies\n- Test strategy\n- Subtasks (if any)\n\n### 4. Kickoff Workflow\n\nBased on the task type, follow the appropriate workflow:\n\n#### For Main Tasks (e.g., \"1\", \"2\", \"3\")\n- Review the task's subtasks\n- If no subtasks exist, suggest expanding the task first\n- Identify the first pending subtask\n- Begin implementation following the subtask's requirements\n\n#### For Subtasks (e.g., \"1.1\", \"2.3\")\n- Mark the subtask as in-progress:\n  ```bash\n  tm set-status --id=<subtask-id> --status=in-progress\n  ```\n- Review the task details and requirements\n- Check for related code files or dependencies\n- Create an implementation plan\n- Begin implementation following project conventions\n\n### 5. Implementation Guidelines\n\nFollow these principles during implementation:\n\n1. **Understand First**: Read related files and understand the current architecture\n2. **Plan**: Create a mental model or brief plan before coding\n3. **Follow Conventions**: Adhere to project structure and coding standards\n4. **Test As You Go**: Validate changes incrementally\n5. **Stay Focused**: Complete the current subtask before moving to the next\n\n### 6. Task Completion\n\nWhen the subtask is complete:\n```bash\ntm set-status --id=<subtask-id> --status=done\n```\n\nThen automatically check for the next available task by repeating from step 2.\n\n## Example Flows\n\n### With Specific Task ID\n```\nUser: \"/go:ham 1.2\"\n\n1. Claude runs: tm show 1.2\n   → Displays full task details\n2. Claude analyzes the task and creates an implementation plan\n3. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n4. Claude begins implementation following the task requirements\n5. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n6. Claude automatically identifies next task with tm list\n```\n\n### Without Specific Task ID (Auto-discovery)\n```\nUser: \"/go:ham\"\n\n1. Claude runs: tm list\n2. Claude identifies next available task (e.g., 1.2)\n3. Claude runs: tm show 1.2\n   → Displays full task details\n4. Claude analyzes the task and creates an implementation plan\n5. Claude marks task in-progress: tm set-status --id=1.2 --status=in-progress\n6. Claude begins implementation following the task requirements\n7. Upon completion, Claude runs: tm set-status --id=1.2 --status=done\n8. Claude automatically identifies next task with tm list\n```\n\n## Notes\n\n- Always verify task dependencies are complete before starting\n- If a task is blocked, mark it as such and move to the next available task\n- Keep the user informed of progress at each major step\n- Ask for clarification if task requirements are unclear\n- Follow the project's CLAUDE.md and .cursor/rules/* guidelines at all times\n- Unlike the usual Taskmaster process, do not bother using update-task nor update-subtask as they do not work with Hamster tasks yet.\n\n- Use only `tm list`, `tm show <sub/task id>` and `tm set status` - other commands don't yet work with it.\n- Do not use the MCP tools when connected with Hamster briefs - that is not yet up to date.\n- Use `.cursor/rules/git_workflow.mdc` as a guide for the workflow\n- When starting a task, mark it as in-progress. You can mark multiple task statuses at once with comma separation (i.e. `tm set-status -i 1,1.1 -s in-progress`)\n- Read the task, then if it has subtasks, begin implementing the subtasks one at a time.\n- When the subtask is done, run lint and typecheck, mark the task as done if it passes, and commit.\n- Continue until all subtasks are done, then run a final lint and typecheck (`npm lint` and `npm typecheck`) and create a PR using `gh` cli for that Task.\n- Keep committing to the same PR as long as the scope is maintained. An entire task list (brief) might fit into a single PR but not if it ends up being huge. It is preferred for everything to land in one PR if it is possible, otherwise commit to different PRs that build on top of the previous ones. Confirm with the human when doing this.\n- When the parent task is completed, ensure you mark is as done.\n- When the first task is done, repeat this process for all tasks until all tasks are done.\n- If you run into an issue where the JWT seems expired or commands don't work, ensure you use `tm auth refresh` to refresh the token and if that does not work, use `tm context <brief url>` to reconnect the context. If you do not have the brief url, ask the user for it (perhaps use it at the beginning)\n\nYou're a fast hamster. Go go go.","isInternal":false,"tokens":1350,"sizeBytes":5530},{"name":"pr-comments.md","path":".claude/commands/go/pr-comments.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.claude/commands/go/pr-comments.md","title":"Command: /pr-comments","category":"command-prompt","format":"markdown","content":"Fix PR review comments: PR # $ARGUMENTS\n\nThis command collects all review comments from a GitHub PR (including CodeRabbit, human reviewers, and other bots), consolidates them by author and severity, shows them to you for approval, then implements the approved fixes.\n\nSteps:\n\n1. **Collect PR comments**\n   - Run: `gh pr view $ARGUMENTS --comments` to get ALL comments (no truncation)\n   - Parse and extract all review comments from:\n     - PR review comments (file-level)\n     - General comments\n     - Review threads\n   - Include author information for each comment\n   - IMPORTANT: Do NOT use `head`, `tail`, or any truncation - we need complete comment history\n\n2. **Consolidate comments**\n   - Group comments by:\n     - Author (CodeRabbit, human reviewers, other bots)\n     - Severity (🚨 Critical, ⚠️ Important, 💡 Suggestion, ℹ️ Info)\n     - Category (Security, Performance, Best Practices, Style, etc.)\n   - Remove duplicates and group similar issues\n   - Present in a clear, numbered list format showing author for each\n\n3. **Show consolidated issues for approval**\n   - Display the organized list with:\n     - Issue number for reference\n     - Severity indicator\n     - File location\n     - Description\n     - Suggested fix\n   - Ask: \"Which issues would you like me to fix? (Enter numbers separated by commas, or 'all' for everything)\"\n   - Wait for user confirmation\n\n4. **Implement approved fixes**\n   - For each approved issue:\n     - Read the relevant file(s)\n     - Implement the suggested fix\n     - Log what was changed\n\n5. **Validate changes**\n   - Run: `pnpm typecheck`\n   - If fails: review errors, fix them, retry\n   - Run: `pnpm lint`\n   - If fails: review errors, fix them, retry\n   - Continue until both pass\n\n6. **Commit and push**\n   - Stage changes: `git add .`\n   - Create commit: `git commit -m \"fix: address review comments from PR #$ARGUMENTS\"`\n   - Push: `git push`\n   - Confirm completion with summary of fixes applied\n\nNotes:\n- If no review comments found, inform user and exit\n- If typecheck/lint fails after fixes, show errors and ask for guidance\n- Keep fixes focused on reviewers' specific suggestions\n- Preserve existing code style and patterns\n- Group related fixes in the commit message if many changes\n- Treat all reviewers equally - human and bot feedback both matter\n\nYou previously got all the PR comments in a temporary JSON file and then ran something like this;\n\ncat > /tmp/parse_comments.js << 'EOF'\nconst fs = require('fs');\nconst comments = JSON.parse(fs.readFileSync('/tmp/all-pr-comments.json', 'utf8'));\n\nconst byFile = {};\nconst bySeverity = {\n  critical: [],\n  important: [],\n  suggestion: [],\n  info: []\n};\n\ncomments.forEach((c, idx) => {\n  const file = c.path;\n  const author = c.user.login;\n  const line = c.line || c.original_line || 'N/A';\n  const body = c.body;\n  \n  if (!byFile[file]) byFile[file] = [];\n  \n  const comment = {\n    num: idx + 1,\n    author,\n    line,\n    body: body.substring(0, 200) + (body.length > 200 ? '...' : ''),\n    fullBody: body\n  };\n  \n  byFile[file].push(comment);\n  \n  // Categorize by severity\n  const lower = body.toLowerCase();\n  if (lower.includes('critical') || lower.includes('security') || lower.includes('bug:')) {\n    bySeverity.critical.push({...comment, file});\n  } else if (lower.includes('important') || lower.includes('error') || lower.includes('fail')) {\n    bySeverity.important.push({...comment, file});\n  } else if (lower.includes('suggestion') || lower.includes('consider') || lower.includes('recommend')) {\n    bySeverity.suggestion.push({...comment, file});\n  } else {\n    bySeverity.info.push({...comment, file});\n  }\n});\n\nconsole.log('\\n=== SUMMARY BY SEVERITY ===\\n');\nconsole.log(`🚨 Critical: ${bySeverity.critical.length}`);\nconsole.log(`⚠️  Important: ${bySeverity.important.length}`);\nconsole.log(`💡 Suggestion: ${bySeverity.suggestion.length}`);\nconsole.log(`ℹ️  Info: ${bySeverity.info.length}`);\n\nconsole.log('\\n=== SUMMARY BY FILE ===\\n');\nObject.entries(byFile)\n  .sort((a, b) => b[1].length - a[1].length)\n  .forEach(([file, comments]) => {\n    console.log(`${file}: ${comments.length} comments`);\n  });\n\nconsole.log('\\n=== CRITICAL ISSUES ===\\n');\nbySeverity.critical.forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\n\nconsole.log('\\n=== IMPORTANT ISSUES ===\\n');\nbySeverity.important.slice(0, 10).forEach(c => {\n  console.log(`\\n#${c.num} [${c.author}] ${c.file}:${c.line}`);\n  console.log(c.body);\n});\nEOF\nnode /tmp/parse_comments.js\n\nAnd got a nice report you could act on.","isInternal":false,"tokens":1150,"sizeBytes":4583},{"name":"goham.md","path":".cursor/commands/goham.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/commands/goham.md","title":"Command: /goham","category":"command-prompt","format":"markdown","content":"# Start Working with Hamster Brief\n\nEnd-to-end workflow for working on tasks from a connected Hamster brief. All tasks from the brief are worked on in a single branch, with one PR created at the end.\n\n## Step 1: Verify Connection & Authentication\n\n```bash\n# Check current context and authentication status\ntm context\n```\n\nIf not connected or authentication fails:\n- Get brief URL from user if not available\n- Connect: `tm context <brief url>`\n- Refresh token if needed: `tm auth refresh`\n\n## Step 2: List Available Tasks\n\n```bash\n# View all tasks from the brief\ntm list\n```\n\nReview the task list to understand what needs to be done. Note the total number of tasks.\n\n## Step 3: Initialize Git Branch for Brief\n\n```bash\n# Ensure you're on dev branch and pull latest\ngit checkout dev\ngit pull origin dev\n\n# Create a single branch for the entire brief (e.g., hamster-brief-YYYY-MM-DD or brief-specific name)\ngit checkout -b hamster-brief\n\n# Verify branch creation\ngit branch\n```\n\n**Note**: This branch will be used for ALL tasks in the brief. Do not create separate branches per task.\n\n## Step 4: Task Loop (Repeat for Each Task)\n\nWork through all tasks sequentially in the same branch:\n\n### 4.1: Read Task Details\n\n```bash\n# Get detailed information about the task\ntm show 1\n\n# If task has subtasks, examine them all\ntm show 1,1.1,1.2,1.3  # Adjust IDs as needed\n```\n\n### 4.2: Log Initial Context\n\n```bash\n# Document task understanding and initial findings\ntm update-task -i 1 --append --prompt=\"Starting task implementation.\n\nInitial context:\n- Task requirements: [summarize key requirements]\n- Dependencies identified: [list any dependencies]\n- Files that may need modification: [list relevant files]\n- Approach planned: [brief implementation approach]\"\n```\n\n### 4.3: Mark Task as In-Progress\n\n```bash\n# Mark task and first subtask (if exists) as in-progress\ntm set-status -i 1,1.1 -s in-progress\n```\n\n### 4.4: Subtask Implementation Loop\n\nFor each subtask (1.1, 1.2, 1.3, etc.):\n\n#### 4.4.1: Read Subtask Details\n```bash\ntm show 1.1  # Replace with current subtask ID\n```\n\n#### 4.4.2: Log Research & Context Gathering\n```bash\n# Document findings during implementation\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Context gathered:\n\n- Code exploration findings: [what you discovered]\n- Implementation approach: [how you plan to implement]\n- Key decisions made: [important choices]\n- Challenges encountered: [any blockers or issues]\"\n```\n\n#### 4.4.3: Implement Subtask\n- Write code following the subtask requirements\n- Make necessary changes to files\n\n#### 4.4.4: Quality Verification\n```bash\n# Run linting\npnpm lint\n\n# Run type checking\npnpm typecheck\n\n# If either fails, fix issues and re-run until both pass\n```\n\n#### 4.4.5: CodeRabbit Review\n```bash\n# Generate code review (wait for plain text results)\ncoderabbit --prompt-only\n\n# Review the output and address any critical issues if needed\n```\n\n#### 4.4.6: Log Implementation Completion\n```bash\n# Document what was completed\ntm update-task -i 1 --append --prompt=\"Subtask 1.1 - Implementation complete:\n\n- Files modified: [list files changed]\n- Key changes: [summary of implementation]\n- CodeRabbit feedback addressed: [if any issues were fixed]\n- Ready for commit\"\n```\n\n#### 4.4.7: Commit Subtask Work\n```bash\n# Stage changes\ngit add .\n\n# Commit with detailed message following git_workflow.mdc format\ngit commit -m \"feat(task-1): Complete subtask 1.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Files modified: [list files]\n- CodeRabbit review completed\n\nSubtask 1.1: [Brief description of what was accomplished]\nRelates to Task 1: [Main task title]\"\n```\n\n#### 4.4.8: Mark Subtask as Done\n```bash\ntm set-status -i 1.1 -s done\n```\n\n#### 4.4.9: Move to Next Subtask\nRepeat steps 4.4.1 through 4.4.8 for the next subtask (1.2, 1.3, etc.)\n\n### 4.5: Complete Parent Task\n\nAfter all subtasks are complete:\n\n#### 4.5.1: Final Quality Checks\n```bash\n# Final linting\npnpm lint\n\n# Final type checking\npnpm typecheck\n\n# Final CodeRabbit review\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n#### 4.5.2: Log Task Completion\n```bash\n# Document final task completion\ntm update-task -i 1 --append --prompt=\"Task 1 - Complete:\n\n- All subtasks completed: [list all subtasks]\n- Final verification passed: lint, typecheck, CodeRabbit review\n- Files changed: [comprehensive list]\n- Committed to brief branch\"\n```\n\n#### 4.5.3: Mark Parent Task as Done\n```bash\ntm set-status -i 1 -s done\n```\n\n**Note**: Do NOT push or create PR yet. Continue to next task in the same branch.\n\n### 4.6: Move to Next Task\n\n```bash\n# Verify remaining tasks\ntm list\n\n# Continue with next task (e.g., Task 2)\n# Repeat steps 4.1 through 4.5 for Task 2, then Task 3, etc.\n```\n\n## Step 5: Complete All Tasks\n\nContinue working through all tasks (Steps 4.1-4.6) until all tasks in the brief are complete. All work is committed to the same `hamster-brief` branch.\n\n## Step 6: Final Verification & PR Creation\n\nAfter ALL tasks are complete:\n\n### 6.1: Verify All Tasks Complete\n```bash\n# Verify all tasks are done\ntm list\n\n# Should show all tasks with status 'done'\n```\n\n### 6.2: Final Quality Checks\n```bash\n# Final comprehensive checks\npnpm lint\npnpm typecheck\ncoderabbit --prompt-only\n\n# Address any remaining issues if critical\n```\n\n### 6.3: Push Branch\n```bash\n# Push the brief branch to remote\ngit push origin hamster-brief\n```\n\n### 6.4: Create Pull Request to Dev\n```bash\n# Get all task titles (adjust task IDs as needed)\n# Create comprehensive PR description\n\ngh pr create \\\n  --base dev \\\n  --title \"Hamster Brief: Complete Implementation\" \\\n  --body \"## Brief Overview\nCompleted all tasks from Hamster brief.\n\n## Tasks Completed\n- [x] Task 1: [Task 1 title]\n  - Subtasks: 1.1, 1.2, 1.3\n- [x] Task 2: [Task 2 title]\n  - Subtasks: 2.1, 2.2\n- [x] Task 3: [Task 3 title]\n  - [Continue listing all tasks]\n\n## Implementation Summary\n- Total tasks: [number]\n- Total subtasks: [number]\n- Files modified: [comprehensive list]\n- All quality checks passed\n\n## Quality Checks\n- ✅ Linting passed (pnpm lint)\n- ✅ Type checking passed (pnpm typecheck)\n- ✅ CodeRabbit review completed for all changes\n\n## Testing\n- [ ] Manual testing completed\n- [ ] All checks passing\n\nComplete implementation of Hamster brief tasks\"\n```\n\n## Step 7: Cleanup\n\n```bash\n# After PR is merged, switch back to dev\ngit checkout dev\ngit pull origin dev\n\n# Delete local branch (optional)\ngit branch -d hamster-brief\n```\n\n## Important Notes\n\n- **Use ONLY**: `tm list`, `tm show <id>`, `tm set-status`, `tm update-task`, `tm auth refresh`, `tm context <brief url>`\n- **DON'T use MCP tools** - not compatible with Hamster integration\n- **Single branch per brief**: All tasks work in the same branch (`hamster-brief`)\n- **Single PR per brief**: One PR created after all tasks are complete\n- **Always target dev branch** - never main branch\n- **Regular logging**: Use `tm update-task -i <id> --append` frequently to document:\n  - Context gathered during exploration\n  - Implementation decisions made\n  - Challenges encountered\n  - Completion status\n- **Quality gates**: Never skip lint, typecheck, or CodeRabbit review\n- **Commit format**: Follow git_workflow.mdc commit message standards\n- **PR format**: Always use `--base dev` when creating PRs\n\n## Workflow Summary\n\n```\n1. Verify connection → tm context\n2. List tasks → tm list\n3. Create single branch → git checkout -b hamster-brief\n4. For each task (in same branch):\n   a. Read task → tm show X\n   b. Log context → tm update-task -i X --append\n   c. Mark in-progress → tm set-status -i X,X.Y -s in-progress\n   d. For each subtask:\n      - Read → tm show X.Y\n      - Log context → tm update-task -i X --append\n      - Implement code\n      - Verify → pnpm lint && pnpm typecheck\n      - Review → coderabbit --prompt-only\n      - Log completion → tm update-task -i X --append\n      - Commit → git commit (following git_workflow.mdc format)\n      - Mark done → tm set-status -i X.Y -s done\n   e. Final checks → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   f. Log completion → tm update-task -i X --append\n   g. Mark task done → tm set-status -i X -s done\n   h. Continue to next task (same branch)\n5. After ALL tasks complete:\n   a. Final verification → pnpm lint && pnpm typecheck && coderabbit --prompt-only\n   b. Push branch → git push origin hamster-brief\n   c. Create PR → gh pr create --base dev\n```\n\n## References\n\n- Full guidelines: [hamster.mdc](mdc:.cursor/rules/hamster.mdc)\n- Git workflow: [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc)\n","isInternal":false,"tokens":2327,"sizeBytes":8589},{"name":"sync-readme.md","path":"packages/claude-code-plugin/commands/sync-readme.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/claude-code-plugin/commands/sync-readme.md","title":"Command: /sync-readme","category":"command-prompt","format":"markdown","content":"Export tasks to README.md with professional formatting.\n\nArguments: $ARGUMENTS\n\nGenerate a well-formatted README with current task information.\n\n## README Synchronization\n\nCreates or updates README.md with beautifully formatted task information.\n\n## Argument Parsing\n\nOptional filters:\n- \"pending\" → Only pending tasks\n- \"with-subtasks\" → Include subtask details\n- \"by-priority\" → Group by priority\n- \"sprint\" → Current sprint only\n\n## Execution\n\n```bash\ntask-master sync-readme [--with-subtasks] [--status=<status>]\n```\n\n## README Generation\n\n### 1. **Project Header**\n```markdown\n# Project Name\n\n## 📋 Task Progress\n\nLast Updated: 2024-01-15 10:30 AM\n\n### Summary\n- Total Tasks: 45\n- Completed: 15 (33%)\n- In Progress: 5 (11%)\n- Pending: 25 (56%)\n```\n\n### 2. **Task Sections**\nOrganized by status or priority:\n- Progress indicators\n- Task descriptions\n- Dependencies noted\n- Time estimates\n\n### 3. **Visual Elements**\n- Progress bars\n- Status badges\n- Priority indicators\n- Completion checkmarks\n\n## Smart Features\n\n1. **Intelligent Grouping**\n   - By feature area\n   - By sprint/milestone\n   - By assigned developer\n   - By priority\n\n2. **Progress Tracking**\n   - Overall completion\n   - Sprint velocity\n   - Burndown indication\n   - Time tracking\n\n3. **Formatting Options**\n   - GitHub-flavored markdown\n   - Task checkboxes\n   - Collapsible sections\n   - Table format available\n\n## Example Output\n\n```markdown\n## 🚀 Current Sprint\n\n### In Progress\n- [ ] 🔄 #5 **Implement user authentication** (60% complete)\n  - Dependencies: API design (#3 ✅)\n  - Subtasks: 4 (2 completed)\n  - Est: 8h / Spent: 5h\n\n### Pending (High Priority)\n- [ ] ⚡ #8 **Create dashboard UI**\n  - Blocked by: #5\n  - Complexity: High\n  - Est: 12h\n```\n\n## Customization\n\nBased on arguments:\n- Include/exclude sections\n- Detail level control\n- Custom grouping\n- Filter by criteria\n\n## Post-Sync\n\nAfter generation:\n1. Show diff preview\n2. Backup existing README\n3. Write new content\n4. Commit reminder\n5. Update timestamp\n\n## Integration\n\nWorks well with:\n- Git workflows\n- CI/CD pipelines\n- Project documentation\n- Team updates\n- Client reports","isInternal":false,"tokens":555,"sizeBytes":2134},{"name":"README.md","path":"tests/unit/scripts/modules/commands/README.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/tests/unit/scripts/modules/commands/README.md","title":"Command: /readme","category":"command-prompt","format":"markdown","content":"# Mock System Documentation\n\n## Overview\n\nThe `move-cross-tag.test.js` file has been refactored to use a focused, maintainable mock system that addresses the brittleness and complexity of the original implementation.\n\n## Key Improvements\n\n### 1. **Focused Mocking**\n\n- **Before**: Mocked 20+ modules, many irrelevant to cross-tag functionality\n- **After**: Only mocks 5 core modules actually used in cross-tag moves\n\n### 2. **Configuration-Driven Mocking**\n\n```javascript\nconst mockConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true,\n    initTaskMaster: true,\n    findProjectRoot: true\n  }\n};\n```\n\n### 3. **Reusable Mock Factory**\n\n```javascript\nfunction createMockFactory(config = mockConfig) {\n  const mocks = {};\n  \n  if (config.core?.moveTasksBetweenTags) {\n    mocks.moveTasksBetweenTags = createMock('moveTasksBetweenTags');\n  }\n  // ... other mocks\n  \n  return mocks;\n}\n```\n\n## Mock Configuration\n\n### Core Mocks (Required for Cross-Tag Functionality)\n\n- `moveTasksBetweenTags`: Core move functionality\n- `generateTaskFiles`: File generation after moves\n- `readJSON`: Reading task data\n- `initTaskMaster`: TaskMaster initialization\n- `findProjectRoot`: Project path resolution\n\n### Optional Mocks\n\n- Console methods: `error`, `log`, `exit`\n- TaskMaster instance methods: `getCurrentTag`, `getTasksPath`, `getProjectRoot`\n\n## Usage Examples\n\n### Default Configuration\n\n```javascript\nconst mocks = setupMocks(); // Uses default mockConfig\n```\n\n### Minimal Configuration\n\n```javascript\nconst minimalConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: true,\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(minimalConfig);\n```\n\n### Selective Mocking\n\n```javascript\nconst selectiveConfig = {\n  core: {\n    moveTasksBetweenTags: true,\n    generateTaskFiles: false, // Disabled\n    readJSON: true\n  }\n};\nconst mocks = setupMocks(selectiveConfig);\n```\n\n## Benefits\n\n1. **Reduced Complexity**: From 150+ lines of mock setup to 50 lines\n2. **Better Maintainability**: Clear configuration object shows dependencies\n3. **Focused Testing**: Only mocks what's actually used\n4. **Flexible Configuration**: Easy to enable/disable specific mocks\n5. **Consistent Naming**: All mocks use `createMock()` with descriptive names\n\n## Migration Guide\n\n### For Other Test Files\n\n1. Identify actual module dependencies\n2. Create configuration object for required mocks\n3. Use `createMockFactory()` and `setupMocks()`\n4. Remove unnecessary mocks\n\n### Example Migration\n\n```javascript\n// Before: 20+ jest.mock() calls\njest.mock('module1', () => ({ ... }));\njest.mock('module2', () => ({ ... }));\n// ... many more\n\n// After: Configuration-driven\nconst mockConfig = {\n  core: {\n    requiredFunction1: true,\n    requiredFunction2: true\n  }\n};\nconst mocks = setupMocks(mockConfig);\n```\n\n## Testing the Mock System\n\nThe test suite includes validation tests:\n\n- `should work with minimal mock configuration`\n- `should allow disabling specific mocks`\n\nThese ensure the mock factory works correctly and can be configured flexibly.\n","isInternal":false,"tokens":721,"sizeBytes":3078},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"{\n\t\"mcpServers\": {\n\t\t\"task-master-ai\": {\n\t\t\t\"command\": \"node\",\n\t\t\t\"args\": [\"./dist/mcp-server.js\"],\n\t\t\t\"env\": {\n\t\t\t\t\"ANTHROPIC_API_KEY\": \"ANTHROPIC_API_KEY_HERE\",\n\t\t\t\t\"PERPLEXITY_API_KEY\": \"PERPLEXITY_API_KEY_HERE\",\n\t\t\t\t\"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n\t\t\t\t\"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n\t\t\t\t\"GROQ_API_KEY\": \"GROQ_API_KEY_HERE\",\n\t\t\t\t\"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n\t\t\t\t\"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n\t\t\t\t\"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n\t\t\t\t\"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n\t\t\t\t\"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\",\n\t\t\t\t\"GITHUB_API_KEY\": \"GITHUB_API_KEY_HERE\"\n\t\t\t}\n\t\t}\n\t}\n}\n","frontmatter":{"mcpServers":{"task-master-ai":{"command":"node","args":["./dist/mcp-server.js"],"env":{"ANTHROPIC_API_KEY":"ANTHROPIC_API_KEY_HERE","PERPLEXITY_API_KEY":"PERPLEXITY_API_KEY_HERE","OPENAI_API_KEY":"OPENAI_API_KEY_HERE","GOOGLE_API_KEY":"GOOGLE_API_KEY_HERE","GROQ_API_KEY":"GROQ_API_KEY_HERE","XAI_API_KEY":"XAI_API_KEY_HERE","OPENROUTER_API_KEY":"OPENROUTER_API_KEY_HERE","MISTRAL_API_KEY":"MISTRAL_API_KEY_HERE","AZURE_OPENAI_API_KEY":"AZURE_OPENAI_API_KEY_HERE","OLLAMA_API_KEY":"OLLAMA_API_KEY_HERE","GITHUB_API_KEY":"GITHUB_API_KEY_HERE"}}}},"isInternal":false,"tokens":231,"sizeBytes":646},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/.claude-plugin/marketplace.json","title":"taskmaster","category":"marketplace","format":"json","content":"{\n\t\"name\": \"taskmaster\",\n\t\"owner\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"email\": \"ralph@tryhamster.com\"\n\t},\n\t\"metadata\": {\n\t\t\"description\": \"Official marketplace for Taskmaster AI - AI-powered task management for ambitious development\",\n\t\t\"version\": \"1.0.0\"\n\t},\n\t\"plugins\": [\n\t\t{\n\t\t\t\"name\": \"taskmaster\",\n\t\t\t\"source\": \"./packages/claude-code-plugin\",\n\t\t\t\"description\": \"AI-powered task management system for ambitious development workflows with intelligent orchestration, complexity analysis, and automated coordination\",\n\t\t\t\"author\": {\n\t\t\t\t\"name\": \"Hamster\"\n\t\t\t},\n\t\t\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\t\t\"keywords\": [\n\t\t\t\t\"task-management\",\n\t\t\t\t\"ai\",\n\t\t\t\t\"workflow\",\n\t\t\t\t\"orchestration\",\n\t\t\t\t\"automation\",\n\t\t\t\t\"mcp\"\n\t\t\t],\n\t\t\t\"category\": \"productivity\"\n\t\t}\n\t]\n}\n","frontmatter":{"name":"taskmaster","owner":{"name":"Hamster","email":"ralph@tryhamster.com"},"metadata":{"description":"Official marketplace for Taskmaster AI - AI-powered task management for ambitious development","version":"1.0.0"},"plugins":[{"name":"taskmaster","source":"./packages/claude-code-plugin","description":"AI-powered task management system for ambitious development workflows with intelligent orchestration, complexity analysis, and automated coordination","author":{"name":"Hamster"},"homepage":"https://github.com/eyaltoledano/claude-task-master","repository":"https://github.com/eyaltoledano/claude-task-master","keywords":["task-management","ai","workflow","orchestration","automation","mcp"],"category":"productivity"}]},"isInternal":false,"tokens":247,"sizeBytes":853},{"name":"README.md","path":"packages/ai-sdk-provider-grok-cli/README.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/ai-sdk-provider-grok-cli/README.md","title":"ai-sdk-provider-grok-cli Documentation","category":"plugin-manifest","format":"markdown","content":"# AI SDK Provider for Grok CLI\n\nA provider for the [AI SDK](https://sdk.vercel.ai) that integrates with [Grok CLI](https://docs.x.ai/api) for accessing xAI's Grok language models.\n\n## Features\n\n- ✅ **AI SDK v5 Compatible** - Full support for the latest AI SDK interfaces\n- ✅ **Streaming & Non-streaming** - Both generation modes supported\n- ✅ **Error Handling** - Comprehensive error handling with retry logic\n- ✅ **Type Safety** - Full TypeScript support with proper type definitions\n- ✅ **JSON Mode** - Automatic JSON extraction from responses\n- ✅ **Abort Signals** - Proper cancellation support\n\n## Installation\n\n```bash\nnpm install @tm/ai-sdk-provider-grok-cli\n# or\nyarn add @tm/ai-sdk-provider-grok-cli\n```\n\n## Prerequisites\n\n1. Install the Grok CLI:\n\n   ```bash\n   npm install -g grok-cli\n   # or follow xAI's installation instructions\n   ```\n\n2. Set up authentication:\n\n   ```bash\n   export GROK_CLI_API_KEY=\"your-api-key\"\n   # or configure via grok CLI: grok config set api-key your-key\n   ```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: grokCli('grok-3-latest'),\n  prompt: 'Write a haiku about TypeScript'\n});\n\nconsole.log(result.text);\n```\n\n### Streaming\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { streamText } from 'ai';\n\nconst { textStream } = await streamText({\n  model: grokCli('grok-4-latest'),\n  prompt: 'Explain quantum computing'\n});\n\nfor await (const delta of textStream) {\n  process.stdout.write(delta);\n}\n```\n\n### JSON Mode\n\n```typescript\nimport { grokCli } from '@tm/ai-sdk-provider-grok-cli';\nimport { generateObject } from 'ai';\nimport { z } from 'zod';\n\nconst result = await generateObject({\n  model: grokCli('grok-3-latest'),\n  schema: z.object({\n    name: z.string(),\n    age: z.number(),\n    hobbies: z.array(z.string())\n  }),\n  prompt: 'Generate a person profile'\n});\n\nconsole.log(result.object);\n```\n\n## Supported Models\n\n- `grok-3-latest` - Grok 3 (latest version)\n- `grok-4-latest` - Grok 4 (latest version)\n- `grok-4` - Grok 4 (stable)\n- Custom model strings supported\n\n## Configuration\n\n### Provider Settings\n\n```typescript\nimport { createGrokCli } from '@tm/ai-sdk-provider-grok-cli';\n\nconst grok = createGrokCli({\n  apiKey: 'your-api-key', // Optional if set via env/CLI\n  timeout: 120000, // 2 minutes default\n  workingDirectory: '/path/to/project', // Optional\n  baseURL: 'https://api.x.ai' // Optional\n});\n```\n\n### Model Settings\n\n```typescript\nconst model = grok('grok-4-latest', {\n  timeout: 300000, // 5 minutes for grok-4\n  // Other CLI-specific settings\n});\n```\n\n## Error Handling\n\nThe provider includes comprehensive error handling:\n\n```typescript\nimport {\n  isAuthenticationError,\n  isTimeoutError,\n  isInstallationError\n} from '@tm/ai-sdk-provider-grok-cli';\n\ntry {\n  const result = await generateText({\n    model: grokCli('grok-4-latest'),\n    prompt: 'Hello!'\n  });\n} catch (error) {\n  if (isAuthenticationError(error)) {\n    console.error('Authentication failed:', error.message);\n  } else if (isTimeoutError(error)) {\n    console.error('Request timed out:', error.message);\n  } else if (isInstallationError(error)) {\n    console.error('Grok CLI not installed or not found in PATH');\n  }\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start development mode (keep running during development)\nnpm run dev\n\n# Type check\nnpm run typecheck\n\n# Run tests (requires build first)\nNODE_ENV=production npm run build\nnpm test\n```\n\n**Important**: Always run `npm run dev` and keep it running during development. This ensures proper compilation and hot-reloading of TypeScript files.\n","isInternal":false,"tokens":975,"sizeBytes":3727},{"name":"plugin.json","path":"packages/claude-code-plugin/.claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/claude-code-plugin/.claude-plugin/plugin.json","title":"taskmaster","category":"plugin-manifest","format":"json","content":"{\n\t\"name\": \"taskmaster\",\n\t\"description\": \"A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.\",\n\t\"author\": {\n\t\t\"name\": \"Hamster\",\n\t\t\"url\": \"https://github.com/eyaltoledano/claude-task-master\"\n\t},\n\t\"homepage\": \"https://github.com/eyaltoledano/claude-task-master#readme\",\n\t\"repository\": \"https://github.com/eyaltoledano/claude-task-master\",\n\t\"license\": \"MIT WITH Commons-Clause\",\n\t\"keywords\": [\n\t\t\"task-management\",\n\t\t\"ai\",\n\t\t\"workflow\",\n\t\t\"orchestration\",\n\t\t\"automation\",\n\t\t\"mcp\",\n\t\t\"development\",\n\t\t\"productivity\"\n\t]\n}\n","frontmatter":{"name":"taskmaster","description":"A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.","author":{"name":"Hamster","url":"https://github.com/eyaltoledano/claude-task-master"},"homepage":"https://github.com/eyaltoledano/claude-task-master#readme","repository":"https://github.com/eyaltoledano/claude-task-master","license":"MIT WITH Commons-Clause","keywords":["task-management","ai","workflow","orchestration","automation","mcp","development","productivity"]},"isInternal":false,"tokens":170,"sizeBytes":571},{"name":"README.md","path":"packages/tm-bridge/README.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/tm-bridge/README.md","title":"tm-bridge Documentation","category":"plugin-manifest","format":"markdown","content":"# @tm/bridge\n\n> ⚠️ **TEMPORARY PACKAGE - DELETE WHEN LEGACY CODE IS REMOVED** ⚠️\n\nThis package exists solely as a bridge between legacy scripts (`scripts/modules/task-manager/`) and the new tm-core architecture. It provides shared functionality that both CLI and MCP direct functions can use during the migration period.\n\n## Why does this exist?\n\nDuring the transition from legacy scripts to tm-core, we need a single source of truth for bridge logic that handles:\n- API vs file storage detection\n- Remote AI service delegation\n- Consistent behavior across CLI and MCP interfaces\n\n## When to delete this\n\nDelete this entire package when:\n1. ✅ Legacy scripts in `scripts/modules/task-manager/` are removed\n2. ✅ MCP direct functions in `mcp-server/src/core/direct-functions/` are removed\n3. ✅ All functionality has moved to tm-core\n4. ✅ CLI and MCP use tm-core directly via TasksDomain\n\n## Migration path\n\n```text\nCurrent:   CLI → legacy scripts → @tm/bridge → @tm/core\n          MCP → direct functions → legacy scripts → @tm/bridge → @tm/core\n\nFuture:    CLI → @tm/core (TasksDomain)\n          MCP → @tm/core (TasksDomain)\n\nDELETE:    legacy scripts, direct functions, @tm/bridge\n```\n\n## Usage\n\n```typescript\nimport { tryUpdateViaRemote } from '@tm/bridge';\n\nconst result = await tryUpdateViaRemote({\n  taskId: '1.2',\n  prompt: 'Update task...',\n  projectRoot: '/path/to/project',\n  // ... other params\n});\n```\n\n## Contents\n\n- `update-bridge.ts` - Shared update bridge logic for task/subtask updates\n\n---\n\n**Remember:** This package should NOT accumulate new features. It's a temporary migration aid only.\n","isInternal":false,"tokens":386,"sizeBytes":1639},{"name":"README.md","path":"packages/tm-core/README.md","rawUrl":"https://raw.githubusercontent.com/eyaltoledano/claude-task-master/HEAD/packages/tm-core/README.md","title":"tm-core Documentation","category":"plugin-manifest","format":"markdown","content":"# @task-master/tm-core\n\nCore library for Task Master AI - providing task management and orchestration capabilities with TypeScript support.\n\n## Overview\n\n`tm-core` is the foundational library that powers Task Master AI's task management system. It provides a comprehensive set of tools for creating, managing, and orchestrating tasks with AI integration.\n\n## Features\n\n- **TypeScript-first**: Built with full TypeScript support and strict type checking\n- **Dual Format**: Supports both ESM and CommonJS with automatic format detection\n- **Modular Architecture**: Clean separation of concerns with dedicated modules for different functionality\n- **AI Provider Integration**: Pluggable AI provider system for task generation and management\n- **Flexible Storage**: Abstracted storage layer supporting different persistence strategies\n- **Task Parsing**: Advanced parsing capabilities for various task definition formats\n- **Error Handling**: Comprehensive error system with specific error types\n- **Testing**: Complete test coverage with Jest and TypeScript support\n\n## Installation\n\n```bash\nnpm install @task-master/tm-core\n```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { generateTaskId, PlaceholderTask } from '@task-master/tm-core';\n\n// Generate a unique task ID\nconst taskId = generateTaskId();\n\n// Create a task (coming soon - full implementation)\nconst task: PlaceholderTask = {\n  id: taskId,\n  title: 'My Task',\n  status: 'pending',\n  priority: 'medium'\n};\n```\n\n### Modular Imports\n\nYou can import specific modules to reduce bundle size:\n\n```typescript\n// Import types only\nimport type { TaskId, TaskStatus } from '@task-master/tm-core/types';\n\n// Import utilities\nimport { generateTaskId, formatDate } from '@task-master/tm-core/utils';\n\n// Import providers (AI providers coming soon)\n// import { AIProvider } from '@task-master/tm-core/providers';\n\n// Import storage\nimport { PlaceholderStorage } from '@task-master/tm-core/storage';\n\n// Import parsers\nimport { PlaceholderParser } from '@task-master/tm-core/parser';\n\n// Import errors\nimport { TmCoreError, TaskNotFoundError } from '@task-master/tm-core/errors';\n```\n\n## Architecture\n\nThe library is organized into several key modules:\n\n- **types/**: TypeScript type definitions and interfaces\n- **providers/**: AI provider implementations for task generation\n- **storage/**: Storage adapters for different persistence strategies\n- **parser/**: Task parsing utilities for various formats\n- **utils/**: Common utility functions and helpers\n- **errors/**: Custom error classes and error handling\n\n## Development\n\n### Prerequisites\n\n- Node.js >= 20.0.0\n- npm or yarn\n\n### Setup\n\n```bash\n# Install dependencies\nnpm install\n\n# Build the library\nnpm run build\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Lint code\nnpm run lint\n\n# Format code\nnpm run format\n```\n\n### Scripts\n\n- `build`: Build the library for both ESM and CJS formats\n- `build:watch`: Build in watch mode for development\n- `test`: Run the test suite\n- `test:watch`: Run tests in watch mode\n- `test:coverage`: Run tests with coverage reporting\n- `lint`: Lint TypeScript files\n- `lint:fix`: Lint and auto-fix issues\n- `format`: Format code with Prettier\n- `format:check`: Check code formatting\n- `typecheck`: Type-check without emitting files\n- `clean`: Clean build artifacts\n- `dev`: Development mode with watch\n\n## ESM and CommonJS Support\n\nThis package supports both ESM and CommonJS formats automatically:\n\n```javascript\n// ESM\nimport { generateTaskId } from '@task-master/tm-core';\n\n// CommonJS\nconst { generateTaskId } = require('@task-master/tm-core');\n```\n\n## Roadmap\n\nThis is the initial package structure. The following features are planned for implementation:\n\n### Task 116: TypeScript Types\n- [ ] Complete type definitions for tasks, projects, and configurations\n- [ ] Zod schema validation\n- [ ] Generic type utilities\n\n### Task 117: AI Provider System\n- [ ] Base provider interface\n- [ ] Anthropic Claude integration\n- [ ] OpenAI integration\n- [ ] Perplexity integration\n- [ ] Provider factory and registry\n\n### Task 118: Storage Layer\n- [ ] File system storage adapter\n- [ ] Memory storage adapter\n- [ ] Storage interface and factory\n\n### Task 119: Task Parser\n- [ ] PRD parser implementation\n- [ ] Markdown parser\n- [ ] JSON task format parser\n- [ ] Validation utilities\n\n### Task 120: Utility Functions\n- [ ] Task ID generation\n- [ ] Date formatting\n- [ ] Validation helpers\n- [ ] File system utilities\n\n### Task 121: Error Handling\n- [ ] Task-specific errors\n- [ ] Storage errors\n- [ ] Provider errors\n- [ ] Validation errors\n\n### Task 122: Configuration System\n- [ ] Configuration schema\n- [ ] Default configurations\n- [ ] Environment variable support\n\n### Task 123: Testing Infrastructure\n- [ ] Unit test coverage\n- [ ] Integration tests\n- [ ] Mock utilities\n\n### Task 124: Documentation\n- [ ] API documentation\n- [ ] Usage examples\n- [ ] Migration guides\n\n### Task 125: Package Finalization\n- [ ] Final testing and validation\n- [ ] Release preparation\n- [ ] CI/CD integration\n\n## Implementation Checklist\n\n### ✅ Task 115: Initialize tm-core Package Structure (COMPLETED)\n- [x] Create tm-core directory structure and base configuration files\n- [x] Configure build and test infrastructure \n- [x] Create barrel export files for all directories\n- [x] Add development tooling and documentation\n- [x] Validate package structure and prepare for development\n\n### 🚧 Remaining Implementation Tasks\n- [ ] **Task 116**: TypeScript Types - Complete type definitions for tasks, projects, and configurations\n- [ ] **Task 117**: AI Provider System - Base provider interface and integrations\n- [ ] **Task 118**: Storage Layer - File system and memory storage adapters\n- [ ] **Task 119**: Task Parser - PRD, Markdown, and JSON parsers\n- [ ] **Task 120**: Utility Functions - Task ID generation, validation helpers\n- [ ] **Task 121**: Error Handling - Task-specific and validation errors\n- [ ] **Task 122**: Configuration System - Schema and environment support\n- [ ] **Task 123**: Testing Infrastructure - Complete unit and integration tests\n- [ ] **Task 124**: Documentation - API docs and usage examples\n- [ ] **Task 125**: Package Finalization - Release preparation and CI/CD\n\n## Contributing\n\nThis package is part of the Task Master AI project. Please refer to the main project's contributing guidelines.\n\n## License\n\nMIT - See the main project's LICENSE file for details.\n\n## Support\n\nFor questions and support, please refer to the main Task Master AI documentation.","isInternal":false,"tokens":1478,"sizeBytes":6530}],"systemPromptSnippet":"<yakaai_skills repo=\"eyaltoledano/claude-task-master\">\n<!-- File: assets/AGENTS.md (Tokens: ~3510 | Category: root-instruction) -->\n# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\ntask-master generate                                         # Update task markdown files (usually auto-called)\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nDefault: `core` (7 tools). Set via `TASK_MASTER_TOOLS` env var.\n\n| Tier | Count | Tools |\n|------|-------|-------|\n| `core` | 7 | `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task` |\n| `standard` | 14 | core + `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report` |\n| `all` | 44+ | standard + dependencies, tags, research, autopilot, scoping, models, rules |\n\n**Upgrade when tool unavailable:** Edit MCP config, change `TASK_MASTER_TOOLS` from `\"core\"` to `\"standard\"` or `\"all\"`, restart MCP.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Regenerate task files from tasks.json\ntask-master generate\n\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n- Task markdown files in `tasks/` are auto-generated\n- Run `task-master generate` after manual changes to tasks.json\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n\n<!-- File: .taskmaster/CLAUDE.md (Tokens: ~3495 | Category: claude-rule) -->\n# Task Master AI - Agent Integration Guide\n\n## Essential Commands\n\n### Core Workflow Commands\n\n```bash\n# Project Setup\ntask-master init                                    # Initialize Task Master in current project\ntask-master parse-prd .taskmaster/docs/prd.md       # Generate tasks from PRD document\ntask-master models --setup                        # Configure AI models interactively\n\n# Daily Development Workflow\ntask-master list                                   # Show all tasks with status\ntask-master next                                   # Get next available task to work on\ntask-master show <id>                             # View detailed task information (e.g., task-master show 1.2)\ntask-master set-status --id=<id> --status=done    # Mark task complete\n\n# Task Management\ntask-master add-task --prompt=\"description\" --research        # Add new task with AI assistance\ntask-master expand --id=<id> --research --force              # Break task into subtasks\ntask-master update-task --id=<id> --prompt=\"changes\"         # Update specific task\ntask-master update --from=<id> --prompt=\"changes\"            # Update multiple tasks from ID onwards\ntask-master update-subtask --id=<id> --prompt=\"notes\"        # Add implementation notes to subtask\n\n# Analysis & Planning\ntask-master analyze-complexity --research          # Analyze task complexity\ntask-master complexity-report                      # View complexity analysis\ntask-master expand --all --research               # Expand all eligible tasks\n\n# Dependencies & Organization\ntask-master add-dependency --id=<id> --depends-on=<id>       # Add task dependency\ntask-master move --from=<id> --to=<id>                       # Reorganize task hierarchy\ntask-master validate-dependencies                            # Check for dependency issues\n```\n\n## Key Files & Project Structure\n\n### Core Files\n\n- `.taskmaster/tasks/tasks.json` - Main task data file (auto-managed)\n- `.taskmaster/config.json` - AI model configuration (use `task-master models` to modify)\n- `.taskmaster/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)\n- `.taskmaster/tasks/*.txt` - Individual task files (auto-generated from tasks.json)\n- `.env` - API keys for CLI usage\n\n**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:\n- Markdown syntax highlighting in editors improves readability\n- Proper rendering when previewing in VS Code, GitHub, or other tools\n- Better collaboration through formatted documentation\n\n### Claude Code Integration Files\n\n- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)\n- `.claude/settings.json` - Claude Code tool allowlist and preferences\n- `.claude/commands/` - Custom slash commands for repeated workflows\n- `.mcp.json` - MCP server configuration (project-specific)\n\n### Directory Structure\n\n```\nproject/\n├── .taskmaster/\n│   ├── tasks/              # Task files directory\n│   │   ├── tasks.json      # Main task database\n│   │   ├── task-1.md      # Individual task files\n│   │   └── task-2.md\n│   ├── docs/              # Documentation directory\n│   │   ├── prd.md         # Product requirements (.md recommended)\n│   ├── reports/           # Analysis reports directory\n│   │   └── task-complexity-report.json\n│   ├── templates/         # Template files\n│   │   └── example_prd.md  # Example PRD template (.md recommended)\n│   └── config.json        # AI models & settings\n├── .claude/\n│   ├── settings.json      # Claude Code configuration\n│   └── commands/         # Custom slash commands\n├── .env                  # API keys\n├── .mcp.json            # MCP configuration\n└── CLAUDE.md            # This file - auto-loaded by Claude Code\n```\n\n## MCP Integration\n\nTask Master provides an MCP server that Claude Code can connect to. Configure in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"task-master-ai\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"task-master-ai\"],\n      \"env\": {\n        \"TASK_MASTER_TOOLS\": \"core\",\n        \"ANTHROPIC_API_KEY\": \"your_key_here\",\n        \"PERPLEXITY_API_KEY\": \"your_key_here\",\n        \"OPENAI_API_KEY\": \"OPENAI_API_KEY_HERE\",\n        \"GOOGLE_API_KEY\": \"GOOGLE_API_KEY_HERE\",\n        \"XAI_API_KEY\": \"XAI_API_KEY_HERE\",\n        \"OPENROUTER_API_KEY\": \"OPENROUTER_API_KEY_HERE\",\n        \"MISTRAL_API_KEY\": \"MISTRAL_API_KEY_HERE\",\n        \"AZURE_OPENAI_API_KEY\": \"AZURE_OPENAI_API_KEY_HERE\",\n        \"OLLAMA_API_KEY\": \"OLLAMA_API_KEY_HERE\"\n      }\n    }\n  }\n}\n```\n\n### MCP Tool Tiers\n\nTask Master uses tiered tool loading to optimize context window usage:\n\n| Tier | Tools | Use Case |\n|------|-------|----------|\n| `core` | 7 | Minimal daily workflow tools (default) |\n| `standard` | 14 | Common task management |\n| `all` | 42+ | Full suite with research, autopilot, dependencies |\n\n**Core tools (7):** `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task`\n\n**Standard adds (7 more):** `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report`\n\n**All tier adds:** Dependency management, tag management, research, autopilot TDD workflow, scope up/down, models, rules\n\n**To upgrade tiers:** Change `TASK_MASTER_TOOLS` in `.mcp.json` from `\"core\"` to `\"standard\"` or `\"all\"` and restart the MCP connection.\n\n### Essential MCP Tools\n\n```javascript\nhelp; // = shows available taskmaster commands\n// Project setup\ninitialize_project; // = task-master init\nparse_prd; // = task-master parse-prd\n\n// Daily workflow\nget_tasks; // = task-master list\nnext_task; // = task-master next\nget_task; // = task-master show <id>\nset_task_status; // = task-master set-status\n\n// Task management\nadd_task; // = task-master add-task\nexpand_task; // = task-master expand\nupdate_task; // = task-master update-task\nupdate_subtask; // = task-master update-subtask\nupdate; // = task-master update\n\n// Analysis\nanalyze_project_complexity; // = task-master analyze-complexity\ncomplexity_report; // = task-master complexity-report\n```\n\n## Claude Code Workflow Integration\n\n### Standard Development Workflow\n\n#### 1. Project Initialization\n\n```bash\n# Initialize Task Master\ntask-master init\n\n# Create or obtain PRD, then parse it (use .md extension for better editor support)\ntask-master parse-prd .taskmaster/docs/prd.md\n\n# Analyze complexity and expand tasks\ntask-master analyze-complexity --research\ntask-master expand --all --research\n```\n\nIf tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..\n\n#### 2. Daily Development Loop\n\n```bash\n# Start each session\ntask-master next                           # Find next available task\ntask-master show <id>                     # Review task details\n\n# During implementation, check in code context into the tasks and subtasks\ntask-master update-subtask --id=<id> --prompt=\"implementation notes...\"\n\n# Complete tasks\ntask-master set-status --id=<id> --status=done\n```\n\n#### 3. Multi-Claude Workflows\n\nFor complex projects, use multiple Claude Code sessions:\n\n```bash\n# Terminal 1: Main implementation\ncd project && claude\n\n# Terminal 2: Testing and validation\ncd project-test-worktree && claude\n\n# Terminal 3: Documentation updates\ncd project-docs-worktree && claude\n```\n\n### Custom Slash Commands\n\nCreate `.claude/commands/taskmaster-next.md`:\n\n```markdown\nFind the next available Task Master task and show its details.\n\nSteps:\n\n1. Run `task-master next` to get the next task\n2. If a task is available, run `task-master show <id>` for full details\n3. Provide a summary of what needs to be implemented\n4. Suggest the first implementation step\n```\n\nCreate `.claude/commands/taskmaster-complete.md`:\n\n```markdown\nComplete a Task Master task: $ARGUMENTS\n\nSteps:\n\n1. Review the current task with `task-master show $ARGUMENTS`\n2. Verify all implementation is complete\n3. Run any tests related to this task\n4. Mark as complete: `task-master set-status --id=$ARGUMENTS --status=done`\n5. Show the next available task with `task-master next`\n```\n\n## Tool Allowlist Recommendations\n\nAdd to `.claude/settings.json`:\n\n```json\n{\n  \"allowedTools\": [\n    \"Edit\",\n    \"Bash(task-master *)\",\n    \"Bash(git commit:*)\",\n    \"Bash(git add:*)\",\n    \"Bash(npm run *)\",\n    \"mcp__task_master_ai__*\"\n  ]\n}\n```\n\n## Configuration & Setup\n\n### API Keys Required\n\nAt least **one** of these API keys must be configured:\n\n- `ANTHROPIC_API_KEY` (Claude models) - **Recommended**\n- `PERPLEXITY_API_KEY` (Research features) - **Highly recommended**\n- `OPENAI_API_KEY` (GPT models)\n- `GOOGLE_API_KEY` (Gemini models)\n- `MISTRAL_API_KEY` (Mistral models)\n- `OPENROUTER_API_KEY` (Multiple models)\n- `XAI_API_KEY` (Grok models)\n\nAn API key is required for any provider used across any of the 3 roles defined in the `models` command.\n\n### Model Configuration\n\n```bash\n# Interactive setup (recommended)\ntask-master models --setup\n\n# Set specific models\ntask-master models --set-main claude-3-5-sonnet-20241022\ntask-master models --set-research perplexity-llama-3.1-sonar-large-128k-online\ntask-master models --set-fallback gpt-4o-mini\n```\n\n## Task Structure & IDs\n\n### Task ID Format\n\n- Main tasks: `1`, `2`, `3`, etc.\n- Subtasks: `1.1`, `1.2`, `2.1`, etc.\n- Sub-subtasks: `1.1.1`, `1.1.2`, etc.\n\n### Task Status Values\n\n- `pending` - Ready to work on\n- `in-progress` - Currently being worked on\n- `done` - Completed and verified\n- `deferred` - Postponed\n- `cancelled` - No longer needed\n- `blocked` - Waiting on external factors\n\n### Task Fields\n\n```json\n{\n  \"id\": \"1.2\",\n  \"title\": \"Implement user authentication\",\n  \"description\": \"Set up JWT-based auth system\",\n  \"status\": \"pending\",\n  \"priority\": \"high\",\n  \"dependencies\": [\"1.1\"],\n  \"details\": \"Use bcrypt for hashing, JWT for tokens...\",\n  \"testStrategy\": \"Unit tests for auth functions, integration tests for login flow\",\n  \"subtasks\": []\n}\n```\n\n## Claude Code Best Practices with Task Master\n\n### Context Management\n\n- Use `/clear` between different tasks to maintain focus\n- This CLAUDE.md file is automatically loaded for context\n- Use `task-master show <id>` to pull specific task context when needed\n\n### Iterative Implementation\n\n1. `task-master show <subtask-id>` - Understand requirements\n2. Explore codebase and plan implementation\n3. `task-master update-subtask --id=<id> --prompt=\"detailed plan\"` - Log plan\n4. `task-master set-status --id=<id> --status=in-progress` - Start work\n5. Implement code following logged plan\n6. `task-master update-subtask --id=<id> --prompt=\"what worked/didn't work\"` - Log progress\n7. `task-master set-status --id=<id> --status=done` - Complete task\n\n### Complex Workflows with Checklists\n\nFor large migrations or multi-step processes:\n\n1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)\n2. Use Taskmaster to parse the new prd with `task-master parse-prd --append` (also available in MCP)\n3. Use Taskmaster to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.\n4. Work through items systematically, checking them off as completed\n5. Use `task-master update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck\n\n### Git Integration\n\nTask Master works well with `gh` CLI:\n\n```bash\n# Create PR for completed task\ngh pr create --title \"Complete task 1.2: User authentication\" --body \"Implements JWT auth system as specified in task 1.2\"\n\n# Reference task in commits\ngit commit -m \"feat: implement JWT auth (task 1.2)\"\n```\n\n### Parallel Development with Git Worktrees\n\n```bash\n# Create worktrees for parallel task development\ngit worktree add ../project-auth feature/auth-system\ngit worktree add ../project-api feature/api-refactor\n\n# Run Claude Code in each worktree\ncd ../project-auth && claude    # Terminal 1: Auth work\ncd ../project-api && claude     # Terminal 2: API work\n```\n\n## Troubleshooting\n\n### AI Commands Failing\n\n```bash\n# Check API keys are configured\ncat .env                           # For CLI usage\n\n# Verify model configuration\ntask-master models\n\n# Test with different model\ntask-master models --set-fallback gpt-4o-mini\n```\n\n### MCP Connection Issues\n\n- Check `.mcp.json` configuration\n- Verify Node.js installation\n- Use `--mcp-debug` flag when starting Claude Code\n- Use CLI as fallback if MCP unavailable\n\n### Task File Sync Issues\n\n```bash\n# Fix dependency issues\ntask-master fix-dependencies\n```\n\nDO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same Taskmaster core files.\n\n## Important Notes\n\n### AI-Powered Operations\n\nThese commands make AI calls and may take up to a minute:\n\n- `parse_prd` / `task-master parse-prd`\n- `analyze_project_complexity` / `task-master analyze-complexity`\n- `expand_task` / `task-master expand`\n- `expand_all` / `task-master expand --all`\n- `add_task` / `task-master add-task`\n- `update` / `task-master update`\n- `update_task` / `task-master update-task`\n- `update_subtask` / `task-master update-subtask`\n\n### File Management\n\n- Never manually edit `tasks.json` - use commands instead\n- Never manually edit `.taskmaster/config.json` - use `task-master models`\n\n### Claude Code Session Management\n\n- Use `/clear` frequently to maintain focused context\n- Create custom slash commands for repeated Task Master workflows\n- Configure tool allowlist to streamline permissions\n- Use headless mode for automation: `claude -p \"task-master next\"`\n\n### Multi-Task Updates\n\n- Use `update --from=<id>` to update multiple future tasks\n- Use `update-task --id=<id>` for single task updates\n- Use `update-subtask --id=<id>` for implementation logging\n\n### Research Mode\n\n- Add `--research` flag for research-based AI enhancement\n- Requires a research model API key like Perplexity (`PERPLEXITY_API_KEY`) in environment\n- Provides more informed task creation and updates\n- Recommended for complex technical tasks\n\n---\n\n_This guide ensures Claude Code has immediate access to Task Master's essential functionality for agentic development workflows._\n\n<!-- File: CLAUDE.md (Tokens: ~1792 | Category: claude-rule) -->\n# Claude Code Instructions\n\n## Task Master AI Instructions\n\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n@./.taskmaster/CLAUDE.md\n\n## Test Guidelines\n\n### Test File Placement\n\n- **Package & tests**: Place in `packages/<package-name>/src/<module>/<file>.spec.ts` or `apps/<app-name>/src/<module>/<file.spec.ts>` alongside source\n- **Package integration tests**: Place in `packages/<package-name>/tests/integration/<module>/<file>.test.ts` or `apps/<app-name>/tests/integration/<module>/<file>.test.ts` alongside source\n- **Isolated unit tests**: Use `tests/unit/packages/<package-name>/` only when parallel placement isn't possible\n- **Test extension**: Always use `.ts` for TypeScript tests, never `.js`\n\n### Synchronous Tests\n\n- **NEVER use async/await in test functions** unless testing actual asynchronous operations\n- Use synchronous top-level imports instead of dynamic `await import()`\n- Test bodies should be synchronous whenever possible\n- Example:\n\n  ```typescript\n  // ✅ CORRECT - Synchronous imports with .ts extension\n  import { MyClass } from '../src/my-class.js';\n\n  it('should verify behavior', () => {\n    expect(new MyClass().property).toBe(value);\n  });\n\n  // ❌ INCORRECT - Async imports\n  it('should verify behavior', async () => {\n    const { MyClass } = await import('../src/my-class.js');\n    expect(new MyClass().property).toBe(value);\n  });\n  ```\n\n### When to Write Tests\n\n**ALWAYS write tests for:**\n\n- **Bug fixes**: Add a regression test that would have caught the bug\n- **Business logic**: Complex calculations, validations, transformations\n- **Edge cases**: Boundary conditions, error handling, null/undefined cases\n- **Public APIs**: Methods other code depends on\n- **Integration points**: Database, file system, external APIs\n\n**SKIP tests for:**\n\n- Simple getters/setters: `getX() { return this.x; }`\n- Trivial pass-through functions with no logic\n- Pure configuration objects\n- Code that just delegates to another tested function\n\n**Examples:**\n\n```javascript\n// ✅ WRITE A TEST - Bug fix with regression prevention\nit('should use correct baseURL from defaultBaseURL config', () => {\n  const provider = new ZAIProvider();\n  expect(provider.defaultBaseURL).toBe('https://api.z.ai/api/paas/v4/');\n});\n\n// ✅ WRITE A TEST - Business logic with edge cases\nit('should parse subtask IDs correctly', () => {\n  expect(parseTaskId('1.2.3')).toEqual({ taskId: 1, subtaskId: 2, subSubtaskId: 3 });\n  expect(parseTaskId('invalid')).toBeNull();\n});\n\n// ❌ SKIP TEST - Trivial getter\nclass Task {\n  get id() { return this._id; } // No test needed\n}\n\n// ❌ SKIP TEST - Pure delegation\nfunction getTasks() {\n  return taskManager.getTasks(); // Already tested in taskManager\n}\n```\n\n**Bug Fix Workflow:**\n\n1. Encounter a bug\n2. Write a failing test that reproduces it\n3. Fix the bug\n4. Verify test now passes\n5. Commit both fix and test together\n\n### Testing Guidelines\n\n**Principles**: FIRST (Fast, Independent, Repeatable, Self-validating, Timely)\n**Structure**: AAA (Arrange, Act, Assert)\n**Coverage**: Right-BICEP (Right results, Boundary, Inverse, Cross-check, Error conditions, Performance)\n\n#### What to Mock\n\n**Unit tests** (`.spec.ts` - test single unit in isolation):\n- **@tm/core**: Mock only external I/O (Supabase, APIs, filesystem). Use real internal services.\n- **apps/cli**: Mock tm-core responses. Use real Commander/chalk/inquirer/other npm packages (test display logic).\n- **apps/mcp**: Mock tm-core responses. Use real MCP framework (test response formatting).\n\n**Integration tests** (`tests/integration/` - test multiple units together):\n- **All packages**: Use real tm-core, mock only external boundaries (APIs, DB, filesystem).\n\n**Never mock**:\n- Internal utilities/helpers in the same package\n- Standard frameworks (Commander, Express) - let them run\n- Standard library\n\n**Rule of thumb**: Mock what you're NOT testing. CLI unit tests test display → mock tm-core. Core unit tests test logic → mock I/O. Integration tests test full flow → mock only external APIs.\n\n**Red flag**: Mocking 3+ dependencies in a unit test means code is doing too much or is in the wrong layer.\n\n**Anti-pattern**: Heavily mocked tests don't verify real behavior—they verify that you wired up mocks correctly. You end up writing orchestration code to satisfy tests, rather than tests that validate your actual implementation. If testing is hard, move the logic to where it's naturally testable.\n\n## Architecture Guidelines\n\n### Business Logic Separation\n\n**CRITICAL RULE**: ALL business logic must live in `@tm/core`, NOT in presentation layers.\n\n- **`@tm/core`** (packages/tm-core/):\n  - Contains ALL business logic, domain models, services, and utilities\n  - Provides clean facade APIs through domain objects (tasks, auth, workflow, git, config)\n  - Houses all complexity - parsing, validation, transformations, calculations, etc.\n  - Example: Task ID parsing, subtask extraction, status validation, dependency resolution\n\n- **`@tm/cli`** (apps/cli/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays results\n  - Handles CLI-specific concerns: argument parsing, output formatting, user prompts\n  - NO business logic, NO data transformations, NO calculations\n\n- **`@tm/mcp`** (apps/mcp/):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and returns MCP-formatted responses\n  - Handles MCP-specific concerns: tool schemas, parameter validation, response formatting\n  - NO business logic, NO data transformations, NO calculations\n\n- **`apps/extension`** (future):\n  - Thin presentation layer ONLY\n  - Calls tm-core methods and displays in VS Code UI\n  - NO business logic\n\n**Examples of violations to avoid:**\n\n- ❌ Creating helper functions in CLI/MCP to parse task IDs → Move to tm-core\n- ❌ Data transformation logic in CLI/MCP → Move to tm-core\n- ❌ Validation logic in CLI/MCP → Move to tm-core\n- ❌ Duplicating logic across CLI and MCP → Implement once in tm-core\n\n**Correct approach:**\n\n- ✅ Add method to TasksDomain: `tasks.get(taskId)` (automatically handles task and subtask IDs)\n- ✅ CLI calls: `await tmCore.tasks.get(taskId)` (supports \"1\", \"1.2\", \"HAM-123\", \"HAM-123.2\")\n- ✅ MCP calls: `await tmCore.tasks.get(taskId)` (same intelligent ID parsing)\n- ✅ Single source of truth in tm-core\n\n## Code Quality & Reusability Guidelines\n\nApply standard software engineering principles:\n\n- **DRY (Don't Repeat Yourself)**: Extract patterns that appear 2+ times into reusable components or utilities\n- **YAGNI (You Aren't Gonna Need It)**: Don't over-engineer. Create abstractions when duplication appears, not before\n- **Maintainable**: Single source of truth. Change once, update everywhere\n- **Readable**: Clear naming, proper structure, export from index files\n- **Flexible**: Accept configuration options with sensible defaults\n\n## Documentation Guidelines\n\n- **Documentation location**: Write docs in `apps/docs/` (Mintlify site source), not `docs/`\n- **Documentation URL**: Reference docs at <https://tryhamster.com/docs/taskmaster>, not local file paths\n\n## Changeset Guidelines\n\n- **Add a changeset for code changes** - Run `npx changeset` after making code changes (not needed for docs-only PRs)\n- When creating changesets, remember that it's user-facing, meaning we don't have to get into the specifics of the code, but rather mention what the end-user is getting or fixing from this changeset\n- Run `npm run turbo:typecheck` before pushing to ensure TypeScript type checks pass\n- Run `npm run test -w <package-name>` to test a package\n\n<!-- File: .cursor/rules/ai_providers.mdc (Tokens: ~2660 | Category: cursor-rule) -->\n---\ndescription: Guidelines for managing Task Master AI providers and models.\nglobs: \nalwaysApply: false\n---\n# Task Master AI Provider Management\n\nThis rule guides AI assistants on how to view, configure, and interact with the different AI providers and models supported by Task Master. For internal implementation details of the service layer, see [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc).\n\n-   **Primary Interaction:**\n    -   Use the `models` MCP tool or the `task-master models` CLI command to manage AI configurations. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for detailed command/tool usage.\n\n-   **Configuration Roles:**\n    -   Task Master uses three roles for AI models:\n        -   `main`: Primary model for general tasks (generation, updates).\n        -   `research`: Model used when the `--research` flag or `research: true` parameter is used (typically models with web access or specialized knowledge).\n        -   `fallback`: Model used if the primary (`main`) model fails.\n    -   Each role is configured with a specific `provider:modelId` pair (e.g., `openai:gpt-4o`).\n\n-   **Viewing Configuration & Available Models:**\n    -   To see the current model assignments for each role and list all models available for assignment:\n        -   **MCP Tool:** `models` (call with no arguments or `listAvailableModels: true`)\n        -   **CLI Command:** `task-master models`\n    -   The output will show currently assigned models and a list of others, prefixed with their provider (e.g., `google:gemini-2.5-pro-exp-03-25`).\n\n-   **Setting Models for Roles:**\n    -   To assign a model to a role:\n        -   **MCP Tool:** `models` with `setMain`, `setResearch`, or `setFallback` parameters.\n        -   **CLI Command:** `task-master models` with `--set-main`, `--set-research`, or `--set-fallback` flags.\n    -   **Crucially:** When providing the model ID to *set*, **DO NOT include the `provider:` prefix**. Use only the model ID itself.\n        -   ✅ **DO:** `models(setMain='gpt-4o')` or `task-master models --set-main=gpt-4o`\n        -   ❌ **DON'T:** `models(setMain='openai:gpt-4o')` or `task-master models --set-main=openai:gpt-4o`\n    -   The tool/command will automatically determine the provider based on the model ID.\n\n-   **Setting Custom Models (Ollama/OpenRouter):**\n    -   To set a model ID not in the internal list for Ollama or OpenRouter:\n        -   **MCP Tool:** Use `models` with `set<Role>` and **also** `ollama: true` or `openrouter: true`.\n            -   Example: `models(setMain='my-custom-ollama-model', ollama=true)`\n            -   Example: `models(setMain='some-openrouter-model', openrouter=true)`\n        -   **CLI Command:** Use `task-master models` with `--set-<role>` and **also** `--ollama` or `--openrouter`.\n            -   Example: `task-master models --set-main=my-custom-ollama-model --ollama`\n            -   Example: `task-master models --set-main=some-openrouter-model --openrouter`\n        -   **Interactive Setup:** Use `task-master models --setup` and select the `Ollama (Enter Custom ID)` or `OpenRouter (Enter Custom ID)` options.\n    -   **OpenRouter Validation:** When setting a custom OpenRouter model, Taskmaster attempts to validate the ID against the live OpenRouter API.\n    -   **Ollama:** No live validation occurs for custom Ollama models; ensure the model is available on your Ollama server.\n\n-   **Supported Providers & Required API Keys:**\n    -   Task Master integrates with various providers via the Vercel AI SDK.\n    -   **API keys are essential** for most providers and must be configured correctly.\n    -   **Key Locations** (See [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) - Configuration Management):\n        -   **MCP/Cursor:** Set keys in the `env` section of `.cursor/mcp.json`.\n        -   **CLI:** Set keys in a `.env` file in the project root.\n    -   **Provider List & Keys:**\n        -   **`anthropic`**: Requires `ANTHROPIC_API_KEY`.\n        -   **`google`**: Requires `GOOGLE_API_KEY`.\n        -   **`openai`**: Requires `OPENAI_API_KEY`.\n        -   **`perplexity`**: Requires `PERPLEXITY_API_KEY`.\n        -   **`xai`**: Requires `XAI_API_KEY`.\n        -   **`mistral`**: Requires `MISTRAL_API_KEY`.\n        -   **`azure`**: Requires `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT`.\n        -   **`openrouter`**: Requires `OPENROUTER_API_KEY`.\n        -   **`ollama`**: Might require `OLLAMA_API_KEY` (not currently supported) *and* `OLLAMA_BASE_URL` (default: `http://localhost:11434/api`). *Check specific setup.*\n\n-   **Troubleshooting:**\n    -   If AI commands fail (especially in MCP context):\n        1.  **Verify API Key:** Ensure the correct API key for the *selected provider* (check `models` output) exists in the appropriate location (`.cursor/mcp.json` env or `.env`).\n        2.  **Check Model ID:** Ensure the model ID set for the role is valid (use `models` listAvailableModels/`task-master models`).\n        3.  **Provider Status:** Check the status of the external AI provider's service.\n        4.  **Restart MCP:** If changes were made to configuration or provider code, restart the MCP server.\n\n## Adding a New AI Provider (Vercel AI SDK Method)\n\nFollow these steps to integrate a new AI provider that has an official Vercel AI SDK adapter (`@ai-sdk/<provider>`):\n\n1.  **Install Dependency:**\n    -   Install the provider-specific package:\n        ```bash\n        npm install @ai-sdk/<provider-name>\n        ```\n\n2.  **Create Provider Module:**\n    -   Create a new file in `src/ai-providers/` named `<provider-name>.js`.\n    -   Use existing modules (`openai.js`, `anthropic.js`, etc.) as a template.\n    -   **Import:**\n        -   Import the provider's `create<ProviderName>` function from `@ai-sdk/<provider-name>`.\n        -   Import `generateText`, `streamText`, `generateObject` from the core `ai` package.\n        -   Import the `log` utility from `../../scripts/modules/utils.js`.\n    -   **Implement Core Functions:**\n        -   `generate<ProviderName>Text(params)`:\n            -   Accepts `params` (apiKey, modelId, messages, etc.).\n            -   Instantiate the client: `const client = create<ProviderName>({ apiKey });`\n            -   Call `generateText({ model: client(modelId), ... })`.\n            -   Return `result.text`.\n            -   Include basic validation and try/catch error handling.\n        -   `stream<ProviderName>Text(params)`:\n            -   Similar structure to `generateText`.\n            -   Call `streamText({ model: client(modelId), ... })`.\n            -   Return the full stream result object.\n            -   Include basic validation and try/catch.\n        -   `generate<ProviderName>Object(params)`:\n            -   Similar structure.\n            -   Call `generateObject({ model: client(modelId), schema, messages, ... })`.\n            -   Return `result.object`.\n            -   Include basic validation and try/catch.\n    -   **Export Functions:** Export the three implemented functions (`generate<ProviderName>Text`, `stream<ProviderName>Text`, `generate<ProviderName>Object`).\n\n3.  **Integrate with Unified Service:**\n    -   Open `scripts/modules/ai-services-unified.js`.\n    -   **Import:** Add `import * as <providerName> from '../../src/ai-providers/<provider-name>.js';`\n    -   **Map:** Add an entry to the `PROVIDER_FUNCTIONS` map:\n        ```javascript\n        '<provider-name>': {\n            generateText: <providerName>.generate<ProviderName>Text,\n            streamText: <providerName>.stream<ProviderName>Text,\n            generateObject: <providerName>.generate<ProviderName>Object\n        },\n        ```\n\n4.  **Update Configuration Management:**\n    -   Open `scripts/modules/config-manager.js`.\n    -   **`MODEL_MAP`:** Add the new `<provider-name>` key to the `MODEL_MAP` loaded from `supported-models.json` (or ensure the loading handles new providers dynamically if `supported-models.json` is updated first).\n    -   **`VALID_PROVIDERS`:** Ensure the new `<provider-name>` is included in the `VALID_PROVIDERS` array (this should happen automatically if derived from `MODEL_MAP` keys).\n    -   **API Key Handling:**\n        -   Update the `keyMap` in `_resolveApiKey` and `isApiKeySet` with the correct environment variable name (e.g., `PROVIDER_API_KEY`).\n        -   Update the `switch` statement in `getMcpApiKeyStatus` to check the corresponding key in `mcp.json` and its placeholder value.\n        -   Add a case to the `switch` statement in `getMcpApiKeyStatus` for the new provider, including its placeholder string if applicable.\n    -   **Ollama Exception:** If adding Ollama or another provider *not* requiring an API key, add a specific check at the beginning of `isApiKeySet` and `getMcpApiKeyStatus` to return `true` immediately for that provider.\n\n5.  **Update Supported Models List:**\n    -   Edit `scripts/modules/supported-models.json`.\n    -   Add a new key for the `<provider-name>`.\n    -   Add an array of model objects under the provider key, each including:\n        -   `id`: The specific model identifier (e.g., `claude-3-opus-20240229`).\n        -   `name`: A user-friendly name (optional).\n        -   `swe_score`, `cost_per_1m_tokens`: (Optional) Add performance/cost data if available.\n        -   `allowed_roles`: An array of roles (`\"main\"`, `\"research\"`, `\"fallback\"`) the model is suitable for.\n        -   `max_tokens`: (Optional but recommended) The maximum token limit for the model.\n\n6.  **Update Environment Examples:**\n    -   Add the new `PROVIDER_API_KEY` to `.env.example`.\n    -   Add the new `PROVIDER_API_KEY` with its placeholder (`YOUR_PROVIDER_API_KEY_HERE`) to the `env` section for `taskmaster-ai` in `.cursor/mcp.json.example` (if it exists) or update instructions.\n\n7.  **Add Unit Tests:**\n    -   Create `tests/unit/ai-providers/<provider-name>.test.js`.\n    -   Mock the `@ai-sdk/<provider-name>` module and the core `ai` module functions (`generateText`, `streamText`, `generateObject`).\n    -   Write tests for each exported function (`generate<ProviderName>Text`, etc.) to verify:\n        -   Correct client instantiation.\n        -   Correct parameters passed to the mocked Vercel AI SDK functions.\n        -   Correct handling of results.\n        -   Error handling (missing API key, SDK errors).\n\n8.  **Documentation:**\n    -   Update any relevant documentation (like `README.md` or other rules) mentioning supported providers or configuration.\n\n*(Note: For providers **without** an official Vercel AI SDK adapter, the process would involve directly using the provider's own SDK or API within the `src/ai-providers/<provider-name>.js` module and manually constructing responses compatible with the unified service layer, which is significantly more complex.)*\n\n<!-- File: .cursor/rules/ai_services.mdc (Tokens: ~1668 | Category: cursor-rule) -->\n---\ndescription: Guidelines for interacting with the unified AI service layer.\nglobs: scripts/modules/ai-services-unified.js, scripts/modules/task-manager/*.js, scripts/modules/commands.js\n---\n\n# AI Services Layer Guidelines\n\nThis document outlines the architecture and usage patterns for interacting with Large Language Models (LLMs) via Task Master's unified AI service layer (`ai-services-unified.js`). The goal is to centralize configuration, provider selection, API key management, fallback logic, and error handling.\n\n**Core Components:**\n\n*   **Configuration (`.taskmasterconfig` & [`config-manager.js`](mdc:scripts/modules/config-manager.js)):**\n    *   Defines the AI provider and model ID for different **roles** (`main`, `research`, `fallback`).\n    *   Stores parameters like `maxTokens` and `temperature` per role.\n    *   Managed via the `task-master models --setup` CLI command.\n    *   [`config-manager.js`](mdc:scripts/modules/config-manager.js) provides **getters** (e.g., `getMainProvider()`, `getParametersForRole()`) to access these settings. Core logic should **only** use these getters for *non-AI related application logic* (e.g., `getDefaultSubtasks`). The unified service fetches necessary AI parameters internally based on the `role`.\n    *   **API keys** are **NOT** stored here; they are resolved via `resolveEnvVariable` (in [`utils.js`](mdc:scripts/modules/utils.js)) from `.env` (for CLI) or the MCP `session.env` object (for MCP calls). See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc).\n\n*   **Unified Service (`ai-services-unified.js`):**\n    *   Exports primary interaction functions: `generateTextService`, `generateObjectService`. (Note: `streamTextService` exists but has known reliability issues with some providers/payloads).\n    *   Contains the core `_unifiedServiceRunner` logic.\n    *   Internally uses `config-manager.js` getters to determine the provider/model/parameters based on the requested `role`.\n    *   Implements the **fallback sequence** (e.g., main -> fallback -> research) if the primary provider/model fails.\n    *   Constructs the `messages` array required by the Vercel AI SDK.\n    *   Implements **retry logic** for specific API errors (`_attemptProviderCallWithRetries`).\n    *   Resolves API keys automatically via `_resolveApiKey` (using `resolveEnvVariable`).\n    *   Maps requests to the correct provider implementation (in `src/ai-providers/`) via `PROVIDER_FUNCTIONS`.\n    *   Returns a structured object containing the primary AI result (`mainResult`) and telemetry data (`telemetryData`). See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for details on how this telemetry data is propagated and handled.\n\n*   **Provider Implementations (`src/ai-providers/*.js`):**\n    *   Contain provider-specific wrappers around Vercel AI SDK functions (`generateText`, `generateObject`).\n\n**Usage Pattern (from Core Logic like `task-manager/*.js`):**\n\n1.  **Import Service:** Import `generateTextService` or `generateObjectService` from `../ai-services-unified.js`.\n    ```javascript\n    // Preferred for most tasks (especially with complex JSON)\n    import { generateTextService } from '../ai-services-unified.js';\n\n    // Use if structured output is reliable for the specific use case\n    // import { generateObjectService } from '../ai-services-unified.js';\n    ```\n\n2.  **Prepare Parameters:** Construct the parameters object for the service call.\n    *   `role`: **Required.** `'main'`, `'research'`, or `'fallback'`. Determines the initial provider/model/parameters used by the unified service.\n    *   `session`: **Required if called from MCP context.** Pass the `session` object received by the direct function wrapper. The unified service uses `session.env` to find API keys.\n    *   `systemPrompt`: Your system instruction string.\n    *   `prompt`: The user message string (can be long, include stringified data, etc.).\n    *   (For `generateObjectService` only): `schema` (Zod schema), `objectName`.\n\n3.  **Call Service:** Use `await` to call the service function.\n    ```javascript\n    // Example using generateTextService (most common)\n    try {\n        const resultText = await generateTextService({\n            role: useResearch ? 'research' : 'main', // Determine role based on logic\n            session: context.session, // Pass session from context object\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // Process the raw text response (e.g., parse JSON, use directly)\n        // ...\n    } catch (error) {\n        // Handle errors thrown by the unified service (if all fallbacks/retries fail)\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n\n    // Example using generateObjectService (use cautiously)\n    try {\n        const resultObject = await generateObjectService({\n            role: 'main',\n            session: context.session,\n            schema: myZodSchema,\n            objectName: 'myDataObject',\n            systemPrompt: \"You are...\",\n            prompt: userMessageContent\n        });\n        // resultObject is already a validated JS object\n        // ...\n    } catch (error) {\n        report('error', `Unified AI service call failed: ${error.message}`);\n        throw error;\n    }\n    ```\n\n4.  **Handle Results/Errors:** Process the returned text/object or handle errors thrown by the unified service layer.\n\n**Key Implementation Rules & Gotchas:**\n\n*   ✅ **DO**: Centralize **all** LLM calls through `generateTextService` or `generateObjectService`.\n*   ✅ **DO**: Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.\n*   ✅ **DO**: Pass the `session` object (received in the `context` parameter, especially from direct function wrappers) to the service call when in MCP context.\n*   ✅ **DO**: Ensure API keys are correctly configured in `.env` (for CLI) or `.cursor/mcp.json` (for MCP).\n*   ✅ **DO**: Ensure `.taskmasterconfig` exists and has valid provider/model IDs for the roles you intend to use (manage via `task-master models --setup`).\n*   ✅ **DO**: Use `generateTextService` and implement robust manual JSON parsing (with Zod validation *after* parsing) when structured output is needed, as `generateObjectService` has shown unreliability with some providers/schemas.\n*   ❌ **DON'T**: Import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.\n*   ❌ **DON'T**: Initialize AI clients (Anthropic, Perplexity, etc.) directly within core logic (`task-manager/`) or MCP direct functions.\n*   ❌ **DON'T**: Fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters *for the AI call*. Pass the `role` instead.\n*   ❌ **DON'T**: Implement fallback or retry logic outside `ai-services-unified.js`.\n*   ❌ **DON'T**: Handle API key resolution outside the service layer (it uses `utils.js` internally).\n*   ⚠️ **generateObjectService Caution**: Be aware of potential reliability issues with `generateObjectService` across different providers and complex schemas. Prefer `generateTextService` + manual parsing as a more robust alternative for structured data needs.\n\n<!-- File: .cursor/rules/architecture.mdc (Tokens: ~4303 | Category: cursor-rule) -->\n---\ndescription: Describes the high-level architecture of the Task Master CLI application.\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Application Architecture Overview\n\n- **Modular Structure**: The Task Master CLI is built using a modular architecture, with distinct modules responsible for different aspects of the application. This promotes separation of concerns, maintainability, and testability.\n\n- **Main Modules and Responsibilities**:\n\n  - **[`commands.js`](mdc:scripts/modules/commands.js): Command Handling**\n    - **Purpose**: Defines and registers all CLI commands using Commander.js.\n    - **Responsibilities** (See also: [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n      - Parses command-line arguments and options.\n      - Invokes appropriate core logic functions from `scripts/modules/`.\n      - Handles user input/output for CLI.\n      - Implements CLI-specific validation.\n\n  - **[`task-manager.js`](mdc:scripts/modules/task-manager.js) & `task-manager/` directory: Task Data & Core Logic**\n    - **Purpose**: Contains core functions for task data manipulation (CRUD), AI interactions, and related logic.\n    - **Responsibilities**:\n      - Reading/writing `tasks.json` with tagged task lists support.\n      - Implementing functions for task CRUD, parsing PRDs, expanding tasks, updating status, etc.\n      - **Tagged Task Lists**: Handles task organization across multiple contexts (tags) like \"master\", branch names, or project phases.\n      - **Tag Resolution**: Provides backward compatibility by resolving tagged format to legacy format transparently.\n      - **Delegating AI interactions** to the `ai-services-unified.js` layer.\n      - Accessing non-AI configuration via `config-manager.js` getters.\n    - **Key Files**: Individual files within `scripts/modules/task-manager/` handle specific actions (e.g., `add-task.js`, `expand-task.js`).\n\n  - **[`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js): Dependency Management**\n    - **Purpose**: Manages task dependencies.\n    - **Responsibilities**: Add/remove/validate/fix dependencies across tagged task contexts.\n\n  - **[`ui.js`](mdc:scripts/modules/ui.js): User Interface Components**\n    - **Purpose**: Handles CLI output formatting (tables, colors, boxes, spinners).\n    - **Responsibilities**: Displaying tasks, reports, progress, suggestions, and migration notices for tagged systems.\n\n  - **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js): Unified AI Service Layer**\n    - **Purpose**: Centralized interface for all LLM interactions using Vercel AI SDK.\n    - **Responsibilities** (See also: [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc)):\n      - Exports `generateTextService`, `generateObjectService`.\n      - Handles provider/model selection based on `role` and `.taskmasterconfig`.\n      - Resolves API keys (from `.env` or `session.env`).\n      - Implements fallback and retry logic.\n      - Orchestrates calls to provider-specific implementations (`src/ai-providers/`).\n    - Telemetry data generated by the AI service layer is propagated upwards through core logic, direct functions, and MCP tools. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the detailed integration pattern.\n\n  - **[`src/ai-providers/*.js`](mdc:src/ai-providers/): Provider-Specific Implementations**\n    - **Purpose**: Provider-specific wrappers for Vercel AI SDK functions.\n    - **Responsibilities**: Interact directly with Vercel AI SDK adapters.\n\n  - **[`config-manager.js`](mdc:scripts/modules/config-manager.js): Configuration Management**\n    - **Purpose**: Loads, validates, and provides access to configuration.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Reads and merges `.taskmasterconfig` with defaults.\n      - Provides getters (e.g., `getMainProvider`, `getLogLevel`, `getDefaultSubtasks`) for accessing settings.\n      - **Tag Configuration**: Manages `global.defaultTag` and `tags` section for tag system settings.\n      - **Note**: Does **not** store or directly handle API keys (keys are in `.env` or MCP `session.env`).\n\n  - **[`utils.js`](mdc:scripts/modules/utils.js): Core Utility Functions**\n    - **Purpose**: Low-level, reusable CLI utilities.\n    - **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n      - Logging (`log` function), File I/O (`readJSON`, `writeJSON`), String utils (`truncate`).\n      - Task utils (`findTaskById`), Dependency utils (`findCycles`).\n      - API Key Resolution (`resolveEnvVariable`).\n      - Silent Mode Control (`enableSilentMode`, `disableSilentMode`).\n      - **Tagged Task Lists**: Silent migration system, tag resolution, current tag management.\n      - **Migration System**: `performCompleteTagMigration`, `migrateConfigJson`, `createStateJson`.\n\n  - **[`mcp-server/`](mdc:mcp-server/): MCP Server Integration**\n    - **Purpose**: Provides MCP interface using FastMCP.\n    - **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):\n      - Registers tools (`mcp-server/src/tools/*.js`). Tool `execute` methods **should be wrapped** with the `withNormalizedProjectRoot` HOF (from `tools/utils.js`) to ensure consistent path handling.\n      - The HOF provides a normalized `args.projectRoot` to the `execute` method.\n      - Tool `execute` methods call **direct function wrappers** (`mcp-server/src/core/direct-functions/*.js`), passing the normalized `projectRoot` and other args.\n      - Direct functions use path utilities (`mcp-server/src/core/utils/`) to resolve paths based on `projectRoot` from session.\n      - Direct functions implement silent mode, logger wrappers, and call core logic functions from `scripts/modules/`.\n      - **Tagged Task Lists**: MCP tools fully support the tagged format with complete tag management capabilities.\n      - Manages MCP caching and response formatting.\n\n  - **[`init.js`](mdc:scripts/init.js): Project Initialization Logic**\n    - **Purpose**: Sets up new Task Master project structure.\n    - **Responsibilities**: Creates directories, copies templates, manages `package.json`, sets up `.cursor/mcp.json`, initializes state.json for tagged system.\n\n## Tagged Task Lists System Architecture\n\n**Data Structure**: Task Master now uses a tagged task lists system where the `tasks.json` file contains multiple named task lists as top-level keys:\n\n```json\n{\n  \"master\": {\n    \"tasks\": [/* standard task objects */]\n  },\n  \"feature-branch\": {\n    \"tasks\": [/* separate task context */]\n  }\n}\n```\n\n**Key Components:**\n\n- **Silent Migration**: Automatically transforms legacy `{\"tasks\": [...]}` format to tagged format `{\"master\": {\"tasks\": [...]}}` on first read\n- **Tag Resolution Layer**: Provides 100% backward compatibility by intercepting tagged format and returning legacy format to existing code\n- **Configuration Integration**: `global.defaultTag` and `tags` section in config.json manage tag system settings\n- **State Management**: `.taskmaster/state.json` tracks current tag, migration status, and tag-branch mappings\n- **Migration Notice**: User-friendly notification system for seamless migration experience\n\n**Backward Compatibility**: All existing CLI commands and MCP tools continue to work unchanged. The tag resolution layer ensures that existing code receives the expected legacy format while the underlying storage uses the new tagged structure.\n\n- **Data Flow and Module Dependencies (Updated)**:\n\n  - **CLI**: `bin/task-master.js` -> `scripts/dev.js` (loads `.env`) -> `scripts/modules/commands.js` -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **MCP**: External Tool -> `mcp-server/server.js` -> Tool (`mcp-server/src/tools/*`) -> Direct Function (`mcp-server/src/core/direct-functions/*`) -> Core Logic (`scripts/modules/*`) -> **Tag Resolution Layer** -> Unified AI Service (`ai-services-unified.js`) -> Provider Adapters -> LLM API.\n  - **Configuration**: Core logic needing non-AI settings calls `config-manager.js` getters (passing `session.env` via `explicitRoot` if from MCP). Unified AI Service internally calls `config-manager.js` getters (using `role`) for AI params and `utils.js` (`resolveEnvVariable` with `session.env`) for API keys.\n\n## Silent Mode Implementation Pattern in MCP Direct Functions\n\nDirect functions (the `*Direct` functions in `mcp-server/src/core/direct-functions/`) need to carefully implement silent mode to prevent console logs from interfering with the structured JSON responses required by MCP. This involves both using `enableSilentMode`/`disableSilentMode` around core function calls AND passing the MCP logger via the standard wrapper pattern (see mcp.mdc). Here's the standard pattern for correct implementation:\n\n1. **Import Silent Mode Utilities**:\n   ```javascript\n   import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n   ```\n\n2. **Parameter Matching with Core Functions**:\n   - ✅ **DO**: Ensure direct function parameters match the core function parameters\n   - ✅ **DO**: Check the original core function signature before implementing\n   - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n   ```javascript\n   // Example: Core function signature\n   // async function expandTask(tasksPath, taskId, numSubtasks, useResearch, additionalContext, options)\n   \n   // Direct function implementation - extract only parameters that exist in core\n   export async function expandTaskDirect(args, log, context = {}) {\n     // Extract parameters that match the core function\n     const taskId = parseInt(args.id, 10);\n     const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n     const useResearch = args.research === true;\n     const additionalContext = args.prompt || '';\n     \n     // Later pass these parameters in the correct order to the core function\n     const result = await expandTask(\n       tasksPath, \n       taskId, \n       numSubtasks, \n       useResearch, \n       additionalContext,\n       { mcpLog: log, session: context.session }\n     );\n   }\n   ```\n\n3. **Checking Silent Mode State**:\n   - ✅ **DO**: Always use `isSilentMode()` function to check current status\n   - ❌ **DON'T**: Directly access the global `silentMode` variable or `global.silentMode`\n   ```javascript\n   // CORRECT: Use the function to check current state\n   if (!isSilentMode()) {\n     // Only create a loading indicator if not in silent mode\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   \n   // INCORRECT: Don't access global variables directly\n   if (!silentMode) { // ❌ WRONG\n     loadingIndicator = startLoadingIndicator('Processing...');\n   }\n   ```\n\n4. **Wrapping Core Function Calls**:\n   - ✅ **DO**: Use a try/finally block pattern to ensure silent mode is always restored\n   - ✅ **DO**: Enable silent mode before calling core functions that produce console output\n   - ✅ **DO**: Disable silent mode in a finally block to ensure it runs even if errors occur\n   - ❌ **DON'T**: Enable silent mode without ensuring it gets disabled\n   ```javascript\n   export async function someDirectFunction(args, log) {\n     try {\n       // Argument preparation\n       const tasksPath = findTasksJsonPath(args, log);\n       const someArg = args.someArg;\n       \n       // Enable silent mode to prevent console logs\n       enableSilentMode();\n       \n       try {\n         // Call core function which might produce console output\n         const result = await someCoreFunction(tasksPath, someArg);\n         \n         // Return standardized result object\n         return { \n           success: true, \n           data: result, \n           fromCache: false \n         };\n       } finally {\n         // ALWAYS disable silent mode in finally block\n         disableSilentMode();\n       }\n     } catch (error) {\n       // Standard error handling\n       log.error(`Error in direct function: ${error.message}`);\n       return { \n         success: false, \n         error: { code: 'OPERATION_ERROR', message: error.message }, \n         fromCache: false \n       };\n     }\n   }\n   ```\n\n5. **Mixed Parameter and Global Silent Mode Handling**:\n   - For functions that need to handle both a passed `silentMode` parameter and check global state:\n   ```javascript\n   // Check both the function parameter and global state\n   const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n   \n   if (!isSilent) {\n     console.log('Operation starting...');\n   }\n   ```\n\nBy following these patterns consistently, direct functions will properly manage console output suppression while ensuring that silent mode is always properly reset, even when errors occur. This creates a more robust system that helps prevent unexpected silent mode states that could cause logging problems in subsequent operations.\n\n- **Testing Architecture**:\n\n  - **Test Organization Structure** (See also: [`tests.mdc`](mdc:.cursor/rules/tests.mdc)):\n    - **Unit Tests**: Located in `tests/unit/`, reflect the module structure with one test file per module\n    - **Integration Tests**: Located in `tests/integration/`, test interactions between modules\n    - **End-to-End Tests**: Located in `tests/e2e/`, test complete workflows from a user perspective\n    - **Test Fixtures**: Located in `tests/fixtures/`, provide reusable test data\n    - **Tagged System Tests**: Test migration, tag resolution, and multi-context functionality\n\n  - **Module Design for Testability**:\n    - **Explicit Dependencies**: Functions accept their dependencies as parameters rather than using globals\n    - **Functional Style**: Pure functions with minimal side effects make testing deterministic\n    - **Separate Logic from I/O**: Core business logic is separated from file system operations\n    - **Clear Module Interfaces**: Each module has well-defined exports that can be mocked in tests\n    - **Callback Isolation**: Callbacks are defined as separate functions for easier testing\n    - **Stateless Design**: Modules avoid maintaining internal state where possible\n    - **Tag Resolution Testing**: Test both tagged and legacy format handling\n\n  - **Mock Integration Patterns**:\n    - **External Libraries**: Libraries like `fs`, `commander`, and `@anthropic-ai/sdk` are mocked at module level\n    - **Internal Modules**: Application modules are mocked with appropriate spy functions\n    - **Testing Function Callbacks**: Callbacks are extracted from mock call arguments and tested in isolation\n    - **UI Elements**: Output functions from `ui.js` are mocked to verify display calls\n    - **Tagged Data Mocking**: Test both legacy and tagged task data structures\n\n  - **Testing Flow**:\n    - Module dependencies are mocked (following Jest's hoisting behavior)\n    - Test modules are imported after mocks are established\n    - Spy functions are set up on module methods\n    - Tests call the functions under test and verify behavior\n    - Mocks are reset between test cases to maintain isolation\n    - Tagged system behavior is tested for both migration and normal operation\n\n- **Benefits of this Architecture**:\n\n  - **Maintainability**: Modules are self-contained and focused, making it easier to understand, modify, and debug specific features.\n  - **Testability**:  Each module can be tested in isolation (unit testing), and interactions between modules can be tested (integration testing).\n    - **Mocking Support**: The clear dependency boundaries make mocking straightforward\n    - **Test Isolation**: Each component can be tested without affecting others\n    - **Callback Testing**: Function callbacks can be extracted and tested independently\n    - **Multi-Context Testing**: Tagged system enables testing different task contexts independently\n  - **Reusability**: Utility functions and UI components can be reused across different parts of the application.\n  - **Scalability**:  New features can be added as new modules or by extending existing ones without significantly impacting other parts of the application.\n  - **Multi-Context Support**: Tagged task lists enable working across different contexts (branches, environments, phases) without conflicts.\n  - **Backward Compatibility**: Seamless migration and tag resolution ensure existing workflows continue unchanged.\n  - **Clarity**: The modular structure provides a clear separation of concerns, making the codebase easier to navigate and understand for developers.\n\nThis architectural overview should help AI models understand the structure and organization of the Task Master CLI codebase, enabling them to more effectively assist with code generation, modification, and understanding.\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.\n\n2.  **Create Direct Function File in `mcp-server/src/core/direct-functions/`:**\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**.\n    - Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:\n        - **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` being provided.\n        - Parse other `args` and perform necessary validation.\n        - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()`.\n        - Implement caching with `getCachedOrExecute` if applicable.\n        - Call core logic.\n        - Return `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n    - **Note**: Tag-aware MCP tools are fully implemented with complete tag management support.\n\n3.  **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method:\n      - Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).\n      - Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)` or use `asyncOperationManager.addOperation`.\n      - Pass the result to `handleApiResult`.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition.\n\n## Project Initialization\n\nThe `initialize_project` command provides a way to set up a new Task Master project:\n\n- **CLI Command**: `task-master init`\n- **MCP Tool**: `initialize_project`\n- **Functionality**:\n  - Creates necessary directories and files for a new project\n  - Sets up `tasks.json` with tagged structure and initial task files\n  - Configures project metadata (name, description, version)\n  - Initializes state.json for tag system\n  - Handles shell alias creation if requested\n  - Works in both interactive and non-interactive modes\n\n<!-- File: .cursor/rules/changeset.mdc (Tokens: ~1491 | Category: cursor-rule) -->\n---\ndescription: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\nalwaysApply: true\n---\n\n# Changesets Workflow Guidelines\n\nChangesets is used to manage package versioning and generate accurate `CHANGELOG.md` files automatically. It's crucial to use it correctly after making meaningful changes that affect the package from an external perspective or significantly impact internal development workflow documented elsewhere.\n\n## When to Run Changeset\n\n- Run `npm run changeset` (or `npx changeset add`) **after** you have staged (`git add .`) a logical set of changes that should be communicated in the next release's `CHANGELOG.md`.\n- This typically includes:\n    - **New Features** (Backward-compatible additions)\n    - **Bug Fixes** (Fixes to existing functionality)\n    - **Breaking Changes** (Changes that are not backward-compatible)\n    - **Performance Improvements** (Enhancements to speed or resource usage)\n    - **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability) - *Such as reorganizing the MCP server's direct function implementations into separate files*\n    - **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)\n    - **Dependency Updates** (Especially if they fix known issues or introduce significant changes)\n    - **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)\n- **Every Pull Request** containing one or more of the above change types **should include a changeset file**.\n\n## What NOT to Add a Changeset For\n\nAvoid creating changesets for changes that have **no impact or relevance to external consumers** of the `task-master` package or contributors following **public-facing documentation**. Examples include:\n\n- **Internal Documentation Updates:** Changes *only* to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.\n- **Trivial Chores:** Very minor code cleanup, adding comments that don't clarify behavior, typo fixes in non-user-facing code or internal docs.\n- **Non-Impactful Test Updates:** Minor refactoring of tests, adding tests for existing functionality without fixing bugs.\n- **Local Configuration Changes:** Updates to personal editor settings, local `.env` files, etc.\n\n**Rule of Thumb:** If a user installing or using the `task-master` package wouldn't care about the change, or if a contributor following the main README wouldn't need to know about it for their workflow, you likely don't need a changeset.\n\n## How to Run and What It Asks\n\n1.  **Run the command**:\n    ```bash\n    npm run changeset\n    # or\n    npx changeset add\n    ```\n2.  **Select Packages**: It will prompt you to select the package(s) affected by your changes using arrow keys and spacebar. If this is not a monorepo, select the main package.\n3.  **Select Bump Type**: Choose the appropriate semantic version bump for **each** selected package:\n    *   **`Major`**: For **breaking changes**. Use sparingly.\n    *   **`Minor`**: For **new features**.\n    *   **`Patch`**: For **bug fixes**, performance improvements, **user-facing documentation changes**, significant refactoring, relevant dependency updates, or impactful build/tooling changes.\n4.  **Enter Summary**: Provide a concise summary of the changes **for the `CHANGELOG.md`**.\n    *   **Purpose**: This message is user-facing and explains *what* changed in the release.\n    *   **Format**: Use the imperative mood (e.g., \"Add feature X\", \"Fix bug Y\", \"Update README setup instructions\"). Keep it brief, typically a single line.\n    *   **Audience**: Think about users installing/updating the package or developers consuming its public API/CLI.\n    *   **Not a Git Commit Message**: This summary is *different* from your detailed Git commit message.\n\n## Changeset Summary vs. Git Commit Message\n\n- **Changeset Summary**:\n    - **Audience**: Users/Consumers of the package (reads `CHANGELOG.md`).\n    - **Purpose**: Briefly describe *what* changed in the released version that is relevant to them.\n    - **Format**: Concise, imperative mood, single line usually sufficient.\n    - **Example**: `Fix dependency resolution bug in 'next' command.`\n- **Git Commit Message**:\n    - **Audience**: Developers browsing the Git history of *this* repository.\n    - **Purpose**: Explain *why* the change was made, the context, and the implementation details (can include internal context).\n    - **Format**: Follows commit conventions (e.g., Conventional Commits), can be multi-line with a subject and body.\n    - **Example**:\n      ```\n      fix(deps): Correct dependency lookup in 'next' command\n\n      The logic previously failed to account for subtask dependencies when\n      determining the next available task. This commit refactors the\n      dependency check in `findNextTask` within `task-manager.js` to\n      correctly traverse both direct and subtask dependencies. Added\n      unit tests to cover this specific scenario.\n      ```\n- ✅ **DO**: Provide *both* a concise changeset summary (when appropriate) *and* a detailed Git commit message.\n- ❌ **DON'T**: Use your detailed Git commit message body as the changeset summary.\n- ❌ **DON'T**: Skip running `changeset` for user-relevant changes just because you wrote a good commit message.\n\n## The `.changeset` File\n\n- Running the command creates a unique markdown file in the `.changeset/` directory (e.g., `.changeset/random-name.md`).\n- This file contains the bump type information and the summary you provided.\n- **This file MUST be staged and committed** along with your relevant code changes.\n\n## Standard Workflow Sequence (When a Changeset is Needed)\n\n1.  Make your code or relevant documentation changes.\n2.  Stage your changes: `git add .`\n3.  Run changeset: `npm run changeset`\n    *   Select package(s).\n    *   Select bump type (`Patch`, `Minor`, `Major`).\n    *   Enter the **concise summary** for the changelog.\n4.  Stage the generated changeset file: `git add .changeset/*.md`\n5.  Commit all staged changes (code + changeset file) using your **detailed Git commit message**:\n    ```bash\n    git commit -m \"feat(module): Add new feature X...\"\n    ```\n\n## Release Process (Context)\n\n- The generated `.changeset/*.md` files are consumed later during the release process.\n- Commands like `changeset version` read these files, update `package.json` versions, update the `CHANGELOG.md`, and delete the individual changeset files.\n- Commands like `changeset publish` then publish the new versions to npm.\n\nFollowing this workflow ensures that versioning is consistent and changelogs are automatically and accurately generated based on the contributions made.\n\n<!-- File: .cursor/rules/commands.mdc (Tokens: ~6525 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing CLI commands using Commander.js\nglobs: scripts/modules/commands.js\nalwaysApply: false\n---\n\n# Command-Line Interface Implementation Guidelines\n\n**Note on Interaction Method:**\n\nWhile this document details the implementation of Task Master's **CLI commands**, the **preferred method for interacting with Task Master in integrated environments (like Cursor) is through the MCP server tools**. \n\n- **Use MCP Tools First**: Always prefer using the MCP tools (e.g., `get_tasks`, `add_task`) when interacting programmatically or via an integrated tool. They offer better performance, structured data, and richer error handling. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a comprehensive list of MCP tools and their corresponding CLI commands.\n- **CLI as Fallback/User Interface**: The `task-master` CLI commands described here are primarily intended for:\n    - Direct user interaction in the terminal.\n    - A fallback mechanism if the MCP server is unavailable or a specific functionality is not exposed via an MCP tool.\n- **Implementation Context**: This document (`commands.mdc`) focuses on the standards for *implementing* the CLI commands using Commander.js within the [`commands.js`](mdc:scripts/modules/commands.js) module.\n\n## Command Structure Standards\n\n- **Basic Command Template**:\n  ```javascript\n  // ✅ DO: Follow this structure for all commands\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-o, --option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n- **Command Handler Organization**:\n  - ✅ DO: Keep action handlers concise and focused\n  - ✅ DO: Extract core functionality to appropriate modules\n  - ✅ DO: Have the action handler import and call the relevant functions from core modules, like `task-manager.js` or `init.js`, passing the parsed `options`.\n  - ✅ DO: Perform basic parameter validation, such as checking for required options, within the action handler or at the start of the called core function.\n  - ❌ DON'T: Implement business logic in command handlers\n\n## Best Practices for Removal/Delete Commands\n\nWhen implementing commands that delete or remove data (like `remove-task` or `remove-subtask`), follow these specific guidelines:\n\n- **Confirmation Prompts**:\n  - ✅ **DO**: Include a confirmation prompt by default for destructive operations\n  - ✅ **DO**: Provide a `--yes` or `-y` flag to skip confirmation, useful for scripting or automation\n  - ✅ **DO**: Show what will be deleted in the confirmation message\n  - ❌ **DON'T**: Perform destructive operations without user confirmation unless explicitly overridden\n\n  ```javascript\n  // ✅ DO: Include confirmation for destructive operations\n  programInstance\n    .command('remove-task')\n    .description('Remove a task or subtask permanently')\n    .option('-i, --id <id>', 'ID of the task to remove')\n    .option('-y, --yes', 'Skip confirmation prompt', false)\n    .action(async (options) => {\n      // Validation code...\n      \n      if (!options.yes) {\n        const confirm = await inquirer.prompt([{\n          type: 'confirm',\n          name: 'proceed',\n          message: `Are you sure you want to permanently delete task ${taskId}? This cannot be undone.`,\n          default: false\n        }]);\n        \n        if (!confirm.proceed) {\n          console.log(chalk.yellow('Operation cancelled.'));\n          return;\n        }\n      }\n      \n      // Proceed with removal...\n    });\n  ```\n\n- **File Path Handling**:\n  - ✅ **DO**: Use `path.join()` to construct file paths\n  - ✅ **DO**: Follow established naming conventions for tasks, like `task_001.txt`\n  - ✅ **DO**: Check if files exist before attempting to delete them\n  - ✅ **DO**: Handle file deletion errors gracefully\n  - ❌ **DON'T**: Construct paths with string concatenation\n\n  ```javascript\n  // ✅ DO: Properly construct file paths\n  const taskFilePath = path.join(\n    path.dirname(tasksPath),\n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ✅ DO: Check existence before deletion\n  if (fs.existsSync(taskFilePath)) {\n    try {\n      fs.unlinkSync(taskFilePath);\n      console.log(chalk.green(`Task file deleted: ${taskFilePath}`));\n    } catch (error) {\n      console.warn(chalk.yellow(`Could not delete task file: ${error.message}`));\n    }\n  }\n  ```\n\n- **Clean Up References**:\n  - ✅ **DO**: Clean up references to the deleted item in other parts of the data\n  - ✅ **DO**: Handle both direct and indirect references\n  - ✅ **DO**: Explain what related data is being updated\n  - ❌ **DON'T**: Leave dangling references\n\n  ```javascript\n  // ✅ DO: Clean up references when deleting items\n  console.log(chalk.blue('Cleaning up task dependencies...'));\n  let referencesRemoved = 0;\n  \n  // Update dependencies in other tasks\n  data.tasks.forEach(task => {\n    if (task.dependencies && task.dependencies.includes(taskId)) {\n      task.dependencies = task.dependencies.filter(depId => depId !== taskId);\n      referencesRemoved++;\n    }\n  });\n  \n  if (referencesRemoved > 0) {\n    console.log(chalk.green(`Removed ${referencesRemoved} references to task ${taskId} from other tasks`));\n  }\n  ```\n\n- **Task File Regeneration**:\n  - ✅ **DO**: Regenerate task files after destructive operations\n  - ✅ **DO**: Pass all required parameters to generation functions\n  - ✅ **DO**: Provide an option to skip regeneration if needed\n  - ❌ **DON'T**: Assume default parameters will work\n\n  ```javascript\n  // ✅ DO: Properly regenerate files after deletion\n  if (!options.skipGenerate) {\n    console.log(chalk.blue('Regenerating task files...'));\n    try {\n      // Note both parameters are explicitly provided\n      await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n      console.log(chalk.green('Task files regenerated successfully'));\n    } catch (error) {\n      console.warn(chalk.yellow(`Warning: Could not regenerate task files: ${error.message}`));\n    }\n  }\n  ```\n\n- **Alternative Suggestions**:\n  - ✅ **DO**: Suggest non-destructive alternatives when appropriate\n  - ✅ **DO**: Explain the difference between deletion and status changes\n  - ✅ **DO**: Include examples of alternative commands\n\n  ```javascript\n  // ✅ DO: Suggest alternatives for destructive operations\n  console.log(chalk.yellow('Note: If you just want to exclude this task from active work, consider:'));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='cancelled'`));\n  console.log(chalk.cyan(`  task-master set-status --id='${taskId}' --status='deferred'`));\n  console.log('This preserves the task and its history for reference.');\n  ```\n\n## Option Naming Conventions\n\n- **Command Names**:\n  - ✅ DO: Use kebab-case for command names (`analyze-complexity`)\n  - ❌ DON'T: Use camelCase for command names (`analyzeComplexity`)\n  - ✅ DO: Use descriptive, action-oriented names\n\n- **Option Names**:\n  - ✅ DO: Use kebab-case for long-form option names, like `--output-format`\n  - ✅ DO: Provide single-letter shortcuts when appropriate, like `-f, --file`\n  - ✅ DO: Use consistent option names across similar commands\n  - ❌ DON'T: Use different names for the same concept, such as `--file` in one command and `--path` in another\n\n  ```javascript\n  // ✅ DO: Use consistent option naming\n  .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <dir>', 'Output directory', 'tasks')\n  \n  // ❌ DON'T: Use inconsistent naming\n  .option('-f, --file <path>', 'Path to the tasks file')\n  .option('-p, --path <dir>', 'Output directory') // Should be --output\n  ```\n\n  > **Note**: Although options are defined with kebab-case, like `--num-tasks`, Commander.js stores them internally as camelCase properties. Access them in code as `options.numTasks`, not `options['num-tasks']`.\n\n- **Boolean Flag Conventions**:\n  - ✅ DO: Use positive flags with `--skip-` prefix for disabling behavior\n  - ❌ DON'T: Use negated boolean flags with `--no-` prefix\n  - ✅ DO: Use consistent flag handling across all commands\n\n  ```javascript\n  // ✅ DO: Use positive flag with skip- prefix \n  .option('--skip-generate', 'Skip generating task files')\n  \n  // ❌ DON'T: Use --no- prefix \n  .option('--no-generate', 'Skip generating task files')\n  ```\n\n  > **Important**: When handling boolean flags in the code, make your intent clear:\n  ```javascript\n  // ✅ DO: Use clear variable naming that matches the flag's intent\n  const generateFiles = !options.skipGenerate;\n  \n  // ❌ DON'T: Use confusing double negatives\n  const dontSkipGenerate = !options.skipGenerate;\n  ```\n\n## Input Validation\n\n- **Required Parameters**:\n  - ✅ DO: Check that required parameters are provided\n  - ✅ DO: Provide clear error messages when parameters are missing\n  - ✅ DO: Use early returns with `process.exit(1)` for validation failures\n\n  ```javascript\n  // ✅ DO: Validate required parameters early\n  if (!prompt) {\n    console.error(chalk.red('Error: --prompt parameter is required. Please provide a task description.'));\n    process.exit(1);\n  }\n  ```\n\n- **Parameter Type Conversion**:\n  - ✅ DO: Convert string inputs to appropriate types, such as numbers or booleans\n  - ✅ DO: Handle conversion errors gracefully\n\n  ```javascript\n  // ✅ DO: Parse numeric parameters properly\n  const fromId = parseInt(options.from, 10);\n  if (isNaN(fromId)) {\n    console.error(chalk.red('Error: --from must be a valid number'));\n    process.exit(1);\n  }\n  ```\n\n- **Enhanced Input Validation**:\n  - ✅ DO: Validate file existence for critical file operations\n  - ✅ DO: Provide context-specific validation for identifiers\n  - ✅ DO: Check required API keys for features that depend on them\n\n  ```javascript\n  // ✅ DO: Validate file existence\n  if (!fs.existsSync(tasksPath)) {\n    console.error(chalk.red(`Error: Tasks file not found at path: ${tasksPath}`));\n    if (tasksPath === 'tasks/tasks.json') {\n      console.log(chalk.yellow('Hint: Run task-master init or task-master parse-prd to create tasks.json first'));\n    } else {\n      console.log(chalk.yellow(`Hint: Check if the file path is correct: ${tasksPath}`));\n    }\n    process.exit(1);\n  }\n  \n  // ✅ DO: Validate task ID\n  const taskId = parseInt(options.id, 10);\n  if (isNaN(taskId) || taskId <= 0) {\n    console.error(chalk.red(`Error: Invalid task ID: ${options.id}. Task ID must be a positive integer.`));\n    console.log(chalk.yellow(\"Usage example: task-master update-task --id='23' --prompt='Update with new information.\\\\nEnsure proper error handling.'\"));\n    process.exit(1);\n  }\n  \n  // ✅ DO: Check for required API keys\n  if (useResearch && !process.env.PERPLEXITY_API_KEY) {\n    console.log(chalk.yellow('Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'));\n    console.log(chalk.yellow('Falling back to Claude AI for task update.'));\n  }\n  ```\n\n## User Feedback\n\n- **Operation Status**:\n  - ✅ DO: Provide clear feedback about the operation being performed\n  - ✅ DO: Display success or error messages after completion\n  - ✅ DO: Use colored output to distinguish between different message types\n\n  ```javascript\n  // ✅ DO: Show operation status\n  console.log(chalk.blue(`Parsing PRD file: ${file}`));\n  console.log(chalk.blue(`Generating ${numTasks} tasks...`));\n  \n  try {\n    await parsePRD(file, outputPath, numTasks);\n    console.log(chalk.green('Successfully generated tasks from PRD'));\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    process.exit(1);\n  }\n  ```\n\n- **Success Messages with Next Steps**:\n  - ✅ DO: Use boxen for important success messages with clear formatting\n  - ✅ DO: Provide suggested next steps after command completion\n  - ✅ DO: Include ready-to-use commands for follow-up actions\n\n  ```javascript\n  // ✅ DO: Display success with next steps\n  console.log(boxen(\n    chalk.white.bold(`Subtask ${parentId}.${subtask.id} Added Successfully`) + '\\n\\n' +\n    chalk.white(`Title: ${subtask.title}`) + '\\n' +\n    chalk.white(`Status: ${getStatusWithColor(subtask.status)}`) + '\\n' +\n    (dependencies.length > 0 ? chalk.white(`Dependencies: ${dependencies.join(', ')}`) + '\\n' : '') +\n    '\\n' +\n    chalk.white.bold('Next Steps:') + '\\n' +\n    chalk.cyan(`1. Run ${chalk.yellow(`task-master show '${parentId}'`)} to see the parent task with all subtasks`) + '\\n' +\n    chalk.cyan(`2. Run ${chalk.yellow(`task-master set-status --id='${parentId}.${subtask.id}' --status='in-progress'`)} to start working on it`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Command Registration\n\n- **Command Grouping**:\n  - ✅ DO: Group related commands together in the code\n  - ✅ DO: Add related commands in a logical order\n  - ✅ DO: Use comments to delineate command groups\n\n- **Command Export**:\n  - ✅ DO: Export the registerCommands function\n  - ✅ DO: Keep the CLI setup code clean and maintainable\n\n  ```javascript\n  // ✅ DO: Follow this export pattern\n  export {\n    registerCommands,\n    setupCLI,\n    runCLI,\n    checkForUpdate, // Include version checking functions\n    compareVersions,\n    displayUpgradeNotification\n  };\n  ```\n\n## Context-Aware Command Pattern\n\nFor AI-powered commands that benefit from project context, follow the research command pattern:\n\n- **Context Integration**:\n  - ✅ DO: Use `ContextGatherer` utility for multi-source context extraction\n  - ✅ DO: Support task IDs, file paths, custom context, and project tree\n  - ✅ DO: Implement fuzzy search for automatic task discovery\n  - ✅ DO: Display detailed token breakdown for transparency\n\n  ```javascript\n  // ✅ DO: Follow this pattern for context-aware commands\n  programInstance\n    .command('research')\n    .description('Perform AI-powered research queries with project context')\n    .argument('<prompt>', 'Research prompt to investigate')\n    .option('-i, --id <ids>', 'Comma-separated task/subtask IDs to include as context')\n    .option('-f, --files <paths>', 'Comma-separated file paths to include as context')\n    .option('-c, --context <text>', 'Additional custom context')\n    .option('--tree', 'Include project file tree structure')\n    .option('-d, --detail <level>', 'Output detail level: low, medium, high', 'medium')\n    .action(async (prompt, options) => {\n      // 1. Parameter validation and parsing\n      const taskIds = options.id ? parseTaskIds(options.id) : [];\n      const filePaths = options.files ? parseFilePaths(options.files) : [];\n      \n      // 2. Initialize context gatherer\n      const projectRoot = findProjectRoot() || '.';\n      const gatherer = new ContextGatherer(projectRoot, tasksPath);\n      \n      // 3. Auto-discover relevant tasks if none specified\n      if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n          fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n      }\n      \n      // 4. Gather context with token breakdown\n      const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n      });\n      \n      // 5. Display token breakdown and execute AI call\n      // Implementation continues...\n    });\n  ```\n\n## Error Handling\n\n- **Exception Management**:\n  - ✅ DO: Wrap async operations in try/catch blocks\n  - ✅ DO: Display user-friendly error messages\n  - ✅ DO: Include detailed error information in debug mode\n\n  ```javascript\n  // ✅ DO: Handle errors properly\n  try {\n    // Command implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n- **Unknown Options Handling**:\n  - ✅ DO: Provide clear error messages for unknown options\n  - ✅ DO: Show available options when an unknown option is used\n  - ✅ DO: Include command-specific help displays for common errors\n  - ❌ DON'T: Allow unknown options with `.allowUnknownOption()`\n\n  ```javascript\n  // ✅ DO: Register global error handlers for unknown options\n  programInstance.on('option:unknown', function(unknownOption) {\n    const commandName = this._name || 'unknown';\n    console.error(chalk.red(`Error: Unknown option '${unknownOption}'`));\n    console.error(chalk.yellow(`Run 'task-master ${commandName} --help' to see available options`));\n    process.exit(1);\n  });\n  \n  // ✅ DO: Add command-specific help displays\n  function showCommandHelp() {\n    console.log(boxen(\n      chalk.white.bold('Command Help') + '\\n\\n' +\n      chalk.cyan('Usage:') + '\\n' +\n      `  task-master command --option1=<value> [options]\\n\\n` +\n      chalk.cyan('Options:') + '\\n' +\n      '  --option1 <value>    Description of option1 (required)\\n' +\n      '  --option2 <value>    Description of option2\\n\\n' +\n      chalk.cyan('Examples:') + '\\n' +\n      '  task-master command --option1=\\'value1\\' --option2=\\'value2\\'',\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n- **Global Error Handling**:\n  - ✅ DO: Set up global error handlers for uncaught exceptions\n  - ✅ DO: Detect and format Commander-specific errors\n  - ✅ DO: Provide suitable guidance for fixing common errors\n\n  ```javascript\n  // ✅ DO: Set up global error handlers with helpful messages\n  process.on('uncaughtException', (err) => {\n    // Handle Commander-specific errors\n    if (err.code === 'commander.unknownOption') {\n      const option = err.message.match(/'([^']+)'/)?.[1]; // Safely extract option name\n      console.error(chalk.red(`Error: Unknown option '${option}'`));\n      console.error(chalk.yellow(\"Run 'task-master <command> --help' to see available options\"));\n      process.exit(1);\n    }\n    \n    // Handle other error types...\n    console.error(chalk.red(`Error: ${err.message}`));\n    process.exit(1);\n  });\n  ```\n\n- **Contextual Error Handling**:\n  - ✅ DO: Provide specific error handling for common issues\n  - ✅ DO: Include troubleshooting hints for each error type\n  - ✅ DO: Use consistent error formatting across all commands\n\n  ```javascript\n  // ✅ DO: Provide specific error handling with guidance\n  try {\n    // Implementation\n  } catch (error) {\n    console.error(chalk.red(`Error: ${error.message}`));\n    \n    // Provide more helpful error messages for common issues\n    if (error.message.includes('task') && error.message.includes('not found')) {\n      console.log(chalk.yellow('\\nTo fix this issue:'));\n      console.log('  1. Run \\'task-master list\\' to see all available task IDs');\n      console.log('  2. Use a valid task ID with the --id parameter');\n    } else if (error.message.includes('API key')) {\n      console.log(chalk.yellow('\\nThis error is related to API keys. Check your environment variables.'));\n    }\n    \n    if (CONFIG.debug) {\n      console.error(error);\n    }\n    \n    process.exit(1);\n  }\n  ```\n\n## Integration with Other Modules\n\n- **Import Organization**:\n  - ✅ DO: Group imports by module/functionality\n  - ✅ DO: Import only what's needed, not entire modules\n  - ❌ DON'T: Create circular dependencies\n\n  ```javascript\n  // ✅ DO: Organize imports by module\n  import { program } from 'commander';\n  import path from 'path';\n  import chalk from 'chalk';\n  import https from 'https';\n  \n  import { CONFIG, log, readJSON } from './utils.js';\n  import { displayBanner, displayHelp } from './ui.js';\n  import { parsePRD, listTasks } from './task-manager.js';\n  import { addDependency } from './dependency-manager.js';\n  ```\n\n## Subtask Management Commands\n\n- **Add Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for adding subtasks\n  programInstance\n    .command('add-subtask')\n    .description('Add a new subtask to a parent task or convert an existing task to a subtask')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-p, --parent <id>', 'ID of the parent task (required)')\n    .option('-i, --task-id <id>', 'Existing task ID to convert to subtask')\n    .option('-t, --title <title>', 'Title for the new subtask, required if not converting')\n    .option('-d, --description <description>', 'Description for the new subtask, optional')\n    .option('--details <details>', 'Implementation details for the new subtask, optional')\n    .option('--dependencies <ids>', 'Comma-separated list of subtask IDs this subtask depends on')\n    .option('--status <status>', 'Initial status for the subtask', 'pending')\n    .option('--generate', 'Regenerate task files after adding subtask')\n    .action(async (options) => {\n      // Validate required parameters\n      if (!options.parent) {\n        console.error(chalk.red('Error: --parent parameter is required'));\n        showAddSubtaskHelp(); // Show contextual help\n        process.exit(1);\n      }\n      \n      // Implementation with detailed error handling\n    });\n  ```\n\n- **Remove Subtask Command Structure**:\n  ```javascript\n  // ✅ DO: Follow this structure for removing subtasks\n  programInstance\n    .command('remove-subtask')\n    .description('Remove a subtask from its parent task, optionally converting it to a standalone task')\n    .option('-f, --file <path>', 'Path to the tasks file', 'tasks/tasks.json')\n    .option('-i, --id <id>', 'ID of the subtask to remove in format parentId.subtaskId, required')\n    .option('-c, --convert', 'Convert the subtask to a standalone task instead of deleting')\n    .option('--generate', 'Regenerate task files after removing subtask')\n    .action(async (options) => {\n      // Implementation with detailed error handling\n    })\n    .on('error', function(err) {\n      console.error(chalk.red(`Error: ${err.message}`));\n      showRemoveSubtaskHelp(); // Show contextual help\n      process.exit(1);\n    });\n  ```\n\n## Version Checking and Updates\n\n- **Automatic Version Checking**:\n  - ✅ DO: Implement version checking to notify users of available updates\n  - ✅ DO: Use non-blocking version checks that don't delay command execution\n  - ✅ DO: Display update notifications after command completion\n\n  ```javascript\n  // ✅ DO: Implement version checking function\n  async function checkForUpdate() {\n    // Implementation details...\n    // Example return structure:\n    return { currentVersion, latestVersion, updateAvailable };\n  }\n  \n  // ✅ DO: Implement semantic version comparison\n  function compareVersions(v1, v2) {\n    const v1Parts = v1.split('.').map(p => parseInt(p, 10));\n    const v2Parts = v2.split('.').map(p => parseInt(p, 10));\n    \n    // Implementation details...\n    return result; // -1, 0, or 1\n  }\n  \n  // ✅ DO: Display attractive update notifications\n  function displayUpgradeNotification(currentVersion, latestVersion) {\n    const message = boxen(\n      `${chalk.blue.bold('Update Available!')} ${chalk.dim(currentVersion)} → ${chalk.green(latestVersion)}\\n\\n` +\n      `Run ${chalk.cyan('npm i task-master-ai@latest -g')} to update to the latest version with new features and bug fixes.`,\n      {\n        padding: 1,\n        margin: { top: 1, bottom: 1 },\n        borderColor: 'yellow',\n        borderStyle: 'round'\n      }\n    );\n    \n    console.log(message);\n  }\n  \n  // ✅ DO: Integrate version checking in CLI run function\n  async function runCLI(argv = process.argv) {\n    try {\n      // Start the update check in the background - don't await yet\n      const updateCheckPromise = checkForUpdate();\n      \n      // Setup and parse\n      const programInstance = setupCLI();\n      await programInstance.parseAsync(argv);\n      \n      // After command execution, check if an update is available\n      const updateInfo = await updateCheckPromise;\n      if (updateInfo.updateAvailable) {\n        displayUpgradeNotification(updateInfo.currentVersion, updateInfo.latestVersion);\n      }\n    } catch (error) {\n      // Error handling...\n    }\n  }\n  ```\n\nRefer to [`commands.js`](mdc:scripts/modules/commands.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. \n// Helper function to show add-subtask command help\nfunction showAddSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Add Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master add-subtask --parent=<id> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -p, --parent <id>         Parent task ID (required)\\n' +\n    '  -i, --task-id <id>        Existing task ID to convert to subtask\\n' +\n    '  -t, --title <title>       Title for the new subtask\\n' +\n    '  -d, --description <text>  Description for the new subtask\\n' +\n    '  --details <text>          Implementation details for the new subtask\\n' +\n    '  --dependencies <ids>      Comma-separated list of dependency IDs\\n' +\n    '  -s, --status <status>     Status for the new subtask (default: \"pending\")\\n' +\n    '  -f, --file <file>         Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate                Regenerate task files after adding subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master add-subtask --parent=\\'5\\' --task-id=\\'8\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Implement login UI\\' -d \\'Create the login form\\'\\n' +\n    '  task-master add-subtask -p \\'5\\' -t \\'Handle API Errors\\' --details \"Handle 401 Unauthorized.\\\\nHandle 500 Server Error.\" --generate',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n}\n\n// Helper function to show remove-subtask command help\nfunction showRemoveSubtaskHelp() {\n  console.log(boxen(\n    chalk.white.bold('Remove Subtask Command Help') + '\\n\\n' +\n    chalk.cyan('Usage:') + '\\n' +\n    `  task-master remove-subtask --id=<parentId.subtaskId> [options]\\n\\n` +\n    chalk.cyan('Options:') + '\\n' +\n    '  -i, --id <id>       Subtask ID(s) to remove in format \"parentId.subtaskId\" (can be comma-separated, required)\\n' +\n    '  -c, --convert       Convert the subtask to a standalone task instead of deleting it\\n' +\n    '  -f, --file <file>   Path to the tasks file (default: \"tasks/tasks.json\")\\n' +\n    '  --generate          Regenerate task files after removing subtask\\n\\n' +\n    chalk.cyan('Examples:') + '\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2,6.3,7.1\\'\\n' +\n    '  task-master remove-subtask --id=\\'5.2\\' --convert',\n    { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n  ));\n}\n\n<!-- File: .cursor/rules/context_gathering.mdc (Tokens: ~2178 | Category: cursor-rule) -->\n---\ndescription: Standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\nglobs: \nalwaysApply: false\n---\n# Context Gathering Patterns and Utilities\n\nThis document outlines the standardized patterns for gathering and processing context from multiple sources in Task Master commands, particularly for AI-powered features.\n\n## Core Context Gathering Utility\n\nThe `ContextGatherer` class (`scripts/modules/utils/contextGatherer.js`) provides a centralized, reusable utility for extracting context from multiple sources:\n\n### **Key Features**\n- **Multi-source Context**: Tasks, files, custom text, project file tree\n- **Token Counting**: Detailed breakdown using `gpt-tokens` library\n- **Format Support**: Different output formats (research, chat, system-prompt)\n- **Error Handling**: Graceful handling of missing files, invalid task IDs\n- **Performance**: File size limits, depth limits for tree generation\n\n### **Usage Pattern**\n```javascript\nimport { ContextGatherer } from '../utils/contextGatherer.js';\n\n// Initialize with project paths\nconst gatherer = new ContextGatherer(projectRoot, tasksPath);\n\n// Gather context with detailed token breakdown\nconst result = await gatherer.gather({\n    tasks: ['15', '16.2'],           // Task and subtask IDs\n    files: ['src/api.js', 'README.md'], // File paths\n    customContext: 'Additional context text',\n    includeProjectTree: true,        // Include file tree\n    format: 'research',              // Output format\n    includeTokenCounts: true         // Get detailed token breakdown\n});\n\n// Access results\nconst contextString = result.context;\nconst tokenBreakdown = result.tokenBreakdown;\n```\n\n### **Token Breakdown Structure**\n```javascript\n{\n    customContext: { tokens: 150, characters: 800 },\n    tasks: [\n        { id: '15', type: 'task', title: 'Task Title', tokens: 245, characters: 1200 },\n        { id: '16.2', type: 'subtask', title: 'Subtask Title', tokens: 180, characters: 900 }\n    ],\n    files: [\n        { path: 'src/api.js', tokens: 890, characters: 4500, size: '4.5 KB' }\n    ],\n    projectTree: { tokens: 320, characters: 1600 },\n    total: { tokens: 1785, characters: 8000 }\n}\n```\n\n## Fuzzy Search Integration\n\nThe `FuzzyTaskSearch` class (`scripts/modules/utils/fuzzyTaskSearch.js`) provides intelligent task discovery:\n\n### **Key Features**\n- **Semantic Matching**: Uses Fuse.js for similarity scoring\n- **Purpose Categories**: Pattern-based task categorization\n- **Relevance Scoring**: High/medium/low relevance thresholds\n- **Context-Aware**: Different search configurations for different use cases\n\n### **Usage Pattern**\n```javascript\nimport { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n\n// Initialize with tasks data and context\nconst fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n\n// Find relevant tasks\nconst searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n});\n\n// Get task IDs for context gathering\nconst taskIds = fuzzySearch.getTaskIds(searchResults);\n```\n\n## Implementation Patterns for Commands\n\n### **1. Context-Aware Command Structure**\n```javascript\n// In command action handler\nasync function commandAction(prompt, options) {\n    // 1. Parameter validation and parsing\n    const taskIds = options.id ? parseTaskIds(options.id) : [];\n    const filePaths = options.files ? parseFilePaths(options.files) : [];\n    \n    // 2. Initialize context gatherer\n    const projectRoot = findProjectRoot() || '.';\n    const tasksPath = path.join(projectRoot, 'tasks', 'tasks.json');\n    const gatherer = new ContextGatherer(projectRoot, tasksPath);\n    \n    // 3. Auto-discover relevant tasks if none specified\n    if (taskIds.length === 0) {\n        const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n        const discoveredIds = fuzzySearch.getTaskIds(\n            fuzzySearch.findRelevantTasks(prompt)\n        );\n        taskIds.push(...discoveredIds);\n    }\n    \n    // 4. Gather context with token breakdown\n    const contextResult = await gatherer.gather({\n        tasks: taskIds,\n        files: filePaths,\n        customContext: options.context,\n        includeProjectTree: options.projectTree,\n        format: 'research',\n        includeTokenCounts: true\n    });\n    \n    // 5. Display token breakdown (for CLI)\n    if (outputFormat === 'text') {\n        displayDetailedTokenBreakdown(contextResult.tokenBreakdown);\n    }\n    \n    // 6. Use context in AI call\n    const aiResult = await generateTextService(role, session, systemPrompt, userPrompt);\n    \n    // 7. Display results with enhanced formatting\n    displayResults(aiResult, contextResult.tokenBreakdown);\n}\n```\n\n### **2. Token Display Pattern**\n```javascript\nfunction displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    // Build context breakdown\n    if (tokenBreakdown.tasks?.length > 0) {\n        const taskDetails = tokenBreakdown.tasks.map(task => \n            `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n        ).join('\\n');\n        sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    if (tokenBreakdown.files?.length > 0) {\n        const fileDetails = tokenBreakdown.files.map(file =>\n            `  ${file.path}: ${file.tokens.toLocaleString()} (${file.size})`\n        ).join('\\n');\n        sections.push(`Files (${tokenBreakdown.files.reduce((sum, f) => sum + f.tokens, 0).toLocaleString()}):\\n${fileDetails}`);\n    }\n    \n    // Add prompts breakdown\n    sections.push(`Prompts: system ${systemTokens.toLocaleString()}, user ${userTokens.toLocaleString()}`);\n    \n    // Display in clean box\n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n        title: chalk.cyan('Token Usage'),\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        borderStyle: 'round',\n        borderColor: 'cyan'\n    }));\n}\n```\n\n### **3. Enhanced Result Display Pattern**\n```javascript\nfunction displayResults(result, query, detailLevel, tokenBreakdown) {\n    // Header with query info\n    const header = boxen(\n        chalk.green.bold('Research Results') + '\\n\\n' +\n        chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n        chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n        {\n            padding: { top: 1, bottom: 1, left: 2, right: 2 },\n            margin: { top: 1, bottom: 0 },\n            borderStyle: 'round',\n            borderColor: 'green'\n        }\n    );\n    console.log(header);\n    \n    // Process and highlight code blocks\n    const processedResult = processCodeBlocks(result);\n    \n    // Main content in clean box\n    const contentBox = boxen(processedResult, {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 0, bottom: 1 },\n        borderStyle: 'single',\n        borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Research complete'));\n}\n```\n\n## Code Block Enhancement\n\n### **Syntax Highlighting Pattern**\n```javascript\nimport { highlight } from 'cli-highlight';\n\nfunction processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n        try {\n            const highlighted = highlight(code.trim(), { \n                language: language || 'javascript',\n                theme: 'default'\n            });\n            return `\\n${highlighted}\\n`;\n        } catch (error) {\n            return `\\n${code.trim()}\\n`;\n        }\n    });\n}\n```\n\n## Integration Guidelines\n\n### **When to Use Context Gathering**\n- ✅ **DO**: Use for AI-powered commands that benefit from project context\n- ✅ **DO**: Use when users might want to reference specific tasks or files\n- ✅ **DO**: Use for research, analysis, or generation commands\n- ❌ **DON'T**: Use for simple CRUD operations that don't need AI context\n\n### **Performance Considerations**\n- ✅ **DO**: Set reasonable file size limits (50KB default)\n- ✅ **DO**: Limit project tree depth (3-5 levels)\n- ✅ **DO**: Provide token counts to help users understand context size\n- ✅ **DO**: Allow users to control what context is included\n\n### **Error Handling**\n- ✅ **DO**: Gracefully handle missing files with warnings\n- ✅ **DO**: Validate task IDs and provide helpful error messages\n- ✅ **DO**: Continue processing even if some context sources fail\n- ✅ **DO**: Provide fallback behavior when context gathering fails\n\n### **Future Command Integration**\nCommands that should consider adopting this pattern:\n- `analyze-complexity` - Could benefit from file context\n- `expand-task` - Could use related task context\n- `update-task` - Could reference similar tasks for consistency\n- `add-task` - Could use project context for better task generation\n\n## Export Patterns\n\n### **Context Gatherer Module**\n```javascript\nexport {\n    ContextGatherer,\n    createContextGatherer  // Factory function\n};\n```\n\n### **Fuzzy Search Module**\n```javascript\nexport {\n    FuzzyTaskSearch,\n    PURPOSE_CATEGORIES,\n    RELEVANCE_THRESHOLDS\n};\n```\n\nThis context gathering system provides a foundation for building more intelligent, context-aware commands that can leverage project knowledge to provide better AI-powered assistance.\n\n<!-- File: .cursor/rules/cursor_rules.mdc (Tokens: ~377 | Category: cursor-rule) -->\n---\ndescription: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\nglobs: .cursor/rules/*.mdc\nalwaysApply: true\n---\n\n- **Required Rule Structure:**\n  ```markdown\n  ---\n  description: Clear, one-line description of what the rule enforces\n  globs: path/to/files/*.ext, other/path/**/*\n  alwaysApply: boolean\n  ---\n\n  - **Main Points in Bold**\n    - Sub-points with details\n    - Examples and explanations\n  ```\n\n- **File References:**\n  - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files\n  - Example: [prisma.mdc](mdc:.cursor/rules/prisma.mdc) for rule references\n  - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references\n\n- **Code Examples:**\n  - Use language-specific code blocks\n  ```typescript\n  // ✅ DO: Show good examples\n  const goodExample = true;\n  \n  // ❌ DON'T: Show anti-patterns\n  const badExample = false;\n  ```\n\n- **Rule Content Guidelines:**\n  - Start with high-level overview\n  - Include specific, actionable requirements\n  - Show examples of correct implementation\n  - Reference existing code when possible\n  - Keep rules DRY by referencing other rules\n\n- **Rule Maintenance:**\n  - Update rules when new patterns emerge\n  - Add examples from actual codebase\n  - Remove outdated patterns\n  - Cross-reference related rules\n\n- **Best Practices:**\n  - Use bullet points for clarity\n  - Keep descriptions concise\n  - Include both DO and DON'T examples\n  - Reference actual code over theoretical examples\n  - Use consistent formatting across rules\n\n<!-- File: .cursor/rules/dependencies.mdc (Tokens: ~1827 | Category: cursor-rule) -->\n---\ndescription: Guidelines for managing task dependencies and relationships\nglobs: scripts/modules/dependency-manager.js\nalwaysApply: false\n---\n\n# Dependency Management Guidelines\n\n## Dependency Structure Principles\n\n- **Dependency References**:\n  - ✅ DO: Represent task dependencies as arrays of task IDs\n  - ✅ DO: Use numeric IDs for direct task references\n  - ✅ DO: Use string IDs with dot notation (e.g., \"1.2\") for subtask references\n  - ❌ DON'T: Mix reference types without proper conversion\n\n  ```javascript\n  // ✅ DO: Use consistent dependency formats\n  // For main tasks\n  task.dependencies = [1, 2, 3]; // Dependencies on other main tasks\n  \n  // For subtasks\n  subtask.dependencies = [1, \"3.2\"]; // Dependency on main task 1 and subtask 2 of task 3\n  ```\n\n- **Subtask Dependencies**:\n  - ✅ DO: Allow numeric subtask IDs to reference other subtasks within the same parent\n  - ✅ DO: Convert between formats appropriately when needed\n  - ❌ DON'T: Create circular dependencies between subtasks\n\n  ```javascript\n  // ✅ DO: Properly normalize subtask dependencies\n  // When a subtask refers to another subtask in the same parent\n  if (typeof depId === 'number' && depId < 100) {\n    // It's likely a reference to another subtask in the same parent task\n    const fullSubtaskId = `${parentId}.${depId}`;\n    // Now use fullSubtaskId for validation\n  }\n  ```\n\n## Dependency Validation\n\n- **Existence Checking**:\n  - ✅ DO: Validate that referenced tasks exist before adding dependencies\n  - ✅ DO: Provide clear error messages for non-existent dependencies\n  - ✅ DO: Remove references to non-existent tasks during validation\n\n  ```javascript\n  // ✅ DO: Check if the dependency exists before adding\n  if (!taskExists(data.tasks, formattedDependencyId)) {\n    log('error', `Dependency target ${formattedDependencyId} does not exist in tasks.json`);\n    process.exit(1);\n  }\n  ```\n\n- **Circular Dependency Prevention**:\n  - ✅ DO: Check for circular dependencies before adding new relationships\n  - ✅ DO: Use graph traversal algorithms (DFS) to detect cycles\n  - ✅ DO: Provide clear error messages explaining the circular chain\n\n  ```javascript\n  // ✅ DO: Check for circular dependencies before adding\n  const dependencyChain = [formattedTaskId];\n  if (isCircularDependency(data.tasks, formattedDependencyId, dependencyChain)) {\n    log('error', `Cannot add dependency ${formattedDependencyId} to task ${formattedTaskId} as it would create a circular dependency.`);\n    process.exit(1);\n  }\n  ```\n\n- **Self-Dependency Prevention**:\n  - ✅ DO: Prevent tasks from depending on themselves\n  - ✅ DO: Handle both direct and indirect self-dependencies\n\n  ```javascript\n  // ✅ DO: Prevent self-dependencies\n  if (String(formattedTaskId) === String(formattedDependencyId)) {\n    log('error', `Task ${formattedTaskId} cannot depend on itself.`);\n    process.exit(1);\n  }\n  ```\n\n## Dependency Modification\n\n- **Adding Dependencies**:\n  - ✅ DO: Format task and dependency IDs consistently\n  - ✅ DO: Check for existing dependencies to prevent duplicates\n  - ✅ DO: Sort dependencies for better readability\n\n  ```javascript\n  // ✅ DO: Format IDs consistently when adding dependencies\n  const formattedTaskId = typeof taskId === 'string' && taskId.includes('.') \n    ? taskId : parseInt(taskId, 10);\n  \n  const formattedDependencyId = formatTaskId(dependencyId);\n  ```\n\n- **Removing Dependencies**:\n  - ✅ DO: Check if the dependency exists before removing\n  - ✅ DO: Handle different ID formats consistently\n  - ✅ DO: Provide feedback about the removal result\n\n  ```javascript\n  // ✅ DO: Properly handle dependency removal\n  const dependencyIndex = targetTask.dependencies.findIndex(dep => {\n    // Convert both to strings for comparison\n    let depStr = String(dep);\n    \n    // Handle relative subtask references\n    if (typeof dep === 'number' && dep < 100 && isSubtask) {\n      const [parentId] = formattedTaskId.split('.');\n      depStr = `${parentId}.${dep}`;\n    }\n    \n    return depStr === normalizedDependencyId;\n  });\n  \n  if (dependencyIndex === -1) {\n    log('info', `Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`);\n    return;\n  }\n  \n  // Remove the dependency\n  targetTask.dependencies.splice(dependencyIndex, 1);\n  ```\n\n## Dependency Cleanup\n\n- **Duplicate Removal**:\n  - ✅ DO: Use Set objects to identify and remove duplicates\n  - ✅ DO: Handle both numeric and string ID formats\n\n  ```javascript\n  // ✅ DO: Remove duplicate dependencies\n  const uniqueDeps = new Set();\n  const uniqueDependencies = task.dependencies.filter(depId => {\n    // Convert to string for comparison to handle both numeric and string IDs\n    const depIdStr = String(depId);\n    if (uniqueDeps.has(depIdStr)) {\n      log('warn', `Removing duplicate dependency from task ${task.id}: ${depId}`);\n      return false;\n    }\n    uniqueDeps.add(depIdStr);\n    return true;\n  });\n  ```\n\n- **Invalid Reference Cleanup**:\n  - ✅ DO: Check for and remove references to non-existent tasks\n  - ✅ DO: Check for and remove self-references\n  - ✅ DO: Track and report changes made during cleanup\n\n  ```javascript\n  // ✅ DO: Filter invalid task dependencies\n  task.dependencies = task.dependencies.filter(depId => {\n    const numericId = typeof depId === 'string' ? parseInt(depId, 10) : depId;\n    if (!validTaskIds.has(numericId)) {\n      log('warn', `Removing invalid task dependency from task ${task.id}: ${depId} (task does not exist)`);\n      return false;\n    }\n    return true;\n  });\n  ```\n\n## Dependency Visualization\n\n- **Status Indicators**:\n  - ✅ DO: Use visual indicators to show dependency status (✅/⏱️)\n  - ✅ DO: Format dependency lists consistently\n\n  ```javascript\n  // ✅ DO: Format dependencies with status indicators\n  function formatDependenciesWithStatus(dependencies, allTasks) {\n    if (!dependencies || dependencies.length === 0) {\n      return 'None';\n    }\n    \n    return dependencies.map(depId => {\n      const depTask = findTaskById(allTasks, depId);\n      if (!depTask) return `${depId} (Not found)`;\n      \n      const isDone = depTask.status === 'done' || depTask.status === 'completed';\n      const statusIcon = isDone ? '✅' : '⏱️';\n      \n      return `${statusIcon} ${depId} (${depTask.status})`;\n    }).join(', ');\n  }\n  ```\n\n## Cycle Detection\n\n- **Graph Traversal**:\n  - ✅ DO: Use depth-first search (DFS) for cycle detection\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Support both task and subtask dependencies\n\n  ```javascript\n  // ✅ DO: Use proper cycle detection algorithms\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set()) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    \n    const cyclesToBreak = [];\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    for (const depId of dependencies) {\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack);\n        cyclesToBreak.push(...cycles);\n      } \n      else if (recursionStack.has(depId)) {\n        // Found a cycle, add the edge to break\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\nRefer to [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines.\n\n<!-- File: .cursor/rules/dev_workflow.mdc (Tokens: ~6978 | Category: cursor-rule) -->\n---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc))\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*\n\n<!-- File: .cursor/rules/git_workflow.mdc (Tokens: ~2932 | Category: cursor-rule) -->\n---\ndescription: Git workflow integrated with Task Master for feature development and collaboration\nglobs: \"**/*\"\nalwaysApply: true\n---\n# Git Workflow with Task Master Integration\n\n## **Branch Strategy**\n\n### **Main Branch Protection**\n- **main** branch contains production-ready code\n- All feature development happens on task-specific branches\n- Direct commits to main are prohibited\n- All changes merge via Pull Requests\n\n### **Task Branch Naming**\n```bash\n# ✅ DO: Use consistent task branch naming\ntask-001  # For Task 1\ntask-004  # For Task 4\ntask-015  # For Task 15\n\n# ❌ DON'T: Use inconsistent naming\nfeature/user-auth\nfix-database-issue\nrandom-branch-name\n```\n\n## **Tagged Task Lists Integration**\n\nTask Master's **tagged task lists system** provides significant benefits for Git workflows:\n\n### **Multi-Context Development**\n- **Branch-Specific Tasks**: Each branch can have its own task context using tags\n- **Merge Conflict Prevention**: Tasks in different tags are completely isolated\n- **Context Switching**: Seamlessly switch between different development contexts\n- **Parallel Development**: Multiple team members can work on separate task contexts\n\n### **Migration and Compatibility**\n- **Seamless Migration**: Existing projects automatically migrate to use a \"master\" tag\n- **Zero Disruption**: All existing Git workflows continue unchanged\n- **Backward Compatibility**: Legacy projects work exactly as before\n\n### **Manual Git Integration**\n- **Manual Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Switching**: Explicitly switch tag contexts as needed for different branches\n- **Simplified Integration**: Focused on manual control rather than automatic workflows\n\n## **Workflow Overview**\n\n```mermaid\nflowchart TD\n    A[Start: On main branch] --> B[Pull latest changes]\n    B --> C[Create task branch<br/>git checkout -b task-XXX]\n    C --> D[Set task status: in-progress]\n    D --> E[Get task context & expand if needed<br/>Tasks automatically use current tag]\n    E --> F[Identify next subtask]\n    \n    F --> G[Set subtask: in-progress]\n    G --> H[Research & collect context<br/>update_subtask with findings]\n    H --> I[Implement subtask]\n    I --> J[Update subtask with completion]\n    J --> K[Set subtask: done]\n    K --> L[Git commit subtask]\n    \n    L --> M{More subtasks?}\n    M -->|Yes| F\n    M -->|No| N[Run final tests]\n    \n    N --> O[Commit tests if added]\n    O --> P[Push task branch]\n    P --> Q[Create Pull Request]\n    Q --> R[Human review & merge]\n    R --> S[Switch to main & pull]\n    S --> T[Delete task branch]\n    T --> U[Ready for next task]\n    \n    style A fill:#e1f5fe\n    style C fill:#f3e5f5\n    style G fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n    style R fill:#f1f8e9\n    style U fill:#e1f5fe\n```\n\n## **Complete Task Development Workflow**\n\n### **Phase 1: Task Preparation**\n```bash\n# 1. Ensure you're on main branch and pull latest\ngit checkout main\ngit pull origin main\n\n# 2. Check current branch status\ngit branch  # Verify you're on main\n\n# 3. Create task-specific branch\ngit checkout -b task-004  # For Task 4\n\n# 4. Set task status in Task Master (tasks automatically use current tag context)\n# Use: set_task_status tool or `task-master set-status --id=4 --status=in-progress`\n```\n\n### **Phase 2: Task Analysis & Planning**\n```bash\n# 5. Get task context and expand if needed (uses current tag automatically)\n# Use: get_task tool or `task-master show 4`\n# Use: expand_task tool or `task-master expand --id=4 --research --force` (if complex)\n\n# 6. Identify next subtask to work on\n# Use: next_task tool or `task-master next`\n```\n\n### **Phase 3: Subtask Implementation Loop**\nFor each subtask, follow this pattern:\n\n```bash\n# 7. Mark subtask as in-progress\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=in-progress`\n\n# 8. Gather context and research (if needed)\n# Use: update_subtask tool with research flag or:\n# `task-master update-subtask --id=4.1 --prompt=\"Research findings...\" --research`\n\n# 9. Collect code context through AI exploration\n# Document findings in subtask using update_subtask\n\n# 10. Implement the subtask\n# Write code, tests, documentation\n\n# 11. Update subtask with completion details\n# Use: update_subtask tool or:\n# `task-master update-subtask --id=4.1 --prompt=\"Implementation complete...\"`\n\n# 12. Mark subtask as done\n# Use: set_task_status tool or `task-master set-status --id=4.1 --status=done`\n\n# 13. Commit the subtask implementation\ngit add .\ngit commit -m \"feat(task-4): Complete subtask 4.1 - [Subtask Title]\n\n- Implementation details\n- Key changes made\n- Any important notes\n\nSubtask 4.1: [Brief description of what was accomplished]\nRelates to Task 4: [Main task title]\"\n```\n\n### **Phase 4: Task Completion**\n```bash\n# 14. When all subtasks are complete, run final testing\n# Create test file if needed, ensure all tests pass\nnpm test  # or jest, or manual testing\n\n# 15. If tests were added/modified, commit them\ngit add .\ngit commit -m \"test(task-4): Add comprehensive tests for Task 4\n\n- Unit tests for core functionality\n- Integration tests for API endpoints\n- All tests passing\n\nTask 4: [Main task title] - Testing complete\"\n\n# 16. Push the task branch\ngit push origin task-004\n\n# 17. Create Pull Request\n# Title: \"Task 4: [Task Title]\"\n# Description should include:\n# - Task overview\n# - Subtasks completed\n# - Testing approach\n# - Any breaking changes or considerations\n```\n\n### **Phase 5: PR Merge & Cleanup**\n```bash\n# 18. Human reviews and merges PR into main\n\n# 19. Switch back to main and pull merged changes\ngit checkout main\ngit pull origin main\n\n# 20. Delete the feature branch (optional cleanup)\ngit branch -d task-004\ngit push origin --delete task-004\n```\n\n## **Commit Message Standards**\n\n### **Subtask Commits**\n```bash\n# ✅ DO: Consistent subtask commit format\ngit commit -m \"feat(task-4): Complete subtask 4.1 - Initialize Express server\n\n- Set up Express.js with TypeScript configuration\n- Added CORS and body parsing middleware\n- Implemented health check endpoints\n- Basic error handling middleware\n\nSubtask 4.1: Initialize project with npm and install dependencies\nRelates to Task 4: Setup Express.js Server Project\"\n\n# ❌ DON'T: Vague or inconsistent commits\ngit commit -m \"fixed stuff\"\ngit commit -m \"working on task\"\n```\n\n### **Test Commits**\n```bash\n# ✅ DO: Separate test commits when substantial\ngit commit -m \"test(task-4): Add comprehensive tests for Express server setup\n\n- Unit tests for middleware configuration\n- Integration tests for health check endpoints\n- Mock tests for database connection\n- All tests passing with 95% coverage\n\nTask 4: Setup Express.js Server Project - Testing complete\"\n```\n\n### **Commit Type Prefixes**\n- `feat(task-X):` - New feature implementation\n- `fix(task-X):` - Bug fixes\n- `test(task-X):` - Test additions/modifications\n- `docs(task-X):` - Documentation updates\n- `refactor(task-X):` - Code refactoring\n- `chore(task-X):` - Build/tooling changes\n\n## **Task Master Commands Integration**\n\n### **Essential Commands for Git Workflow**\n```bash\n# Task management (uses current tag context automatically)\ntask-master show <id>           # Get task/subtask details\ntask-master next                # Find next task to work on\ntask-master set-status --id=<id> --status=<status>\ntask-master update-subtask --id=<id> --prompt=\"...\" --research\n\n# Task expansion (for complex tasks)\ntask-master expand --id=<id> --research --force\n\n# Progress tracking\ntask-master list                # View all tasks and status\ntask-master list --status=in-progress  # View active tasks\n```\n\n### **MCP Tool Equivalents**\nWhen using Cursor or other MCP-integrated tools:\n- `get_task` instead of `task-master show`\n- `next_task` instead of `task-master next`\n- `set_task_status` instead of `task-master set-status`\n- `update_subtask` instead of `task-master update-subtask`\n\n## **Branch Management Rules**\n\n### **Branch Protection**\n```bash\n# ✅ DO: Always work on task branches\ngit checkout -b task-005\n# Make changes\ngit commit -m \"...\"\ngit push origin task-005\n\n# ❌ DON'T: Commit directly to main\ngit checkout main\ngit commit -m \"...\"  # NEVER do this\n```\n\n### **Keeping Branches Updated**\n```bash\n# ✅ DO: Regularly sync with main (for long-running tasks)\ngit checkout task-005\ngit fetch origin\ngit rebase origin/main  # or merge if preferred\n\n# Resolve any conflicts and continue\n```\n\n## **Pull Request Guidelines**\n\n### **PR Title Format**\n```\nTask <ID>: <Task Title>\n\nExamples:\nTask 4: Setup Express.js Server Project\nTask 7: Implement User Authentication\nTask 12: Add Stripe Payment Integration\n```\n\n### **PR Description Template**\n```markdown\n## Task Overview\nBrief description of the main task objective.\n\n## Subtasks Completed\n- [x] 4.1: Initialize project with npm and install dependencies\n- [x] 4.2: Configure TypeScript, ESLint and Prettier  \n- [x] 4.3: Create basic Express app with middleware and health check route\n\n## Implementation Details\n- Key architectural decisions made\n- Important code changes\n- Any deviations from original plan\n\n## Testing\n- [ ] Unit tests added/updated\n- [ ] Integration tests passing\n- [ ] Manual testing completed\n\n## Breaking Changes\nList any breaking changes or migration requirements.\n\n## Related Tasks\nMention any dependent tasks or follow-up work needed.\n```\n\n## **Conflict Resolution**\n\n### **Task Conflicts with Tagged System**\n```bash\n# With tagged task lists, merge conflicts are significantly reduced:\n# 1. Different branches can use different tag contexts\n# 2. Tasks in separate tags are completely isolated\n# 3. Use Task Master's move functionality to reorganize if needed\n\n# Manual git integration available:\n# - Use `task-master add-tag --from-branch` to create tags from current branch\n# - Manually switch contexts with `task-master use-tag <name>`\n# - Simple, predictable workflow without automatic behavior\n```\n\n### **Code Conflicts**\n```bash\n# Standard Git conflict resolution\ngit fetch origin\ngit rebase origin/main\n# Resolve conflicts in files\ngit add .\ngit rebase --continue\n```\n\n## **Emergency Procedures**\n\n### **Hotfixes**\n```bash\n# For urgent production fixes:\ngit checkout main\ngit pull origin main\ngit checkout -b hotfix-urgent-issue\n\n# Make minimal fix\ngit commit -m \"hotfix: Fix critical production issue\n\n- Specific fix description\n- Minimal impact change\n- Requires immediate deployment\"\n\ngit push origin hotfix-urgent-issue\n# Create emergency PR for immediate review\n```\n\n### **Task Abandonment**\n```bash\n# If task needs to be abandoned or significantly changed:\n# 1. Update task status\ntask-master set-status --id=<id> --status=cancelled\n\n# 2. Clean up branch\ngit checkout main\ngit branch -D task-<id>\ngit push origin --delete task-<id>\n\n# 3. Document reasoning in task\ntask-master update-task --id=<id> --prompt=\"Task cancelled due to...\"\n```\n\n## **Tagged System Benefits for Git Workflows**\n\n### **Multi-Team Development**\n- **Isolated Contexts**: Different teams can work on separate tag contexts without conflicts\n- **Feature Branches**: Each feature branch can have its own task context\n- **Release Management**: Separate tags for different release versions or environments\n\n### **Merge Conflict Prevention**\n- **Context Separation**: Tasks in different tags don't interfere with each other\n- **Clean Merges**: Reduced likelihood of task-related merge conflicts\n- **Parallel Development**: Multiple developers can work simultaneously without task conflicts\n\n### **Manual Git Integration**\n- **Branch-Based Tag Creation**: Use `--from-branch` option to create tags from current git branch\n- **Manual Context Management**: Explicitly switch tag contexts as needed\n- **Predictable Workflow**: Simple, manual control without automatic behavior\n\n---\n\n**References:**\n- [Task Master Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Architecture Guidelines](mdc:.cursor/rules/architecture.mdc)\n- [Task Master Commands](mdc:.cursor/rules/taskmaster.mdc)\n\n<!-- File: .cursor/rules/glossary.mdc (Tokens: ~569 | Category: cursor-rule) -->\n---\ndescription: Glossary of other Cursor rules\nglobs: **/*\nalwaysApply: true\n---\n# Glossary of Task Master Cursor Rules\n\nThis file provides a quick reference to the purpose of each rule file located in the `.cursor/rules` directory.\n\n- **[`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)**: Describes the high-level architecture of the Task Master CLI application, including the new tagged task lists system.\n- **[`changeset.mdc`](mdc:.cursor/rules/changeset.mdc)**: Guidelines for using Changesets (npm run changeset) to manage versioning and changelogs.\n- **[`commands.mdc`](mdc:.cursor/rules/commands.mdc)**: Guidelines for implementing CLI commands using Commander.js.\n- **[`cursor_rules.mdc`](mdc:.cursor/rules/cursor_rules.mdc)**: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness.\n- **[`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc)**: Guidelines for managing task dependencies and relationships across tagged task contexts.\n- **[`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc)**: Guide for using Task Master to manage task-driven development workflows with tagged task lists support.\n- **[`glossary.mdc`](mdc:.cursor/rules/glossary.mdc)**: This file; provides a glossary of other Cursor rules.\n- **[`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)**: Guidelines for implementing and interacting with the Task Master MCP Server.\n- **[`new_features.mdc`](mdc:.cursor/rules/new_features.mdc)**: Guidelines for integrating new features into the Task Master CLI with tagged system considerations.\n- **[`self_improve.mdc`](mdc:.cursor/rules/self_improve.mdc)**: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\n- **[`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc)**: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information.\n- **[`tasks.mdc`](mdc:.cursor/rules/tasks.mdc)**: Guidelines for implementing task management operations with tagged task lists system support.\n- **[`tests.mdc`](mdc:.cursor/rules/tests.mdc)**: Guidelines for implementing and maintaining tests for Task Master CLI.\n- **[`ui.mdc`](mdc:.cursor/rules/ui.mdc)**: Guidelines for implementing and maintaining user interface components.\n- **[`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)**: Guidelines for implementing utility functions including tagged task lists utilities.\n- **[`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc)**: Guidelines for integrating AI usage telemetry across Task Master.\n\n<!-- File: .cursor/rules/hamster.mdc (Tokens: ~1552 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing tasks imported from Hamster using Task Master CLI\nglobs: \"**/*\"\nalwaysApply: true\n---\n\n# Hamster Integration Workflow\n\nThis guide outlines the process for working with tasks imported from Hamster briefs using Task Master. When connected to a Hamster brief, follow these specific guidelines to ensure proper task management and workflow execution.\n\n## **Command Restrictions**\n\n### **Supported Commands**\n- **✅ DO**: Use only these Task Master CLI commands when working with Hamster briefs:\n  ```bash\n  tm list                      # List all tasks\n  tm show <sub/task id> --json # Show task details\n  tm set-status                # Update task status\n  tm auth refresh              # Refresh authentication token\n  tm context <brief url>       # Reconnect to Hamster brief context\n  ```\n\n### **Unsupported Commands**\n- **❌ DON'T**: Use MCP tools when connected with Hamster briefs - they are not yet up to date with Hamster integration\n- **❌ DON'T**: Use other Task Master CLI commands that haven't been verified to work with Hamster integration\n\n## **Task Workflow Process**\n\n### **Starting a Task**\n```bash\n# ✅ DO: Mark task and subtasks as in-progress when starting\ntm set-status -i 1,1.1 -s in-progress\n\n# Multiple tasks/subtasks can be marked at once using comma separation\ntm set-status -i 1,1.1,1.2,2 -s in-progress\n```\n\n### **Task Implementation Flow**\n1. **Read the Task**: Use `tm show <id> --json` to understand the task requirements (json used to save tokens, gets you same information)\n2. **Check for Subtasks**: If the task has subtasks, implement them one at a time\n3. **Implement Subtask**: Complete the subtask implementation\n4. **Verify Quality**: Run lint and typecheck before marking as done\n   ```bash\n   npm lint\n   npm typecheck\n   ```\n5. **Mark Complete**: If verification passes, mark the subtask as done\n   ```bash\n   tm set-status -i 1.1 -s done\n   ```\n6. **Commit Changes**: Commit the completed subtask work\n7. **Repeat**: Continue until all subtasks are complete\n\n### **Parent Task Completion**\n- After all subtasks are done, run final verification:\n  ```bash\n  npm lint\n  npm typecheck\n  ```\n- Mark the parent task as done:\n  ```bash\n  tm set-status -i 1 -s done\n  ```\n- Move to the next task and repeat the process\n\n## **Multiple Task Context**\n\n### **Viewing Multiple Tasks**\n```bash\n# ✅ DO: Use comma-separated IDs to get context from multiple tasks\ntm show 1,1.1,2,2.1 --json\n\n# This is more efficient than calling tm show multiple times\n```\n\n### **Parallel Subtask Execution**\n- **When to Parallelize**: If a task has subtasks that can be completed in parallel\n- **Requirements**:\n  - Ensure work/files to adjust are **not the same** across subtasks\n  - Spawn sub-agents for each parallel subtask\n  - Verify clear separation of work before parallelizing\n- **Example**: If subtask 1.1 modifies `src/api.js` and subtask 1.2 modifies `src/utils.js`, these can run in parallel\n\n## **Pull Request Management**\n\n### **PR Creation Strategy**\n- **Preferred Approach**: Keep everything in one PR if scope remains manageable\n- **When to Split**: Create separate PRs if the work becomes too large\n- **Multi-PR Strategy**: If splitting is necessary:\n  - Create PRs that build on top of previous ones\n  - **Always confirm with the human** before creating multiple PRs\n- **PR Creation**: Use GitHub CLI after completing a task:\n  ```bash\n  gh pr create --title \"Task X: [Task Title]\" --body \"Description\"\n  ```\n\n### **Committing to PRs**\n- Keep committing to the same PR as long as the scope is maintained\n- An entire task list (brief) might fit into a single PR\n- If scope grows too large, discuss with human before creating new PRs\n\n## **Authentication & Context Management**\n\n### **Token Refresh**\n```bash\n# ✅ DO: Refresh token if JWT seems expired or commands don't work\ntm auth refresh\n\n# If refresh doesn't work, reconnect context\ntm context <brief url>\n```\n\n### **Context Reconnection**\n- **When Needed**: If commands stop working or authentication fails\n- **Required Information**: Brief URL (ask user if not available)\n- **Best Practice**: Store brief URL at the beginning of the session\n- **Command**: `tm context <brief url>`\n\n## **Integration with Git Workflow**\n\nWhen working with Hamster briefs, follow the standard Git workflow patterns outlined in [git_workflow.mdc](mdc:.cursor/rules/git_workflow.mdc):\n\n- Create task-specific branches: `task-XXX`\n- Commit subtask work incrementally\n- Create PRs after task completion\n- Follow commit message standards\n\n## **Workflow Summary**\n\n```mermaid\nflowchart TD\n    A[Start: Connect to Hamster Brief] --> B[Get Brief URL]\n    B --> C[tm list - View Tasks]\n    C --> D[Select Task]\n    D --> E[tm show <id> --json - Read Task]\n    E --> F{Has Subtasks?}\n    F -->|Yes| G[Select First Subtask]\n    F -->|No| M[Implement Task]\n    G --> H[tm set-status -i X.Y -s in-progress]\n    H --> I[Implement Subtask]\n    I --> J[npm lint && npm typecheck]\n    J --> K{Passes?}\n    K -->|Yes| L[tm set-status -i X.Y -s done]\n    K -->|No| I\n    L --> N{More Subtasks?}\n    N -->|Yes| G\n    N -->|No| O[Final lint/typecheck]\n    M --> O\n    O --> P[tm set-status -i X -s done]\n    P --> Q[Commit & Create PR]\n    Q --> R{More Tasks?}\n    R -->|Yes| D\n    R -->|No| S[Complete]\n    \n    style A fill:#e1f5fe\n    style H fill:#fff3e0\n    style L fill:#e8f5e8\n    style Q fill:#fce4ec\n```\n\n## **Key Principles**\n\n- **Incremental Progress**: Work through subtasks one at a time\n- **Quality Gates**: Always run lint and typecheck before marking tasks as done\n- **Clear Communication**: Confirm with human before splitting work across multiple PRs\n- **Efficient Context Gathering**: Use comma-separated IDs when viewing multiple tasks\n- **Authentication Management**: Proactively refresh tokens and reconnect context when needed\n\n## **Related Rules**\n\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc) - Standard Git branching and PR practices\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc) - General Task Master development patterns\n- [Task Management](mdc:.cursor/rules/tasks.mdc) - Task structure and operations\n\n<!-- File: .cursor/rules/mcp.mdc (Tokens: ~7200 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing and interacting with the Task Master MCP Server\nglobs: mcp-server/src/**/*, scripts/modules/**/*\nalwaysApply: false\n---\n# Task Master MCP Server Guidelines\n\nThis document outlines the architecture and implementation patterns for the Task Master Model Context Protocol (MCP) server, designed for integration with tools like Cursor.\n\n## Architecture Overview (See also: [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc))\n\nThe MCP server acts as a bridge between external tools (like Cursor) and the core Task Master CLI logic. It leverages FastMCP for the server framework.\n\n- **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/direct-functions/*.js`, exported via `task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`)\n- **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation.\n\n## Direct Function Implementation Best Practices\n\nWhen implementing a new direct function in `mcp-server/src/core/direct-functions/`, follow these critical guidelines:\n\n1. **Verify Function Dependencies**:\n   - ✅ **DO**: Check that all helper functions your direct function needs are properly exported from their source modules\n   - ✅ **DO**: Import these dependencies explicitly at the top of your file\n   - ❌ **DON'T**: Assume helper functions like `findTaskById` or `taskExists` are automatically available\n   - **Example**:\n     ```javascript\n     // At top of direct-function file\n     import { removeTask, findTaskById, taskExists } from '../../../../scripts/modules/task-manager.js';\n     ```\n\n2. **Parameter Verification and Completeness**:\n   - ✅ **DO**: Verify the signature of core functions you're calling and ensure all required parameters are provided\n   - ✅ **DO**: Pass explicit values for required parameters rather than relying on defaults\n   - ✅ **DO**: Double-check parameter order against function definition\n   - ❌ **DON'T**: Omit parameters assuming they have default values\n   - **Example**:\n     ```javascript\n     // Correct parameter handling in direct function\n     async function generateTaskFilesDirect(args, log) {\n       const tasksPath = findTasksJsonPath(args, log);\n       const outputDir = args.output || path.dirname(tasksPath);\n       \n       try {\n         // Pass all required parameters\n         const result = await generateTaskFiles(tasksPath, outputDir);\n         return { success: true, data: result, fromCache: false };\n       } catch (error) {\n         // Error handling...\n       }\n     }\n     ```\n\n3. **Consistent File Path Handling**:\n   - ✅ **DO**: Use `path.join()` instead of string concatenation for file paths\n   - ✅ **DO**: Follow established file naming conventions (`task_001.txt` not `1.md`)\n   - ✅ **DO**: Use `path.dirname()` and other path utilities for manipulating paths\n   - ✅ **DO**: When paths relate to task files, follow the standard format: `task_${id.toString().padStart(3, '0')}.txt`\n   - ❌ **DON'T**: Create custom file path handling logic that diverges from established patterns\n   - **Example**:\n     ```javascript\n     // Correct file path handling\n     const taskFilePath = path.join(\n       path.dirname(tasksPath),\n       `task_${taskId.toString().padStart(3, '0')}.txt`\n     );\n     ```\n\n4. **Comprehensive Error Handling**:\n   - ✅ **DO**: Wrap core function calls *and AI calls* in try/catch blocks\n   - ✅ **DO**: Log errors with appropriate severity and context\n   - ✅ **DO**: Return standardized error objects with code and message (`{ success: false, error: { code: '...', message: '...' } }`)\n   - ✅ **DO**: Handle file system errors, AI client errors, AI processing errors, and core function errors distinctly with appropriate codes.\n   - **Example**:\n     ```javascript\n     try {\n       // Core function call or AI logic\n     } catch (error) {\n       log.error(`Failed to execute direct function logic: ${error.message}`);\n       return {\n         success: false,\n         error: {\n           code: error.code || 'DIRECT_FUNCTION_ERROR', // Use specific codes like AI_CLIENT_ERROR, etc.\n           message: error.message,\n           details: error.stack // Optional: Include stack in debug mode\n         },\n         fromCache: false // Ensure this is included if applicable\n       };\n     }\n     ```\n\n5. **Handling Logging Context (`mcpLog`)**:\n   - **Requirement**: Core functions (like those in `task-manager.js`) may accept an `options` object containing an optional `mcpLog` property. If provided, the core function expects this object to have methods like `mcpLog.info(...)`, `mcpLog.error(...)`.\n   - **Solution: The Logger Wrapper Pattern**: When calling a core function from a direct function, pass the `log` object provided by FastMCP *wrapped* in the standard `logWrapper` object. This ensures the core function receives a logger with the expected method structure.\n     ```javascript\n     // Standard logWrapper pattern within a Direct Function\n     const logWrapper = {\n       info: (message, ...args) => log.info(message, ...args),\n       warn: (message, ...args) => log.warn(message, ...args),\n       error: (message, ...args) => log.error(message, ...args),\n       debug: (message, ...args) => log.debug && log.debug(message, ...args),\n       success: (message, ...args) => log.info(message, ...args)\n     };\n\n     // ... later when calling the core function ...\n     await coreFunction(\n       // ... other arguments ...\n       { \n         mcpLog: logWrapper, // Pass the wrapper object\n         session // Also pass session if needed by core logic or AI service\n       },\n       'json' // Pass 'json' output format if supported by core function\n     );\n     ```\n   - **JSON Output**: Passing `mcpLog` (via the wrapper) often triggers the core function to use a JSON-friendly output format, suppressing spinners/boxes.\n   - ✅ **DO**: Implement this pattern in direct functions calling core functions that might use `mcpLog`.\n\n6. **Silent Mode Implementation**:\n    - ✅ **DO**: Import silent mode utilities: `import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';`\n    - ✅ **DO**: Wrap core function calls *within direct functions* using `enableSilentMode()` / `disableSilentMode()` in a `try/finally` block if the core function might produce console output (spinners, boxes, direct `console.log`) that isn't reliably controlled by passing `{ mcpLog }` or an `outputFormat` parameter.\n    - ✅ **DO**: Always disable silent mode in the `finally` block.\n    - ❌ **DON'T**: Wrap calls to the unified AI service (`generateTextService`, `generateObjectService`) in silent mode; their logging is handled internally.\n    - **Example (Direct Function Guaranteeing Silence & using Log Wrapper)**:\n      ```javascript\n      export async function coreWrapperDirect(args, log, context = {}) {\n        const { session } = context;\n        const tasksPath = findTasksJsonPath(args, log);\n        const logWrapper = { /* ... */ };\n\n        enableSilentMode(); // Ensure silence for direct console output\n        try {\n          const result = await coreFunction(\n             tasksPath,\n             args.param1,\n             { mcpLog: logWrapper, session }, // Pass context\n             'json' // Request JSON format if supported\n          );\n          return { success: true, data: result };\n        } catch (error) {\n           log.error(`Error: ${error.message}`);\n           return { success: false, error: { /* ... */ } };\n        } finally {\n           disableSilentMode(); // Critical: Always disable in finally\n        }\n      }\n      ```\n\n7. **Debugging MCP/Core Logic Interaction**:\n    - ✅ **DO**: If an MCP tool fails with unclear errors (like JSON parsing failures), run the equivalent `task-master` CLI command in the terminal. The CLI often provides more detailed error messages originating from the core logic (e.g., `ReferenceError`, stack traces) that are obscured by the MCP layer.\n\n## Tool Definition and Execution\n\n### Tool Structure\n\nMCP tools must follow a specific structure to properly interact with the FastMCP framework:\n\n```javascript\nserver.addTool({\n  name: \"tool_name\",  // Use snake_case for tool names\n  description: \"Description of what the tool does\",\n  parameters: z.object({\n    // Define parameters using Zod\n    param1: z.string().describe(\"Parameter description\"),\n    param2: z.number().optional().describe(\"Optional parameter description\"),\n    // IMPORTANT: For file operations, always include these optional parameters\n    file: z.string().optional().describe(\"Path to the tasks file\"),\n    projectRoot: z.string().optional().describe(\"Root directory of the project (typically derived from session)\")\n  }),\n\n  // The execute function is the core of the tool implementation\n  execute: async (args, context) => {\n    // Implementation goes here\n    // Return response in the appropriate format\n  }\n});\n```\n\n### Execute Function Signature\n\nThe `execute` function receives validated arguments and the FastMCP context:\n\n```javascript\n// Destructured signature (recommended)\nexecute: async (args, { log, session }) => {\n  // Tool implementation\n}\n```\n\n- **args**: Validated parameters.\n- **context**: Contains `{ log, session }` from FastMCP. (Removed `reportProgress`).\n\n### Standard Tool Execution Pattern with Path Normalization (Updated)\n\nTo ensure consistent handling of project paths across different client environments (Windows, macOS, Linux, WSL) and input formats (e.g., `file:///...`, URI encoded paths), all MCP tool `execute` methods that require access to the project root **MUST** be wrapped with the `withNormalizedProjectRoot` Higher-Order Function (HOF).\n\nThis HOF, defined in [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js), performs the following before calling the tool's core logic:\n\n1.  **Determines the Raw Root:** It prioritizes `args.projectRoot` if provided by the client, otherwise it calls `getRawProjectRootFromSession` to extract the path from the session.\n2.  **Normalizes the Path:** It uses the `normalizeProjectRoot` helper to decode URIs, strip `file://` prefixes, fix potential Windows drive letter prefixes (e.g., `/C:/`), convert backslashes (`\\`) to forward slashes (`/`), and resolve the path to an absolute path suitable for the server's OS.\n3.  **Injects Normalized Path:** It updates the `args` object by replacing the original `projectRoot` (or adding it) with the normalized, absolute path.\n4.  **Executes Original Logic:** It calls the original `execute` function body, passing the updated `args` object.\n\n**Implementation Example:**\n\n```javascript\n// In mcp-server/src/tools/your-tool.js\nimport {\n    handleApiResult,\n    createErrorResponse,\n    withNormalizedProjectRoot // <<< Import HOF\n} from './utils.js';\nimport { yourDirectFunction } from '../core/task-master-core.js';\nimport { findTasksJsonPath } from '../core/utils/path-utils.js'; // If needed\n\nexport function registerYourTool(server) {\n    server.addTool({\n        name: \"your_tool\",\n        description: \"...\".\n        parameters: z.object({\n            // ... other parameters ...\n            projectRoot: z.string().optional().describe('...') // projectRoot is optional here, HOF handles fallback\n        }),\n        // Wrap the entire execute function\n        execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n            // args.projectRoot is now guaranteed to be normalized and absolute\n            const { /* other args */, projectRoot } = args;\n\n            try {\n                log.info(`Executing your_tool with normalized root: ${projectRoot}`);\n\n                // Resolve paths using the normalized projectRoot\n                let tasksPath = findTasksJsonPath({ projectRoot, file: args.file }, log);\n\n                // Call direct function, passing normalized projectRoot if needed by direct func\n                const result = await yourDirectFunction(\n                    {\n                        /* other args */,\n                        projectRoot // Pass it if direct function needs it\n                    },\n                    log,\n                    { session }\n                );\n\n                return handleApiResult(result, log);\n            } catch (error) {\n                log.error(`Error in your_tool: ${error.message}`);\n                return createErrorResponse(error.message);\n            }\n        }) // End HOF wrap\n    });\n}\n```\n\nBy using this HOF, the core logic within the `execute` method and any downstream functions (like `findTasksJsonPath` or direct functions) can reliably expect `args.projectRoot` to be a clean, absolute path suitable for the server environment.\n\n### Project Initialization Tool\n\nThe `initialize_project` tool allows integrated clients like Cursor to set up a new Task Master project:\n\n```javascript\n// In initialize-project.js\nimport { z } from \"zod\";\nimport { initializeProjectDirect } from \"../core/task-master-core.js\";\nimport { handleApiResult, createErrorResponse } from \"./utils.js\";\n\nexport function registerInitializeProjectTool(server) {\n  server.addTool({\n    name: \"initialize_project\",\n    description: \"Initialize a new Task Master project\",\n    parameters: z.object({\n      projectName: z.string().optional().describe(\"The name for the new project\"),\n      projectDescription: z.string().optional().describe(\"A brief description\"),\n      projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n      authorName: z.string().optional().describe(\"The author's name\"),\n      skipInstall: z.boolean().optional().describe(\"Skip installing dependencies\"),\n      addAliases: z.boolean().optional().describe(\"Add shell aliases\"),\n      yes: z.boolean().optional().describe(\"Skip prompts and use defaults\")\n    }),\n    execute: async (args, { log, reportProgress }) => {\n      try {\n        // Since we're initializing, we don't need project root\n        const result = await initializeProjectDirect(args, log);\n        return handleApiResult(result, log, 'Error initializing project');\n      } catch (error) {\n        log.error(`Error in initialize_project: ${error.message}`);\n        return createErrorResponse(`Failed to initialize project: ${error.message}`);\n      }\n    }\n  });\n}\n```\n\n### Logging Convention\n\nThe `log` object (destructured from `context`) provides standardized logging methods. Use it within both the `execute` method and the `*Direct` functions. **If progress indication is needed within a direct function, use `log.info()` instead of `reportProgress`**.\n\n```javascript\n// Proper logging usage\nlog.info(`Starting ${toolName} with parameters: ${JSON.stringify(sanitizedArgs)}`);\nlog.debug(\"Detailed operation info\", { data });\nlog.warn(\"Potential issue detected\");\nlog.error(`Error occurred: ${error.message}`, { stack: error.stack });\nlog.info('Progress: 50% - AI call initiated...'); // Example progress logging\n```\n\n## Session Usage Convention\n\nThe `session` object (destructured from `context`) contains authenticated session data and client information.\n\n- **Authentication**: Access user-specific data (`session.userId`, etc.) if authentication is implemented.\n- **Project Root**: The primary use in Task Master is accessing `session.roots` to determine the client's project root directory via the `getProjectRootFromSession` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)). See the Standard Tool Execution Pattern above.\n- **Environment Variables**: The `session.env` object provides access to environment variables set in the MCP client configuration (e.g., `.cursor/mcp.json`). This is the **primary mechanism** for the unified AI service layer (`ai-services-unified.js`) to securely access **API keys** when called from MCP context.\n- **Capabilities**: Can be used to check client capabilities (`session.clientCapabilities`).\n\n## Direct Function Wrappers (`*Direct`)\n\nThese functions, located in `mcp-server/src/core/direct-functions/`, form the core logic execution layer for MCP tools.\n\n- **Purpose**: Bridge MCP tools and core Task Master modules (`scripts/modules/*`). Handle AI interactions if applicable.\n- **Responsibilities**:\n  - Receive `args` (including `projectRoot`), `log`, and optionally `{ session }` context.\n  - Find `tasks.json` using `findTasksJsonPath`.\n  - Validate arguments.\n  - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n  - **Call Core Logic**: Invoke function from `scripts/modules/*`.\n    - Pass `outputFormat: 'json'` if applicable.\n    - Wrap with `enableSilentMode/disableSilentMode` if needed.\n    - Pass `{ mcpLog: logWrapper, session }` context if core logic needs it.\n  - Handle errors.\n  - Return standardized result object.\n  - ❌ **DON'T**: Call `reportProgress`.\n  - ❌ **DON'T**: Initialize AI clients or call AI services directly.\n\n## Key Principles\n\n- **Prefer Direct Function Calls**: MCP tools should always call `*Direct` wrappers instead of `executeTaskMasterCommand`.\n- **Standardized Execution Flow**: Follow the pattern: MCP Tool -> `getProjectRootFromSession` -> `*Direct` Function -> Core Logic / AI Logic.\n- **Path Resolution via Direct Functions**: The `*Direct` function is responsible for finding the exact `tasks.json` path using `findTasksJsonPath`, relying on the `projectRoot` passed in `args`.\n- **AI Logic in Core Modules**: AI interactions (prompt building, calling unified service) reside within the core logic functions (`scripts/modules/*`), not direct functions.\n- **Silent Mode in Direct Functions**: Wrap *core function* calls (from `scripts/modules`) with `enableSilentMode()` and `disableSilentMode()` if they produce console output not handled by `outputFormat`. Do not wrap AI calls.\n- **Selective Async Processing**: Use `AsyncOperationManager` in the *MCP Tool layer* for operations involving multiple steps or long waits beyond a single AI call (e.g., file processing + AI call + file writing). Simple AI calls handled entirely within the `*Direct` function (like `addTaskDirect`) may not need it at the tool layer.\n- **No `reportProgress` in Direct Functions**: Do not pass or use `reportProgress` within `*Direct` functions. Use `log.info()` for internal progress or report progress from the `AsyncOperationManager` callback in the MCP tool layer.\n- **Output Formatting**: Ensure core functions called by `*Direct` functions can suppress CLI output, ideally via an `outputFormat` parameter.\n- **Project Initialization**: Use the initialize_project tool for setting up new projects in integrated environments.\n- **Centralized Utilities**: Use helpers from `mcp-server/src/tools/utils.js`, `mcp-server/src/core/utils/path-utils.js`, and `mcp-server/src/core/utils/ai-client-utils.js`. See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).\n- **Caching in Direct Functions**: Caching logic resides *within* the `*Direct` functions using `getCachedOrExecute`.\n\n## Resources and Resource Templates\n\nResources provide LLMs with static or dynamic data without executing tools.\n\n- **Implementation**: Use `@mcp.resource()` decorator pattern or `server.addResource`/`server.addResourceTemplate` in `mcp-server/src/core/resources/`.\n- **Registration**: Register resources during server initialization in [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js).\n- **Best Practices**: Organize resources, validate parameters, use consistent URIs, handle errors. See [`fastmcp-core.txt`](docs/fastmcp-core.txt) for underlying SDK details.\n\n*(Self-correction: Removed detailed Resource implementation examples as they were less relevant to the current user focus on tool execution flow and project roots. Kept the overview.)*\n\n## Implementing MCP Support for a Command\n\nFollow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):\n\n1.  **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`. Ensure the core function can suppress console output (e.g., via an `outputFormat` parameter).\n\n2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case** naming.\n    - Import necessary core functions, `findTasksJsonPath`, silent mode utilities, and potentially AI client/prompt utilities.\n    - Implement `async function yourCommandDirect(args, log, context = {})` using **camelCase** with `Direct` suffix. **Remember `context` should only contain `{ session }` if needed (for AI keys/config).**\n        - **Path Resolution**: Obtain `tasksPath` using `findTasksJsonPath(args, log)`.\n        - Parse other `args` and perform necessary validation.\n        - **Handle AI (if applicable)**: Initialize clients using `get*ClientForMCP(session, log)`, build prompts, call AI, parse response. Handle AI-specific errors.\n        - **Implement Caching (if applicable)**: Use `getCachedOrExecute`.\n        - **Call Core Logic**:\n            - Wrap with `enableSilentMode/disableSilentMode` if necessary.\n            - Pass `outputFormat: 'json'` (or similar) if applicable.\n            - Handle errors from the core function.\n        - Format the return as `{ success: true/false, data/error, fromCache?: boolean }`.\n        - ❌ **DON'T**: Call `reportProgress`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, `createErrorResponse`, `getProjectRootFromSession`, and your `yourCommandDirect` function. Import `AsyncOperationManager` if needed.\n    - Implement `registerYourCommandTool(server)`.\n    - Define the tool `name` using **snake_case** (e.g., `your_command`).\n    - Define the `parameters` using `zod`. Include `projectRoot: z.string().optional()`.\n    - Implement the `async execute(args, { log, session })` method (omitting `reportProgress` from destructuring).\n        - Get `rootFolder` using `getProjectRootFromSession(session, log)`.\n        - **Determine Execution Strategy**:\n            - **If using `AsyncOperationManager`**: Create the operation, call the `*Direct` function from within the async task callback (passing `log` and `{ session }`), report progress *from the callback*, and return the initial `ACCEPTED` response.\n            - **If calling `*Direct` function synchronously** (like `add-task`): Call `await yourCommandDirect({ ...args, projectRoot }, log, { session });`. Handle the result with `handleApiResult`.\n        - ❌ **DON'T**: Pass `reportProgress` down to the direct function in either case.\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Handling Responses\n\n- MCP tools should return the object generated by `handleApiResult`.\n- `handleApiResult` uses `createContentResponse` or `createErrorResponse` internally.\n- `handleApiResult` also uses `processMCPResponseData` by default to filter potentially large fields (`details`, `testStrategy`) from task data. Provide a custom processor function to `handleApiResult` if different filtering is needed.\n- The final JSON response sent to the MCP client will include the `fromCache` boolean flag (obtained from the `*Direct` function's result) alongside the actual data (e.g., `{ \"fromCache\": true, \"data\": { ... } }` or `{ \"fromCache\": false, \"data\": { ... } }`).\n\n## Parameter Type Handling\n\n- **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n- **Standard Tool Execution Pattern**:\n    - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should:\n        1.  Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger.\n        2.  Receive the result object (typically `{ success, data/error, fromCache }`).\n        3.  Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized response formatting and error handling.\n        4.  Return the formatted response object provided by `handleApiResult`.\n- **CLI Execution as Fallback**: The `executeTaskMasterCommand` utility in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) allows executing commands via the CLI (`task-master ...`). This should **only** be used as a fallback if a direct function wrapper is not yet implemented or if a specific command intrinsically requires CLI execution.\n- **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):\n    - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently.\n    - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation:\n        - `getProjectRoot`: Normalizes project paths.\n        - `handleApiResult`: Takes the raw result from a `*Direct` function and formats it into a standard MCP success or error response, automatically handling data processing via `processMCPResponseData`. This is called by the tool's `execute` method.\n        - `createContentResponse`/`createErrorResponse`: Used by `handleApiResult` to format successful/error MCP responses.\n        - `processMCPResponseData`: Filters/cleans data (e.g., removing `details`, `testStrategy`) before it's sent in the MCP response. Called by `handleApiResult`.\n        - `getCachedOrExecute`: **Used inside `*Direct` functions** in `task-master-core.js` to implement caching logic.\n        - `executeTaskMasterCommand`: Fallback for executing CLI commands.\n- **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented.\n    - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) using the `getCachedOrExecute` utility from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    - Generate unique cache keys based on function arguments that define a distinct call (e.g., file path, filters).\n    - The `getCachedOrExecute` utility handles checking the cache, executing the core logic function on a cache miss, storing the result, and returning the data along with a `fromCache` flag.\n    - Cache statistics can be monitored using the `cacheStats` MCP tool (implemented via `getCacheStatsDirect`).\n    - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data.\n\n**MCP Tool Implementation Checklist**:\n\n1. **Core Logic Verification**:\n   - [ ] Confirm the core function is properly exported from its module (e.g., `task-manager.js`)\n   - [ ] Identify all required parameters and their types\n\n2. **Direct Function Wrapper**:\n   - [ ] Create the `*Direct` function in the appropriate file in `mcp-server/src/core/direct-functions/`\n   - [ ] Import silent mode utilities and implement them around core function calls\n   - [ ] Handle all parameter validations and type conversions\n   - [ ] Implement path resolving for relative paths\n   - [ ] Add appropriate error handling with standardized error codes\n   - [ ] Add to imports/exports in `task-master-core.js`\n\n3. **MCP Tool Implementation**:\n   - [ ] Create new file in `mcp-server/src/tools/` with kebab-case naming\n   - [ ] Define zod schema for all parameters\n   - [ ] Implement the `execute` method following the standard pattern\n   - [ ] Consider using AsyncOperationManager for long-running operations\n   - [ ] Register tool in `mcp-server/src/tools/index.js`\n\n4. **Testing**:\n   - [ ] Write unit tests for the direct function wrapper\n   - [ ] Write integration tests for the MCP tool\n\n## Standard Error Codes\n\n- **Standard Error Codes**: Use consistent error codes across direct function wrappers\n  - `INPUT_VALIDATION_ERROR`: For missing or invalid required parameters\n  - `FILE_NOT_FOUND_ERROR`: For file system path issues\n  - `CORE_FUNCTION_ERROR`: For errors thrown by the core function\n  - `UNEXPECTED_ERROR`: For all other unexpected errors\n\n- **Error Object Structure**:\n  ```javascript\n  {\n    success: false,\n    error: {\n      code: 'ERROR_CODE',\n      message: 'Human-readable error message'\n    },\n    fromCache: false\n  }\n  ```\n\n- **MCP Tool Logging Pattern**:\n  - ✅ DO: Log the start of execution with arguments (sanitized if sensitive)\n  - ✅ DO: Log successful completion with result summary\n  - ✅ DO: Log all error conditions with appropriate log levels\n  - ✅ DO: Include the cache status in result logs\n  - ❌ DON'T: Log entire large data structures or sensitive information\n\n- The MCP server integrates with Task Master core functions through three layers:\n  1. Tool Definitions (`mcp-server/src/tools/*.js`) - Define parameters and validation\n  2. Direct Functions (`mcp-server/src/core/direct-functions/*.js`) - Handle core logic integration\n  3. Core Functions (`scripts/modules/*.js`) - Implement the actual functionality\n\n- This layered approach provides:\n  - Clear separation of concerns\n  - Consistent parameter validation\n  - Centralized error handling\n  - Performance optimization through caching (for read operations)\n  - Standardized response formatting\n\n## MCP Naming Conventions\n\n- **Files and Directories**:\n  - ✅ DO: Use **kebab-case** for all file names: `list-tasks.js`, `set-task-status.js`\n  - ✅ DO: Use consistent directory structure: `mcp-server/src/tools/` for tool definitions, `mcp-server/src/core/direct-functions/` for direct function implementations\n\n- **JavaScript Functions**:\n  - ✅ DO: Use **camelCase** with `Direct` suffix for direct function implementations: `listTasksDirect`, `setTaskStatusDirect`\n  - ✅ DO: Use **camelCase** with `Tool` suffix for tool registration functions: `registerListTasksTool`, `registerSetTaskStatusTool`\n  - ✅ DO: Use consistent action function naming inside direct functions: `coreActionFn` or similar descriptive name\n\n- **MCP Tool Names**:\n  - ✅ DO: Use **snake_case** for tool names exposed to MCP clients: `list_tasks`, `set_task_status`, `parse_prd_document`\n  - ✅ DO: Include the core action in the tool name without redundant words: Use `list_tasks` instead of `list_all_tasks`\n\n- **Examples**:\n  - File: `list-tasks.js` \n  - Direct Function: `listTasksDirect`\n  - Tool Registration: `registerListTasksTool`\n  - MCP Tool Name: `list_tasks`\n\n- **Mapping**:\n  - The `directFunctions` map in `task-master-core.js` maps the core function name (in camelCase) to its direct implementation:\n    ```javascript\n    export const directFunctions = {\n      list: listTasksDirect,\n      setStatus: setTaskStatusDirect,\n      // Add more functions as implemented\n    };\n    ```\n\n## Telemetry Integration\n\n- Direct functions calling core logic that involves AI should receive and pass through `telemetryData` within their successful `data` payload. See [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc) for the standard pattern.\n- MCP tools use `handleApiResult`, which ensures the `data` object (potentially including `telemetryData`) from the direct function is correctly included in the final response.\n\n<!-- File: .cursor/rules/new_features.mdc (Tokens: ~8711 | Category: cursor-rule) -->\n---\ndescription: Guidelines for integrating new features into the Task Master CLI\nglobs: scripts/modules/*.js\nalwaysApply: false\n---\n# Task Master Feature Integration Guidelines\n\n## Feature Placement Decision Process\n\n- **Identify Feature Type** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module details):\n  - **Data Manipulation**: Features that create, read, update, or delete tasks belong in [`task-manager.js`](mdc:scripts/modules/task-manager.js). Follow guidelines in [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc).\n  - **Dependency Management**: Features that handle task relationships belong in [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js). Follow guidelines in [`dependencies.mdc`](mdc:.cursor/rules/dependencies.mdc).\n  - **User Interface**: Features that display information to users belong in [`ui.js`](mdc:scripts/modules/ui.js). Follow guidelines in [`ui.mdc`](mdc:.cursor/rules/ui.mdc).\n  - **AI Integration**: Features that use AI models belong in [`ai-services.js`](mdc:scripts/modules/ai-services.js).\n  - **Cross-Cutting**: Features that don't fit one category may need components in multiple modules\n\n- **Command-Line Interface** (See [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):\n  - All new user-facing commands should be added to [`commands.js`](mdc:scripts/modules/commands.js)\n  - Use consistent patterns for option naming and help text\n  - Follow the Commander.js model for subcommand structure\n\n## Implementation Pattern\n\nThe standard pattern for adding a feature follows this workflow:\n\n1. **Core Logic**: Implement the business logic in the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2. **Context Gathering (If Applicable)**: \n   - For AI-powered commands that benefit from project context, use the standardized context gathering patterns from [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc).\n   - Import `ContextGatherer` and `FuzzyTaskSearch` utilities for reusable context extraction.\n   - Support multiple context types: tasks, files, custom text, project tree.\n   - Implement detailed token breakdown display for transparency.\n3. **AI Integration (If Applicable)**: \n   - Import necessary service functions (e.g., `generateTextService`, `streamTextService`) from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n   - Prepare parameters (`role`, `session`, `systemPrompt`, `prompt`).\n   - Call the service function.\n   - Handle the response (direct text or stream object).\n   - **Important**: Prefer `generateTextService` for calls sending large context (like stringified JSON) where incremental display is not needed. See [`ai_services.mdc`](mdc:.cursor/rules/ai_services.mdc) for detailed usage patterns and cautions.\n4. **UI Components**: Add any display functions to [`ui.js`](mdc:scripts/modules/ui.js) following [`ui.mdc`](mdc:.cursor/rules/ui.mdc). Consider enhanced formatting with syntax highlighting for code blocks.\n5. **Command Integration**: Add the CLI command to [`commands.js`](mdc:scripts/modules/commands.js) following [`commands.mdc`](mdc:.cursor/rules/commands.mdc).\n6. **Testing**: Write tests for all components of the feature (following [`tests.mdc`](mdc:.cursor/rules/tests.mdc))\n7. **Configuration**: Update configuration settings or add new ones in [`config-manager.js`](mdc:scripts/modules/config-manager.js) and ensure getters/setters are appropriate. Update documentation in [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc). Update the `.taskmasterconfig` structure if needed.\n8. **Documentation**: Update help text and documentation in [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) and [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc).\n\n## Critical Checklist for New Features\n\n- **Comprehensive Function Exports**:\n  - ✅ **DO**: Export **all core functions, helper functions (like `generateSubtaskPrompt`), and utility methods** needed by your new function or command from their respective modules.\n  - ✅ **DO**: **Explicitly review the module's `export { ... }` block** at the bottom of the file to ensure every required dependency (even seemingly minor helpers like `findTaskById`, `taskExists`, specific prompt generators, AI call handlers, etc.) is included.\n  - ❌ **DON'T**: Assume internal functions are already exported - **always verify**. A missing export will cause runtime errors (e.g., `ReferenceError: generateSubtaskPrompt is not defined`).\n  - **Example**: If implementing a feature that checks task existence, ensure the helper function is in exports:\n  ```javascript\n  // At the bottom of your module file:\n  export {\n    // ... existing exports ...\n    yourNewFunction,\n    taskExists,  // Helper function used by yourNewFunction\n    findTaskById, // Helper function used by yourNewFunction\n    generateSubtaskPrompt, // Helper needed by expand/add features\n    getSubtasksFromAI,     // Helper needed by expand/add features\n  };\n  ```\n\n- **Parameter Completeness and Matching**:\n  - ✅ **DO**: Pass all required parameters to functions you call within your implementation\n  - ✅ **DO**: Check function signatures before implementing calls to them\n  - ✅ **DO**: Verify that direct function parameters match their core function counterparts\n  - ✅ **DO**: When implementing a direct function for MCP, ensure it only accepts parameters that exist in the core function\n  - ✅ **DO**: Verify the expected *internal structure* of complex object parameters (like the `mcpLog` object, see mcp.mdc for the required logger wrapper pattern)\n  - ❌ **DON'T**: Add parameters to direct functions that don't exist in core functions\n  - ❌ **DON'T**: Assume default parameter values will handle missing arguments\n  - ❌ **DON'T**: Assume object parameters will work without verifying their required internal structure or methods.\n  - **Example**: When calling file generation, pass all required parameters:\n  ```javascript\n  // ✅ DO: Pass all required parameters\n  await generateTaskFiles(tasksPath, path.dirname(tasksPath));\n  \n  // ❌ DON'T: Omit required parameters\n  await generateTaskFiles(tasksPath); // Error - missing outputDir parameter\n  ```\n  \n  **Example**: Properly match direct function parameters to core function:\n  ```javascript\n  // Core function signature\n  async function expandTask(tasksPath, taskId, numSubtasks, useResearch = false, additionalContext = '', options = {}) {\n    // Implementation...\n  }\n  \n  // ✅ DO: Match direct function parameters to core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // Extract only parameters that exist in the core function\n    const taskId = parseInt(args.id, 10);\n    const numSubtasks = args.num ? parseInt(args.num, 10) : undefined;\n    const useResearch = args.research === true;\n    const additionalContext = args.prompt || '';\n    \n    // Call core function with matched parameters\n    const result = await expandTask(\n      tasksPath,\n      taskId,\n      numSubtasks,\n      useResearch,\n      additionalContext,\n      { mcpLog: log, session: context.session }\n    );\n    \n    // Return result\n    return { success: true, data: result, fromCache: false };\n  }\n  \n  // ❌ DON'T: Use parameters that don't exist in the core function\n  export async function expandTaskDirect(args, log, context = {}) {\n    // DON'T extract parameters that don't exist in the core function!\n    const force = args.force === true; // ❌ WRONG - 'force' doesn't exist in core function\n    \n    // DON'T pass non-existent parameters to core functions\n    const result = await expandTask(\n      tasksPath,\n      args.id,\n      args.num,\n      args.research,\n      args.prompt,\n      force, // ❌ WRONG - this parameter doesn't exist in the core function\n      { mcpLog: log }\n    );\n  }\n  ```\n\n- **Consistent File Path Handling**:\n  - ✅ DO: Use consistent file naming conventions: `task_${id.toString().padStart(3, '0')}.txt`\n  - ✅ DO: Use `path.join()` for composing file paths\n  - ✅ DO: Use appropriate file extensions (.txt for tasks, .json for data)\n  - ❌ DON'T: Hardcode path separators or inconsistent file extensions\n  - **Example**: Creating file paths for tasks:\n  ```javascript\n  // ✅ DO: Use consistent file naming and path.join\n  const taskFileName = path.join(\n    path.dirname(tasksPath), \n    `task_${taskId.toString().padStart(3, '0')}.txt`\n  );\n  \n  // ❌ DON'T: Use inconsistent naming or string concatenation \n  const taskFileName = path.dirname(tasksPath) + '/' + taskId + '.md';\n  ```\n\n- **Error Handling and Reporting**:\n  - ✅ DO: Use structured error objects with code and message properties\n  - ✅ DO: Include clear error messages identifying the specific problem\n  - ✅ DO: Handle both function-specific errors and potential file system errors\n  - ✅ DO: Log errors at appropriate severity levels\n  - **Example**: Structured error handling in core functions:\n  ```javascript\n  try {\n    // Implementation...\n  } catch (error) {\n    log('error', `Error removing task: ${error.message}`);\n    throw {\n      code: 'REMOVE_TASK_ERROR',\n      message: error.message,\n      details: error.stack\n    };\n  }\n  ```\n\n- **Silent Mode Implementation**:\n  - ✅ **DO**: Import all silent mode utilities together:\n    ```javascript\n    import { enableSilentMode, disableSilentMode, isSilentMode } from '../../../../scripts/modules/utils.js';\n    ```\n  - ✅ **DO**: Always use `isSilentMode()` function to check global silent mode status, never reference global variables.\n  - ✅ **DO**: Wrap core function calls **within direct functions** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block if the core function might produce console output (like banners, spinners, direct `console.log`s) that isn't reliably controlled by an `outputFormat` parameter.\n    ```javascript\n    // Direct Function Example:\n    try {\n      // Prefer passing 'json' if the core function reliably handles it\n      const result = await coreFunction(...args, 'json'); \n      // OR, if outputFormat is not enough/unreliable:\n      // enableSilentMode(); // Enable *before* the call\n      // const result = await coreFunction(...args);\n      // disableSilentMode(); // Disable *after* the call (typically in finally)\n\n      return { success: true, data: result };\n    } catch (error) {\n       log.error(`Error: ${error.message}`);\n       return { success: false, error: { message: error.message } };\n    } finally {\n       // If you used enable/disable, ensure disable is called here\n       // disableSilentMode(); \n    }\n    ```\n  - ✅ **DO**: Core functions themselves *should* ideally check `outputFormat === 'text'` before displaying UI elements (banners, spinners, boxes) and use internal logging (`log`/`report`) that respects silent mode. The `enable/disableSilentMode` wrapper in the direct function is a safety net.\n  - ✅ **DO**: Handle mixed parameter/global silent mode correctly for functions accepting both (less common now, prefer `outputFormat`):\n    ```javascript\n    // Check both the passed parameter and global silent mode\n    const isSilent = silentMode || (typeof silentMode === 'undefined' && isSilentMode());\n    ```\n  - ❌ **DON'T**: Forget to disable silent mode in a `finally` block if you enabled it.\n  - ❌ **DON'T**: Access the global `silentMode` flag directly.\n\n- **Debugging Strategy**:\n  - ✅ **DO**: If an MCP tool fails with vague errors (e.g., JSON parsing issues like `Unexpected token ... is not valid JSON`), **try running the equivalent CLI command directly in the terminal** (e.g., `task-master expand --all`). CLI output often provides much more specific error messages (like missing function definitions or stack traces from the core logic) that pinpoint the root cause.\n  - ❌ **DON'T**: Rely solely on MCP logs if the error is unclear; use the CLI as a complementary debugging tool for core logic issues.\n\n- **Telemetry Integration**: Ensure AI calls correctly handle and propagate `telemetryData` as described in [`telemetry.mdc`](mdc:.cursor/rules/telemetry.mdc).\n\n```javascript\n// 1. CORE LOGIC: Add function to appropriate module (example in task-manager.js)\n/**\n * Archives completed tasks to archive.json\n * @param {string} tasksPath - Path to the tasks.json file\n * @param {string} archivePath - Path to the archive.json file\n * @returns {number} Number of tasks archived\n */\nasync function archiveTasks(tasksPath, archivePath = 'tasks/archive.json') {\n  // Implementation...\n  return archivedCount;\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  archiveTasks,\n};\n```\n\n```javascript\n// 2. AI Integration: Add import and use necessary service functions\nimport { generateTextService } from './ai-services-unified.js';\n\n// Example usage:\nasync function handleAIInteraction() {\n  const role = 'user';\n  const session = 'exampleSession';\n  const systemPrompt = 'You are a helpful assistant.';\n  const prompt = 'What is the capital of France?';\n\n  const result = await generateTextService(role, session, systemPrompt, prompt);\n  console.log(result);\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  handleAIInteraction,\n};\n```\n\n```javascript\n// 3. UI COMPONENTS: Add display function to ui.js\n/**\n * Display archive operation results\n * @param {string} archivePath - Path to the archive file\n * @param {number} count - Number of tasks archived\n */\nfunction displayArchiveResults(archivePath, count) {\n  console.log(boxen(\n    chalk.green(`Successfully archived ${count} tasks to ${archivePath}`),\n    { padding: 1, borderColor: 'green', borderStyle: 'round' }\n  ));\n}\n\n// Export from the module\nexport {\n  // ... existing exports ...\n  displayArchiveResults,\n};\n```\n\n```javascript\n// 4. COMMAND INTEGRATION: Add to commands.js\nimport { archiveTasks } from './task-manager.js';\nimport { displayArchiveResults } from './ui.js';\n\n// In registerCommands function\nprogramInstance\n  .command('archive')\n  .description('Archive completed tasks to separate file')\n  .option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')\n  .option('-o, --output <file>', 'Archive output file', 'tasks/archive.json')\n  .action(async (options) => {\n    const tasksPath = options.file;\n    const archivePath = options.output;\n    \n    console.log(chalk.blue(`Archiving completed tasks from ${tasksPath} to ${archivePath}...`));\n    \n    const archivedCount = await archiveTasks(tasksPath, archivePath);\n    displayArchiveResults(archivePath, archivedCount);\n  });\n```\n\n## Cross-Module Features\n\nFor features requiring components in multiple modules:\n\n- ✅ **DO**: Create a clear unidirectional flow of dependencies\n  ```javascript\n  // In task-manager.js\n  function analyzeTasksDifficulty(tasks) {\n    // Implementation...\n    return difficultyScores;\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasksDifficulty } from './task-manager.js';\n  \n  function displayDifficultyReport(tasks) {\n    const scores = analyzeTasksDifficulty(tasks);\n    // Render the scores...\n  }\n  ```\n\n- ❌ **DON'T**: Create circular dependencies between modules\n  ```javascript\n  // In task-manager.js - depends on ui.js\n  import { displayDifficultyReport } from './ui.js';\n  \n  function analyzeTasks() {\n    // Implementation...\n    displayDifficultyReport(tasks); // WRONG! Don't call UI functions from task-manager\n  }\n  \n  // In ui.js - depends on task-manager.js\n  import { analyzeTasks } from './task-manager.js';\n  ```\n\n## Command-Line Interface Standards\n\n- **Naming Conventions**:\n  - Use kebab-case for command names (`analyze-complexity`, not `analyzeComplexity`)\n  - Use kebab-case for option names (`--output-format`, not `--outputFormat`) \n  - Use the same option names across commands when they represent the same concept\n\n- **Command Structure**:\n  ```javascript\n  programInstance\n    .command('command-name')\n    .description('Clear, concise description of what the command does')\n    .option('-s, --short-option <value>', 'Option description', 'default value')\n    .option('--long-option <value>', 'Option description')\n    .action(async (options) => {\n      // Command implementation\n    });\n  ```\n\n## Utility Function Guidelines\n\nWhen adding utilities to [`utils.js`](mdc:scripts/modules/utils.js):\n\n- Only add functions that could be used by multiple modules\n- Keep utilities single-purpose and purely functional\n- Document parameters and return values\n\n```javascript\n/**\n * Formats a duration in milliseconds to a human-readable string\n * @param {number} ms - Duration in milliseconds\n * @returns {string} Formatted duration string (e.g., \"2h 30m 15s\")\n */\nfunction formatDuration(ms) {\n  // Implementation...\n  return formatted;\n}\n```\n\n## Writing Testable Code\n\nWhen implementing new features, follow these guidelines to ensure your code is testable:\n\n- **Dependency Injection**\n  - Design functions to accept dependencies as parameters\n  - Avoid hard-coded dependencies that are difficult to mock\n  ```javascript\n  // ✅ DO: Accept dependencies as parameters\n  function processTask(task, fileSystem, logger) {\n    fileSystem.writeFile('task.json', JSON.stringify(task));\n    logger.info('Task processed');\n  }\n  \n  // ❌ DON'T: Use hard-coded dependencies\n  function processTask(task) {\n    fs.writeFile('task.json', JSON.stringify(task));\n    console.log('Task processed');\n  }\n  ```\n\n- **Separate Logic from Side Effects**\n  - Keep pure logic separate from I/O operations or UI rendering\n  - This allows testing the logic without mocking complex dependencies\n  ```javascript\n  // ✅ DO: Separate logic from side effects\n  function calculateTaskPriority(task, dependencies) {\n    // Pure logic that returns a value\n    return computedPriority;\n  }\n  \n  function displayTaskPriority(task, dependencies) {\n    const priority = calculateTaskPriority(task, dependencies);\n    console.log(`Task priority: ${priority}`);\n  }\n  ```\n\n- **Callback Functions and Testing**\n  - When using callbacks (like in Commander.js commands), define them separately\n  - This allows testing the callback logic independently\n  ```javascript\n  // ✅ DO: Define callbacks separately for testing\n  function getVersionString() {\n    // Logic to determine version\n    return version;\n  }\n  \n  // In setupCLI\n  programInstance.version(getVersionString);\n  \n  // In tests\n  test('getVersionString returns correct version', () => {\n    expect(getVersionString()).toBe('1.5.0');\n  });\n  ```\n\n- **UI Output Testing**\n  - For UI components, focus on testing conditional logic rather than exact output\n  - Use string pattern matching (like `expect(result).toContain('text')`)\n  - Pay attention to emojis and formatting which can make exact string matching difficult\n  ```javascript\n  // ✅ DO: Test the essence of the output, not exact formatting\n  test('statusFormatter shows done status correctly', () => {\n    const result = formatStatus('done');\n    expect(result).toContain('done');\n    expect(result).toContain('✅');\n  });\n  ```\n\n## Testing Requirements\n\nEvery new feature **must** include comprehensive tests following the guidelines in [`tests.mdc`](mdc:.cursor/rules/tests.mdc). Testing should include:\n\n1. **Unit Tests**: Test individual functions and components in isolation\n   ```javascript\n   // Example unit test for a new utility function\n   describe('newFeatureUtil', () => {\n     test('should perform expected operation with valid input', () => {\n       expect(newFeatureUtil('valid input')).toBe('expected result');\n     });\n     \n     test('should handle edge cases appropriately', () => {\n       expect(newFeatureUtil('')).toBeNull();\n     });\n   });\n   ```\n\n2. **Integration Tests**: Verify the feature works correctly with other components\n   ```javascript\n   // Example integration test for a new command\n   describe('newCommand integration', () => {\n     test('should call the correct service functions with parsed arguments', () => {\n       const mockService = jest.fn().mockResolvedValue('success');\n       // Set up test with mocked dependencies\n       // Call the command handler\n       // Verify service was called with expected arguments\n     });\n   });\n   ```\n\n3. **Edge Cases**: Test boundary conditions and error handling\n   - Invalid inputs\n   - Missing dependencies\n   - File system errors\n   - API failures\n\n4. **Test Coverage**: Aim for at least 80% coverage for all new code\n\n5. **Jest Mocking Best Practices**\n   - Follow the mock-first-then-import pattern as described in [`tests.mdc`](mdc:.cursor/rules/tests.mdc)\n   - Use jest.spyOn() to create spy functions for testing\n   - Clear mocks between tests to prevent interference\n   - See the Jest Module Mocking Best Practices section in [`tests.mdc`](mdc:.cursor/rules/tests.mdc) for details\n\nWhen submitting a new feature, always run the full test suite to ensure nothing was broken:\n\n```bash\nnpm test\n```\n\n## Documentation Requirements\n\nFor each new feature:\n\n1. Add help text to the command definition\n2. Update [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) with command reference\n3. Consider updating [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) if the feature significantly changes module responsibilities.\n\nFollow the existing command reference format:\n```markdown\n- **Command Reference: your-command**\n  - CLI Syntax: `task-master your-command [options]`\n  - Description: Brief explanation of what the command does\n  - Parameters:\n    - `--option1=<value>`: Description of option1 (default: 'default')\n    - `--option2=<value>`: Description of option2 (required)\n  - Example: `task-master your-command --option1=value --option2=value2`\n  - Notes: Additional details, limitations, or special considerations\n```\n\nFor more information on module structure, see [`MODULE_PLAN.md`](mdc:scripts/modules/MODULE_PLAN.md) and follow [`self_improve.mdc`](mdc:scripts/modules/self_improve.mdc) for best practices on updating documentation.\n\n## Adding MCP Server Support for Commands\n\nIntegrating Task Master commands with the MCP server (for use by tools like Cursor) follows a specific pattern distinct from the CLI command implementation, prioritizing performance and reliability.\n\n- **Goal**: Leverage direct function calls to core logic, avoiding CLI overhead.\n- **Reference**: See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for full details.\n\n**MCP Integration Workflow**:\n\n1.  **Core Logic**: Ensure the command's core logic exists and is exported from the appropriate module (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).\n2.  **Direct Function Wrapper (`mcp-server/src/core/direct-functions/`)**:\n    - Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.\n    - Import the core logic function, necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`**, and **silent mode utilities**: `import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js';`\n    - Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.\n    - **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` (derived from the session) being passed correctly.\n    - Perform validation on other arguments received in `args`.\n    - **Implement Silent Mode**: Wrap core function calls with `enableSilentMode()` and `disableSilentMode()` to prevent logs from interfering with JSON responses.\n    - **If Caching**: Implement caching using `getCachedOrExecute` from `../../tools/utils.js`.\n    - **If Not Caching**: Directly call the core logic function within a try/catch block.\n    - Format the return as `{ success: true/false, data/error, fromCache: boolean }`.\n    - Export the wrapper function.\n\n3.  **Update `task-master-core.js` with Import/Export**: Import and re-export your `*Direct` function and add it to the `directFunctions` map.\n\n4.  **Create MCP Tool (`mcp-server/src/tools/`)**:\n    - Create a new file (e.g., `your-command.js`) using **kebab-case**.\n    - Import `zod`, `handleApiResult`, **`withNormalizedProjectRoot` HOF**, and your `yourCommandDirect` function.\n    - Implement `registerYourCommandTool(server)`.\n    - **Define parameters**: Make `projectRoot` optional (`z.string().optional().describe(...)`) as the HOF handles fallback.\n    - Consider if this operation should run in the background using `AsyncOperationManager`.\n    - Implement the standard `execute` method **wrapped with `withNormalizedProjectRoot`**:\n      ```javascript\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n          // args.projectRoot is now normalized\n          const { projectRoot /*, other args */ } = args;\n          // ... resolve tasks path if needed using normalized projectRoot ...\n          const result = await yourCommandDirect(\n              { /* other args */, projectRoot /* if needed by direct func */ }, \n              log, \n              { session }\n          );\n          return handleApiResult(result, log);\n      })\n      ```\n\n5.  **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.\n\n6.  **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.\n\n## Implementing Background Operations\n\nFor long-running operations that should not block the client, use the AsyncOperationManager:\n\n1. **Identify Background-Appropriate Operations**:\n   - ✅ **DO**: Use async operations for CPU-intensive tasks like task expansion or PRD parsing\n   - ✅ **DO**: Consider async operations for tasks that may take more than 1-2 seconds\n   - ❌ **DON'T**: Use async operations for quick read/status operations\n   - ❌ **DON'T**: Use async operations when immediate feedback is critical\n\n2. **Use AsyncOperationManager in MCP Tools**:\n   ```javascript\n   import { asyncOperationManager } from '../core/utils/async-manager.js';\n   \n   // In execute method:\n   const operationId = asyncOperationManager.addOperation(\n     expandTaskDirect, // The direct function to run in background\n     { ...args, projectRoot: rootFolder }, // Args to pass to the function\n     { log, reportProgress, session } // Context to preserve for the operation\n   );\n   \n   // Return immediate response with operation ID\n   return createContentResponse({\n     message: \"Operation started successfully\",\n     operationId,\n     status: \"pending\"\n   });\n   ```\n\n3. **Implement Progress Reporting**:\n   - ✅ **DO**: Use the reportProgress function in direct functions:\n   ```javascript\n   // In your direct function:\n   if (reportProgress) {\n     await reportProgress({ progress: 50 }); // 50% complete\n   }\n   ```\n   - AsyncOperationManager will forward progress updates to the client\n\n4. **Check Operation Status**:\n   - Implement a way for clients to check status using the `get_operation_status` MCP tool\n   - Return appropriate status codes and messages\n\n## Project Initialization\n\nWhen implementing project initialization commands:\n\n1. **Support Programmatic Initialization**:\n   - ✅ **DO**: Design initialization to work with both CLI and MCP\n   - ✅ **DO**: Support non-interactive modes with sensible defaults\n   - ✅ **DO**: Handle project metadata like name, description, version\n   - ✅ **DO**: Create necessary files and directories\n\n2. **In MCP Tool Implementation**:\n   ```javascript\n   // In initialize-project.js MCP tool:\n   import { z } from \"zod\";\n   import { initializeProjectDirect } from \"../core/task-master-core.js\";\n   \n   export function registerInitializeProjectTool(server) {\n     server.addTool({\n       name: \"initialize_project\",\n       description: \"Initialize a new Task Master project\",\n       parameters: z.object({\n         projectName: z.string().optional().describe(\"The name for the new project\"),\n         projectDescription: z.string().optional().describe(\"A brief description\"),\n         projectVersion: z.string().optional().describe(\"Initial version (e.g., '0.1.0')\"),\n         // Add other parameters as needed\n       }),\n       execute: async (args, { log, reportProgress, session }) => {\n         try {\n           // No need for project root since we're creating a new project\n           const result = await initializeProjectDirect(args, log);\n           return handleApiResult(result, log, 'Error initializing project');\n         } catch (error) {\n           log.error(`Error in initialize_project: ${error.message}`);\n           return createErrorResponse(`Failed to initialize project: ${error.message}`);\n         }\n       }\n     });\n   }\n   ```\n\n## Feature Planning\n\n- **Core Logic First**:\n  - ✅ DO: Implement core logic in `scripts/modules/` before CLI or MCP interfaces\n  - ✅ DO: Consider tagged task lists system compatibility from the start\n  - ✅ DO: Design functions to work with both legacy and tagged data formats\n  - ✅ DO: Use tag resolution functions (`getTasksForTag`, `setTasksForTag`) for task data access\n  - ❌ DON'T: Directly manipulate tagged data structure in new features\n\n  ```javascript\n  // ✅ DO: Design tagged-aware core functions\n  async function newFeatureCore(tasksPath, featureParams, options = {}) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Perform feature logic on tasks array\n    const result = performFeatureLogic(tasks, featureParams);\n    \n    // Save back using tag resolution\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n    \n    return result;\n  }\n  ```\n\n- **Backward Compatibility**:\n  - ✅ DO: Ensure new features work with existing projects seamlessly\n  - ✅ DO: Test with both legacy and tagged task data formats\n  - ✅ DO: Support silent migration during feature usage\n  - ❌ DON'T: Break existing workflows when adding tagged system features\n\n## CLI Command Implementation\n\n- **Command Structure**:\n  - ✅ DO: Follow the established pattern in [`commands.js`](mdc:scripts/modules/commands.js)\n  - ✅ DO: Use Commander.js for argument parsing\n  - ✅ DO: Include comprehensive help text and examples\n  - ✅ DO: Support tagged task context awareness\n\n  ```javascript\n  // ✅ DO: Implement CLI commands with tagged system awareness\n  program\n    .command('new-feature')\n    .description('Description of the new feature with tagged task lists support')\n    .option('-t, --tag <tag>', 'Specify tag context (defaults to current tag)')\n    .option('-p, --param <value>', 'Feature-specific parameter')\n    .option('--force', 'Force operation without confirmation')\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot();\n        if (!projectRoot) {\n          console.error('Not in a Task Master project directory');\n          process.exit(1);\n        }\n        \n        // Use specified tag or current tag\n        const targetTag = options.tag || getCurrentTag() || 'master';\n        \n        const result = await newFeatureCore(\n          path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'),\n          { param: options.param },\n          { \n            force: options.force,\n            targetTag: targetTag,\n            outputFormat: 'text'\n          }\n        );\n        \n        console.log('Feature executed successfully');\n      } catch (error) {\n        console.error(`Error: ${error.message}`);\n        process.exit(1);\n      }\n    });\n  ```\n\n- **Error Handling**:\n  - ✅ DO: Provide clear error messages for common failures\n  - ✅ DO: Handle tagged system migration errors gracefully\n  - ✅ DO: Include suggestion for resolution when possible\n  - ✅ DO: Exit with appropriate codes for scripting\n\n## MCP Tool Implementation\n\n- **Direct Function Pattern**:\n  - ✅ DO: Create direct function wrappers in `mcp-server/src/core/direct-functions/`\n  - ✅ DO: Follow silent mode patterns to prevent console output interference\n  - ✅ DO: Use `findTasksJsonPath` for consistent path resolution\n  - ✅ DO: Ensure tagged system compatibility\n\n  ```javascript\n  // ✅ DO: Implement MCP direct functions with tagged awareness\n  export async function newFeatureDirect(args, log, context = {}) {\n    try {\n      const tasksPath = findTasksJsonPath(args, log);\n      \n      // Enable silent mode for clean MCP responses\n      enableSilentMode();\n      \n      try {\n        const result = await newFeatureCore(\n          tasksPath,\n          { param: args.param },\n          { \n            force: args.force,\n            targetTag: args.tag || 'master', // Support tag specification\n            mcpLog: log,\n            session: context.session,\n            outputFormat: 'json'\n          }\n        );\n        \n        return {\n          success: true,\n          data: result,\n          fromCache: false\n        };\n      } finally {\n        disableSilentMode();\n      }\n    } catch (error) {\n      log.error(`Error in newFeatureDirect: ${error.message}`);\n      return {\n        success: false,\n        error: { code: 'FEATURE_ERROR', message: error.message },\n        fromCache: false\n      };\n    }\n  }\n  ```\n\n- **Tool Registration**:\n  - ✅ DO: Create tool definitions in `mcp-server/src/tools/`\n  - ✅ DO: Use Zod for parameter validation\n  - ✅ DO: Include optional tag parameter for multi-context support\n  - ✅ DO: Follow established naming conventions\n\n  ```javascript\n  // ✅ DO: Register MCP tools with tagged system support\n  export function registerNewFeatureTool(server) {\n    server.addTool({\n      name: \"new_feature\",\n      description: \"Description of the new feature with tagged task lists support\",\n      inputSchema: z.object({\n        param: z.string().describe(\"Feature-specific parameter\"),\n        tag: z.string().optional().describe(\"Target tag context (defaults to current tag)\"),\n        force: z.boolean().optional().describe(\"Force operation without confirmation\"),\n        projectRoot: z.string().optional().describe(\"Project root directory\")\n      }),\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const result = await newFeatureDirect(\n            { ...args, projectRoot: args.projectRoot },\n            log,\n            { session }\n          );\n          return handleApiResult(result, log);\n        } catch (error) {\n          return handleApiResult({\n            success: false,\n            error: { code: 'EXECUTION_ERROR', message: error.message }\n          }, log);\n        }\n      })\n    });\n  }\n  ```\n\n## Testing Strategy\n\n- **Unit Tests**:\n  - ✅ DO: Test core logic independently with both data formats\n  - ✅ DO: Mock file system operations appropriately\n  - ✅ DO: Test tag resolution behavior\n  - ✅ DO: Verify migration compatibility\n\n  ```javascript\n  // ✅ DO: Test new features with tagged system awareness\n  describe('newFeature', () => {\n    beforeEach(() => {\n      jest.clearAllMocks();\n    });\n    \n    it('should work with legacy task format', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test legacy format handling\n    });\n    \n    it('should work with tagged task format', async () => {\n      const taggedData = { \n        master: { tasks: [/* test data */] },\n        feature: { tasks: [/* test data */] }\n      };\n      fs.readFileSync.mockReturnValue(JSON.stringify(taggedData));\n      \n      const result = await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      expect(result).toBeDefined();\n      // Test tagged format handling\n    });\n    \n    it('should handle tag migration during feature usage', async () => {\n      const legacyData = { tasks: [/* test data */] };\n      fs.readFileSync.mockReturnValue(JSON.stringify(legacyData));\n      \n      await newFeatureCore('/test/tasks.json', { param: 'test' });\n      \n      // Verify migration occurred\n      expect(fs.writeFileSync).toHaveBeenCalledWith(\n        '/test/tasks.json',\n        expect.stringContaining('\"master\"')\n      );\n    });\n  });\n  ```\n\n- **Integration Tests**:\n  - ✅ DO: Test CLI and MCP interfaces with real task data\n  - ✅ DO: Verify end-to-end workflows across tag contexts\n  - ✅ DO: Test error scenarios and recovery\n\n## Documentation Updates\n\n- **Rule Updates**:\n  - ✅ DO: Update relevant `.cursor/rules/*.mdc` files\n  - ✅ DO: Include tagged system considerations in architecture docs\n  - ✅ DO: Add examples showing multi-context usage\n  - ✅ DO: Update workflow documentation as needed\n\n- **User Documentation**:\n  - ✅ DO: Add feature documentation to `/docs` folder\n  - ✅ DO: Include tagged system usage examples\n  - ✅ DO: Update command reference documentation\n  - ✅ DO: Provide migration notes if relevant\n\n## Migration Considerations\n\n- **Silent Migration Support**:\n  - ✅ DO: Ensure new features trigger migration when needed\n  - ✅ DO: Handle migration errors gracefully in feature code\n  - ✅ DO: Test feature behavior with pre-migration projects\n  - ❌ DON'T: Assume projects are already migrated\n\n- **Tag Context Handling**:\n  - ✅ DO: Default to current tag when not specified\n  - ✅ DO: Support explicit tag selection in advanced features\n  - ✅ DO: Validate tag existence before operations\n  - ✅ DO: Provide clear messaging about tag context\n\n## Performance Considerations\n\n- **Efficient Tag Operations**:\n  - ✅ DO: Minimize file I/O operations per feature execution\n  - ✅ DO: Cache tag resolution results when appropriate\n  - ✅ DO: Use streaming for large task datasets\n  - ❌ DON'T: Load all tags when only one is needed\n\n- **Memory Management**:\n  - ✅ DO: Process large task lists efficiently\n  - ✅ DO: Clean up temporary data structures\n  - ✅ DO: Avoid keeping all tag data in memory simultaneously\n\n## Deployment and Versioning\n\n- **Changesets**:\n  - ✅ DO: Create appropriate changesets for new features\n  - ✅ DO: Use semantic versioning (minor for new features)\n  - ✅ DO: Include tagged system information in release notes\n  - ✅ DO: Document breaking changes if any\n\n- **Feature Flags**:\n  - ✅ DO: Consider feature flags for experimental functionality\n  - ✅ DO: Ensure tagged system features work with flags\n  - ✅ DO: Provide clear documentation about flag usage\n\nBy following these guidelines, new features will integrate smoothly with the Task Master ecosystem while supporting the enhanced tagged task lists system for multi-context development workflows.\n\n<!-- File: .cursor/rules/self_improve.mdc (Tokens: ~529 | Category: cursor-rule) -->\n---\ndescription: Guidelines for continuously improving Cursor rules based on emerging code patterns and best practices.\nglobs: **/*\nalwaysApply: true\n---\n\n- **Rule Improvement Triggers:**\n  - New code patterns not covered by existing rules\n  - Repeated similar implementations across files\n  - Common error patterns that could be prevented\n  - New libraries or tools being used consistently\n  - Emerging best practices in the codebase\n\n- **Analysis Process:**\n  - Compare new code with existing rules\n  - Identify patterns that should be standardized\n  - Look for references to external documentation\n  - Check for consistent error handling patterns\n  - Monitor test patterns and coverage\n\n- **Rule Updates:**\n  - **Add New Rules When:**\n    - A new technology/pattern is used in 3+ files\n    - Common bugs could be prevented by a rule\n    - Code reviews repeatedly mention the same feedback\n    - New security or performance patterns emerge\n\n  - **Modify Existing Rules When:**\n    - Better examples exist in the codebase\n    - Additional edge cases are discovered\n    - Related rules have been updated\n    - Implementation details have changed\n\n- **Example Pattern Recognition:**\n  ```typescript\n  // If you see repeated patterns like:\n  const data = await prisma.user.findMany({\n    select: { id: true, email: true },\n    where: { status: 'ACTIVE' }\n  });\n  \n  // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc):\n  // - Standard select fields\n  // - Common where conditions\n  // - Performance optimization patterns\n  ```\n\n- **Rule Quality Checks:**\n  - Rules should be actionable and specific\n  - Examples should come from actual code\n  - References should be up to date\n  - Patterns should be consistently enforced\n\n- **Continuous Improvement:**\n  - Monitor code review comments\n  - Track common development questions\n  - Update rules after major refactors\n  - Add links to relevant documentation\n  - Cross-reference related rules\n\n- **Rule Deprecation:**\n  - Mark outdated patterns as deprecated\n  - Remove rules that no longer apply\n  - Update references to deprecated rules\n  - Document migration paths for old patterns\n\n- **Documentation Updates:**\n  - Keep examples synchronized with code\n  - Update references to external docs\n  - Maintain links between related rules\n  - Document breaking changes\nFollow [cursor_rules.mdc](mdc:.cursor/rules/cursor_rules.mdc) for proper rule formatting and structure.\n\n<!-- File: .cursor/rules/tags.mdc (Tokens: ~1684 | Category: cursor-rule) -->\n---\ndescription: \nglobs: scripts/modules/*\nalwaysApply: false\n---\n# Tagged Task Lists Command Patterns\n\nThis document outlines the standardized patterns that **ALL** Task Master commands must follow to properly support the tagged task lists system.\n\n## Core Principles\n\n- **Every command** that reads or writes tasks.json must be tag-aware\n- **Consistent tag resolution** across all commands using `getCurrentTag(projectRoot)`\n- **Proper context passing** to core functions with `{ projectRoot, tag }`\n- **Standardized CLI options** with `--tag <tag>` flag\n\n## Required Imports\n\nAll command files must import `getCurrentTag`:\n\n```javascript\n// ✅ DO: Import getCurrentTag in commands.js\nimport { \n  log, \n  readJSON, \n  writeJSON, \n  findProjectRoot, \n  getCurrentTag \n} from './utils.js';\n\n// ✅ DO: Import getCurrentTag in task-manager files\nimport { \n  readJSON, \n  writeJSON, \n  getCurrentTag \n} from '../utils.js';\n```\n\n## CLI Command Pattern\n\nEvery CLI command that operates on tasks must follow this exact pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware CLI command pattern\nprogramInstance\n  .command('command-name')\n  .description('Command description')\n  .option('-f, --file <file>', 'Path to the tasks file', TASKMASTER_TASKS_FILE)\n  .option('--tag <tag>', 'Specify tag context for task operations') // REQUIRED\n  .action(async (options) => {\n    // 1. Find project root\n    const projectRoot = findProjectRoot();\n    if (!projectRoot) {\n      console.error(chalk.red('Error: Could not find project root.'));\n      process.exit(1);\n    }\n\n    // 2. Resolve tag using standard pattern\n    const tag = options.tag || getCurrentTag(projectRoot) || 'master';\n\n    // 3. Call core function with proper context\n    await coreFunction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag } // REQUIRED context object\n    );\n  });\n```\n\n## Core Function Pattern\n\nAll core functions in `scripts/modules/task-manager/` must follow this pattern:\n\n```javascript\n// ✅ DO: Standard tag-aware core function pattern\nasync function coreFunction(\n  tasksPath,\n  // ... other parameters ...\n  context = {} // REQUIRED context parameter\n) {\n  const { projectRoot, tag } = context;\n  \n  // Use tag-aware readJSON/writeJSON\n  const data = readJSON(tasksPath, projectRoot, tag);\n  \n  // ... function logic ...\n  \n  writeJSON(tasksPath, data, projectRoot, tag);\n}\n```\n\n## Tag Resolution Priority\n\nThe tag resolution follows this exact priority order:\n\n1. **Explicit `--tag` flag**: `options.tag`\n2. **Current active tag**: `getCurrentTag(projectRoot)`  \n3. **Default fallback**: `'master'`\n\n```javascript\n// ✅ DO: Standard tag resolution pattern\nconst tag = options.tag || getCurrentTag(projectRoot) || 'master';\n```\n\n## Commands Requiring Updates\n\n### High Priority (Core Task Operations)\n- [x] `add-task` - ✅ Fixed\n- [x] `list` - ✅ Fixed  \n- [x] `update-task` - ✅ Fixed\n- [x] `update-subtask` - ✅ Fixed\n- [x] `set-status` - ✅ Already correct\n- [x] `remove-task` - ✅ Already correct\n- [x] `remove-subtask` - ✅ Fixed\n- [x] `add-subtask` - ✅ Already correct\n- [x] `clear-subtasks` - ✅ Fixed\n- [x] `move-task` - ✅ Already correct\n\n### Medium Priority (Analysis & Expansion)\n- [x] `expand` - ✅ Fixed\n- [ ] `next` - ✅ Fixed\n- [ ] `show` (get-task) - Needs checking\n- [ ] `analyze-complexity` - Needs checking\n- [ ] `generate` - ✅ Fixed\n\n### Lower Priority (Utilities)\n- [ ] `research` - Needs checking\n- [ ] `complexity-report` - Needs checking\n- [ ] `validate-dependencies` - ✅ Fixed\n- [ ] `fix-dependencies` - ✅ Fixed\n- [ ] `add-dependency` - ✅ Fixed\n- [ ] `remove-dependency` - ✅ Fixed\n\n## MCP Integration Pattern\n\nMCP direct functions must also follow the tag-aware pattern:\n\n```javascript\n// ✅ DO: Tag-aware MCP direct function\nexport async function coreActionDirect(args, log, context = {}) {\n  const { session } = context;\n  const { projectRoot, tag } = args; // MCP passes these in args\n  \n  try {\n    const result = await coreAction(\n      tasksPath,\n      // ... other parameters ...\n      { projectRoot, tag, session, mcpLog: logWrapper }\n    );\n    \n    return { success: true, data: result };\n  } catch (error) {\n    return { success: false, error: { code: 'ERROR_CODE', message: error.message } };\n  }\n}\n```\n\n## File Generation Tag-Aware Naming\n\nThe `generate` command must use tag-aware file naming:\n\n```javascript\n// ✅ DO: Tag-aware file naming\nconst taskFileName = targetTag === 'master' \n  ? `task_${task.id.toString().padStart(3, '0')}.txt`\n  : `task_${task.id.toString().padStart(3, '0')}_${targetTag}.txt`;\n```\n\n**Examples:**\n- Master tag: `task_001.txt`, `task_002.txt`\n- Other tags: `task_001_feature.txt`, `task_002_feature.txt`\n\n## Common Anti-Patterns\n\n```javascript\n// ❌ DON'T: Missing getCurrentTag import\nimport { readJSON, writeJSON } from '../utils.js'; // Missing getCurrentTag\n\n// ❌ DON'T: Hard-coded tag resolution\nconst tag = options.tag || 'master'; // Missing getCurrentTag\n\n// ❌ DON'T: Missing --tag option\n.option('-f, --file <file>', 'Path to tasks file') // Missing --tag option\n\n// ❌ DON'T: Missing context parameter\nawait coreFunction(tasksPath, param1, param2); // Missing { projectRoot, tag }\n\n// ❌ DON'T: Incorrect readJSON/writeJSON calls\nconst data = readJSON(tasksPath); // Missing projectRoot and tag\nwriteJSON(tasksPath, data); // Missing projectRoot and tag\n```\n\n## Validation Checklist\n\nFor each command, verify:\n\n- [ ] Imports `getCurrentTag` from utils.js\n- [ ] Has `--tag <tag>` CLI option\n- [ ] Uses standard tag resolution: `options.tag || getCurrentTag(projectRoot) || 'master'`\n- [ ] Finds `projectRoot` with error handling\n- [ ] Passes `{ projectRoot, tag }` context to core functions\n- [ ] Core functions accept and use context parameter\n- [ ] Uses `readJSON(tasksPath, projectRoot, tag)` and `writeJSON(tasksPath, data, projectRoot, tag)`\n\n## Testing Tag Resolution\n\nTest each command with:\n\n```bash\n# Test with explicit tag\nnode bin/task-master command-name --tag test-tag\n\n# Test with active tag (should use current active tag)\nnode bin/task-master use-tag test-tag\nnode bin/task-master command-name\n\n# Test with master tag (default)\nnode bin/task-master use-tag master  \nnode bin/task-master command-name\n```\n\n## Migration Strategy\n\n1. **Audit Phase**: Systematically check each command against the checklist\n2. **Fix Phase**: Apply the standard patterns to non-compliant commands\n3. **Test Phase**: Verify tag resolution works correctly\n4. **Document Phase**: Update command documentation with tag support\n\nThis ensures consistent, predictable behavior across all Task Master commands and prevents tag deletion bugs.\n\n<!-- File: .cursor/rules/taskmaster.mdc (Tokens: ~10945 | Category: cursor-rule) -->\n---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `--no-git`: `Skip initializing a Git repository entirely.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `noGit`: `Skip initializing a Git repository entirely. Default is false.` (CLI: `--no-git`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [Development Workflow Guide](mdc:.cursor/rules/dev_workflow.mdc).\n\n<!-- File: .cursor/rules/taskmaster/dev_workflow.mdc (Tokens: ~6835 | Category: cursor-rule) -->\n---\ndescription: Guide for using Taskmaster to manage task-driven development workflows\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Development Workflow\n\nThis guide outlines the standard process for using Taskmaster to manage software development projects. It is written as a set of instructions for you, the AI agent.\n\n- **Your Default Stance**: For most projects, the user can work directly within the `master` task context. Your initial actions should operate on this default context unless a clear pattern for multi-context work emerges.\n- **Your Goal**: Your role is to elevate the user's workflow by intelligently introducing advanced features like **Tagged Task Lists** when you detect the appropriate context. Do not force tags on the user; suggest them as a helpful solution to a specific need.\n\n## The Basic Loop\nThe fundamental development cycle you will facilitate is:\n1.  **`list`**: Show the user what needs to be done.\n2.  **`next`**: Help the user decide what to work on.\n3.  **`show <id>`**: Provide details for a specific task.\n4.  **`expand <id>`**: Break down a complex task into smaller, manageable subtasks.\n5.  **Implement**: The user writes the code and tests.\n6.  **`update-subtask`**: Log progress and findings on behalf of the user.\n7.  **`set-status`**: Mark tasks and subtasks as `done` as work is completed.\n8.  **Repeat**.\n\nAll your standard command executions should operate on the user's current task context, which defaults to `master`.\n\n---\n\n## Standard Development Workflow Process\n\n### Simple Workflow (Default Starting Point)\n\nFor new projects or when users are getting started, operate within the `master` tag context:\n\n-   Start new projects by running `initialize_project` tool / `task-master init` or `parse_prd` / `task-master parse-prd --input='<prd-file.txt>'` (see @`taskmaster.mdc`) to generate initial tasks.json with tagged structure\n-   Configure rule sets during initialization with `--rules` flag (e.g., `task-master init --rules cursor,windsurf`) or manage them later with `task-master rules add/remove` commands  \n-   Begin coding sessions with `get_tasks` / `task-master list` (see @`taskmaster.mdc`) to see current tasks, status, and IDs\n-   Determine the next task to work on using `next_task` / `task-master next` (see @`taskmaster.mdc`)\n-   Analyze task complexity with `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) before breaking down tasks\n-   Review complexity report using `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`)\n-   Select tasks based on dependencies (all marked 'done'), priority level, and ID order\n-   View specific task details using `get_task` / `task-master show <id>` (see @`taskmaster.mdc`) to understand implementation requirements\n-   Break down complex tasks using `expand_task` / `task-master expand --id=<id> --force --research` (see @`taskmaster.mdc`) with appropriate flags like `--force` (to replace existing subtasks) and `--research`\n-   Implement code following task details, dependencies, and project standards\n-   Mark completed tasks with `set_task_status` / `task-master set-status --id=<id> --status=done` (see @`taskmaster.mdc`)\n-   Update dependent tasks when implementation differs from original plan using `update` / `task-master update --from=<id> --prompt=\"...\"` or `update_task` / `task-master update-task --id=<id> --prompt=\"...\"` (see @`taskmaster.mdc`)\n\n---\n\n## Leveling Up: Agent-Led Multi-Context Workflows\n\nWhile the basic workflow is powerful, your primary opportunity to add value is by identifying when to introduce **Tagged Task Lists**. These patterns are your tools for creating a more organized and efficient development environment for the user, especially if you detect agentic or parallel development happening across the same session.\n\n**Critical Principle**: Most users should never see a difference in their experience. Only introduce advanced workflows when you detect clear indicators that the project has evolved beyond simple task management.\n\n### When to Introduce Tags: Your Decision Patterns\n\nHere are the patterns to look for. When you detect one, you should propose the corresponding workflow to the user.\n\n#### Pattern 1: Simple Git Feature Branching\nThis is the most common and direct use case for tags.\n\n- **Trigger**: The user creates a new git branch (e.g., `git checkout -b feature/user-auth`).\n- **Your Action**: Propose creating a new tag that mirrors the branch name to isolate the feature's tasks from `master`.\n- **Your Suggested Prompt**: *\"I see you've created a new branch named 'feature/user-auth'. To keep all related tasks neatly organized and separate from your main list, I can create a corresponding task tag for you. This helps prevent merge conflicts in your `tasks.json` file later. Shall I create the 'feature-user-auth' tag?\"*\n- **Tool to Use**: `task-master add-tag --from-branch`\n\n#### Pattern 2: Team Collaboration\n- **Trigger**: The user mentions working with teammates (e.g., \"My teammate Alice is handling the database schema,\" or \"I need to review Bob's work on the API.\").\n- **Your Action**: Suggest creating a separate tag for the user's work to prevent conflicts with shared master context.\n- **Your Suggested Prompt**: *\"Since you're working with Alice, I can create a separate task context for your work to avoid conflicts. This way, Alice can continue working with the master list while you have your own isolated context. When you're ready to merge your work, we can coordinate the tasks back to master. Shall I create a tag for your current work?\"*\n- **Tool to Use**: `task-master add-tag my-work --copy-from-current --description=\"My tasks while collaborating with Alice\"`\n\n#### Pattern 3: Experiments or Risky Refactors\n- **Trigger**: The user wants to try something that might not be kept (e.g., \"I want to experiment with switching our state management library,\" or \"Let's refactor the old API module, but I want to keep the current tasks as a reference.\").\n- **Your Action**: Propose creating a sandboxed tag for the experimental work.\n- **Your Suggested Prompt**: *\"This sounds like a great experiment. To keep these new tasks separate from our main plan, I can create a temporary 'experiment-zustand' tag for this work. If we decide not to proceed, we can simply delete the tag without affecting the main task list. Sound good?\"*\n- **Tool to Use**: `task-master add-tag experiment-zustand --description=\"Exploring Zustand migration\"`\n\n#### Pattern 4: Large Feature Initiatives (PRD-Driven)\nThis is a more structured approach for significant new features or epics.\n\n- **Trigger**: The user describes a large, multi-step feature that would benefit from a formal plan.\n- **Your Action**: Propose a comprehensive, PRD-driven workflow.\n- **Your Suggested Prompt**: *\"This sounds like a significant new feature. To manage this effectively, I suggest we create a dedicated task context for it. Here's the plan: I'll create a new tag called 'feature-xyz', then we can draft a Product Requirements Document (PRD) together to scope the work. Once the PRD is ready, I'll automatically generate all the necessary tasks within that new tag. How does that sound?\"*\n- **Your Implementation Flow**:\n    1.  **Create an empty tag**: `task-master add-tag feature-xyz --description \"Tasks for the new XYZ feature\"`. You can also start by creating a git branch if applicable, and then create the tag from that branch.\n    2.  **Collaborate & Create PRD**: Work with the user to create a detailed PRD file (e.g., `.taskmaster/docs/feature-xyz-prd.txt`).\n    3.  **Parse PRD into the new tag**: `task-master parse-prd .taskmaster/docs/feature-xyz-prd.txt --tag feature-xyz`\n    4.  **Prepare the new task list**: Follow up by suggesting `analyze-complexity` and `expand-all` for the newly created tasks within the `feature-xyz` tag.\n\n#### Pattern 5: Version-Based Development\nTailor your approach based on the project maturity indicated by tag names.\n\n- **Prototype/MVP Tags** (`prototype`, `mvp`, `poc`, `v0.x`):\n  - **Your Approach**: Focus on speed and functionality over perfection\n  - **Task Generation**: Create tasks that emphasize \"get it working\" over \"get it perfect\"\n  - **Complexity Level**: Lower complexity, fewer subtasks, more direct implementation paths\n  - **Research Prompts**: Include context like \"This is a prototype - prioritize speed and basic functionality over optimization\"\n  - **Example Prompt Addition**: *\"Since this is for the MVP, I'll focus on tasks that get core functionality working quickly rather than over-engineering.\"*\n\n- **Production/Mature Tags** (`v1.0+`, `production`, `stable`):\n  - **Your Approach**: Emphasize robustness, testing, and maintainability\n  - **Task Generation**: Include comprehensive error handling, testing, documentation, and optimization\n  - **Complexity Level**: Higher complexity, more detailed subtasks, thorough implementation paths\n  - **Research Prompts**: Include context like \"This is for production - prioritize reliability, performance, and maintainability\"\n  - **Example Prompt Addition**: *\"Since this is for production, I'll ensure tasks include proper error handling, testing, and documentation.\"*\n\n### Advanced Workflow (Tag-Based & PRD-Driven)\n\n**When to Transition**: Recognize when the project has evolved (or has initiated a project which existing code) beyond simple task management. Look for these indicators:\n- User mentions teammates or collaboration needs\n- Project has grown to 15+ tasks with mixed priorities\n- User creates feature branches or mentions major initiatives\n- User initializes Taskmaster on an existing, complex codebase\n- User describes large features that would benefit from dedicated planning\n\n**Your Role in Transition**: Guide the user to a more sophisticated workflow that leverages tags for organization and PRDs for comprehensive planning.\n\n#### Master List Strategy (High-Value Focus)\nOnce you transition to tag-based workflows, the `master` tag should ideally contain only:\n- **High-level deliverables** that provide significant business value\n- **Major milestones** and epic-level features\n- **Critical infrastructure** work that affects the entire project\n- **Release-blocking** items\n\n**What NOT to put in master**:\n- Detailed implementation subtasks (these go in feature-specific tags' parent tasks)\n- Refactoring work (create dedicated tags like `refactor-auth`)\n- Experimental features (use `experiment-*` tags)\n- Team member-specific tasks (use person-specific tags)\n\n#### PRD-Driven Feature Development\n\n**For New Major Features**:\n1. **Identify the Initiative**: When user describes a significant feature\n2. **Create Dedicated Tag**: `add_tag feature-[name] --description=\"[Feature description]\"`\n3. **Collaborative PRD Creation**: Work with user to create comprehensive PRD in `.taskmaster/docs/feature-[name]-prd.txt`\n4. **Parse & Prepare**: \n   - `parse_prd .taskmaster/docs/feature-[name]-prd.txt --tag=feature-[name]`\n   - `analyze_project_complexity --tag=feature-[name] --research`\n   - `expand_all --tag=feature-[name] --research`\n5. **Add Master Reference**: Create a high-level task in `master` that references the feature tag\n\n**For Existing Codebase Analysis**:\nWhen users initialize Taskmaster on existing projects:\n1. **Codebase Discovery**: Use your native tools for producing deep context about the code base. You may use `research` tool with `--tree` and `--files` to collect up to date information using the existing architecture as context.\n2. **Collaborative Assessment**: Work with user to identify improvement areas, technical debt, or new features\n3. **Strategic PRD Creation**: Co-author PRDs that include:\n   - Current state analysis (based on your codebase research)\n   - Proposed improvements or new features\n   - Implementation strategy considering existing code\n4. **Tag-Based Organization**: Parse PRDs into appropriate tags (`refactor-api`, `feature-dashboard`, `tech-debt`, etc.)\n5. **Master List Curation**: Keep only the most valuable initiatives in master\n\nThe parse-prd's `--append` flag enables the user to parse multiple PRDs within tags or across tags. PRDs should be focused and the number of tasks they are parsed into should be strategically chosen relative to the PRD's complexity and level of detail.\n\n### Workflow Transition Examples\n\n**Example 1: Simple → Team-Based**\n```\nUser: \"Alice is going to help with the API work\"\nYour Response: \"Great! To avoid conflicts, I'll create a separate task context for your work. Alice can continue with the master list while you work in your own context. When you're ready to merge, we can coordinate the tasks back together.\"\nAction: add_tag my-api-work --copy-from-current --description=\"My API tasks while collaborating with Alice\"\n```\n\n**Example 2: Simple → PRD-Driven**\n```\nUser: \"I want to add a complete user dashboard with analytics, user management, and reporting\"\nYour Response: \"This sounds like a major feature that would benefit from detailed planning. Let me create a dedicated context for this work and we can draft a PRD together to ensure we capture all requirements.\"\nActions: \n1. add_tag feature-dashboard --description=\"User dashboard with analytics and management\"\n2. Collaborate on PRD creation\n3. parse_prd dashboard-prd.txt --tag=feature-dashboard\n4. Add high-level \"User Dashboard\" task to master\n```\n\n**Example 3: Existing Project → Strategic Planning**\n```\nUser: \"I just initialized Taskmaster on my existing React app. It's getting messy and I want to improve it.\"\nYour Response: \"Let me research your codebase to understand the current architecture, then we can create a strategic plan for improvements.\"\nActions:\n1. research \"Current React app architecture and improvement opportunities\" --tree --files=src/\n2. Collaborate on improvement PRD based on findings\n3. Create tags for different improvement areas (refactor-components, improve-state-management, etc.)\n4. Keep only major improvement initiatives in master\n```\n\n---\n\n## Primary Interaction: MCP Server vs. CLI\n\nTaskmaster offers two primary ways to interact:\n\n1.  **MCP Server (Recommended for Integrated Tools)**:\n    - For AI agents and integrated development environments (like Cursor), interacting via the **MCP server is the preferred method**.\n    - The MCP server exposes Taskmaster functionality through a set of tools (e.g., `get_tasks`, `add_subtask`).\n    - This method offers better performance, structured data exchange, and richer error handling compared to CLI parsing.\n    - Refer to @`mcp.mdc` for details on the MCP architecture and available tools.\n    - A comprehensive list and description of MCP tools and their corresponding CLI commands can be found in @`taskmaster.mdc`.\n    - **Restart the MCP server** if core logic in `scripts/modules` or MCP tool/direct function definitions change.\n    - **Note**: MCP tools fully support tagged task lists with complete tag management capabilities.\n\n2.  **`task-master` CLI (For Users & Fallback)**:\n    - The global `task-master` command provides a user-friendly interface for direct terminal interaction.\n    - It can also serve as a fallback if the MCP server is inaccessible or a specific function isn't exposed via MCP.\n    - Install globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.\n    - The CLI commands often mirror the MCP tools (e.g., `task-master list` corresponds to `get_tasks`).\n    - Refer to @`taskmaster.mdc` for a detailed command reference.\n    - **Tagged Task Lists**: CLI fully supports the new tagged system with seamless migration.\n\n## How the Tag System Works (For Your Reference)\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) like \"master\", \"feature-branch\", or \"v2.0\".\n- **Silent Migration**: Existing projects automatically migrate to use a \"master\" tag with zero disruption.\n- **Context Isolation**: Tasks in different tags are completely separate. Changes in one tag do not affect any other tag.\n- **Manual Control**: The user is always in control. There is no automatic switching. You facilitate switching by using `use-tag <name>`.\n- **Full CLI & MCP Support**: All tag management commands are available through both the CLI and MCP tools for you to use. Refer to @`taskmaster.mdc` for a full command list.\n\n---\n\n## Task Complexity Analysis\n\n-   Run `analyze_project_complexity` / `task-master analyze-complexity --research` (see @`taskmaster.mdc`) for comprehensive analysis\n-   Review complexity report via `complexity_report` / `task-master complexity-report` (see @`taskmaster.mdc`) for a formatted, readable version.\n-   Focus on tasks with highest complexity scores (8-10) for detailed breakdown\n-   Use analysis results to determine appropriate subtask allocation\n-   Note that reports are automatically used by the `expand_task` tool/command\n\n## Task Breakdown Process\n\n-   Use `expand_task` / `task-master expand --id=<id>`. It automatically uses the complexity report if found, otherwise generates default number of subtasks.\n-   Use `--num=<number>` to specify an explicit number of subtasks, overriding defaults or complexity report recommendations.\n-   Add `--research` flag to leverage Perplexity AI for research-backed expansion.\n-   Add `--force` flag to clear existing subtasks before generating new ones (default is to append).\n-   Use `--prompt=\"<context>\"` to provide additional context when needed.\n-   Review and adjust generated subtasks as necessary.\n-   Use `expand_all` tool or `task-master expand --all` to expand multiple pending tasks at once, respecting flags like `--force` and `--research`.\n-   If subtasks need complete replacement (regardless of the `--force` flag on `expand`), clear them first with `clear_subtasks` / `task-master clear-subtasks --id=<id>`.\n\n## Implementation Drift Handling\n\n-   When implementation differs significantly from planned approach\n-   When future tasks need modification due to current implementation choices\n-   When new dependencies or requirements emerge\n-   Use `update` / `task-master update --from=<futureTaskId> --prompt='<explanation>\\nUpdate context...' --research` to update multiple future tasks.\n-   Use `update_task` / `task-master update-task --id=<taskId> --prompt='<explanation>\\nUpdate context...' --research` to update a single specific task.\n\n## Task Status Management\n\n-   Use 'pending' for tasks ready to be worked on\n-   Use 'done' for completed and verified tasks\n-   Use 'deferred' for postponed tasks\n-   Add custom status values as needed for project-specific workflows\n\n## Task Structure Fields\n\n- **id**: Unique identifier for the task (Example: `1`, `1.1`)\n- **title**: Brief, descriptive title (Example: `\"Initialize Repo\"`)\n- **description**: Concise summary of what the task involves (Example: `\"Create a new repository, set up initial structure.\"`)\n- **status**: Current state of the task (Example: `\"pending\"`, `\"done\"`, `\"deferred\"`)\n- **dependencies**: IDs of prerequisite tasks (Example: `[1, 2.1]`)\n    - Dependencies are displayed with status indicators (✅ for completed, ⏱️ for pending)\n    - This helps quickly identify which prerequisite tasks are blocking work\n- **priority**: Importance level (Example: `\"high\"`, `\"medium\"`, `\"low\"`)\n- **details**: In-depth implementation instructions (Example: `\"Use GitHub client ID/secret, handle callback, set session token.\"`) \n- **testStrategy**: Verification approach (Example: `\"Deploy and call endpoint to confirm 'Hello World' response.\"`) \n- **subtasks**: List of smaller, more specific tasks (Example: `[{\"id\": 1, \"title\": \"Configure OAuth\", ...}]`) \n- Refer to task structure details (previously linked to `tasks.mdc`).\n\n## Configuration Management (Updated)\n\nTaskmaster configuration is managed through two main mechanisms:\n\n1.  **`.taskmaster/config.json` File (Primary):**\n    *   Located in the project root directory.\n    *   Stores most configuration settings: AI model selections (main, research, fallback), parameters (max tokens, temperature), logging level, default subtasks/priority, project name, etc.\n    *   **Tagged System Settings**: Includes `global.defaultTag` (defaults to \"master\") and `tags` section for tag management configuration.\n    *   **Managed via `task-master models --setup` command.** Do not edit manually unless you know what you are doing.\n    *   **View/Set specific models via `task-master models` command or `models` MCP tool.**\n    *   Created automatically when you run `task-master models --setup` for the first time or during tagged system migration.\n\n2.  **Environment Variables (`.env` / `mcp.json`):**\n    *   Used **only** for sensitive API keys and specific endpoint URLs.\n    *   Place API keys (one per provider) in a `.env` file in the project root for CLI usage.\n    *   For MCP/Cursor integration, configure these keys in the `env` section of `.cursor/mcp.json`.\n    *   Available keys/variables: See `assets/env.example` or the Configuration section in the command reference (previously linked to `taskmaster.mdc`).\n\n3.  **`.taskmaster/state.json` File (Tagged System State):**\n    *   Tracks current tag context and migration status.\n    *   Automatically created during tagged system migration.\n    *   Contains: `currentTag`, `lastSwitched`, `migrationNoticeShown`.\n\n**Important:** Non-API key settings (like model selections, `MAX_TOKENS`, `TASKMASTER_LOG_LEVEL`) are **no longer configured via environment variables**. Use the `task-master models` command (or `--setup` for interactive configuration) or the `models` MCP tool.\n**If AI commands FAIL in MCP** verify that the API key for the selected provider is present in the `env` section of `.cursor/mcp.json`.\n**If AI commands FAIL in CLI** verify that the API key for the selected provider is present in the `.env` file in the root of the project.\n\n## Rules Management\n\nTaskmaster supports multiple AI coding assistant rule sets that can be configured during project initialization or managed afterward:\n\n- **Available Profiles**: Claude Code, Cline, Codex, Cursor, Roo Code, Trae, Windsurf (claude, cline, codex, cursor, roo, trae, windsurf)\n- **During Initialization**: Use `task-master init --rules cursor,windsurf` to specify which rule sets to include\n- **After Initialization**: Use `task-master rules add <profiles>` or `task-master rules remove <profiles>` to manage rule sets\n- **Interactive Setup**: Use `task-master rules setup` to launch an interactive prompt for selecting rule profiles\n- **Default Behavior**: If no `--rules` flag is specified during initialization, all available rule profiles are included\n- **Rule Structure**: Each profile creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files\n\n## Determining the Next Task\n\n- Run `next_task` / `task-master next` to show the next task to work on.\n- The command identifies tasks with all dependencies satisfied\n- Tasks are prioritized by priority level, dependency count, and ID\n- The command shows comprehensive task information including:\n    - Basic task details and description\n    - Implementation details\n    - Subtasks (if they exist)\n    - Contextual suggested actions\n- Recommended before starting any new development work\n- Respects your project's dependency structure\n- Ensures tasks are completed in the appropriate sequence\n- Provides ready-to-use commands for common task actions\n\n## Viewing Specific Task Details\n\n- Run `get_task` / `task-master show <id>` to view a specific task.\n- Use dot notation for subtasks: `task-master show 1.2` (shows subtask 2 of task 1)\n- Displays comprehensive information similar to the next command, but for a specific task\n- For parent tasks, shows all subtasks and their current status\n- For subtasks, shows parent task information and relationship\n- Provides contextual suggested actions appropriate for the specific task\n- Useful for examining task details before implementation or checking status\n\n## Managing Task Dependencies\n\n- Use `add_dependency` / `task-master add-dependency --id=<id> --depends-on=<id>` to add a dependency.\n- Use `remove_dependency` / `task-master remove-dependency --id=<id> --depends-on=<id>` to remove a dependency.\n- The system prevents circular dependencies and duplicate dependency entries\n- Dependencies are checked for existence before being added or removed\n- Task files are automatically regenerated after dependency changes\n- Dependencies are visualized with status indicators in task listings and files\n\n## Task Reorganization\n\n- Use `move_task` / `task-master move --from=<id> --to=<id>` to move tasks or subtasks within the hierarchy\n- This command supports several use cases:\n  - Moving a standalone task to become a subtask (e.g., `--from=5 --to=7`)\n  - Moving a subtask to become a standalone task (e.g., `--from=5.2 --to=7`) \n  - Moving a subtask to a different parent (e.g., `--from=5.2 --to=7.3`)\n  - Reordering subtasks within the same parent (e.g., `--from=5.2 --to=5.4`)\n  - Moving a task to a new, non-existent ID position (e.g., `--from=5 --to=25`)\n  - Moving multiple tasks at once using comma-separated IDs (e.g., `--from=10,11,12 --to=16,17,18`)\n- The system includes validation to prevent data loss:\n  - Allows moving to non-existent IDs by creating placeholder tasks\n  - Prevents moving to existing task IDs that have content (to avoid overwriting)\n  - Validates source tasks exist before attempting to move them\n- The system maintains proper parent-child relationships and dependency integrity\n- Task files are automatically regenerated after the move operation\n- This provides greater flexibility in organizing and refining your task structure as project understanding evolves\n- This is especially useful when dealing with potential merge conflicts arising from teams creating tasks on separate branches. Solve these conflicts very easily by moving your tasks and keeping theirs.\n\n## Iterative Subtask Implementation\n\nOnce a task has been broken down into subtasks using `expand_task` or similar methods, follow this iterative process for implementation:\n\n1.  **Understand the Goal (Preparation):**\n    *   Use `get_task` / `task-master show <subtaskId>` (see @`taskmaster.mdc`) to thoroughly understand the specific goals and requirements of the subtask.\n\n2.  **Initial Exploration & Planning (Iteration 1):**\n    *   This is the first attempt at creating a concrete implementation plan.\n    *   Explore the codebase to identify the precise files, functions, and even specific lines of code that will need modification.\n    *   Determine the intended code changes (diffs) and their locations.\n    *   Gather *all* relevant details from this exploration phase.\n\n3.  **Log the Plan:**\n    *   Run `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<detailed plan>'`.\n    *   Provide the *complete and detailed* findings from the exploration phase in the prompt. Include file paths, line numbers, proposed diffs, reasoning, and any potential challenges identified. Do not omit details. The goal is to create a rich, timestamped log within the subtask's `details`.\n\n4.  **Verify the Plan:**\n    *   Run `get_task` / `task-master show <subtaskId>` again to confirm that the detailed implementation plan has been successfully appended to the subtask's details.\n\n5.  **Begin Implementation:**\n    *   Set the subtask status using `set_task_status` / `task-master set-status --id=<subtaskId> --status=in-progress`.\n    *   Start coding based on the logged plan.\n\n6.  **Refine and Log Progress (Iteration 2+):**\n    *   As implementation progresses, you will encounter challenges, discover nuances, or confirm successful approaches.\n    *   **Before appending new information**: Briefly review the *existing* details logged in the subtask (using `get_task` or recalling from context) to ensure the update adds fresh insights and avoids redundancy.\n    *   **Regularly** use `update_subtask` / `task-master update-subtask --id=<subtaskId> --prompt='<update details>\\n- What worked...\\n- What didn't work...'` to append new findings.\n    *   **Crucially, log:**\n        *   What worked (\"fundamental truths\" discovered).\n        *   What didn't work and why (to avoid repeating mistakes).\n        *   Specific code snippets or configurations that were successful.\n        *   Decisions made, especially if confirmed with user input.\n        *   Any deviations from the initial plan and the reasoning.\n    *   The objective is to continuously enrich the subtask's details, creating a log of the implementation journey that helps the AI (and human developers) learn, adapt, and avoid repeating errors.\n\n7.  **Review & Update Rules (Post-Implementation):**\n    *   Once the implementation for the subtask is functionally complete, review all code changes and the relevant chat history.\n    *   Identify any new or modified code patterns, conventions, or best practices established during the implementation.\n    *   Create new or update existing rules following internal guidelines (previously linked to `cursor_rules.mdc` and `self_improve.mdc`).\n\n8.  **Mark Task Complete:**\n    *   After verifying the implementation and updating any necessary rules, mark the subtask as completed: `set_task_status` / `task-master set-status --id=<subtaskId> --status=done`.\n\n9.  **Commit Changes (If using Git):**\n    *   Stage the relevant code changes and any updated/new rule files (`git add .`).\n    *   Craft a comprehensive Git commit message summarizing the work done for the subtask, including both code implementation and any rule adjustments.\n    *   Execute the commit command directly in the terminal (e.g., `git commit -m 'feat(module): Implement feature X for subtask <subtaskId>\\n\\n- Details about changes...\\n- Updated rule Y for pattern Z'`).\n    *   Consider if a Changeset is needed according to internal versioning guidelines (previously linked to `changeset.mdc`). If so, run `npm run changeset`, stage the generated file, and amend the commit or create a new one.\n\n10. **Proceed to Next Subtask:**\n    *   Identify the next subtask (e.g., using `next_task` / `task-master next`).\n\n## Code Analysis & Refactoring Techniques\n\n- **Top-Level Function Search**:\n    - Useful for understanding module structure or planning refactors.\n    - Use grep/ripgrep to find exported functions/constants:\n      `rg \"export (async function|function|const) \\w+\"` or similar patterns.\n    - Can help compare functions between files during migrations or identify potential naming conflicts.\n\n---\n*This workflow provides a general guideline. Adapt it based on your specific project needs and team practices.*\n\n<!-- File: .cursor/rules/taskmaster/taskmaster.mdc (Tokens: ~10904 | Category: cursor-rule) -->\n---\ndescription: Comprehensive reference for Taskmaster MCP tools and CLI commands.\nglobs: **/*\nalwaysApply: true\n---\n\n# Taskmaster Tool & Command Reference\n\nThis document provides a detailed reference for interacting with Taskmaster, covering both the recommended MCP tools, suitable for integrations like Cursor, and the corresponding `task-master` CLI commands, designed for direct user interaction or fallback.\n\n**Note:** For interacting with Taskmaster programmatically or via integrated tools, using the **MCP tools is strongly recommended** due to better performance, structured data, and error handling. The CLI commands serve as a user-friendly alternative and fallback. \n\n**Important:** Several MCP tools involve AI processing... The AI-powered tools include `parse_prd`, `analyze_project_complexity`, `update_subtask`, `update_task`, `update`, `expand_all`, `expand_task`, and `add_task`.\n\n**🏷️ Tagged Task Lists System:** Task Master now supports **tagged task lists** for multi-context task management. This allows you to maintain separate, isolated lists of tasks for different features, branches, or experiments. Existing projects are seamlessly migrated to use a default \"master\" tag. Most commands now support a `--tag <name>` flag to specify which context to operate on. If omitted, commands use the currently active tag.\n\n---\n\n## Initialization & Setup\n\n### 1. Initialize Project (`init`)\n\n*   **MCP Tool:** `initialize_project`\n*   **CLI Command:** `task-master init [options]`\n*   **Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project.`\n*   **Key CLI Options:**\n    *   `--name <name>`: `Set the name for your project in Taskmaster's configuration.`\n    *   `--description <text>`: `Provide a brief description for your project.`\n    *   `--version <version>`: `Set the initial version for your project, e.g., '0.1.0'.`\n    *   `-y, --yes`: `Initialize Taskmaster quickly using default settings without interactive prompts.`\n*   **Usage:** Run this once at the beginning of a new project.\n*   **MCP Variant Description:** `Set up the basic Taskmaster file structure and configuration in the current directory for a new project by running the 'task-master init' command.`\n*   **Key MCP Parameters/Options:**\n    *   `projectName`: `Set the name for your project.` (CLI: `--name <name>`)\n    *   `projectDescription`: `Provide a brief description for your project.` (CLI: `--description <text>`)\n    *   `projectVersion`: `Set the initial version for your project, e.g., '0.1.0'.` (CLI: `--version <version>`)\n    *   `authorName`: `Author name.` (CLI: `--author <author>`)\n    *   `skipInstall`: `Skip installing dependencies. Default is false.` (CLI: `--skip-install`)\n    *   `addAliases`: `Add shell aliases tm and taskmaster. Default is false.` (CLI: `--aliases`)\n    *   `yes`: `Skip prompts and use defaults/provided arguments. Default is false.` (CLI: `-y, --yes`)\n*   **Usage:** Run this once at the beginning of a new project, typically via an integrated tool like Cursor. Operates on the current working directory of the MCP server. \n*   **Important:** Once complete, you *MUST* parse a prd in order to generate tasks. There will be no tasks files until then. The next step after initializing should be to create a PRD using the example PRD in .taskmaster/templates/example_prd.txt. \n*   **Tagging:** Use the `--tag` option to parse the PRD into a specific, non-default tag context. If the tag doesn't exist, it will be created automatically. Example: `task-master parse-prd spec.txt --tag=new-feature`.\n\n### 2. Parse PRD (`parse_prd`)\n\n*   **MCP Tool:** `parse_prd`\n*   **CLI Command:** `task-master parse-prd [file] [options]`\n*   **Description:** `Parse a Product Requirements Document, PRD, or text file with Taskmaster to automatically generate an initial set of tasks in tasks.json.`\n*   **Key Parameters/Options:**\n    *   `input`: `Path to your PRD or requirements text file that Taskmaster should parse for tasks.` (CLI: `[file]` positional or `-i, --input <file>`)\n    *   `output`: `Specify where Taskmaster should save the generated 'tasks.json' file. Defaults to '.taskmaster/tasks/tasks.json'.` (CLI: `-o, --output <file>`)\n    *   `numTasks`: `Approximate number of top-level tasks Taskmaster should aim to generate from the document.` (CLI: `-n, --num-tasks <number>`)\n    *   `force`: `Use this to allow Taskmaster to overwrite an existing 'tasks.json' without asking for confirmation.` (CLI: `-f, --force`)\n*   **Usage:** Useful for bootstrapping a project from an existing requirements document.\n*   **Notes:** Task Master will strictly adhere to any specific requirements mentioned in the PRD, such as libraries, database schemas, frameworks, tech stacks, etc., while filling in any gaps where the PRD isn't fully specified. Tasks are designed to provide the most direct implementation path while avoiding over-engineering.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress. If the user does not have a PRD, suggest discussing their idea and then use the example PRD in `.taskmaster/templates/example_prd.txt` as a template for creating the PRD based on their idea, for use with `parse-prd`.\n\n---\n\n## AI Model Configuration\n\n### 2. Manage Models (`models`)\n*   **MCP Tool:** `models`\n*   **CLI Command:** `task-master models [options]`\n*   **Description:** `View the current AI model configuration or set specific models for different roles (main, research, fallback). Allows setting custom model IDs for Ollama and OpenRouter.`\n*   **Key MCP Parameters/Options:**\n    *   `setMain <model_id>`: `Set the primary model ID for task generation/updates.` (CLI: `--set-main <model_id>`)\n    *   `setResearch <model_id>`: `Set the model ID for research-backed operations.` (CLI: `--set-research <model_id>`)\n    *   `setFallback <model_id>`: `Set the model ID to use if the primary fails.` (CLI: `--set-fallback <model_id>`)\n    *   `ollama <boolean>`: `Indicates the set model ID is a custom Ollama model.` (CLI: `--ollama`)\n    *   `openrouter <boolean>`: `Indicates the set model ID is a custom OpenRouter model.` (CLI: `--openrouter`)\n    *   `listAvailableModels <boolean>`: `If true, lists available models not currently assigned to a role.` (CLI: No direct equivalent; CLI lists available automatically)\n    *   `projectRoot <string>`: `Optional. Absolute path to the project root directory.` (CLI: Determined automatically)\n*   **Key CLI Options:**\n    *   `--set-main <model_id>`: `Set the primary model.`\n    *   `--set-research <model_id>`: `Set the research model.`\n    *   `--set-fallback <model_id>`: `Set the fallback model.`\n    *   `--ollama`: `Specify that the provided model ID is for Ollama (use with --set-*).`\n    *   `--openrouter`: `Specify that the provided model ID is for OpenRouter (use with --set-*). Validates against OpenRouter API.`\n    *   `--bedrock`: `Specify that the provided model ID is for AWS Bedrock (use with --set-*).`\n    *   `--setup`: `Run interactive setup to configure models, including custom Ollama/OpenRouter IDs.`\n*   **Usage (MCP):** Call without set flags to get current config. Use `setMain`, `setResearch`, or `setFallback` with a valid model ID to update the configuration. Use `listAvailableModels: true` to get a list of unassigned models. To set a custom model, provide the model ID and set `ollama: true` or `openrouter: true`.\n*   **Usage (CLI):** Run without flags to view current configuration and available models. Use set flags to update specific roles. Use `--setup` for guided configuration, including custom models. To set a custom model via flags, use `--set-<role>=<model_id>` along with either `--ollama` or `--openrouter`.\n*   **Notes:** Configuration is stored in `.taskmaster/config.json` in the project root. This command/tool modifies that file. Use `listAvailableModels` or `task-master models` to see internally supported models. OpenRouter custom models are validated against their live API. Ollama custom models are not validated live.\n*   **API note:** API keys for selected AI providers (based on their model) need to exist in the mcp.json file to be accessible in MCP context. The API keys must be present in the local .env file for the CLI to be able to read them.\n*   **Model costs:** The costs in supported models are expressed in dollars. An input/output value of 3 is $3.00. A value of 0.8 is $0.80. \n*   **Warning:** DO NOT MANUALLY EDIT THE .taskmaster/config.json FILE. Use the included commands either in the MCP or CLI format as needed. Always prioritize MCP tools when available and use the CLI as a fallback.\n\n---\n\n## Task Listing & Viewing\n\n### 3. Get Tasks (`get_tasks`)\n\n*   **MCP Tool:** `get_tasks`\n*   **CLI Command:** `task-master list [options]`\n*   **Description:** `List your Taskmaster tasks, optionally filtering by status and showing subtasks.`\n*   **Key Parameters/Options:**\n    *   `status`: `Show only Taskmaster tasks matching this status (or multiple statuses, comma-separated), e.g., 'pending' or 'done,in-progress'.` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks indented under their parent tasks in the list.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to list tasks from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Get an overview of the project status, often used at the start of a work session.\n\n### 4. Get Next Task (`next_task`)\n\n*   **MCP Tool:** `next_task`\n*   **CLI Command:** `task-master next [options]`\n*   **Description:** `Ask Taskmaster to show the next available task you can work on, based on status and completed dependencies.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `tag`: `Specify which tag context to use. Defaults to the current active tag.` (CLI: `--tag <name>`)\n*   **Usage:** Identify what to work on next according to the plan.\n\n### 5. Get Task Details (`get_task`)\n\n*   **MCP Tool:** `get_task`\n*   **CLI Command:** `task-master show [id] [options]`\n*   **Description:** `Display detailed information for one or more specific Taskmaster tasks or subtasks by ID.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task (e.g., '15'), subtask (e.g., '15.2'), or a comma-separated list of IDs ('1,5,10.2') you want to view.` (CLI: `[id]` positional or `-i, --id <id>`)\n    *   `tag`: `Specify which tag context to get the task(s) from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Understand the full details for a specific task. When multiple IDs are provided, a summary table is shown.\n*   **CRITICAL INFORMATION** If you need to collect information from multiple tasks, use comma-separated IDs (i.e. 1,2,3) to receive an array of tasks. Do not needlessly get tasks one at a time if you need to get many as that is wasteful.\n\n---\n\n## Task Creation & Modification\n\n### 6. Add Task (`add_task`)\n\n*   **MCP Tool:** `add_task`\n*   **CLI Command:** `task-master add-task [options]`\n*   **Description:** `Add a new task to Taskmaster by describing it; AI will structure it.`\n*   **Key Parameters/Options:**\n    *   `prompt`: `Required. Describe the new task you want Taskmaster to create, e.g., \"Implement user authentication using JWT\".` (CLI: `-p, --prompt <text>`)\n    *   `dependencies`: `Specify the IDs of any Taskmaster tasks that must be completed before this new one can start, e.g., '12,14'.` (CLI: `-d, --dependencies <ids>`)\n    *   `priority`: `Set the priority for the new task: 'high', 'medium', or 'low'. Default is 'medium'.` (CLI: `--priority <priority>`)\n    *   `research`: `Enable Taskmaster to use the research role for potentially more informed task creation.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to add the task to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Quickly add newly identified tasks during development.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 7. Add Subtask (`add_subtask`)\n\n*   **MCP Tool:** `add_subtask`\n*   **CLI Command:** `task-master add-subtask [options]`\n*   **Description:** `Add a new subtask to a Taskmaster parent task, or convert an existing task into a subtask.`\n*   **Key Parameters/Options:**\n    *   `id` / `parent`: `Required. The ID of the Taskmaster task that will be the parent.` (MCP: `id`, CLI: `-p, --parent <id>`)\n    *   `taskId`: `Use this if you want to convert an existing top-level Taskmaster task into a subtask of the specified parent.` (CLI: `-i, --task-id <id>`)\n    *   `title`: `Required if not using taskId. The title for the new subtask Taskmaster should create.` (CLI: `-t, --title <title>`)\n    *   `description`: `A brief description for the new subtask.` (CLI: `-d, --description <text>`)\n    *   `details`: `Provide implementation notes or details for the new subtask.` (CLI: `--details <text>`)\n    *   `dependencies`: `Specify IDs of other tasks or subtasks, e.g., '15' or '16.1', that must be done before this new subtask.` (CLI: `--dependencies <ids>`)\n    *   `status`: `Set the initial status for the new subtask. Default is 'pending'.` (CLI: `-s, --status <status>`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after adding the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Break down tasks manually or reorganize existing tasks.\n\n### 8. Update Tasks (`update`)\n\n*   **MCP Tool:** `update`\n*   **CLI Command:** `task-master update [options]`\n*   **Description:** `Update multiple upcoming tasks in Taskmaster based on new context or changes, starting from a specific task ID.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. The ID of the first task Taskmaster should update. All tasks with this ID or higher that are not 'done' will be considered.` (CLI: `--from <id>`)\n    *   `prompt`: `Required. Explain the change or new context for Taskmaster to apply to the tasks, e.g., \"We are now using React Query instead of Redux Toolkit for data fetching\".` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Handle significant implementation changes or pivots that affect multiple future tasks. Example CLI: `task-master update --from='18' --prompt='Switching to React Query.\\nNeed to refactor data fetching...'`\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 9. Update Task (`update_task`)\n\n*   **MCP Tool:** `update_task`\n*   **CLI Command:** `task-master update-task [options]`\n*   **Description:** `Modify a specific Taskmaster task by ID, incorporating new information or changes. By default, this replaces the existing task details.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The specific ID of the Taskmaster task, e.g., '15', you want to update.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. Explain the specific changes or provide the new information Taskmaster should incorporate into this task.` (CLI: `-p, --prompt <text>`)\n    *   `append`: `If true, appends the prompt content to the task's details with a timestamp, rather than replacing them. Behaves like update-subtask.` (CLI: `--append`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Refine a specific task based on new understanding. Use `--append` to log progress without creating subtasks.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 10. Update Subtask (`update_subtask`)\n\n*   **MCP Tool:** `update_subtask`\n*   **CLI Command:** `task-master update-subtask [options]`\n*   **Description:** `Append timestamped notes or details to a specific Taskmaster subtask without overwriting existing content. Intended for iterative implementation logging.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster subtask, e.g., '5.2', to update with new information.` (CLI: `-i, --id <id>`)\n    *   `prompt`: `Required. The information, findings, or progress notes to append to the subtask's details with a timestamp.` (CLI: `-p, --prompt <text>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed updates. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context the subtask belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Log implementation progress, findings, and discoveries during subtask development. Each update is timestamped and appended to preserve the implementation journey.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 11. Set Task Status (`set_task_status`)\n\n*   **MCP Tool:** `set_task_status`\n*   **CLI Command:** `task-master set-status [options]`\n*   **Description:** `Update the status of one or more Taskmaster tasks or subtasks, e.g., 'pending', 'in-progress', 'done'.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster task(s) or subtask(s), e.g., '15', '15.2', or '16,17.1', to update.` (CLI: `-i, --id <id>`)\n    *   `status`: `Required. The new status to set, e.g., 'done', 'pending', 'in-progress', 'review', 'cancelled'.` (CLI: `-s, --status <status>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Mark progress as tasks move through the development cycle.\n\n### 12. Remove Task (`remove_task`)\n\n*   **MCP Tool:** `remove_task`\n*   **CLI Command:** `task-master remove-task [options]`\n*   **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task, e.g., '5', or subtask, e.g., '5.2', to permanently remove.` (CLI: `-i, --id <id>`)\n    *   `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.\n*   **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.\n\n---\n\n## Task Structure & Breakdown\n\n### 13. Expand Task (`expand_task`)\n\n*   **MCP Tool:** `expand_task`\n*   **CLI Command:** `task-master expand [options]`\n*   **Description:** `Use Taskmaster's AI to break down a complex task into smaller, manageable subtasks. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID of the specific Taskmaster task you want to break down into subtasks.` (CLI: `-i, --id <id>`)\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create. Uses complexity analysis/defaults otherwise.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable Taskmaster to use the research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context or specific instructions to Taskmaster for generating the subtasks.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context the task belongs to. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Generate a detailed implementation plan for a complex task before starting coding. Automatically uses complexity report recommendations if available and `num` is not specified.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 14. Expand All Tasks (`expand_all`)\n\n*   **MCP Tool:** `expand_all`\n*   **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)\n*   **Description:** `Tell Taskmaster to automatically expand all eligible pending/in-progress tasks based on complexity analysis or defaults. Appends subtasks by default.`\n*   **Key Parameters/Options:**\n    *   `num`: `Optional: Suggests how many subtasks Taskmaster should aim to create per task.` (CLI: `-n, --num <number>`)\n    *   `research`: `Enable research role for more informed subtask generation. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `prompt`: `Optional: Provide extra context for Taskmaster to apply generally during expansion.` (CLI: `-p, --prompt <text>`)\n    *   `force`: `Optional: If true, clear existing subtasks before generating new ones for each eligible task. Default is false (append).` (CLI: `--force`)\n    *   `tag`: `Specify which tag context to expand. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 15. Clear Subtasks (`clear_subtasks`)\n\n*   **MCP Tool:** `clear_subtasks`\n*   **CLI Command:** `task-master clear-subtasks [options]`\n*   **Description:** `Remove all subtasks from one or more specified Taskmaster parent tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `The ID(s) of the Taskmaster parent task(s) whose subtasks you want to remove, e.g., '15' or '16,18'. Required unless using 'all'.` (CLI: `-i, --id <ids>`)\n    *   `all`: `Tell Taskmaster to remove subtasks from all parent tasks.` (CLI: `--all`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.\n\n### 16. Remove Subtask (`remove_subtask`)\n\n*   **MCP Tool:** `remove_subtask`\n*   **CLI Command:** `task-master remove-subtask [options]`\n*   **Description:** `Remove a subtask from its Taskmaster parent, optionally converting it into a standalone task.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID(s) of the Taskmaster subtask(s) to remove, e.g., '15.2' or '16.1,16.3'.` (CLI: `-i, --id <id>`)\n    *   `convert`: `If used, Taskmaster will turn the subtask into a regular top-level task instead of deleting it.` (CLI: `-c, --convert`)\n    *   `generate`: `Enable Taskmaster to regenerate markdown task files after removing the subtask.` (CLI: `--generate`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Delete unnecessary subtasks or promote a subtask to a top-level task.\n\n### 17. Move Task (`move_task`)\n\n*   **MCP Tool:** `move_task`\n*   **CLI Command:** `task-master move [options]`\n*   **Description:** `Move a task or subtask to a new position within the task hierarchy.`\n*   **Key Parameters/Options:**\n    *   `from`: `Required. ID of the task/subtask to move (e.g., \"5\" or \"5.2\"). Can be comma-separated for multiple tasks.` (CLI: `--from <id>`)\n    *   `to`: `Required. ID of the destination (e.g., \"7\" or \"7.3\"). Must match the number of source IDs if comma-separated.` (CLI: `--to <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Reorganize tasks by moving them within the hierarchy. Supports various scenarios like:\n    *   Moving a task to become a subtask\n    *   Moving a subtask to become a standalone task\n    *   Moving a subtask to a different parent\n    *   Reordering subtasks within the same parent\n    *   Moving a task to a new, non-existent ID (automatically creates placeholders)\n    *   Moving multiple tasks at once with comma-separated IDs\n*   **Validation Features:**\n    *   Allows moving tasks to non-existent destination IDs (creates placeholder tasks)\n    *   Prevents moving to existing task IDs that already have content (to avoid overwriting)\n    *   Validates that source tasks exist before attempting to move them\n    *   Maintains proper parent-child relationships\n*   **Example CLI:** `task-master move --from=5.2 --to=7.3` to move subtask 5.2 to become subtask 7.3.\n*   **Example Multi-Move:** `task-master move --from=10,11,12 --to=16,17,18` to move multiple tasks to new positions.\n*   **Common Use:** Resolving merge conflicts in tasks.json when multiple team members create tasks on different branches.\n\n---\n\n## Dependency Management\n\n### 18. Add Dependency (`add_dependency`)\n\n*   **MCP Tool:** `add_dependency`\n*   **CLI Command:** `task-master add-dependency [options]`\n*   **Description:** `Define a dependency in Taskmaster, making one task a prerequisite for another.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task that will depend on another.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that must be completed first, the prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <path>`)\n*   **Usage:** Establish the correct order of execution between tasks.\n\n### 19. Remove Dependency (`remove_dependency`)\n\n*   **MCP Tool:** `remove_dependency`\n*   **CLI Command:** `task-master remove-dependency [options]`\n*   **Description:** `Remove a dependency relationship between two Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `id`: `Required. The ID of the Taskmaster task you want to remove a prerequisite from.` (CLI: `-i, --id <id>`)\n    *   `dependsOn`: `Required. The ID of the Taskmaster task that should no longer be a prerequisite.` (CLI: `-d, --depends-on <id>`)\n    *   `tag`: `Specify which tag context to operate on. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Update task relationships when the order of execution changes.\n\n### 20. Validate Dependencies (`validate_dependencies`)\n\n*   **MCP Tool:** `validate_dependencies`\n*   **CLI Command:** `task-master validate-dependencies [options]`\n*   **Description:** `Check your Taskmaster tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to validate. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Audit the integrity of your task dependencies.\n\n### 21. Fix Dependencies (`fix_dependencies`)\n\n*   **MCP Tool:** `fix_dependencies`\n*   **CLI Command:** `task-master fix-dependencies [options]`\n*   **Description:** `Automatically fix dependency issues (like circular references or links to non-existent tasks) in your Taskmaster tasks.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to fix dependencies in. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Clean up dependency errors automatically.\n\n---\n\n## Analysis & Reporting\n\n### 22. Analyze Project Complexity (`analyze_project_complexity`)\n\n*   **MCP Tool:** `analyze_project_complexity`\n*   **CLI Command:** `task-master analyze-complexity [options]`\n*   **Description:** `Have Taskmaster analyze your tasks to determine their complexity and suggest which ones need to be broken down further.`\n*   **Key Parameters/Options:**\n    *   `output`: `Where to save the complexity analysis report. Default is '.taskmaster/reports/task-complexity-report.json' (or '..._tagname.json' if a tag is used).` (CLI: `-o, --output <file>`)\n    *   `threshold`: `The minimum complexity score (1-10) that should trigger a recommendation to expand a task.` (CLI: `-t, --threshold <number>`)\n    *   `research`: `Enable research role for more accurate complexity analysis. Requires appropriate API key.` (CLI: `-r, --research`)\n    *   `tag`: `Specify which tag context to analyze. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Used before breaking down tasks to identify which ones need the most attention.\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. Please inform users to hang tight while the operation is in progress.\n\n### 23. View Complexity Report (`complexity_report`)\n\n*   **MCP Tool:** `complexity_report`\n*   **CLI Command:** `task-master complexity-report [options]`\n*   **Description:** `Display the task complexity analysis report in a readable format.`\n*   **Key Parameters/Options:**\n    *   `tag`: `Specify which tag context to show the report for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to the complexity report (default: '.taskmaster/reports/task-complexity-report.json').` (CLI: `-f, --file <file>`)\n*   **Usage:** Review and understand the complexity analysis results after running analyze-complexity.\n\n---\n\n## File Management\n\n### 24. Generate Task Files (`generate`)\n\n*   **MCP Tool:** `generate`\n*   **CLI Command:** `task-master generate [options]`\n*   **Description:** `Create or update individual Markdown files for each task based on your tasks.json.`\n*   **Key Parameters/Options:**\n    *   `output`: `The directory where Taskmaster should save the task files (default: in a 'tasks' directory).` (CLI: `-o, --output <directory>`)\n    *   `tag`: `Specify which tag context to generate files for. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n*   **Usage:** Run this after making changes to tasks.json to keep individual task files up to date. This command is now manual and no longer runs automatically.\n\n---\n\n## AI-Powered Research\n\n### 25. Research (`research`)\n\n*   **MCP Tool:** `research`\n*   **CLI Command:** `task-master research [options]`\n*   **Description:** `Perform AI-powered research queries with project context to get fresh, up-to-date information beyond the AI's knowledge cutoff.`\n*   **Key Parameters/Options:**\n    *   `query`: `Required. Research query/prompt (e.g., \"What are the latest best practices for React Query v5?\").` (CLI: `[query]` positional or `-q, --query <text>`)\n    *   `taskIds`: `Comma-separated list of task/subtask IDs from the current tag context (e.g., \"15,16.2,17\").` (CLI: `-i, --id <ids>`)\n    *   `filePaths`: `Comma-separated list of file paths for context (e.g., \"src/api.js,docs/readme.md\").` (CLI: `-f, --files <paths>`)\n    *   `customContext`: `Additional custom context text to include in the research.` (CLI: `-c, --context <text>`)\n    *   `includeProjectTree`: `Include project file tree structure in context (default: false).` (CLI: `--tree`)\n    *   `detailLevel`: `Detail level for the research response: 'low', 'medium', 'high' (default: medium).` (CLI: `--detail <level>`)\n    *   `saveTo`: `Task or subtask ID (e.g., \"15\", \"15.2\") to automatically save the research conversation to.` (CLI: `--save-to <id>`)\n    *   `saveFile`: `If true, saves the research conversation to a markdown file in '.taskmaster/docs/research/'.` (CLI: `--save-file`)\n    *   `noFollowup`: `Disables the interactive follow-up question menu in the CLI.` (CLI: `--no-followup`)\n    *   `tag`: `Specify which tag context to use for task-based context gathering. Defaults to the current active tag.` (CLI: `--tag <name>`)\n    *   `projectRoot`: `The directory of the project. Must be an absolute path.` (CLI: Determined automatically)\n*   **Usage:** **This is a POWERFUL tool that agents should use FREQUENTLY** to:\n    *   Get fresh information beyond knowledge cutoff dates\n    *   Research latest best practices, library updates, security patches\n    *   Find implementation examples for specific technologies\n    *   Validate approaches against current industry standards\n    *   Get contextual advice based on project files and tasks\n*   **When to Consider Using Research:**\n    *   **Before implementing any task** - Research current best practices\n    *   **When encountering new technologies** - Get up-to-date implementation guidance (libraries, apis, etc)\n    *   **For security-related tasks** - Find latest security recommendations\n    *   **When updating dependencies** - Research breaking changes and migration guides\n    *   **For performance optimization** - Get current performance best practices\n    *   **When debugging complex issues** - Research known solutions and workarounds\n*   **Research + Action Pattern:**\n    *   Use `research` to gather fresh information\n    *   Use `update_subtask` to commit findings with timestamps\n    *   Use `update_task` to incorporate research into task details\n    *   Use `add_task` with research flag for informed task creation\n*   **Important:** This MCP tool makes AI calls and can take up to a minute to complete. The research provides FRESH data beyond the AI's training cutoff, making it invaluable for current best practices and recent developments.\n\n---\n\n## Tag Management\n\nThis new suite of commands allows you to manage different task contexts (tags).\n\n### 26. List Tags (`tags`)\n\n*   **MCP Tool:** `list_tags`\n*   **CLI Command:** `task-master tags [options]`\n*   **Description:** `List all available tags with task counts, completion status, and other metadata.`\n*   **Key Parameters/Options:**\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n    *   `--show-metadata`: `Include detailed metadata in the output (e.g., creation date, description).` (CLI: `--show-metadata`)\n\n### 27. Add Tag (`add_tag`)\n\n*   **MCP Tool:** `add_tag`\n*   **CLI Command:** `task-master add-tag <tagName> [options]`\n*   **Description:** `Create a new, empty tag context, or copy tasks from another tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the new tag to create (alphanumeric, hyphens, underscores).` (CLI: `<tagName>` positional)\n    *   `--from-branch`: `Creates a tag with a name derived from the current git branch, ignoring the <tagName> argument.` (CLI: `--from-branch`)\n    *   `--copy-from-current`: `Copy tasks from the currently active tag to the new tag.` (CLI: `--copy-from-current`)\n    *   `--copy-from <tag>`: `Copy tasks from a specific source tag to the new tag.` (CLI: `--copy-from <tag>`)\n    *   `--description <text>`: `Provide an optional description for the new tag.` (CLI: `-d, --description <text>`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 28. Delete Tag (`delete_tag`)\n\n*   **MCP Tool:** `delete_tag`\n*   **CLI Command:** `task-master delete-tag <tagName> [options]`\n*   **Description:** `Permanently delete a tag and all of its associated tasks.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to delete.` (CLI: `<tagName>` positional)\n    *   `--yes`: `Skip the confirmation prompt.` (CLI: `-y, --yes`)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 29. Use Tag (`use_tag`)\n\n*   **MCP Tool:** `use_tag`\n*   **CLI Command:** `task-master use-tag <tagName>`\n*   **Description:** `Switch your active task context to a different tag.`\n*   **Key Parameters/Options:**\n    *   `tagName`: `Name of the tag to switch to.` (CLI: `<tagName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 30. Rename Tag (`rename_tag`)\n\n*   **MCP Tool:** `rename_tag`\n*   **CLI Command:** `task-master rename-tag <oldName> <newName>`\n*   **Description:** `Rename an existing tag.`\n*   **Key Parameters/Options:**\n    *   `oldName`: `The current name of the tag.` (CLI: `<oldName>` positional)\n    *   `newName`: `The new name for the tag.` (CLI: `<newName>` positional)\n    *   `file`: `Path to your Taskmaster 'tasks.json' file. Default relies on auto-detection.` (CLI: `-f, --file <file>`)\n\n### 31. Copy Tag (`copy_tag`)\n\n*   **MCP Tool:** `copy_tag`\n*   **CLI Command:** `task-master copy-tag <sourceName> <targetName> [options]`\n*   **Description:** `Copy an entire tag context, including all its tasks and metadata, to a new tag.`\n*   **Key Parameters/Options:**\n    *   `sourceName`: `Name of the tag to copy from.` (CLI: `<sourceName>` positional)\n    *   `targetName`: `Name of the new tag to create.` (CLI: `<targetName>` positional)\n    *   `--description <text>`: `Optional description for the new tag.` (CLI: `-d, --description <text>`)\n\n---\n\n## Miscellaneous\n\n### 32. Sync Readme (`sync-readme`) -- experimental\n\n*   **MCP Tool:** N/A\n*   **CLI Command:** `task-master sync-readme [options]`\n*   **Description:** `Exports your task list to your project's README.md file, useful for showcasing progress.`\n*   **Key Parameters/Options:**\n    *   `status`: `Filter tasks by status (e.g., 'pending', 'done').` (CLI: `-s, --status <status>`)\n    *   `withSubtasks`: `Include subtasks in the export.` (CLI: `--with-subtasks`)\n    *   `tag`: `Specify which tag context to export from. Defaults to the current active tag.` (CLI: `--tag <name>`)\n\n---\n\n## Environment Variables Configuration (Updated)\n\nTaskmaster primarily uses the **`.taskmaster/config.json`** file (in project root) for configuration (models, parameters, logging level, etc.), managed via `task-master models --setup`.\n\nEnvironment variables are used **only** for sensitive API keys related to AI providers and specific overrides like the Ollama base URL:\n\n*   **API Keys (Required for corresponding provider):**\n    *   `ANTHROPIC_API_KEY`\n    *   `PERPLEXITY_API_KEY`\n    *   `OPENAI_API_KEY`\n    *   `GOOGLE_API_KEY`\n    *   `MISTRAL_API_KEY`\n    *   `AZURE_OPENAI_API_KEY` (Requires `AZURE_OPENAI_ENDPOINT` too)\n    *   `OPENROUTER_API_KEY`\n    *   `XAI_API_KEY`\n    *   `OLLAMA_API_KEY` (Requires `OLLAMA_BASE_URL` too)\n*   **Endpoints (Optional/Provider Specific inside .taskmaster/config.json):**\n    *   `AZURE_OPENAI_ENDPOINT`\n    *   `OLLAMA_BASE_URL` (Default: `http://localhost:11434/api`)\n\n**Set API keys** in your **`.env`** file in the project root (for CLI use) or within the `env` section of your **`.cursor/mcp.json`** file (for MCP/Cursor integration). All other settings (model choice, max tokens, temperature, log level, custom endpoints) are managed in `.taskmaster/config.json` via `task-master models` command or `models` MCP tool.\n\n---\n\nFor details on how these commands fit into the development process, see the [dev_workflow.mdc](mdc:.cursor/rules/taskmaster/dev_workflow.mdc).\n\n<!-- File: .cursor/rules/tasks.mdc (Tokens: ~2781 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing task management operations\nglobs: scripts/modules/task-manager.js\nalwaysApply: false\n---\n# Task Management Guidelines\n\n## Tagged Task Lists System\n\nTask Master now uses a **tagged task lists system** for multi-context task management:\n\n- **Data Structure**: Tasks are organized into separate contexts (tags) within `tasks.json`\n- **Legacy Format**: `{\"tasks\": [...]}`\n- **Tagged Format**: `{\"master\": {\"tasks\": [...]}, \"feature-branch\": {\"tasks\": [...]}}`\n- **Silent Migration**: Legacy format automatically converts to tagged format on first use\n- **Tag Resolution**: Core functions receive legacy format for 100% backward compatibility\n- **Default Tag**: \"master\" is used for all existing and new tasks unless otherwise specified\n\n## Task Structure Standards\n\n- **Core Task Properties**:\n  - ✅ DO: Include all required properties in each task object\n  - ✅ DO: Provide default values for optional properties\n  - ❌ DON'T: Add extra properties that aren't in the standard schema\n\n  ```javascript\n  // ✅ DO: Follow this structure for task objects\n  const task = {\n    id: nextId,\n    title: \"Task title\",\n    description: \"Brief task description\",\n    status: \"pending\", // \"pending\", \"in-progress\", \"done\", etc.\n    dependencies: [], // Array of task IDs\n    priority: \"medium\", // \"high\", \"medium\", \"low\"\n    details: \"Detailed implementation instructions\",\n    testStrategy: \"Verification approach\",\n    subtasks: [] // Array of subtask objects\n  };\n  ```\n\n- **Tagged Data Structure**:\n  - ✅ DO: Access tasks through tag resolution layer\n  - ✅ DO: Use `getTasksForTag(data, tagName)` to retrieve tasks for a specific tag\n  - ✅ DO: Use `setTasksForTag(data, tagName, tasks)` to update tasks for a specific tag\n  - ❌ DON'T: Directly manipulate the tagged structure in core functions\n\n  ```javascript\n  // ✅ DO: Use tag resolution functions\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Manipulate tasks as normal...\n  \n  // Save back to the tagged structure\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n- **Subtask Structure**:\n  - ✅ DO: Use consistent properties across subtasks\n  - ✅ DO: Maintain simple numeric IDs within parent tasks\n  - ❌ DON'T: Duplicate parent task properties in subtasks\n\n  ```javascript\n  // ✅ DO: Structure subtasks consistently\n  const subtask = {\n    id: nextSubtaskId, // Simple numeric ID, unique within the parent task\n    title: \"Subtask title\",\n    description: \"Brief subtask description\",\n    status: \"pending\",\n    dependencies: [], // Can include numeric IDs (other subtasks) or full task IDs\n    details: \"Detailed implementation instructions\"\n  };\n  ```\n\n## Task Creation and Parsing\n\n- **ID Management**:\n  - ✅ DO: Assign unique sequential IDs to tasks within each tag context\n  - ✅ DO: Calculate the next ID based on existing tasks in the current tag\n  - ❌ DON'T: Hardcode or reuse IDs within the same tag\n\n  ```javascript\n  // ✅ DO: Calculate the next available ID within the current tag\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  const highestId = Math.max(...tasks.map(t => t.id));\n  const nextTaskId = highestId + 1;\n  ```\n\n- **PRD Parsing**:\n  - ✅ DO: Extract tasks from PRD documents using AI\n  - ✅ DO: Create tasks in the current tag context (defaults to \"master\")\n  - ✅ DO: Provide clear prompts to guide AI task generation\n  - ✅ DO: Validate and clean up AI-generated tasks\n\n  ```javascript\n  // ✅ DO: Parse into current tag context\n  const tasksData = readJSON(tasksPath) || {};\n  const currentTag = getCurrentTag() || 'master';\n  \n  // Parse tasks and add to current tag\n  const newTasks = await parseTasksFromPRD(prdContent);\n  setTasksForTag(tasksData, currentTag, newTasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task Updates and Modifications\n\n- **Status Management**:\n  - ✅ DO: Provide functions for updating task status within current tag context\n  - ✅ DO: Handle both individual tasks and subtasks\n  - ✅ DO: Consider subtask status when updating parent tasks\n\n  ```javascript\n  // ✅ DO: Handle status updates within tagged context\n  async function setTaskStatus(tasksPath, taskIdInput, newStatus) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Check if it's a subtask (e.g., \"1.2\")\n    if (taskIdInput.includes('.')) {\n      const [parentId, subtaskId] = taskIdInput.split('.').map(id => parseInt(id, 10));\n      \n      // Find the parent task and subtask\n      const parentTask = tasks.find(t => t.id === parentId);\n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      \n      // Update subtask status\n      subtask.status = newStatus;\n      \n      // Check if all subtasks are done\n      if (newStatus === 'done') {\n        const allSubtasksDone = parentTask.subtasks.every(st => st.status === 'done');\n        if (allSubtasksDone) {\n          // Suggest updating parent task\n        }\n      }\n    } else {\n      // Handle regular task\n      const task = tasks.find(t => t.id === parseInt(taskIdInput, 10));\n      task.status = newStatus;\n      \n      // If marking as done, also mark subtasks\n      if (newStatus === 'done' && task.subtasks && task.subtasks.length > 0) {\n        task.subtasks.forEach(subtask => {\n          subtask.status = newStatus;\n        });\n      }\n    }\n    \n    // Save updated tasks back to tagged structure\n    setTasksForTag(tasksData, currentTag, tasks);\n    writeJSON(tasksPath, tasksData);\n  }\n  ```\n\n- **Task Expansion**:\n  - ✅ DO: Use AI to generate detailed subtasks within current tag context\n  - ✅ DO: Consider complexity analysis for subtask counts\n  - ✅ DO: Ensure proper IDs for newly created subtasks\n\n  ```javascript\n  // ✅ DO: Generate appropriate subtasks based on complexity\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  if (taskAnalysis) {\n    log('info', `Found complexity analysis for task ${taskId}: Score ${taskAnalysis.complexityScore}/10`);\n    \n    // Use recommended number of subtasks if available\n    if (taskAnalysis.recommendedSubtasks && numSubtasks === CONFIG.defaultSubtasks) {\n      numSubtasks = taskAnalysis.recommendedSubtasks;\n      log('info', `Using recommended number of subtasks: ${numSubtasks}`);\n    }\n  }\n  \n  // Generate subtasks and save back\n  // ... subtask generation logic ...\n  setTasksForTag(tasksData, currentTag, tasks);\n  writeJSON(tasksPath, tasksData);\n  ```\n\n## Task File Generation\n\n- **File Formatting**:\n  - ✅ DO: Use consistent formatting for task files\n  - ✅ DO: Include all task properties in text files\n  - ✅ DO: Format dependencies with status indicators\n\n  ```javascript\n  // ✅ DO: Use consistent file formatting\n  let content = `# Task ID: ${task.id}\\n`;\n  content += `# Title: ${task.title}\\n`;\n  content += `# Status: ${task.status || 'pending'}\\n`;\n  \n  // Format dependencies with their status\n  if (task.dependencies && task.dependencies.length > 0) {\n    content += `# Dependencies: ${formatDependenciesWithStatus(task.dependencies, tasks)}\\n`;\n  } else {\n    content += '# Dependencies: None\\n';\n  }\n  ```\n\n- **Tagged Context Awareness**:\n  - ✅ DO: Generate task files from current tag context\n  - ✅ DO: Include tag information in generated files\n  - ❌ DON'T: Mix tasks from different tags in file generation\n\n  ```javascript\n  // ✅ DO: Generate files for current tag context\n  async function generateTaskFiles(tasksPath, outputDir) {\n    const tasksData = readJSON(tasksPath);\n    const currentTag = getCurrentTag() || 'master';\n    const tasks = getTasksForTag(tasksData, currentTag);\n    \n    // Add tag context to file header\n    let content = `# Tag Context: ${currentTag}\\n`;\n    content += `# Task ID: ${task.id}\\n`;\n    // ... rest of file generation\n  }\n  ```\n\n## Task Listing and Display\n\n- **Filtering and Organization**:\n  - ✅ DO: Allow filtering tasks by status within current tag context\n  - ✅ DO: Handle subtask display in lists\n  - ✅ DO: Use consistent table formats\n\n  ```javascript\n  // ✅ DO: Implement clear filtering within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Filter tasks by status if specified\n  const filteredTasks = statusFilter \n    ? tasks.filter(task => \n        task.status && task.status.toLowerCase() === statusFilter.toLowerCase())\n    : tasks;\n  ```\n\n- **Progress Tracking**:\n  - ✅ DO: Calculate and display completion statistics for current tag\n  - ✅ DO: Track both task and subtask completion\n  - ✅ DO: Use visual progress indicators\n\n  ```javascript\n  // ✅ DO: Track and display progress within tag context\n  const tasksData = readJSON(tasksPath);\n  const currentTag = getCurrentTag() || 'master';\n  const tasks = getTasksForTag(tasksData, currentTag);\n  \n  // Calculate completion statistics\n  const totalTasks = tasks.length;\n  const completedTasks = tasks.filter(task => \n    task.status === 'done' || task.status === 'completed').length;\n  const completionPercentage = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0;\n  \n  // Count subtasks\n  let totalSubtasks = 0;\n  let completedSubtasks = 0;\n  \n  tasks.forEach(task => {\n    if (task.subtasks && task.subtasks.length > 0) {\n      totalSubtasks += task.subtasks.length;\n      completedSubtasks += task.subtasks.filter(st => \n        st.status === 'done' || st.status === 'completed').length;\n    }\n  });\n  ```\n\n## Migration and Compatibility\n\n- **Silent Migration Handling**:\n  - ✅ DO: Implement silent migration in `readJSON()` function\n  - ✅ DO: Detect legacy format and convert automatically\n  - ✅ DO: Preserve all existing task data during migration\n\n  ```javascript\n  // ✅ DO: Handle silent migration (implemented in utils.js)\n  function readJSON(filepath) {\n    let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n    \n    // Silent migration for tasks.json files\n    if (data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n      const migratedData = {\n        master: {\n          tasks: data.tasks\n        }\n      };\n      writeJSON(filepath, migratedData);\n      data = migratedData;\n    }\n    \n    return data;\n  }\n  ```\n\n- **Tag Resolution**:\n  - ✅ DO: Use tag resolution functions to maintain backward compatibility\n  - ✅ DO: Return legacy format to core functions\n  - ❌ DON'T: Expose tagged structure to existing core logic\n\n  ```javascript\n  // ✅ DO: Use tag resolution layer\n  function getTasksForTag(data, tagName) {\n    if (data.tasks && Array.isArray(data.tasks)) {\n      // Legacy format - return as-is\n      return data.tasks;\n    }\n    \n    if (data[tagName] && data[tagName].tasks) {\n      // Tagged format - return tasks for specified tag\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  ```\n\nRefer to [`task-manager.js`](mdc:scripts/modules/task-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines.\n\n<!-- File: .cursor/rules/telemetry.mdc (Tokens: ~2469 | Category: cursor-rule) -->\n---\ndescription: Guidelines for integrating AI usage telemetry across Task Master.\nglobs: scripts/modules/**/*.js,mcp-server/src/**/*.js\nalwaysApply: true\n---\n\n# AI Usage Telemetry Integration\n\nThis document outlines the standard pattern for capturing, propagating, and handling AI usage telemetry data (cost, tokens, model, etc.) across the Task Master stack. This ensures consistent telemetry for both CLI and MCP interactions.\n\n## Overview\n\nTelemetry data is generated within the unified AI service layer ([`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)) and then passed upwards through the calling functions.\n\n- **Data Source**: [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js) (specifically its `generateTextService`, `generateObjectService`, etc.) returns an object like `{ mainResult: AI_CALL_OUTPUT, telemetryData: TELEMETRY_OBJECT }`.\n- **`telemetryData` Object Structure**:\n  ```json\n  {\n    \"timestamp\": \"ISO_STRING_DATE\",\n    \"userId\": \"USER_ID_FROM_CONFIG\",\n    \"commandName\": \"invoking_command_or_tool_name\",\n    \"modelUsed\": \"ai_model_id\",\n    \"providerName\": \"ai_provider_name\",\n    \"inputTokens\": NUMBER,\n    \"outputTokens\": NUMBER,\n    \"totalTokens\": NUMBER,\n    \"totalCost\": NUMBER, // e.g., 0.012414\n    \"currency\": \"USD\" // e.g., \"USD\"\n  }\n  ```\n\n## Integration Pattern by Layer\n\nThe key principle is that each layer receives telemetry data from the layer below it (if applicable) and passes it to the layer above it, or handles it for display in the case of the CLI.\n\n### 1. Core Logic Functions (e.g., in `scripts/modules/task-manager/`)\n\nFunctions in this layer that invoke AI services are responsible for handling the `telemetryData` they receive from [`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js).\n\n- **Actions**:\n    1.  Call the appropriate AI service function (e.g., `generateObjectService`).\n        -   Pass `commandName` (e.g., `add-task`, `expand-task`) and `outputType` (e.g., `cli` or `mcp`) in the `params` object to the AI service. The `outputType` can be derived from context (e.g., presence of `mcpLog`).\n    2.  The AI service returns an object, e.g., `aiServiceResponse = { mainResult: {/*AI output*/}, telemetryData: {/*telemetry data*/} }`.\n    3.  Extract `aiServiceResponse.mainResult` for the core processing.\n    4.  **Must return an object that includes `aiServiceResponse.telemetryData`**.\n        Example: `return { operationSpecificData: /*...*/, telemetryData: aiServiceResponse.telemetryData };`\n\n- **CLI Output Handling (If Applicable)**:\n    -   If the core function also handles CLI output (e.g., it has an `outputFormat` parameter that can be `'text'` or `'cli'`):\n        1.  Check if `outputFormat === 'text'` (or `'cli'`).\n        2.  If so, and if `aiServiceResponse.telemetryData` is available, call `displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli')` from [`scripts/modules/ui.js`](mdc:scripts/modules/ui.js).\n        - This ensures telemetry is displayed directly to CLI users after the main command output.\n\n- **Example Snippet (Core Logic in `scripts/modules/task-manager/someAiAction.js`)**:\n  ```javascript\n  import { generateObjectService } from '../ai-services-unified.js';\n  import { displayAiUsageSummary } from '../ui.js';\n\n  async function performAiRelatedAction(params, context, outputFormat = 'text') {\n    const { commandNameFromContext, /* other context vars */ } = context;\n    let aiServiceResponse = null;\n\n    try {\n      aiServiceResponse = await generateObjectService({\n        // ... other parameters for AI service ...\n        commandName: commandNameFromContext || 'default-action-name',\n        outputType: context.mcpLog ? 'mcp' : 'cli' // Derive outputType\n      });\n\n      const usefulAiOutput = aiServiceResponse.mainResult.object;\n      // ... do work with usefulAiOutput ...\n\n      if (outputFormat === 'text' && aiServiceResponse.telemetryData) {\n        displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli');\n      }\n\n      return {\n        actionData: /* results of processing */,\n        telemetryData: aiServiceResponse.telemetryData\n      };\n    } catch (error) {\n      // ... handle error ...\n      throw error;\n    }\n  }\n  ```\n\n### 2. Direct Function Wrappers (in `mcp-server/src/core/direct-functions/`)\n\nThese functions adapt core logic for the MCP server, ensuring structured responses.\n\n- **Actions**:\n    1.  Call the corresponding core logic function.\n        -   Pass necessary context (e.g., `session`, `mcpLog`, `projectRoot`).\n        -   Provide the `commandName` (typically derived from the MCP tool name) and `outputType: 'mcp'` in the context object passed to the core function.\n        -   If the core function supports an `outputFormat` parameter, pass `'json'` to suppress CLI-specific UI.\n    2.  The core logic function returns an object (e.g., `coreResult = { actionData: ..., telemetryData: ... }`).\n    3.  Include `coreResult.telemetryData` as a field within the `data` object of the successful response returned by the direct function.\n\n- **Example Snippet (Direct Function `someAiActionDirect.js`)**:\n  ```javascript\n  import { performAiRelatedAction } from '../../../../scripts/modules/task-manager/someAiAction.js'; // Core function\n  import { createLogWrapper } from '../../tools/utils.js'; // MCP Log wrapper\n\n  export async function someAiActionDirect(args, log, context = {}) {\n    const { session } = context;\n    // ... prepare arguments for core function from args, including args.projectRoot ...\n\n    try {\n      const coreResult = await performAiRelatedAction(\n        { /* parameters for core function */ },\n        { // Context for core function\n          session,\n          mcpLog: createLogWrapper(log),\n          projectRoot: args.projectRoot,\n          commandNameFromContext: 'mcp_tool_some_ai_action', // Example command name\n          outputType: 'mcp'\n        },\n        'json' // Request 'json' output format from core function\n      );\n\n      return {\n        success: true,\n        data: {\n          operationSpecificData: coreResult.actionData,\n          telemetryData: coreResult.telemetryData // Pass telemetry through\n        }\n      };\n    } catch (error) {\n      // ... error handling, return { success: false, error: ... } ...\n    }\n  }\n  ```\n\n### 3. MCP Tools (in `mcp-server/src/tools/`)\n\nThese are the exposed endpoints for MCP clients.\n\n- **Actions**:\n    1.  Call the corresponding direct function wrapper.\n    2.  The direct function returns an object structured like `{ success: true, data: { operationSpecificData: ..., telemetryData: ... } }` (or an error object).\n    3.  Pass this entire result object to `handleApiResult(result, log)` from [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n    4.  `handleApiResult` ensures that the `data` field from the direct function's response (which correctly includes `telemetryData`) is part of the final MCP response.\n\n- **Example Snippet (MCP Tool `some_ai_action.js`)**:\n  ```javascript\n  import { someAiActionDirect } from '../core/task-master-core.js';\n  import { handleApiResult, withNormalizedProjectRoot } from './utils.js';\n  // ... zod for parameters ...\n\n  export function registerSomeAiActionTool(server) {\n    server.addTool({\n      name: \"some_ai_action\",\n      // ... description, parameters ...\n      execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n        try {\n          const resultFromDirectFunction = await someAiActionDirect(\n            { /* args including projectRoot */ },\n            log,\n            { session }\n          );\n          return handleApiResult(resultFromDirectFunction, log); // This passes the nested telemetryData through\n        } catch (error) {\n          // ... error handling ...\n        }\n      })\n    });\n  }\n  ```\n\n### 4. CLI Commands (`scripts/modules/commands.js`)\n\nThese define the command-line interface.\n\n- **Actions**:\n    1.  Call the appropriate core logic function.\n    2.  Pass `outputFormat: 'text'` (or ensure the core function defaults to text-based output for CLI).\n    3.  The core logic function (as per Section 1) is responsible for calling `displayAiUsageSummary` if telemetry data is available and it's in CLI mode.\n    4.  The command action itself **should not** call `displayAiUsageSummary` if the core logic function already handles this. This avoids duplicate display.\n\n- **Example Snippet (CLI Command in `commands.js`)**:\n  ```javascript\n  // In scripts/modules/commands.js\n  import { performAiRelatedAction } from './task-manager/someAiAction.js'; // Core function\n\n  programInstance\n    .command('some-cli-ai-action')\n    // ... .option() ...\n    .action(async (options) => {\n      try {\n        const projectRoot = findProjectRoot() || '.'; // Example root finding\n        // ... prepare parameters for core function from command options ...\n        await performAiRelatedAction(\n          { /* parameters for core function */ },\n          { // Context for core function\n            projectRoot,\n            commandNameFromContext: 'some-cli-ai-action',\n            outputType: 'cli'\n          },\n          'text' // Explicitly request text output format for CLI\n        );\n        // Core function handles displayAiUsageSummary internally for 'text' outputFormat\n      } catch (error) {\n        // ... error handling ...\n      }\n    });\n  ```\n\n## Summary Flow\n\nThe telemetry data flows as follows:\n\n1.  **[`ai-services-unified.js`](mdc:scripts/modules/ai-services-unified.js)**: Generates `telemetryData` and returns `{ mainResult, telemetryData }`.\n2.  **Core Logic Function**:\n    *   Receives `{ mainResult, telemetryData }`.\n    *   Uses `mainResult`.\n    *   If CLI (`outputFormat: 'text'`), calls `displayAiUsageSummary(telemetryData)`.\n    *   Returns `{ operationSpecificData, telemetryData }`.\n3.  **Direct Function Wrapper**:\n    *   Receives `{ operationSpecificData, telemetryData }` from core logic.\n    *   Returns `{ success: true, data: { operationSpecificData, telemetryData } }`.\n4.  **MCP Tool**:\n    *   Receives direct function response.\n    *   `handleApiResult` ensures the final MCP response to the client is `{ success: true, data: { operationSpecificData, telemetryData } }`.\n5.  **CLI Command**:\n    *   Calls core logic with `outputFormat: 'text'`. Display is handled by core logic.\n\nThis pattern ensures telemetry is captured and appropriately handled/exposed across all interaction modes.\n\n<!-- File: .cursor/rules/test_workflow.mdc (Tokens: ~5218 | Category: cursor-rule) -->\n---\ndescription: \nglobs: \nalwaysApply: true\n---\n# Test Workflow & Development Process\n\n## **Initial Testing Framework Setup**\n\nBefore implementing the TDD workflow, ensure your project has a proper testing framework configured. This section covers setup for different technology stacks.\n\n### **Detecting Project Type & Framework Needs**\n\n**AI Agent Assessment Checklist:**\n1. **Language Detection**: Check for `package.json` (Node.js/JavaScript), `requirements.txt` (Python), `Cargo.toml` (Rust), etc.\n2. **Existing Tests**: Look for test files (`.test.`, `.spec.`, `_test.`) or test directories\n3. **Framework Detection**: Check for existing test runners in dependencies\n4. **Project Structure**: Analyze directory structure for testing patterns\n\n### **JavaScript/Node.js Projects (Jest Setup)**\n\n#### **Prerequisites Check**\n```bash\n# Verify Node.js project\nls package.json  # Should exist\n\n# Check for existing testing setup\nls jest.config.js jest.config.ts  # Check for Jest config\ngrep -E \"(jest|vitest|mocha)\" package.json  # Check for test runners\n```\n\n#### **Jest Installation & Configuration**\n\n**Step 1: Install Dependencies**\n```bash\n# Core Jest dependencies\nnpm install --save-dev jest\n\n# TypeScript support (if using TypeScript)\nnpm install --save-dev ts-jest @types/jest\n\n# Additional useful packages\nnpm install --save-dev supertest @types/supertest  # For API testing\nnpm install --save-dev jest-watch-typeahead  # Enhanced watch mode\n```\n\n**Step 2: Create Jest Configuration**\n\nCreate `jest.config.js` with the following production-ready configuration:\n\n```javascript\n/** @type {import('jest').Config} */\nmodule.exports = {\n  // Use ts-jest preset for TypeScript support\n  preset: 'ts-jest',\n\n  // Test environment\n  testEnvironment: 'node',\n\n  // Roots for test discovery\n  roots: ['<rootDir>/src', '<rootDir>/tests'],\n\n  // Test file patterns\n  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],\n\n  // Transform files\n  transform: {\n    '^.+\\\\.ts$': [\n      'ts-jest',\n      {\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          skipLibCheck: true,\n          strict: false,\n          noImplicitAny: false,\n        },\n      },\n    ],\n    '^.+\\\\.js$': [\n      'ts-jest',\n      {\n        useESM: false,\n        tsconfig: {\n          target: 'es2020',\n          module: 'commonjs',\n          esModuleInterop: true,\n          allowSyntheticDefaultImports: true,\n          allowJs: true,\n        },\n      },\n    ],\n  },\n\n  // Module file extensions\n  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n\n  // Transform ignore patterns - adjust for ES modules\n  transformIgnorePatterns: ['node_modules/(?!(your-es-module-deps|.*\\\\.mjs$))'],\n\n  // Coverage configuration\n  collectCoverage: true,\n  coverageDirectory: 'coverage',\n  coverageReporters: [\n    'text', // Console output\n    'text-summary', // Brief summary\n    'lcov', // For IDE integration\n    'html', // Detailed HTML report\n  ],\n\n  // Files to collect coverage from\n  collectCoverageFrom: [\n    'src/**/*.ts',\n    '!src/**/*.d.ts',\n    '!src/**/*.test.ts',\n    '!src/**/index.ts', // Often just exports\n    '!src/generated/**', // Generated code\n    '!src/config/database.ts', // Database config (tested via integration)\n  ],\n\n  // Coverage thresholds - TaskMaster standards\n  coverageThreshold: {\n    global: {\n      branches: 70,\n      functions: 80,\n      lines: 80,\n      statements: 80,\n    },\n    // Higher standards for critical business logic\n    './src/utils/': {\n      branches: 85,\n      functions: 90,\n      lines: 90,\n      statements: 90,\n    },\n    './src/middleware/': {\n      branches: 80,\n      functions: 85,\n      lines: 85,\n      statements: 85,\n    },\n  },\n\n  // Setup files\n  setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],\n\n  // Global teardown to prevent worker process leaks\n  globalTeardown: '<rootDir>/tests/teardown.ts',\n\n  // Module path mapping (if needed)\n  moduleNameMapper: {\n    '^@/(.*)$': '<rootDir>/src/$1',\n  },\n\n  // Clear mocks between tests\n  clearMocks: true,\n\n  // Restore mocks after each test\n  restoreMocks: true,\n\n  // Global test timeout\n  testTimeout: 10000,\n\n  // Projects for different test types\n  projects: [\n    // Unit tests - for pure functions only\n    {\n      displayName: 'unit',\n      testMatch: ['<rootDir>/src/**/*.test.ts'],\n      testPathIgnorePatterns: ['.*\\\\.integration\\\\.test\\\\.ts$', '/tests/'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      collectCoverageFrom: [\n        'src/**/*.ts',\n        '!src/**/*.d.ts',\n        '!src/**/*.test.ts',\n        '!src/**/*.integration.test.ts',\n      ],\n      coverageThreshold: {\n        global: {\n          branches: 70,\n          functions: 80,\n          lines: 80,\n          statements: 80,\n        },\n      },\n    },\n    // Integration tests - real database/services\n    {\n      displayName: 'integration',\n      testMatch: [\n        '<rootDir>/src/**/*.integration.test.ts',\n        '<rootDir>/tests/integration/**/*.test.ts',\n      ],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/integration.ts'],\n      testTimeout: 10000,\n    },\n    // E2E tests - full workflows\n    {\n      displayName: 'e2e',\n      testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],\n      preset: 'ts-jest',\n      testEnvironment: 'node',\n      setupFilesAfterEnv: ['<rootDir>/tests/setup/e2e.ts'],\n      testTimeout: 30000,\n    },\n  ],\n\n  // Verbose output for better debugging\n  verbose: true,\n\n  // Run projects sequentially to avoid conflicts\n  maxWorkers: 1,\n\n  // Enable watch mode plugins\n  watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],\n};\n```\n\n**Step 3: Update package.json Scripts**\n\nAdd these scripts to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:coverage\": \"jest --coverage\",\n    \"test:unit\": \"jest --selectProjects unit\",\n    \"test:integration\": \"jest --selectProjects integration\", \n    \"test:e2e\": \"jest --selectProjects e2e\",\n    \"test:ci\": \"jest --ci --coverage --watchAll=false\"\n  }\n}\n```\n\n**Step 4: Create Test Setup Files**\n\nCreate essential test setup files:\n\n```typescript\n// tests/setup.ts - Global setup\nimport { jest } from '@jest/globals';\n\n// Global test configuration\nbeforeAll(() => {\n  // Set test timeout\n  jest.setTimeout(10000);\n});\n\nafterEach(() => {\n  // Clean up mocks after each test\n  jest.clearAllMocks();\n});\n```\n\n```typescript\n// tests/setup/integration.ts - Integration test setup\nimport { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nbeforeAll(async () => {\n  // Connect to test database\n  await prisma.$connect();\n});\n\nafterAll(async () => {\n  // Cleanup and disconnect\n  await prisma.$disconnect();\n});\n\nbeforeEach(async () => {\n  // Clean test data before each test\n  // Add your cleanup logic here\n});\n```\n\n```typescript\n// tests/teardown.ts - Global teardown\nexport default async () => {\n  // Global cleanup after all tests\n  console.log('Global test teardown complete');\n};\n```\n\n**Step 5: Create Initial Test Structure**\n\n```bash\n# Create test directories\nmkdir -p tests/{setup,fixtures,unit,integration,e2e}\nmkdir -p tests/unit/src/{utils,services,middleware}\n\n# Create sample test fixtures\nmkdir tests/fixtures\n```\n\n### **Generic Testing Framework Setup (Any Language)**\n\n#### **Framework Selection Guide**\n\n**Python Projects:**\n- **pytest**: Recommended for most Python projects\n- **unittest**: Built-in, suitable for simple projects\n- **Coverage**: Use `coverage.py` for code coverage\n\n```bash\n# Python setup example\npip install pytest pytest-cov\necho \"[tool:pytest]\" > pytest.ini\necho \"testpaths = tests\" >> pytest.ini\necho \"addopts = --cov=src --cov-report=html --cov-report=term\" >> pytest.ini\n```\n\n**Go Projects:**\n- **Built-in testing**: Use Go's built-in `testing` package\n- **Coverage**: Built-in with `go test -cover`\n\n```bash\n# Go setup example\ngo mod init your-project\nmkdir -p tests\n# Tests are typically *_test.go files alongside source\n```\n\n**Rust Projects:**\n- **Built-in testing**: Use Rust's built-in test framework\n- **cargo-tarpaulin**: For coverage analysis\n\n```bash\n# Rust setup example\ncargo new your-project\ncd your-project\ncargo install cargo-tarpaulin  # For coverage\n```\n\n**Java Projects:**\n- **JUnit 5**: Modern testing framework\n- **Maven/Gradle**: Build tools with testing integration\n\n```xml\n<!-- Maven pom.xml example -->\n<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter</artifactId>\n    <version>5.9.2</version>\n    <scope>test</scope>\n</dependency>\n```\n\n#### **Universal Testing Principles**\n\n**Coverage Standards (Adapt to Your Language):**\n- **Global Minimum**: 70-80% line coverage\n- **Critical Code**: 85-90% coverage\n- **New Features**: Must meet or exceed standards\n- **Legacy Code**: Gradual improvement strategy\n\n**Test Organization:**\n- **Unit Tests**: Fast, isolated, no external dependencies\n- **Integration Tests**: Test component interactions\n- **E2E Tests**: Test complete user workflows\n- **Performance Tests**: Load and stress testing (if applicable)\n\n**Naming Conventions:**\n- **Test Files**: `*.test.*`, `*_test.*`, or language-specific patterns\n- **Test Functions**: Descriptive names (e.g., `should_return_error_for_invalid_input`)\n- **Test Directories**: Organized by test type and mirroring source structure\n\n#### **TaskMaster Integration for Any Framework**\n\n**Document Testing Setup in Subtasks:**\n```bash\n# Update subtask with testing framework setup\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework setup:\n- Installed [Framework Name] with coverage support\n- Configured [Coverage Tool] with thresholds: 80% lines, 70% branches\n- Created test directory structure: unit/, integration/, e2e/\n- Added test scripts to build configuration\n- All setup tests passing\"\n```\n\n**Testing Framework Verification:**\n```bash\n# Verify setup works\n[test-command]  # e.g., npm test, pytest, go test, cargo test\n\n# Check coverage reporting\n[coverage-command]  # e.g., npm run test:coverage\n\n# Update task with verification\ntask-master update-subtask --id=X.Y --prompt=\"Testing framework verified:\n- Sample tests running successfully\n- Coverage reporting functional\n- CI/CD integration ready\n- Ready to begin TDD workflow\"\n```\n\n## **Test-Driven Development (TDD) Integration**\n\n### **Core TDD Cycle with Jest**\n```bash\n# 1. Start development with watch mode\nnpm run test:watch\n\n# 2. Write failing test first\n# Create test file: src/utils/newFeature.test.ts\n# Write test that describes expected behavior\n\n# 3. Implement minimum code to make test pass\n# 4. Refactor while keeping tests green\n# 5. Add edge cases and error scenarios\n```\n\n### **TDD Workflow Per Subtask**\n```bash\n# When starting a new subtask:\ntask-master set-status --id=4.1 --status=in-progress\n\n# Begin TDD cycle:\nnpm run test:watch  # Keep running during development\n\n# Document TDD progress in subtask:\ntask-master update-subtask --id=4.1 --prompt=\"TDD Progress:\n- Written 3 failing tests for core functionality\n- Implemented basic feature, tests now passing\n- Adding edge case tests for error handling\"\n\n# Complete subtask with test summary:\ntask-master update-subtask --id=4.1 --prompt=\"Implementation complete:\n- Feature implemented with 8 unit tests\n- Coverage: 95% statements, 88% branches  \n- All tests passing, TDD cycle complete\"\n```\n\n## **Testing Commands & Usage**\n\n### **Development Commands**\n```bash\n# Primary development command - use during coding\nnpm run test:watch              # Watch mode with Jest\nnpm run test:watch -- --testNamePattern=\"auth\"  # Watch specific tests\n\n# Targeted testing during development\nnpm run test:unit               # Run only unit tests\nnpm run test:unit -- --coverage # Unit tests with coverage\n\n# Integration testing when APIs are ready\nnpm run test:integration        # Run integration tests\nnpm run test:integration -- --detectOpenHandles  # Debug hanging tests\n\n# End-to-end testing for workflows\nnpm run test:e2e               # Run E2E tests\nnpm run test:e2e -- --timeout=30000  # Extended timeout for E2E\n```\n\n### **Quality Assurance Commands**\n```bash\n# Full test suite with coverage (before commits)\nnpm run test:coverage          # Complete coverage analysis\n\n# All tests (CI/CD pipeline)\nnpm test                       # Run all test projects\n\n# Specific test file execution\nnpm test -- auth.test.ts       # Run specific test file\nnpm test -- --testNamePattern=\"should handle errors\"  # Run specific tests\n```\n\n## **Test Implementation Patterns**\n\n### **Unit Test Development**\n```typescript\n// ✅ DO: Follow established patterns from auth.test.ts\ndescribe('FeatureName', () => {\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Setup mocks with proper typing\n  });\n\n  describe('functionName', () => {\n    it('should handle normal case', () => {\n      // Test implementation with specific assertions\n    });\n    \n    it('should throw error for invalid input', async () => {\n      // Error scenario testing\n      await expect(functionName(invalidInput))\n        .rejects.toThrow('Specific error message');\n    });\n  });\n});\n```\n\n### **Integration Test Development**  \n```typescript\n// ✅ DO: Use supertest for API endpoint testing\nimport request from 'supertest';\nimport { app } from '../../src/app';\n\ndescribe('POST /api/auth/register', () => {\n  beforeEach(async () => {\n    await integrationTestUtils.cleanupTestData();\n  });\n  \n  it('should register user successfully', async () => {\n    const userData = createTestUser();\n    \n    const response = await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n      \n    expect(response.body).toMatchObject({\n      id: expect.any(String),\n      email: userData.email\n    });\n    \n    // Verify database state\n    const user = await prisma.user.findUnique({\n      where: { email: userData.email }\n    });\n    expect(user).toBeTruthy();\n  });\n});\n```\n\n### **E2E Test Development**\n```typescript\n// ✅ DO: Test complete user workflows\ndescribe('User Authentication Flow', () => {\n  it('should complete registration → login → protected access', async () => {\n    // Step 1: Register\n    const userData = createTestUser();\n    await request(app)\n      .post('/api/auth/register')\n      .send(userData)\n      .expect(201);\n    \n    // Step 2: Login\n    const loginResponse = await request(app)\n      .post('/api/auth/login')\n      .send({ email: userData.email, password: userData.password })\n      .expect(200);\n    \n    const { token } = loginResponse.body;\n    \n    // Step 3: Access protected resource\n    await request(app)\n      .get('/api/profile')\n      .set('Authorization', `Bearer ${token}`)\n      .expect(200);\n  }, 30000); // Extended timeout for E2E\n});\n```\n\n## **Mocking & Test Utilities**\n\n### **Established Mocking Patterns**\n```typescript\n// ✅ DO: Use established bcrypt mocking pattern\njest.mock('bcrypt');\nimport bcrypt from 'bcrypt';\nconst mockHash = bcrypt.hash as jest.MockedFunction<typeof bcrypt.hash>;\nconst mockCompare = bcrypt.compare as jest.MockedFunction<typeof bcrypt.compare>;\n\n// ✅ DO: Use Prisma mocking for unit tests\njest.mock('@prisma/client', () => ({\n  PrismaClient: jest.fn().mockImplementation(() => ({\n    user: {\n      create: jest.fn(),\n      findUnique: jest.fn(),\n    },\n    $connect: jest.fn(),\n    $disconnect: jest.fn(),\n  })),\n}));\n```\n\n### **Test Fixtures Usage**\n```typescript\n// ✅ DO: Use centralized test fixtures\nimport { createTestUser, adminUser, invalidUser } from '../fixtures/users';\n\ndescribe('User Service', () => {\n  it('should handle admin user creation', async () => {\n    const userData = createTestUser(adminUser);\n    // Test implementation\n  });\n  \n  it('should reject invalid user data', async () => {\n    const userData = createTestUser(invalidUser);\n    // Error testing\n  });\n});\n```\n\n## **Coverage Standards & Monitoring**\n\n### **Coverage Thresholds**\n- **Global Standards**: 80% lines/functions, 70% branches\n- **Critical Code**: 90% utils, 85% middleware\n- **New Features**: Must meet or exceed global thresholds\n- **Legacy Code**: Gradual improvement with each change\n\n### **Coverage Reporting & Analysis**\n```bash\n# Generate coverage reports\nnpm run test:coverage\n\n# View detailed HTML report\nopen coverage/lcov-report/index.html\n\n# Coverage files generated:\n# - coverage/lcov-report/index.html  # Detailed HTML report\n# - coverage/lcov.info               # LCOV format for IDE integration  \n# - coverage/coverage-final.json     # JSON format for tooling\n```\n\n### **Coverage Quality Checks**\n```typescript\n// ✅ DO: Test all code paths\ndescribe('validateInput', () => {\n  it('should return true for valid input', () => {\n    expect(validateInput('valid')).toBe(true);\n  });\n  \n  it('should return false for various invalid inputs', () => {\n    expect(validateInput('')).toBe(false);      // Empty string\n    expect(validateInput(null)).toBe(false);    // Null value\n    expect(validateInput(undefined)).toBe(false); // Undefined\n  });\n  \n  it('should throw for unexpected input types', () => {\n    expect(() => validateInput(123)).toThrow('Invalid input type');\n  });\n});\n```\n\n## **Testing During Development Phases**\n\n### **Feature Development Phase**\n```bash\n# 1. Start feature development\ntask-master set-status --id=X.Y --status=in-progress\n\n# 2. Begin TDD cycle  \nnpm run test:watch\n\n# 3. Document test progress in subtask\ntask-master update-subtask --id=X.Y --prompt=\"Test development:\n- Created test file with 5 failing tests\n- Implemented core functionality\n- Tests passing, adding error scenarios\"\n\n# 4. Verify coverage before completion\nnpm run test:coverage\n\n# 5. Update subtask with final test status\ntask-master update-subtask --id=X.Y --prompt=\"Testing complete:\n- 12 unit tests with full coverage\n- All edge cases and error scenarios covered\n- Ready for integration testing\"\n```\n\n### **Integration Testing Phase**\n```bash\n# After API endpoints are implemented\nnpm run test:integration\n\n# Update integration test templates\n# Replace placeholder tests with real endpoint calls\n\n# Document integration test results\ntask-master update-subtask --id=X.Y --prompt=\"Integration tests:\n- Updated auth endpoint tests  \n- Database integration verified\n- All HTTP status codes and responses tested\"\n```\n\n### **Pre-Commit Testing Phase**\n```bash\n# Before committing code\nnpm run test:coverage         # Verify all tests pass with coverage\nnpm run test:unit            # Quick unit test verification\nnpm run test:integration     # Integration test verification (if applicable)\n\n# Commit pattern for test updates\ngit add tests/ src/**/*.test.ts\ngit commit -m \"test(task-X): Add comprehensive tests for Feature Y\n\n- Unit tests with 95% coverage (exceeds 90% threshold)\n- Integration tests for API endpoints\n- Test fixtures for data generation\n- Proper mocking patterns established\n\nTask X: Feature Y - Testing complete\"\n```\n\n## **Error Handling & Debugging**\n\n### **Test Debugging Techniques**\n```typescript\n// ✅ DO: Use test utilities for debugging\nimport { testUtils } from '../setup';\n\nit('should debug complex operation', () => {\n  testUtils.withConsole(() => {\n    // Console output visible only for this test\n    console.log('Debug info:', complexData);\n    service.complexOperation();\n  });\n});\n\n// ✅ DO: Use proper async debugging\nit('should handle async operations', async () => {\n  const promise = service.asyncOperation();\n  \n  // Test intermediate state\n  expect(service.isProcessing()).toBe(true);\n  \n  const result = await promise;\n  expect(result).toBe('expected');\n  expect(service.isProcessing()).toBe(false);\n});\n```\n\n### **Common Test Issues & Solutions**\n```bash\n# Hanging tests (common with database connections)\nnpm run test:integration -- --detectOpenHandles\n\n# Memory leaks in tests\nnpm run test:unit -- --logHeapUsage\n\n# Slow tests identification\nnpm run test:coverage -- --verbose\n\n# Mock not working properly\n# Check: mock is declared before imports\n# Check: jest.clearAllMocks() in beforeEach\n# Check: TypeScript typing is correct\n```\n\n## **Continuous Integration Integration**\n\n### **CI/CD Pipeline Testing**\n```yaml\n# Example GitHub Actions integration\n- name: Run tests\n  run: |\n    npm ci\n    npm run test:coverage\n    \n- name: Upload coverage reports\n  uses: codecov/codecov-action@v3\n  with:\n    file: ./coverage/lcov.info\n```\n\n### **Pre-commit Hooks**\n```bash\n# Setup pre-commit testing (recommended)\n# In package.json scripts:\n\"pre-commit\": \"npm run test:unit && npm run test:integration\"\n\n# Husky integration example:\nnpx husky add .husky/pre-commit \"npm run test:unit\"\n```\n\n## **Test Maintenance & Evolution**\n\n### **Adding Tests for New Features**\n1. **Create test file** alongside source code or in `tests/unit/`\n2. **Follow established patterns** from `src/utils/auth.test.ts`\n3. **Use existing fixtures** from `tests/fixtures/`\n4. **Apply proper mocking** patterns for dependencies\n5. **Meet coverage thresholds** for the module\n\n### **Updating Integration/E2E Tests**\n1. **Update templates** in `tests/integration/` when APIs change\n2. **Modify E2E workflows** in `tests/e2e/` for new user journeys  \n3. **Update test fixtures** for new data requirements\n4. **Maintain database cleanup** utilities\n\n### **Test Performance Optimization**\n- **Parallel execution**: Jest runs tests in parallel by default\n- **Test isolation**: Use proper setup/teardown for independence\n- **Mock optimization**: Mock heavy dependencies appropriately  \n- **Database efficiency**: Use transaction rollbacks where possible\n\n---\n\n**Key References:**\n- [Testing Standards](mdc:.cursor/rules/tests.mdc)\n- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc)\n- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc)\n- [Jest Configuration](mdc:jest.config.js)\n\n<!-- File: .cursor/rules/tests.mdc (Tokens: ~7678 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing and maintaining tests for Task Master CLI\nglobs: \"**/*.test.js,tests/**/*\"\n---\n\n# Testing Guidelines for Task Master CLI\n\n*Note:* Never use asynchronous operations in tests. Always mock tests properly based on the way the tested functions are defined and used. Do not arbitrarily create tests. Based them on the low-level details and execution of the underlying code being tested. \n\n## Test Organization Structure\n\n- **Unit Tests** (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for module breakdown)\n  - Located in `tests/unit/`\n  - Test individual functions and utilities in isolation\n  - Mock all external dependencies\n  - Keep tests small, focused, and fast\n  - Example naming: `utils.test.js`, `task-manager.test.js`\n\n- **Integration Tests**\n  - Located in `tests/integration/`\n  - Test interactions between modules\n  - Focus on component interfaces rather than implementation details\n  - Use more realistic but still controlled test environments\n  - Example naming: `task-workflow.test.js`, `command-integration.test.js`\n\n- **End-to-End Tests**\n  - Located in `tests/e2e/`\n  - Test complete workflows from a user perspective\n  - Focus on CLI commands as they would be used by users\n  - Example naming: `create-task.e2e.test.js`, `expand-task.e2e.test.js`\n\n- **Test Fixtures**\n  - Located in `tests/fixtures/`\n  - Provide reusable test data\n  - Keep fixtures small and representative\n  - Export fixtures as named exports for reuse\n\n## Test File Organization\n\n```javascript\n// 1. Imports\nimport { jest } from '@jest/globals';\n\n// 2. Mock setup (MUST come before importing the modules under test)\njest.mock('fs');\njest.mock('@anthropic-ai/sdk');\njest.mock('../../scripts/modules/utils.js', () => ({\n  CONFIG: {\n    projectVersion: '1.5.0'\n  },\n  log: jest.fn()\n}));\n\n// 3. Import modules AFTER all mocks are defined\nimport { functionToTest } from '../../scripts/modules/module-name.js';\nimport { testFixture } from '../fixtures/fixture-name.js';\nimport fs from 'fs';\n\n// 4. Set up spies on mocked modules (if needed)\nconst mockReadFileSync = jest.spyOn(fs, 'readFileSync');\n\n// 5. Test suite with descriptive name\ndescribe('Feature or Function Name', () => {\n  // 6. Setup and teardown (if needed)\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Additional setup code\n  });\n  \n  afterEach(() => {\n    // Cleanup code\n  });\n  \n  // 7. Grouped tests for related functionality\n  describe('specific functionality', () => {\n    // 8. Individual test cases with clear descriptions\n    test('should behave in expected way when given specific input', () => {\n      // Arrange - set up test data\n      const input = testFixture.sampleInput;\n      mockReadFileSync.mockReturnValue('mocked content');\n      \n      // Act - call the function being tested\n      const result = functionToTest(input);\n      \n      // Assert - verify the result\n      expect(result).toBe(expectedOutput);\n      expect(mockReadFileSync).toHaveBeenCalledWith(expect.stringContaining('path'));\n    });\n  });\n});\n```\n\n## Commander.js Command Testing Best Practices\n\nWhen testing CLI commands built with Commander.js, several special considerations must be made to avoid common pitfalls:\n\n- **Direct Action Handler Testing**\n  - ✅ **DO**: Test the command action handlers directly rather than trying to mock the entire Commander.js chain\n  - ✅ **DO**: Create simplified test-specific implementations of command handlers that match the original behavior\n  - ✅ **DO**: Explicitly handle all options, including defaults and shorthand flags (e.g., `-p` for `--prompt`)\n  - ✅ **DO**: Include null/undefined checks in test implementations for parameters that might be optional\n  - ✅ **DO**: Use fixtures from `tests/fixtures/` for consistent sample data across tests\n  \n  ```javascript\n  // ✅ DO: Create a simplified test version of the command handler\n  const testAddTaskAction = async (options) => {\n    options = options || {}; // Ensure options aren't undefined\n    \n    // Validate parameters\n    const isManualCreation = options.title && options.description;\n    const prompt = options.prompt || options.p; // Handle shorthand flags\n    \n    if (!prompt && !isManualCreation) {\n      throw new Error('Expected error message');\n    }\n    \n    // Call the mocked task manager\n    return mockTaskManager.addTask(/* parameters */);\n  };\n  \n  test('should handle required parameters correctly', async () => {\n    // Call the test implementation directly\n    await expect(async () => {\n      await testAddTaskAction({ file: 'tasks.json' });\n    }).rejects.toThrow('Expected error message');\n  });\n  ```\n\n- **Commander Chain Mocking (If Necessary)**\n  - ✅ **DO**: Mock ALL chainable methods (`option`, `argument`, `action`, `on`, etc.)\n  - ✅ **DO**: Return `this` (or the mock object) from all chainable method mocks\n  - ✅ **DO**: Remember to mock not only the initial object but also all objects returned by methods\n  - ✅ **DO**: Implement a mechanism to capture the action handler for direct testing\n  \n  ```javascript\n  // If you must mock the Commander.js chain:\n  const mockCommand = {\n    command: jest.fn().mockReturnThis(),\n    description: jest.fn().mockReturnThis(),\n    option: jest.fn().mockReturnThis(),\n    argument: jest.fn().mockReturnThis(), // Don't forget this one\n    action: jest.fn(fn => { \n      actionHandler = fn; // Capture the handler for testing\n      return mockCommand; \n    }),\n    on: jest.fn().mockReturnThis() // Don't forget this one\n  };\n  ```\n\n- **Parameter Handling**\n  - ✅ **DO**: Check for both main flag and shorthand flags (e.g., `prompt` and `p`)\n  - ✅ **DO**: Handle parameters like Commander would (comma-separated lists, etc.)\n  - ✅ **DO**: Set proper default values as defined in the command\n  - ✅ **DO**: Validate that required parameters are actually required in tests\n  \n  ```javascript\n  // Parse dependencies like Commander would\n  const dependencies = options.dependencies \n    ? options.dependencies.split(',').map(id => id.trim())\n    : [];\n  ```\n\n- **Environment and Session Handling**\n  - ✅ **DO**: Properly mock session objects when required by functions\n  - ✅ **DO**: Reset environment variables between tests if modified\n  - ✅ **DO**: Use a consistent pattern for environment-dependent tests\n  \n  ```javascript\n  // Session parameter mock pattern\n  const sessionMock = { session: process.env };\n  \n  // In test:\n  expect(mockAddTask).toHaveBeenCalledWith(\n    expect.any(String),\n    'Test prompt',\n    [],\n    'medium',\n    sessionMock,\n    false,\n    null,\n    null\n  );\n  ```\n\n- **Common Pitfalls to Avoid**\n  - ❌ **DON'T**: Try to use the real action implementation without proper mocking\n  - ❌ **DON'T**: Mock Commander partially - either mock it completely or test the action directly\n  - ❌ **DON'T**: Forget to handle optional parameters that may be undefined\n  - ❌ **DON'T**: Neglect to test shorthand flag functionality (e.g., `-p`, `-r`)\n  - ❌ **DON'T**: Create circular dependencies in your test mocks\n  - ❌ **DON'T**: Access variables before initialization in your test implementations\n  - ❌ **DON'T**: Include actual command execution in unit tests\n  - ❌ **DON'T**: Overwrite the same file path in multiple tests\n  \n  ```javascript\n  // ❌ DON'T: Create circular references in mocks\n  const badMock = {\n    method: jest.fn().mockImplementation(() => badMock.method())\n  };\n  \n  // ❌ DON'T: Access uninitialized variables\n  const badImplementation = () => {\n    const result = uninitialized;\n    let uninitialized = 'value';\n    return result;\n  };\n  ```\n\n## Jest Module Mocking Best Practices\n\n- **Mock Hoisting Behavior**\n  - Jest hoists `jest.mock()` calls to the top of the file, even above imports\n  - Always declare mocks before importing the modules being tested\n  - Use the factory pattern for complex mocks that need access to other variables\n\n  ```javascript\n  // ✅ DO: Place mocks before imports\n  jest.mock('commander');\n  import { program } from 'commander';\n  \n  // ❌ DON'T: Define variables and then try to use them in mocks\n  const mockFn = jest.fn();\n  jest.mock('module', () => ({\n    func: mockFn // This won't work due to hoisting!\n  }));\n  ```\n\n- **Mocking Modules with Function References**\n  - Use `jest.spyOn()` after imports to create spies on mock functions\n  - Reference these spies in test assertions\n  \n  ```javascript\n  // Mock the module first\n  jest.mock('fs');\n  \n  // Import the mocked module\n  import fs from 'fs';\n  \n  // Create spies on the mock functions\n  const mockExistsSync = jest.spyOn(fs, 'existsSync').mockReturnValue(true);\n  \n  test('should call existsSync', () => {\n    // Call function that uses fs.existsSync\n    const result = functionUnderTest();\n    \n    // Verify the mock was called correctly\n    expect(mockExistsSync).toHaveBeenCalled();\n  });\n  ```\n\n- **Testing Functions with Callbacks**\n  - Get the callback from your mock's call arguments\n  - Execute it directly with test inputs\n  - Verify the results match expectations\n  \n  ```javascript\n  jest.mock('commander');\n  import { program } from 'commander';\n  import { setupCLI } from '../../scripts/modules/commands.js';\n  \n  const mockVersion = jest.spyOn(program, 'version').mockReturnValue(program);\n  \n  test('version callback should return correct version', () => {\n    // Call the function that registers the callback\n    setupCLI();\n    \n    // Extract the callback function\n    const versionCallback = mockVersion.mock.calls[0][0];\n    expect(typeof versionCallback).toBe('function');\n    \n    // Execute the callback and verify results\n    const result = versionCallback();\n    expect(result).toBe('1.5.0');\n  });\n  ```\n\n## ES Module Testing Strategies\n\nWhen testing ES modules (`\"type\": \"module\"` in package.json), traditional mocking approaches require special handling to avoid reference and scoping issues.\n\n- **Module Import Challenges**\n  - Functions imported from ES modules may still reference internal module-scoped variables\n  - Imported functions may not use your mocked dependencies even with proper jest.mock() setup\n  - ES module exports are read-only properties (cannot be reassigned during tests)\n\n- **Mocking Modules Statically Imported**\n  - For modules imported with standard `import` statements at the top level:\n    - Use `jest.mock('path/to/module', factory)` **before** any imports.\n    - Jest hoists these mocks.\n    - Ensure the factory function returns the mocked structure correctly.\n\n- **Mocking Dependencies for Dynamically Imported Modules**\n  - **Problem**: Standard `jest.mock()` often fails for dependencies of modules loaded later using dynamic `import('path/to/module')`. The mocks aren't applied correctly when the dynamic import resolves.\n  - **Solution**: Use `jest.unstable_mockModule(modulePath, factory)` **before** the dynamic `import()` call.\n  ```javascript\n  // 1. Define mock function instances\n  const mockExistsSync = jest.fn();\n  const mockReadFileSync = jest.fn();\n  // ... other mocks\n\n  // 2. Mock the dependency module *before* the dynamic import\n  jest.unstable_mockModule('fs', () => ({\n    __esModule: true, // Important for ES module mocks\n    // Mock named exports\n    existsSync: mockExistsSync,\n    readFileSync: mockReadFileSync,\n    // Mock default export if necessary\n    // default: { ... }\n  }));\n\n  // 3. Dynamically import the module under test (e.g., in beforeAll or test case)\n  let moduleUnderTest;\n  beforeAll(async () => {\n    // Ensure mocks are reset if needed before import\n    mockExistsSync.mockReset();\n    mockReadFileSync.mockReset();\n    // ... reset other mocks ...\n\n    // Import *after* unstable_mockModule is called\n    moduleUnderTest = await import('../../scripts/modules/module-using-fs.js');\n  });\n\n  // 4. Now tests can use moduleUnderTest, and its 'fs' calls will hit the mocks\n  test('should use mocked fs.readFileSync', () => {\n    mockReadFileSync.mockReturnValue('mock data');\n    moduleUnderTest.readFileAndProcess();\n    expect(mockReadFileSync).toHaveBeenCalled();\n    // ... other assertions\n  });\n  ```\n  - ✅ **DO**: Call `jest.unstable_mockModule()` before `await import()`.\n  - ✅ **DO**: Include `__esModule: true` in the mock factory for ES modules.\n  - ✅ **DO**: Mock named and default exports as needed within the factory.\n  - ✅ **DO**: Reset mock functions (`mockFn.mockReset()`) before the dynamic import if they might have been called previously.\n\n- **Mocking Entire Modules (Static Import)**\n  ```javascript\n  // Mock the entire module with custom implementation for static imports\n  // ... (existing example remains valid) ...\n  ```\n\n- **Direct Implementation Testing**\n  - Instead of calling the actual function which may have module-scope reference issues:\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Avoiding Module Property Assignment**\n  ```javascript\n  // ... (existing example remains valid) ...\n  ```\n\n- **Handling Mock Verification Failures**\n  - If verification like `expect(mockFn).toHaveBeenCalled()` fails:\n    1.  Check that your mock setup (`jest.mock` or `jest.unstable_mockModule`) is correctly placed **before** imports (static or dynamic).\n    2.  Ensure you're using the right mock instance and it's properly passed to the module.\n    3.  Verify your test invokes behavior that *should* call the mock.\n    4.  Use `jest.clearAllMocks()` or specific `mockFn.mockReset()` in `beforeEach` to prevent state leakage between tests.\n    5.  **Check Console Assertions**: If verifying `console.log`, `console.warn`, or `console.error` calls, ensure your assertion matches the *actual* arguments passed. If the code logs a single formatted string, assert against that single string (using `expect.stringContaining` or exact match), not multiple `expect.stringContaining` arguments.\n        ```javascript\n        // Example: Code logs console.error(`Error: ${message}. Details: ${details}`)\n        // ❌ DON'T: Assert multiple arguments if only one is logged\n        // expect(console.error).toHaveBeenCalledWith(\n        //   expect.stringContaining('Error:'),\n        //   expect.stringContaining('Details:')\n        // );\n        // ✅ DO: Assert the single string argument\n        expect(console.error).toHaveBeenCalledWith(\n           expect.stringContaining('Error: Specific message. Details: More details')\n        );\n        // or for exact match:\n        expect(console.error).toHaveBeenCalledWith(\n           'Error: Specific message. Details: More details'\n        );\n        ```\n    6.  Consider implementing a simpler test that *only* verifies the mock behavior in isolation.\n\n## Mocking Guidelines\n\n- **File System Operations**\n  ```javascript\n  import mockFs from 'mock-fs';\n  \n  beforeEach(() => {\n    mockFs({\n      'tasks': {\n        'tasks.json': JSON.stringify({\n          meta: { projectName: 'Test Project' },\n          tasks: []\n        })\n      }\n    });\n  });\n  \n  afterEach(() => {\n    mockFs.restore();\n  });\n  ```\n\n- **API Calls (Anthropic/Claude)**\n  ```javascript\n  import { Anthropic } from '@anthropic-ai/sdk';\n  \n  jest.mock('@anthropic-ai/sdk');\n  \n  beforeEach(() => {\n    Anthropic.mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ text: 'Mocked response' }]\n        })\n      }\n    }));\n  });\n  ```\n\n- **Environment Variables**\n  ```javascript\n  const originalEnv = process.env;\n  \n  beforeEach(() => {\n    jest.resetModules();\n    process.env = { ...originalEnv };\n    process.env.MODEL = 'test-model';\n  });\n  \n  afterEach(() => {\n    process.env = originalEnv;\n  });\n  ```\n\n## Testing Common Components\n\n- **CLI Commands**\n  - Mock the action handlers (defined in [`commands.js`](mdc:scripts/modules/commands.js)) and verify they're called with correct arguments\n  - Test command registration and option parsing\n  - Use `commander` test utilities or custom mocks\n\n- **Task Operations**\n  - Use sample task fixtures for consistent test data\n  - Mock file system operations\n  - Test both success and error paths\n\n- **UI Functions**\n  - Mock console output and verify correct formatting\n  - Test conditional output logic\n  - When testing strings with emojis or formatting, use `toContain()` or `toMatch()` rather than exact `toBe()` comparisons\n  - For functions with different behavior modes (e.g., `forConsole`, `forTable` parameters), create separate tests for each mode\n  - Test the structure of formatted output (e.g., check that it's a comma-separated list with the right number of items) rather than exact string matching\n  - When testing chalk-formatted output, remember that strict equality comparison (`toBe()`) can fail even when the visible output looks identical\n  - Consider using more flexible assertions like checking for the presence of key elements when working with styled text\n  - Mock chalk functions to return the input text to make testing easier while still verifying correct function calls\n\n## Test Quality Guidelines\n\n- ✅ **DO**: Write tests before implementing features (TDD approach when possible)\n- ✅ **DO**: Test edge cases and error conditions, not just happy paths\n- ✅ **DO**: Keep tests independent and isolated from each other\n- ✅ **DO**: Use descriptive test names that explain the expected behavior\n- ✅ **DO**: Maintain test fixtures separate from test logic\n- ✅ **DO**: Aim for 80%+ code coverage, with critical paths at 100%\n- ✅ **DO**: Follow the mock-first-then-import pattern for all Jest mocks\n\n- ❌ **DON'T**: Test implementation details that might change\n- ❌ **DON'T**: Write brittle tests that depend on specific output formatting\n- ❌ **DON'T**: Skip testing error handling and validation\n- ❌ **DON'T**: Duplicate test fixtures across multiple test files\n- ❌ **DON'T**: Write tests that depend on execution order\n- ❌ **DON'T**: Define mock variables before `jest.mock()` calls (they won't be accessible due to hoisting)\n\n\n- **Task File Operations**\n  - ✅ DO: Use test-specific file paths (e.g., 'test-tasks.json') for all operations\n  - ✅ DO: Mock `readJSON` and `writeJSON` to avoid real file system interactions\n  - ✅ DO: Verify file operations use the correct paths in `expect` statements\n  - ✅ DO: Use different paths for each test to avoid test interdependence\n  - ✅ DO: Verify modifications on the in-memory task objects passed to `writeJSON`\n  - ❌ DON'T: Modify real task files (tasks.json) during tests\n  - ❌ DON'T: Skip testing file operations because they're \"just I/O\"\n  \n  ```javascript\n  // ✅ DO: Test file operations without real file system changes\n  test('should update task status in tasks.json', async () => {\n    // Setup mock to return sample data\n    readJSON.mockResolvedValue(JSON.parse(JSON.stringify(sampleTasks)));\n    \n    // Use test-specific file path\n    await setTaskStatus('test-tasks.json', '2', 'done');\n    \n    // Verify correct file path was read\n    expect(readJSON).toHaveBeenCalledWith('test-tasks.json');\n    \n    // Verify correct file path was written with updated content\n    expect(writeJSON).toHaveBeenCalledWith(\n      'test-tasks.json',\n      expect.objectContaining({\n        tasks: expect.arrayContaining([\n          expect.objectContaining({\n            id: 2,\n            status: 'done'\n          })\n        ])\n      })\n    );\n  });\n  ```\n\n## Running Tests\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Run tests with coverage reporting\nnpm run test:coverage\n\n# Run a specific test file\nnpm test -- tests/unit/specific-file.test.js\n\n# Run tests matching a pattern\nnpm test -- -t \"pattern to match\"\n```\n\n## Troubleshooting Test Issues\n\n- **Mock Functions Not Called**\n  - Ensure mocks are defined before imports (Jest hoists `jest.mock()` calls)\n  - Check that you're referencing the correct mock instance\n  - Verify the import paths match exactly\n\n- **Unexpected Mock Behavior**\n  - Clear mocks between tests with `jest.clearAllMocks()` in `beforeEach`\n  - Check mock implementation for conditional behavior\n  - Ensure mock return values are correctly configured for each test\n\n- **Tests Affecting Each Other**\n  - Isolate tests by properly mocking shared resources\n  - Reset state in `beforeEach` and `afterEach` hooks\n  - Avoid global state modifications\n\n## Common Testing Pitfalls and Solutions\n\n- **Complex Library Mocking**\n  - **Problem**: Trying to create full mocks of complex libraries like Commander.js can be error-prone\n  - **Solution**: Instead of mocking the entire library, test the command handlers directly by calling your action handlers with the expected arguments\n  ```javascript\n  // ❌ DON'T: Create complex mocks of Commander.js\n  class MockCommand {\n    constructor() { /* Complex mock implementation */ }\n    option() { /* ... */ }\n    action() { /* ... */ }\n    // Many methods to implement\n  }\n  \n  // ✅ DO: Test the command handlers directly\n  test('should use default PRD path when no arguments provided', async () => {\n    // Call the action handler directly with the right params\n    await parsePrdAction(undefined, { numTasks: '10', output: 'tasks/tasks.json' });\n    \n    // Assert on behavior\n    expect(mockParsePRD).toHaveBeenCalledWith('scripts/prd.txt', 'tasks/tasks.json', 10);\n  });\n  ```\n\n- **ES Module Mocking Challenges**\n  - **Problem**: ES modules don't support `require()` and imports are read-only\n  - **Solution**: Use Jest's module factory pattern and ensure mocks are defined before imports\n  ```javascript\n  // ❌ DON'T: Try to modify imported modules\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  detectCamelCaseFlags = jest.fn(); // Error: Assignment to constant variable\n  \n  // ❌ DON'T: Try to use require with ES modules\n  const utils = require('../../scripts/modules/utils.js'); // Error in ES modules\n  \n  // ✅ DO: Use Jest module factory pattern\n  jest.mock('../../scripts/modules/utils.js', () => ({\n    detectCamelCaseFlags: jest.fn(),\n    toKebabCase: jest.fn()\n  }));\n  \n  // Import after mocks are defined\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  ```\n\n- **Function Redeclaration Errors**\n  - **Problem**: Declaring the same function twice in a test file causes errors\n  - **Solution**: Use different function names or create local test-specific implementations\n  ```javascript\n  // ❌ DON'T: Redefine imported functions with the same name\n  import { detectCamelCaseFlags } from '../../scripts/modules/utils.js';\n  \n  function detectCamelCaseFlags() { /* Test implementation */ }\n  // Error: Identifier has already been declared\n  \n  // ✅ DO: Use a different name for test implementations\n  function testDetectCamelCaseFlags() { /* Test implementation */ }\n  ```\n\n- **Console.log Circular References**\n  - **Problem**: Creating infinite recursion by spying on console.log while also allowing it to log\n  - **Solution**: Implement a mock that doesn't call the original function\n  ```javascript\n  // ❌ DON'T: Create circular references with console.log\n  const mockConsoleLog = jest.spyOn(console, 'log');\n  mockConsoleLog.mockImplementation(console.log); // Creates infinite recursion\n  \n  // ✅ DO: Use a non-recursive mock implementation\n  const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => {});\n  ```\n\n- **Mock Function Method Issues**\n  - **Problem**: Trying to use jest.fn() methods on imported functions that aren't properly mocked\n  - **Solution**: Create explicit jest.fn() mocks for functions you need to call jest methods on\n  ```javascript\n  // ❌ DON'T: Try to use jest methods on imported functions without proper mocking\n  import { parsePRD } from '../../scripts/modules/task-manager.js';\n  parsePRD.mockClear(); // Error: parsePRD.mockClear is not a function\n  \n  // ✅ DO: Create proper jest.fn() mocks\n  const mockParsePRD = jest.fn().mockResolvedValue(undefined);\n  jest.mock('../../scripts/modules/task-manager.js', () => ({\n    parsePRD: mockParsePRD\n  }));\n  // Now you can use:\n  mockParsePRD.mockClear();\n  ```\n\n- **EventEmitter Max Listeners Warning**\n  - **Problem**: Commander.js adds many listeners in complex mocks, causing warnings\n  - **Solution**: Either increase the max listeners limit or avoid deep mocking\n  ```javascript\n  // Option 1: Increase max listeners if you must mock Commander\n  class MockCommand extends EventEmitter {\n    constructor() {\n      super();\n      this.setMaxListeners(20); // Avoid MaxListenersExceededWarning\n    }\n  }\n  \n  // Option 2 (preferred): Test command handlers directly instead\n  // (as shown in the first example)\n  ```\n\n- **Test Isolation Issues**\n  - **Problem**: Tests affecting each other due to shared mock state\n  - **Solution**: Reset all mocks in beforeEach and use separate test-specific mocks\n  ```javascript\n  // ❌ DON'T: Allow mock state to persist between tests\n  const globalMock = jest.fn().mockReturnValue('test');\n  \n  // ✅ DO: Clear mocks before each test\n  beforeEach(() => {\n    jest.clearAllMocks();\n    // Set up test-specific mock behavior\n    mockFunction.mockReturnValue('test-specific value');\n  });\n  ```\n\n## Testing AI Service Integrations\n\n- **DO NOT import real AI service clients**\n  - ❌ DON'T: Import actual AI clients from their libraries\n  - ✅ DO: Create fully mocked versions that return predictable responses\n\n  ```javascript\n  // ❌ DON'T: Import and instantiate real AI clients\n  import { Anthropic } from '@anthropic-ai/sdk';\n  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n\n  // ✅ DO: Mock the entire module with controlled behavior\n  jest.mock('@anthropic-ai/sdk', () => ({\n    Anthropic: jest.fn().mockImplementation(() => ({\n      messages: {\n        create: jest.fn().mockResolvedValue({\n          content: [{ type: 'text', text: 'Mocked AI response' }]\n        })\n      }\n    }))\n  }));\n  ```\n\n- **DO NOT rely on environment variables for API keys**\n  - ❌ DON'T: Assume environment variables are set in tests\n  - ✅ DO: Set mock environment variables in test setup\n\n  ```javascript\n  // In tests/setup.js or at the top of test file\n  process.env.ANTHROPIC_API_KEY = 'test-mock-api-key-for-tests';\n  process.env.PERPLEXITY_API_KEY = 'test-mock-perplexity-key-for-tests';\n  ```\n\n- **DO NOT use real AI client initialization logic**\n  - ❌ DON'T: Use code that attempts to initialize or validate real AI clients\n  - ✅ DO: Create test-specific paths that bypass client initialization\n\n  ```javascript\n  // ❌ DON'T: Test functions that require valid AI client initialization\n  // This will fail without proper API keys or network access\n  test('should use AI client', async () => {\n    const result = await functionThatInitializesAIClient();\n    expect(result).toBeDefined();\n  });\n\n  // ✅ DO: Test with bypassed initialization or manual task paths\n  test('should handle manual task creation without AI', () => {\n    // Using a path that doesn't require AI client initialization\n    const result = addTaskDirect({ \n      title: 'Manual Task', \n      description: 'Test Description'\n    }, mockLogger);\n    \n    expect(result.success).toBe(true);\n  });\n  ```\n\n## Testing Asynchronous Code\n\n- **DO NOT rely on asynchronous operations in tests**\n  - ❌ DON'T: Use real async/await or Promise resolution in tests\n  - ✅ DO: Make all mocks return synchronous values when possible\n\n  ```javascript\n  // ❌ DON'T: Use real async functions that might fail unpredictably\n  test('should handle async operation', async () => {\n    const result = await realAsyncFunction(); // Can time out or fail for external reasons\n    expect(result).toBe(expectedValue);\n  });\n\n  // ✅ DO: Make async operations synchronous in tests\n  test('should handle operation', () => {\n    mockAsyncFunction.mockReturnValue({ success: true, data: 'test' });\n    const result = functionUnderTest();\n    expect(result).toEqual({ success: true, data: 'test' });\n  });\n  ```\n\n- **DO NOT test exact error messages**\n  - ❌ DON'T: Assert on exact error message text that might change\n  - ✅ DO: Test for error presence and general properties\n\n  ```javascript\n  // ❌ DON'T: Test for exact error message text\n  expect(result.error).toBe('Could not connect to API: Network error');\n\n  // ✅ DO: Test for general error properties or message patterns\n  expect(result.success).toBe(false);\n  expect(result.error).toContain('Could not connect');\n  // Or even better:\n  expect(result).toMatchObject({ \n    success: false,\n    error: expect.stringContaining('connect')\n  });\n  ```\n\n## Reliable Testing Techniques\n\n- **Create Simplified Test Functions**\n  - Create simplified versions of complex functions that focus only on core logic\n  - Remove file system operations, API calls, and other external dependencies\n  - Pass all dependencies as parameters to make testing easier\n  \n  ```javascript\n  // Original function (hard to test)\n  const setTaskStatus = async (taskId, newStatus) => {\n    const tasksPath = 'tasks/tasks.json';\n    const data = await readJSON(tasksPath);\n    // [implementation]\n    await writeJSON(tasksPath, data);\n    return { success: true };\n  };\n  \n  // Test-friendly version (easier to test)\n  const updateTaskStatus = (tasks, taskId, newStatus) => {\n    // Pure logic without side effects\n    const updatedTasks = [...tasks];\n    const taskIndex = findTaskById(updatedTasks, taskId);\n    if (taskIndex === -1) return { success: false, error: 'Task not found' };\n    updatedTasks[taskIndex].status = newStatus;\n    return { success: true, tasks: updatedTasks };\n  };\n  ```\n\nSee [tests/README.md](mdc:tests/README.md) for more details on the testing approach.\n\nRefer to [jest.config.js](mdc:jest.config.js) for Jest configuration options.\n\n## Variable Hoisting and Module Initialization Issues\n\nWhen testing ES modules or working with complex module imports, you may encounter variable hoisting and initialization issues. These can be particularly tricky to debug and often appear as \"Cannot access 'X' before initialization\" errors.\n\n- **Understanding Module Initialization Order**\n  - ✅ **DO**: Declare and initialize global variables at the top of modules\n  - ✅ **DO**: Use proper function declarations to avoid hoisting issues\n  - ✅ **DO**: Initialize variables before they are referenced, especially in imported modules\n  - ✅ **DO**: Be aware that imports are hoisted to the top of the file\n  \n  ```javascript\n  // ✅ DO: Define global state variables at the top of the module\n  let silentMode = false; // Declare and initialize first\n  \n  const CONFIG = { /* configuration */ };\n  \n  function isSilentMode() {\n    return silentMode; // Reference variable after it's initialized\n  }\n  \n  function log(level, message) {\n    if (isSilentMode()) return; // Use the function instead of accessing variable directly\n    // ...\n  }\n  ```\n\n- **Testing Modules with Initialization-Dependent Functions**\n  - ✅ **DO**: Create test-specific implementations that initialize all variables correctly\n  - ✅ **DO**: Use factory functions in mocks to ensure proper initialization order\n  - ✅ **DO**: Be careful with how you mock or stub functions that depend on module state\n  \n  ```javascript\n  // ✅ DO: Test-specific implementation that avoids initialization issues\n  const testLog = (level, ...args) => {\n    // Local implementation with proper initialization\n    const isSilent = false; // Explicit initialization\n    if (isSilent) return;\n    // Test implementation...\n  };\n  ```\n\n- **Common Hoisting-Related Errors to Avoid**\n  - ❌ **DON'T**: Reference variables before their declaration in module scope\n  - ❌ **DON'T**: Create circular dependencies between modules\n  - ❌ **DON'T**: Rely on variable initialization order across module boundaries\n  - ❌ **DON'T**: Define functions that use hoisted variables before they're initialized\n  \n  ```javascript\n  // ❌ DON'T: Create reference-before-initialization patterns\n  function badFunction() {\n    if (silentMode) { /* ... */ } // ReferenceError if silentMode is declared later\n  }\n  \n  let silentMode = false;\n  \n  // ❌ DON'T: Create cross-module references that depend on initialization order\n  // module-a.js\n  import { getSetting } from './module-b.js';\n  export const config = { value: getSetting() };\n  \n  // module-b.js\n  import { config } from './module-a.js';\n  export function getSetting() {\n    return config.value; // Circular dependency causing initialization issues\n  }\n  ```\n\n- **Dynamic Imports as a Solution**\n  - ✅ **DO**: Use dynamic imports (`import()`) to avoid initialization order issues\n  - ✅ **DO**: Structure modules to avoid circular dependencies that cause initialization issues\n  - ✅ **DO**: Consider factory functions for modules with complex state\n  \n  ```javascript\n  // ✅ DO: Use dynamic imports to avoid initialization issues\n  async function getTaskManager() {\n    return import('./task-manager.js');\n  }\n  \n  async function someFunction() {\n    const taskManager = await getTaskManager();\n    return taskManager.someMethod();\n  }\n  ```\n\n- **Testing Approach for Modules with Initialization Issues**\n  - ✅ **DO**: Create self-contained test implementations rather than using real implementations\n  - ✅ **DO**: Mock dependencies at module boundaries instead of trying to mock deep dependencies\n  - ✅ **DO**: Isolate module-specific state in tests\n  \n  ```javascript\n  // ✅ DO: Create isolated test implementation instead of reusing module code\n  test('should log messages when not in silent mode', () => {\n    // Local test implementation instead of importing from module\n    const testLog = (level, message) => {\n      if (false) return; // Always non-silent for this test\n      mockConsole(level, message);\n    };\n    \n    testLog('info', 'test message');\n    expect(mockConsole).toHaveBeenCalledWith('info', 'test message');\n  });\n  ```\n\n<!-- File: .cursor/rules/ui.mdc (Tokens: ~1839 | Category: cursor-rule) -->\n---\ndescription: Guidelines for implementing and maintaining user interface components\nglobs: scripts/modules/ui.js\nalwaysApply: false\n---\n\n# User Interface Implementation Guidelines\n\n## Core UI Component Principles\n\n- **Function Scope Separation**:\n  - ✅ DO: Keep display logic separate from business logic\n  - ✅ DO: Import data processing functions from other modules\n  - ❌ DON'T: Include task manipulations within UI functions\n  - ❌ DON'T: Create circular dependencies with other modules\n\n- **Standard Display Pattern**:\n  ```javascript\n  // ✅ DO: Follow this pattern for display functions\n  /**\n   * Display information about a task\n   * @param {Object} task - The task to display\n   */\n  function displayTaskInfo(task) {\n    console.log(boxen(\n      chalk.white.bold(`Task: #${task.id} - ${task.title}`),\n      { padding: 1, borderColor: 'blue', borderStyle: 'round' }\n    ));\n  }\n  ```\n\n## Visual Styling Standards\n\n- **Color Scheme**:\n  - Use `chalk.blue` for informational messages\n  - Use `chalk.green` for success messages\n  - Use `chalk.yellow` for warnings\n  - Use `chalk.red` for errors\n  - Use `chalk.cyan` for prompts and highlights\n  - Use `chalk.magenta` for subtask-related information\n\n- **Box Styling**:\n  ```javascript\n  // ✅ DO: Use consistent box styles by content type\n  // For success messages:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'green', \n    borderStyle: 'round', \n    margin: { top: 1 } \n  })\n\n  // For errors:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'red', \n    borderStyle: 'round'\n  })\n\n  // For information:\n  boxen(content, { \n    padding: 1, \n    borderColor: 'blue', \n    borderStyle: 'round', \n    margin: { top: 1, bottom: 1 } \n  })\n  ```\n\n## Table Display Guidelines\n\n- **Table Structure**:\n  - Use [`cli-table3`](mdc:node_modules/cli-table3/README.md) for consistent table rendering\n  - Include colored headers with bold formatting\n  - Use appropriate column widths for readability\n\n  ```javascript\n  // ✅ DO: Create well-structured tables\n  const table = new Table({\n    head: [\n      chalk.cyan.bold('ID'),\n      chalk.cyan.bold('Title'),\n      chalk.cyan.bold('Status'),\n      chalk.cyan.bold('Priority'),\n      chalk.cyan.bold('Dependencies')\n    ],\n    colWidths: [5, 40, 15, 10, 20]\n  });\n  \n  // Add content rows\n  table.push([\n    task.id,\n    truncate(task.title, 37),\n    getStatusWithColor(task.status),\n    chalk.white(task.priority || 'medium'),\n    formatDependenciesWithStatus(task.dependencies, allTasks, true)\n  ]);\n  \n  console.log(table.toString());\n  ```\n\n## Loading Indicators\n\n- **Animation Standards**:\n  - Use [`ora`](mdc:node_modules/ora/readme.md) for spinner animations\n  - Create and stop loading indicators correctly\n\n  ```javascript\n  // ✅ DO: Properly manage loading state\n  const loadingIndicator = startLoadingIndicator('Processing task data...');\n  try {\n    // Do async work...\n    stopLoadingIndicator(loadingIndicator);\n    // Show success message\n  } catch (error) {\n    stopLoadingIndicator(loadingIndicator);\n    // Show error message\n  }\n  ```\n\n## Helper Functions\n\n- **Status Formatting**:\n  - Use `getStatusWithColor` for consistent status display\n  - Use `formatDependenciesWithStatus` for dependency lists\n  - Use `truncate` to handle text that may overflow display\n\n- **Progress Reporting**:\n  - Use visual indicators for progress (bars, percentages)\n  - Include both numeric and visual representations\n  \n  ```javascript\n  // ✅ DO: Show clear progress indicators\n  console.log(`${chalk.cyan('Tasks:')} ${completedTasks}/${totalTasks} (${completionPercentage.toFixed(1)}%)`);\n  console.log(`${chalk.cyan('Progress:')} ${createProgressBar(completionPercentage)}`);\n  ```\n\n## Command Suggestions\n\n- **Action Recommendations**:\n  - Provide next step suggestions after command completion\n  - Use a consistent format for suggested commands\n\n  ```javascript\n  // ✅ DO: Show suggested next actions\n  console.log(boxen(\n    chalk.white.bold('Next Steps:') + '\\n\\n' +\n    `${chalk.cyan('1.')} Run ${chalk.yellow('task-master list')} to view all tasks\\n` +\n    `${chalk.cyan('2.')} Run ${chalk.yellow('task-master show --id=' + newTaskId)} to view details`,\n    { padding: 1, borderColor: 'cyan', borderStyle: 'round', margin: { top: 1 } }\n  ));\n  ```\n\n## Enhanced Display Patterns\n\n### **Token Breakdown Display**\n- Use detailed, granular token breakdowns for AI-powered commands\n- Display context sources with individual token counts\n- Show both token count and character count for transparency\n\n  ```javascript\n  // ✅ DO: Display detailed token breakdown\n  function displayDetailedTokenBreakdown(tokenBreakdown, systemTokens, userTokens) {\n    const sections = [];\n    \n    if (tokenBreakdown.tasks?.length > 0) {\n      const taskDetails = tokenBreakdown.tasks.map(task => \n        `${task.type === 'subtask' ? '  ' : ''}${task.id}: ${task.tokens.toLocaleString()}`\n      ).join('\\n');\n      sections.push(`Tasks (${tokenBreakdown.tasks.reduce((sum, t) => sum + t.tokens, 0).toLocaleString()}):\\n${taskDetails}`);\n    }\n    \n    const content = sections.join('\\n\\n');\n    console.log(boxen(content, {\n      title: chalk.cyan('Token Usage'),\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      borderStyle: 'round',\n      borderColor: 'cyan'\n    }));\n  }\n  ```\n\n### **Code Block Syntax Highlighting**\n- Use `cli-highlight` library for syntax highlighting in terminal output\n- Process code blocks in AI responses for better readability\n\n  ```javascript\n  // ✅ DO: Enhance code blocks with syntax highlighting\n  import { highlight } from 'cli-highlight';\n  \n  function processCodeBlocks(text) {\n    return text.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, language, code) => {\n      try {\n        const highlighted = highlight(code.trim(), { \n          language: language || 'javascript',\n          theme: 'default'\n        });\n        return `\\n${highlighted}\\n`;\n      } catch (error) {\n        return `\\n${code.trim()}\\n`;\n      }\n    });\n  }\n  ```\n\n### **Multi-Section Result Display**\n- Use separate boxes for headers, content, and metadata\n- Maintain consistent styling across different result types\n\n  ```javascript\n  // ✅ DO: Use structured result display\n  function displayResults(result, query, detailLevel) {\n    // Header with query info\n    const header = boxen(\n      chalk.green.bold('Research Results') + '\\n\\n' +\n      chalk.gray('Query: ') + chalk.white(query) + '\\n' +\n      chalk.gray('Detail Level: ') + chalk.cyan(detailLevel),\n      {\n        padding: { top: 1, bottom: 1, left: 2, right: 2 },\n        margin: { top: 1, bottom: 0 },\n        borderStyle: 'round',\n        borderColor: 'green'\n      }\n    );\n    console.log(header);\n    \n    // Process and display main content\n    const processedResult = processCodeBlocks(result);\n    const contentBox = boxen(processedResult, {\n      padding: { top: 1, bottom: 1, left: 2, right: 2 },\n      margin: { top: 0, bottom: 1 },\n      borderStyle: 'single',\n      borderColor: 'gray'\n    });\n    console.log(contentBox);\n    \n    console.log(chalk.green('✓ Operation complete'));\n  }\n  ```\n\nRefer to [`ui.js`](mdc:scripts/modules/ui.js) for implementation examples, [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for context display patterns, and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines.\n\n<!-- File: .cursor/rules/utilities.mdc (Tokens: ~9975 | Category: cursor-rule) -->\n---\ndescription: \nglobs: \nalwaysApply: false\n---\n# Utility Function Guidelines\n\n## General Principles\n\n- **Function Scope**:\n  - ✅ DO: Create utility functions that serve multiple modules\n  - ✅ DO: Keep functions single-purpose and focused\n  - ❌ DON'T: Include business logic in utility functions\n  - ❌ DON'T: Create utilities with side effects\n\n  ```javascript\n  // ✅ DO: Create focused, reusable utilities\n  /**\n   * Truncates text to a specified length\n   * @param {string} text - The text to truncate\n   * @param {number} maxLength - The maximum length\n   * @returns {string} The truncated text\n   */\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n  ```javascript\n  // ❌ DON'T: Add side effects to utilities\n  function truncate(text, maxLength) {\n    if (!text || text.length <= maxLength) {\n      return text;\n    }\n    \n    // Side effect - modifying global state or logging\n    console.log(`Truncating text from ${text.length} to ${maxLength} chars`);\n    \n    return text.slice(0, maxLength - 3) + '...';\n  }\n  ```\n\n- **Location**:\n    - **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).\n    - **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.\n        - Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils) (e.g., `path-utils.js`).\n        - Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).\n\n## Documentation Standards\n\n- **JSDoc Format**:\n  - ✅ DO: Document all parameters and return values\n  - ✅ DO: Include descriptions for complex logic\n  - ✅ DO: Add examples for non-obvious usage\n  - ❌ DON'T: Skip documentation for \"simple\" functions\n\n  ```javascript\n  // ✅ DO: Provide complete JSDoc documentation\n  /**\n   * Reads and parses a JSON file\n   * @param {string} filepath - Path to the JSON file\n   * @returns {Object|null} Parsed JSON data or null if error occurs\n   */\n  function readJSON(filepath) {\n    try {\n      const rawData = fs.readFileSync(filepath, 'utf8');\n      return JSON.parse(rawData);\n    } catch (error) {\n      log('error', `Error reading JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n      return null;\n    }\n  }\n  ```\n\n## Configuration Management (via `config-manager.js`)\n\nTaskmaster configuration (excluding API keys) is primarily managed through the `.taskmasterconfig` file located in the project root and accessed via getters in [`scripts/modules/config-manager.js`](mdc:scripts/modules/config-manager.js).\n\n- **`.taskmasterconfig` File**:\n  - ✅ DO: Use this JSON file to store settings like AI model selections (main, research, fallback), parameters (temperature, maxTokens), logging level, default priority/subtasks, etc.\n  - ✅ DO: Manage this file using the `task-master models --setup` CLI command or the `models` MCP tool.\n  - ✅ DO: Rely on [`config-manager.js`](mdc:scripts/modules/config-manager.js) to load this file (using the correct project root passed from MCP or found via CLI utils), merge with defaults, and provide validated settings.\n  - ❌ DON'T: Store API keys in this file.\n  - ❌ DON'T: Manually edit this file unless necessary.\n\n- **Configuration Getters (`config-manager.js`)**:\n  - ✅ DO: Import and use specific getters from `config-manager.js` (e.g., `getMainProvider()`, `getLogLevel()`, `getMainMaxTokens()`) to access configuration values *needed for application logic* (like `getDefaultSubtasks`).\n  - ✅ DO: Pass the `explicitRoot` parameter to getters if calling from MCP direct functions to ensure the correct project's config is loaded.\n  - ❌ DON'T: Call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions (`scripts/modules/task-manager/*`). Instead, pass the `role` to the unified AI service.\n  - ❌ DON'T: Access configuration values directly from environment variables (except API keys).\n\n- **API Key Handling (`utils.js` & `ai-services-unified.js`)**:\n  - ✅ DO: Store API keys **only** in `.env` (for CLI, loaded by `dotenv` in `scripts/dev.js`) or `.cursor/mcp.json` (for MCP, accessed via `session.env`).\n  - ✅ DO: Use `isApiKeySet(providerName, session)` from `config-manager.js` to check if a provider's key is available *before* potentially attempting an AI call if needed, but note the unified service performs its own internal check.\n  - ✅ DO: Understand that the unified service layer (`ai-services-unified.js`) internally resolves API keys using `resolveEnvVariable(key, session)` from `utils.js`.\n\n- **Error Handling**:\n  - ✅ DO: Handle potential `ConfigurationError` if the `.taskmasterconfig` file is missing or invalid when accessed via `getConfig` (e.g., in `commands.js` or direct functions).\n\n## Logging Utilities (in `scripts/modules/utils.js`)\n\n- **Log Levels**:\n  - ✅ DO: Support multiple log levels (debug, info, warn, error)\n  - ✅ DO: Use appropriate icons for different log levels\n  - ✅ DO: Respect the configured log level\n  - ❌ DON'T: Add direct console.log calls outside the logging utility\n  - **Note on Passed Loggers**: When a logger object (like the FastMCP `log` object) is passed *as a parameter* (e.g., as `mcpLog`) into core Task Master functions, the receiving function often expects specific methods (`.info`, `.warn`, `.error`, etc.) to be directly callable on that object (e.g., `mcpLog[level](mdc:...)`). If the passed logger doesn't have this exact structure, a wrapper object may be needed. See the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for the standard pattern used in direct functions.\n\n- **Logger Wrapper Pattern**: \n  - ✅ DO: Use the logger wrapper pattern when passing loggers to prevent `mcpLog[level] is not a function` errors:\n  ```javascript\n  // Standard logWrapper pattern to wrap FastMCP's log object\n  const logWrapper = {\n    info: (message, ...args) => log.info(message, ...args),\n    warn: (message, ...args) => log.warn(message, ...args),\n    error: (message, ...args) => log.error(message, ...args),\n    debug: (message, ...args) => log.debug && log.debug(message, ...args),\n    success: (message, ...args) => log.info(message, ...args) // Map success to info\n  };\n  \n  // Pass this wrapper as mcpLog to ensure consistent method availability\n  // This also ensures output format is set to 'json' in many core functions\n  const options = { mcpLog: logWrapper, session };\n  ```\n  - ✅ DO: Implement this pattern in any direct function that calls core functions expecting `mcpLog`\n  - ✅ DO: Use this solution in conjunction with silent mode for complete output control\n  - ❌ DON'T: Pass the FastMCP `log` object directly as `mcpLog` to core functions\n  - **Important**: This pattern has successfully fixed multiple issues in MCP tools (e.g., `update-task`, `update-subtask`) where using or omitting `mcpLog` incorrectly led to runtime errors or JSON parsing failures.\n  - For complete implementation details, see the **Handling Logging Context (`mcpLog`)** section in [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc).\n\n  ```javascript\n  // ✅ DO: Implement a proper logging utility\n  const LOG_LEVELS = {\n    debug: 0,\n    info: 1,\n    warn: 2,\n    error: 3\n  };\n  \n  function log(level, ...args) {\n    const icons = {\n      debug: chalk.gray('🔍'),\n      info: chalk.blue('ℹ️'),\n      warn: chalk.yellow('⚠️'),\n      error: chalk.red('❌'),\n      success: chalk.green('✅')\n    };\n    \n    if (LOG_LEVELS[level] >= LOG_LEVELS[CONFIG.logLevel]) {\n      const icon = icons[level] || '';\n      console.log(`${icon} ${args.join(' ')}`);\n    }\n  }\n  ```\n\n## Silent Mode Utilities (in `scripts/modules/utils.js`)\n\n- **Silent Mode Control**:\n  - ✅ DO: Use the exported silent mode functions rather than accessing global variables\n  - ✅ DO: Always use `isSilentMode()` to check the current silent mode state\n  - ✅ DO: Ensure silent mode is disabled in a `finally` block to prevent it from staying enabled\n  - ❌ DON'T: Access the global `silentMode` variable directly\n  - ❌ DON'T: Forget to disable silent mode after enabling it\n\n  ```javascript\n  // ✅ DO: Use the silent mode control functions properly\n  \n  // Example of proper implementation in utils.js:\n  \n  // Global silent mode flag (private to the module)\n  let silentMode = false;\n  \n  // Enable silent mode\n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  // Disable silent mode\n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  // Check if silent mode is enabled\n  function isSilentMode() {\n    return silentMode;\n  }\n  \n  // Example of proper usage in another module:\n  import { enableSilentMode, disableSilentMode, isSilentMode } from './utils.js';\n  \n  // Check current status\n  if (!isSilentMode()) {\n    console.log('Silent mode is not enabled');\n  }\n  \n  // Use try/finally pattern to ensure silent mode is disabled\n  try {\n    enableSilentMode();\n    // Do something that should suppress console output\n    performOperation();\n  } finally {\n    disableSilentMode();\n  }\n  ```\n\n- **Integration with Logging**:\n  - ✅ DO: Make the `log` function respect silent mode\n  ```javascript\n  function log(level, ...args) {\n    // Skip logging if silent mode is enabled\n    if (isSilentMode()) {\n      return;\n    }\n    \n    // Rest of logging logic...\n  }\n  ```\n\n- **Common Patterns for Silent Mode**:\n  - ✅ DO: In **direct functions** (`mcp-server/src/core/direct-functions/*`) that call **core functions** (`scripts/modules/*`), ensure console output from the core function is suppressed to avoid breaking MCP JSON responses.\n    - **Preferred Method**: Update the core function to accept an `outputFormat` parameter (e.g., `outputFormat = 'text'`) and make it check `outputFormat === 'text'` before displaying any UI elements (banners, spinners, boxes, direct `console.log`s). Pass `'json'` from the direct function.\n    - **Necessary Fallback/Guarantee**: If the core function *cannot* be modified or its output suppression via `outputFormat` is unreliable, **wrap the core function call within the direct function** using `enableSilentMode()` and `disableSilentMode()` in a `try/finally` block. This acts as a safety net.\n  ```javascript\n  // Example in a direct function\n  export async function someOperationDirect(args, log) {\n    let result;\n    const tasksPath = findTasksJsonPath(args, log); // Get path first\n    \n    // Option 1: Core function handles 'json' format (Preferred)\n    try {\n      result = await coreFunction(tasksPath, ...otherArgs, 'json'); // Pass 'json'\n      return { success: true, data: result, fromCache: false };\n    } catch (error) {\n      // Handle error...\n    }\n\n    // Option 2: Core function output unreliable (Fallback/Guarantee)\n    try {\n      enableSilentMode(); // Enable before call\n      result = await coreFunction(tasksPath, ...otherArgs); // Call without format param\n    } catch (error) {\n      // Handle error...\n      log.error(`Failed: ${error.message}`);\n      return { success: false, error: { /* ... */ } };\n    } finally {\n      disableSilentMode(); // ALWAYS disable in finally\n    }\n    return { success: true, data: result, fromCache: false }; // Assuming success if no error caught\n  }\n  ```\n  - ✅ DO: For functions that accept a silent mode parameter but also need to check global state (less common):\n  ```javascript\n  // Check both the passed parameter and global silent mode\n  const isSilent = options.silentMode || (typeof options.silentMode === 'undefined' && isSilentMode());\n  ```\n\n## File Operations (in `scripts/modules/utils.js`)\n\n- **Error Handling**:\n  - ✅ DO: Use try/catch blocks for all file operations\n  - ✅ DO: Return null or a default value on failure\n  - ✅ DO: Log detailed error information using the `log` utility\n  - ❌ DON'T: Allow exceptions to propagate unhandled from simple file reads/writes\n\n  ```javascript\n  // ✅ DO: Handle file operation errors properly in core utils\n  function writeJSON(filepath, data) {\n    try {\n      // Ensure directory exists (example)\n      const dir = path.dirname(filepath);\n      if (!fs.existsSync(dir)) {\n        fs.mkdirSync(dir, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Error writing JSON file ${filepath}:`, error.message);\n      if (CONFIG.debug) {\n        console.error(error);\n      }\n    }\n  }\n  ```\n\n## Task-Specific Utilities (in `scripts/modules/utils.js`)\n\n- **Task ID Formatting**:\n  - ✅ DO: Create utilities for consistent ID handling\n  - ✅ DO: Support different ID formats (numeric, string, dot notation)\n  - ❌ DON'T: Duplicate formatting logic across modules\n\n  ```javascript\n  // ✅ DO: Create utilities for common operations\n  /**\n   * Formats a task ID as a string\n   * @param {string|number} id - The task ID to format\n   * @returns {string} The formatted task ID\n   */\n  function formatTaskId(id) {\n    if (typeof id === 'string' && id.includes('.')) {\n      return id; // Already formatted as a string with a dot (e.g., \"1.2\")\n    }\n    \n    if (typeof id === 'number') {\n      return id.toString();\n    }\n    \n    return id;\n  }\n  ```\n\n- **Task Search**:\n  - ✅ DO: Implement reusable task finding utilities\n  - ✅ DO: Support both task and subtask lookups\n  - ✅ DO: Add context to subtask results\n\n  ```javascript\n  // ✅ DO: Create comprehensive search utilities\n  /**\n   * Finds a task by ID in the tasks array\n   * @param {Array} tasks - The tasks array\n   * @param {string|number} taskId - The task ID to find\n   * @returns {Object|null} The task object or null if not found\n   */\n  function findTaskById(tasks, taskId) {\n    if (!taskId || !tasks || !Array.isArray(tasks)) {\n      return null;\n    }\n    \n    // Check if it's a subtask ID (e.g., \"1.2\")\n    if (typeof taskId === 'string' && taskId.includes('.')) {\n      const [parentId, subtaskId] = taskId.split('.').map(id => parseInt(id, 10));\n      const parentTask = tasks.find(t => t.id === parentId);\n      \n      if (!parentTask || !parentTask.subtasks) {\n        return null;\n      }\n      \n      const subtask = parentTask.subtasks.find(st => st.id === subtaskId);\n      if (subtask) {\n        // Add reference to parent task for context\n        subtask.parentTask = { \n          id: parentTask.id, \n          title: parentTask.title,\n          status: parentTask.status\n        };\n        subtask.isSubtask = true;\n      }\n      \n      return subtask || null;\n    }\n    \n    const id = parseInt(taskId, 10);\n    return tasks.find(t => t.id === id) || null;\n  }\n  ```\n\n## Cycle Detection (in `scripts/modules/utils.js`)\n\n- **Graph Algorithms**:\n  - ✅ DO: Implement cycle detection using graph traversal\n  - ✅ DO: Track visited nodes and recursion stack\n  - ✅ DO: Return specific information about cycles\n\n  ```javascript\n  // ✅ DO: Implement proper cycle detection\n  /**\n   * Find cycles in a dependency graph using DFS\n   * @param {string} subtaskId - Current subtask ID\n   * @param {Map} dependencyMap - Map of subtask IDs to their dependencies\n   * @param {Set} visited - Set of visited nodes\n   * @param {Set} recursionStack - Set of nodes in current recursion stack\n   * @returns {Array} - List of dependency edges that need to be removed to break cycles\n   */\n  function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set(), path = []) {\n    // Mark the current node as visited and part of recursion stack\n    visited.add(subtaskId);\n    recursionStack.add(subtaskId);\n    path.push(subtaskId);\n    \n    const cyclesToBreak = [];\n    \n    // Get all dependencies of the current subtask\n    const dependencies = dependencyMap.get(subtaskId) || [];\n    \n    // For each dependency\n    for (const depId of dependencies) {\n      // If not visited, recursively check for cycles\n      if (!visited.has(depId)) {\n        const cycles = findCycles(depId, dependencyMap, visited, recursionStack, [...path]);\n        cyclesToBreak.push(...cycles);\n      } \n      // If the dependency is in the recursion stack, we found a cycle\n      else if (recursionStack.has(depId)) {\n        // The last edge in the cycle is what we want to remove\n        cyclesToBreak.push(depId);\n      }\n    }\n    \n    // Remove the node from recursion stack before returning\n    recursionStack.delete(subtaskId);\n    \n    return cyclesToBreak;\n  }\n  ```\n\n## MCP Server Core Utilities (`mcp-server/src/core/utils/`)\n\n### Project Root and Task File Path Detection (`path-utils.js`)\n\n- **Purpose**: This module ([`mcp-server/src/core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) provides the mechanism for locating the user's `tasks.json` file, used by direct functions.\n- **`findTasksJsonPath(args, log)`**:\n    - ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.\n    - Pass the *entire `args` object* received by the MCP tool (which should include `projectRoot` derived from the session) and the `log` object.\n    - Implements a **simplified precedence system** for finding the `tasks.json` path:\n        1.  Explicit `projectRoot` passed in `args` (Expected from MCP tools).\n        2.  Cached `lastFoundProjectRoot` (CLI fallback).\n        3.  Search upwards from `process.cwd()` (CLI fallback).\n    - Throws a specific error if the `tasks.json` file cannot be located.\n    - Updates the `lastFoundProjectRoot` cache on success.\n- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the CLI fallback search.\n- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself (potentially removable).\n\n## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)\n\nThese utilities specifically support the implementation and execution of MCP tools.\n\n- **`normalizeProjectRoot(rawPath, log)`**:\n    - **Purpose**: Takes a raw project root path (potentially URI encoded, with `file://` prefix, Windows slashes) and returns a normalized, absolute path suitable for the server's OS.\n    - **Logic**: Decodes URI, strips `file://`, handles Windows drive prefix (`/C:/`), replaces `\\` with `/`, uses `path.resolve()`.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF.\n\n- **`getRawProjectRootFromSession(session, log)`**:\n    - **Purpose**: Extracts the *raw* project root URI string from the session object (`session.roots[0].uri` or `session.roots.roots[0].uri`) without performing normalization.\n    - **Usage**: Used internally by `withNormalizedProjectRoot` HOF as a fallback if `args.projectRoot` isn't provided.\n\n- **`withNormalizedProjectRoot(executeFn)`**:\n    - **Purpose**: A Higher-Order Function (HOF) designed to wrap a tool's `execute` method.\n    - **Logic**: \n        1. Determines the raw project root (from `args.projectRoot` or `getRawProjectRootFromSession`).\n        2. Normalizes the raw path using `normalizeProjectRoot`.\n        3. Injects the normalized, absolute path back into the `args` object as `args.projectRoot`.\n        4. Calls the original `executeFn` with the updated `args`.\n    - **Usage**: Should wrap the `execute` function of *every* MCP tool that needs a reliable, normalized project root path.\n    - **Example**:\n      ```javascript\n      // In mcp-server/src/tools/your-tool.js\n      import { withNormalizedProjectRoot } from './utils.js';\n      \n      export function registerYourTool(server) {\n          server.addTool({\n              // ... name, description, parameters ...\n              execute: withNormalizedProjectRoot(async (args, context) => {\n                  // args.projectRoot is now normalized here\n                  const { projectRoot /*, other args */ } = args;\n                  // ... rest of tool logic using normalized projectRoot ...\n              })\n          });\n      }\n      ```\n\n- **`handleApiResult(result, log, errorPrefix, processFunction)`**:\n    - **Purpose**: Standardizes the formatting of responses returned by direct functions (`{ success, data/error, fromCache }`) into the MCP response format.\n    - **Usage**: Call this at the end of the tool's `execute` method, passing the result from the direct function call.\n\n- **`createContentResponse(content)` / `createErrorResponse(errorMessage)`**:\n    - **Purpose**: Helper functions to create the basic MCP response structure for success or error messages.\n    - **Usage**: Used internally by `handleApiResult` and potentially directly for simple responses.\n\n- **`createLogWrapper(log)`**:\n    - **Purpose**: Creates a logger object wrapper with standard methods (`info`, `warn`, `error`, `debug`, `success`) mapping to the passed MCP `log` object's methods. Ensures compatibility when passing loggers to core functions.\n    - **Usage**: Used within direct functions before passing the `log` object down to core logic that expects the standard method names.\n\n- **`getCachedOrExecute({ cacheKey, actionFn, log })`**:\n    - **Purpose**: Utility for implementing caching within direct functions. Checks cache for `cacheKey`; if miss, executes `actionFn`, caches successful result, and returns.\n    - **Usage**: Wrap the core logic execution within a direct function call.\n\n- **`processMCPResponseData(taskOrData, fieldsToRemove)`**:\n    - **Purpose**: Utility to filter potentially sensitive or large fields (like `details`, `testStrategy`) from task objects before sending the response back via MCP.\n    - **Usage**: Passed as the default `processFunction` to `handleApiResult`.\n\n- **`getProjectRootFromSession(session, log)`**:\n    - **Purpose**: Legacy function to extract *and normalize* the project root from the session. Replaced by the HOF pattern but potentially still used.\n    - **Recommendation**: Prefer using the `withNormalizedProjectRoot` HOF in tools instead of calling this directly.\n\n- **`executeTaskMasterCommand(...)`**: \n    - **Purpose**: Executes `task-master` CLI command as a fallback. \n    - **Recommendation**: Deprecated for most uses; prefer direct function calls.\n\n## Export Organization\n\n- **Grouping Related Functions**:\n  - ✅ DO: Keep utilities relevant to their location (e.g., core CLI utils in `scripts/modules/utils.js`, MCP path utils in `mcp-server/src/core/utils/path-utils.js`, MCP tool utils in `mcp-server/src/tools/utils.js`).\n  - ✅ DO: Export all utility functions in a single statement per file.\n  - ✅ DO: Group related exports together.\n  - ✅ DO: Export configuration constants (from `scripts/modules/utils.js`).\n  - ❌ DON'T: Use default exports.\n  - ❌ DON'T: Create circular dependencies (See [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)).\n\n```javascript\n// Example export from scripts/modules/utils.js\nexport {\n  // Configuration\n  CONFIG,\n  LOG_LEVELS,\n  \n  // Logging\n  log,\n  \n  // File operations\n  readJSON,\n  writeJSON,\n  \n  // String manipulation\n  sanitizePrompt,\n  truncate,\n  \n  // Task utilities\n  // ... (taskExists, formatTaskId, findTaskById, etc.)\n  \n  // Graph algorithms\n  findCycles,\n};\n\n// Example export from mcp-server/src/core/utils/path-utils.js\nexport {\n  findTasksJsonPath,\n  getPackagePath,\n  PROJECT_MARKERS,\n  lastFoundProjectRoot // Exporting for potential direct use/reset if needed\n};\n\n// Example export from mcp-server/src/tools/utils.js\nexport {\n  getProjectRoot,\n  getProjectRootFromSession,\n  handleApiResult,\n  executeTaskMasterCommand,\n  processMCPResponseData,\n  createContentResponse,\n  createErrorResponse,\n  getCachedOrExecute\n};\n```\n\n## Context Gathering Utilities\n\n### **ContextGatherer** (`scripts/modules/utils/contextGatherer.js`)\n\n- **Multi-Source Context Extraction**:\n  - ✅ DO: Use for AI-powered commands that need project context\n  - ✅ DO: Support tasks, files, custom text, and project tree context\n  - ✅ DO: Implement detailed token counting with `gpt-tokens` library\n  - ✅ DO: Provide multiple output formats (research, chat, system-prompt)\n\n  ```javascript\n  // ✅ DO: Use ContextGatherer for consistent context extraction\n  import { ContextGatherer } from '../utils/contextGatherer.js';\n  \n  const gatherer = new ContextGatherer(projectRoot, tasksPath);\n  const result = await gatherer.gather({\n    tasks: ['15', '16.2'],\n    files: ['src/api.js'],\n    customContext: 'Additional context',\n    includeProjectTree: true,\n    format: 'research',\n    includeTokenCounts: true\n  });\n  ```\n\n### **FuzzyTaskSearch** (`scripts/modules/utils/fuzzyTaskSearch.js`)\n\n- **Intelligent Task Discovery**:\n  - ✅ DO: Use for automatic task relevance detection\n  - ✅ DO: Configure search parameters based on use case context\n  - ✅ DO: Implement purpose-based categorization for better matching\n  - ✅ DO: Sort results by relevance score and task ID\n\n  ```javascript\n  // ✅ DO: Use FuzzyTaskSearch for intelligent task discovery\n  import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';\n  \n  const fuzzySearch = new FuzzyTaskSearch(tasksData.tasks, 'research');\n  const searchResults = fuzzySearch.findRelevantTasks(query, {\n    maxResults: 8,\n    includeRecent: true,\n    includeCategoryMatches: true\n  });\n  const taskIds = fuzzySearch.getTaskIds(searchResults);\n  ```\n\n- **Integration Guidelines**:\n  - ✅ DO: Use fuzzy search to supplement user-provided task IDs\n  - ✅ DO: Display discovered task IDs to users for transparency\n  - ✅ DO: Sort discovered task IDs numerically for better readability\n  - ❌ DON'T: Replace explicit user task selections with fuzzy results\n\nRefer to [`context_gathering.mdc`](mdc:.cursor/rules/context_gathering.mdc) for detailed implementation patterns, [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for more context on MCP server architecture and integration. \n\n## File System Operations\n\n- **JSON File Handling**:\n  - ✅ DO: Use `readJSON` and `writeJSON` for all JSON operations\n  - ✅ DO: Include error handling for file operations\n  - ✅ DO: Validate JSON structure after reading\n  - ❌ DON'T: Use raw `fs.readFileSync` or `fs.writeFileSync` for JSON\n\n  ```javascript\n  // ✅ DO: Use utility functions with error handling\n  function readJSON(filepath) {\n    try {\n      if (!fs.existsSync(filepath)) {\n        return null; // or appropriate default\n      }\n      \n      let data = JSON.parse(fs.readFileSync(filepath, 'utf8'));\n      \n      // Silent migration for tasks.json files: Transform old format to tagged format\n      const isTasksFile = filepath.includes('tasks.json') || path.basename(filepath) === 'tasks.json';\n      \n      if (data && data.tasks && Array.isArray(data.tasks) && !data.master && isTasksFile) {\n        // Migrate from old format { \"tasks\": [...] } to new format { \"master\": { \"tasks\": [...] } }\n        const migratedData = {\n          master: {\n            tasks: data.tasks\n          }\n        };\n        \n        writeJSON(filepath, migratedData);\n        \n        // Set global flag for CLI notice and perform complete migration\n        global.taskMasterMigrationOccurred = true;\n        performCompleteTagMigration(filepath);\n        \n        data = migratedData;\n      }\n      \n      return data;\n    } catch (error) {\n      log('error', `Failed to read JSON from ${filepath}: ${error.message}`);\n      return null;\n    }\n  }\n  \n  function writeJSON(filepath, data) {\n    try {\n      const dirPath = path.dirname(filepath);\n      if (!fs.existsSync(dirPath)) {\n        fs.mkdirSync(dirPath, { recursive: true });\n      }\n      fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n    } catch (error) {\n      log('error', `Failed to write JSON to ${filepath}: ${error.message}`);\n      throw error;\n    }\n  }\n  ```\n\n- **Path Resolution**:\n  - ✅ DO: Use `path.join()` for cross-platform path construction\n  - ✅ DO: Use `path.resolve()` for absolute paths\n  - ✅ DO: Validate paths before file operations\n\n  ```javascript\n  // ✅ DO: Handle paths correctly\n  function findProjectRoot(startPath = process.cwd()) {\n    let currentPath = path.resolve(startPath);\n    const rootPath = path.parse(currentPath).root;\n    \n    while (currentPath !== rootPath) {\n      const taskMasterPath = path.join(currentPath, '.taskmaster');\n      if (fs.existsSync(taskMasterPath)) {\n        return currentPath;\n      }\n      currentPath = path.dirname(currentPath);\n    }\n    \n    return null; // Not found\n  }\n  ```\n\n## Tagged Task Lists System Utilities\n\n- **Tag Resolution Functions**:\n  - ✅ DO: Use tag resolution layer for all task data access\n  - ✅ DO: Provide backward compatibility with legacy format\n  - ✅ DO: Default to \"master\" tag when no tag is specified\n\n  ```javascript\n  // ✅ DO: Implement tag resolution functions\n  function getTasksForTag(data, tagName = 'master') {\n    if (!data) {\n      return [];\n    }\n    \n    // Handle legacy format - direct tasks array\n    if (data.tasks && Array.isArray(data.tasks)) {\n      return data.tasks;\n    }\n    \n    // Handle tagged format - tasks under specific tag\n    if (data[tagName] && data[tagName].tasks && Array.isArray(data[tagName].tasks)) {\n      return data[tagName].tasks;\n    }\n    \n    return [];\n  }\n  \n  function setTasksForTag(data, tagName = 'master', tasks) {\n    // Ensure data object exists\n    if (!data) {\n      data = {};\n    }\n    \n    // Create tag structure if it doesn't exist\n    if (!data[tagName]) {\n      data[tagName] = {};\n    }\n    \n    // Set tasks for the tag\n    data[tagName].tasks = tasks;\n    \n    return data;\n  }\n  \n  function getCurrentTag() {\n    // Get current tag from state.json or default to 'master'\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return 'master';\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (fs.existsSync(statePath)) {\n        const state = readJSON(statePath);\n        return state.currentTag || 'master';\n      }\n    } catch (error) {\n      log('debug', `Error reading current tag: ${error.message}`);\n    }\n    \n    return 'master';\n  }\n  ```\n\n- **Migration Functions**:\n  - ✅ DO: Implement complete migration for all related files\n  - ✅ DO: Handle configuration and state file creation\n  - ✅ DO: Provide migration status tracking\n\n  ```javascript\n  // ✅ DO: Implement complete migration system\n  function performCompleteTagMigration(tasksJsonPath) {\n    try {\n      // Derive project root from tasks.json path\n      const projectRoot = findProjectRoot(path.dirname(tasksJsonPath)) || path.dirname(tasksJsonPath);\n      \n      // 1. Migrate config.json - add defaultTag and tags section\n      const configPath = path.join(projectRoot, '.taskmaster', 'config.json');\n      if (fs.existsSync(configPath)) {\n        migrateConfigJson(configPath);\n      }\n      \n      // 2. Create state.json if it doesn't exist\n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      if (!fs.existsSync(statePath)) {\n        createStateJson(statePath);\n      }\n      \n      if (getDebugFlag()) {\n        log('debug', 'Completed tagged task lists migration for project');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error during complete tag migration: ${error.message}`);\n      }\n    }\n  }\n  \n  function migrateConfigJson(configPath) {\n    try {\n      const config = readJSON(configPath);\n      if (!config) return;\n      \n      let modified = false;\n      \n      // Add global.defaultTag if missing\n      if (!config.global) {\n        config.global = {};\n      }\n      if (!config.global.defaultTag) {\n        config.global.defaultTag = 'master';\n        modified = true;\n      }\n      \n      // Add tags section if missing\n      if (!config.tags) {\n        config.tags = {\n                  // Git integration settings removed - now manual only\n        };\n        modified = true;\n      }\n      \n      if (modified) {\n        writeJSON(configPath, config);\n        if (getDebugFlag()) {\n          log('debug', 'Updated config.json with tagged task system settings');\n        }\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error migrating config.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function createStateJson(statePath) {\n    try {\n      const initialState = {\n        currentTag: 'master',\n        lastSwitched: new Date().toISOString(),\n        migrationNoticeShown: false\n      };\n      \n      writeJSON(statePath, initialState);\n      if (getDebugFlag()) {\n        log('debug', 'Created initial state.json for tagged task system');\n      }\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error creating state.json: ${error.message}`);\n      }\n    }\n  }\n  \n  function markMigrationForNotice() {\n    try {\n      const projectRoot = findProjectRoot();\n      if (!projectRoot) return;\n      \n      const statePath = path.join(projectRoot, '.taskmaster', 'state.json');\n      const state = readJSON(statePath) || {};\n      \n      state.migrationNoticeShown = false; // Reset to show notice\n      writeJSON(statePath, state);\n    } catch (error) {\n      if (getDebugFlag()) {\n        log('warn', `Error marking migration for notice: ${error.message}`);\n      }\n    }\n  }\n  ```\n\n## Logging Functions\n\n- **Consistent Logging**:\n  - ✅ DO: Use the central `log` function for all output\n  - ✅ DO: Use appropriate log levels (info, warn, error, debug)\n  - ✅ DO: Support silent mode for programmatic usage\n\n  ```javascript\n  // ✅ DO: Implement consistent logging with silent mode\n  let silentMode = false;\n  \n  function log(level, ...messages) {\n    if (silentMode && level !== 'error') {\n      return; // Suppress non-error logs in silent mode\n    }\n    \n    const timestamp = new Date().toISOString();\n    const formattedMessage = messages.join(' ');\n    \n    switch (level) {\n      case 'error':\n        console.error(`[ERROR] ${formattedMessage}`);\n        break;\n      case 'warn':\n        console.warn(`[WARN] ${formattedMessage}`);\n        break;\n      case 'info':\n        console.log(`[INFO] ${formattedMessage}`);\n        break;\n      case 'debug':\n        if (getDebugFlag()) {\n          console.log(`[DEBUG] ${formattedMessage}`);\n        }\n        break;\n      default:\n        console.log(formattedMessage);\n    }\n  }\n  \n  function enableSilentMode() {\n    silentMode = true;\n  }\n  \n  function disableSilentMode() {\n    silentMode = false;\n  }\n  \n  function isSilentMode() {\n    return silentMode;\n  }\n  ```\n\n## Task Utilities\n\n- **Task Finding and Manipulation**:\n  - ✅ DO: Use tagged task system aware functions\n  - ✅ DO: Handle both task and subtask operations\n  - ✅ DO: Validate task IDs before operations\n\n  ```javascript\n  // ✅ DO: Implement tag-aware task utilities\n  function findTaskById(tasks, taskId) {\n    if (!Array.isArray(tasks)) {\n      return null;\n    }\n    return tasks.find(task => task.id === taskId) || null;\n  }\n  \n  function findSubtaskById(tasks, parentId, subtaskId) {\n    const parentTask = findTaskById(tasks, parentId);\n    if (!parentTask || !parentTask.subtasks) {\n      return null;\n    }\n    \n    return parentTask.subtasks.find(subtask => subtask.id === subtaskId) || null;\n  }\n  \n  function getNextTaskId(tasks) {\n    if (!Array.isArray(tasks) || tasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...tasks.map(task => task.id));\n    return maxId + 1;\n  }\n  \n  function getNextSubtaskId(parentTask) {\n    if (!parentTask.subtasks || parentTask.subtasks.length === 0) {\n      return 1;\n    }\n    \n    const maxId = Math.max(...parentTask.subtasks.map(subtask => subtask.id));\n    return maxId + 1;\n  }\n  ```\n\n## String Utilities\n\n- **Text Processing**:\n  - ✅ DO: Handle text truncation appropriately\n  - ✅ DO: Provide consistent formatting functions\n  - ✅ DO: Support different output formats\n\n  ```javascript\n  // ✅ DO: Implement useful string utilities\n  function truncate(str, maxLength = 50) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    if (str.length <= maxLength) {\n      return str;\n    }\n    \n    return str.substring(0, maxLength - 3) + '...';\n  }\n  \n  function formatDuration(ms) {\n    const seconds = Math.floor(ms / 1000);\n    const minutes = Math.floor(seconds / 60);\n    const hours = Math.floor(minutes / 60);\n    \n    if (hours > 0) {\n      return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n    } else if (minutes > 0) {\n      return `${minutes}m ${seconds % 60}s`;\n    } else {\n      return `${seconds}s`;\n    }\n  }\n  \n  function capitalizeFirst(str) {\n    if (!str || typeof str !== 'string') {\n      return '';\n    }\n    \n    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n  }\n  ```\n\n## Dependency Management Utilities\n\n- **Dependency Analysis**:\n  - ✅ DO: Detect circular dependencies\n  - ✅ DO: Validate dependency references\n  - ✅ DO: Support cross-tag dependency checking (future enhancement)\n\n  ```javascript\n  // ✅ DO: Implement dependency utilities\n  function findCycles(tasks) {\n    const cycles = [];\n    const visited = new Set();\n    const recStack = new Set();\n    \n    function dfs(taskId, path = []) {\n      if (recStack.has(taskId)) {\n        // Found a cycle\n        const cycleStart = path.indexOf(taskId);\n        const cycle = path.slice(cycleStart).concat([taskId]);\n        cycles.push(cycle);\n        return;\n      }\n      \n      if (visited.has(taskId)) {\n        return;\n      }\n      \n      visited.add(taskId);\n      recStack.add(taskId);\n      \n      const task = findTaskById(tasks, taskId);\n      if (task && task.dependencies) {\n        task.dependencies.forEach(depId => {\n          dfs(depId, path.concat([taskId]));\n        });\n      }\n      \n      recStack.delete(taskId);\n    }\n    \n    tasks.forEach(task => {\n      if (!visited.has(task.id)) {\n        dfs(task.id);\n      }\n    });\n    \n    return cycles;\n  }\n  \n  function validateDependencies(tasks) {\n    const validationErrors = [];\n    const taskIds = new Set(tasks.map(task => task.id));\n    \n    tasks.forEach(task => {\n      if (task.dependencies) {\n        task.dependencies.forEach(depId => {\n          if (!taskIds.has(depId)) {\n            validationErrors.push({\n              taskId: task.id,\n              invalidDependency: depId,\n              message: `Task ${task.id} depends on non-existent task ${depId}`\n            });\n          }\n        });\n      }\n    });\n    \n    return validationErrors;\n  }\n  ```\n\n## Environment and Configuration Utilities\n\n- **Environment Variable Resolution**:\n  - ✅ DO: Support both `.env` files and MCP session environment\n  - ✅ DO: Provide fallbacks for missing values\n  - ✅ DO: Handle API key resolution correctly\n\n  ```javascript\n  // ✅ DO: Implement flexible environment resolution\n  function resolveEnvVariable(key, sessionEnv = null) {\n    // First check session environment (for MCP)\n    if (sessionEnv && sessionEnv[key]) {\n      return sessionEnv[key];\n    }\n    \n    // Then check process environment\n    if (process.env[key]) {\n      return process.env[key];\n    }\n    \n    // Finally try .env file if in project root\n    try {\n      const projectRoot = findProjectRoot();\n      if (projectRoot) {\n        const envPath = path.join(projectRoot, '.env');\n        if (fs.existsSync(envPath)) {\n          const envContent = fs.readFileSync(envPath, 'utf8');\n          const lines = envContent.split('\\n');\n          \n          for (const line of lines) {\n            const [envKey, envValue] = line.split('=');\n            if (envKey && envKey.trim() === key) {\n              return envValue ? envValue.trim().replace(/^[\"']|[\"']$/g, '') : undefined;\n            }\n          }\n        }\n      }\n    } catch (error) {\n      log('debug', `Error reading .env file: ${error.message}`);\n    }\n    \n    return undefined;\n  }\n  \n  function getDebugFlag() {\n    const debugFlag = resolveEnvVariable('TASKMASTER_DEBUG') || \n                     resolveEnvVariable('DEBUG') || \n                     'false';\n    return debugFlag.toLowerCase() === 'true';\n  }\n  ```\n\n## Export Pattern\n\n- **Module Exports**:\n  - ✅ DO: Export all utility functions explicitly\n  - ✅ DO: Group related functions logically\n  - ✅ DO: Include new tagged system utilities\n\n  ```javascript\n  // ✅ DO: Export utilities in logical groups\n  module.exports = {\n    // File system utilities\n    readJSON,\n    writeJSON,\n    findProjectRoot,\n    \n    // Tagged task system utilities\n    getTasksForTag,\n    setTasksForTag,\n    getCurrentTag,\n    performCompleteTagMigration,\n    migrateConfigJson,\n    createStateJson,\n    markMigrationForNotice,\n    \n    // Logging utilities\n    log,\n    enableSilentMode,\n    disableSilentMode,\n    isSilentMode,\n    \n    // Task utilities\n    findTaskById,\n    findSubtaskById,\n    getNextTaskId,\n    getNextSubtaskId,\n    \n    // String utilities\n    truncate,\n    formatDuration,\n    capitalizeFirst,\n    \n    // Dependency utilities\n    findCycles,\n    validateDependencies,\n    \n    // Environment utilities\n    resolveEnvVariable,\n    getDebugFlag,\n    \n    // Legacy utilities (maintained for compatibility)\n    aggregateTelemetry\n  };\n  ```\n\nRefer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc) for integration patterns.\n\n<!-- File: packages/tm-core/docs/listTasks-architecture.md (Tokens: ~1369 | Category: anthropic-skill) -->\n# ListTasks Architecture - End-to-End POC\n\n## Current Implementation Structure\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                         CLI Layer                            │\n│  scripts/modules/task-manager/list-tasks.js                 │\n│  - Complex UI rendering (tables, progress bars)             │\n│  - Multiple output formats (json, text, markdown, compact)  │\n│  - Status filtering and statistics                          │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              │ Currently reads directly\n                              │ from files (needs integration)\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                      tm-core Package                         │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            TaskMasterCore (Facade)                   │   │\n│  │  src/task-master-core.ts                            │   │\n│  │                                                      │   │\n│  │  - listTasks(options)                               │   │\n│  │    • tag filtering                                  │   │\n│  │    • status filtering                               │   │\n│  │    • include/exclude subtasks                       │   │\n│  │  - getTask(id)                                      │   │\n│  │  - getTasksByStatus(status)                         │   │\n│  │  - getTaskStats()                                   │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                              │                               │\n│                              ▼                               │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │              Storage Layer (IStorage)                │   │\n│  │                                                      │   │\n│  │  ┌──────────────┐        ┌──────────────┐          │   │\n│  │  │ FileStorage  │        │ ApiStorage   │          │   │\n│  │  │              │        │ (Hamster)    │          │   │\n│  │  └──────────────┘        └──────────────┘          │   │\n│  │                                                      │   │\n│  │  StorageFactory.create() selects based on config    │   │\n│  └─────────────────────────────────────────────────────┘   │\n│                                                              │\n│  ┌─────────────────────────────────────────────────────┐   │\n│  │            Domain Layer (Entities)                   │   │\n│  │                                                      │   │\n│  │  TaskEntity                                         │   │\n│  │  - Business logic                                   │   │\n│  │  - Validation                                       │   │\n│  │  - Status transitions                               │   │\n│  └─────────────────────────────────────────────────────┘   │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## ListTasks Data Flow\n\n### 1. CLI Request\n```javascript\n// Current CLI (needs update to use tm-core)\nlistTasks(tasksPath, statusFilter, reportPath, withSubtasks, outputFormat, context)\n```\n\n### 2. TaskMasterCore Processing\n```typescript\n// Our new implementation\nconst tmCore = createTaskMasterCore(projectPath, { \n  storage: { \n    type: 'api',  // or 'file'\n    apiEndpoint: 'https://tryhamster.com',\n    apiAccessToken: 'xxx'\n  }\n});\n\nconst result = await tmCore.listTasks({\n  tag: 'feature-branch',\n  filter: {\n    status: ['pending', 'in-progress'],\n    priority: 'high',\n    search: 'authentication'\n  },\n  includeSubtasks: true\n});\n```\n\n### 3. Storage Selection\n```typescript\n// StorageFactory automatically selects storage\nconst storage = StorageFactory.create(config, projectPath);\n// Returns either FileStorage or ApiStorage based on config\n```\n\n### 4. Data Loading\n```typescript\n// FileStorage\n- Reads from .taskmaster/tasks/tasks.json (or tag-specific file)\n- Local file system operations\n\n// ApiStorage (Hamster)\n- Makes HTTP requests to Hamster API\n- Uses access token from config\n- Handles retries and rate limiting\n```\n\n### 5. Entity Processing\n```typescript\n// Convert raw data to TaskEntity for business logic\nconst taskEntities = TaskEntity.fromArray(rawTasks);\n\n// Apply filters\nconst filtered = applyFilters(taskEntities, filter);\n\n// Convert back to plain objects\nconst tasks = filtered.map(entity => entity.toJSON());\n```\n\n### 6. Response Structure\n```typescript\ninterface ListTasksResult {\n  tasks: Task[];        // Filtered tasks\n  total: number;        // Total task count\n  filtered: number;     // Filtered task count  \n  tag?: string;         // Tag context if applicable\n}\n```\n\n## Integration Points Needed\n\n### 1. CLI Integration\n- [ ] Update `scripts/modules/task-manager/list-tasks.js` to use tm-core\n- [ ] Map CLI options to TaskMasterCore options\n- [ ] Handle output formatting in CLI layer\n\n### 2. Configuration Loading\n- [ ] Load `.taskmaster/config.json` for storage settings\n- [ ] Support environment variables for API tokens\n- [ ] Handle storage type selection\n\n### 3. Testing Requirements\n- [x] Unit tests for TaskEntity\n- [x] Unit tests for BaseProvider\n- [x] Integration tests for listTasks with FileStorage\n- [ ] Integration tests for listTasks with ApiStorage (mock API)\n- [ ] E2E tests with real Hamster API (optional)\n\n## Benefits of This Architecture\n\n1. **Storage Abstraction**: Switch between file and API storage without changing business logic\n2. **Clean Separation**: UI (CLI) separate from business logic (tm-core)\n3. **Testability**: Each layer can be tested independently\n4. **Extensibility**: Easy to add new storage types (database, cloud, etc.)\n5. **Type Safety**: Full TypeScript support throughout\n6. **Error Handling**: Consistent error handling with TaskMasterError\n\n## Next Steps\n\n1. Create a simple CLI wrapper that uses tm-core\n2. Test with file storage (existing functionality)\n3. Test with mock API storage\n4. Integrate with actual Hamster API when available\n5. Migrate other commands (addTask, updateTask, etc.) following same pattern\n\n<!-- File: .claude/commands/dedupe.md (Tokens: ~442 | Category: command-prompt) -->\n---\nallowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)\ndescription: Find duplicate GitHub issues\n---\n\nFind up to 3 likely duplicate issues for a given GitHub issue.\n\nTo do this, follow these steps precisely:\n\n1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.\n2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue\n3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1\n4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.\n5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)\n\nNotes (be sure to tell this to your agents, too):\n\n- Use `gh` to interact with Github, rather than web fetch\n- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)\n- Make a todo list first\n- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):\n\n---\n\nFound 3 possible duplicate issues:\n\n1. <link to issue>\n2. <link to issue>\n3. <link to issue>\n\nThis issue will be automatically closed as a duplicate in 3 days.\n\n- If your issue is a duplicate, please close it and 👍 the existing issue instead\n- To prevent auto-closure, add a comment or 👎 this comment\n\n🤖 Generated with \\[Task Master Bot\\]\n\n---\n\n<!-- ... +11 more modular skills available via /api/skills/eyaltoledano/claude-task-master?path={path} -->\n</yakaai_skills>"}