#
tokens: 47653/50000 15/975 files (page 21/69)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 21 of 69. Use http://codebase.md/eyaltoledano/claude-task-master?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── README.md
├── .claude
│   ├── commands
│   │   └── dedupe.md
│   └── TM_COMMANDS_GUIDE.md
├── .claude-plugin
│   └── marketplace.json
├── .coderabbit.yaml
├── .cursor
│   ├── mcp.json
│   └── rules
│       ├── ai_providers.mdc
│       ├── ai_services.mdc
│       ├── architecture.mdc
│       ├── changeset.mdc
│       ├── commands.mdc
│       ├── context_gathering.mdc
│       ├── cursor_rules.mdc
│       ├── dependencies.mdc
│       ├── dev_workflow.mdc
│       ├── git_workflow.mdc
│       ├── glossary.mdc
│       ├── mcp.mdc
│       ├── new_features.mdc
│       ├── self_improve.mdc
│       ├── tags.mdc
│       ├── taskmaster.mdc
│       ├── tasks.mdc
│       ├── telemetry.mdc
│       ├── test_workflow.mdc
│       ├── tests.mdc
│       ├── ui.mdc
│       └── utilities.mdc
├── .cursorignore
├── .env.example
├── .github
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   ├── enhancements---feature-requests.md
│   │   └── feedback.md
│   ├── PULL_REQUEST_TEMPLATE
│   │   ├── bugfix.md
│   │   ├── config.yml
│   │   ├── feature.md
│   │   └── integration.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── scripts
│   │   ├── auto-close-duplicates.mjs
│   │   ├── backfill-duplicate-comments.mjs
│   │   ├── check-pre-release-mode.mjs
│   │   ├── parse-metrics.mjs
│   │   ├── release.mjs
│   │   ├── tag-extension.mjs
│   │   ├── utils.mjs
│   │   └── validate-changesets.mjs
│   └── workflows
│       ├── auto-close-duplicates.yml
│       ├── backfill-duplicate-comments.yml
│       ├── ci.yml
│       ├── claude-dedupe-issues.yml
│       ├── claude-docs-trigger.yml
│       ├── claude-docs-updater.yml
│       ├── claude-issue-triage.yml
│       ├── claude.yml
│       ├── extension-ci.yml
│       ├── extension-release.yml
│       ├── log-issue-events.yml
│       ├── pre-release.yml
│       ├── release-check.yml
│       ├── release.yml
│       ├── update-models-md.yml
│       └── weekly-metrics-discord.yml
├── .gitignore
├── .kiro
│   ├── hooks
│   │   ├── tm-code-change-task-tracker.kiro.hook
│   │   ├── tm-complexity-analyzer.kiro.hook
│   │   ├── tm-daily-standup-assistant.kiro.hook
│   │   ├── tm-git-commit-task-linker.kiro.hook
│   │   ├── tm-pr-readiness-checker.kiro.hook
│   │   ├── tm-task-dependency-auto-progression.kiro.hook
│   │   └── tm-test-success-task-completer.kiro.hook
│   ├── settings
│   │   └── mcp.json
│   └── steering
│       ├── dev_workflow.md
│       ├── kiro_rules.md
│       ├── self_improve.md
│       ├── taskmaster_hooks_workflow.md
│       └── taskmaster.md
├── .manypkg.json
├── .mcp.json
├── .npmignore
├── .nvmrc
├── .taskmaster
│   ├── CLAUDE.md
│   ├── config.json
│   ├── docs
│   │   ├── autonomous-tdd-git-workflow.md
│   │   ├── MIGRATION-ROADMAP.md
│   │   ├── prd-tm-start.txt
│   │   ├── prd.txt
│   │   ├── README.md
│   │   ├── research
│   │   │   ├── 2025-06-14_how-can-i-improve-the-scope-up-and-scope-down-comm.md
│   │   │   ├── 2025-06-14_should-i-be-using-any-specific-libraries-for-this.md
│   │   │   ├── 2025-06-14_test-save-functionality.md
│   │   │   ├── 2025-06-14_test-the-fix-for-duplicate-saves-final-test.md
│   │   │   └── 2025-08-01_do-we-need-to-add-new-commands-or-can-we-just-weap.md
│   │   ├── task-template-importing-prd.txt
│   │   ├── tdd-workflow-phase-0-spike.md
│   │   ├── tdd-workflow-phase-1-core-rails.md
│   │   ├── tdd-workflow-phase-1-orchestrator.md
│   │   ├── tdd-workflow-phase-2-pr-resumability.md
│   │   ├── tdd-workflow-phase-3-extensibility-guardrails.md
│   │   ├── test-prd.txt
│   │   └── tm-core-phase-1.txt
│   ├── reports
│   │   ├── task-complexity-report_autonomous-tdd-git-workflow.json
│   │   ├── task-complexity-report_cc-kiro-hooks.json
│   │   ├── task-complexity-report_tdd-phase-1-core-rails.json
│   │   ├── task-complexity-report_tdd-workflow-phase-0.json
│   │   ├── task-complexity-report_test-prd-tag.json
│   │   ├── task-complexity-report_tm-core-phase-1.json
│   │   ├── task-complexity-report.json
│   │   └── tm-core-complexity.json
│   ├── state.json
│   ├── tasks
│   │   ├── task_001_tm-start.txt
│   │   ├── task_002_tm-start.txt
│   │   ├── task_003_tm-start.txt
│   │   ├── task_004_tm-start.txt
│   │   ├── task_007_tm-start.txt
│   │   └── tasks.json
│   └── templates
│       ├── example_prd_rpg.md
│       └── example_prd.md
├── .vscode
│   ├── extensions.json
│   └── settings.json
├── apps
│   ├── cli
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── command-registry.ts
│   │   │   ├── commands
│   │   │   │   ├── auth.command.ts
│   │   │   │   ├── autopilot
│   │   │   │   │   ├── abort.command.ts
│   │   │   │   │   ├── commit.command.ts
│   │   │   │   │   ├── complete.command.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── next.command.ts
│   │   │   │   │   ├── resume.command.ts
│   │   │   │   │   ├── shared.ts
│   │   │   │   │   ├── start.command.ts
│   │   │   │   │   └── status.command.ts
│   │   │   │   ├── briefs.command.ts
│   │   │   │   ├── context.command.ts
│   │   │   │   ├── export.command.ts
│   │   │   │   ├── list.command.ts
│   │   │   │   ├── models
│   │   │   │   │   ├── custom-providers.ts
│   │   │   │   │   ├── fetchers.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── prompts.ts
│   │   │   │   │   ├── setup.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── next.command.ts
│   │   │   │   ├── set-status.command.ts
│   │   │   │   ├── show.command.ts
│   │   │   │   ├── start.command.ts
│   │   │   │   └── tags.command.ts
│   │   │   ├── index.ts
│   │   │   ├── lib
│   │   │   │   └── model-management.ts
│   │   │   ├── types
│   │   │   │   └── tag-management.d.ts
│   │   │   ├── ui
│   │   │   │   ├── components
│   │   │   │   │   ├── cardBox.component.ts
│   │   │   │   │   ├── dashboard.component.ts
│   │   │   │   │   ├── header.component.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── next-task.component.ts
│   │   │   │   │   ├── suggested-steps.component.ts
│   │   │   │   │   └── task-detail.component.ts
│   │   │   │   ├── display
│   │   │   │   │   ├── messages.ts
│   │   │   │   │   └── tables.ts
│   │   │   │   ├── formatters
│   │   │   │   │   ├── complexity-formatters.ts
│   │   │   │   │   ├── dependency-formatters.ts
│   │   │   │   │   ├── priority-formatters.ts
│   │   │   │   │   ├── status-formatters.spec.ts
│   │   │   │   │   └── status-formatters.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── layout
│   │   │   │       ├── helpers.spec.ts
│   │   │   │       └── helpers.ts
│   │   │   └── utils
│   │   │       ├── auth-helpers.ts
│   │   │       ├── auto-update.ts
│   │   │       ├── brief-selection.ts
│   │   │       ├── display-helpers.ts
│   │   │       ├── error-handler.ts
│   │   │       ├── index.ts
│   │   │       ├── project-root.ts
│   │   │       ├── task-status.ts
│   │   │       ├── ui.spec.ts
│   │   │       └── ui.ts
│   │   ├── tests
│   │   │   ├── integration
│   │   │   │   └── commands
│   │   │   │       └── autopilot
│   │   │   │           └── workflow.test.ts
│   │   │   └── unit
│   │   │       ├── commands
│   │   │       │   ├── autopilot
│   │   │       │   │   └── shared.test.ts
│   │   │       │   ├── list.command.spec.ts
│   │   │       │   └── show.command.spec.ts
│   │   │       └── ui
│   │   │           └── dashboard.component.spec.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.ts
│   ├── docs
│   │   ├── archive
│   │   │   ├── ai-client-utils-example.mdx
│   │   │   ├── ai-development-workflow.mdx
│   │   │   ├── command-reference.mdx
│   │   │   ├── configuration.mdx
│   │   │   ├── cursor-setup.mdx
│   │   │   ├── examples.mdx
│   │   │   └── Installation.mdx
│   │   ├── best-practices
│   │   │   ├── advanced-tasks.mdx
│   │   │   ├── configuration-advanced.mdx
│   │   │   └── index.mdx
│   │   ├── capabilities
│   │   │   ├── cli-root-commands.mdx
│   │   │   ├── index.mdx
│   │   │   ├── mcp.mdx
│   │   │   ├── rpg-method.mdx
│   │   │   └── task-structure.mdx
│   │   ├── CHANGELOG.md
│   │   ├── command-reference.mdx
│   │   ├── configuration.mdx
│   │   ├── docs.json
│   │   ├── favicon.svg
│   │   ├── getting-started
│   │   │   ├── api-keys.mdx
│   │   │   ├── contribute.mdx
│   │   │   ├── faq.mdx
│   │   │   └── quick-start
│   │   │       ├── configuration-quick.mdx
│   │   │       ├── execute-quick.mdx
│   │   │       ├── installation.mdx
│   │   │       ├── moving-forward.mdx
│   │   │       ├── prd-quick.mdx
│   │   │       ├── quick-start.mdx
│   │   │       ├── requirements.mdx
│   │   │       ├── rules-quick.mdx
│   │   │       └── tasks-quick.mdx
│   │   ├── introduction.mdx
│   │   ├── licensing.md
│   │   ├── logo
│   │   │   ├── dark.svg
│   │   │   ├── light.svg
│   │   │   └── task-master-logo.png
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── style.css
│   │   ├── tdd-workflow
│   │   │   ├── ai-agent-integration.mdx
│   │   │   └── quickstart.mdx
│   │   ├── vercel.json
│   │   └── whats-new.mdx
│   ├── extension
│   │   ├── .vscodeignore
│   │   ├── assets
│   │   │   ├── banner.png
│   │   │   ├── icon-dark.svg
│   │   │   ├── icon-light.svg
│   │   │   ├── icon.png
│   │   │   ├── screenshots
│   │   │   │   ├── kanban-board.png
│   │   │   │   └── task-details.png
│   │   │   └── sidebar-icon.svg
│   │   ├── CHANGELOG.md
│   │   ├── components.json
│   │   ├── docs
│   │   │   ├── extension-CI-setup.md
│   │   │   └── extension-development-guide.md
│   │   ├── esbuild.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── package.mjs
│   │   ├── package.publish.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── components
│   │   │   │   ├── ConfigView.tsx
│   │   │   │   ├── constants.ts
│   │   │   │   ├── TaskDetails
│   │   │   │   │   ├── AIActionsSection.tsx
│   │   │   │   │   ├── DetailsSection.tsx
│   │   │   │   │   ├── PriorityBadge.tsx
│   │   │   │   │   ├── SubtasksSection.tsx
│   │   │   │   │   ├── TaskMetadataSidebar.tsx
│   │   │   │   │   └── useTaskDetails.ts
│   │   │   │   ├── TaskDetailsView.tsx
│   │   │   │   ├── TaskMasterLogo.tsx
│   │   │   │   └── ui
│   │   │   │       ├── badge.tsx
│   │   │   │       ├── breadcrumb.tsx
│   │   │   │       ├── button.tsx
│   │   │   │       ├── card.tsx
│   │   │   │       ├── collapsible.tsx
│   │   │   │       ├── CollapsibleSection.tsx
│   │   │   │       ├── dropdown-menu.tsx
│   │   │   │       ├── label.tsx
│   │   │   │       ├── scroll-area.tsx
│   │   │   │       ├── separator.tsx
│   │   │   │       ├── shadcn-io
│   │   │   │       │   └── kanban
│   │   │   │       │       └── index.tsx
│   │   │   │       └── textarea.tsx
│   │   │   ├── extension.ts
│   │   │   ├── index.ts
│   │   │   ├── lib
│   │   │   │   └── utils.ts
│   │   │   ├── services
│   │   │   │   ├── config-service.ts
│   │   │   │   ├── error-handler.ts
│   │   │   │   ├── notification-preferences.ts
│   │   │   │   ├── polling-service.ts
│   │   │   │   ├── polling-strategies.ts
│   │   │   │   ├── sidebar-webview-manager.ts
│   │   │   │   ├── task-repository.ts
│   │   │   │   ├── terminal-manager.ts
│   │   │   │   └── webview-manager.ts
│   │   │   ├── test
│   │   │   │   └── extension.test.ts
│   │   │   ├── utils
│   │   │   │   ├── configManager.ts
│   │   │   │   ├── connectionManager.ts
│   │   │   │   ├── errorHandler.ts
│   │   │   │   ├── event-emitter.ts
│   │   │   │   ├── logger.ts
│   │   │   │   ├── mcpClient.ts
│   │   │   │   ├── notificationPreferences.ts
│   │   │   │   └── task-master-api
│   │   │   │       ├── cache
│   │   │   │       │   └── cache-manager.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── mcp-client.ts
│   │   │   │       ├── transformers
│   │   │   │       │   └── task-transformer.ts
│   │   │   │       └── types
│   │   │   │           └── index.ts
│   │   │   └── webview
│   │   │       ├── App.tsx
│   │   │       ├── components
│   │   │       │   ├── AppContent.tsx
│   │   │       │   ├── EmptyState.tsx
│   │   │       │   ├── ErrorBoundary.tsx
│   │   │       │   ├── PollingStatus.tsx
│   │   │       │   ├── PriorityBadge.tsx
│   │   │       │   ├── SidebarView.tsx
│   │   │       │   ├── TagDropdown.tsx
│   │   │       │   ├── TaskCard.tsx
│   │   │       │   ├── TaskEditModal.tsx
│   │   │       │   ├── TaskMasterKanban.tsx
│   │   │       │   ├── ToastContainer.tsx
│   │   │       │   └── ToastNotification.tsx
│   │   │       ├── constants
│   │   │       │   └── index.ts
│   │   │       ├── contexts
│   │   │       │   └── VSCodeContext.tsx
│   │   │       ├── hooks
│   │   │       │   ├── useTaskQueries.ts
│   │   │       │   ├── useVSCodeMessages.ts
│   │   │       │   └── useWebviewHeight.ts
│   │   │       ├── index.css
│   │   │       ├── index.tsx
│   │   │       ├── providers
│   │   │       │   └── QueryProvider.tsx
│   │   │       ├── reducers
│   │   │       │   └── appReducer.ts
│   │   │       ├── sidebar.tsx
│   │   │       ├── types
│   │   │       │   └── index.ts
│   │   │       └── utils
│   │   │           ├── logger.ts
│   │   │           └── toast.ts
│   │   └── tsconfig.json
│   └── mcp
│       ├── CHANGELOG.md
│       ├── package.json
│       ├── src
│       │   ├── index.ts
│       │   ├── shared
│       │   │   ├── types.ts
│       │   │   └── utils.ts
│       │   └── tools
│       │       ├── autopilot
│       │       │   ├── abort.tool.ts
│       │       │   ├── commit.tool.ts
│       │       │   ├── complete.tool.ts
│       │       │   ├── finalize.tool.ts
│       │       │   ├── index.ts
│       │       │   ├── next.tool.ts
│       │       │   ├── resume.tool.ts
│       │       │   ├── start.tool.ts
│       │       │   └── status.tool.ts
│       │       ├── README-ZOD-V3.md
│       │       └── tasks
│       │           ├── get-task.tool.ts
│       │           ├── get-tasks.tool.ts
│       │           └── index.ts
│       ├── tsconfig.json
│       └── vitest.config.ts
├── assets
│   ├── .windsurfrules
│   ├── AGENTS.md
│   ├── claude
│   │   └── TM_COMMANDS_GUIDE.md
│   ├── config.json
│   ├── env.example
│   ├── example_prd_rpg.txt
│   ├── example_prd.txt
│   ├── GEMINI.md
│   ├── gitignore
│   ├── kiro-hooks
│   │   ├── tm-code-change-task-tracker.kiro.hook
│   │   ├── tm-complexity-analyzer.kiro.hook
│   │   ├── tm-daily-standup-assistant.kiro.hook
│   │   ├── tm-git-commit-task-linker.kiro.hook
│   │   ├── tm-pr-readiness-checker.kiro.hook
│   │   ├── tm-task-dependency-auto-progression.kiro.hook
│   │   └── tm-test-success-task-completer.kiro.hook
│   ├── roocode
│   │   ├── .roo
│   │   │   ├── rules-architect
│   │   │   │   └── architect-rules
│   │   │   ├── rules-ask
│   │   │   │   └── ask-rules
│   │   │   ├── rules-code
│   │   │   │   └── code-rules
│   │   │   ├── rules-debug
│   │   │   │   └── debug-rules
│   │   │   ├── rules-orchestrator
│   │   │   │   └── orchestrator-rules
│   │   │   └── rules-test
│   │   │       └── test-rules
│   │   └── .roomodes
│   ├── rules
│   │   ├── cursor_rules.mdc
│   │   ├── dev_workflow.mdc
│   │   ├── self_improve.mdc
│   │   ├── taskmaster_hooks_workflow.mdc
│   │   └── taskmaster.mdc
│   └── scripts_README.md
├── bin
│   └── task-master.js
├── biome.json
├── CHANGELOG.md
├── CLAUDE_CODE_PLUGIN.md
├── CLAUDE.md
├── context
│   ├── chats
│   │   ├── add-task-dependencies-1.md
│   │   └── max-min-tokens.txt.md
│   ├── fastmcp-core.txt
│   ├── fastmcp-docs.txt
│   ├── MCP_INTEGRATION.md
│   ├── mcp-js-sdk-docs.txt
│   ├── mcp-protocol-repo.txt
│   ├── mcp-protocol-schema-03262025.json
│   └── mcp-protocol-spec.txt
├── CONTRIBUTING.md
├── docs
│   ├── claude-code-integration.md
│   ├── CLI-COMMANDER-PATTERN.md
│   ├── command-reference.md
│   ├── configuration.md
│   ├── contributor-docs
│   │   ├── testing-roo-integration.md
│   │   └── worktree-setup.md
│   ├── cross-tag-task-movement.md
│   ├── examples
│   │   ├── claude-code-usage.md
│   │   └── codex-cli-usage.md
│   ├── examples.md
│   ├── licensing.md
│   ├── mcp-provider-guide.md
│   ├── mcp-provider.md
│   ├── migration-guide.md
│   ├── models.md
│   ├── providers
│   │   ├── codex-cli.md
│   │   └── gemini-cli.md
│   ├── README.md
│   ├── scripts
│   │   └── models-json-to-markdown.js
│   ├── task-structure.md
│   └── tutorial.md
├── images
│   ├── hamster-hiring.png
│   └── logo.png
├── index.js
├── jest.config.js
├── jest.resolver.cjs
├── LICENSE
├── llms-install.md
├── mcp-server
│   ├── server.js
│   └── src
│       ├── core
│       │   ├── __tests__
│       │   │   └── context-manager.test.js
│       │   ├── context-manager.js
│       │   ├── direct-functions
│       │   │   ├── add-dependency.js
│       │   │   ├── add-subtask.js
│       │   │   ├── add-tag.js
│       │   │   ├── add-task.js
│       │   │   ├── analyze-task-complexity.js
│       │   │   ├── cache-stats.js
│       │   │   ├── clear-subtasks.js
│       │   │   ├── complexity-report.js
│       │   │   ├── copy-tag.js
│       │   │   ├── create-tag-from-branch.js
│       │   │   ├── delete-tag.js
│       │   │   ├── expand-all-tasks.js
│       │   │   ├── expand-task.js
│       │   │   ├── fix-dependencies.js
│       │   │   ├── generate-task-files.js
│       │   │   ├── initialize-project.js
│       │   │   ├── list-tags.js
│       │   │   ├── models.js
│       │   │   ├── move-task-cross-tag.js
│       │   │   ├── move-task.js
│       │   │   ├── next-task.js
│       │   │   ├── parse-prd.js
│       │   │   ├── remove-dependency.js
│       │   │   ├── remove-subtask.js
│       │   │   ├── remove-task.js
│       │   │   ├── rename-tag.js
│       │   │   ├── research.js
│       │   │   ├── response-language.js
│       │   │   ├── rules.js
│       │   │   ├── scope-down.js
│       │   │   ├── scope-up.js
│       │   │   ├── set-task-status.js
│       │   │   ├── update-subtask-by-id.js
│       │   │   ├── update-task-by-id.js
│       │   │   ├── update-tasks.js
│       │   │   ├── use-tag.js
│       │   │   └── validate-dependencies.js
│       │   ├── task-master-core.js
│       │   └── utils
│       │       ├── env-utils.js
│       │       └── path-utils.js
│       ├── custom-sdk
│       │   ├── errors.js
│       │   ├── index.js
│       │   ├── json-extractor.js
│       │   ├── language-model.js
│       │   ├── message-converter.js
│       │   └── schema-converter.js
│       ├── index.js
│       ├── logger.js
│       ├── providers
│       │   └── mcp-provider.js
│       └── tools
│           ├── add-dependency.js
│           ├── add-subtask.js
│           ├── add-tag.js
│           ├── add-task.js
│           ├── analyze.js
│           ├── clear-subtasks.js
│           ├── complexity-report.js
│           ├── copy-tag.js
│           ├── delete-tag.js
│           ├── expand-all.js
│           ├── expand-task.js
│           ├── fix-dependencies.js
│           ├── generate.js
│           ├── get-operation-status.js
│           ├── index.js
│           ├── initialize-project.js
│           ├── list-tags.js
│           ├── models.js
│           ├── move-task.js
│           ├── next-task.js
│           ├── parse-prd.js
│           ├── README-ZOD-V3.md
│           ├── remove-dependency.js
│           ├── remove-subtask.js
│           ├── remove-task.js
│           ├── rename-tag.js
│           ├── research.js
│           ├── response-language.js
│           ├── rules.js
│           ├── scope-down.js
│           ├── scope-up.js
│           ├── set-task-status.js
│           ├── tool-registry.js
│           ├── update-subtask.js
│           ├── update-task.js
│           ├── update.js
│           ├── use-tag.js
│           ├── utils.js
│           └── validate-dependencies.js
├── mcp-test.js
├── output.json
├── package-lock.json
├── package.json
├── packages
│   ├── ai-sdk-provider-grok-cli
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── errors.test.ts
│   │   │   ├── errors.ts
│   │   │   ├── grok-cli-language-model.ts
│   │   │   ├── grok-cli-provider.test.ts
│   │   │   ├── grok-cli-provider.ts
│   │   │   ├── index.ts
│   │   │   ├── json-extractor.test.ts
│   │   │   ├── json-extractor.ts
│   │   │   ├── message-converter.test.ts
│   │   │   ├── message-converter.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── build-config
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── src
│   │   │   └── tsdown.base.ts
│   │   └── tsconfig.json
│   ├── claude-code-plugin
│   │   ├── .claude-plugin
│   │   │   └── plugin.json
│   │   ├── .gitignore
│   │   ├── agents
│   │   │   ├── task-checker.md
│   │   │   ├── task-executor.md
│   │   │   └── task-orchestrator.md
│   │   ├── CHANGELOG.md
│   │   ├── commands
│   │   │   ├── add-dependency.md
│   │   │   ├── add-subtask.md
│   │   │   ├── add-task.md
│   │   │   ├── analyze-complexity.md
│   │   │   ├── analyze-project.md
│   │   │   ├── auto-implement-tasks.md
│   │   │   ├── command-pipeline.md
│   │   │   ├── complexity-report.md
│   │   │   ├── convert-task-to-subtask.md
│   │   │   ├── expand-all-tasks.md
│   │   │   ├── expand-task.md
│   │   │   ├── fix-dependencies.md
│   │   │   ├── generate-tasks.md
│   │   │   ├── help.md
│   │   │   ├── init-project-quick.md
│   │   │   ├── init-project.md
│   │   │   ├── install-taskmaster.md
│   │   │   ├── learn.md
│   │   │   ├── list-tasks-by-status.md
│   │   │   ├── list-tasks-with-subtasks.md
│   │   │   ├── list-tasks.md
│   │   │   ├── next-task.md
│   │   │   ├── parse-prd-with-research.md
│   │   │   ├── parse-prd.md
│   │   │   ├── project-status.md
│   │   │   ├── quick-install-taskmaster.md
│   │   │   ├── remove-all-subtasks.md
│   │   │   ├── remove-dependency.md
│   │   │   ├── remove-subtask.md
│   │   │   ├── remove-subtasks.md
│   │   │   ├── remove-task.md
│   │   │   ├── setup-models.md
│   │   │   ├── show-task.md
│   │   │   ├── smart-workflow.md
│   │   │   ├── sync-readme.md
│   │   │   ├── tm-main.md
│   │   │   ├── to-cancelled.md
│   │   │   ├── to-deferred.md
│   │   │   ├── to-done.md
│   │   │   ├── to-in-progress.md
│   │   │   ├── to-pending.md
│   │   │   ├── to-review.md
│   │   │   ├── update-single-task.md
│   │   │   ├── update-task.md
│   │   │   ├── update-tasks-from-id.md
│   │   │   ├── validate-dependencies.md
│   │   │   └── view-models.md
│   │   ├── mcp.json
│   │   └── package.json
│   ├── tm-bridge
│   │   ├── CHANGELOG.md
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── add-tag-bridge.ts
│   │   │   ├── bridge-types.ts
│   │   │   ├── bridge-utils.ts
│   │   │   ├── expand-bridge.ts
│   │   │   ├── index.ts
│   │   │   ├── tags-bridge.ts
│   │   │   ├── update-bridge.ts
│   │   │   └── use-tag-bridge.ts
│   │   └── tsconfig.json
│   └── tm-core
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── docs
│       │   └── listTasks-architecture.md
│       ├── package.json
│       ├── POC-STATUS.md
│       ├── README.md
│       ├── src
│       │   ├── common
│       │   │   ├── constants
│       │   │   │   ├── index.ts
│       │   │   │   ├── paths.ts
│       │   │   │   └── providers.ts
│       │   │   ├── errors
│       │   │   │   ├── index.ts
│       │   │   │   └── task-master-error.ts
│       │   │   ├── interfaces
│       │   │   │   ├── configuration.interface.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── storage.interface.ts
│       │   │   ├── logger
│       │   │   │   ├── factory.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── logger.spec.ts
│       │   │   │   └── logger.ts
│       │   │   ├── mappers
│       │   │   │   ├── TaskMapper.test.ts
│       │   │   │   └── TaskMapper.ts
│       │   │   ├── types
│       │   │   │   ├── database.types.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── legacy.ts
│       │   │   │   └── repository-types.ts
│       │   │   └── utils
│       │   │       ├── git-utils.ts
│       │   │       ├── id-generator.ts
│       │   │       ├── index.ts
│       │   │       ├── path-helpers.ts
│       │   │       ├── path-normalizer.spec.ts
│       │   │       ├── path-normalizer.ts
│       │   │       ├── project-root-finder.spec.ts
│       │   │       ├── project-root-finder.ts
│       │   │       ├── run-id-generator.spec.ts
│       │   │       └── run-id-generator.ts
│       │   ├── index.ts
│       │   ├── modules
│       │   │   ├── ai
│       │   │   │   ├── index.ts
│       │   │   │   ├── interfaces
│       │   │   │   │   └── ai-provider.interface.ts
│       │   │   │   └── providers
│       │   │   │       ├── base-provider.ts
│       │   │   │       └── index.ts
│       │   │   ├── auth
│       │   │   │   ├── auth-domain.spec.ts
│       │   │   │   ├── auth-domain.ts
│       │   │   │   ├── config.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── managers
│       │   │   │   │   ├── auth-manager.spec.ts
│       │   │   │   │   └── auth-manager.ts
│       │   │   │   ├── services
│       │   │   │   │   ├── context-store.ts
│       │   │   │   │   ├── oauth-service.ts
│       │   │   │   │   ├── organization.service.ts
│       │   │   │   │   ├── supabase-session-storage.spec.ts
│       │   │   │   │   └── supabase-session-storage.ts
│       │   │   │   └── types.ts
│       │   │   ├── briefs
│       │   │   │   ├── briefs-domain.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── services
│       │   │   │   │   └── brief-service.ts
│       │   │   │   ├── types.ts
│       │   │   │   └── utils
│       │   │   │       └── url-parser.ts
│       │   │   ├── commands
│       │   │   │   └── index.ts
│       │   │   ├── config
│       │   │   │   ├── config-domain.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── managers
│       │   │   │   │   ├── config-manager.spec.ts
│       │   │   │   │   └── config-manager.ts
│       │   │   │   └── services
│       │   │   │       ├── config-loader.service.spec.ts
│       │   │   │       ├── config-loader.service.ts
│       │   │   │       ├── config-merger.service.spec.ts
│       │   │   │       ├── config-merger.service.ts
│       │   │   │       ├── config-persistence.service.spec.ts
│       │   │   │       ├── config-persistence.service.ts
│       │   │   │       ├── environment-config-provider.service.spec.ts
│       │   │   │       ├── environment-config-provider.service.ts
│       │   │   │       ├── index.ts
│       │   │   │       ├── runtime-state-manager.service.spec.ts
│       │   │   │       └── runtime-state-manager.service.ts
│       │   │   ├── dependencies
│       │   │   │   └── index.ts
│       │   │   ├── execution
│       │   │   │   ├── executors
│       │   │   │   │   ├── base-executor.ts
│       │   │   │   │   ├── claude-executor.ts
│       │   │   │   │   └── executor-factory.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── services
│       │   │   │   │   └── executor-service.ts
│       │   │   │   └── types.ts
│       │   │   ├── git
│       │   │   │   ├── adapters
│       │   │   │   │   ├── git-adapter.test.ts
│       │   │   │   │   └── git-adapter.ts
│       │   │   │   ├── git-domain.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── services
│       │   │   │       ├── branch-name-generator.spec.ts
│       │   │   │       ├── branch-name-generator.ts
│       │   │   │       ├── commit-message-generator.test.ts
│       │   │   │       ├── commit-message-generator.ts
│       │   │   │       ├── scope-detector.test.ts
│       │   │   │       ├── scope-detector.ts
│       │   │   │       ├── template-engine.test.ts
│       │   │   │       └── template-engine.ts
│       │   │   ├── integration
│       │   │   │   ├── clients
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── supabase-client.ts
│       │   │   │   ├── integration-domain.ts
│       │   │   │   └── services
│       │   │   │       ├── export.service.ts
│       │   │   │       ├── task-expansion.service.ts
│       │   │   │       └── task-retrieval.service.ts
│       │   │   ├── reports
│       │   │   │   ├── index.ts
│       │   │   │   ├── managers
│       │   │   │   │   └── complexity-report-manager.ts
│       │   │   │   └── types.ts
│       │   │   ├── storage
│       │   │   │   ├── adapters
│       │   │   │   │   ├── activity-logger.ts
│       │   │   │   │   ├── api-storage.ts
│       │   │   │   │   └── file-storage
│       │   │   │   │       ├── file-operations.ts
│       │   │   │   │       ├── file-storage.ts
│       │   │   │   │       ├── format-handler.ts
│       │   │   │   │       ├── index.ts
│       │   │   │   │       └── path-resolver.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── services
│       │   │   │   │   └── storage-factory.ts
│       │   │   │   └── utils
│       │   │   │       └── api-client.ts
│       │   │   ├── tasks
│       │   │   │   ├── entities
│       │   │   │   │   └── task.entity.ts
│       │   │   │   ├── parser
│       │   │   │   │   └── index.ts
│       │   │   │   ├── repositories
│       │   │   │   │   ├── supabase
│       │   │   │   │   │   ├── dependency-fetcher.ts
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   └── supabase-repository.ts
│       │   │   │   │   └── task-repository.interface.ts
│       │   │   │   ├── services
│       │   │   │   │   ├── preflight-checker.service.ts
│       │   │   │   │   ├── tag.service.ts
│       │   │   │   │   ├── task-execution-service.ts
│       │   │   │   │   ├── task-loader.service.ts
│       │   │   │   │   └── task-service.ts
│       │   │   │   └── tasks-domain.ts
│       │   │   ├── ui
│       │   │   │   └── index.ts
│       │   │   └── workflow
│       │   │       ├── managers
│       │   │       │   ├── workflow-state-manager.spec.ts
│       │   │       │   └── workflow-state-manager.ts
│       │   │       ├── orchestrators
│       │   │       │   ├── workflow-orchestrator.test.ts
│       │   │       │   └── workflow-orchestrator.ts
│       │   │       ├── services
│       │   │       │   ├── test-result-validator.test.ts
│       │   │       │   ├── test-result-validator.ts
│       │   │       │   ├── test-result-validator.types.ts
│       │   │       │   ├── workflow-activity-logger.ts
│       │   │       │   └── workflow.service.ts
│       │   │       ├── types.ts
│       │   │       └── workflow-domain.ts
│       │   ├── subpath-exports.test.ts
│       │   ├── tm-core.ts
│       │   └── utils
│       │       └── time.utils.ts
│       ├── tests
│       │   ├── auth
│       │   │   └── auth-refresh.test.ts
│       │   ├── integration
│       │   │   ├── auth-token-refresh.test.ts
│       │   │   ├── list-tasks.test.ts
│       │   │   └── storage
│       │   │       └── activity-logger.test.ts
│       │   ├── mocks
│       │   │   └── mock-provider.ts
│       │   ├── setup.ts
│       │   └── unit
│       │       ├── base-provider.test.ts
│       │       ├── executor.test.ts
│       │       └── smoke.test.ts
│       ├── tsconfig.json
│       └── vitest.config.ts
├── README-task-master.md
├── README.md
├── scripts
│   ├── create-worktree.sh
│   ├── dev.js
│   ├── init.js
│   ├── list-worktrees.sh
│   ├── modules
│   │   ├── ai-services-unified.js
│   │   ├── bridge-utils.js
│   │   ├── commands.js
│   │   ├── config-manager.js
│   │   ├── dependency-manager.js
│   │   ├── index.js
│   │   ├── prompt-manager.js
│   │   ├── supported-models.json
│   │   ├── sync-readme.js
│   │   ├── task-manager
│   │   │   ├── add-subtask.js
│   │   │   ├── add-task.js
│   │   │   ├── analyze-task-complexity.js
│   │   │   ├── clear-subtasks.js
│   │   │   ├── expand-all-tasks.js
│   │   │   ├── expand-task.js
│   │   │   ├── find-next-task.js
│   │   │   ├── generate-task-files.js
│   │   │   ├── is-task-dependent.js
│   │   │   ├── list-tasks.js
│   │   │   ├── migrate.js
│   │   │   ├── models.js
│   │   │   ├── move-task.js
│   │   │   ├── parse-prd
│   │   │   │   ├── index.js
│   │   │   │   ├── parse-prd-config.js
│   │   │   │   ├── parse-prd-helpers.js
│   │   │   │   ├── parse-prd-non-streaming.js
│   │   │   │   ├── parse-prd-streaming.js
│   │   │   │   └── parse-prd.js
│   │   │   ├── remove-subtask.js
│   │   │   ├── remove-task.js
│   │   │   ├── research.js
│   │   │   ├── response-language.js
│   │   │   ├── scope-adjustment.js
│   │   │   ├── set-task-status.js
│   │   │   ├── tag-management.js
│   │   │   ├── task-exists.js
│   │   │   ├── update-single-task-status.js
│   │   │   ├── update-subtask-by-id.js
│   │   │   ├── update-task-by-id.js
│   │   │   └── update-tasks.js
│   │   ├── task-manager.js
│   │   ├── ui.js
│   │   ├── update-config-tokens.js
│   │   ├── utils
│   │   │   ├── contextGatherer.js
│   │   │   ├── fuzzyTaskSearch.js
│   │   │   └── git-utils.js
│   │   └── utils.js
│   ├── task-complexity-report.json
│   ├── test-claude-errors.js
│   └── test-claude.js
├── sonar-project.properties
├── src
│   ├── ai-providers
│   │   ├── anthropic.js
│   │   ├── azure.js
│   │   ├── base-provider.js
│   │   ├── bedrock.js
│   │   ├── claude-code.js
│   │   ├── codex-cli.js
│   │   ├── gemini-cli.js
│   │   ├── google-vertex.js
│   │   ├── google.js
│   │   ├── grok-cli.js
│   │   ├── groq.js
│   │   ├── index.js
│   │   ├── lmstudio.js
│   │   ├── ollama.js
│   │   ├── openai-compatible.js
│   │   ├── openai.js
│   │   ├── openrouter.js
│   │   ├── perplexity.js
│   │   ├── xai.js
│   │   ├── zai-coding.js
│   │   └── zai.js
│   ├── constants
│   │   ├── commands.js
│   │   ├── paths.js
│   │   ├── profiles.js
│   │   ├── rules-actions.js
│   │   ├── task-priority.js
│   │   └── task-status.js
│   ├── profiles
│   │   ├── amp.js
│   │   ├── base-profile.js
│   │   ├── claude.js
│   │   ├── cline.js
│   │   ├── codex.js
│   │   ├── cursor.js
│   │   ├── gemini.js
│   │   ├── index.js
│   │   ├── kilo.js
│   │   ├── kiro.js
│   │   ├── opencode.js
│   │   ├── roo.js
│   │   ├── trae.js
│   │   ├── vscode.js
│   │   ├── windsurf.js
│   │   └── zed.js
│   ├── progress
│   │   ├── base-progress-tracker.js
│   │   ├── cli-progress-factory.js
│   │   ├── parse-prd-tracker.js
│   │   ├── progress-tracker-builder.js
│   │   └── tracker-ui.js
│   ├── prompts
│   │   ├── add-task.json
│   │   ├── analyze-complexity.json
│   │   ├── expand-task.json
│   │   ├── parse-prd.json
│   │   ├── README.md
│   │   ├── research.json
│   │   ├── schemas
│   │   │   ├── parameter.schema.json
│   │   │   ├── prompt-template.schema.json
│   │   │   ├── README.md
│   │   │   └── variant.schema.json
│   │   ├── update-subtask.json
│   │   ├── update-task.json
│   │   └── update-tasks.json
│   ├── provider-registry
│   │   └── index.js
│   ├── schemas
│   │   ├── add-task.js
│   │   ├── analyze-complexity.js
│   │   ├── base-schemas.js
│   │   ├── expand-task.js
│   │   ├── parse-prd.js
│   │   ├── registry.js
│   │   ├── update-subtask.js
│   │   ├── update-task.js
│   │   └── update-tasks.js
│   ├── task-master.js
│   ├── ui
│   │   ├── confirm.js
│   │   ├── indicators.js
│   │   └── parse-prd.js
│   └── utils
│       ├── asset-resolver.js
│       ├── create-mcp-config.js
│       ├── format.js
│       ├── getVersion.js
│       ├── logger-utils.js
│       ├── manage-gitignore.js
│       ├── path-utils.js
│       ├── profiles.js
│       ├── rule-transformer.js
│       ├── stream-parser.js
│       └── timeout-manager.js
├── test-clean-tags.js
├── test-config-manager.js
├── test-prd.txt
├── test-tag-functions.js
├── test-version-check-full.js
├── test-version-check.js
├── tests
│   ├── e2e
│   │   ├── e2e_helpers.sh
│   │   ├── parse_llm_output.cjs
│   │   ├── run_e2e.sh
│   │   ├── run_fallback_verification.sh
│   │   └── test_llm_analysis.sh
│   ├── fixtures
│   │   ├── .taskmasterconfig
│   │   ├── sample-claude-response.js
│   │   ├── sample-prd.txt
│   │   └── sample-tasks.js
│   ├── helpers
│   │   └── tool-counts.js
│   ├── integration
│   │   ├── claude-code-error-handling.test.js
│   │   ├── claude-code-optional.test.js
│   │   ├── cli
│   │   │   ├── commands.test.js
│   │   │   ├── complex-cross-tag-scenarios.test.js
│   │   │   └── move-cross-tag.test.js
│   │   ├── manage-gitignore.test.js
│   │   ├── mcp-server
│   │   │   └── direct-functions.test.js
│   │   ├── move-task-cross-tag.integration.test.js
│   │   ├── move-task-simple.integration.test.js
│   │   ├── profiles
│   │   │   ├── amp-init-functionality.test.js
│   │   │   ├── claude-init-functionality.test.js
│   │   │   ├── cline-init-functionality.test.js
│   │   │   ├── codex-init-functionality.test.js
│   │   │   ├── cursor-init-functionality.test.js
│   │   │   ├── gemini-init-functionality.test.js
│   │   │   ├── opencode-init-functionality.test.js
│   │   │   ├── roo-files-inclusion.test.js
│   │   │   ├── roo-init-functionality.test.js
│   │   │   ├── rules-files-inclusion.test.js
│   │   │   ├── trae-init-functionality.test.js
│   │   │   ├── vscode-init-functionality.test.js
│   │   │   └── windsurf-init-functionality.test.js
│   │   └── providers
│   │       └── temperature-support.test.js
│   ├── manual
│   │   ├── progress
│   │   │   ├── parse-prd-analysis.js
│   │   │   ├── test-parse-prd.js
│   │   │   └── TESTING_GUIDE.md
│   │   └── prompts
│   │       ├── prompt-test.js
│   │       └── README.md
│   ├── README.md
│   ├── setup.js
│   └── unit
│       ├── ai-providers
│       │   ├── base-provider.test.js
│       │   ├── claude-code.test.js
│       │   ├── codex-cli.test.js
│       │   ├── gemini-cli.test.js
│       │   ├── lmstudio.test.js
│       │   ├── mcp-components.test.js
│       │   ├── openai-compatible.test.js
│       │   ├── openai.test.js
│       │   ├── provider-registry.test.js
│       │   ├── zai-coding.test.js
│       │   ├── zai-provider.test.js
│       │   ├── zai-schema-introspection.test.js
│       │   └── zai.test.js
│       ├── ai-services-unified.test.js
│       ├── commands.test.js
│       ├── config-manager.test.js
│       ├── config-manager.test.mjs
│       ├── dependency-manager.test.js
│       ├── init.test.js
│       ├── initialize-project.test.js
│       ├── kebab-case-validation.test.js
│       ├── manage-gitignore.test.js
│       ├── mcp
│       │   └── tools
│       │       ├── __mocks__
│       │       │   └── move-task.js
│       │       ├── add-task.test.js
│       │       ├── analyze-complexity.test.js
│       │       ├── expand-all.test.js
│       │       ├── get-tasks.test.js
│       │       ├── initialize-project.test.js
│       │       ├── move-task-cross-tag-options.test.js
│       │       ├── move-task-cross-tag.test.js
│       │       ├── remove-task.test.js
│       │       └── tool-registration.test.js
│       ├── mcp-providers
│       │   ├── mcp-components.test.js
│       │   └── mcp-provider.test.js
│       ├── parse-prd.test.js
│       ├── profiles
│       │   ├── amp-integration.test.js
│       │   ├── claude-integration.test.js
│       │   ├── cline-integration.test.js
│       │   ├── codex-integration.test.js
│       │   ├── cursor-integration.test.js
│       │   ├── gemini-integration.test.js
│       │   ├── kilo-integration.test.js
│       │   ├── kiro-integration.test.js
│       │   ├── mcp-config-validation.test.js
│       │   ├── opencode-integration.test.js
│       │   ├── profile-safety-check.test.js
│       │   ├── roo-integration.test.js
│       │   ├── rule-transformer-cline.test.js
│       │   ├── rule-transformer-cursor.test.js
│       │   ├── rule-transformer-gemini.test.js
│       │   ├── rule-transformer-kilo.test.js
│       │   ├── rule-transformer-kiro.test.js
│       │   ├── rule-transformer-opencode.test.js
│       │   ├── rule-transformer-roo.test.js
│       │   ├── rule-transformer-trae.test.js
│       │   ├── rule-transformer-vscode.test.js
│       │   ├── rule-transformer-windsurf.test.js
│       │   ├── rule-transformer-zed.test.js
│       │   ├── rule-transformer.test.js
│       │   ├── selective-profile-removal.test.js
│       │   ├── subdirectory-support.test.js
│       │   ├── trae-integration.test.js
│       │   ├── vscode-integration.test.js
│       │   ├── windsurf-integration.test.js
│       │   └── zed-integration.test.js
│       ├── progress
│       │   └── base-progress-tracker.test.js
│       ├── prompt-manager.test.js
│       ├── prompts
│       │   ├── expand-task-prompt.test.js
│       │   └── prompt-migration.test.js
│       ├── scripts
│       │   └── modules
│       │       ├── commands
│       │       │   ├── move-cross-tag.test.js
│       │       │   └── README.md
│       │       ├── dependency-manager
│       │       │   ├── circular-dependencies.test.js
│       │       │   ├── cross-tag-dependencies.test.js
│       │       │   └── fix-dependencies-command.test.js
│       │       ├── task-manager
│       │       │   ├── add-subtask.test.js
│       │       │   ├── add-task.test.js
│       │       │   ├── analyze-task-complexity.test.js
│       │       │   ├── clear-subtasks.test.js
│       │       │   ├── complexity-report-tag-isolation.test.js
│       │       │   ├── expand-all-tasks.test.js
│       │       │   ├── expand-task.test.js
│       │       │   ├── find-next-task.test.js
│       │       │   ├── generate-task-files.test.js
│       │       │   ├── list-tasks.test.js
│       │       │   ├── models-baseurl.test.js
│       │       │   ├── move-task-cross-tag.test.js
│       │       │   ├── move-task.test.js
│       │       │   ├── parse-prd-schema.test.js
│       │       │   ├── parse-prd.test.js
│       │       │   ├── remove-subtask.test.js
│       │       │   ├── remove-task.test.js
│       │       │   ├── research.test.js
│       │       │   ├── scope-adjustment.test.js
│       │       │   ├── set-task-status.test.js
│       │       │   ├── setup.js
│       │       │   ├── update-single-task-status.test.js
│       │       │   ├── update-subtask-by-id.test.js
│       │       │   ├── update-task-by-id.test.js
│       │       │   └── update-tasks.test.js
│       │       ├── ui
│       │       │   └── cross-tag-error-display.test.js
│       │       └── utils-tag-aware-paths.test.js
│       ├── task-finder.test.js
│       ├── task-manager
│       │   ├── clear-subtasks.test.js
│       │   ├── move-task.test.js
│       │   ├── tag-boundary.test.js
│       │   └── tag-management.test.js
│       ├── task-master.test.js
│       ├── ui
│       │   └── indicators.test.js
│       ├── ui.test.js
│       ├── utils-strip-ansi.test.js
│       └── utils.test.js
├── tsconfig.json
├── tsdown.config.ts
├── turbo.json
└── update-task-migration-plan.md
```

# Files

--------------------------------------------------------------------------------
/mcp-server/src/core/direct-functions/move-task-cross-tag.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * Direct function wrapper for cross-tag task moves
  3 |  */
  4 | 
  5 | import { moveTasksBetweenTags } from '../../../../scripts/modules/task-manager/move-task.js';
  6 | import { findTasksPath } from '../utils/path-utils.js';
  7 | 
  8 | import {
  9 | 	enableSilentMode,
 10 | 	disableSilentMode
 11 | } from '../../../../scripts/modules/utils.js';
 12 | 
 13 | /**
 14 |  * Move tasks between tags
 15 |  * @param {Object} args - Function arguments
 16 |  * @param {string} args.tasksJsonPath - Explicit path to the tasks.json file
 17 |  * @param {string} args.sourceIds - Comma-separated IDs of tasks to move
 18 |  * @param {string} args.sourceTag - Source tag name
 19 |  * @param {string} args.targetTag - Target tag name
 20 |  * @param {boolean} args.withDependencies - Move dependent tasks along with main task
 21 |  * @param {boolean} args.ignoreDependencies - Break cross-tag dependencies during move
 22 |  * @param {string} args.file - Alternative path to the tasks.json file
 23 |  * @param {string} args.projectRoot - Project root directory
 24 |  * @param {Object} log - Logger object
 25 |  * @returns {Promise<{success: boolean, data?: Object, error?: Object}>}
 26 |  */
 27 | export async function moveTaskCrossTagDirect(args, log, context = {}) {
 28 | 	const { session } = context;
 29 | 	const { projectRoot } = args;
 30 | 
 31 | 	log.info(`moveTaskCrossTagDirect called with args: ${JSON.stringify(args)}`);
 32 | 
 33 | 	// Validate required parameters
 34 | 	if (!args.sourceIds) {
 35 | 		return {
 36 | 			success: false,
 37 | 			error: {
 38 | 				message: 'Source IDs are required',
 39 | 				code: 'MISSING_SOURCE_IDS'
 40 | 			}
 41 | 		};
 42 | 	}
 43 | 
 44 | 	if (!args.sourceTag) {
 45 | 		return {
 46 | 			success: false,
 47 | 			error: {
 48 | 				message: 'Source tag is required for cross-tag moves',
 49 | 				code: 'MISSING_SOURCE_TAG'
 50 | 			}
 51 | 		};
 52 | 	}
 53 | 
 54 | 	if (!args.targetTag) {
 55 | 		return {
 56 | 			success: false,
 57 | 			error: {
 58 | 				message: 'Target tag is required for cross-tag moves',
 59 | 				code: 'MISSING_TARGET_TAG'
 60 | 			}
 61 | 		};
 62 | 	}
 63 | 
 64 | 	// Validate that source and target tags are different
 65 | 	if (args.sourceTag === args.targetTag) {
 66 | 		return {
 67 | 			success: false,
 68 | 			error: {
 69 | 				message: `Source and target tags are the same ("${args.sourceTag}")`,
 70 | 				code: 'SAME_SOURCE_TARGET_TAG',
 71 | 				suggestions: [
 72 | 					'Use different tags for cross-tag moves',
 73 | 					'Use within-tag move: task-master move --from=<id> --to=<id> --tag=<tag>',
 74 | 					'Check available tags: task-master tags'
 75 | 				]
 76 | 			}
 77 | 		};
 78 | 	}
 79 | 
 80 | 	try {
 81 | 		// Find tasks.json path if not provided
 82 | 		let tasksPath = args.tasksJsonPath || args.file;
 83 | 		if (!tasksPath) {
 84 | 			if (!args.projectRoot) {
 85 | 				return {
 86 | 					success: false,
 87 | 					error: {
 88 | 						message:
 89 | 							'Project root is required if tasksJsonPath is not provided',
 90 | 						code: 'MISSING_PROJECT_ROOT'
 91 | 					}
 92 | 				};
 93 | 			}
 94 | 			tasksPath = findTasksPath(args, log);
 95 | 		}
 96 | 
 97 | 		// Enable silent mode to prevent console output during MCP operation
 98 | 		enableSilentMode();
 99 | 
100 | 		try {
101 | 			// Parse source IDs
102 | 			const sourceIds = args.sourceIds.split(',').map((id) => id.trim());
103 | 
104 | 			// Prepare move options
105 | 			const moveOptions = {
106 | 				withDependencies: args.withDependencies || false,
107 | 				ignoreDependencies: args.ignoreDependencies || false
108 | 			};
109 | 
110 | 			// Call the core moveTasksBetweenTags function
111 | 			const result = await moveTasksBetweenTags(
112 | 				tasksPath,
113 | 				sourceIds,
114 | 				args.sourceTag,
115 | 				args.targetTag,
116 | 				moveOptions,
117 | 				{ projectRoot }
118 | 			);
119 | 
120 | 			return {
121 | 				success: true,
122 | 				data: {
123 | 					...result,
124 | 					message: `Successfully moved ${sourceIds.length} task(s) from "${args.sourceTag}" to "${args.targetTag}"`,
125 | 					moveOptions,
126 | 					sourceTag: args.sourceTag,
127 | 					targetTag: args.targetTag
128 | 				}
129 | 			};
130 | 		} finally {
131 | 			// Restore console output - always executed regardless of success or error
132 | 			disableSilentMode();
133 | 		}
134 | 	} catch (error) {
135 | 		log.error(`Failed to move tasks between tags: ${error.message}`);
136 | 		log.error(`Error code: ${error.code}, Error name: ${error.name}`);
137 | 
138 | 		// Enhanced error handling with structured error objects
139 | 		let errorCode = 'MOVE_TASK_CROSS_TAG_ERROR';
140 | 		let suggestions = [];
141 | 
142 | 		// Handle structured errors first
143 | 		if (error.code === 'CROSS_TAG_DEPENDENCY_CONFLICTS') {
144 | 			errorCode = 'CROSS_TAG_DEPENDENCY_CONFLICT';
145 | 			suggestions = [
146 | 				'Use --with-dependencies to move dependent tasks together',
147 | 				'Use --ignore-dependencies to break cross-tag dependencies',
148 | 				'Run task-master validate-dependencies to check for issues',
149 | 				'Move dependencies first, then move the main task'
150 | 			];
151 | 		} else if (error.code === 'CANNOT_MOVE_SUBTASK') {
152 | 			errorCode = 'SUBTASK_MOVE_RESTRICTION';
153 | 			suggestions = [
154 | 				'Promote subtask to full task first: task-master remove-subtask --id=<subtaskId> --convert',
155 | 				'Move the parent task with all subtasks using --with-dependencies'
156 | 			];
157 | 		} else if (
158 | 			error.code === 'TASK_NOT_FOUND' ||
159 | 			error.code === 'INVALID_SOURCE_TAG' ||
160 | 			error.code === 'INVALID_TARGET_TAG'
161 | 		) {
162 | 			errorCode = 'TAG_OR_TASK_NOT_FOUND';
163 | 			suggestions = [
164 | 				'Check available tags: task-master tags',
165 | 				'Verify task IDs exist: task-master list',
166 | 				'Check task details: task-master show <id>'
167 | 			];
168 | 		} else if (error.message.includes('cross-tag dependency conflicts')) {
169 | 			// Fallback for legacy error messages
170 | 			errorCode = 'CROSS_TAG_DEPENDENCY_CONFLICT';
171 | 			suggestions = [
172 | 				'Use --with-dependencies to move dependent tasks together',
173 | 				'Use --ignore-dependencies to break cross-tag dependencies',
174 | 				'Run task-master validate-dependencies to check for issues',
175 | 				'Move dependencies first, then move the main task'
176 | 			];
177 | 		} else if (error.message.includes('Cannot move subtask')) {
178 | 			// Fallback for legacy error messages
179 | 			errorCode = 'SUBTASK_MOVE_RESTRICTION';
180 | 			suggestions = [
181 | 				'Promote subtask to full task first: task-master remove-subtask --id=<subtaskId> --convert',
182 | 				'Move the parent task with all subtasks using --with-dependencies'
183 | 			];
184 | 		} else if (error.message.includes('not found')) {
185 | 			// Fallback for legacy error messages
186 | 			errorCode = 'TAG_OR_TASK_NOT_FOUND';
187 | 			suggestions = [
188 | 				'Check available tags: task-master tags',
189 | 				'Verify task IDs exist: task-master list',
190 | 				'Check task details: task-master show <id>'
191 | 			];
192 | 		} else if (
193 | 			error.code === 'TASK_ALREADY_EXISTS' ||
194 | 			error.message?.includes('already exists in target tag')
195 | 		) {
196 | 			// Target tag has an ID collision
197 | 			errorCode = 'TASK_ALREADY_EXISTS';
198 | 			suggestions = [
199 | 				'Choose a different target tag without conflicting IDs',
200 | 				'Move a different set of IDs (avoid existing ones)',
201 | 				'If needed, move within-tag to a new ID first, then cross-tag move'
202 | 			];
203 | 		}
204 | 
205 | 		return {
206 | 			success: false,
207 | 			error: {
208 | 				message: error.message,
209 | 				code: errorCode,
210 | 				suggestions
211 | 			}
212 | 		};
213 | 	}
214 | }
215 | 
```

--------------------------------------------------------------------------------
/scripts/modules/task-manager/generate-task-files.js:
--------------------------------------------------------------------------------

```javascript
  1 | import path from 'path';
  2 | import fs from 'fs';
  3 | import chalk from 'chalk';
  4 | 
  5 | import { log, readJSON } from '../utils.js';
  6 | import { formatDependenciesWithStatus } from '../ui.js';
  7 | import { validateAndFixDependencies } from '../dependency-manager.js';
  8 | import { getDebugFlag } from '../config-manager.js';
  9 | 
 10 | /**
 11 |  * Generate individual task files from tasks.json
 12 |  * @param {string} tasksPath - Path to the tasks.json file
 13 |  * @param {string} outputDir - Output directory for task files
 14 |  * @param {Object} options - Additional options (mcpLog for MCP mode, projectRoot, tag)
 15 |  * @param {string} [options.projectRoot] - Project root path
 16 |  * @param {string} [options.tag] - Tag for the task
 17 |  * @param {Object} [options.mcpLog] - MCP logger object
 18 |  * @returns {Object|undefined} Result object in MCP mode, undefined in CLI mode
 19 |  */
 20 | function generateTaskFiles(tasksPath, outputDir, options = {}) {
 21 | 	try {
 22 | 		const isMcpMode = !!options?.mcpLog;
 23 | 		const { projectRoot, tag } = options;
 24 | 
 25 | 		// 1. Read the raw data structure, ensuring we have all tags.
 26 | 		// We call readJSON without a specific tag to get the resolved default view,
 27 | 		// which correctly contains the full structure in `_rawTaggedData`.
 28 | 		const resolvedData = readJSON(tasksPath, projectRoot, tag);
 29 | 		if (!resolvedData) {
 30 | 			throw new Error(`Could not read or parse tasks file: ${tasksPath}`);
 31 | 		}
 32 | 		// Prioritize the _rawTaggedData if it exists, otherwise use the data as is.
 33 | 		const rawData = resolvedData._rawTaggedData || resolvedData;
 34 | 
 35 | 		// 2. Determine the target tag we need to generate files for.
 36 | 		const tagData = rawData[tag];
 37 | 
 38 | 		if (!tagData || !tagData.tasks) {
 39 | 			throw new Error(`Tag '${tag}' not found or has no tasks in the data.`);
 40 | 		}
 41 | 		const tasksForGeneration = tagData.tasks;
 42 | 
 43 | 		// Create the output directory if it doesn't exist
 44 | 		if (!fs.existsSync(outputDir)) {
 45 | 			fs.mkdirSync(outputDir, { recursive: true });
 46 | 		}
 47 | 
 48 | 		log(
 49 | 			'info',
 50 | 			`Preparing to regenerate ${tasksForGeneration.length} task files for tag '${tag}'`
 51 | 		);
 52 | 
 53 | 		// 3. Validate dependencies using the FULL, raw data structure to prevent data loss.
 54 | 		validateAndFixDependencies(
 55 | 			rawData, // Pass the entire object with all tags
 56 | 			tasksPath,
 57 | 			projectRoot,
 58 | 			tag // Provide the current tag context for the operation
 59 | 		);
 60 | 
 61 | 		const allTasksInTag = tagData.tasks;
 62 | 		const validTaskIds = allTasksInTag.map((task) => task.id);
 63 | 
 64 | 		// Cleanup orphaned task files
 65 | 		log('info', 'Checking for orphaned task files to clean up...');
 66 | 		try {
 67 | 			const files = fs.readdirSync(outputDir);
 68 | 			// Tag-aware file patterns: master -> task_001.txt, other tags -> task_001_tagname.txt
 69 | 			const masterFilePattern = /^task_(\d+)\.txt$/;
 70 | 			const taggedFilePattern = new RegExp(`^task_(\\d+)_${tag}\\.txt$`);
 71 | 
 72 | 			const orphanedFiles = files.filter((file) => {
 73 | 				let match = null;
 74 | 				let fileTaskId = null;
 75 | 
 76 | 				// Check if file belongs to current tag
 77 | 				if (tag === 'master') {
 78 | 					match = file.match(masterFilePattern);
 79 | 					if (match) {
 80 | 						fileTaskId = parseInt(match[1], 10);
 81 | 						// Only clean up master files when processing master tag
 82 | 						return !validTaskIds.includes(fileTaskId);
 83 | 					}
 84 | 				} else {
 85 | 					match = file.match(taggedFilePattern);
 86 | 					if (match) {
 87 | 						fileTaskId = parseInt(match[1], 10);
 88 | 						// Only clean up files for the current tag
 89 | 						return !validTaskIds.includes(fileTaskId);
 90 | 					}
 91 | 				}
 92 | 				return false;
 93 | 			});
 94 | 
 95 | 			if (orphanedFiles.length > 0) {
 96 | 				log(
 97 | 					'info',
 98 | 					`Found ${orphanedFiles.length} orphaned task files to remove for tag '${tag}'`
 99 | 				);
100 | 				orphanedFiles.forEach((file) => {
101 | 					const filePath = path.join(outputDir, file);
102 | 					fs.unlinkSync(filePath);
103 | 				});
104 | 			} else {
105 | 				log('info', 'No orphaned task files found.');
106 | 			}
107 | 		} catch (err) {
108 | 			log('warn', `Error cleaning up orphaned task files: ${err.message}`);
109 | 		}
110 | 
111 | 		// Generate task files for the target tag
112 | 		log('info', `Generating individual task files for tag '${tag}'...`);
113 | 		tasksForGeneration.forEach((task) => {
114 | 			// Tag-aware file naming: master -> task_001.txt, other tags -> task_001_tagname.txt
115 | 			const taskFileName =
116 | 				tag === 'master'
117 | 					? `task_${task.id.toString().padStart(3, '0')}.txt`
118 | 					: `task_${task.id.toString().padStart(3, '0')}_${tag}.txt`;
119 | 
120 | 			const taskPath = path.join(outputDir, taskFileName);
121 | 
122 | 			let content = `# Task ID: ${task.id}\n`;
123 | 			content += `# Title: ${task.title}\n`;
124 | 			content += `# Status: ${task.status || 'pending'}\n`;
125 | 
126 | 			if (task.dependencies && task.dependencies.length > 0) {
127 | 				content += `# Dependencies: ${formatDependenciesWithStatus(task.dependencies, allTasksInTag, false)}\n`;
128 | 			} else {
129 | 				content += '# Dependencies: None\n';
130 | 			}
131 | 
132 | 			content += `# Priority: ${task.priority || 'medium'}\n`;
133 | 			content += `# Description: ${task.description || ''}\n`;
134 | 			content += '# Details:\n';
135 | 			content += (task.details || '')
136 | 				.split('\n')
137 | 				.map((line) => line)
138 | 				.join('\n');
139 | 			content += '\n\n';
140 | 			content += '# Test Strategy:\n';
141 | 			content += (task.testStrategy || '')
142 | 				.split('\n')
143 | 				.map((line) => line)
144 | 				.join('\n');
145 | 			content += '\n';
146 | 
147 | 			if (task.subtasks && task.subtasks.length > 0) {
148 | 				content += '\n# Subtasks:\n';
149 | 				task.subtasks.forEach((subtask) => {
150 | 					content += `## ${subtask.id}. ${subtask.title} [${subtask.status || 'pending'}]\n`;
151 | 					if (subtask.dependencies && subtask.dependencies.length > 0) {
152 | 						const subtaskDeps = subtask.dependencies
153 | 							.map((depId) =>
154 | 								typeof depId === 'number'
155 | 									? `${task.id}.${depId}`
156 | 									: depId.toString()
157 | 							)
158 | 							.join(', ');
159 | 						content += `### Dependencies: ${subtaskDeps}\n`;
160 | 					} else {
161 | 						content += '### Dependencies: None\n';
162 | 					}
163 | 					content += `### Description: ${subtask.description || ''}\n`;
164 | 					content += '### Details:\n';
165 | 					content += (subtask.details || '')
166 | 						.split('\n')
167 | 						.map((line) => line)
168 | 						.join('\n');
169 | 					content += '\n\n';
170 | 				});
171 | 			}
172 | 
173 | 			fs.writeFileSync(taskPath, content);
174 | 		});
175 | 
176 | 		log(
177 | 			'success',
178 | 			`All ${tasksForGeneration.length} tasks for tag '${tag}' have been generated into '${outputDir}'.`
179 | 		);
180 | 
181 | 		if (isMcpMode) {
182 | 			return {
183 | 				success: true,
184 | 				count: tasksForGeneration.length,
185 | 				directory: outputDir
186 | 			};
187 | 		}
188 | 	} catch (error) {
189 | 		log('error', `Error generating task files: ${error.message}`);
190 | 		if (!options?.mcpLog) {
191 | 			console.error(chalk.red(`Error generating task files: ${error.message}`));
192 | 			if (getDebugFlag()) {
193 | 				console.error(error);
194 | 			}
195 | 			process.exit(1);
196 | 		} else {
197 | 			throw error;
198 | 		}
199 | 	}
200 | }
201 | 
202 | export default generateTaskFiles;
203 | 
```

--------------------------------------------------------------------------------
/apps/docs/tdd-workflow/quickstart.mdx:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "TDD Workflow Quick Start"
  3 | description: "Get started with TaskMaster's autonomous TDD workflow in 5 minutes"
  4 | ---
  5 | 
  6 | Get started with TaskMaster's autonomous TDD workflow in 5 minutes.
  7 | 
  8 | ## Prerequisites
  9 | 
 10 | - TaskMaster initialized project (`tm init`)
 11 | - Tasks with subtasks created (`tm parse-prd` or `tm expand`)
 12 | - Git repository with clean working tree
 13 | - Test framework installed (vitest, jest, mocha, etc.)
 14 | 
 15 | ## 1. Start a Workflow
 16 | 
 17 | ```bash
 18 | tm autopilot start <taskId>
 19 | ```
 20 | 
 21 | Example:
 22 | ```bash
 23 | $ tm autopilot start 7
 24 | 
 25 | ✓ Workflow started for task 7
 26 | ✓ Created branch: task-7
 27 | ✓ Current phase: RED
 28 | ✓ Subtask 1/5: Implement start command
 29 | → Next action: Write a failing test
 30 | ```
 31 | 
 32 | ## 2. The TDD Cycle
 33 | 
 34 | ### RED Phase: Write Failing Test
 35 | 
 36 | ```bash
 37 | # Check what to do next
 38 | $ tm autopilot next --json
 39 | {
 40 |   "action": "generate_test",
 41 |   "currentSubtask": {
 42 |     "id": "1",
 43 |     "title": "Implement start command"
 44 |   }
 45 | }
 46 | ```
 47 | 
 48 | Write a test that fails:
 49 | ```typescript
 50 | // tests/start.test.ts
 51 | import { describe, it, expect } from 'vitest';
 52 | import { StartCommand } from '../src/commands/start';
 53 | 
 54 | describe('StartCommand', () => {
 55 |   it('should initialize workflow', async () => {
 56 |     const command = new StartCommand();
 57 |     const result = await command.execute({ taskId: '7' });
 58 |     expect(result.success).toBe(true);
 59 |   });
 60 | });
 61 | ```
 62 | 
 63 | Run tests:
 64 | ```bash
 65 | $ npm test
 66 | # ✗ 1 test failed
 67 | ```
 68 | 
 69 | Complete RED phase:
 70 | ```bash
 71 | $ tm autopilot complete --results '{"total":1,"passed":0,"failed":1,"skipped":0}'
 72 | 
 73 | ✓ RED phase complete
 74 | ✓ Current phase: GREEN
 75 | → Next action: Implement code to pass tests
 76 | ```
 77 | 
 78 | ### GREEN Phase: Implement Feature
 79 | 
 80 | Write minimal code to pass:
 81 | ```typescript
 82 | // src/commands/start.ts
 83 | export class StartCommand {
 84 |   async execute(options: { taskId: string }) {
 85 |     return { success: true };
 86 |   }
 87 | }
 88 | ```
 89 | 
 90 | Run tests:
 91 | ```bash
 92 | $ npm test
 93 | # ✓ 1 test passed
 94 | ```
 95 | 
 96 | Complete GREEN phase:
 97 | ```bash
 98 | $ tm autopilot complete --results '{"total":1,"passed":1,"failed":0,"skipped":0}'
 99 | 
100 | ✓ GREEN phase complete
101 | ✓ Current phase: COMMIT
102 | → Next action: Commit changes
103 | ```
104 | 
105 | ### COMMIT Phase: Save Progress
106 | 
107 | ```bash
108 | $ tm autopilot commit
109 | 
110 | ✓ Created commit: abc123
111 | ✓ Message: feat(autopilot): implement start command (Task 7.1)
112 | ✓ Advanced to subtask 2/5
113 | ✓ Current phase: RED
114 | → Next action: Write a failing test
115 | ```
116 | 
117 | ## 3. Continue for All Subtasks
118 | 
119 | Repeat the RED-GREEN-COMMIT cycle for each subtask until complete.
120 | 
121 | ```bash
122 | # Check progress anytime
123 | $ tm autopilot status --json
124 | {
125 |   "taskId": "7",
126 |   "progress": {
127 |     "completed": 1,
128 |     "total": 5,
129 |     "percentage": 20
130 |   },
131 |   "currentSubtask": {
132 |     "id": "2",
133 |     "title": "Implement resume command"
134 |   }
135 | }
136 | ```
137 | 
138 | ## 4. Complete the Workflow
139 | 
140 | When all subtasks are done:
141 | 
142 | ```bash
143 | $ tm autopilot status --json
144 | {
145 |   "phase": "COMPLETE",
146 |   "progress": {
147 |     "completed": 5,
148 |     "total": 5,
149 |     "percentage": 100
150 |   }
151 | }
152 | ```
153 | 
154 | Your branch `task-7` is ready for review/merge!
155 | 
156 | ## Common Patterns
157 | 
158 | ### Parse Test Output
159 | 
160 | Your test runner outputs human-readable format - convert to JSON:
161 | 
162 | **Vitest:**
163 | ```
164 | Tests  2 failed | 8 passed | 10 total
165 | ```
166 | → `{"total":10,"passed":8,"failed":2,"skipped":0}`
167 | 
168 | **Jest:**
169 | ```
170 | Tests:  2 failed, 8 passed, 10 total
171 | ```
172 | → `{"total":10,"passed":8,"failed":2,"skipped":0}`
173 | 
174 | ### Handle Errors
175 | 
176 | **Problem:** RED phase won't complete - "no test failures"
177 | 
178 | **Solution:** Your test isn't testing new behavior. Make sure it fails:
179 | ```typescript
180 | // Bad - test passes immediately
181 | it('should exist', () => {
182 |   expect(StartCommand).toBeDefined(); // Always passes
183 | });
184 | 
185 | // Good - test fails until feature exists
186 | it('should initialize workflow', async () => {
187 |   const result = await new StartCommand().execute({ taskId: '7' });
188 |   expect(result.success).toBe(true); // Fails until execute() is implemented
189 | });
190 | ```
191 | 
192 | **Problem:** GREEN phase won't complete - "tests still failing"
193 | 
194 | **Solution:** Fix your implementation until all tests pass:
195 | ```bash
196 | # Run tests to see what's failing
197 | $ npm test
198 | 
199 | # Fix the issue
200 | $ vim src/commands/start.ts
201 | 
202 | # Verify tests pass
203 | $ npm test
204 | 
205 | # Try again
206 | $ tm autopilot complete --results '{"total":1,"passed":1,"failed":0,"skipped":0}'
207 | ```
208 | 
209 | ### Resume Interrupted Work
210 | 
211 | ```bash
212 | # If you interrupted the workflow
213 | $ tm autopilot resume
214 | 
215 | ✓ Workflow resumed
216 | ✓ Task 7 - subtask 3/5
217 | ✓ Current phase: GREEN
218 | → Continue from where you left off
219 | ```
220 | 
221 | ## JSON Output Mode
222 | 
223 | All commands support `--json` for programmatic use:
224 | 
225 | ```bash
226 | $ tm autopilot start 7 --json | jq .
227 | {
228 |   "success": true,
229 |   "taskId": "7",
230 |   "branchName": "task-7",
231 |   "phase": "SUBTASK_LOOP",
232 |   "tddPhase": "RED",
233 |   "progress": { ... },
234 |   "currentSubtask": { ... },
235 |   "nextAction": "generate_test"
236 | }
237 | ```
238 | 
239 | Perfect for:
240 | - CI/CD integration
241 | - Custom tooling
242 | - Automated workflows
243 | - Progress monitoring
244 | 
245 | ## MCP Integration
246 | 
247 | For AI agents (Claude Code, etc.), use MCP tools:
248 | 
249 | ```typescript
250 | // Start workflow
251 | await mcp.call('autopilot_start', {
252 |   taskId: '7',
253 |   projectRoot: '/path/to/project'
254 | });
255 | 
256 | // Get next action
257 | const next = await mcp.call('autopilot_next', {
258 |   projectRoot: '/path/to/project'
259 | });
260 | 
261 | // Complete phase
262 | await mcp.call('autopilot_complete_phase', {
263 |   projectRoot: '/path/to/project',
264 |   testResults: { total: 1, passed: 0, failed: 1, skipped: 0 }
265 | });
266 | 
267 | // Commit
268 | await mcp.call('autopilot_commit', {
269 |   projectRoot: '/path/to/project'
270 | });
271 | ```
272 | 
273 | See [AI Agent Integration Guide](./ai-agent-integration.mdx) for details.
274 | 
275 | ## Cheat Sheet
276 | 
277 | ```bash
278 | # Start
279 | tm autopilot start <taskId>         # Initialize workflow
280 | 
281 | # Workflow Control
282 | tm autopilot next                    # What's next?
283 | tm autopilot status                  # Current state
284 | tm autopilot resume                  # Continue interrupted work
285 | tm autopilot abort                   # Cancel and cleanup
286 | 
287 | # TDD Cycle
288 | tm autopilot complete --results '{...}'   # Advance phase
289 | tm autopilot commit                       # Save progress
290 | 
291 | # Options
292 | --json                              # Machine-readable output
293 | --project-root <path>               # Specify project location
294 | --force                             # Override safety checks
295 | ```
296 | 
297 | ## Next Steps
298 | 
299 | - Read [AI Agent Integration Guide](./ai-agent-integration.mdx) for complete documentation
300 | - Check [Command Reference](/command-reference) for all options
301 | 
302 | ## Tips
303 | 
304 | 1. **Always let tests fail first** - That's the RED phase
305 | 2. **Write minimal code** - Just enough to pass
306 | 3. **Commit frequently** - After each subtask
307 | 4. **Use --json** - Better for programmatic use
308 | 5. **Check status often** - Know where you are
309 | 6. **Trust the workflow** - It enforces TDD rules
310 | 
311 | ---
312 | 
313 | **Ready to start?** Run `tm autopilot start <taskId>` and begin your TDD journey!
314 | 
```

--------------------------------------------------------------------------------
/src/profiles/vscode.js:
--------------------------------------------------------------------------------

```javascript
  1 | // VS Code conversion profile for rule-transformer
  2 | import path from 'path';
  3 | import fs from 'fs';
  4 | import { log } from '../../scripts/modules/utils.js';
  5 | import { createProfile, COMMON_TOOL_MAPPINGS } from './base-profile.js';
  6 | 
  7 | /**
  8 |  * Transform standard MCP config format to VS Code format
  9 |  * @param {Object} mcpConfig - Standard MCP configuration object
 10 |  * @returns {Object} - Transformed VS Code configuration object
 11 |  */
 12 | function transformToVSCodeFormat(mcpConfig) {
 13 | 	const vscodeConfig = {};
 14 | 
 15 | 	// Transform mcpServers to servers
 16 | 	if (mcpConfig.mcpServers) {
 17 | 		vscodeConfig.servers = {};
 18 | 
 19 | 		for (const [serverName, serverConfig] of Object.entries(
 20 | 			mcpConfig.mcpServers
 21 | 		)) {
 22 | 			// Transform server configuration
 23 | 			const transformedServer = {
 24 | 				...serverConfig
 25 | 			};
 26 | 
 27 | 			// Add type: "stdio" after the env block
 28 | 			if (transformedServer.env) {
 29 | 				// Reorder properties: keep command, args, env, then add type
 30 | 				const reorderedServer = {};
 31 | 				if (transformedServer.command)
 32 | 					reorderedServer.command = transformedServer.command;
 33 | 				if (transformedServer.args)
 34 | 					reorderedServer.args = transformedServer.args;
 35 | 				if (transformedServer.env) reorderedServer.env = transformedServer.env;
 36 | 				reorderedServer.type = 'stdio';
 37 | 
 38 | 				// Add any other properties that might exist
 39 | 				Object.keys(transformedServer).forEach((key) => {
 40 | 					if (!['command', 'args', 'env', 'type'].includes(key)) {
 41 | 						reorderedServer[key] = transformedServer[key];
 42 | 					}
 43 | 				});
 44 | 
 45 | 				vscodeConfig.servers[serverName] = reorderedServer;
 46 | 			} else {
 47 | 				// If no env block, just add type at the end
 48 | 				transformedServer.type = 'stdio';
 49 | 				vscodeConfig.servers[serverName] = transformedServer;
 50 | 			}
 51 | 		}
 52 | 	}
 53 | 
 54 | 	return vscodeConfig;
 55 | }
 56 | 
 57 | /**
 58 |  * Lifecycle function called after MCP config generation to transform to VS Code format
 59 |  * @param {string} targetDir - Target project directory
 60 |  * @param {string} assetsDir - Assets directory (unused for VS Code)
 61 |  */
 62 | function onPostConvertRulesProfile(targetDir, assetsDir) {
 63 | 	const vscodeConfigPath = path.join(targetDir, '.vscode', 'mcp.json');
 64 | 
 65 | 	if (!fs.existsSync(vscodeConfigPath)) {
 66 | 		log('debug', '[VS Code] No .vscode/mcp.json found to transform');
 67 | 		return;
 68 | 	}
 69 | 
 70 | 	try {
 71 | 		// Read the generated standard MCP config
 72 | 		const mcpConfigContent = fs.readFileSync(vscodeConfigPath, 'utf8');
 73 | 		const mcpConfig = JSON.parse(mcpConfigContent);
 74 | 
 75 | 		// Check if it's already in VS Code format (has servers instead of mcpServers)
 76 | 		if (mcpConfig.servers) {
 77 | 			log(
 78 | 				'info',
 79 | 				'[VS Code] mcp.json already in VS Code format, skipping transformation'
 80 | 			);
 81 | 			return;
 82 | 		}
 83 | 
 84 | 		// Transform to VS Code format
 85 | 		const vscodeConfig = transformToVSCodeFormat(mcpConfig);
 86 | 
 87 | 		// Write back the transformed config with proper formatting
 88 | 		fs.writeFileSync(
 89 | 			vscodeConfigPath,
 90 | 			JSON.stringify(vscodeConfig, null, 2) + '\n'
 91 | 		);
 92 | 
 93 | 		log('info', '[VS Code] Transformed mcp.json to VS Code format');
 94 | 		log('debug', `[VS Code] Renamed mcpServers->servers, added type: "stdio"`);
 95 | 	} catch (error) {
 96 | 		log('error', `[VS Code] Failed to transform mcp.json: ${error.message}`);
 97 | 	}
 98 | }
 99 | 
100 | /**
101 |  * Lifecycle function called when removing VS Code profile
102 |  * @param {string} targetDir - Target project directory
103 |  */
104 | function onRemoveRulesProfile(targetDir) {
105 | 	const vscodeConfigPath = path.join(targetDir, '.vscode', 'mcp.json');
106 | 
107 | 	if (!fs.existsSync(vscodeConfigPath)) {
108 | 		log('debug', '[VS Code] No .vscode/mcp.json found to clean up');
109 | 		return;
110 | 	}
111 | 
112 | 	try {
113 | 		// Read the current config
114 | 		const configContent = fs.readFileSync(vscodeConfigPath, 'utf8');
115 | 		const config = JSON.parse(configContent);
116 | 
117 | 		// Check if it has the servers section and task-master-ai server
118 | 		if (config.servers && config.servers['task-master-ai']) {
119 | 			// Remove task-master-ai server
120 | 			delete config.servers['task-master-ai'];
121 | 
122 | 			// Check if there are other MCP servers
123 | 			const remainingServers = Object.keys(config.servers);
124 | 
125 | 			if (remainingServers.length === 0) {
126 | 				// No other servers, remove entire file
127 | 				fs.rmSync(vscodeConfigPath, { force: true });
128 | 				log('info', '[VS Code] Removed empty mcp.json file');
129 | 
130 | 				// Also remove .vscode directory if it's empty
131 | 				const vscodeDir = path.dirname(vscodeConfigPath);
132 | 				try {
133 | 					const dirContents = fs.readdirSync(vscodeDir);
134 | 					if (dirContents.length === 0) {
135 | 						fs.rmSync(vscodeDir, { recursive: true, force: true });
136 | 						log('debug', '[VS Code] Removed empty .vscode directory');
137 | 					}
138 | 				} catch (err) {
139 | 					// Directory might not be empty or might not exist, that's fine
140 | 				}
141 | 			} else {
142 | 				// Write back the modified config
143 | 				fs.writeFileSync(
144 | 					vscodeConfigPath,
145 | 					JSON.stringify(config, null, 2) + '\n'
146 | 				);
147 | 				log(
148 | 					'info',
149 | 					'[VS Code] Removed TaskMaster from mcp.json, preserved other configurations'
150 | 				);
151 | 			}
152 | 		} else {
153 | 			log('debug', '[VS Code] TaskMaster not found in mcp.json');
154 | 		}
155 | 	} catch (error) {
156 | 		log('error', `[VS Code] Failed to clean up mcp.json: ${error.message}`);
157 | 	}
158 | }
159 | 
160 | // Create and export vscode profile using the base factory
161 | export const vscodeProfile = createProfile({
162 | 	name: 'vscode',
163 | 	displayName: 'VS Code',
164 | 	url: 'code.visualstudio.com',
165 | 	docsUrl: 'code.visualstudio.com/docs',
166 | 	rulesDir: '.github/instructions', // VS Code instructions location
167 | 	profileDir: '.vscode', // VS Code configuration directory
168 | 	mcpConfigName: 'mcp.json', // VS Code uses mcp.json in .vscode directory
169 | 	targetExtension: '.instructions.md',
170 | 	customReplacements: [
171 | 		// Core VS Code directory structure changes
172 | 		{ from: /\.cursor\/rules/g, to: '.github/instructions' },
173 | 		{ from: /\.cursor\/mcp\.json/g, to: '.vscode/mcp.json' },
174 | 
175 | 		// Fix any remaining vscode/rules references that might be created during transformation
176 | 		{ from: /\.vscode\/rules/g, to: '.github/instructions' },
177 | 
178 | 		// VS Code custom instructions format - use applyTo with quoted patterns instead of globs
179 | 		{ from: /^globs:\s*(.+)$/gm, to: 'applyTo: "$1"' },
180 | 
181 | 		// Remove unsupported property - alwaysApply
182 | 		{ from: /^alwaysApply:\s*(true|false)\s*\n?/gm, to: '' },
183 | 
184 | 		// Essential markdown link transformations for VS Code structure
185 | 		{
186 | 			from: /\[(.+?)\]\(mdc:\.cursor\/rules\/(.+?)\.mdc\)/g,
187 | 			to: '[$1](.github/instructions/$2.instructions.md)'
188 | 		},
189 | 
190 | 		// VS Code specific terminology
191 | 		{ from: /rules directory/g, to: 'instructions directory' },
192 | 		{ from: /cursor rules/gi, to: 'VS Code instructions' }
193 | 	],
194 | 	onPostConvert: onPostConvertRulesProfile,
195 | 	onRemove: onRemoveRulesProfile
196 | });
197 | 
198 | // Export lifecycle functions separately to avoid naming conflicts
199 | export { onPostConvertRulesProfile, onRemoveRulesProfile };
200 | 
```

--------------------------------------------------------------------------------
/packages/tm-core/src/modules/workflow/services/test-result-validator.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { z } from 'zod';
  2 | import type {
  3 | 	CoverageThresholds,
  4 | 	PhaseValidationOptions,
  5 | 	TestResult,
  6 | 	ValidationResult
  7 | } from './test-result-validator.types.js';
  8 | 
  9 | /**
 10 |  * Schema for coverage metrics validation
 11 |  */
 12 | const coverageSchema = z.object({
 13 | 	line: z.number().min(0).max(100),
 14 | 	branch: z.number().min(0).max(100),
 15 | 	function: z.number().min(0).max(100),
 16 | 	statement: z.number().min(0).max(100)
 17 | });
 18 | 
 19 | /**
 20 |  * Schema for test result validation
 21 |  */
 22 | const testResultSchema = z.object({
 23 | 	total: z.number().int().nonnegative(),
 24 | 	passed: z.number().int().nonnegative(),
 25 | 	failed: z.number().int().nonnegative(),
 26 | 	skipped: z.number().int().nonnegative(),
 27 | 	phase: z.enum(['RED', 'GREEN', 'REFACTOR']),
 28 | 	coverage: coverageSchema.optional()
 29 | });
 30 | 
 31 | /**
 32 |  * Validates test results according to TDD phase semantics
 33 |  */
 34 | export class TestResultValidator {
 35 | 	/**
 36 | 	 * Validates a test result object
 37 | 	 */
 38 | 	validate(testResult: TestResult): ValidationResult {
 39 | 		const errors: string[] = [];
 40 | 		const warnings: string[] = [];
 41 | 		const suggestions: string[] = [];
 42 | 
 43 | 		// Schema validation
 44 | 		const parseResult = testResultSchema.safeParse(testResult);
 45 | 		if (!parseResult.success) {
 46 | 			const zodIssues = parseResult.error.issues || [];
 47 | 			errors.push(
 48 | 				...zodIssues.map((e) => {
 49 | 					const path = e.path.length > 0 ? `${e.path.join('.')}: ` : '';
 50 | 					return `${path}${e.message}`;
 51 | 				})
 52 | 			);
 53 | 			return { valid: false, errors, warnings, suggestions };
 54 | 		}
 55 | 
 56 | 		// Total validation
 57 | 		const sum = testResult.passed + testResult.failed + testResult.skipped;
 58 | 		if (sum !== testResult.total) {
 59 | 			errors.push('Total tests must equal passed + failed + skipped');
 60 | 		}
 61 | 
 62 | 		// If there are validation errors, return early
 63 | 		if (errors.length > 0) {
 64 | 			return { valid: false, errors, warnings, suggestions };
 65 | 		}
 66 | 
 67 | 		return { valid: true, errors, warnings, suggestions };
 68 | 	}
 69 | 
 70 | 	/**
 71 | 	 * Validates RED phase test results
 72 | 	 * RED phase must have at least one failing test
 73 | 	 */
 74 | 	validateRedPhase(testResult: TestResult): ValidationResult {
 75 | 		const baseValidation = this.validate(testResult);
 76 | 		if (!baseValidation.valid) {
 77 | 			return baseValidation;
 78 | 		}
 79 | 
 80 | 		const errors: string[] = [];
 81 | 		const suggestions: string[] = [];
 82 | 
 83 | 		// RED phase must have failures
 84 | 		if (testResult.failed === 0) {
 85 | 			errors.push('RED phase must have at least one failing test');
 86 | 			suggestions.push('Write failing tests first to follow TDD workflow');
 87 | 		}
 88 | 
 89 | 		// Must have at least one test
 90 | 		if (testResult.total === 0) {
 91 | 			errors.push('Cannot validate empty test suite');
 92 | 			suggestions.push('Add at least one test to begin TDD cycle');
 93 | 		}
 94 | 
 95 | 		return {
 96 | 			valid: errors.length === 0,
 97 | 			errors,
 98 | 			suggestions
 99 | 		};
100 | 	}
101 | 
102 | 	/**
103 | 	 * Validates GREEN phase test results
104 | 	 * GREEN phase must have zero failures
105 | 	 */
106 | 	validateGreenPhase(
107 | 		testResult: TestResult,
108 | 		previousTestCount?: number
109 | 	): ValidationResult {
110 | 		const baseValidation = this.validate(testResult);
111 | 		if (!baseValidation.valid) {
112 | 			return baseValidation;
113 | 		}
114 | 
115 | 		const errors: string[] = [];
116 | 		const warnings: string[] = [];
117 | 		const suggestions: string[] = [];
118 | 
119 | 		// GREEN phase must have zero failures
120 | 		if (testResult.failed > 0) {
121 | 			errors.push('GREEN phase must have zero failures');
122 | 			suggestions.push('Fix implementation to make all tests pass');
123 | 		}
124 | 
125 | 		// Must have at least one passing test
126 | 		if (testResult.passed === 0) {
127 | 			errors.push('GREEN phase must have at least one passing test');
128 | 			suggestions.push('Ensure tests exist and implementation makes them pass');
129 | 		}
130 | 
131 | 		// Check for test count regression
132 | 		if (
133 | 			previousTestCount !== undefined &&
134 | 			testResult.total < previousTestCount
135 | 		) {
136 | 			warnings.push(
137 | 				`Test count decreased from ${previousTestCount} to ${testResult.total}`
138 | 			);
139 | 			suggestions.push('Verify that no tests were accidentally removed');
140 | 		}
141 | 
142 | 		return {
143 | 			valid: errors.length === 0,
144 | 			errors,
145 | 			warnings,
146 | 			suggestions
147 | 		};
148 | 	}
149 | 
150 | 	/**
151 | 	 * Validates coverage thresholds if provided
152 | 	 */
153 | 	validateCoverage(
154 | 		testResult: TestResult,
155 | 		thresholds: CoverageThresholds
156 | 	): ValidationResult {
157 | 		const baseValidation = this.validate(testResult);
158 | 		if (!baseValidation.valid) {
159 | 			return baseValidation;
160 | 		}
161 | 
162 | 		const errors: string[] = [];
163 | 		const suggestions: string[] = [];
164 | 
165 | 		// Skip validation if no coverage data
166 | 		if (!testResult.coverage) {
167 | 			return { valid: true, errors: [], suggestions: [] };
168 | 		}
169 | 
170 | 		const coverage = testResult.coverage;
171 | 		const gaps: string[] = [];
172 | 
173 | 		// Check each coverage type against threshold
174 | 		if (thresholds.line !== undefined && coverage.line < thresholds.line) {
175 | 			gaps.push(`line coverage (${coverage.line}% < ${thresholds.line}%)`);
176 | 		}
177 | 
178 | 		if (
179 | 			thresholds.branch !== undefined &&
180 | 			coverage.branch < thresholds.branch
181 | 		) {
182 | 			gaps.push(
183 | 				`branch coverage (${coverage.branch}% < ${thresholds.branch}%)`
184 | 			);
185 | 		}
186 | 
187 | 		if (
188 | 			thresholds.function !== undefined &&
189 | 			coverage.function < thresholds.function
190 | 		) {
191 | 			gaps.push(
192 | 				`function coverage (${coverage.function}% < ${thresholds.function}%)`
193 | 			);
194 | 		}
195 | 
196 | 		if (
197 | 			thresholds.statement !== undefined &&
198 | 			coverage.statement < thresholds.statement
199 | 		) {
200 | 			gaps.push(
201 | 				`statement coverage (${coverage.statement}% < ${thresholds.statement}%)`
202 | 			);
203 | 		}
204 | 
205 | 		if (gaps.length > 0) {
206 | 			errors.push(`Coverage thresholds not met: ${gaps.join(', ')}`);
207 | 			suggestions.push('Add more tests to improve code coverage');
208 | 		}
209 | 
210 | 		return {
211 | 			valid: errors.length === 0,
212 | 			errors,
213 | 			suggestions
214 | 		};
215 | 	}
216 | 
217 | 	/**
218 | 	 * Validates test results based on TDD phase
219 | 	 */
220 | 	validatePhase(
221 | 		testResult: TestResult,
222 | 		options?: PhaseValidationOptions
223 | 	): ValidationResult {
224 | 		const phase = options?.phase ?? testResult.phase;
225 | 
226 | 		// Phase-specific validation
227 | 		let phaseResult: ValidationResult;
228 | 		if (phase === 'RED') {
229 | 			phaseResult = this.validateRedPhase(testResult);
230 | 		} else if (phase === 'GREEN') {
231 | 			phaseResult = this.validateGreenPhase(
232 | 				testResult,
233 | 				options?.previousTestCount
234 | 			);
235 | 		} else {
236 | 			// REFACTOR phase uses same rules as GREEN
237 | 			phaseResult = this.validateGreenPhase(
238 | 				testResult,
239 | 				options?.previousTestCount
240 | 			);
241 | 		}
242 | 
243 | 		if (!phaseResult.valid) {
244 | 			return phaseResult;
245 | 		}
246 | 
247 | 		// Coverage validation if thresholds provided
248 | 		if (options?.coverageThresholds) {
249 | 			const coverageResult = this.validateCoverage(
250 | 				testResult,
251 | 				options.coverageThresholds
252 | 			);
253 | 
254 | 			// Merge results
255 | 			return {
256 | 				valid: coverageResult.valid,
257 | 				errors: [...(phaseResult.errors || []), ...coverageResult.errors],
258 | 				warnings: phaseResult.warnings,
259 | 				suggestions: [
260 | 					...(phaseResult.suggestions || []),
261 | 					...(coverageResult.suggestions || [])
262 | 				]
263 | 			};
264 | 		}
265 | 
266 | 		return phaseResult;
267 | 	}
268 | }
269 | 
```

--------------------------------------------------------------------------------
/apps/docs/capabilities/task-structure.mdx:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "Task Structure"
  3 | sidebarTitle: "Task Structure"
  4 | description: "Tasks in Task Master follow a specific format designed to provide comprehensive information for both humans and AI assistants."
  5 | ---
  6 | 
  7 | ## Task Fields in tasks.json
  8 | 
  9 | Tasks in tasks.json have the following structure:
 10 | 
 11 | | Field          | Description                                    | Example                                                |
 12 | | -------------- | ---------------------------------------------- | ------------------------------------------------------ |
 13 | | `id`           | Unique identifier for the task.                | `1`                                                    |
 14 | | `title`        | Brief, descriptive title.                      | `"Initialize Repo"`                                    |
 15 | | `description`  | What the task involves.                        | `"Create a new repository, set up initial structure."` |
 16 | | `status`       | Current state.                                 | `"pending"`, `"done"`, `"deferred"`                    |
 17 | | `dependencies` | Prerequisite task IDs. ✅ Completed, ⏱️ Pending | `[1, 2]`                                               |
 18 | | `priority`     | Task importance.                               | `"high"`, `"medium"`, `"low"`                          |
 19 | | `details`      | Implementation instructions.                   | `"Use GitHub client ID/secret, handle callback..."`    |
 20 | | `testStrategy` | How to verify success.                         | `"Deploy and confirm 'Hello World' response."`         |
 21 | | `subtasks`     | Nested subtasks related to the main task.      | `[{"id": 1, "title": "Configure OAuth", ...}]`         |
 22 | 
 23 | ## Task File Format
 24 | 
 25 | Individual task files follow this format:
 26 | 
 27 | ```
 28 | # Task ID: <id>
 29 | # Title: <title>
 30 | # Status: <status>
 31 | # Dependencies: <comma-separated list of dependency IDs>
 32 | # Priority: <priority>
 33 | # Description: <brief description>
 34 | # Details:
 35 | <detailed implementation notes>
 36 | 
 37 | # Test Strategy:
 38 | <verification approach>
 39 | ```
 40 | 
 41 | ## Features in Detail
 42 | 
 43 | <AccordionGroup>
 44 | <Accordion title="Analyzing Task Complexity">
 45 | The `analyze-complexity` command:
 46 | 
 47 | - Analyzes each task using AI to assess its complexity on a scale of 1-10
 48 | - Recommends optimal number of subtasks based on configured DEFAULT_SUBTASKS
 49 | - Generates tailored prompts for expanding each task
 50 | - Creates a comprehensive JSON report with ready-to-use commands
 51 | - Saves the report to scripts/task-complexity-report.json by default
 52 | 
 53 | The generated report contains:
 54 | 
 55 | - Complexity analysis for each task (scored 1-10)
 56 | - Recommended number of subtasks based on complexity
 57 | - AI-generated expansion prompts customized for each task
 58 | - Ready-to-run expansion commands directly within each task analysis
 59 | </Accordion>
 60 | 
 61 | <Accordion title="Viewing Complexity Report">
 62 | The `complexity-report` command:
 63 | 
 64 | - Displays a formatted, easy-to-read version of the complexity analysis report
 65 | - Shows tasks organized by complexity score (highest to lowest)
 66 | - Provides complexity distribution statistics (low, medium, high)
 67 | - Highlights tasks recommended for expansion based on threshold score
 68 | - Includes ready-to-use expansion commands for each complex task
 69 | - If no report exists, offers to generate one on the spot
 70 | </Accordion>
 71 | 
 72 | <Accordion title="Smart Task Expansion">
 73 | The `expand` command automatically checks for and uses the complexity report:
 74 | 
 75 | When a complexity report exists:
 76 | 
 77 | - Tasks are automatically expanded using the recommended subtask count and prompts
 78 | - When expanding all tasks, they're processed in order of complexity (highest first)
 79 | - Research-backed generation is preserved from the complexity analysis
 80 | - You can still override recommendations with explicit command-line options
 81 | 
 82 | Example workflow:
 83 | 
 84 | ```bash
 85 | # Generate the complexity analysis report with research capabilities
 86 | task-master analyze-complexity --research
 87 | 
 88 | # Review the report in a readable format
 89 | task-master complexity-report
 90 | 
 91 | # Expand tasks using the optimized recommendations
 92 | task-master expand --id=8
 93 | # or expand all tasks
 94 | task-master expand --all
 95 | ```
 96 | </Accordion>
 97 | 
 98 | <Accordion title="Finding the Next Task">
 99 | The `next` command:
100 | 
101 | - Identifies tasks that are pending/in-progress and have all dependencies satisfied
102 | - Prioritizes tasks by priority level, dependency count, and task ID
103 | - Displays comprehensive information about the selected task:
104 |   - Basic task details (ID, title, priority, dependencies)
105 |   - Implementation details
106 |   - Subtasks (if they exist)
107 | - Provides contextual suggested actions:
108 |   - Command to mark the task as in-progress
109 |   - Command to mark the task as done
110 |   - Commands for working with subtasks
111 | </Accordion>
112 | 
113 | <Accordion title="Viewing Specific Task Details">
114 | The `show` command:
115 | 
116 | - Displays comprehensive details about a specific task or subtask
117 | - Shows task status, priority, dependencies, and detailed implementation notes
118 | - For parent tasks, displays all subtasks and their status
119 | - For subtasks, shows parent task relationship
120 | - Provides contextual action suggestions based on the task's state
121 | - Works with both regular tasks and subtasks (using the format taskId.subtaskId)
122 | </Accordion>
123 | </AccordionGroup>
124 | 
125 | ## Best Practices for AI-Driven Development
126 | 
127 | <CardGroup cols={2}>
128 |   <Card title="📝 Detailed PRD" icon="lightbulb">
129 |     The more detailed your PRD, the better the generated tasks will be.
130 |   </Card>
131 |   
132 |   <Card title="👀 Review Tasks" icon="magnifying-glass">
133 |     After parsing the PRD, review the tasks to ensure they make sense and have appropriate dependencies.
134 |   </Card>
135 |   
136 |   <Card title="📊 Analyze Complexity" icon="chart-line">
137 |     Use the complexity analysis feature to identify which tasks should be broken down further.
138 |   </Card>
139 |   
140 |   <Card title="⛓️ Follow Dependencies" icon="link">
141 |     Always respect task dependencies - the Cursor agent will help with this.
142 |   </Card>
143 |   
144 |   <Card title="🔄 Update As You Go" icon="arrows-rotate">
145 |     If your implementation diverges from the plan, use the update command to keep future tasks aligned.
146 |   </Card>
147 |   
148 |   <Card title="📦 Break Down Tasks" icon="boxes-stacked">
149 |     Use the expand command to break down complex tasks into manageable subtasks.
150 |   </Card>
151 |   
152 |   <Card title="🔄 Regenerate Files" icon="file-arrow-up">
153 |     After any updates to tasks.json, regenerate the task files to keep them in sync.
154 |   </Card>
155 |   
156 |   <Card title="💬 Provide Context" icon="comment">
157 |     When asking the Cursor agent to help with a task, provide context about what you're trying to achieve.
158 |   </Card>
159 |   
160 |   <Card title="✅ Validate Dependencies" icon="circle-check">
161 |     Periodically run the validate-dependencies command to check for invalid or circular dependencies.
162 |   </Card>
163 | </CardGroup>
164 | 
```

--------------------------------------------------------------------------------
/tests/unit/task-finder.test.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * Task finder tests
  3 |  */
  4 | 
  5 | // Import after mocks are set up - No mocks needed for readComplexityReport anymore
  6 | import { findTaskById } from '../../scripts/modules/utils.js';
  7 | import { emptySampleTasks, sampleTasks } from '../fixtures/sample-tasks.js';
  8 | 
  9 | describe('Task Finder', () => {
 10 | 	describe('findTaskById function', () => {
 11 | 		test('should find a task by numeric ID', () => {
 12 | 			const result = findTaskById(sampleTasks.tasks, 2);
 13 | 			expect(result.task).toBeDefined();
 14 | 			expect(result.task.id).toBe(2);
 15 | 			expect(result.task.title).toBe('Create Core Functionality');
 16 | 			expect(result.originalSubtaskCount).toBeNull();
 17 | 		});
 18 | 
 19 | 		test('should find a task by string ID', () => {
 20 | 			const result = findTaskById(sampleTasks.tasks, '2');
 21 | 			expect(result.task).toBeDefined();
 22 | 			expect(result.task.id).toBe(2);
 23 | 			expect(result.originalSubtaskCount).toBeNull();
 24 | 		});
 25 | 
 26 | 		test('should find tasks when JSON contains string IDs (normalized to numbers)', () => {
 27 | 			// Simulate tasks loaded from JSON with string IDs and mixed subtask notations
 28 | 			const tasksWithStringIds = [
 29 | 				{ id: '1', title: 'First Task' },
 30 | 				{
 31 | 					id: '2',
 32 | 					title: 'Second Task',
 33 | 					subtasks: [
 34 | 						{ id: '1', title: 'Subtask One' },
 35 | 						{ id: '2.2', title: 'Subtask Two (with dotted notation)' } // Testing dotted notation
 36 | 					]
 37 | 				},
 38 | 				{
 39 | 					id: '5',
 40 | 					title: 'Fifth Task',
 41 | 					subtasks: [
 42 | 						{ id: '5.1', title: 'Subtask with dotted ID' }, // Should normalize to 1
 43 | 						{ id: '3', title: 'Subtask with simple ID' } // Should stay as 3
 44 | 					]
 45 | 				}
 46 | 			];
 47 | 
 48 | 			// The readJSON function should normalize these IDs to numbers
 49 | 			// For this test, we'll manually normalize them to simulate what happens
 50 | 			tasksWithStringIds.forEach((task) => {
 51 | 				task.id = parseInt(task.id, 10);
 52 | 				if (task.subtasks) {
 53 | 					task.subtasks.forEach((subtask) => {
 54 | 						// Handle dotted notation like "5.1" -> extract the subtask part
 55 | 						if (typeof subtask.id === 'string' && subtask.id.includes('.')) {
 56 | 							const parts = subtask.id.split('.');
 57 | 							subtask.id = parseInt(parts[parts.length - 1], 10);
 58 | 						} else {
 59 | 							subtask.id = parseInt(subtask.id, 10);
 60 | 						}
 61 | 					});
 62 | 				}
 63 | 			});
 64 | 
 65 | 			// Test finding tasks by numeric ID
 66 | 			const result1 = findTaskById(tasksWithStringIds, 5);
 67 | 			expect(result1.task).toBeDefined();
 68 | 			expect(result1.task.id).toBe(5);
 69 | 			expect(result1.task.title).toBe('Fifth Task');
 70 | 
 71 | 			// Test finding tasks by string ID
 72 | 			const result2 = findTaskById(tasksWithStringIds, '5');
 73 | 			expect(result2.task).toBeDefined();
 74 | 			expect(result2.task.id).toBe(5);
 75 | 
 76 | 			// Test finding subtasks with normalized IDs
 77 | 			const result3 = findTaskById(tasksWithStringIds, '2.1');
 78 | 			expect(result3.task).toBeDefined();
 79 | 			expect(result3.task.id).toBe(1);
 80 | 			expect(result3.task.title).toBe('Subtask One');
 81 | 			expect(result3.task.isSubtask).toBe(true);
 82 | 
 83 | 			// Test subtask that was originally "2.2" (should be normalized to 2)
 84 | 			const result4 = findTaskById(tasksWithStringIds, '2.2');
 85 | 			expect(result4.task).toBeDefined();
 86 | 			expect(result4.task.id).toBe(2);
 87 | 			expect(result4.task.title).toBe('Subtask Two (with dotted notation)');
 88 | 
 89 | 			// Test subtask that was originally "5.1" (should be normalized to 1)
 90 | 			const result5 = findTaskById(tasksWithStringIds, '5.1');
 91 | 			expect(result5.task).toBeDefined();
 92 | 			expect(result5.task.id).toBe(1);
 93 | 			expect(result5.task.title).toBe('Subtask with dotted ID');
 94 | 
 95 | 			// Test subtask that was originally "3" (should stay as 3)
 96 | 			const result6 = findTaskById(tasksWithStringIds, '5.3');
 97 | 			expect(result6.task).toBeDefined();
 98 | 			expect(result6.task.id).toBe(3);
 99 | 			expect(result6.task.title).toBe('Subtask with simple ID');
100 | 		});
101 | 
102 | 		test('should find a subtask using dot notation', () => {
103 | 			const result = findTaskById(sampleTasks.tasks, '3.1');
104 | 			expect(result.task).toBeDefined();
105 | 			expect(result.task.id).toBe(1);
106 | 			expect(result.task.title).toBe('Create Header Component');
107 | 			expect(result.task.isSubtask).toBe(true);
108 | 			expect(result.task.parentTask.id).toBe(3);
109 | 			expect(result.originalSubtaskCount).toBeNull();
110 | 		});
111 | 
112 | 		test('should return null for non-existent task ID', () => {
113 | 			const result = findTaskById(sampleTasks.tasks, 99);
114 | 			expect(result.task).toBeNull();
115 | 			expect(result.originalSubtaskCount).toBeNull();
116 | 		});
117 | 
118 | 		test('should return null for non-existent subtask ID', () => {
119 | 			const result = findTaskById(sampleTasks.tasks, '3.99');
120 | 			expect(result.task).toBeNull();
121 | 			expect(result.originalSubtaskCount).toBeNull();
122 | 		});
123 | 
124 | 		test('should return null for non-existent parent task ID in subtask notation', () => {
125 | 			const result = findTaskById(sampleTasks.tasks, '99.1');
126 | 			expect(result.task).toBeNull();
127 | 			expect(result.originalSubtaskCount).toBeNull();
128 | 		});
129 | 
130 | 		test('should return null when tasks array is empty', () => {
131 | 			const result = findTaskById(emptySampleTasks.tasks, 1);
132 | 			expect(result.task).toBeNull();
133 | 			expect(result.originalSubtaskCount).toBeNull();
134 | 		});
135 | 		test('should work correctly when no complexity report is provided', () => {
136 | 			// Pass null as the complexity report
137 | 			const result = findTaskById(sampleTasks.tasks, 2, null);
138 | 
139 | 			expect(result.task).toBeDefined();
140 | 			expect(result.task.id).toBe(2);
141 | 			expect(result.task.complexityScore).toBeUndefined();
142 | 		});
143 | 		test('should work correctly when task has no complexity data in the provided report', () => {
144 | 			// Define a complexity report that doesn't include task 2
145 | 			const complexityReport = {
146 | 				complexityAnalysis: [{ taskId: 999, complexityScore: 5 }]
147 | 			};
148 | 
149 | 			const result = findTaskById(sampleTasks.tasks, 2, complexityReport);
150 | 
151 | 			expect(result.task).toBeDefined();
152 | 			expect(result.task.id).toBe(2);
153 | 			expect(result.task.complexityScore).toBeUndefined();
154 | 		});
155 | 
156 | 		test('should include complexity score when report is provided', () => {
157 | 			// Define the complexity report for this test
158 | 			const complexityReport = {
159 | 				meta: {
160 | 					generatedAt: '2023-01-01T00:00:00.000Z',
161 | 					tasksAnalyzed: 3,
162 | 					thresholdScore: 5
163 | 				},
164 | 				complexityAnalysis: [
165 | 					{
166 | 						taskId: 1,
167 | 						taskTitle: 'Initialize Project',
168 | 						complexityScore: 3,
169 | 						recommendedSubtasks: 2
170 | 					},
171 | 					{
172 | 						taskId: 2,
173 | 						taskTitle: 'Create Core Functionality',
174 | 						complexityScore: 8,
175 | 						recommendedSubtasks: 5
176 | 					},
177 | 					{
178 | 						taskId: 3,
179 | 						taskTitle: 'Implement UI Components',
180 | 						complexityScore: 6,
181 | 						recommendedSubtasks: 4
182 | 					}
183 | 				]
184 | 			};
185 | 
186 | 			const result = findTaskById(sampleTasks.tasks, 2, complexityReport);
187 | 
188 | 			expect(result.task).toBeDefined();
189 | 			expect(result.task.id).toBe(2);
190 | 			expect(result.task.complexityScore).toBe(8);
191 | 		});
192 | 	});
193 | });
194 | 
```

--------------------------------------------------------------------------------
/.taskmaster/reports/task-complexity-report_cc-kiro-hooks.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 | 	"meta": {
 3 | 		"generatedAt": "2025-07-22T09:41:10.517Z",
 4 | 		"tasksAnalyzed": 10,
 5 | 		"totalTasks": 10,
 6 | 		"analysisCount": 10,
 7 | 		"thresholdScore": 5,
 8 | 		"projectName": "Taskmaster",
 9 | 		"usedResearch": false
10 | 	},
11 | 	"complexityAnalysis": [
12 | 		{
13 | 			"taskId": 1,
14 | 			"taskTitle": "Implement Task Integration Layer (TIL) Core",
15 | 			"complexityScore": 8,
16 | 			"recommendedSubtasks": 5,
17 | 			"expansionPrompt": "Break down the TIL Core implementation into distinct components: hook registration system, task lifecycle management, event coordination, state persistence layer, and configuration validation. Each subtask should focus on a specific architectural component with clear interfaces and testable boundaries.",
18 | 			"reasoning": "This is a foundational component with multiple complex subsystems including event-driven architecture, API integration, state management, and configuration validation. The existing 5 subtasks are well-structured and appropriately sized."
19 | 		},
20 | 		{
21 | 			"taskId": 2,
22 | 			"taskTitle": "Develop Dependency Monitor with Taskmaster MCP Integration",
23 | 			"complexityScore": 7,
24 | 			"recommendedSubtasks": 4,
25 | 			"expansionPrompt": "Divide the dependency monitor into: dependency graph data structure implementation, circular dependency detection algorithm, Taskmaster MCP integration layer, and real-time notification system. Focus on performance optimization for large graphs and efficient caching strategies.",
26 | 			"reasoning": "Complex graph algorithms and real-time monitoring require careful implementation. The task involves sophisticated data structures, algorithm design, and API integration with performance constraints."
27 | 		},
28 | 		{
29 | 			"taskId": 3,
30 | 			"taskTitle": "Build Execution Manager with Priority Queue and Parallel Execution",
31 | 			"complexityScore": 8,
32 | 			"recommendedSubtasks": 5,
33 | 			"expansionPrompt": "Structure the execution manager into: priority queue implementation, resource conflict detection system, parallel execution coordinator, timeout and cancellation handler, and execution history persistence layer. Each component should handle specific aspects of concurrent task management.",
34 | 			"reasoning": "Managing concurrent execution with resource conflicts, priority scheduling, and persistence is highly complex. Requires careful synchronization, error handling, and performance optimization."
35 | 		},
36 | 		{
37 | 			"taskId": 4,
38 | 			"taskTitle": "Implement Safety Manager with Configurable Constraints and Emergency Controls",
39 | 			"complexityScore": 7,
40 | 			"recommendedSubtasks": 4,
41 | 			"expansionPrompt": "Break down into: constraint validation engine, emergency control system (stop/pause), user approval workflow implementation, and safety monitoring/audit logging. Each subtask should address specific safety aspects with fail-safe mechanisms.",
42 | 			"reasoning": "Safety systems require careful design with multiple fail-safes. The task involves validation logic, real-time controls, workflow management, and comprehensive logging."
43 | 		},
44 | 		{
45 | 			"taskId": 5,
46 | 			"taskTitle": "Develop Event-Based Hook Processor",
47 | 			"complexityScore": 6,
48 | 			"recommendedSubtasks": 4,
49 | 			"expansionPrompt": "Organize into: file system event integration, Git/VCS event listeners, build system event connectors, and event filtering/debouncing mechanism. Focus on modular event source integration with configurable processing pipelines.",
50 | 			"reasoning": "While conceptually straightforward, integrating multiple event sources with proper filtering and performance optimization requires careful implementation. Each event source has unique characteristics."
51 | 		},
52 | 		{
53 | 			"taskId": 6,
54 | 			"taskTitle": "Implement Prompt-Based Hook Processor with AI Integration",
55 | 			"complexityScore": 7,
56 | 			"recommendedSubtasks": 4,
57 | 			"expansionPrompt": "Divide into: prompt interception mechanism, NLP-based task suggestion engine, context injection system, and conversation-based status updater. Each component should handle specific aspects of AI conversation integration.",
58 | 			"reasoning": "AI integration with prompt analysis and dynamic context injection is complex. Requires understanding of conversation flow, relevance scoring, and seamless integration with existing systems."
59 | 		},
60 | 		{
61 | 			"taskId": 7,
62 | 			"taskTitle": "Create Update-Based Hook Processor for Automatic Progress Tracking",
63 | 			"complexityScore": 6,
64 | 			"recommendedSubtasks": 4,
65 | 			"expansionPrompt": "Structure as: code change monitor, acceptance criteria validator, dependency update propagator, and conflict detection/resolution system. Focus on accurate progress tracking and automated validation logic.",
66 | 			"reasoning": "Automatic progress tracking requires integration with version control and intelligent analysis of code changes. Conflict detection and dependency propagation add complexity."
67 | 		},
68 | 		{
69 | 			"taskId": 8,
70 | 			"taskTitle": "Develop Real-Time Automation Dashboard and User Controls",
71 | 			"complexityScore": 7,
72 | 			"recommendedSubtasks": 5,
73 | 			"expansionPrompt": "Break down into: WebSocket real-time communication layer, interactive dependency graph visualization, task queue and status displays, user control interfaces, and analytics/charting components. Each UI component should be modular and reusable.",
74 | 			"reasoning": "Building a responsive real-time dashboard with complex visualizations and interactive controls is challenging. Requires careful state management, performance optimization, and user experience design."
75 | 		},
76 | 		{
77 | 			"taskId": 9,
78 | 			"taskTitle": "Integrate Kiro IDE and Taskmaster MCP with Core Services",
79 | 			"complexityScore": 8,
80 | 			"recommendedSubtasks": 4,
81 | 			"expansionPrompt": "Organize into: KiroHookAdapter implementation, TaskmasterMCPAdapter development, error handling and retry logic layer, and IDE UI component integration. Focus on robust adapter patterns and comprehensive error recovery.",
82 | 			"reasoning": "End-to-end integration of multiple systems with different architectures is highly complex. Requires careful adapter design, extensive error handling, and thorough testing across all integration points."
83 | 		},
84 | 		{
85 | 			"taskId": 10,
86 | 			"taskTitle": "Implement Configuration Management and Safety Profiles",
87 | 			"complexityScore": 6,
88 | 			"recommendedSubtasks": 4,
89 | 			"expansionPrompt": "Divide into: visual configuration editor UI, JSON Schema validation engine, import/export functionality, and version control integration. Each component should provide intuitive configuration management with robust validation.",
90 | 			"reasoning": "While technically less complex than core systems, building an intuitive configuration editor with validation, versioning, and import/export requires careful UI/UX design and robust data handling."
91 | 		}
92 | 	]
93 | }
94 | 
```

--------------------------------------------------------------------------------
/apps/extension/src/components/TaskDetails/SubtasksSection.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import type React from 'react';
  2 | import { useState } from 'react';
  3 | import { Button } from '@/components/ui/button';
  4 | import { Label } from '@/components/ui/label';
  5 | import { Textarea } from '@/components/ui/textarea';
  6 | import { Badge } from '@/components/ui/badge';
  7 | import { CollapsibleSection } from '@/components/ui/CollapsibleSection';
  8 | import { Plus, Loader2 } from 'lucide-react';
  9 | import type { TaskMasterTask } from '../../webview/types';
 10 | import { getStatusDotColor } from '../constants';
 11 | 
 12 | interface SubtasksSectionProps {
 13 | 	currentTask: TaskMasterTask;
 14 | 	isSubtask: boolean;
 15 | 	sendMessage: (message: any) => Promise<any>;
 16 | 	onNavigateToTask: (taskId: string) => void;
 17 | }
 18 | 
 19 | export const SubtasksSection: React.FC<SubtasksSectionProps> = ({
 20 | 	currentTask,
 21 | 	isSubtask,
 22 | 	sendMessage,
 23 | 	onNavigateToTask
 24 | }) => {
 25 | 	const [isAddingSubtask, setIsAddingSubtask] = useState(false);
 26 | 	const [newSubtaskTitle, setNewSubtaskTitle] = useState('');
 27 | 	const [newSubtaskDescription, setNewSubtaskDescription] = useState('');
 28 | 	const [isSubmittingSubtask, setIsSubmittingSubtask] = useState(false);
 29 | 
 30 | 	const handleAddSubtask = async () => {
 31 | 		if (!currentTask || !newSubtaskTitle.trim() || isSubtask) {
 32 | 			return;
 33 | 		}
 34 | 
 35 | 		setIsSubmittingSubtask(true);
 36 | 		try {
 37 | 			await sendMessage({
 38 | 				type: 'addSubtask',
 39 | 				data: {
 40 | 					parentTaskId: currentTask.id,
 41 | 					subtaskData: {
 42 | 						title: newSubtaskTitle.trim(),
 43 | 						description: newSubtaskDescription.trim() || undefined,
 44 | 						status: 'pending'
 45 | 					}
 46 | 				}
 47 | 			});
 48 | 
 49 | 			// Reset form and close
 50 | 			setNewSubtaskTitle('');
 51 | 			setNewSubtaskDescription('');
 52 | 			setIsAddingSubtask(false);
 53 | 		} catch (error) {
 54 | 			console.error('❌ TaskDetailsView: Failed to add subtask:', error);
 55 | 		} finally {
 56 | 			setIsSubmittingSubtask(false);
 57 | 		}
 58 | 	};
 59 | 
 60 | 	const handleCancelAddSubtask = () => {
 61 | 		setIsAddingSubtask(false);
 62 | 		setNewSubtaskTitle('');
 63 | 		setNewSubtaskDescription('');
 64 | 	};
 65 | 
 66 | 	if (
 67 | 		!((currentTask.subtasks && currentTask.subtasks.length > 0) || !isSubtask)
 68 | 	) {
 69 | 		return null;
 70 | 	}
 71 | 
 72 | 	const rightElement = (
 73 | 		<>
 74 | 			{currentTask.subtasks && currentTask.subtasks.length > 0 && (
 75 | 				<span className="text-sm text-vscode-foreground/50">
 76 | 					{currentTask.subtasks?.filter((st) => st.status === 'done').length}/
 77 | 					{currentTask.subtasks?.length}
 78 | 				</span>
 79 | 			)}
 80 | 			{!isSubtask && (
 81 | 				<Button
 82 | 					variant="ghost"
 83 | 					size="sm"
 84 | 					className="ml-auto p-1 h-6 w-6 hover:bg-vscode-button-hoverBackground"
 85 | 					onClick={() => setIsAddingSubtask(true)}
 86 | 					title="Add subtask"
 87 | 				>
 88 | 					<Plus className="w-4 h-4" />
 89 | 				</Button>
 90 | 			)}
 91 | 		</>
 92 | 	);
 93 | 
 94 | 	return (
 95 | 		<CollapsibleSection
 96 | 			title="Sub-issues"
 97 | 			defaultExpanded={true}
 98 | 			rightElement={rightElement}
 99 | 		>
100 | 			<div className="space-y-3">
101 | 				{/* Add Subtask Form */}
102 | 				{isAddingSubtask && (
103 | 					<div className="bg-widget-background rounded-lg p-4 border border-widget-border">
104 | 						<h4 className="text-sm font-medium text-vscode-foreground mb-3">
105 | 							Add New Subtask
106 | 						</h4>
107 | 						<div className="space-y-3">
108 | 							<div>
109 | 								<Label
110 | 									htmlFor="subtask-title"
111 | 									className="block text-sm text-vscode-foreground/80 mb-1"
112 | 								>
113 | 									Title*
114 | 								</Label>
115 | 								<input
116 | 									id="subtask-title"
117 | 									type="text"
118 | 									placeholder="Enter subtask title..."
119 | 									value={newSubtaskTitle}
120 | 									onChange={(e) => setNewSubtaskTitle(e.target.value)}
121 | 									className="w-full px-3 py-2 text-sm bg-vscode-input-background border border-vscode-input-border text-vscode-input-foreground placeholder-vscode-input-foreground/50 rounded focus:border-vscode-focusBorder focus:ring-1 focus:ring-vscode-focusBorder"
122 | 									disabled={isSubmittingSubtask}
123 | 								/>
124 | 							</div>
125 | 
126 | 							<div>
127 | 								<Label
128 | 									htmlFor="subtask-description"
129 | 									className="block text-sm text-vscode-foreground/80 mb-1"
130 | 								>
131 | 									Description (Optional)
132 | 								</Label>
133 | 								<Textarea
134 | 									id="subtask-description"
135 | 									placeholder="Enter subtask description..."
136 | 									value={newSubtaskDescription}
137 | 									onChange={(e) => setNewSubtaskDescription(e.target.value)}
138 | 									className="min-h-[80px] bg-vscode-input-background border-vscode-input-border text-vscode-input-foreground placeholder-vscode-input-foreground/50 focus:border-vscode-focusBorder focus:ring-vscode-focusBorder"
139 | 									disabled={isSubmittingSubtask}
140 | 								/>
141 | 							</div>
142 | 
143 | 							<div className="flex gap-3 pt-2">
144 | 								<Button
145 | 									onClick={handleAddSubtask}
146 | 									disabled={!newSubtaskTitle.trim() || isSubmittingSubtask}
147 | 									className="bg-primary text-primary-foreground hover:bg-primary/90"
148 | 								>
149 | 									{isSubmittingSubtask ? (
150 | 										<>
151 | 											<Loader2 className="w-4 h-4 mr-2 animate-spin" />
152 | 											Adding...
153 | 										</>
154 | 									) : (
155 | 										<>
156 | 											<Plus className="w-4 h-4 mr-2" />
157 | 											Add Subtask
158 | 										</>
159 | 									)}
160 | 								</Button>
161 | 								<Button
162 | 									onClick={handleCancelAddSubtask}
163 | 									variant="outline"
164 | 									disabled={isSubmittingSubtask}
165 | 									className="border-widget-border"
166 | 								>
167 | 									Cancel
168 | 								</Button>
169 | 							</div>
170 | 						</div>
171 | 					</div>
172 | 				)}
173 | 
174 | 				{/* Subtasks List */}
175 | 				{currentTask.subtasks && currentTask.subtasks.length > 0 && (
176 | 					<div className="space-y-2">
177 | 						{currentTask.subtasks.map((subtask, index) => {
178 | 							const subtaskId = `${currentTask.id}.${index + 1}`;
179 | 
180 | 							return (
181 | 								<div
182 | 									key={subtask.id}
183 | 									className="flex items-center gap-3 p-3 rounded-md border border-textSeparator-foreground hover:border-vscode-border/70 transition-colors cursor-pointer"
184 | 									onClick={() => onNavigateToTask(subtaskId)}
185 | 								>
186 | 									<div
187 | 										className="w-4 h-4 rounded-full flex items-center justify-center"
188 | 										style={{
189 | 											backgroundColor: getStatusDotColor(subtask.status)
190 | 										}}
191 | 									/>
192 | 									<div className="flex-1 min-w-0">
193 | 										<p className="text-sm text-vscode-foreground truncate">
194 | 											{subtask.title}
195 | 										</p>
196 | 										{subtask.description && (
197 | 											<p className="text-xs text-vscode-foreground/60 truncate mt-0.5">
198 | 												{subtask.description}
199 | 											</p>
200 | 										)}
201 | 									</div>
202 | 									<div className="flex items-center gap-2 flex-shrink-0">
203 | 										<Badge
204 | 											variant="secondary"
205 | 											className="text-xs bg-secondary/20 border-secondary/30 text-secondary-foreground px-2 py-0.5"
206 | 										>
207 | 											{subtask.status === 'pending' ? 'todo' : subtask.status}
208 | 										</Badge>
209 | 									</div>
210 | 								</div>
211 | 							);
212 | 						})}
213 | 					</div>
214 | 				)}
215 | 			</div>
216 | 		</CollapsibleSection>
217 | 	);
218 | };
219 | 
```

--------------------------------------------------------------------------------
/mcp-server/src/custom-sdk/language-model.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * src/ai-providers/custom-sdk/mcp/language-model.js
  3 |  *
  4 |  * MCP Language Model implementation following AI SDK LanguageModelV1 interface.
  5 |  * Uses MCP session.requestSampling() for AI operations.
  6 |  */
  7 | 
  8 | import {
  9 | 	convertToMCPFormat,
 10 | 	convertFromMCPFormat
 11 | } from './message-converter.js';
 12 | import { MCPError, mapMCPError } from './errors.js';
 13 | import { extractJson } from './json-extractor.js';
 14 | import {
 15 | 	convertSchemaToInstructions,
 16 | 	enhancePromptForJSON
 17 | } from './schema-converter.js';
 18 | 
 19 | /**
 20 |  * MCP Language Model implementing AI SDK LanguageModelV1 interface
 21 |  */
 22 | export class MCPLanguageModel {
 23 | 	specificationVersion = 'v1';
 24 | 	defaultObjectGenerationMode = 'json';
 25 | 	supportsImageUrls = false;
 26 | 	supportsStructuredOutputs = true;
 27 | 
 28 | 	constructor(options) {
 29 | 		this.session = options.session; // MCP session object
 30 | 		this.modelId = options.modelId;
 31 | 		this.settings = options.settings || {};
 32 | 		this.provider = 'mcp-ai-sdk';
 33 | 		this.maxTokens = this.settings.maxTokens;
 34 | 		this.temperature = this.settings.temperature;
 35 | 
 36 | 		this.validateSession();
 37 | 	}
 38 | 
 39 | 	/**
 40 | 	 * Validate that the MCP session has required capabilities
 41 | 	 */
 42 | 	validateSession() {
 43 | 		if (!this.session?.clientCapabilities?.sampling) {
 44 | 			throw new MCPError('MCP session must have client sampling capabilities');
 45 | 		}
 46 | 	}
 47 | 
 48 | 	/**
 49 | 	 * Generate text using MCP session sampling
 50 | 	 * @param {object} options - Generation options
 51 | 	 * @param {Array} options.prompt - AI SDK prompt format
 52 | 	 * @param {AbortSignal} options.abortSignal - Abort signal
 53 | 	 * @returns {Promise<object>} Generation result in AI SDK format
 54 | 	 */
 55 | 	async doGenerate(options) {
 56 | 		try {
 57 | 			// Convert AI SDK prompt to MCP format
 58 | 			const { messages, systemPrompt } = convertToMCPFormat(options.prompt);
 59 | 
 60 | 			// Use MCP session.requestSampling (same as MCPRemoteProvider)
 61 | 			const response = await this.session.requestSampling(
 62 | 				{
 63 | 					messages,
 64 | 					systemPrompt,
 65 | 					temperature: this.settings.temperature,
 66 | 					maxTokens: this.settings.maxTokens,
 67 | 					includeContext: 'thisServer'
 68 | 				},
 69 | 				{
 70 | 					// signal: options.abortSignal,
 71 | 					timeout: 240000 // 4 minutes timeout
 72 | 				}
 73 | 			);
 74 | 
 75 | 			// Convert MCP response back to AI SDK format
 76 | 			const result = convertFromMCPFormat(response);
 77 | 
 78 | 			return {
 79 | 				text: result.text,
 80 | 				finishReason: result.finishReason || 'stop',
 81 | 				usage: {
 82 | 					promptTokens: result.usage?.inputTokens || 0,
 83 | 					completionTokens: result.usage?.outputTokens || 0,
 84 | 					totalTokens:
 85 | 						(result.usage?.inputTokens || 0) + (result.usage?.outputTokens || 0)
 86 | 				},
 87 | 				rawResponse: response,
 88 | 				warnings: result.warnings
 89 | 			};
 90 | 		} catch (error) {
 91 | 			throw mapMCPError(error);
 92 | 		}
 93 | 	}
 94 | 
 95 | 	/**
 96 | 	 * Generate structured object using MCP session sampling
 97 | 	 * @param {object} options - Generation options
 98 | 	 * @param {Array} options.prompt - AI SDK prompt format
 99 | 	 * @param {import('zod').ZodSchema} options.schema - Zod schema for validation
100 | 	 * @param {string} [options.mode='json'] - Generation mode ('json' or 'tool')
101 | 	 * @param {AbortSignal} options.abortSignal - Abort signal
102 | 	 * @returns {Promise<object>} Generation result with structured object
103 | 	 */
104 | 	async doGenerateObject(options) {
105 | 		try {
106 | 			const { schema, mode = 'json', ...restOptions } = options;
107 | 
108 | 			if (!schema) {
109 | 				throw new MCPError('Schema is required for object generation');
110 | 			}
111 | 
112 | 			// Convert schema to JSON instructions
113 | 			const objectName = restOptions.objectName || 'generated_object';
114 | 			const jsonInstructions = convertSchemaToInstructions(schema, objectName);
115 | 
116 | 			// Enhance prompt with JSON generation instructions
117 | 			const enhancedPrompt = enhancePromptForJSON(
118 | 				options.prompt,
119 | 				jsonInstructions
120 | 			);
121 | 
122 | 			// Convert enhanced prompt to MCP format
123 | 			const { messages, systemPrompt } = convertToMCPFormat(enhancedPrompt);
124 | 
125 | 			// Use MCP session.requestSampling with enhanced prompt
126 | 			const response = await this.session.requestSampling(
127 | 				{
128 | 					messages,
129 | 					systemPrompt,
130 | 					temperature: this.settings.temperature,
131 | 					maxTokens: this.settings.maxTokens,
132 | 					includeContext: 'thisServer'
133 | 				},
134 | 				{
135 | 					timeout: 240000 // 4 minutes timeout
136 | 				}
137 | 			);
138 | 
139 | 			// Convert MCP response back to AI SDK format
140 | 			const result = convertFromMCPFormat(response);
141 | 
142 | 			// Extract JSON from the response text
143 | 			const jsonText = extractJson(result.text);
144 | 
145 | 			// Parse and validate JSON
146 | 			let parsedObject;
147 | 			try {
148 | 				parsedObject = JSON.parse(jsonText);
149 | 			} catch (parseError) {
150 | 				throw new MCPError(
151 | 					`Failed to parse JSON response: ${parseError.message}. Response: ${result.text.substring(0, 200)}...`
152 | 				);
153 | 			}
154 | 
155 | 			// Validate against schema
156 | 			try {
157 | 				const validatedObject = schema.parse(parsedObject);
158 | 
159 | 				return {
160 | 					object: validatedObject,
161 | 					finishReason: result.finishReason || 'stop',
162 | 					usage: {
163 | 						promptTokens: result.usage?.inputTokens || 0,
164 | 						completionTokens: result.usage?.outputTokens || 0,
165 | 						totalTokens:
166 | 							(result.usage?.inputTokens || 0) +
167 | 							(result.usage?.outputTokens || 0)
168 | 					},
169 | 					rawResponse: response,
170 | 					warnings: result.warnings
171 | 				};
172 | 			} catch (validationError) {
173 | 				throw new MCPError(
174 | 					`Generated object does not match schema: ${validationError.message}. Generated: ${JSON.stringify(parsedObject, null, 2)}`
175 | 				);
176 | 			}
177 | 		} catch (error) {
178 | 			throw mapMCPError(error);
179 | 		}
180 | 	}
181 | 
182 | 	/**
183 | 	 * Stream text generation using MCP session sampling
184 | 	 * Note: MCP may not support native streaming, so this may simulate streaming
185 | 	 * @param {object} options - Generation options
186 | 	 * @returns {AsyncIterable} Stream of generation chunks
187 | 	 */
188 | 	async doStream(options) {
189 | 		try {
190 | 			// For now, simulate streaming by chunking the complete response
191 | 			// TODO: Implement native streaming if MCP supports it
192 | 			const result = await this.doGenerate(options);
193 | 
194 | 			// Create async generator that yields chunks
195 | 			return this.simulateStreaming(result);
196 | 		} catch (error) {
197 | 			throw mapMCPError(error);
198 | 		}
199 | 	}
200 | 
201 | 	/**
202 | 	 * Simulate streaming by chunking a complete response
203 | 	 * @param {object} result - Complete generation result
204 | 	 * @returns {AsyncIterable} Simulated stream chunks
205 | 	 */
206 | 	async *simulateStreaming(result) {
207 | 		const text = result.text;
208 | 		const chunkSize = Math.max(1, Math.floor(text.length / 10)); // 10 chunks
209 | 
210 | 		for (let i = 0; i < text.length; i += chunkSize) {
211 | 			const chunk = text.slice(i, i + chunkSize);
212 | 			const isLast = i + chunkSize >= text.length;
213 | 
214 | 			yield {
215 | 				type: 'text-delta',
216 | 				textDelta: chunk
217 | 			};
218 | 
219 | 			// Small delay to simulate streaming
220 | 			await new Promise((resolve) => setTimeout(resolve, 50));
221 | 		}
222 | 
223 | 		// Final chunk with finish reason and usage
224 | 		yield {
225 | 			type: 'finish',
226 | 			finishReason: result.finishReason,
227 | 			usage: result.usage
228 | 		};
229 | 	}
230 | }
231 | 
```

--------------------------------------------------------------------------------
/scripts/test-claude-errors.js:
--------------------------------------------------------------------------------

```javascript
  1 | #!/usr/bin/env node
  2 | 
  3 | /**
  4 |  * test-claude-errors.js
  5 |  *
  6 |  * A test script to verify the error handling and retry logic in the callClaude function.
  7 |  * This script creates a modified version of dev.js that simulates different error scenarios.
  8 |  */
  9 | 
 10 | import fs from 'fs';
 11 | import path from 'path';
 12 | import dotenv from 'dotenv';
 13 | import { fileURLToPath } from 'url';
 14 | import { dirname } from 'path';
 15 | import { execSync, spawn } from 'child_process';
 16 | 
 17 | const __filename = fileURLToPath(import.meta.url);
 18 | const __dirname = dirname(__filename);
 19 | 
 20 | // Load environment variables from .env file
 21 | dotenv.config();
 22 | 
 23 | // Create a simple PRD for testing
 24 | const createTestPRD = () => {
 25 | 	return `# Test PRD for Error Handling
 26 | 
 27 | ## Overview
 28 | This is a simple test PRD to verify the error handling in the callClaude function.
 29 | 
 30 | ## Requirements
 31 | 1. Create a simple web application
 32 | 2. Implement user authentication
 33 | 3. Add a dashboard for users
 34 | `;
 35 | };
 36 | 
 37 | // Create a modified version of dev.js that simulates errors
 38 | function createErrorSimulationScript(errorType, failureCount = 2) {
 39 | 	// Read the original dev.js file
 40 | 	const devJsPath = path.join(__dirname, 'dev.js');
 41 | 	const devJsContent = fs.readFileSync(devJsPath, 'utf8');
 42 | 
 43 | 	// Create a modified version that simulates errors
 44 | 	let modifiedContent = devJsContent;
 45 | 
 46 | 	// Find the anthropic.messages.create call and replace it with our mock
 47 | 	const anthropicCallRegex =
 48 | 		/const response = await anthropic\.messages\.create\(/;
 49 | 
 50 | 	let mockCode = '';
 51 | 
 52 | 	switch (errorType) {
 53 | 		case 'network':
 54 | 			mockCode = `
 55 |       // Mock for network error simulation
 56 |       let currentAttempt = 0;
 57 |       const failureCount = ${failureCount};
 58 |       
 59 |       // Simulate network error for the first few attempts
 60 |       currentAttempt++;
 61 |       console.log(\`[Mock] API call attempt \${currentAttempt}\`);
 62 |       
 63 |       if (currentAttempt <= failureCount) {
 64 |         console.log(\`[Mock] Simulating network error (attempt \${currentAttempt}/\${failureCount})\`);
 65 |         throw new Error('Network error: Connection refused');
 66 |       }
 67 |       
 68 |       const response = await anthropic.messages.create(`;
 69 | 			break;
 70 | 
 71 | 		case 'timeout':
 72 | 			mockCode = `
 73 |       // Mock for timeout error simulation
 74 |       let currentAttempt = 0;
 75 |       const failureCount = ${failureCount};
 76 |       
 77 |       // Simulate timeout error for the first few attempts
 78 |       currentAttempt++;
 79 |       console.log(\`[Mock] API call attempt \${currentAttempt}\`);
 80 |       
 81 |       if (currentAttempt <= failureCount) {
 82 |         console.log(\`[Mock] Simulating timeout error (attempt \${currentAttempt}/\${failureCount})\`);
 83 |         throw new Error('Request timed out after 60000ms');
 84 |       }
 85 |       
 86 |       const response = await anthropic.messages.create(`;
 87 | 			break;
 88 | 
 89 | 		case 'invalid-json':
 90 | 			mockCode = `
 91 |       // Mock for invalid JSON response
 92 |       let currentAttempt = 0;
 93 |       const failureCount = ${failureCount};
 94 |       
 95 |       // Simulate invalid JSON for the first few attempts
 96 |       currentAttempt++;
 97 |       console.log(\`[Mock] API call attempt \${currentAttempt}\`);
 98 |       
 99 |       if (currentAttempt <= failureCount) {
100 |         console.log(\`[Mock] Simulating invalid JSON response (attempt \${currentAttempt}/\${failureCount})\`);
101 |         return {
102 |           content: [
103 |             {
104 |               text: \`\`\`json\\n{"meta": {"projectName": "Test Project"}, "tasks": [{"id": 1, "title": "Task 1"\`
105 |             }
106 |           ]
107 |         };
108 |       }
109 |       
110 |       const response = await anthropic.messages.create(`;
111 | 			break;
112 | 
113 | 		case 'empty-tasks':
114 | 			mockCode = `
115 |       // Mock for empty tasks array
116 |       let currentAttempt = 0;
117 |       const failureCount = ${failureCount};
118 |       
119 |       // Simulate empty tasks array for the first few attempts
120 |       currentAttempt++;
121 |       console.log(\`[Mock] API call attempt \${currentAttempt}\`);
122 |       
123 |       if (currentAttempt <= failureCount) {
124 |         console.log(\`[Mock] Simulating empty tasks array (attempt \${currentAttempt}/\${failureCount})\`);
125 |         return {
126 |           content: [
127 |             {
128 |               text: \`\`\`json\\n{"meta": {"projectName": "Test Project"}, "tasks": []}\\n\`\`\`
129 |             }
130 |           ]
131 |         };
132 |       }
133 |       
134 |       const response = await anthropic.messages.create(`;
135 | 			break;
136 | 
137 | 		default:
138 | 			// No modification
139 | 			mockCode = `const response = await anthropic.messages.create(`;
140 | 	}
141 | 
142 | 	// Replace the anthropic call with our mock
143 | 	modifiedContent = modifiedContent.replace(anthropicCallRegex, mockCode);
144 | 
145 | 	// Write the modified script to a temporary file
146 | 	const tempScriptPath = path.join(__dirname, `temp-dev-${errorType}.js`);
147 | 	fs.writeFileSync(tempScriptPath, modifiedContent, 'utf8');
148 | 
149 | 	return tempScriptPath;
150 | }
151 | 
152 | // Function to run a test with a specific error type
153 | async function runErrorTest(errorType, numTasks = 5, failureCount = 2) {
154 | 	console.log(`\n=== Test: ${errorType.toUpperCase()} Error Simulation ===`);
155 | 
156 | 	// Create a test PRD
157 | 	const testPRD = createTestPRD();
158 | 	const testPRDPath = path.join(__dirname, `test-prd-${errorType}.txt`);
159 | 	fs.writeFileSync(testPRDPath, testPRD, 'utf8');
160 | 
161 | 	// Create a modified dev.js that simulates the specified error
162 | 	const tempScriptPath = createErrorSimulationScript(errorType, failureCount);
163 | 
164 | 	console.log(`Created test PRD at ${testPRDPath}`);
165 | 	console.log(`Created error simulation script at ${tempScriptPath}`);
166 | 	console.log(
167 | 		`Running with error type: ${errorType}, failure count: ${failureCount}, tasks: ${numTasks}`
168 | 	);
169 | 
170 | 	try {
171 | 		// Run the modified script
172 | 		execSync(
173 | 			`node ${tempScriptPath} parse-prd --input=${testPRDPath} --tasks=${numTasks}`,
174 | 			{
175 | 				stdio: 'inherit'
176 | 			}
177 | 		);
178 | 		console.log(`${errorType} error test completed successfully`);
179 | 	} catch (error) {
180 | 		console.error(`${errorType} error test failed:`, error.message);
181 | 	} finally {
182 | 		// Clean up temporary files
183 | 		if (fs.existsSync(tempScriptPath)) {
184 | 			fs.unlinkSync(tempScriptPath);
185 | 		}
186 | 		if (fs.existsSync(testPRDPath)) {
187 | 			fs.unlinkSync(testPRDPath);
188 | 		}
189 | 	}
190 | }
191 | 
192 | // Function to run all error tests
193 | async function runAllErrorTests() {
194 | 	console.log('Starting error handling tests for callClaude function...');
195 | 
196 | 	// Test 1: Network error with automatic retry
197 | 	await runErrorTest('network', 5, 2);
198 | 
199 | 	// Test 2: Timeout error with automatic retry
200 | 	await runErrorTest('timeout', 5, 2);
201 | 
202 | 	// Test 3: Invalid JSON response with task reduction
203 | 	await runErrorTest('invalid-json', 10, 2);
204 | 
205 | 	// Test 4: Empty tasks array with task reduction
206 | 	await runErrorTest('empty-tasks', 15, 2);
207 | 
208 | 	// Test 5: Exhausted retries (more failures than MAX_RETRIES)
209 | 	await runErrorTest('network', 5, 4);
210 | 
211 | 	console.log('\nAll error tests completed!');
212 | }
213 | 
214 | // Run the tests
215 | runAllErrorTests().catch((error) => {
216 | 	console.error('Error running tests:', error);
217 | 	process.exit(1);
218 | });
219 | 
```

--------------------------------------------------------------------------------
/apps/docs/command-reference.mdx:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "Task Master Commands"
  3 | description: "A comprehensive reference of all available Task Master commands"
  4 | ---
  5 | 
  6 | <AccordionGroup>
  7 |   <Accordion title="Parse PRD">
  8 |     ```bash
  9 |     # Parse a PRD file and generate tasks
 10 |     task-master parse-prd <prd-file.txt>
 11 | 
 12 |     # Limit the number of tasks generated
 13 |     task-master parse-prd <prd-file.txt> --num-tasks=10
 14 |     ```
 15 |   </Accordion>
 16 | 
 17 |   <Accordion title="List Tasks">
 18 |     ```bash
 19 |     # List all tasks
 20 |     task-master list
 21 | 
 22 |     # List tasks with a specific status
 23 |     task-master list --status=<status>
 24 | 
 25 |     # List tasks with subtasks
 26 |     task-master list --with-subtasks
 27 | 
 28 |     # List tasks with a specific status and include subtasks
 29 |     task-master list --status=<status> --with-subtasks
 30 |     ```
 31 |   </Accordion>
 32 | 
 33 |   <Accordion title="Show Next Task">
 34 |     ```bash
 35 |     # Show the next task to work on based on dependencies and status
 36 |     task-master next
 37 |     ```
 38 |   </Accordion>
 39 | 
 40 |   <Accordion title="Show Specific Task">
 41 |     ```bash
 42 |     # Show details of a specific task
 43 |     task-master show <id>
 44 |     # or
 45 |     task-master show --id=<id>
 46 | 
 47 |     # View a specific subtask (e.g., subtask 2 of task 1)
 48 |     task-master show 1.2
 49 |     ```
 50 |   </Accordion>
 51 | 
 52 |   <Accordion title="Update Tasks">
 53 |     ```bash
 54 |     # Update tasks from a specific ID and provide context
 55 |     task-master update --from=<id> --prompt="<prompt>"
 56 |     ```
 57 |   </Accordion>
 58 | 
 59 |   <Accordion title="Update a Specific Task">
 60 |     ```bash
 61 |     # Update a single task by ID with new information
 62 |     task-master update-task --id=<id> --prompt="<prompt>"
 63 | 
 64 |     # Use research-backed updates with Perplexity AI
 65 |     task-master update-task --id=<id> --prompt="<prompt>" --research
 66 |     ```
 67 |   </Accordion>
 68 | 
 69 |   <Accordion title="Update a Subtask">
 70 |     ```bash
 71 |     # Append additional information to a specific subtask
 72 |     task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>"
 73 | 
 74 |     # Example: Add details about API rate limiting to subtask 2 of task 5
 75 |     task-master update-subtask --id=5.2 --prompt="Add rate limiting of 100 requests per minute"
 76 | 
 77 |     # Use research-backed updates with Perplexity AI
 78 |     task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>" --research
 79 |     ```
 80 | 
 81 |     Unlike the `update-task` command which replaces task information, the `update-subtask` command _appends_ new information to the existing subtask details, marking it with a timestamp. This is useful for iteratively enhancing subtasks while preserving the original content.
 82 |   </Accordion>
 83 | 
 84 |   <Accordion title="Generate Task Files">
 85 |     ```bash
 86 |     # Generate individual task files from tasks.json
 87 |     task-master generate
 88 |     ```
 89 |   </Accordion>
 90 | 
 91 |   <Accordion title="Set Task Status">
 92 |     ```bash
 93 |     # Set status of a single task
 94 |     task-master set-status --id=<id> --status=<status>
 95 | 
 96 |     # Set status for multiple tasks
 97 |     task-master set-status --id=1,2,3 --status=<status>
 98 | 
 99 |     # Set status for subtasks
100 |     task-master set-status --id=1.1,1.2 --status=<status>
101 |     ```
102 | 
103 |     When marking a task as "done", all of its subtasks will automatically be marked as "done" as well.
104 |   </Accordion>
105 | 
106 |   <Accordion title="Expand Tasks">
107 |     ```bash
108 |     # Expand a specific task with subtasks
109 |     task-master expand --id=<id> --num=<number>
110 | 
111 |     # Expand with additional context
112 |     task-master expand --id=<id> --prompt="<context>"
113 | 
114 |     # Expand all pending tasks
115 |     task-master expand --all
116 | 
117 |     # Force regeneration of subtasks for tasks that already have them
118 |     task-master expand --all --force
119 | 
120 |     # Research-backed subtask generation for a specific task
121 |     task-master expand --id=<id> --research
122 | 
123 |     # Research-backed generation for all tasks
124 |     task-master expand --all --research
125 |     ```
126 |   </Accordion>
127 | 
128 |   <Accordion title="Clear Subtasks">
129 |     ```bash
130 |     # Clear subtasks from a specific task
131 |     task-master clear-subtasks --id=<id>
132 | 
133 |     # Clear subtasks from multiple tasks
134 |     task-master clear-subtasks --id=1,2,3
135 | 
136 |     # Clear subtasks from all tasks
137 |     task-master clear-subtasks --all
138 |     ```
139 |   </Accordion>
140 | 
141 |   <Accordion title="Analyze Task Complexity">
142 |     ```bash
143 |     # Analyze complexity of all tasks
144 |     task-master analyze-complexity
145 | 
146 |     # Save report to a custom location
147 |     task-master analyze-complexity --output=my-report.json
148 | 
149 |     # Use a specific LLM model
150 |     task-master analyze-complexity --model=claude-3-opus-20240229
151 | 
152 |     # Set a custom complexity threshold (1-10)
153 |     task-master analyze-complexity --threshold=6
154 | 
155 |     # Use an alternative tasks file
156 |     task-master analyze-complexity --file=custom-tasks.json
157 | 
158 |     # Use Perplexity AI for research-backed complexity analysis
159 |     task-master analyze-complexity --research
160 |     ```
161 |   </Accordion>
162 | 
163 |   <Accordion title="View Complexity Report">
164 |     ```bash
165 |     # Display the task complexity analysis report
166 |     task-master complexity-report
167 | 
168 |     # View a report at a custom location
169 |     task-master complexity-report --file=my-report.json
170 |     ```
171 |   </Accordion>
172 | 
173 |   <Accordion title="Managing Task Dependencies">
174 |     ```bash
175 |     # Add a dependency to a task
176 |     task-master add-dependency --id=<id> --depends-on=<id>
177 | 
178 |     # Remove a dependency from a task
179 |     task-master remove-dependency --id=<id> --depends-on=<id>
180 | 
181 |     # Validate dependencies without fixing them
182 |     task-master validate-dependencies
183 | 
184 |     # Find and fix invalid dependencies automatically
185 |     task-master fix-dependencies
186 |     ```
187 |   </Accordion>
188 | 
189 |   <Accordion title="Add a New Task">
190 |     ```bash
191 |     # Add a new task using AI
192 |     task-master add-task --prompt="Description of the new task"
193 | 
194 |     # Add a task with dependencies
195 |     task-master add-task --prompt="Description" --dependencies=1,2,3
196 | 
197 |     # Add a task with priority
198 |     task-master add-task --prompt="Description" --priority=high
199 |     ```
200 |   </Accordion>
201 | 
202 |   <Accordion title="Initialize a Project">
203 |     ```bash
204 |     # Initialize a new project with Task Master structure
205 |     task-master init
206 |     ```
207 |   </Accordion>
208 | 
209 |   <Accordion title="TDD Workflow (Autopilot)">
210 |     ```bash
211 |     # Start autonomous TDD workflow for a task
212 |     task-master autopilot start <taskId>
213 | 
214 |     # Get next action with context
215 |     task-master autopilot next
216 | 
217 |     # Complete phase with test results
218 |     task-master autopilot complete --results '{"total":N,"passed":N,"failed":N}'
219 | 
220 |     # Commit changes
221 |     task-master autopilot commit
222 | 
223 |     # Check workflow status
224 |     task-master autopilot status
225 | 
226 |     # Resume interrupted workflow
227 |     task-master autopilot resume
228 | 
229 |     # Abort workflow
230 |     task-master autopilot abort
231 |     ```
232 | 
233 |     The TDD workflow enforces RED → GREEN → COMMIT cycles for each subtask. See [AI Agent Integration](/tdd-workflow/ai-agent-integration) for details.
234 |   </Accordion>
235 | </AccordionGroup>
236 | 
```

--------------------------------------------------------------------------------
/.github/workflows/log-issue-events.yml:
--------------------------------------------------------------------------------

```yaml
  1 | name: Log GitHub Issue Events
  2 | 
  3 | on:
  4 |   issues:
  5 |     types: [opened, closed]
  6 | 
  7 | jobs:
  8 |   log-issue-created:
  9 |     if: github.event.action == 'opened'
 10 |     runs-on: ubuntu-latest
 11 |     timeout-minutes: 5
 12 |     permissions:
 13 |       contents: read
 14 |       issues: read
 15 | 
 16 |     steps:
 17 |       - name: Log issue creation to Statsig
 18 |         env:
 19 |           STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
 20 |         run: |
 21 |           ISSUE_NUMBER=${{ github.event.issue.number }}
 22 |           REPO=${{ github.repository }}
 23 |           ISSUE_TITLE=$(echo '${{ github.event.issue.title }}' | sed "s/'/'\\\\''/g")
 24 |           AUTHOR="${{ github.event.issue.user.login }}"
 25 |           CREATED_AT="${{ github.event.issue.created_at }}"
 26 | 
 27 |           if [ -z "$STATSIG_API_KEY" ]; then
 28 |             echo "STATSIG_API_KEY not found, skipping Statsig logging"
 29 |             exit 0
 30 |           fi
 31 | 
 32 |           # Prepare the event payload
 33 |           EVENT_PAYLOAD=$(jq -n \
 34 |             --arg issue_number "$ISSUE_NUMBER" \
 35 |             --arg repo "$REPO" \
 36 |             --arg title "$ISSUE_TITLE" \
 37 |             --arg author "$AUTHOR" \
 38 |             --arg created_at "$CREATED_AT" \
 39 |             '{
 40 |               events: [{
 41 |                 eventName: "github_issue_created",
 42 |                 value: 1,
 43 |                 metadata: {
 44 |                   repository: $repo,
 45 |                   issue_number: ($issue_number | tonumber),
 46 |                   issue_title: $title,
 47 |                   issue_author: $author,
 48 |                   created_at: $created_at
 49 |                 },
 50 |                 time: (now | floor | tostring)
 51 |               }]
 52 |             }')
 53 | 
 54 |           # Send to Statsig API
 55 |           echo "Logging issue creation to Statsig for issue #${ISSUE_NUMBER}"
 56 | 
 57 |           RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
 58 |             -H "Content-Type: application/json" \
 59 |             -H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
 60 |             -d "$EVENT_PAYLOAD")
 61 | 
 62 |           HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
 63 |           BODY=$(echo "$RESPONSE" | head -n-1)
 64 | 
 65 |           if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
 66 |             echo "Successfully logged issue creation for issue #${ISSUE_NUMBER}"
 67 |           else
 68 |             echo "Failed to log issue creation for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
 69 |           fi
 70 | 
 71 |   log-issue-closed:
 72 |     if: github.event.action == 'closed'
 73 |     runs-on: ubuntu-latest
 74 |     timeout-minutes: 5
 75 |     permissions:
 76 |       contents: read
 77 |       issues: read
 78 | 
 79 |     steps:
 80 |       - name: Log issue closure to Statsig
 81 |         env:
 82 |           STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
 83 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 84 |         run: |
 85 |           ISSUE_NUMBER=${{ github.event.issue.number }}
 86 |           REPO=${{ github.repository }}
 87 |           ISSUE_TITLE=$(echo '${{ github.event.issue.title }}' | sed "s/'/'\\\\''/g")
 88 |           CLOSED_BY="${{ github.event.issue.closed_by.login }}"
 89 |           CLOSED_AT="${{ github.event.issue.closed_at }}"
 90 |           STATE_REASON="${{ github.event.issue.state_reason }}"
 91 | 
 92 |           if [ -z "$STATSIG_API_KEY" ]; then
 93 |             echo "STATSIG_API_KEY not found, skipping Statsig logging"
 94 |             exit 0
 95 |           fi
 96 | 
 97 |           # Get additional issue data via GitHub API
 98 |           echo "Fetching additional issue data for #${ISSUE_NUMBER}"
 99 |           ISSUE_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
100 |             -H "Accept: application/vnd.github.v3+json" \
101 |             "https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}")
102 | 
103 |           COMMENTS_COUNT=$(echo "$ISSUE_DATA" | jq -r '.comments')
104 | 
105 |           # Get reactions data
106 |           REACTIONS_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
107 |             -H "Accept: application/vnd.github.v3+json" \
108 |             "https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}/reactions")
109 | 
110 |           REACTIONS_COUNT=$(echo "$REACTIONS_DATA" | jq '. | length')
111 | 
112 |           # Check if issue was closed automatically (by checking if closed_by is a bot)
113 |           CLOSED_AUTOMATICALLY="false"
114 |           if [[ "$CLOSED_BY" == *"[bot]"* ]]; then
115 |             CLOSED_AUTOMATICALLY="true"
116 |           fi
117 | 
118 |           # Check if closed as duplicate by state_reason
119 |           CLOSED_AS_DUPLICATE="false"
120 |           if [ "$STATE_REASON" = "duplicate" ]; then
121 |             CLOSED_AS_DUPLICATE="true"
122 |           fi
123 | 
124 |           # Prepare the event payload
125 |           EVENT_PAYLOAD=$(jq -n \
126 |             --arg issue_number "$ISSUE_NUMBER" \
127 |             --arg repo "$REPO" \
128 |             --arg title "$ISSUE_TITLE" \
129 |             --arg closed_by "$CLOSED_BY" \
130 |             --arg closed_at "$CLOSED_AT" \
131 |             --arg state_reason "$STATE_REASON" \
132 |             --arg comments_count "$COMMENTS_COUNT" \
133 |             --arg reactions_count "$REACTIONS_COUNT" \
134 |             --arg closed_automatically "$CLOSED_AUTOMATICALLY" \
135 |             --arg closed_as_duplicate "$CLOSED_AS_DUPLICATE" \
136 |             '{
137 |               events: [{
138 |                 eventName: "github_issue_closed",
139 |                 value: 1,
140 |                 metadata: {
141 |                   repository: $repo,
142 |                   issue_number: ($issue_number | tonumber),
143 |                   issue_title: $title,
144 |                   closed_by: $closed_by,
145 |                   closed_at: $closed_at,
146 |                   state_reason: $state_reason,
147 |                   comments_count: ($comments_count | tonumber),
148 |                   reactions_count: ($reactions_count | tonumber),
149 |                   closed_automatically: ($closed_automatically | test("true")),
150 |                   closed_as_duplicate: ($closed_as_duplicate | test("true"))
151 |                 },
152 |                 time: (now | floor | tostring)
153 |               }]
154 |             }')
155 | 
156 |           # Send to Statsig API
157 |           echo "Logging issue closure to Statsig for issue #${ISSUE_NUMBER}"
158 | 
159 |           RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
160 |             -H "Content-Type: application/json" \
161 |             -H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
162 |             -d "$EVENT_PAYLOAD")
163 | 
164 |           HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
165 |           BODY=$(echo "$RESPONSE" | head -n-1)
166 | 
167 |           if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
168 |             echo "Successfully logged issue closure for issue #${ISSUE_NUMBER}"
169 |             echo "Closed by: $CLOSED_BY"
170 |             echo "Comments: $COMMENTS_COUNT"
171 |             echo "Reactions: $REACTIONS_COUNT"
172 |             echo "Closed automatically: $CLOSED_AUTOMATICALLY"
173 |             echo "Closed as duplicate: $CLOSED_AS_DUPLICATE"
174 |           else
175 |             echo "Failed to log issue closure for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
176 |           fi
177 | 
```

--------------------------------------------------------------------------------
/docs/examples.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Example Cursor AI Interactions
  2 | 
  3 | Here are some common interactions with Cursor AI when using Task Master:
  4 | 
  5 | ## Starting a new project
  6 | 
  7 | ```
  8 | I've just initialized a new project with Claude Task Master. I have a PRD at .taskmaster/docs/prd.txt.
  9 | Can you help me parse it and set up the initial tasks?
 10 | ```
 11 | 
 12 | ## Working on tasks
 13 | 
 14 | ```
 15 | What's the next task I should work on? Please consider dependencies and priorities.
 16 | ```
 17 | 
 18 | ## Implementing a specific task
 19 | 
 20 | ```
 21 | I'd like to implement task 4. Can you help me understand what needs to be done and how to approach it?
 22 | ```
 23 | 
 24 | ## Viewing multiple tasks
 25 | 
 26 | ```
 27 | Can you show me tasks 1, 3, and 5 so I can understand their relationship?
 28 | ```
 29 | 
 30 | ```
 31 | I need to see the status of tasks 44, 55, and their subtasks. Can you show me those?
 32 | ```
 33 | 
 34 | ```
 35 | Show me tasks 10, 12, and 15 and give me some batch actions I can perform on them.
 36 | ```
 37 | 
 38 | ## Managing subtasks
 39 | 
 40 | ```
 41 | I need to regenerate the subtasks for task 3 with a different approach. Can you help me clear and regenerate them?
 42 | ```
 43 | 
 44 | ## Handling changes
 45 | 
 46 | ```
 47 | I've decided to use MongoDB instead of PostgreSQL. Can you update all future tasks to reflect this change?
 48 | ```
 49 | 
 50 | ## Completing work
 51 | 
 52 | ```
 53 | I've finished implementing the authentication system described in task 2. All tests are passing.
 54 | Please mark it as complete and tell me what I should work on next.
 55 | ```
 56 | 
 57 | ## Reorganizing tasks
 58 | 
 59 | ```
 60 | I think subtask 5.2 would fit better as part of task 7. Can you move it there?
 61 | ```
 62 | 
 63 | (Agent runs: `task-master move --from=5.2 --to=7.3`)
 64 | 
 65 | ```
 66 | Task 8 should actually be a subtask of task 4. Can you reorganize this?
 67 | ```
 68 | 
 69 | (Agent runs: `task-master move --from=8 --to=4.1`)
 70 | 
 71 | ```
 72 | I just merged the main branch and there's a conflict in tasks.json. My teammates created tasks 10-15 on their branch while I created tasks 10-12 on my branch. Can you help me resolve this by moving my tasks?
 73 | ```
 74 | 
 75 | (Agent runs:
 76 | 
 77 | ```bash
 78 | task-master move --from=10 --to=16
 79 | task-master move --from=11 --to=17
 80 | task-master move --from=12 --to=18
 81 | ```
 82 | 
 83 | )
 84 | 
 85 | ## Analyzing complexity
 86 | 
 87 | ```
 88 | Can you analyze the complexity of our tasks to help me understand which ones need to be broken down further?
 89 | ```
 90 | 
 91 | ## Viewing complexity report
 92 | 
 93 | ```
 94 | Can you show me the complexity report in a more readable format?
 95 | ```
 96 | 
 97 | ### Breaking Down Complex Tasks
 98 | 
 99 | ```
100 | Task 5 seems complex. Can you break it down into subtasks?
101 | ```
102 | 
103 | (Agent runs: `task-master expand --id=5`)
104 | 
105 | ```
106 | Please break down task 5 using research-backed generation.
107 | ```
108 | 
109 | (Agent runs: `task-master expand --id=5 --research`)
110 | 
111 | ### Updating Tasks with Research
112 | 
113 | ```
114 | We need to update task 15 based on the latest React Query v5 changes. Can you research this and update the task?
115 | ```
116 | 
117 | (Agent runs: `task-master update-task --id=15 --prompt="Update based on React Query v5 changes" --research`)
118 | 
119 | ### Adding Tasks with Research
120 | 
121 | ```
122 | Please add a new task to implement user profile image uploads using Cloudinary, research the best approach.
123 | ```
124 | 
125 | (Agent runs: `task-master add-task --prompt="Implement user profile image uploads using Cloudinary" --research`)
126 | 
127 | ## Research-Driven Development
128 | 
129 | ### Getting Fresh Information
130 | 
131 | ```
132 | Research the latest best practices for implementing JWT authentication in Node.js applications.
133 | ```
134 | 
135 | (Agent runs: `task-master research "Latest best practices for JWT authentication in Node.js"`)
136 | 
137 | ### Research with Project Context
138 | 
139 | ```
140 | I'm working on task 15 which involves API optimization. Can you research current best practices for our specific implementation?
141 | ```
142 | 
143 | (Agent runs: `task-master research "API optimization best practices" --id=15 --files=src/api.js`)
144 | 
145 | ### Research Before Implementation
146 | 
147 | ```
148 | Before I implement task 8 (React Query integration), can you research the latest React Query v5 patterns and any breaking changes?
149 | ```
150 | 
151 | (Agent runs: `task-master research "React Query v5 patterns and breaking changes" --id=8`)
152 | 
153 | ### Research and Update Pattern
154 | 
155 | ```
156 | Research the latest security recommendations for Express.js applications and update our authentication task with the findings.
157 | ```
158 | 
159 | (Agent runs:
160 | 
161 | 1. `task-master research "Latest Express.js security recommendations" --id=12`
162 | 2. `task-master update-subtask --id=12.3 --prompt="Updated with latest security findings: [research results]"`)
163 | 
164 | ### Research for Debugging
165 | 
166 | ```
167 | I'm having issues with our WebSocket implementation in task 20. Can you research common WebSocket problems and solutions?
168 | ```
169 | 
170 | (Agent runs: `task-master research "Common WebSocket implementation problems and solutions" --id=20 --files=src/websocket.js`)
171 | 
172 | ### Research Technology Comparisons
173 | 
174 | ```
175 | We need to choose between Redis and Memcached for caching. Can you research the current recommendations for our use case?
176 | ```
177 | 
178 | (Agent runs: `task-master research "Redis vs Memcached 2024 comparison for session caching" --tree`)
179 | 
180 | ## Git Integration and Tag Management
181 | 
182 | ### Creating Tags for Feature Branches
183 | 
184 | ```
185 | I'm starting work on a new feature branch for user authentication. Can you create a matching task tag?
186 | ```
187 | 
188 | (Agent runs: `task-master add-tag --from-branch`)
189 | 
190 | ### Creating Named Tags
191 | 
192 | ```
193 | Create a new tag called 'api-v2' for our API redesign work.
194 | ```
195 | 
196 | (Agent runs: `task-master add-tag api-v2 --description="API v2 redesign tasks"`)
197 | 
198 | ### Switching Tag Contexts
199 | 
200 | ```
201 | Switch to the 'testing' tag so I can work on QA tasks.
202 | ```
203 | 
204 | (Agent runs: `task-master use-tag testing`)
205 | 
206 | ### Copying Tasks Between Tags
207 | 
208 | ```
209 | I need to copy the current tasks to a new 'hotfix' tag for urgent fixes.
210 | ```
211 | 
212 | (Agent runs: `task-master add-tag hotfix --copy-from-current --description="Urgent hotfix tasks"`)
213 | 
214 | ### Managing Multiple Contexts
215 | 
216 | ```
217 | Show me all available tags and their current status.
218 | ```
219 | 
220 | (Agent runs: `task-master tags --show-metadata`)
221 | 
222 | ### Tag Cleanup
223 | 
224 | ```
225 | I've finished the 'user-auth' feature and merged the branch. Can you clean up the tag?
226 | ```
227 | 
228 | (Agent runs: `task-master delete-tag user-auth`)
229 | 
230 | ### Working with Tag-Specific Tasks
231 | 
232 | ```
233 | List all tasks in the 'api-v2' tag context.
234 | ```
235 | 
236 | (Agent runs: `task-master use-tag api-v2` then `task-master list`)
237 | 
238 | ### Branch-Based Development Workflow
239 | 
240 | ```
241 | I'm switching to work on the 'feature/payments' branch. Can you set up the task context for this?
242 | ```
243 | 
244 | (Agent runs:
245 | 1. `git checkout feature/payments`
246 | 2. `task-master add-tag --from-branch --description="Payment system implementation"`
247 | 3. `task-master list` to show tasks in the new context)
248 | 
249 | ### Parallel Feature Development
250 | 
251 | ```
252 | I need to work on both authentication and payment features simultaneously. How should I organize the tasks?
253 | ```
254 | 
255 | (Agent suggests and runs:
256 | 1. `task-master add-tag auth --description="Authentication feature tasks"`
257 | 2. `task-master add-tag payments --description="Payment system tasks"`
258 | 3. `task-master use-tag auth` to start with authentication work)
259 | 
```

--------------------------------------------------------------------------------
/apps/mcp/src/tools/autopilot/commit.tool.ts:
--------------------------------------------------------------------------------

```typescript
  1 | /**
  2 |  * @fileoverview autopilot-commit MCP tool
  3 |  * Create a git commit with automatic staging and message generation
  4 |  */
  5 | 
  6 | import { z } from 'zod';
  7 | import {
  8 | 	handleApiResult,
  9 | 	withNormalizedProjectRoot
 10 | } from '../../shared/utils.js';
 11 | import type { MCPContext } from '../../shared/types.js';
 12 | import { WorkflowService, GitAdapter, CommitMessageGenerator } from '@tm/core';
 13 | import type { FastMCP } from 'fastmcp';
 14 | 
 15 | const CommitSchema = z.object({
 16 | 	projectRoot: z
 17 | 		.string()
 18 | 		.describe('Absolute path to the project root directory'),
 19 | 	files: z
 20 | 		.array(z.string())
 21 | 		.optional()
 22 | 		.describe(
 23 | 			'Specific files to stage (relative to project root). If not provided, stages all changes.'
 24 | 		),
 25 | 	customMessage: z
 26 | 		.string()
 27 | 		.optional()
 28 | 		.describe('Custom commit message to use instead of auto-generated message')
 29 | });
 30 | 
 31 | type CommitArgs = z.infer<typeof CommitSchema>;
 32 | 
 33 | /**
 34 |  * Register the autopilot_commit tool with the MCP server
 35 |  */
 36 | export function registerAutopilotCommitTool(server: FastMCP) {
 37 | 	server.addTool({
 38 | 		name: 'autopilot_commit',
 39 | 		description:
 40 | 			'Create a git commit with automatic staging, message generation, and metadata embedding. Generates appropriate commit messages based on subtask context and TDD phase.',
 41 | 		parameters: CommitSchema,
 42 | 		execute: withNormalizedProjectRoot(
 43 | 			async (args: CommitArgs, context: MCPContext) => {
 44 | 				const { projectRoot, files, customMessage } = args;
 45 | 
 46 | 				try {
 47 | 					context.log.info(`Creating commit for workflow in ${projectRoot}`);
 48 | 
 49 | 					const workflowService = new WorkflowService(projectRoot);
 50 | 
 51 | 					// Check if workflow exists
 52 | 					if (!(await workflowService.hasWorkflow())) {
 53 | 						return handleApiResult({
 54 | 							result: {
 55 | 								success: false,
 56 | 								error: {
 57 | 									message:
 58 | 										'No active workflow found. Start a workflow with autopilot_start'
 59 | 								}
 60 | 							},
 61 | 							log: context.log,
 62 | 							projectRoot
 63 | 						});
 64 | 					}
 65 | 
 66 | 					// Resume workflow
 67 | 					await workflowService.resumeWorkflow();
 68 | 					const status = workflowService.getStatus();
 69 | 					const workflowContext = workflowService.getContext();
 70 | 
 71 | 					// Verify we're in COMMIT phase
 72 | 					if (status.tddPhase !== 'COMMIT') {
 73 | 						context.log.warn(
 74 | 							`Not in COMMIT phase (currently in ${status.tddPhase})`
 75 | 						);
 76 | 						return handleApiResult({
 77 | 							result: {
 78 | 								success: false,
 79 | 								error: {
 80 | 									message: `Cannot commit: currently in ${status.tddPhase} phase. Complete the ${status.tddPhase} phase first using autopilot_complete_phase`
 81 | 								}
 82 | 							},
 83 | 							log: context.log,
 84 | 							projectRoot
 85 | 						});
 86 | 					}
 87 | 
 88 | 					// Verify there's an active subtask
 89 | 					if (!status.currentSubtask) {
 90 | 						return handleApiResult({
 91 | 							result: {
 92 | 								success: false,
 93 | 								error: { message: 'No active subtask to commit' }
 94 | 							},
 95 | 							log: context.log,
 96 | 							projectRoot
 97 | 						});
 98 | 					}
 99 | 
100 | 					// Initialize git adapter
101 | 					const gitAdapter = new GitAdapter(projectRoot);
102 | 
103 | 					// Stage files
104 | 					try {
105 | 						if (files && files.length > 0) {
106 | 							await gitAdapter.stageFiles(files);
107 | 							context.log.info(`Staged ${files.length} files`);
108 | 						} else {
109 | 							await gitAdapter.stageFiles(['.']);
110 | 							context.log.info('Staged all changes');
111 | 						}
112 | 					} catch (error: any) {
113 | 						context.log.error(`Failed to stage files: ${error.message}`);
114 | 						return handleApiResult({
115 | 							result: {
116 | 								success: false,
117 | 								error: { message: `Failed to stage files: ${error.message}` }
118 | 							},
119 | 							log: context.log,
120 | 							projectRoot
121 | 						});
122 | 					}
123 | 
124 | 					// Check if there are staged changes
125 | 					const hasStagedChanges = await gitAdapter.hasStagedChanges();
126 | 					if (!hasStagedChanges) {
127 | 						context.log.warn('No staged changes to commit');
128 | 						return handleApiResult({
129 | 							result: {
130 | 								success: false,
131 | 								error: {
132 | 									message:
133 | 										'No staged changes to commit. Make code changes before committing'
134 | 								}
135 | 							},
136 | 							log: context.log,
137 | 							projectRoot
138 | 						});
139 | 					}
140 | 
141 | 					// Get git status for message generation
142 | 					const gitStatus = await gitAdapter.getStatus();
143 | 
144 | 					// Generate commit message
145 | 					let commitMessage: string;
146 | 					if (customMessage) {
147 | 						commitMessage = customMessage;
148 | 						context.log.info('Using custom commit message');
149 | 					} else {
150 | 						const messageGenerator = new CommitMessageGenerator();
151 | 
152 | 						// Determine commit type based on phase and subtask
153 | 						// RED phase = test files, GREEN phase = implementation
154 | 						const type = status.tddPhase === 'COMMIT' ? 'feat' : 'test';
155 | 
156 | 						// Use subtask title as description
157 | 						const description = status.currentSubtask.title;
158 | 
159 | 						// Construct proper CommitMessageOptions
160 | 						const options = {
161 | 							type,
162 | 							description,
163 | 							changedFiles: gitStatus.staged,
164 | 							taskId: status.taskId,
165 | 							phase: status.tddPhase,
166 | 							testsPassing: workflowContext.lastTestResults?.passed,
167 | 							testsFailing: workflowContext.lastTestResults?.failed
168 | 						};
169 | 
170 | 						commitMessage = messageGenerator.generateMessage(options);
171 | 						context.log.info('Generated commit message automatically');
172 | 					}
173 | 
174 | 					// Create commit
175 | 					try {
176 | 						await gitAdapter.createCommit(commitMessage);
177 | 						context.log.info('Commit created successfully');
178 | 					} catch (error: any) {
179 | 						context.log.error(`Failed to create commit: ${error.message}`);
180 | 						return handleApiResult({
181 | 							result: {
182 | 								success: false,
183 | 								error: { message: `Failed to create commit: ${error.message}` }
184 | 							},
185 | 							log: context.log,
186 | 							projectRoot
187 | 						});
188 | 					}
189 | 
190 | 					// Get last commit info
191 | 					const lastCommit = await gitAdapter.getLastCommit();
192 | 
193 | 					// Complete COMMIT phase and advance workflow
194 | 					const newStatus = await workflowService.commit();
195 | 
196 | 					context.log.info(
197 | 						`Commit completed. Current phase: ${newStatus.tddPhase || newStatus.phase}`
198 | 					);
199 | 
200 | 					const isComplete = newStatus.phase === 'COMPLETE';
201 | 
202 | 					// Get next action with guidance
203 | 					const nextAction = workflowService.getNextAction();
204 | 
205 | 					return handleApiResult({
206 | 						result: {
207 | 							success: true,
208 | 							data: {
209 | 								message: isComplete
210 | 									? 'Workflow completed successfully'
211 | 									: 'Commit created and workflow advanced',
212 | 								commitSha: lastCommit.sha,
213 | 								commitMessage,
214 | 								...newStatus,
215 | 								isComplete,
216 | 								nextAction: nextAction.action,
217 | 								nextSteps: nextAction.nextSteps
218 | 							}
219 | 						},
220 | 						log: context.log,
221 | 						projectRoot
222 | 					});
223 | 				} catch (error: any) {
224 | 					context.log.error(`Error in autopilot-commit: ${error.message}`);
225 | 					if (error.stack) {
226 | 						context.log.debug(error.stack);
227 | 					}
228 | 					return handleApiResult({
229 | 						result: {
230 | 							success: false,
231 | 							error: { message: `Failed to commit: ${error.message}` }
232 | 						},
233 | 						log: context.log,
234 | 						projectRoot
235 | 					});
236 | 				}
237 | 			}
238 | 		)
239 | 	});
240 | }
241 | 
```
Page 21/69FirstPrevNextLast