This is page 4 of 38. Use http://codebase.md/eyaltoledano/claude-task-master?lines=false&page={x} to view the full context. # Directory Structure ``` ├── .changeset │ ├── config.json │ └── README.md ├── .claude │ ├── agents │ │ ├── task-checker.md │ │ ├── task-executor.md │ │ └── task-orchestrator.md │ ├── commands │ │ ├── dedupe.md │ │ └── tm │ │ ├── add-dependency │ │ │ └── add-dependency.md │ │ ├── add-subtask │ │ │ ├── add-subtask.md │ │ │ └── convert-task-to-subtask.md │ │ ├── add-task │ │ │ └── add-task.md │ │ ├── analyze-complexity │ │ │ └── analyze-complexity.md │ │ ├── complexity-report │ │ │ └── complexity-report.md │ │ ├── expand │ │ │ ├── expand-all-tasks.md │ │ │ └── expand-task.md │ │ ├── fix-dependencies │ │ │ └── fix-dependencies.md │ │ ├── generate │ │ │ └── generate-tasks.md │ │ ├── help.md │ │ ├── init │ │ │ ├── init-project-quick.md │ │ │ └── init-project.md │ │ ├── learn.md │ │ ├── list │ │ │ ├── list-tasks-by-status.md │ │ │ ├── list-tasks-with-subtasks.md │ │ │ └── list-tasks.md │ │ ├── models │ │ │ ├── setup-models.md │ │ │ └── view-models.md │ │ ├── next │ │ │ └── next-task.md │ │ ├── parse-prd │ │ │ ├── parse-prd-with-research.md │ │ │ └── parse-prd.md │ │ ├── remove-dependency │ │ │ └── remove-dependency.md │ │ ├── remove-subtask │ │ │ └── remove-subtask.md │ │ ├── remove-subtasks │ │ │ ├── remove-all-subtasks.md │ │ │ └── remove-subtasks.md │ │ ├── remove-task │ │ │ └── remove-task.md │ │ ├── set-status │ │ │ ├── to-cancelled.md │ │ │ ├── to-deferred.md │ │ │ ├── to-done.md │ │ │ ├── to-in-progress.md │ │ │ ├── to-pending.md │ │ │ └── to-review.md │ │ ├── setup │ │ │ ├── install-taskmaster.md │ │ │ └── quick-install-taskmaster.md │ │ ├── show │ │ │ └── show-task.md │ │ ├── status │ │ │ └── project-status.md │ │ ├── sync-readme │ │ │ └── sync-readme.md │ │ ├── tm-main.md │ │ ├── update │ │ │ ├── update-single-task.md │ │ │ ├── update-task.md │ │ │ └── update-tasks-from-id.md │ │ ├── utils │ │ │ └── analyze-project.md │ │ ├── validate-dependencies │ │ │ └── validate-dependencies.md │ │ └── workflows │ │ ├── auto-implement-tasks.md │ │ ├── command-pipeline.md │ │ └── smart-workflow.md │ └── TM_COMMANDS_GUIDE.md ├── .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 │ └── 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 │ │ ├── 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 │ │ ├── test-prd.txt │ │ └── tm-core-phase-1.txt │ ├── reports │ │ ├── task-complexity-report_cc-kiro-hooks.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.txt ├── .vscode │ ├── extensions.json │ └── settings.json ├── apps │ ├── cli │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src │ │ │ ├── commands │ │ │ │ ├── auth.command.ts │ │ │ │ ├── context.command.ts │ │ │ │ ├── list.command.ts │ │ │ │ ├── set-status.command.ts │ │ │ │ ├── show.command.ts │ │ │ │ └── start.command.ts │ │ │ ├── index.ts │ │ │ ├── ui │ │ │ │ ├── components │ │ │ │ │ ├── dashboard.component.ts │ │ │ │ │ ├── header.component.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── next-task.component.ts │ │ │ │ │ ├── suggested-steps.component.ts │ │ │ │ │ └── task-detail.component.ts │ │ │ │ └── index.ts │ │ │ └── utils │ │ │ ├── auto-update.ts │ │ │ └── ui.ts │ │ └── tsconfig.json │ ├── 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 │ │ │ └── task-structure.mdx │ │ ├── CHANGELOG.md │ │ ├── docs.json │ │ ├── favicon.svg │ │ ├── getting-started │ │ │ ├── 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 │ │ ├── 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 ├── assets │ ├── .windsurfrules │ ├── AGENTS.md │ ├── claude │ │ ├── agents │ │ │ ├── task-checker.md │ │ │ ├── task-executor.md │ │ │ └── task-orchestrator.md │ │ ├── commands │ │ │ └── tm │ │ │ ├── add-dependency │ │ │ │ └── add-dependency.md │ │ │ ├── add-subtask │ │ │ │ ├── add-subtask.md │ │ │ │ └── convert-task-to-subtask.md │ │ │ ├── add-task │ │ │ │ └── add-task.md │ │ │ ├── analyze-complexity │ │ │ │ └── analyze-complexity.md │ │ │ ├── clear-subtasks │ │ │ │ ├── clear-all-subtasks.md │ │ │ │ └── clear-subtasks.md │ │ │ ├── complexity-report │ │ │ │ └── complexity-report.md │ │ │ ├── expand │ │ │ │ ├── expand-all-tasks.md │ │ │ │ └── expand-task.md │ │ │ ├── fix-dependencies │ │ │ │ └── fix-dependencies.md │ │ │ ├── generate │ │ │ │ └── generate-tasks.md │ │ │ ├── help.md │ │ │ ├── init │ │ │ │ ├── init-project-quick.md │ │ │ │ └── init-project.md │ │ │ ├── learn.md │ │ │ ├── list │ │ │ │ ├── list-tasks-by-status.md │ │ │ │ ├── list-tasks-with-subtasks.md │ │ │ │ └── list-tasks.md │ │ │ ├── models │ │ │ │ ├── setup-models.md │ │ │ │ └── view-models.md │ │ │ ├── next │ │ │ │ └── next-task.md │ │ │ ├── parse-prd │ │ │ │ ├── parse-prd-with-research.md │ │ │ │ └── parse-prd.md │ │ │ ├── remove-dependency │ │ │ │ └── remove-dependency.md │ │ │ ├── remove-subtask │ │ │ │ └── remove-subtask.md │ │ │ ├── remove-subtasks │ │ │ │ ├── remove-all-subtasks.md │ │ │ │ └── remove-subtasks.md │ │ │ ├── remove-task │ │ │ │ └── remove-task.md │ │ │ ├── set-status │ │ │ │ ├── to-cancelled.md │ │ │ │ ├── to-deferred.md │ │ │ │ ├── to-done.md │ │ │ │ ├── to-in-progress.md │ │ │ │ ├── to-pending.md │ │ │ │ └── to-review.md │ │ │ ├── setup │ │ │ │ ├── install-taskmaster.md │ │ │ │ └── quick-install-taskmaster.md │ │ │ ├── show │ │ │ │ └── show-task.md │ │ │ ├── status │ │ │ │ └── project-status.md │ │ │ ├── sync-readme │ │ │ │ └── sync-readme.md │ │ │ ├── tm-main.md │ │ │ ├── update │ │ │ │ ├── update-single-task.md │ │ │ │ ├── update-task.md │ │ │ │ └── update-tasks-from-id.md │ │ │ ├── utils │ │ │ │ └── analyze-project.md │ │ │ ├── validate-dependencies │ │ │ │ └── validate-dependencies.md │ │ │ └── workflows │ │ │ ├── auto-implement-tasks.md │ │ │ ├── command-pipeline.md │ │ │ └── smart-workflow.md │ │ └── TM_COMMANDS_GUIDE.md │ ├── config.json │ ├── env.example │ ├── example_prd.txt │ ├── 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.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 │ ├── CLI-COMMANDER-PATTERN.md │ ├── command-reference.md │ ├── configuration.md │ ├── contributor-docs │ │ └── testing-roo-integration.md │ ├── cross-tag-task-movement.md │ ├── examples │ │ └── claude-code-usage.md │ ├── examples.md │ ├── licensing.md │ ├── mcp-provider-guide.md │ ├── mcp-provider.md │ ├── migration-guide.md │ ├── models.md │ ├── providers │ │ └── gemini-cli.md │ ├── README.md │ ├── scripts │ │ └── models-json-to-markdown.js │ ├── task-structure.md │ └── tutorial.md ├── images │ └── 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 │ │ │ ├── list-tasks.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 │ │ │ ├── show-task.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 │ ├── get-task.js │ ├── get-tasks.js │ ├── index.js │ ├── initialize-project.js │ ├── list-tags.js │ ├── models.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.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 │ ├── build-config │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src │ │ │ └── tsdown.base.ts │ │ └── tsconfig.json │ └── tm-core │ ├── .gitignore │ ├── CHANGELOG.md │ ├── docs │ │ └── listTasks-architecture.md │ ├── package.json │ ├── POC-STATUS.md │ ├── README.md │ ├── src │ │ ├── auth │ │ │ ├── auth-manager.test.ts │ │ │ ├── auth-manager.ts │ │ │ ├── config.ts │ │ │ ├── credential-store.test.ts │ │ │ ├── credential-store.ts │ │ │ ├── index.ts │ │ │ ├── oauth-service.ts │ │ │ ├── supabase-session-storage.ts │ │ │ └── types.ts │ │ ├── clients │ │ │ ├── index.ts │ │ │ └── supabase-client.ts │ │ ├── config │ │ │ ├── config-manager.spec.ts │ │ │ ├── config-manager.ts │ │ │ ├── index.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 │ │ ├── constants │ │ │ └── index.ts │ │ ├── entities │ │ │ └── task.entity.ts │ │ ├── errors │ │ │ ├── index.ts │ │ │ └── task-master-error.ts │ │ ├── executors │ │ │ ├── base-executor.ts │ │ │ ├── claude-executor.ts │ │ │ ├── executor-factory.ts │ │ │ ├── executor-service.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ ├── ai-provider.interface.ts │ │ │ ├── configuration.interface.ts │ │ │ ├── index.ts │ │ │ └── storage.interface.ts │ │ ├── logger │ │ │ ├── factory.ts │ │ │ ├── index.ts │ │ │ └── logger.ts │ │ ├── mappers │ │ │ └── TaskMapper.ts │ │ ├── parser │ │ │ └── index.ts │ │ ├── providers │ │ │ ├── ai │ │ │ │ ├── base-provider.ts │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── repositories │ │ │ ├── supabase-task-repository.ts │ │ │ └── task-repository.interface.ts │ │ ├── services │ │ │ ├── index.ts │ │ │ ├── organization.service.ts │ │ │ ├── task-execution-service.ts │ │ │ └── task-service.ts │ │ ├── storage │ │ │ ├── api-storage.ts │ │ │ ├── file-storage │ │ │ │ ├── file-operations.ts │ │ │ │ ├── file-storage.ts │ │ │ │ ├── format-handler.ts │ │ │ │ ├── index.ts │ │ │ │ └── path-resolver.ts │ │ │ ├── index.ts │ │ │ └── storage-factory.ts │ │ ├── subpath-exports.test.ts │ │ ├── task-master-core.ts │ │ ├── types │ │ │ ├── database.types.ts │ │ │ ├── index.ts │ │ │ └── legacy.ts │ │ └── utils │ │ ├── id-generator.ts │ │ └── index.ts │ ├── tests │ │ ├── integration │ │ │ └── list-tasks.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 │ ├── dev.js │ ├── init.js │ ├── modules │ │ ├── ai-services-unified.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 ├── src │ ├── ai-providers │ │ ├── anthropic.js │ │ ├── azure.js │ │ ├── base-provider.js │ │ ├── bedrock.js │ │ ├── claude-code.js │ │ ├── custom-sdk │ │ │ ├── claude-code │ │ │ │ ├── errors.js │ │ │ │ ├── index.js │ │ │ │ ├── json-extractor.js │ │ │ │ ├── language-model.js │ │ │ │ ├── message-converter.js │ │ │ │ └── types.js │ │ │ └── grok-cli │ │ │ ├── errors.js │ │ │ ├── index.js │ │ │ ├── json-extractor.js │ │ │ ├── language-model.js │ │ │ ├── message-converter.js │ │ │ └── types.js │ │ ├── gemini-cli.js │ │ ├── google-vertex.js │ │ ├── google.js │ │ ├── grok-cli.js │ │ ├── groq.js │ │ ├── index.js │ │ ├── ollama.js │ │ ├── openai.js │ │ ├── openrouter.js │ │ ├── perplexity.js │ │ └── xai.js │ ├── constants │ │ ├── commands.js │ │ ├── paths.js │ │ ├── profiles.js │ │ ├── providers.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 │ ├── 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 │ ├── fixture │ │ └── test-tasks.json │ ├── fixtures │ │ ├── .taskmasterconfig │ │ ├── sample-claude-response.js │ │ ├── sample-prd.txt │ │ └── sample-tasks.js │ ├── integration │ │ ├── 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 │ ├── 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 │ │ ├── claude-code.test.js │ │ ├── custom-sdk │ │ │ └── claude-code │ │ │ └── language-model.test.js │ │ ├── gemini-cli.test.js │ │ ├── mcp-components.test.js │ │ └── openai.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 │ ├── 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 │ ├── providers │ │ └── provider-registry.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 │ │ │ ├── move-task-cross-tag.test.js │ │ │ ├── move-task.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 ``` # Files -------------------------------------------------------------------------------- /apps/docs/getting-started/quick-start/tasks-quick.mdx: -------------------------------------------------------------------------------- ```markdown --- title: Tasks Setup sidebarTitle: "Tasks Setup" --- Now that your tasks are generated you can review the plan and prepare for execution. <Tip> Not all of the setup steps are required but they are recommended in order to ensure your coding agents work on accurate tasks. </Tip> ## Expand Tasks Used to add detail to tasks and create subtasks. We recommend expanding all tasks using the MCP request below: ``` Expand all tasks into subtasks. ``` The agent will execute ```bash task-master expand --all ``` ## List/Show Tasks Used to view task details. It is important to review the plan and ensure it makes sense in your project. Check for correct folder structures, dependencies, out of scope subtasks, etc. To see a list of tasks and descriptions use the following command: ``` List all pending tasks so I can review. ``` To see all tasks in the CLI you can use: ```bash task-master list ``` To see all implementation details of an individual task, including subtasks and testing strategy, you can use Show Task: ``` Show task 2 so I can review. ``` ```bash task-master show --id=<##> ``` ## Update Tasks If the task details need to be edited you can update the task using this request: ``` Update Task 2 to use Postgres instead of MongoDB and remove the sharding subtask ``` Or this CLI command: ```bash task-master update-task --id=2 --prompt="use Postgres instead of MongoDB and remove the sharding subtask" ``` ## Analyze complexity Task Master can provide a complexity report which can be helpful to read before you begin. If you didn't already expand all your tasks, it could help identify which could be broken down further with subtasks. ``` Can you analyze the complexity of our tasks to help me understand which ones need to be broken down further? ``` You can view the report in a friendly table using: ``` Can you show me the complexity report in a more readable format? ``` <Check>Now you are ready to begin [executing tasks](/docs/getting-started/quick-start/execute-quick)</Check> ``` -------------------------------------------------------------------------------- /apps/extension/src/components/ui/button.tsx: -------------------------------------------------------------------------------- ```typescript import { Slot } from '@radix-ui/react-slot'; import { type VariantProps, cva } from 'class-variance-authority'; import type * as React from 'react'; import { cn } from '../../lib/utils'; const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", { variants: { variant: { default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90', destructive: 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', outline: 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50', secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', link: 'text-primary underline-offset-4 hover:underline' }, size: { default: 'h-9 px-4 py-2 has-[>svg]:px-3', sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5', lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', icon: 'size-9' } }, defaultVariants: { variant: 'default', size: 'default' } } ); function Button({ className, variant, size, asChild = false, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & { asChild?: boolean; }) { const Comp = asChild ? Slot : 'button'; return ( <Comp data-slot="button" className={cn(buttonVariants({ variant, size, className }))} {...props} /> ); } export { Button, buttonVariants }; ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/list-tags.js: -------------------------------------------------------------------------------- ```javascript /** * tools/list-tags.js * Tool to list all available tags */ import { z } from 'zod'; import { createErrorResponse, handleApiResult, withNormalizedProjectRoot } from './utils.js'; import { listTagsDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; /** * Register the listTags tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerListTagsTool(server) { server.addTool({ name: 'list_tags', description: 'List all available tags with task counts and metadata', parameters: z.object({ showMetadata: z .boolean() .optional() .describe('Whether to include metadata in the output (default: false)'), file: z .string() .optional() .describe('Path to the tasks file (default: tasks/tasks.json)'), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { log.info(`Starting list-tags with args: ${JSON.stringify(args)}`); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, log ); } catch (error) { log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); } // Call the direct function const result = await listTagsDirect( { tasksJsonPath: tasksJsonPath, showMetadata: args.showMetadata, projectRoot: args.projectRoot }, log, { session } ); return handleApiResult( result, log, 'Error listing tags', undefined, args.projectRoot ); } catch (error) { log.error(`Error in list-tags tool: ${error.message}`); return createErrorResponse(error.message); } }) }); } ``` -------------------------------------------------------------------------------- /tests/e2e/test_llm_analysis.sh: -------------------------------------------------------------------------------- ```bash #!/bin/bash # Script to test the LLM analysis function independently # Exit on error set -u set -o pipefail # Source the helper functions HELPER_SCRIPT="tests/e2e/e2e_helpers.sh" if [ -f "$HELPER_SCRIPT" ]; then source "$HELPER_SCRIPT" echo "[INFO] Sourced helper script: $HELPER_SCRIPT" else echo "[ERROR] Helper script not found at $HELPER_SCRIPT. Exiting." >&2 exit 1 fi # --- Configuration --- # Get the absolute path to the project root (assuming this script is run from the root) PROJECT_ROOT="$(pwd)" # --- Argument Parsing --- if [ "$#" -ne 2 ]; then echo "Usage: $0 <path_to_log_file> <path_to_test_run_directory>" >&2 echo "Example: $0 tests/e2e/log/e2e_run_YYYYMMDD_HHMMSS.log tests/e2e/_runs/run_YYYYMMDD_HHMMSS" >&2 exit 1 fi LOG_FILE_REL="$1" # Relative path from project root TEST_RUN_DIR_REL="$2" # Relative path from project root # Construct absolute paths LOG_FILE_ABS="$PROJECT_ROOT/$LOG_FILE_REL" TEST_RUN_DIR_ABS="$PROJECT_ROOT/$TEST_RUN_DIR_REL" # --- Validation --- if [ ! -f "$LOG_FILE_ABS" ]; then echo "[ERROR] Log file not found: $LOG_FILE_ABS" >&2 exit 1 fi if [ ! -d "$TEST_RUN_DIR_ABS" ]; then echo "[ERROR] Test run directory not found: $TEST_RUN_DIR_ABS" >&2 exit 1 fi if [ ! -f "$TEST_RUN_DIR_ABS/.env" ]; then echo "[ERROR] .env file not found in test run directory: $TEST_RUN_DIR_ABS/.env" >&2 exit 1 fi # --- Execution --- echo "[INFO] Changing directory to test run directory: $TEST_RUN_DIR_ABS" cd "$TEST_RUN_DIR_ABS" || { echo "[ERROR] Failed to cd into $TEST_RUN_DIR_ABS"; exit 1; } echo "[INFO] Current directory: $(pwd)" echo "[INFO] Calling analyze_log_with_llm function with log file: $LOG_FILE_ABS" # Call the function (sourced earlier) analyze_log_with_llm "$LOG_FILE_ABS" ANALYSIS_EXIT_CODE=$? echo "[INFO] analyze_log_with_llm finished with exit code: $ANALYSIS_EXIT_CODE" # Optional: cd back to original directory # echo "[INFO] Changing back to project root: $PROJECT_ROOT" # cd "$PROJECT_ROOT" exit $ANALYSIS_EXIT_CODE ``` -------------------------------------------------------------------------------- /apps/extension/src/services/polling-service.ts: -------------------------------------------------------------------------------- ```typescript /** * Polling Service - Simplified version * Uses strategy pattern for different polling behaviors */ import type { ExtensionLogger } from '../utils/logger'; import type { TaskRepository } from './task-repository'; export interface PollingStrategy { calculateNextInterval( consecutiveNoChanges: number, lastChangeTime?: number ): number; getName(): string; } export class PollingService { private timer?: NodeJS.Timeout; private consecutiveNoChanges = 0; private lastChangeTime?: number; private lastTasksJson?: string; constructor( private repository: TaskRepository, private strategy: PollingStrategy, private logger: ExtensionLogger ) {} start(): void { if (this.timer) { return; } this.logger.log( `Starting polling with ${this.strategy.getName()} strategy` ); this.scheduleNextPoll(); } stop(): void { if (this.timer) { clearTimeout(this.timer); this.timer = undefined; this.logger.log('Polling stopped'); } } setStrategy(strategy: PollingStrategy): void { this.strategy = strategy; this.logger.log(`Changed to ${strategy.getName()} polling strategy`); // Restart with new strategy if running if (this.timer) { this.stop(); this.start(); } } private async poll(): Promise<void> { try { const tasks = await this.repository.getAll(); const tasksJson = JSON.stringify(tasks); // Check for changes if (tasksJson !== this.lastTasksJson) { this.consecutiveNoChanges = 0; this.lastChangeTime = Date.now(); this.logger.debug('Tasks changed'); } else { this.consecutiveNoChanges++; } this.lastTasksJson = tasksJson; } catch (error) { this.logger.error('Polling error', error); } } private scheduleNextPoll(): void { const interval = this.strategy.calculateNextInterval( this.consecutiveNoChanges, this.lastChangeTime ); this.timer = setTimeout(async () => { await this.poll(); this.scheduleNextPoll(); }, interval); this.logger.debug(`Next poll in ${interval}ms`); } } ``` -------------------------------------------------------------------------------- /.github/workflows/claude-docs-trigger.yml: -------------------------------------------------------------------------------- ```yaml name: Trigger Claude Documentation Update on: push: branches: - next paths-ignore: - "apps/docs/**" - "*.md" - ".github/workflows/**" jobs: trigger-docs-update: # Only run if changes were merged (not direct pushes from bots) if: github.actor != 'github-actions[bot]' && github.actor != 'dependabot[bot]' runs-on: ubuntu-latest permissions: contents: read actions: write steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 2 # Need previous commit for comparison - name: Get changed files id: changed-files run: | echo "Changed files in this push:" git diff --name-only HEAD^ HEAD | tee changed_files.txt # Store changed files for Claude to analyze (escaped for JSON) CHANGED_FILES=$(git diff --name-only HEAD^ HEAD | jq -Rs .) echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT # Get the commit message (escaped for JSON) COMMIT_MSG=$(git log -1 --pretty=%B | jq -Rs .) echo "commit_message=$COMMIT_MSG" >> $GITHUB_OUTPUT # Get diff for documentation context (escaped for JSON) COMMIT_DIFF=$(git diff HEAD^ HEAD --stat | jq -Rs .) echo "commit_diff=$COMMIT_DIFF" >> $GITHUB_OUTPUT # Get commit SHA echo "commit_sha=${{ github.sha }}" >> $GITHUB_OUTPUT - name: Trigger Claude workflow env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Trigger the Claude docs updater workflow with the change information gh workflow run claude-docs-updater.yml \ --ref next \ -f commit_sha="${{ steps.changed-files.outputs.commit_sha }}" \ -f commit_message=${{ steps.changed-files.outputs.commit_message }} \ -f changed_files=${{ steps.changed-files.outputs.changed_files }} \ -f commit_diff=${{ steps.changed-files.outputs.commit_diff }} ``` -------------------------------------------------------------------------------- /src/constants/paths.js: -------------------------------------------------------------------------------- ```javascript /** * Path constants for Task Master application */ // .taskmaster directory structure paths export const TASKMASTER_DIR = '.taskmaster'; export const TASKMASTER_TASKS_DIR = '.taskmaster/tasks'; export const TASKMASTER_DOCS_DIR = '.taskmaster/docs'; export const TASKMASTER_REPORTS_DIR = '.taskmaster/reports'; export const TASKMASTER_TEMPLATES_DIR = '.taskmaster/templates'; // Task Master configuration files export const TASKMASTER_CONFIG_FILE = '.taskmaster/config.json'; export const TASKMASTER_STATE_FILE = '.taskmaster/state.json'; export const LEGACY_CONFIG_FILE = '.taskmasterconfig'; // Task Master report files export const COMPLEXITY_REPORT_FILE = '.taskmaster/reports/task-complexity-report.json'; export const LEGACY_COMPLEXITY_REPORT_FILE = 'scripts/task-complexity-report.json'; // Task Master PRD file paths export const PRD_FILE = '.taskmaster/docs/prd.txt'; export const LEGACY_PRD_FILE = 'scripts/prd.txt'; // Task Master template files export const EXAMPLE_PRD_FILE = '.taskmaster/templates/example_prd.txt'; export const LEGACY_EXAMPLE_PRD_FILE = 'scripts/example_prd.txt'; // Task Master task file paths export const TASKMASTER_TASKS_FILE = '.taskmaster/tasks/tasks.json'; export const LEGACY_TASKS_FILE = 'tasks/tasks.json'; // General project files (not Task Master specific but commonly used) export const ENV_EXAMPLE_FILE = '.env.example'; export const GITIGNORE_FILE = '.gitignore'; // Task file naming pattern export const TASK_FILE_PREFIX = 'task_'; export const TASK_FILE_EXTENSION = '.txt'; /** * Project markers used to identify a task-master project root * These files/directories indicate that a directory is a Task Master project */ export const PROJECT_MARKERS = [ '.taskmaster', // New taskmaster directory LEGACY_CONFIG_FILE, // .taskmasterconfig 'tasks.json', // Generic tasks file LEGACY_TASKS_FILE, // tasks/tasks.json (legacy location) TASKMASTER_TASKS_FILE, // .taskmaster/tasks/tasks.json (new location) '.git', // Git repository '.svn' // SVN repository ]; ``` -------------------------------------------------------------------------------- /tests/unit/profiles/windsurf-integration.test.js: -------------------------------------------------------------------------------- ```javascript import { jest } from '@jest/globals'; import fs from 'fs'; import path from 'path'; import os from 'os'; // Mock external modules jest.mock('child_process', () => ({ execSync: jest.fn() })); // Mock console methods jest.mock('console', () => ({ log: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn(), clear: jest.fn() })); describe('Windsurf Integration', () => { let tempDir; beforeEach(() => { jest.clearAllMocks(); // Create a temporary directory for testing tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'task-master-test-')); // Spy on fs methods jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {}); jest.spyOn(fs, 'readFileSync').mockImplementation((filePath) => { if (filePath.toString().includes('mcp.json')) { return JSON.stringify({ mcpServers: {} }, null, 2); } return '{}'; }); jest.spyOn(fs, 'existsSync').mockImplementation(() => false); jest.spyOn(fs, 'mkdirSync').mockImplementation(() => {}); }); afterEach(() => { // Clean up the temporary directory try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch (err) { console.error(`Error cleaning up: ${err.message}`); } }); // Test function that simulates the createProjectStructure behavior for Windsurf files function mockCreateWindsurfStructure() { // Create main .windsurf directory fs.mkdirSync(path.join(tempDir, '.windsurf'), { recursive: true }); // Create rules directory fs.mkdirSync(path.join(tempDir, '.windsurf', 'rules'), { recursive: true }); // Create MCP config file fs.writeFileSync( path.join(tempDir, '.windsurf', 'mcp.json'), JSON.stringify({ mcpServers: {} }, null, 2) ); } test('creates all required .windsurf directories', () => { // Act mockCreateWindsurfStructure(); // Assert expect(fs.mkdirSync).toHaveBeenCalledWith(path.join(tempDir, '.windsurf'), { recursive: true }); expect(fs.mkdirSync).toHaveBeenCalledWith( path.join(tempDir, '.windsurf', 'rules'), { recursive: true } ); }); }); ``` -------------------------------------------------------------------------------- /packages/tm-core/src/executors/base-executor.ts: -------------------------------------------------------------------------------- ```typescript /** * Base executor class providing common functionality for all executors */ import type { Task } from '../types/index.js'; import type { ITaskExecutor, ExecutorType, ExecutionResult } from './types.js'; import { getLogger } from '../logger/index.js'; export abstract class BaseExecutor implements ITaskExecutor { protected readonly logger = getLogger('BaseExecutor'); protected readonly projectRoot: string; protected readonly config: Record<string, any>; constructor(projectRoot: string, config: Record<string, any> = {}) { this.projectRoot = projectRoot; this.config = config; } abstract execute(task: Task): Promise<ExecutionResult>; abstract getType(): ExecutorType; abstract isAvailable(): Promise<boolean>; /** * Format task details into a readable prompt */ protected formatTaskPrompt(task: Task): string { const sections: string[] = []; sections.push(`Task ID: ${task.id}`); sections.push(`Title: ${task.title}`); if (task.description) { sections.push(`\nDescription:\n${task.description}`); } if (task.details) { sections.push(`\nImplementation Details:\n${task.details}`); } if (task.testStrategy) { sections.push(`\nTest Strategy:\n${task.testStrategy}`); } if (task.dependencies && task.dependencies.length > 0) { sections.push(`\nDependencies: ${task.dependencies.join(', ')}`); } if (task.subtasks && task.subtasks.length > 0) { const subtaskList = task.subtasks .map((st) => ` - [${st.status}] ${st.id}: ${st.title}`) .join('\n'); sections.push(`\nSubtasks:\n${subtaskList}`); } sections.push(`\nStatus: ${task.status}`); sections.push(`Priority: ${task.priority}`); return sections.join('\n'); } /** * Create base execution result */ protected createResult( taskId: string, success: boolean, output?: string, error?: string ): ExecutionResult { return { success, taskId, executorType: this.getType(), output, error, startTime: new Date().toISOString(), endTime: new Date().toISOString() }; } } ``` -------------------------------------------------------------------------------- /scripts/modules/task-manager/response-language.js: -------------------------------------------------------------------------------- ```javascript import { getConfig, isConfigFilePresent, writeConfig } from '../config-manager.js'; import { findConfigPath } from '../../../src/utils/path-utils.js'; import { log } from '../utils.js'; function setResponseLanguage(lang, options = {}) { const { mcpLog, projectRoot } = options; const report = (level, ...args) => { if (mcpLog && typeof mcpLog[level] === 'function') { mcpLog[level](...args); } }; // Use centralized config path finding instead of hardcoded path const configPath = findConfigPath(null, { projectRoot }); const configExists = isConfigFilePresent(projectRoot); log( 'debug', `Checking for config file using findConfigPath, found: ${configPath}` ); log( 'debug', `Checking config file using isConfigFilePresent(), exists: ${configExists}` ); if (!configExists) { return { success: false, error: { code: 'CONFIG_MISSING', message: 'The configuration file is missing. Run "task-master init" to create it.' } }; } // Validate response language if (typeof lang !== 'string' || lang.trim() === '') { return { success: false, error: { code: 'INVALID_RESPONSE_LANGUAGE', message: `Invalid response language: ${lang}. Must be a non-empty string.` } }; } try { const currentConfig = getConfig(projectRoot); currentConfig.global.responseLanguage = lang; const writeResult = writeConfig(currentConfig, projectRoot); if (!writeResult) { return { success: false, error: { code: 'WRITE_ERROR', message: 'Error writing updated configuration to configuration file' } }; } const successMessage = `Successfully set response language to: ${lang}`; report('info', successMessage); return { success: true, data: { responseLanguage: lang, message: successMessage } }; } catch (error) { report('error', `Error setting response language: ${error.message}`); return { success: false, error: { code: 'SET_RESPONSE_LANGUAGE_ERROR', message: error.message } }; } } export default setResponseLanguage; ``` -------------------------------------------------------------------------------- /.claude/commands/tm/show/show-task.md: -------------------------------------------------------------------------------- ```markdown Show detailed task information with rich context and insights. Arguments: $ARGUMENTS ## Enhanced Task Display Parse arguments to determine what to show and how. ### 1. **Smart Task Selection** Based on $ARGUMENTS: - Number → Show specific task with full context - "current" → Show active in-progress task(s) - "next" → Show recommended next task - "blocked" → Show all blocked tasks with reasons - "critical" → Show critical path tasks - Multiple IDs → Comparative view ### 2. **Contextual Information** For each task, intelligently include: **Core Details** - Full task information (id, title, description, details) - Current status with history - Test strategy and acceptance criteria - Priority and complexity analysis **Relationships** - Dependencies (what it needs) - Dependents (what needs it) - Parent/subtask hierarchy - Related tasks (similar work) **Time Intelligence** - Created/updated timestamps - Time in current status - Estimated vs actual time - Historical completion patterns ### 3. **Visual Enhancements** ``` 📋 Task #45: Implement User Authentication ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Status: 🟡 in-progress (2 hours) Priority: 🔴 High | Complexity: 73/100 Dependencies: ✅ #41, ✅ #42, ⏳ #43 (blocked) Blocks: #46, #47, #52 Progress: ████████░░ 80% complete Recent Activity: - 2h ago: Status changed to in-progress - 4h ago: Dependency #42 completed - Yesterday: Task expanded with 3 subtasks ``` ### 4. **Intelligent Insights** Based on task analysis: - **Risk Assessment**: Complexity vs time remaining - **Bottleneck Analysis**: Is this blocking critical work? - **Recommendation**: Suggested approach or concerns - **Similar Tasks**: How others completed similar work ### 5. **Action Suggestions** Context-aware next steps: - If blocked → Show how to unblock - If complex → Suggest expansion - If in-progress → Show completion checklist - If done → Show dependent tasks ready to start ### 6. **Multi-Task View** When showing multiple tasks: - Common dependencies - Optimal completion order - Parallel work opportunities - Combined complexity analysis ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/show/show-task.md: -------------------------------------------------------------------------------- ```markdown Show detailed task information with rich context and insights. Arguments: $ARGUMENTS ## Enhanced Task Display Parse arguments to determine what to show and how. ### 1. **Smart Task Selection** Based on $ARGUMENTS: - Number → Show specific task with full context - "current" → Show active in-progress task(s) - "next" → Show recommended next task - "blocked" → Show all blocked tasks with reasons - "critical" → Show critical path tasks - Multiple IDs → Comparative view ### 2. **Contextual Information** For each task, intelligently include: **Core Details** - Full task information (id, title, description, details) - Current status with history - Test strategy and acceptance criteria - Priority and complexity analysis **Relationships** - Dependencies (what it needs) - Dependents (what needs it) - Parent/subtask hierarchy - Related tasks (similar work) **Time Intelligence** - Created/updated timestamps - Time in current status - Estimated vs actual time - Historical completion patterns ### 3. **Visual Enhancements** ``` 📋 Task #45: Implement User Authentication ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Status: 🟡 in-progress (2 hours) Priority: 🔴 High | Complexity: 73/100 Dependencies: ✅ #41, ✅ #42, ⏳ #43 (blocked) Blocks: #46, #47, #52 Progress: ████████░░ 80% complete Recent Activity: - 2h ago: Status changed to in-progress - 4h ago: Dependency #42 completed - Yesterday: Task expanded with 3 subtasks ``` ### 4. **Intelligent Insights** Based on task analysis: - **Risk Assessment**: Complexity vs time remaining - **Bottleneck Analysis**: Is this blocking critical work? - **Recommendation**: Suggested approach or concerns - **Similar Tasks**: How others completed similar work ### 5. **Action Suggestions** Context-aware next steps: - If blocked → Show how to unblock - If complex → Suggest expansion - If in-progress → Show completion checklist - If done → Show dependent tasks ready to start ### 6. **Multi-Task View** When showing multiple tasks: - Common dependencies - Optimal completion order - Parallel work opportunities - Combined complexity analysis ``` -------------------------------------------------------------------------------- /.claude/commands/tm/sync-readme/sync-readme.md: -------------------------------------------------------------------------------- ```markdown Export tasks to README.md with professional formatting. Arguments: $ARGUMENTS Generate a well-formatted README with current task information. ## README Synchronization Creates or updates README.md with beautifully formatted task information. ## Argument Parsing Optional filters: - "pending" → Only pending tasks - "with-subtasks" → Include subtask details - "by-priority" → Group by priority - "sprint" → Current sprint only ## Execution ```bash task-master sync-readme [--with-subtasks] [--status=<status>] ``` ## README Generation ### 1. **Project Header** ```markdown # Project Name ## 📋 Task Progress Last Updated: 2024-01-15 10:30 AM ### Summary - Total Tasks: 45 - Completed: 15 (33%) - In Progress: 5 (11%) - Pending: 25 (56%) ``` ### 2. **Task Sections** Organized by status or priority: - Progress indicators - Task descriptions - Dependencies noted - Time estimates ### 3. **Visual Elements** - Progress bars - Status badges - Priority indicators - Completion checkmarks ## Smart Features 1. **Intelligent Grouping** - By feature area - By sprint/milestone - By assigned developer - By priority 2. **Progress Tracking** - Overall completion - Sprint velocity - Burndown indication - Time tracking 3. **Formatting Options** - GitHub-flavored markdown - Task checkboxes - Collapsible sections - Table format available ## Example Output ```markdown ## 🚀 Current Sprint ### In Progress - [ ] 🔄 #5 **Implement user authentication** (60% complete) - Dependencies: API design (#3 ✅) - Subtasks: 4 (2 completed) - Est: 8h / Spent: 5h ### Pending (High Priority) - [ ] ⚡ #8 **Create dashboard UI** - Blocked by: #5 - Complexity: High - Est: 12h ``` ## Customization Based on arguments: - Include/exclude sections - Detail level control - Custom grouping - Filter by criteria ## Post-Sync After generation: 1. Show diff preview 2. Backup existing README 3. Write new content 4. Commit reminder 5. Update timestamp ## Integration Works well with: - Git workflows - CI/CD pipelines - Project documentation - Team updates - Client reports ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/sync-readme/sync-readme.md: -------------------------------------------------------------------------------- ```markdown Export tasks to README.md with professional formatting. Arguments: $ARGUMENTS Generate a well-formatted README with current task information. ## README Synchronization Creates or updates README.md with beautifully formatted task information. ## Argument Parsing Optional filters: - "pending" → Only pending tasks - "with-subtasks" → Include subtask details - "by-priority" → Group by priority - "sprint" → Current sprint only ## Execution ```bash task-master sync-readme [--with-subtasks] [--status=<status>] ``` ## README Generation ### 1. **Project Header** ```markdown # Project Name ## 📋 Task Progress Last Updated: 2024-01-15 10:30 AM ### Summary - Total Tasks: 45 - Completed: 15 (33%) - In Progress: 5 (11%) - Pending: 25 (56%) ``` ### 2. **Task Sections** Organized by status or priority: - Progress indicators - Task descriptions - Dependencies noted - Time estimates ### 3. **Visual Elements** - Progress bars - Status badges - Priority indicators - Completion checkmarks ## Smart Features 1. **Intelligent Grouping** - By feature area - By sprint/milestone - By assigned developer - By priority 2. **Progress Tracking** - Overall completion - Sprint velocity - Burndown indication - Time tracking 3. **Formatting Options** - GitHub-flavored markdown - Task checkboxes - Collapsible sections - Table format available ## Example Output ```markdown ## 🚀 Current Sprint ### In Progress - [ ] 🔄 #5 **Implement user authentication** (60% complete) - Dependencies: API design (#3 ✅) - Subtasks: 4 (2 completed) - Est: 8h / Spent: 5h ### Pending (High Priority) - [ ] ⚡ #8 **Create dashboard UI** - Blocked by: #5 - Complexity: High - Est: 12h ``` ## Customization Based on arguments: - Include/exclude sections - Detail level control - Custom grouping - Filter by criteria ## Post-Sync After generation: 1. Show diff preview 2. Backup existing README 3. Write new content 4. Commit reminder 5. Update timestamp ## Integration Works well with: - Git workflows - CI/CD pipelines - Project documentation - Team updates - Client reports ``` -------------------------------------------------------------------------------- /mcp-server/src/providers/mcp-provider.js: -------------------------------------------------------------------------------- ```javascript /** * mcp-server/src/providers/mcp-provider.js * * Implementation for MCP custom AI SDK provider that integrates with * the existing MCP server infrastructure and provider registry. * Follows the Claude Code provider pattern for session-based providers. */ import { createMCP } from '../custom-sdk/index.js'; import { BaseAIProvider } from '../../../src/ai-providers/base-provider.js'; export class MCPProvider extends BaseAIProvider { constructor() { super(); this.name = 'mcp'; this.session = null; // MCP server session object } getRequiredApiKeyName() { return 'MCP_API_KEY'; } isRequiredApiKey() { return false; } /** * Override validateAuth to validate MCP session instead of API key * @param {object} params - Parameters to validate */ validateAuth(params) { // Validate MCP session instead of API key if (!this.session) { throw new Error('MCP Provider requires active MCP session'); } if (!this.session.clientCapabilities?.sampling) { throw new Error('MCP session must have client sampling capabilities'); } } /** * Creates and returns an MCP AI SDK client instance. * @param {object} params - Parameters for client initialization * @returns {Function} MCP AI SDK client function * @throws {Error} If initialization fails */ getClient(params) { try { // Pass MCP session to AI SDK implementation return createMCP({ session: this.session, defaultSettings: { temperature: params.temperature, maxTokens: params.maxTokens } }); } catch (error) { this.handleError('client initialization', error); } } /** * Method called by MCP server on connect events * @param {object} session - MCP session object */ setSession(session) { this.session = session; if (!session) { this.logger?.warn('Set null session on MCP Provider'); } else { this.logger?.debug('Updated MCP Provider session'); } } /** * Get current session status * @returns {boolean} True if session is available and valid */ hasValidSession() { return !!(this.session && this.session.clientCapabilities?.sampling); } } ``` -------------------------------------------------------------------------------- /.claude/commands/tm/workflows/auto-implement-tasks.md: -------------------------------------------------------------------------------- ```markdown Enhanced auto-implementation with intelligent code generation and testing. Arguments: $ARGUMENTS ## Intelligent Auto-Implementation Advanced implementation with context awareness and quality checks. ### 1. **Pre-Implementation Analysis** Before starting: - Analyze task complexity and requirements - Check codebase patterns and conventions - Identify similar completed tasks - Assess test coverage needs - Detect potential risks ### 2. **Smart Implementation Strategy** Based on task type and context: **Feature Tasks** 1. Research existing patterns 2. Design component architecture 3. Implement with tests 4. Integrate with system 5. Update documentation **Bug Fix Tasks** 1. Reproduce issue 2. Identify root cause 3. Implement minimal fix 4. Add regression tests 5. Verify side effects **Refactoring Tasks** 1. Analyze current structure 2. Plan incremental changes 3. Maintain test coverage 4. Refactor step-by-step 5. Verify behavior unchanged ### 3. **Code Intelligence** **Pattern Recognition** - Learn from existing code - Follow team conventions - Use preferred libraries - Match style guidelines **Test-Driven Approach** - Write tests first when possible - Ensure comprehensive coverage - Include edge cases - Performance considerations ### 4. **Progressive Implementation** Step-by-step with validation: ``` Step 1/5: Setting up component structure ✓ Step 2/5: Implementing core logic ✓ Step 3/5: Adding error handling ⚡ (in progress) Step 4/5: Writing tests ⏳ Step 5/5: Integration testing ⏳ Current: Adding try-catch blocks and validation... ``` ### 5. **Quality Assurance** Automated checks: - Linting and formatting - Test execution - Type checking - Dependency validation - Performance analysis ### 6. **Smart Recovery** If issues arise: - Diagnostic analysis - Suggestion generation - Fallback strategies - Manual intervention points - Learning from failures ### 7. **Post-Implementation** After completion: - Generate PR description - Update documentation - Log lessons learned - Suggest follow-up tasks - Update task relationships Result: High-quality, production-ready implementations. ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/workflows/auto-implement-tasks.md: -------------------------------------------------------------------------------- ```markdown Enhanced auto-implementation with intelligent code generation and testing. Arguments: $ARGUMENTS ## Intelligent Auto-Implementation Advanced implementation with context awareness and quality checks. ### 1. **Pre-Implementation Analysis** Before starting: - Analyze task complexity and requirements - Check codebase patterns and conventions - Identify similar completed tasks - Assess test coverage needs - Detect potential risks ### 2. **Smart Implementation Strategy** Based on task type and context: **Feature Tasks** 1. Research existing patterns 2. Design component architecture 3. Implement with tests 4. Integrate with system 5. Update documentation **Bug Fix Tasks** 1. Reproduce issue 2. Identify root cause 3. Implement minimal fix 4. Add regression tests 5. Verify side effects **Refactoring Tasks** 1. Analyze current structure 2. Plan incremental changes 3. Maintain test coverage 4. Refactor step-by-step 5. Verify behavior unchanged ### 3. **Code Intelligence** **Pattern Recognition** - Learn from existing code - Follow team conventions - Use preferred libraries - Match style guidelines **Test-Driven Approach** - Write tests first when possible - Ensure comprehensive coverage - Include edge cases - Performance considerations ### 4. **Progressive Implementation** Step-by-step with validation: ``` Step 1/5: Setting up component structure ✓ Step 2/5: Implementing core logic ✓ Step 3/5: Adding error handling ⚡ (in progress) Step 4/5: Writing tests ⏳ Step 5/5: Integration testing ⏳ Current: Adding try-catch blocks and validation... ``` ### 5. **Quality Assurance** Automated checks: - Linting and formatting - Test execution - Type checking - Dependency validation - Performance analysis ### 6. **Smart Recovery** If issues arise: - Diagnostic analysis - Suggestion generation - Fallback strategies - Manual intervention points - Learning from failures ### 7. **Post-Implementation** After completion: - Generate PR description - Update documentation - Log lessons learned - Suggest follow-up tasks - Update task relationships Result: High-quality, production-ready implementations. ``` -------------------------------------------------------------------------------- /tests/integration/profiles/trae-init-functionality.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { traeProfile } from '../../../src/profiles/trae.js'; describe('Trae Profile Initialization Functionality', () => { let traeProfileContent; beforeAll(() => { const traeJsPath = path.join(process.cwd(), 'src', 'profiles', 'trae.js'); traeProfileContent = fs.readFileSync(traeJsPath, 'utf8'); }); test('trae.js uses factory pattern with correct configuration', () => { // Check for explicit, non-default values in the source file expect(traeProfileContent).toContain("name: 'trae'"); expect(traeProfileContent).toContain("displayName: 'Trae'"); expect(traeProfileContent).toContain("url: 'trae.ai'"); expect(traeProfileContent).toContain("docsUrl: 'docs.trae.ai'"); expect(traeProfileContent).toContain('mcpConfig: false'); // Check the final computed properties on the profile object expect(traeProfile.profileName).toBe('trae'); expect(traeProfile.displayName).toBe('Trae'); expect(traeProfile.profileDir).toBe('.trae'); // default expect(traeProfile.rulesDir).toBe('.trae/rules'); // default expect(traeProfile.mcpConfig).toBe(false); // non-default expect(traeProfile.mcpConfigName).toBe(null); // computed from mcpConfig }); test('trae.js configures .mdc to .md extension mapping', () => { // Check that the profile object has the correct file mapping behavior (trae converts to .md) expect(traeProfile.fileMap['rules/cursor_rules.mdc']).toBe('trae_rules.md'); }); test('trae.js uses standard tool mappings', () => { // Check that the profile uses default tool mappings (equivalent to COMMON_TOOL_MAPPINGS.STANDARD) // This verifies the architectural pattern: no custom toolMappings = standard tool names expect(traeProfileContent).not.toContain('toolMappings:'); expect(traeProfileContent).not.toContain('apply_diff'); expect(traeProfileContent).not.toContain('search_files'); // Verify the result: default mappings means tools keep their original names expect(traeProfile.conversionConfig.toolNames.edit_file).toBe('edit_file'); expect(traeProfile.conversionConfig.toolNames.search).toBe('search'); }); }); ``` -------------------------------------------------------------------------------- /.kiro/steering/taskmaster_hooks_workflow.md: -------------------------------------------------------------------------------- ```markdown --- inclusion: always --- # Taskmaster Hook-Driven Workflow ## Core Principle: Hooks Automate Task Management When working with Taskmaster in Kiro, **avoid manually marking tasks as done**. The hook system automatically handles task completion based on: - **Test Success**: `[TM] Test Success Task Completer` detects passing tests and prompts for task completion - **Code Changes**: `[TM] Code Change Task Tracker` monitors implementation progress - **Dependency Chains**: `[TM] Task Dependency Auto-Progression` auto-starts dependent tasks ## AI Assistant Workflow Follow this pattern when implementing features: 1. **Implement First**: Write code, create tests, make changes 2. **Save Frequently**: Hooks trigger on file saves to track progress automatically 3. **Let Hooks Decide**: Allow hooks to detect completion rather than manually setting status 4. **Respond to Prompts**: Confirm when hooks suggest task completion ## Key Rules for AI Assistants - **Never use `tm set-status --status=done`** unless hooks fail to detect completion - **Always write tests** - they provide the most reliable completion signal - **Save files after implementation** - this triggers progress tracking - **Trust hook suggestions** - if no completion prompt appears, more work may be needed ## Automatic Behaviors The hook system provides: - **Progress Logging**: Implementation details automatically added to task notes - **Evidence-Based Completion**: Tasks marked done only when criteria are met - **Dependency Management**: Next tasks auto-started when dependencies complete - **Natural Flow**: Focus on coding, not task management overhead ## Manual Override Cases Only manually set task status for: - Documentation-only tasks - Tasks without testable outcomes - Emergency fixes without proper test coverage Use `tm set-status` sparingly - prefer hook-driven completion. ## Implementation Pattern ``` 1. Implement feature → Save file 2. Write tests → Save test file 3. Tests pass → Hook prompts completion 4. Confirm completion → Next task auto-starts ``` This workflow ensures proper task tracking while maintaining development flow. ``` -------------------------------------------------------------------------------- /.claude/commands/tm/utils/analyze-project.md: -------------------------------------------------------------------------------- ```markdown Advanced project analysis with actionable insights and recommendations. Arguments: $ARGUMENTS ## Comprehensive Project Analysis Multi-dimensional analysis based on requested focus area. ### 1. **Analysis Modes** Based on $ARGUMENTS: - "velocity" → Sprint velocity and trends - "quality" → Code quality metrics - "risk" → Risk assessment and mitigation - "dependencies" → Dependency graph analysis - "team" → Workload and skill distribution - "architecture" → System design coherence - Default → Full spectrum analysis ### 2. **Velocity Analytics** ``` 📊 Velocity Analysis ━━━━━━━━━━━━━━━━━━━ Current Sprint: 24 points/week ↗️ +20% Rolling Average: 20 points/week Efficiency: 85% (17/20 tasks on time) Bottlenecks Detected: - Code review delays (avg 4h wait) - Test environment availability - Dependency on external team Recommendations: 1. Implement parallel review process 2. Add staging environment 3. Mock external dependencies ``` ### 3. **Risk Assessment** **Technical Risks** - High complexity tasks without backup assignee - Single points of failure in architecture - Insufficient test coverage in critical paths - Technical debt accumulation rate **Project Risks** - Critical path dependencies - Resource availability gaps - Deadline feasibility analysis - Scope creep indicators ### 4. **Dependency Intelligence** Visual dependency analysis: ``` Critical Path: #12 → #15 → #23 → #45 → #50 (20 days) ↘ #24 → #46 ↗ Optimization: Parallelize #15 and #24 Time Saved: 3 days ``` ### 5. **Quality Metrics** **Code Quality** - Test coverage trends - Complexity scores - Technical debt ratio - Review feedback patterns **Process Quality** - Rework frequency - Bug introduction rate - Time to resolution - Knowledge distribution ### 6. **Predictive Insights** Based on patterns: - Completion probability by deadline - Resource needs projection - Risk materialization likelihood - Suggested interventions ### 7. **Executive Dashboard** High-level summary with: - Health score (0-100) - Top 3 risks - Top 3 opportunities - Recommended actions - Success probability Result: Data-driven decisions with clear action paths. ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/utils/analyze-project.md: -------------------------------------------------------------------------------- ```markdown Advanced project analysis with actionable insights and recommendations. Arguments: $ARGUMENTS ## Comprehensive Project Analysis Multi-dimensional analysis based on requested focus area. ### 1. **Analysis Modes** Based on $ARGUMENTS: - "velocity" → Sprint velocity and trends - "quality" → Code quality metrics - "risk" → Risk assessment and mitigation - "dependencies" → Dependency graph analysis - "team" → Workload and skill distribution - "architecture" → System design coherence - Default → Full spectrum analysis ### 2. **Velocity Analytics** ``` 📊 Velocity Analysis ━━━━━━━━━━━━━━━━━━━ Current Sprint: 24 points/week ↗️ +20% Rolling Average: 20 points/week Efficiency: 85% (17/20 tasks on time) Bottlenecks Detected: - Code review delays (avg 4h wait) - Test environment availability - Dependency on external team Recommendations: 1. Implement parallel review process 2. Add staging environment 3. Mock external dependencies ``` ### 3. **Risk Assessment** **Technical Risks** - High complexity tasks without backup assignee - Single points of failure in architecture - Insufficient test coverage in critical paths - Technical debt accumulation rate **Project Risks** - Critical path dependencies - Resource availability gaps - Deadline feasibility analysis - Scope creep indicators ### 4. **Dependency Intelligence** Visual dependency analysis: ``` Critical Path: #12 → #15 → #23 → #45 → #50 (20 days) ↘ #24 → #46 ↗ Optimization: Parallelize #15 and #24 Time Saved: 3 days ``` ### 5. **Quality Metrics** **Code Quality** - Test coverage trends - Complexity scores - Technical debt ratio - Review feedback patterns **Process Quality** - Rework frequency - Bug introduction rate - Time to resolution - Knowledge distribution ### 6. **Predictive Insights** Based on patterns: - Completion probability by deadline - Resource needs projection - Risk materialization likelihood - Suggested interventions ### 7. **Executive Dashboard** High-level summary with: - Health score (0-100) - Top 3 risks - Top 3 opportunities - Recommended actions - Success probability Result: Data-driven decisions with clear action paths. ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/delete-tag.js: -------------------------------------------------------------------------------- ```javascript /** * tools/delete-tag.js * Tool to delete an existing tag */ import { z } from 'zod'; import { createErrorResponse, handleApiResult, withNormalizedProjectRoot } from './utils.js'; import { deleteTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; /** * Register the deleteTag tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerDeleteTagTool(server) { server.addTool({ name: 'delete_tag', description: 'Delete an existing tag and all its tasks', parameters: z.object({ name: z.string().describe('Name of the tag to delete'), yes: z .boolean() .optional() .describe('Skip confirmation prompts (default: true for MCP)'), file: z .string() .optional() .describe('Path to the tasks file (default: tasks/tasks.json)'), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { log.info(`Starting delete-tag with args: ${JSON.stringify(args)}`); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, log ); } catch (error) { log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); } // Call the direct function (always skip confirmation for MCP) const result = await deleteTagDirect( { tasksJsonPath: tasksJsonPath, name: args.name, yes: args.yes !== undefined ? args.yes : true, // Default to true for MCP projectRoot: args.projectRoot }, log, { session } ); return handleApiResult( result, log, 'Error deleting tag', undefined, args.projectRoot ); } catch (error) { log.error(`Error in delete-tag tool: ${error.message}`); return createErrorResponse(error.message); } }) }); } ``` -------------------------------------------------------------------------------- /mcp-server/src/core/direct-functions/validate-dependencies.js: -------------------------------------------------------------------------------- ```javascript /** * Direct function wrapper for validateDependenciesCommand */ import { validateDependenciesCommand } from '../../../../scripts/modules/dependency-manager.js'; import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js'; import fs from 'fs'; /** * Validate dependencies in tasks.json * @param {Object} args - Function arguments * @param {string} args.tasksJsonPath - Explicit path to the tasks.json file. * @param {string} args.projectRoot - Project root path (for MCP/env fallback) * @param {string} args.tag - Tag for the task (optional) * @param {Object} log - Logger object * @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>} */ export async function validateDependenciesDirect(args, log) { // Destructure the explicit tasksJsonPath const { tasksJsonPath, projectRoot, tag } = args; if (!tasksJsonPath) { log.error('validateDependenciesDirect called without tasksJsonPath'); return { success: false, error: { code: 'MISSING_ARGUMENT', message: 'tasksJsonPath is required' } }; } try { log.info(`Validating dependencies in tasks: ${tasksJsonPath}`); // Use the provided tasksJsonPath const tasksPath = tasksJsonPath; // Verify the file exists if (!fs.existsSync(tasksPath)) { return { success: false, error: { code: 'FILE_NOT_FOUND', message: `Tasks file not found at ${tasksPath}` } }; } // Enable silent mode to prevent console logs from interfering with JSON response enableSilentMode(); const options = { projectRoot, tag }; // Call the original command function using the provided tasksPath await validateDependenciesCommand(tasksPath, options); // Restore normal logging disableSilentMode(); return { success: true, data: { message: 'Dependencies validated successfully', tasksPath } }; } catch (error) { // Make sure to restore normal logging even if there's an error disableSilentMode(); log.error(`Error validating dependencies: ${error.message}`); return { success: false, error: { code: 'VALIDATION_ERROR', message: error.message } }; } } ``` -------------------------------------------------------------------------------- /tests/integration/profiles/codex-init-functionality.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { codexProfile } from '../../../src/profiles/codex.js'; describe('Codex Profile Initialization Functionality', () => { let codexProfileContent; beforeAll(() => { const codexJsPath = path.join(process.cwd(), 'src', 'profiles', 'codex.js'); codexProfileContent = fs.readFileSync(codexJsPath, 'utf8'); }); test('codex.js has correct asset-only profile configuration', () => { // Check for explicit, non-default values in the source file expect(codexProfileContent).toContain("name: 'codex'"); expect(codexProfileContent).toContain("displayName: 'Codex'"); expect(codexProfileContent).toContain("profileDir: '.'"); // non-default expect(codexProfileContent).toContain("rulesDir: '.'"); // non-default expect(codexProfileContent).toContain('mcpConfig: false'); // non-default expect(codexProfileContent).toContain('includeDefaultRules: false'); // non-default expect(codexProfileContent).toContain("'AGENTS.md': 'AGENTS.md'"); // Check the final computed properties on the profile object expect(codexProfile.profileName).toBe('codex'); expect(codexProfile.displayName).toBe('Codex'); expect(codexProfile.profileDir).toBe('.'); expect(codexProfile.rulesDir).toBe('.'); expect(codexProfile.mcpConfig).toBe(false); expect(codexProfile.mcpConfigName).toBe(null); // computed expect(codexProfile.includeDefaultRules).toBe(false); expect(codexProfile.fileMap['AGENTS.md']).toBe('AGENTS.md'); }); test('codex.js has no lifecycle functions', () => { // Codex has been simplified - no lifecycle functions expect(codexProfileContent).not.toContain('function onAddRulesProfile'); expect(codexProfileContent).not.toContain('function onRemoveRulesProfile'); expect(codexProfileContent).not.toContain( 'function onPostConvertRulesProfile' ); expect(codexProfileContent).not.toContain('log('); }); test('codex.js has minimal implementation', () => { // Should just use createProfile factory expect(codexProfileContent).toContain('createProfile({'); expect(codexProfileContent).toContain("name: 'codex'"); expect(codexProfileContent).toContain("'AGENTS.md': 'AGENTS.md'"); }); }); ``` -------------------------------------------------------------------------------- /src/ai-providers/custom-sdk/grok-cli/index.js: -------------------------------------------------------------------------------- ```javascript /** * @fileoverview Grok CLI provider factory and exports */ import { NoSuchModelError } from '@ai-sdk/provider'; import { GrokCliLanguageModel } from './language-model.js'; /** * @typedef {import('./types.js').GrokCliSettings} GrokCliSettings * @typedef {import('./types.js').GrokCliModelId} GrokCliModelId * @typedef {import('./types.js').GrokCliProvider} GrokCliProvider * @typedef {import('./types.js').GrokCliProviderSettings} GrokCliProviderSettings */ /** * Create a Grok CLI provider * @param {GrokCliProviderSettings} [options={}] - Provider configuration options * @returns {GrokCliProvider} Grok CLI provider instance */ export function createGrokCli(options = {}) { /** * Create a language model instance * @param {GrokCliModelId} modelId - Model ID * @param {GrokCliSettings} [settings={}] - Model settings * @returns {GrokCliLanguageModel} */ const createModel = (modelId, settings = {}) => { return new GrokCliLanguageModel({ id: modelId, settings: { ...options.defaultSettings, ...settings } }); }; /** * Provider function * @param {GrokCliModelId} modelId - Model ID * @param {GrokCliSettings} [settings] - Model settings * @returns {GrokCliLanguageModel} */ const provider = function (modelId, settings) { if (new.target) { throw new Error( 'The Grok CLI model function cannot be called with the new keyword.' ); } return createModel(modelId, settings); }; provider.languageModel = createModel; provider.chat = createModel; // Alias for languageModel // Add textEmbeddingModel method that throws NoSuchModelError provider.textEmbeddingModel = (modelId) => { throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' }); }; return /** @type {GrokCliProvider} */ (provider); } /** * Default Grok CLI provider instance */ export const grokCli = createGrokCli(); // Provider exports export { GrokCliLanguageModel } from './language-model.js'; // Error handling exports export { isAuthenticationError, isTimeoutError, isInstallationError, getErrorMetadata, createAPICallError, createAuthenticationError, createTimeoutError, createInstallationError } from './errors.js'; ``` -------------------------------------------------------------------------------- /tests/unit/profiles/subdirectory-support.test.js: -------------------------------------------------------------------------------- ```javascript // Test for supportsRulesSubdirectories feature import { getRulesProfile } from '../../../src/utils/rule-transformer.js'; describe('Rules Subdirectory Support Feature', () => { it('should support taskmaster subdirectories only for Cursor profile', () => { // Test Cursor profile - should use subdirectories const cursorProfile = getRulesProfile('cursor'); expect(cursorProfile.supportsRulesSubdirectories).toBe(true); // Verify that Cursor uses taskmaster subdirectories in its file mapping expect(cursorProfile.fileMap['rules/dev_workflow.mdc']).toBe( 'taskmaster/dev_workflow.mdc' ); expect(cursorProfile.fileMap['rules/taskmaster.mdc']).toBe( 'taskmaster/taskmaster.mdc' ); }); it('should not use taskmaster subdirectories for other profiles', () => { // Test profiles that should NOT use subdirectories (new default) const profiles = ['roo', 'vscode', 'cline', 'windsurf', 'trae']; profiles.forEach((profileName) => { const profile = getRulesProfile(profileName); expect(profile.supportsRulesSubdirectories).toBe(false); // Verify that these profiles do NOT use taskmaster subdirectories in their file mapping const expectedExt = profile.targetExtension || '.md'; expect(profile.fileMap['rules/dev_workflow.mdc']).toBe( `dev_workflow${expectedExt}` ); expect(profile.fileMap['rules/taskmaster.mdc']).toBe( `taskmaster${expectedExt}` ); }); }); it('should have supportsRulesSubdirectories property accessible on all profiles', () => { const allProfiles = [ 'cursor', 'roo', 'vscode', 'cline', 'windsurf', 'trae' ]; allProfiles.forEach((profileName) => { const profile = getRulesProfile(profileName); expect(profile).toBeDefined(); expect(typeof profile.supportsRulesSubdirectories).toBe('boolean'); }); }); it('should default to false for supportsRulesSubdirectories when not specified', () => { // Most profiles should now default to NOT supporting subdirectories const profiles = ['roo', 'windsurf', 'trae', 'vscode', 'cline']; profiles.forEach((profileName) => { const profile = getRulesProfile(profileName); expect(profile.supportsRulesSubdirectories).toBe(false); }); }); }); ``` -------------------------------------------------------------------------------- /mcp-server/src/core/direct-functions/fix-dependencies.js: -------------------------------------------------------------------------------- ```javascript /** * Direct function wrapper for fixDependenciesCommand */ import { fixDependenciesCommand } from '../../../../scripts/modules/dependency-manager.js'; import { enableSilentMode, disableSilentMode } from '../../../../scripts/modules/utils.js'; import fs from 'fs'; /** * Fix invalid dependencies in tasks.json automatically * @param {Object} args - Function arguments * @param {string} args.tasksJsonPath - Explicit path to the tasks.json file. * @param {string} args.projectRoot - Project root directory * @param {string} args.tag - Tag for the project * @param {Object} log - Logger object * @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>} */ export async function fixDependenciesDirect(args, log) { // Destructure expected args const { tasksJsonPath, projectRoot, tag } = args; try { log.info(`Fixing invalid dependencies in tasks: ${tasksJsonPath}`); // Check if tasksJsonPath was provided if (!tasksJsonPath) { log.error('fixDependenciesDirect called without tasksJsonPath'); return { success: false, error: { code: 'MISSING_ARGUMENT', message: 'tasksJsonPath is required' } }; } // Use provided path const tasksPath = tasksJsonPath; // Verify the file exists if (!fs.existsSync(tasksPath)) { return { success: false, error: { code: 'FILE_NOT_FOUND', message: `Tasks file not found at ${tasksPath}` } }; } // Enable silent mode to prevent console logs from interfering with JSON response enableSilentMode(); const options = { projectRoot, tag }; // Call the original command function using the provided path and proper context await fixDependenciesCommand(tasksPath, options); // Restore normal logging disableSilentMode(); return { success: true, data: { message: 'Dependencies fixed successfully', tasksPath, tag: tag || 'master' } }; } catch (error) { // Make sure to restore normal logging even if there's an error disableSilentMode(); log.error(`Error fixing dependencies: ${error.message}`); return { success: false, error: { code: 'FIX_DEPENDENCIES_ERROR', message: error.message } }; } } ``` -------------------------------------------------------------------------------- /apps/extension/src/components/ui/breadcrumb.tsx: -------------------------------------------------------------------------------- ```typescript import { Slot } from '@radix-ui/react-slot'; import { ChevronRight, MoreHorizontal } from 'lucide-react'; import type * as React from 'react'; import { cn } from '@/lib/utils'; function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) { return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />; } function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) { return ( <ol data-slot="breadcrumb-list" className={cn( 'text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5', className )} {...props} /> ); } function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) { return ( <li data-slot="breadcrumb-item" className={cn('inline-flex items-center gap-1.5', className)} {...props} /> ); } function BreadcrumbLink({ asChild, className, ...props }: React.ComponentProps<'a'> & { asChild?: boolean; }) { const Comp = asChild ? Slot : 'a'; return ( <Comp data-slot="breadcrumb-link" className={cn('hover:text-foreground transition-colors', className)} {...props} /> ); } function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) { return ( <span data-slot="breadcrumb-page" role="link" aria-disabled="true" aria-current="page" className={cn('text-foreground font-normal', className)} {...props} /> ); } function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) { return ( <li data-slot="breadcrumb-separator" role="presentation" aria-hidden="true" className={cn('[&>svg]:size-3.5', className)} {...props} > {children ?? <ChevronRight />} </li> ); } function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) { return ( <span data-slot="breadcrumb-ellipsis" role="presentation" aria-hidden="true" className={cn('flex size-9 items-center justify-center', className)} {...props} > <MoreHorizontal className="size-4" /> <span className="sr-only">More</span> </span> ); } export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis }; ``` -------------------------------------------------------------------------------- /scripts/modules/task-manager.js: -------------------------------------------------------------------------------- ```javascript /** * task-manager.js * Task management functions for the Task Master CLI */ import { findTaskById } from './utils.js'; import parsePRD from './task-manager/parse-prd/index.js'; import updateTasks from './task-manager/update-tasks.js'; import updateTaskById from './task-manager/update-task-by-id.js'; import generateTaskFiles from './task-manager/generate-task-files.js'; import setTaskStatus from './task-manager/set-task-status.js'; import updateSingleTaskStatus from './task-manager/update-single-task-status.js'; import listTasks from './task-manager/list-tasks.js'; import expandTask from './task-manager/expand-task.js'; import expandAllTasks from './task-manager/expand-all-tasks.js'; import clearSubtasks from './task-manager/clear-subtasks.js'; import addTask from './task-manager/add-task.js'; import analyzeTaskComplexity from './task-manager/analyze-task-complexity.js'; import findNextTask from './task-manager/find-next-task.js'; import addSubtask from './task-manager/add-subtask.js'; import removeSubtask from './task-manager/remove-subtask.js'; import updateSubtaskById from './task-manager/update-subtask-by-id.js'; import removeTask from './task-manager/remove-task.js'; import taskExists from './task-manager/task-exists.js'; import isTaskDependentOn from './task-manager/is-task-dependent.js'; import setResponseLanguage from './task-manager/response-language.js'; import moveTask from './task-manager/move-task.js'; import { migrateProject } from './task-manager/migrate.js'; import { performResearch } from './task-manager/research.js'; import { readComplexityReport } from './utils.js'; import { scopeUpTask, scopeDownTask, validateStrength } from './task-manager/scope-adjustment.js'; // Export task manager functions export { parsePRD, updateTasks, updateTaskById, updateSubtaskById, generateTaskFiles, setTaskStatus, updateSingleTaskStatus, listTasks, expandTask, expandAllTasks, clearSubtasks, addTask, addSubtask, removeSubtask, findNextTask, analyzeTaskComplexity, removeTask, findTaskById, taskExists, isTaskDependentOn, setResponseLanguage, moveTask, readComplexityReport, migrateProject, performResearch, scopeUpTask, scopeDownTask, validateStrength }; ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/copy-tag.js: -------------------------------------------------------------------------------- ```javascript /** * tools/copy-tag.js * Tool to copy an existing tag to a new tag */ import { z } from 'zod'; import { createErrorResponse, handleApiResult, withNormalizedProjectRoot } from './utils.js'; import { copyTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; /** * Register the copyTag tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerCopyTagTool(server) { server.addTool({ name: 'copy_tag', description: 'Copy an existing tag to create a new tag with all tasks and metadata', parameters: z.object({ sourceName: z.string().describe('Name of the source tag to copy from'), targetName: z.string().describe('Name of the new tag to create'), description: z .string() .optional() .describe('Optional description for the new tag'), file: z .string() .optional() .describe('Path to the tasks file (default: tasks/tasks.json)'), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { log.info(`Starting copy-tag with args: ${JSON.stringify(args)}`); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, log ); } catch (error) { log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); } // Call the direct function const result = await copyTagDirect( { tasksJsonPath: tasksJsonPath, sourceName: args.sourceName, targetName: args.targetName, description: args.description, projectRoot: args.projectRoot }, log, { session } ); return handleApiResult( result, log, 'Error copying tag', undefined, args.projectRoot ); } catch (error) { log.error(`Error in copy-tag tool: ${error.message}`); return createErrorResponse(error.message); } }) }); } ``` -------------------------------------------------------------------------------- /.claude/commands/tm/remove-task/remove-task.md: -------------------------------------------------------------------------------- ```markdown Remove a task permanently from the project. Arguments: $ARGUMENTS (task ID) Delete a task and handle all its relationships properly. ## Task Removal Permanently removes a task while maintaining project integrity. ## Argument Parsing - "remove task 5" - "delete 5" - "5" → remove task 5 - Can include "-y" for auto-confirm ## Execution ```bash task-master remove-task --id=<id> [-y] ``` ## Pre-Removal Analysis 1. **Task Details** - Current status - Work completed - Time invested - Associated data 2. **Relationship Check** - Tasks that depend on this - Dependencies this task has - Subtasks that will be removed - Blocking implications 3. **Impact Assessment** ``` Task Removal Impact ━━━━━━━━━━━━━━━━━━ Task: #5 "Implement authentication" (in-progress) Status: 60% complete (~8 hours work) Will affect: - 3 tasks depend on this (will be blocked) - Has 4 subtasks (will be deleted) - Part of critical path ⚠️ This action cannot be undone ``` ## Smart Warnings - Warn if task is in-progress - Show dependent tasks that will be blocked - Highlight if part of critical path - Note any completed work being lost ## Removal Process 1. Show comprehensive impact 2. Require confirmation (unless -y) 3. Update dependent task references 4. Remove task and subtasks 5. Clean up orphaned dependencies 6. Log removal with timestamp ## Alternative Actions Suggest before deletion: - Mark as cancelled instead - Convert to documentation - Archive task data - Transfer work to another task ## Post-Removal - List affected tasks - Show broken dependencies - Update project statistics - Suggest dependency fixes - Recalculate timeline ## Example Flows ``` /project:tm/remove-task 5 → Task #5 is in-progress with 8 hours logged → 3 other tasks depend on this → Suggestion: Mark as cancelled instead? Remove anyway? (y/n) /project:tm/remove-task 5 -y → Removed: Task #5 and 4 subtasks → Updated: 3 task dependencies → Warning: Tasks #7, #8, #9 now have missing dependency → Run /project:tm/fix-dependencies to resolve ``` ## Safety Features - Confirmation required - Impact preview - Removal logging - Suggest alternatives - No cascade delete of dependents ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/remove-task/remove-task.md: -------------------------------------------------------------------------------- ```markdown Remove a task permanently from the project. Arguments: $ARGUMENTS (task ID) Delete a task and handle all its relationships properly. ## Task Removal Permanently removes a task while maintaining project integrity. ## Argument Parsing - "remove task 5" - "delete 5" - "5" → remove task 5 - Can include "-y" for auto-confirm ## Execution ```bash task-master remove-task --id=<id> [-y] ``` ## Pre-Removal Analysis 1. **Task Details** - Current status - Work completed - Time invested - Associated data 2. **Relationship Check** - Tasks that depend on this - Dependencies this task has - Subtasks that will be removed - Blocking implications 3. **Impact Assessment** ``` Task Removal Impact ━━━━━━━━━━━━━━━━━━ Task: #5 "Implement authentication" (in-progress) Status: 60% complete (~8 hours work) Will affect: - 3 tasks depend on this (will be blocked) - Has 4 subtasks (will be deleted) - Part of critical path ⚠️ This action cannot be undone ``` ## Smart Warnings - Warn if task is in-progress - Show dependent tasks that will be blocked - Highlight if part of critical path - Note any completed work being lost ## Removal Process 1. Show comprehensive impact 2. Require confirmation (unless -y) 3. Update dependent task references 4. Remove task and subtasks 5. Clean up orphaned dependencies 6. Log removal with timestamp ## Alternative Actions Suggest before deletion: - Mark as cancelled instead - Convert to documentation - Archive task data - Transfer work to another task ## Post-Removal - List affected tasks - Show broken dependencies - Update project statistics - Suggest dependency fixes - Recalculate timeline ## Example Flows ``` /project:tm/remove-task 5 → Task #5 is in-progress with 8 hours logged → 3 other tasks depend on this → Suggestion: Mark as cancelled instead? Remove anyway? (y/n) /project:tm/remove-task 5 -y → Removed: Task #5 and 4 subtasks → Updated: 3 task dependencies → Warning: Tasks #7, #8, #9 now have missing dependency → Run /project:tm/fix-dependencies to resolve ``` ## Safety Features - Confirmation required - Impact preview - Removal logging - Suggest alternatives - No cascade delete of dependents ``` -------------------------------------------------------------------------------- /tests/integration/profiles/windsurf-init-functionality.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { windsurfProfile } from '../../../src/profiles/windsurf.js'; describe('Windsurf Profile Initialization Functionality', () => { let windsurfProfileContent; beforeAll(() => { const windsurfJsPath = path.join( process.cwd(), 'src', 'profiles', 'windsurf.js' ); windsurfProfileContent = fs.readFileSync(windsurfJsPath, 'utf8'); }); test('windsurf.js uses factory pattern with correct configuration', () => { // Check for explicit, non-default values in the source file expect(windsurfProfileContent).toContain("name: 'windsurf'"); expect(windsurfProfileContent).toContain("displayName: 'Windsurf'"); expect(windsurfProfileContent).toContain("url: 'windsurf.com'"); expect(windsurfProfileContent).toContain("docsUrl: 'docs.windsurf.com'"); // Check the final computed properties on the profile object expect(windsurfProfile.profileName).toBe('windsurf'); expect(windsurfProfile.displayName).toBe('Windsurf'); expect(windsurfProfile.profileDir).toBe('.windsurf'); // default expect(windsurfProfile.rulesDir).toBe('.windsurf/rules'); // default expect(windsurfProfile.mcpConfig).toBe(true); // default expect(windsurfProfile.mcpConfigName).toBe('mcp.json'); // default }); test('windsurf.js configures .mdc to .md extension mapping', () => { // Check that the profile object has the correct file mapping behavior (windsurf converts to .md) expect(windsurfProfile.fileMap['rules/cursor_rules.mdc']).toBe( 'windsurf_rules.md' ); }); test('windsurf.js uses standard tool mappings', () => { // Check that the profile uses default tool mappings (equivalent to COMMON_TOOL_MAPPINGS.STANDARD) // This verifies the architectural pattern: no custom toolMappings = standard tool names expect(windsurfProfileContent).not.toContain('toolMappings:'); expect(windsurfProfileContent).not.toContain('apply_diff'); expect(windsurfProfileContent).not.toContain('search_files'); // Verify the result: default mappings means tools keep their original names expect(windsurfProfile.conversionConfig.toolNames.edit_file).toBe( 'edit_file' ); expect(windsurfProfile.conversionConfig.toolNames.search).toBe('search'); }); }); ``` -------------------------------------------------------------------------------- /packages/tm-core/tests/unit/executor.test.ts: -------------------------------------------------------------------------------- ```typescript /** * Tests for executor functionality */ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { ExecutorFactory, ClaudeExecutor, type ExecutorOptions } from '../../src/executors/index.js'; describe('ExecutorFactory', () => { const mockProjectRoot = '/test/project'; it('should create a Claude executor', () => { const options: ExecutorOptions = { type: 'claude', projectRoot: mockProjectRoot }; const executor = ExecutorFactory.create(options); expect(executor).toBeInstanceOf(ClaudeExecutor); }); it('should throw error for unimplemented executor types', () => { const options: ExecutorOptions = { type: 'shell', projectRoot: mockProjectRoot }; expect(() => ExecutorFactory.create(options)).toThrow( 'Shell executor not yet implemented' ); }); it('should get available executor types', () => { const types = ExecutorFactory.getAvailableTypes(); expect(types).toContain('claude'); expect(types).toContain('shell'); expect(types).toContain('custom'); }); }); describe('ClaudeExecutor', () => { const mockProjectRoot = '/test/project'; let executor: ClaudeExecutor; beforeEach(() => { executor = new ClaudeExecutor(mockProjectRoot); }); it('should return claude as executor type', () => { expect(executor.getType()).toBe('claude'); }); it('should format task prompt correctly', () => { const mockTask = { id: '1', title: 'Test Task', description: 'Test description', status: 'pending' as const, priority: 'high' as const, dependencies: [], details: 'Implementation details', testStrategy: 'Unit tests', subtasks: [] }; // Access protected method through any type assertion for testing const formattedPrompt = (executor as any).formatTaskPrompt(mockTask); expect(formattedPrompt).toContain('Task ID: 1'); expect(formattedPrompt).toContain('Title: Test Task'); expect(formattedPrompt).toContain('Description:\nTest description'); expect(formattedPrompt).toContain( 'Implementation Details:\nImplementation details' ); expect(formattedPrompt).toContain('Test Strategy:\nUnit tests'); expect(formattedPrompt).toContain('Status: pending'); expect(formattedPrompt).toContain('Priority: high'); }); }); ``` -------------------------------------------------------------------------------- /packages/tm-core/src/auth/types.ts: -------------------------------------------------------------------------------- ```typescript /** * Authentication types and interfaces */ export interface AuthCredentials { token: string; refreshToken?: string; userId: string; email?: string; expiresAt?: string | number; tokenType?: 'standard'; savedAt: string; selectedContext?: UserContext; } export interface UserContext { orgId?: string; orgName?: string; briefId?: string; briefName?: string; updatedAt: string; } export interface OAuthFlowOptions { /** Callback to open the browser with the auth URL. If not provided, browser won't be opened */ openBrowser?: (url: string) => Promise<void>; /** Timeout for the OAuth flow in milliseconds. Default: 300000 (5 minutes) */ timeout?: number; /** Callback to be invoked with the authorization URL */ onAuthUrl?: (url: string) => void; /** Callback to be invoked when waiting for authentication */ onWaitingForAuth?: () => void; /** Callback to be invoked on successful authentication */ onSuccess?: (credentials: AuthCredentials) => void; /** Callback to be invoked on authentication error */ onError?: (error: AuthenticationError) => void; } export interface AuthConfig { baseUrl: string; configDir: string; configFile: string; } export interface CliData { callback: string; state: string; name: string; version: string; device?: string; user?: string; platform?: string; timestamp?: number; } /** * Authentication error codes */ export type AuthErrorCode = | 'AUTH_TIMEOUT' | 'AUTH_EXPIRED' | 'OAUTH_FAILED' | 'OAUTH_ERROR' | 'OAUTH_CANCELED' | 'URL_GENERATION_FAILED' | 'INVALID_STATE' | 'NO_TOKEN' | 'TOKEN_EXCHANGE_FAILED' | 'INVALID_CREDENTIALS' | 'NO_REFRESH_TOKEN' | 'NOT_AUTHENTICATED' | 'NETWORK_ERROR' | 'CONFIG_MISSING' | 'SAVE_FAILED' | 'CLEAR_FAILED' | 'STORAGE_ERROR' | 'NOT_SUPPORTED' | 'REFRESH_FAILED' | 'INVALID_RESPONSE' | 'PKCE_INIT_FAILED' | 'PKCE_FAILED' | 'CODE_EXCHANGE_FAILED' | 'SESSION_SET_FAILED'; /** * Authentication error class */ export class AuthenticationError extends Error { constructor( message: string, public code: AuthErrorCode, public cause?: unknown ) { super(message); this.name = 'AuthenticationError'; if (cause && cause instanceof Error) { this.stack = `${this.stack}\nCaused by: ${cause.stack}`; } } } ``` -------------------------------------------------------------------------------- /src/ai-providers/custom-sdk/claude-code/index.js: -------------------------------------------------------------------------------- ```javascript /** * @fileoverview Claude Code provider factory and exports */ import { NoSuchModelError } from '@ai-sdk/provider'; import { ClaudeCodeLanguageModel } from './language-model.js'; /** * @typedef {import('./types.js').ClaudeCodeSettings} ClaudeCodeSettings * @typedef {import('./types.js').ClaudeCodeModelId} ClaudeCodeModelId * @typedef {import('./types.js').ClaudeCodeProvider} ClaudeCodeProvider * @typedef {import('./types.js').ClaudeCodeProviderSettings} ClaudeCodeProviderSettings */ /** * Create a Claude Code provider using the official SDK * @param {ClaudeCodeProviderSettings} [options={}] - Provider configuration options * @returns {ClaudeCodeProvider} Claude Code provider instance */ export function createClaudeCode(options = {}) { /** * Create a language model instance * @param {ClaudeCodeModelId} modelId - Model ID * @param {ClaudeCodeSettings} [settings={}] - Model settings * @returns {ClaudeCodeLanguageModel} */ const createModel = (modelId, settings = {}) => { return new ClaudeCodeLanguageModel({ id: modelId, settings: { ...options.defaultSettings, ...settings } }); }; /** * Provider function * @param {ClaudeCodeModelId} modelId - Model ID * @param {ClaudeCodeSettings} [settings] - Model settings * @returns {ClaudeCodeLanguageModel} */ const provider = function (modelId, settings) { if (new.target) { throw new Error( 'The Claude Code model function cannot be called with the new keyword.' ); } return createModel(modelId, settings); }; provider.languageModel = createModel; provider.chat = createModel; // Alias for languageModel // Add textEmbeddingModel method that throws NoSuchModelError provider.textEmbeddingModel = (modelId) => { throw new NoSuchModelError({ modelId, modelType: 'textEmbeddingModel' }); }; return /** @type {ClaudeCodeProvider} */ (provider); } /** * Default Claude Code provider instance */ export const claudeCode = createClaudeCode(); // Provider exports export { ClaudeCodeLanguageModel } from './language-model.js'; // Error handling exports export { isAuthenticationError, isTimeoutError, getErrorMetadata, createAPICallError, createAuthenticationError, createTimeoutError } from './errors.js'; ``` -------------------------------------------------------------------------------- /tests/fixtures/sample-tasks.js: -------------------------------------------------------------------------------- ```javascript /** * Sample task data for testing */ export const sampleTasks = { meta: { projectName: 'Test Project', projectVersion: '1.0.0', createdAt: '2023-01-01T00:00:00.000Z', updatedAt: '2023-01-01T00:00:00.000Z' }, tasks: [ { id: 1, title: 'Initialize Project', description: 'Set up the project structure and dependencies', status: 'done', dependencies: [], priority: 'high', details: 'Create directory structure, initialize package.json, and install dependencies', testStrategy: 'Verify all directories and files are created correctly' }, { id: 2, title: 'Create Core Functionality', description: 'Implement the main features of the application', status: 'in-progress', dependencies: [1], priority: 'high', details: 'Implement user authentication, data processing, and API endpoints', testStrategy: 'Write unit tests for all core functions', subtasks: [ { id: 1, title: 'Implement Authentication', description: 'Create user authentication system', status: 'done', dependencies: [] }, { id: 2, title: 'Set Up Database', description: 'Configure database connection and models', status: 'pending', dependencies: [1] } ] }, { id: 3, title: 'Implement UI Components', description: 'Create the user interface components', status: 'pending', dependencies: [2], priority: 'medium', details: 'Design and implement React components for the user interface', testStrategy: 'Test components with React Testing Library', subtasks: [ { id: 1, title: 'Create Header Component', description: 'Implement the header component', status: 'pending', dependencies: [], details: 'Create a responsive header with navigation links' }, { id: 2, title: 'Create Footer Component', description: 'Implement the footer component', status: 'pending', dependencies: [], details: 'Create a footer with copyright information and links' } ] } ] }; export const emptySampleTasks = { meta: { projectName: 'Empty Project', projectVersion: '1.0.0', createdAt: '2023-01-01T00:00:00.000Z', updatedAt: '2023-01-01T00:00:00.000Z' }, tasks: [] }; ``` -------------------------------------------------------------------------------- /docs/contributor-docs/testing-roo-integration.md: -------------------------------------------------------------------------------- ```markdown # Testing Roo Integration This document provides instructions for testing the Roo integration in the Task Master package. ## Running Tests To run the tests for the Roo integration: ```bash # Run all tests npm test # Run only Roo integration tests npm test -- -t "Roo" # Run specific test file npm test -- tests/integration/roo-files-inclusion.test.js ``` ## Manual Testing To manually verify that the Roo files are properly included in the package: 1. Create a test directory: ```bash mkdir test-tm cd test-tm ``` 2. Create a package.json file: ```bash npm init -y ``` 3. Install the task-master-ai package locally: ```bash # From the root of the claude-task-master repository cd .. npm pack # This will create a file like task-master-ai-0.12.0.tgz # Move back to the test directory cd test-tm npm install ../task-master-ai-0.12.0.tgz ``` 4. Initialize a new Task Master project: ```bash npx task-master init --yes ``` 5. Verify that all Roo files and directories are created: ```bash # Check that .roomodes file exists ls -la | grep .roomodes # Check that .roo directory exists and contains all mode directories ls -la .roo ls -la .roo/rules ls -la .roo/rules-architect ls -la .roo/rules-ask ls -la .roo/rules-orchestrator ls -la .roo/rules-code ls -la .roo/rules-debug ls -la .roo/rules-test ``` ## What to Look For When running the tests or performing manual verification, ensure that: 1. The package includes `.roo/**` and `.roomodes` in the `files` array in package.json 2. The `prepare-package.js` script verifies the existence of all required Roo files 3. The `init.js` script creates all necessary .roo directories and copies .roomodes file 4. All source files for Roo integration exist in `assets/roocode/.roo` and `assets/roocode/.roomodes` ## Compatibility Ensure that the Roo integration works alongside existing Cursor functionality: 1. Initialize a new project that uses both Cursor and Roo: ```bash npx task-master init --yes ``` 2. Verify that both `.cursor` and `.roo` directories are created 3. Verify that both `.windsurfrules` and `.roomodes` files are created 4. Confirm that existing functionality continues to work as expected ``` -------------------------------------------------------------------------------- /.kiro/steering/self_improve.md: -------------------------------------------------------------------------------- ```markdown --- inclusion: always --- - **Rule Improvement Triggers:** - New code patterns not covered by existing rules - Repeated similar implementations across files - Common error patterns that could be prevented - New libraries or tools being used consistently - Emerging best practices in the codebase - **Analysis Process:** - Compare new code with existing rules - Identify patterns that should be standardized - Look for references to external documentation - Check for consistent error handling patterns - Monitor test patterns and coverage - **Rule Updates:** - **Add New Rules When:** - A new technology/pattern is used in 3+ files - Common bugs could be prevented by a rule - Code reviews repeatedly mention the same feedback - New security or performance patterns emerge - **Modify Existing Rules When:** - Better examples exist in the codebase - Additional edge cases are discovered - Related rules have been updated - Implementation details have changed - **Example Pattern Recognition:** ```typescript // If you see repeated patterns like: const data = await prisma.user.findMany({ select: { id: true, email: true }, where: { status: 'ACTIVE' } }); // Consider adding to [prisma.md](.kiro/steering/prisma.md): // - Standard select fields // - Common where conditions // - Performance optimization patterns ``` - **Rule Quality Checks:** - Rules should be actionable and specific - Examples should come from actual code - References should be up to date - Patterns should be consistently enforced - **Continuous Improvement:** - Monitor code review comments - Track common development questions - Update rules after major refactors - Add links to relevant documentation - Cross-reference related rules - **Rule Deprecation:** - Mark outdated patterns as deprecated - Remove rules that no longer apply - Update references to deprecated rules - Document migration paths for old patterns - **Documentation Updates:** - Keep examples synchronized with code - Update references to external docs - Maintain links between related rules - Document breaking changes Follow [kiro_rules.md](.kiro/steering/kiro_rules.md) for proper rule formatting and structure. ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/fix-dependencies.js: -------------------------------------------------------------------------------- ```javascript /** * tools/fix-dependencies.js * Tool for automatically fixing invalid task dependencies */ import { z } from 'zod'; import { handleApiResult, createErrorResponse, withNormalizedProjectRoot } from './utils.js'; import { fixDependenciesDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; /** * Register the fixDependencies tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerFixDependenciesTool(server) { server.addTool({ name: 'fix_dependencies', description: 'Fix invalid dependencies in tasks automatically', parameters: z.object({ file: z.string().optional().describe('Absolute path to the tasks file'), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { log.info(`Fixing dependencies with args: ${JSON.stringify(args)}`); const resolvedTag = resolveTag({ projectRoot: args.projectRoot, tag: args.tag }); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, log ); } catch (error) { log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); } const result = await fixDependenciesDirect( { tasksJsonPath: tasksJsonPath, projectRoot: args.projectRoot, tag: resolvedTag }, log ); if (result.success) { log.info(`Successfully fixed dependencies: ${result.data.message}`); } else { log.error(`Failed to fix dependencies: ${result.error.message}`); } return handleApiResult( result, log, 'Error fixing dependencies', undefined, args.projectRoot ); } catch (error) { log.error(`Error in fixDependencies tool: ${error.message}`); return createErrorResponse(error.message); } }) }); } ``` -------------------------------------------------------------------------------- /tests/unit/profiles/rule-transformer-opencode.test.js: -------------------------------------------------------------------------------- ```javascript import { jest } from '@jest/globals'; import { getRulesProfile } from '../../../src/utils/rule-transformer.js'; import { opencodeProfile } from '../../../src/profiles/opencode.js'; describe('Rule Transformer - OpenCode Profile', () => { test('should have correct profile configuration', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile).toBeDefined(); expect(opencodeProfile.profileName).toBe('opencode'); expect(opencodeProfile.displayName).toBe('OpenCode'); expect(opencodeProfile.profileDir).toBe('.'); expect(opencodeProfile.rulesDir).toBe('.'); expect(opencodeProfile.mcpConfig).toBe(true); expect(opencodeProfile.mcpConfigName).toBe('opencode.json'); expect(opencodeProfile.mcpConfigPath).toBe('opencode.json'); expect(opencodeProfile.includeDefaultRules).toBe(false); expect(opencodeProfile.fileMap).toEqual({ 'AGENTS.md': 'AGENTS.md' }); }); test('should have lifecycle functions for MCP config transformation', () => { // Verify that opencode.js has lifecycle functions expect(opencodeProfile.onPostConvertRulesProfile).toBeDefined(); expect(typeof opencodeProfile.onPostConvertRulesProfile).toBe('function'); expect(opencodeProfile.onRemoveRulesProfile).toBeDefined(); expect(typeof opencodeProfile.onRemoveRulesProfile).toBe('function'); }); test('should use opencode.json instead of mcp.json', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile.mcpConfigName).toBe('opencode.json'); expect(opencodeProfile.mcpConfigPath).toBe('opencode.json'); }); test('should not include default rules', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile.includeDefaultRules).toBe(false); }); test('should have correct file mapping', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile.fileMap).toEqual({ 'AGENTS.md': 'AGENTS.md' }); }); test('should use root directory for both profile and rules', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile.profileDir).toBe('.'); expect(opencodeProfile.rulesDir).toBe('.'); }); test('should have MCP configuration enabled', () => { const opencodeProfile = getRulesProfile('opencode'); expect(opencodeProfile.mcpConfig).toBe(true); }); }); ``` -------------------------------------------------------------------------------- /tests/unit/task-manager/tag-management.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { createTag, deleteTag, renameTag, copyTag, tags as listTags } from '../../../scripts/modules/task-manager/tag-management.js'; const TEMP_DIR = path.join(process.cwd(), '.tmp_tag_management_tests'); const TASKS_PATH = path.join(TEMP_DIR, 'tasks.json'); /** * Helper to write an initial tagged tasks.json structure */ function writeInitialFile() { const initialData = { master: { tasks: [{ id: 1, title: 'Initial Task', status: 'pending' }], metadata: { created: new Date().toISOString(), description: 'Master tag' } } }; fs.mkdirSync(TEMP_DIR, { recursive: true }); fs.writeFileSync(TASKS_PATH, JSON.stringify(initialData, null, 2)); } describe('Tag Management – writeJSON context preservation', () => { beforeEach(() => { writeInitialFile(); }); afterEach(() => { fs.rmSync(TEMP_DIR, { recursive: true, force: true }); }); it('createTag should not corrupt other tags', async () => { await createTag( TASKS_PATH, 'feature', { copyFromCurrent: true }, { projectRoot: TEMP_DIR }, 'json' ); const data = JSON.parse(fs.readFileSync(TASKS_PATH, 'utf8')); expect(data.master).toBeDefined(); expect(data.feature).toBeDefined(); }); it('renameTag should keep overall structure intact', async () => { await createTag( TASKS_PATH, 'oldtag', {}, { projectRoot: TEMP_DIR }, 'json' ); await renameTag( TASKS_PATH, 'oldtag', 'newtag', {}, { projectRoot: TEMP_DIR }, 'json' ); const data = JSON.parse(fs.readFileSync(TASKS_PATH, 'utf8')); expect(data.newtag).toBeDefined(); expect(data.oldtag).toBeUndefined(); }); it('copyTag then deleteTag preserves other tags', async () => { await createTag( TASKS_PATH, 'source', {}, { projectRoot: TEMP_DIR }, 'json' ); await copyTag( TASKS_PATH, 'source', 'copy', {}, { projectRoot: TEMP_DIR }, 'json' ); await deleteTag( TASKS_PATH, 'copy', { yes: true }, { projectRoot: TEMP_DIR }, 'json' ); const tagsList = await listTags( TASKS_PATH, {}, { projectRoot: TEMP_DIR }, 'json' ); const tagNames = tagsList.tags.map((t) => t.name); expect(tagNames).toContain('master'); expect(tagNames).toContain('source'); expect(tagNames).not.toContain('copy'); }); }); ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/complexity-report.js: -------------------------------------------------------------------------------- ```javascript /** * tools/complexity-report.js * Tool for displaying the complexity analysis report */ import { z } from 'zod'; import { handleApiResult, createErrorResponse, withNormalizedProjectRoot } from './utils.js'; import { complexityReportDirect } from '../core/task-master-core.js'; import { COMPLEXITY_REPORT_FILE } from '../../../src/constants/paths.js'; import { findComplexityReportPath } from '../core/utils/path-utils.js'; import { getCurrentTag } from '../../../scripts/modules/utils.js'; /** * Register the complexityReport tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerComplexityReportTool(server) { server.addTool({ name: 'complexity_report', description: 'Display the complexity analysis report in a readable format', parameters: z.object({ file: z .string() .optional() .describe( `Path to the report file (default: ${COMPLEXITY_REPORT_FILE})` ), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { log.info( `Getting complexity report with args: ${JSON.stringify(args)}` ); const resolvedTag = getCurrentTag(args.projectRoot); const pathArgs = { projectRoot: args.projectRoot, complexityReport: args.file, tag: resolvedTag }; const reportPath = findComplexityReportPath(pathArgs, log); log.info('Reading complexity report from path: ', reportPath); if (!reportPath) { return createErrorResponse( 'No complexity report found. Run task-master analyze-complexity first.' ); } const result = await complexityReportDirect( { reportPath: reportPath }, log ); if (result.success) { log.info('Successfully retrieved complexity report'); } else { log.error( `Failed to retrieve complexity report: ${result.error.message}` ); } return handleApiResult( result, log, 'Error retrieving complexity report', undefined, args.projectRoot ); } catch (error) { log.error(`Error in complexity-report tool: ${error.message}`); return createErrorResponse( `Failed to retrieve complexity report: ${error.message}` ); } }) }); } ``` -------------------------------------------------------------------------------- /apps/docs/archive/configuration.mdx: -------------------------------------------------------------------------------- ```markdown --- title: "Configuration" description: "Configure Task Master through environment variables in a .env file" --- ## Required Configuration <Note> Task Master requires an Anthropic API key to function. Add this to your `.env` file: ```bash ANTHROPIC_API_KEY=sk-ant-api03-your-api-key ``` You can obtain an API key from the [Anthropic Console](https://console.anthropic.com/). </Note> ## Optional Configuration | Variable | Default Value | Description | Example | | --- | --- | --- | --- | | `MODEL` | `"claude-3-7-sonnet-20250219"` | Claude model to use | `MODEL=claude-3-opus-20240229` | | `MAX_TOKENS` | `"4000"` | Maximum tokens for responses | `MAX_TOKENS=8000` | | `TEMPERATURE` | `"0.7"` | Temperature for model responses | `TEMPERATURE=0.5` | | `DEBUG` | `"false"` | Enable debug logging | `DEBUG=true` | | `LOG_LEVEL` | `"info"` | Console output level | `LOG_LEVEL=debug` | | `DEFAULT_SUBTASKS` | `"3"` | Default subtask count | `DEFAULT_SUBTASKS=5` | | `DEFAULT_PRIORITY` | `"medium"` | Default priority | `DEFAULT_PRIORITY=high` | | `PROJECT_NAME` | `"MCP SaaS MVP"` | Project name in metadata | `PROJECT_NAME=My Awesome Project` | | `PROJECT_VERSION` | `"1.0.0"` | Version in metadata | `PROJECT_VERSION=2.1.0` | | `PERPLEXITY_API_KEY` | - | For research-backed features | `PERPLEXITY_API_KEY=pplx-...` | | `PERPLEXITY_MODEL` | `"sonar-medium-online"` | Perplexity model | `PERPLEXITY_MODEL=sonar-large-online` | ## Example .env File ``` # Required ANTHROPIC_API_KEY=sk-ant-api03-your-api-key # Optional - Claude Configuration MODEL=claude-3-7-sonnet-20250219 MAX_TOKENS=4000 TEMPERATURE=0.7 # Optional - Perplexity API for Research PERPLEXITY_API_KEY=pplx-your-api-key PERPLEXITY_MODEL=sonar-medium-online # Optional - Project Info PROJECT_NAME=My Project PROJECT_VERSION=1.0.0 # Optional - Application Configuration DEFAULT_SUBTASKS=3 DEFAULT_PRIORITY=medium DEBUG=false LOG_LEVEL=info ``` ## Troubleshooting ### If `task-master init` doesn't respond: Try running it with Node directly: ```bash node node_modules/claude-task-master/scripts/init.js ``` Or clone the repository and run: ```bash git clone https://github.com/eyaltoledano/claude-task-master.git cd claude-task-master node scripts/init.js ``` <Note> For advanced configuration options and detailed customization, see our [Advanced Configuration Guide] page. </Note> ``` -------------------------------------------------------------------------------- /.claude/commands/tm/update/update-tasks-from-id.md: -------------------------------------------------------------------------------- ```markdown Update multiple tasks starting from a specific ID. Arguments: $ARGUMENTS Parse starting task ID and update context. ## Bulk Task Updates Update multiple related tasks based on new requirements or context changes. ## Argument Parsing - "from 5: add security requirements" - "5 onwards: update API endpoints" - "starting at 5: change to use new framework" ## Execution ```bash task-master update --from=<id> --prompt="<context>" ``` ## Update Process ### 1. **Task Selection** Starting from specified ID: - Include the task itself - Include all dependent tasks - Include related subtasks - Smart boundary detection ### 2. **Context Application** AI analyzes the update context and: - Identifies what needs changing - Maintains consistency - Preserves completed work - Updates related information ### 3. **Intelligent Updates** - Modify descriptions appropriately - Update test strategies - Adjust time estimates - Revise dependencies if needed ## Smart Features 1. **Scope Detection** - Find natural task groupings - Identify related features - Stop at logical boundaries - Avoid over-updating 2. **Consistency Maintenance** - Keep naming conventions - Preserve relationships - Update cross-references - Maintain task flow 3. **Change Preview** ``` Bulk Update Preview ━━━━━━━━━━━━━━━━━━ Starting from: Task #5 Tasks to update: 8 tasks + 12 subtasks Context: "add security requirements" Changes will include: - Add security sections to descriptions - Update test strategies for security - Add security-related subtasks where needed - Adjust time estimates (+20% average) Continue? (y/n) ``` ## Example Updates ``` /project:tm/update/from-id 5: change database to PostgreSQL → Analyzing impact starting from task #5 → Found 6 related tasks to update → Updates will maintain consistency → Preview changes? (y/n) Applied updates: ✓ Task #5: Updated connection logic references ✓ Task #6: Changed migration approach ✓ Task #7: Updated query syntax notes ✓ Task #8: Revised testing strategy ✓ Task #9: Updated deployment steps ✓ Task #12: Changed backup procedures ``` ## Safety Features - Preview all changes - Selective confirmation - Rollback capability - Change logging - Validation checks ## Post-Update - Summary of changes - Consistency verification - Suggest review tasks - Update timeline if needed ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/update/update-tasks-from-id.md: -------------------------------------------------------------------------------- ```markdown Update multiple tasks starting from a specific ID. Arguments: $ARGUMENTS Parse starting task ID and update context. ## Bulk Task Updates Update multiple related tasks based on new requirements or context changes. ## Argument Parsing - "from 5: add security requirements" - "5 onwards: update API endpoints" - "starting at 5: change to use new framework" ## Execution ```bash task-master update --from=<id> --prompt="<context>" ``` ## Update Process ### 1. **Task Selection** Starting from specified ID: - Include the task itself - Include all dependent tasks - Include related subtasks - Smart boundary detection ### 2. **Context Application** AI analyzes the update context and: - Identifies what needs changing - Maintains consistency - Preserves completed work - Updates related information ### 3. **Intelligent Updates** - Modify descriptions appropriately - Update test strategies - Adjust time estimates - Revise dependencies if needed ## Smart Features 1. **Scope Detection** - Find natural task groupings - Identify related features - Stop at logical boundaries - Avoid over-updating 2. **Consistency Maintenance** - Keep naming conventions - Preserve relationships - Update cross-references - Maintain task flow 3. **Change Preview** ``` Bulk Update Preview ━━━━━━━━━━━━━━━━━━ Starting from: Task #5 Tasks to update: 8 tasks + 12 subtasks Context: "add security requirements" Changes will include: - Add security sections to descriptions - Update test strategies for security - Add security-related subtasks where needed - Adjust time estimates (+20% average) Continue? (y/n) ``` ## Example Updates ``` /project:tm/update/from-id 5: change database to PostgreSQL → Analyzing impact starting from task #5 → Found 6 related tasks to update → Updates will maintain consistency → Preview changes? (y/n) Applied updates: ✓ Task #5: Updated connection logic references ✓ Task #6: Changed migration approach ✓ Task #7: Updated query syntax notes ✓ Task #8: Revised testing strategy ✓ Task #9: Updated deployment steps ✓ Task #12: Changed backup procedures ``` ## Safety Features - Preview all changes - Selective confirmation - Rollback capability - Change logging - Validation checks ## Post-Update - Summary of changes - Consistency verification - Suggest review tasks - Update timeline if needed ``` -------------------------------------------------------------------------------- /.claude/commands/tm/generate/generate-tasks.md: -------------------------------------------------------------------------------- ```markdown Generate individual task files from tasks.json. ## Task File Generation Creates separate markdown files for each task, perfect for AI agents or documentation. ## Execution ```bash task-master generate ``` ## What It Creates For each task, generates a file like `task_001.txt`: ``` Task ID: 1 Title: Implement user authentication Status: pending Priority: high Dependencies: [] Created: 2024-01-15 Complexity: 7 ## Description Create a secure user authentication system with login, logout, and session management. ## Details - Use JWT tokens for session management - Implement secure password hashing - Add remember me functionality - Include password reset flow ## Test Strategy - Unit tests for auth functions - Integration tests for login flow - Security testing for vulnerabilities - Performance tests for concurrent logins ## Subtasks 1.1 Setup authentication framework (pending) 1.2 Create login endpoints (pending) 1.3 Implement session management (pending) 1.4 Add password reset (pending) ``` ## File Organization Creates structure: ``` .taskmaster/ └── tasks/ ├── task_001.txt ├── task_002.txt ├── task_003.txt └── ... ``` ## Smart Features 1. **Consistent Formatting** - Standardized structure - Clear sections - AI-readable format - Markdown compatible 2. **Contextual Information** - Full task details - Related task references - Progress indicators - Implementation notes 3. **Incremental Updates** - Only regenerate changed tasks - Preserve custom additions - Track generation timestamp - Version control friendly ## Use Cases - **AI Context**: Provide task context to AI assistants - **Documentation**: Standalone task documentation - **Archival**: Task history preservation - **Sharing**: Send specific tasks to team members - **Review**: Easier task review process ## Generation Options Based on arguments: - Filter by status - Include/exclude completed - Custom templates - Different formats ## Post-Generation ``` Task File Generation Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━ Generated: 45 task files Location: .taskmaster/tasks/ Total size: 156 KB New files: 5 Updated files: 12 Unchanged: 28 Ready for: - AI agent consumption - Version control - Team distribution ``` ## Integration Benefits - Git-trackable task history - Easy task sharing - AI tool compatibility - Offline task access - Backup redundancy ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/generate/generate-tasks.md: -------------------------------------------------------------------------------- ```markdown Generate individual task files from tasks.json. ## Task File Generation Creates separate markdown files for each task, perfect for AI agents or documentation. ## Execution ```bash task-master generate ``` ## What It Creates For each task, generates a file like `task_001.txt`: ``` Task ID: 1 Title: Implement user authentication Status: pending Priority: high Dependencies: [] Created: 2024-01-15 Complexity: 7 ## Description Create a secure user authentication system with login, logout, and session management. ## Details - Use JWT tokens for session management - Implement secure password hashing - Add remember me functionality - Include password reset flow ## Test Strategy - Unit tests for auth functions - Integration tests for login flow - Security testing for vulnerabilities - Performance tests for concurrent logins ## Subtasks 1.1 Setup authentication framework (pending) 1.2 Create login endpoints (pending) 1.3 Implement session management (pending) 1.4 Add password reset (pending) ``` ## File Organization Creates structure: ``` .taskmaster/ └── tasks/ ├── task_001.txt ├── task_002.txt ├── task_003.txt └── ... ``` ## Smart Features 1. **Consistent Formatting** - Standardized structure - Clear sections - AI-readable format - Markdown compatible 2. **Contextual Information** - Full task details - Related task references - Progress indicators - Implementation notes 3. **Incremental Updates** - Only regenerate changed tasks - Preserve custom additions - Track generation timestamp - Version control friendly ## Use Cases - **AI Context**: Provide task context to AI assistants - **Documentation**: Standalone task documentation - **Archival**: Task history preservation - **Sharing**: Send specific tasks to team members - **Review**: Easier task review process ## Generation Options Based on arguments: - Filter by status - Include/exclude completed - Custom templates - Different formats ## Post-Generation ``` Task File Generation Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━ Generated: 45 task files Location: .taskmaster/tasks/ Total size: 156 KB New files: 5 Updated files: 12 Unchanged: 28 Ready for: - AI agent consumption - Version control - Team distribution ``` ## Integration Benefits - Git-trackable task history - Easy task sharing - AI tool compatibility - Offline task access - Backup redundancy ``` -------------------------------------------------------------------------------- /tests/integration/profiles/cursor-init-functionality.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { cursorProfile } from '../../../src/profiles/cursor.js'; describe('Cursor Profile Initialization Functionality', () => { let cursorProfileContent; beforeAll(() => { const cursorJsPath = path.join( process.cwd(), 'src', 'profiles', 'cursor.js' ); cursorProfileContent = fs.readFileSync(cursorJsPath, 'utf8'); }); test('cursor.js uses factory pattern with correct configuration', () => { // Check for explicit, non-default values in the source file expect(cursorProfileContent).toContain("name: 'cursor'"); expect(cursorProfileContent).toContain("displayName: 'Cursor'"); expect(cursorProfileContent).toContain("url: 'cursor.so'"); expect(cursorProfileContent).toContain("docsUrl: 'docs.cursor.com'"); expect(cursorProfileContent).toContain("targetExtension: '.mdc'"); // non-default // Check the final computed properties on the profile object expect(cursorProfile.profileName).toBe('cursor'); expect(cursorProfile.displayName).toBe('Cursor'); expect(cursorProfile.profileDir).toBe('.cursor'); // default expect(cursorProfile.rulesDir).toBe('.cursor/rules'); // default expect(cursorProfile.mcpConfig).toBe(true); // default expect(cursorProfile.mcpConfigName).toBe('mcp.json'); // default }); test('cursor.js preserves .mdc extension in both input and output', () => { // Check that the profile object has the correct file mapping behavior (cursor keeps .mdc) expect(cursorProfile.fileMap['rules/cursor_rules.mdc']).toBe( 'cursor_rules.mdc' ); // Also check that targetExtension is explicitly set in the file expect(cursorProfileContent).toContain("targetExtension: '.mdc'"); }); test('cursor.js uses standard tool mappings (no tool renaming)', () => { // Check that the profile uses default tool mappings (equivalent to COMMON_TOOL_MAPPINGS.STANDARD) // This verifies the architectural pattern: no custom toolMappings = standard tool names expect(cursorProfileContent).not.toContain('toolMappings:'); expect(cursorProfileContent).not.toContain('apply_diff'); expect(cursorProfileContent).not.toContain('search_files'); // Verify the result: default mappings means tools keep their original names expect(cursorProfile.conversionConfig.toolNames.edit_file).toBe( 'edit_file' ); expect(cursorProfile.conversionConfig.toolNames.search).toBe('search'); }); }); ``` -------------------------------------------------------------------------------- /mcp-server/src/tools/validate-dependencies.js: -------------------------------------------------------------------------------- ```javascript /** * tools/validate-dependencies.js * Tool for validating task dependencies */ import { z } from 'zod'; import { handleApiResult, createErrorResponse, withNormalizedProjectRoot } from './utils.js'; import { validateDependenciesDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; /** * Register the validateDependencies tool with the MCP server * @param {Object} server - FastMCP server instance */ export function registerValidateDependenciesTool(server) { server.addTool({ name: 'validate_dependencies', description: 'Check tasks for dependency issues (like circular references or links to non-existent tasks) without making changes.', parameters: z.object({ file: z.string().optional().describe('Absolute path to the tasks file'), projectRoot: z .string() .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), execute: withNormalizedProjectRoot(async (args, { log, session }) => { try { const resolvedTag = resolveTag({ projectRoot: args.projectRoot, tag: args.tag }); log.info(`Validating dependencies with args: ${JSON.stringify(args)}`); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, log ); } catch (error) { log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); } const result = await validateDependenciesDirect( { tasksJsonPath: tasksJsonPath, projectRoot: args.projectRoot, tag: resolvedTag }, log ); if (result.success) { log.info( `Successfully validated dependencies: ${result.data.message}` ); } else { log.error(`Failed to validate dependencies: ${result.error.message}`); } return handleApiResult( result, log, 'Error validating dependencies', undefined, args.projectRoot ); } catch (error) { log.error(`Error in validateDependencies tool: ${error.message}`); return createErrorResponse(error.message); } }) }); } ``` -------------------------------------------------------------------------------- /apps/extension/src/webview/components/TaskCard.tsx: -------------------------------------------------------------------------------- ```typescript /** * Task Card Component for Kanban Board */ import React from 'react'; import { KanbanCard } from '@/components/ui/shadcn-io/kanban'; import { PriorityBadge } from './PriorityBadge'; import type { TaskMasterTask } from '../types'; interface TaskCardProps { task: TaskMasterTask; dragging?: boolean; onViewDetails?: (taskId: string) => void; } export const TaskCard: React.FC<TaskCardProps> = ({ task, dragging, onViewDetails }) => { const handleCardClick = (e: React.MouseEvent) => { e.preventDefault(); onViewDetails?.(task.id); }; return ( <KanbanCard id={task.id} name={task.title} index={0} // Index is not used in our implementation parent={task.status} className="cursor-pointer p-3 transition-shadow hover:shadow-md bg-vscode-editor-background border-vscode-border group" onClick={handleCardClick} > <div className="space-y-3 h-full flex flex-col"> <div className="flex items-start justify-between gap-2 flex-shrink-0"> <h3 className="font-medium text-sm leading-tight flex-1 min-w-0 text-vscode-foreground"> {task.title} </h3> <div className="flex items-center gap-1 flex-shrink-0"> <PriorityBadge priority={task.priority} /> </div> </div> {task.description && ( <p className="text-xs text-vscode-foreground/70 line-clamp-3 leading-relaxed flex-1 min-h-0"> {task.description} </p> )} <div className="flex items-center justify-between text-xs mt-auto pt-2 flex-shrink-0 border-t border-vscode-border/20"> <span className="font-mono text-vscode-foreground/50 flex-shrink-0"> #{task.id} </span> {task.dependencies && task.dependencies.length > 0 && ( <div className="flex items-center gap-1 text-vscode-foreground/50 flex-shrink-0 ml-2"> <span>Deps:</span> <div className="flex items-center gap-1"> {task.dependencies.map((depId, index) => ( <React.Fragment key={depId}> <button className="font-mono hover:text-vscode-link-activeForeground hover:underline transition-colors" onClick={(e) => { e.stopPropagation(); onViewDetails?.(depId); }} > #{depId} </button> {index < task.dependencies!.length - 1 && <span>,</span>} </React.Fragment> ))} </div> </div> )} </div> </div> </KanbanCard> ); }; ``` -------------------------------------------------------------------------------- /apps/extension/assets/icon-dark.svg: -------------------------------------------------------------------------------- ``` <svg viewBox="0 0 224 291" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M101.635 286.568L71.4839 256.414C65.6092 250.539 65.6092 241.03 71.4839 235.155L142.52 164.11C144.474 162.156 147.643 162.156 149.61 164.11L176.216 190.719C178.17 192.673 181.339 192.673 183.305 190.719L189.719 184.305C191.673 182.35 191.673 179.181 189.719 177.214L163.113 150.605C161.159 148.651 161.159 145.481 163.113 143.514L191.26 115.365C193.214 113.41 193.214 110.241 191.26 108.274L182.316 99.3291C180.362 97.3748 177.193 97.3748 175.226 99.3291L55.8638 218.706C49.989 224.581 40.4816 224.581 34.6068 218.706L4.4061 188.501C-1.4687 182.626 -1.4687 173.117 4.4061 167.242L23.8342 147.811C25.7883 145.857 25.7883 142.688 23.8342 140.721L4.78187 121.666C-1.09293 115.791 -1.09293 106.282 4.78187 100.406L34.7195 70.4527C40.5943 64.5772 50.1017 64.5772 55.9765 70.4527L75.555 90.0335C77.5091 91.9879 80.6782 91.9879 82.6448 90.0335L124.144 48.5292C126.098 46.5749 126.098 43.4054 124.144 41.4385L115.463 32.7568C113.509 30.8025 110.34 30.8025 108.374 32.7568L99.8683 41.2632C97.9143 43.2175 94.7451 43.2175 92.7785 41.2632L82.1438 30.6271C80.1897 28.6728 80.1897 25.5033 82.1438 23.5364L101.271 4.40662C107.146 -1.46887 116.653 -1.46887 122.528 4.40662L152.478 34.3604C158.353 40.2359 158.353 49.7444 152.478 55.6199L82.6323 125.474C80.6782 127.429 77.5091 127.429 75.5425 125.474L48.8741 98.8029C46.9201 96.8486 43.7509 96.8486 41.7843 98.8029L33.1036 107.485C31.1496 109.439 31.1496 112.608 33.1036 114.575L59.2458 140.721C61.1999 142.675 61.1999 145.844 59.2458 147.811L32.7404 174.32C30.7863 176.274 30.7863 179.444 32.7404 181.411L41.6841 190.355C43.6382 192.31 46.8073 192.31 48.7739 190.355L168.136 70.9789C174.011 65.1034 183.518 65.1034 189.393 70.9789L219.594 101.183C225.469 107.059 225.469 116.567 219.594 122.443L198.537 143.502C196.583 145.456 196.583 148.626 198.537 150.592L218.053 170.111C223.928 175.986 223.928 185.495 218.053 191.37L190.37 219.056C184.495 224.932 174.988 224.932 169.113 219.056L149.597 199.538C147.643 197.584 144.474 197.584 142.508 199.538L99.8057 242.245C97.8516 244.2 97.8516 247.369 99.8057 249.336L108.699 258.231C110.653 260.185 113.823 260.185 115.789 258.231L122.954 251.065C124.908 249.11 128.077 249.11 130.044 251.065L140.679 261.701C142.633 263.655 142.633 266.825 140.679 268.791L122.879 286.593C117.004 292.469 107.497 292.469 101.622 286.593L101.635 286.568Z" fill="#CCCCCC"/> </svg> ``` -------------------------------------------------------------------------------- /apps/extension/assets/icon-light.svg: -------------------------------------------------------------------------------- ``` <svg viewBox="0 0 224 291" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M101.635 286.568L71.4839 256.414C65.6092 250.539 65.6092 241.03 71.4839 235.155L142.52 164.11C144.474 162.156 147.643 162.156 149.61 164.11L176.216 190.719C178.17 192.673 181.339 192.673 183.305 190.719L189.719 184.305C191.673 182.35 191.673 179.181 189.719 177.214L163.113 150.605C161.159 148.651 161.159 145.481 163.113 143.514L191.26 115.365C193.214 113.41 193.214 110.241 191.26 108.274L182.316 99.3291C180.362 97.3748 177.193 97.3748 175.226 99.3291L55.8638 218.706C49.989 224.581 40.4816 224.581 34.6068 218.706L4.4061 188.501C-1.4687 182.626 -1.4687 173.117 4.4061 167.242L23.8342 147.811C25.7883 145.857 25.7883 142.688 23.8342 140.721L4.78187 121.666C-1.09293 115.791 -1.09293 106.282 4.78187 100.406L34.7195 70.4527C40.5943 64.5772 50.1017 64.5772 55.9765 70.4527L75.555 90.0335C77.5091 91.9879 80.6782 91.9879 82.6448 90.0335L124.144 48.5292C126.098 46.5749 126.098 43.4054 124.144 41.4385L115.463 32.7568C113.509 30.8025 110.34 30.8025 108.374 32.7568L99.8683 41.2632C97.9143 43.2175 94.7451 43.2175 92.7785 41.2632L82.1438 30.6271C80.1897 28.6728 80.1897 25.5033 82.1438 23.5364L101.271 4.40662C107.146 -1.46887 116.653 -1.46887 122.528 4.40662L152.478 34.3604C158.353 40.2359 158.353 49.7444 152.478 55.6199L82.6323 125.474C80.6782 127.429 77.5091 127.429 75.5425 125.474L48.8741 98.8029C46.9201 96.8486 43.7509 96.8486 41.7843 98.8029L33.1036 107.485C31.1496 109.439 31.1496 112.608 33.1036 114.575L59.2458 140.721C61.1999 142.675 61.1999 145.844 59.2458 147.811L32.7404 174.32C30.7863 176.274 30.7863 179.444 32.7404 181.411L41.6841 190.355C43.6382 192.31 46.8073 192.31 48.7739 190.355L168.136 70.9789C174.011 65.1034 183.518 65.1034 189.393 70.9789L219.594 101.183C225.469 107.059 225.469 116.567 219.594 122.443L198.537 143.502C196.583 145.456 196.583 148.626 198.537 150.592L218.053 170.111C223.928 175.986 223.928 185.495 218.053 191.37L190.37 219.056C184.495 224.932 174.988 224.932 169.113 219.056L149.597 199.538C147.643 197.584 144.474 197.584 142.508 199.538L99.8057 242.245C97.8516 244.2 97.8516 247.369 99.8057 249.336L108.699 258.231C110.653 260.185 113.823 260.185 115.789 258.231L122.954 251.065C124.908 249.11 128.077 249.11 130.044 251.065L140.679 261.701C142.633 263.655 142.633 266.825 140.679 268.791L122.879 286.593C117.004 292.469 107.497 292.469 101.622 286.593L101.635 286.568Z" fill="#424242"/> </svg> ``` -------------------------------------------------------------------------------- /apps/extension/assets/sidebar-icon.svg: -------------------------------------------------------------------------------- ``` <svg viewBox="0 0 224 291" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M101.635 286.568L71.4839 256.414C65.6092 250.539 65.6092 241.03 71.4839 235.155L142.52 164.11C144.474 162.156 147.643 162.156 149.61 164.11L176.216 190.719C178.17 192.673 181.339 192.673 183.305 190.719L189.719 184.305C191.673 182.35 191.673 179.181 189.719 177.214L163.113 150.605C161.159 148.651 161.159 145.481 163.113 143.514L191.26 115.365C193.214 113.41 193.214 110.241 191.26 108.274L182.316 99.3291C180.362 97.3748 177.193 97.3748 175.226 99.3291L55.8638 218.706C49.989 224.581 40.4816 224.581 34.6068 218.706L4.4061 188.501C-1.4687 182.626 -1.4687 173.117 4.4061 167.242L23.8342 147.811C25.7883 145.857 25.7883 142.688 23.8342 140.721L4.78187 121.666C-1.09293 115.791 -1.09293 106.282 4.78187 100.406L34.7195 70.4527C40.5943 64.5772 50.1017 64.5772 55.9765 70.4527L75.555 90.0335C77.5091 91.9879 80.6782 91.9879 82.6448 90.0335L124.144 48.5292C126.098 46.5749 126.098 43.4054 124.144 41.4385L115.463 32.7568C113.509 30.8025 110.34 30.8025 108.374 32.7568L99.8683 41.2632C97.9143 43.2175 94.7451 43.2175 92.7785 41.2632L82.1438 30.6271C80.1897 28.6728 80.1897 25.5033 82.1438 23.5364L101.271 4.40662C107.146 -1.46887 116.653 -1.46887 122.528 4.40662L152.478 34.3604C158.353 40.2359 158.353 49.7444 152.478 55.6199L82.6323 125.474C80.6782 127.429 77.5091 127.429 75.5425 125.474L48.8741 98.8029C46.9201 96.8486 43.7509 96.8486 41.7843 98.8029L33.1036 107.485C31.1496 109.439 31.1496 112.608 33.1036 114.575L59.2458 140.721C61.1999 142.675 61.1999 145.844 59.2458 147.811L32.7404 174.32C30.7863 176.274 30.7863 179.444 32.7404 181.411L41.6841 190.355C43.6382 192.31 46.8073 192.31 48.7739 190.355L168.136 70.9789C174.011 65.1034 183.518 65.1034 189.393 70.9789L219.594 101.183C225.469 107.059 225.469 116.567 219.594 122.443L198.537 143.502C196.583 145.456 196.583 148.626 198.537 150.592L218.053 170.111C223.928 175.986 223.928 185.495 218.053 191.37L190.37 219.056C184.495 224.932 174.988 224.932 169.113 219.056L149.597 199.538C147.643 197.584 144.474 197.584 142.508 199.538L99.8057 242.245C97.8516 244.2 97.8516 247.369 99.8057 249.336L108.699 258.231C110.653 260.185 113.823 260.185 115.789 258.231L122.954 251.065C124.908 249.11 128.077 249.11 130.044 251.065L140.679 261.701C142.633 263.655 142.633 266.825 140.679 268.791L122.879 286.593C117.004 292.469 107.497 292.469 101.622 286.593L101.635 286.568Z" fill="currentColor"/> </svg> ``` -------------------------------------------------------------------------------- /packages/tm-core/CHANGELOG.md: -------------------------------------------------------------------------------- ```markdown # Changelog ## null ## 0.26.1 All notable changes to the @task-master/tm-core package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - Initial package structure and configuration - TypeScript support with strict mode - Dual ESM/CJS build system with tsup - Jest testing framework with TypeScript support - ESLint and Prettier for code quality - Modular architecture with barrel exports - Placeholder implementations for all modules - Comprehensive documentation and README ### Development Infrastructure - tsup configuration for dual format builds - Jest configuration with ESM support - ESLint configuration with TypeScript rules - Prettier configuration for consistent formatting - Complete package.json with all required fields - TypeScript configuration with strict settings - .gitignore for development files ### Package Structure - `src/types/` - TypeScript type definitions (placeholder) - `src/providers/` - AI provider implementations (placeholder) - `src/storage/` - Storage layer abstractions (placeholder) - `src/parser/` - Task parsing utilities (placeholder) - `src/utils/` - Common utility functions (placeholder) - `src/errors/` - Custom error classes (placeholder) - `tests/` - Test directories and setup ## [1.0.0] - TBD ### Planned Features - Complete TypeScript type system - AI provider implementations - Storage adapters - Task parsing capabilities - Comprehensive utility functions - Custom error handling - Full test coverage - Complete documentation --- ## Release Notes ### Version 1.0.0 (Coming Soon) This will be the first stable release of tm-core with complete implementations of all modules. Currently, all modules contain placeholder implementations to establish the package structure and enable development of dependent packages. ### Development Status - ✅ Package structure and configuration - ✅ Build and test infrastructure - ✅ Development tooling setup - 🚧 TypeScript types implementation (Task 116) - 🚧 AI provider system (Task 117) - 🚧 Storage layer (Task 118) - 🚧 Task parser (Task 119) - 🚧 Utility functions (Task 120) - 🚧 Error handling (Task 121) - 🚧 Configuration system (Task 122) - 🚧 Testing infrastructure (Task 123) - 🚧 Documentation (Task 124) - 🚧 Package finalization (Task 125) ``` -------------------------------------------------------------------------------- /tests/integration/profiles/vscode-init-functionality.test.js: -------------------------------------------------------------------------------- ```javascript import fs from 'fs'; import path from 'path'; import { vscodeProfile } from '../../../src/profiles/vscode.js'; describe('VSCode Profile Initialization Functionality', () => { let vscodeProfileContent; beforeAll(() => { const vscodeJsPath = path.join( process.cwd(), 'src', 'profiles', 'vscode.js' ); vscodeProfileContent = fs.readFileSync(vscodeJsPath, 'utf8'); }); test('vscode.js uses factory pattern with correct configuration', () => { // Check for explicit, non-default values in the source file expect(vscodeProfileContent).toContain("name: 'vscode'"); expect(vscodeProfileContent).toContain("displayName: 'VS Code'"); expect(vscodeProfileContent).toContain("url: 'code.visualstudio.com'"); expect(vscodeProfileContent).toContain( "docsUrl: 'code.visualstudio.com/docs'" ); expect(vscodeProfileContent).toContain("rulesDir: '.github/instructions'"); // non-default expect(vscodeProfileContent).toContain('customReplacements'); // non-default // Check the final computed properties on the profile object expect(vscodeProfile.profileName).toBe('vscode'); expect(vscodeProfile.displayName).toBe('VS Code'); expect(vscodeProfile.profileDir).toBe('.vscode'); // default expect(vscodeProfile.rulesDir).toBe('.github/instructions'); // non-default expect(vscodeProfile.globalReplacements).toBeDefined(); // computed from customReplacements expect(Array.isArray(vscodeProfile.globalReplacements)).toBe(true); }); test('vscode.js configures .mdc to .instructions.md extension mapping', () => { // Check that the profile object has the correct file mapping behavior (vscode converts to .md) expect(vscodeProfile.fileMap['rules/cursor_rules.mdc']).toBe( 'vscode_rules.instructions.md' ); }); test('vscode.js uses standard tool mappings', () => { // Check that the profile uses default tool mappings (equivalent to COMMON_TOOL_MAPPINGS.STANDARD) // This verifies the architectural pattern: no custom toolMappings = standard tool names expect(vscodeProfileContent).not.toContain('toolMappings:'); expect(vscodeProfileContent).not.toContain('apply_diff'); expect(vscodeProfileContent).not.toContain('search_files'); // Verify the result: default mappings means tools keep their original names expect(vscodeProfile.conversionConfig.toolNames.edit_file).toBe( 'edit_file' ); expect(vscodeProfile.conversionConfig.toolNames.search).toBe('search'); }); }); ``` -------------------------------------------------------------------------------- /mcp-server/src/custom-sdk/errors.js: -------------------------------------------------------------------------------- ```javascript /** * src/ai-providers/custom-sdk/mcp/errors.js * * Error handling utilities for MCP AI SDK provider. * Maps MCP errors to AI SDK compatible error types. */ /** * MCP-specific error class */ export class MCPError extends Error { constructor(message, options = {}) { super(message); this.name = 'MCPError'; this.code = options.code; this.cause = options.cause; this.mcpResponse = options.mcpResponse; } } /** * Session-related error */ export class MCPSessionError extends MCPError { constructor(message, options = {}) { super(message, options); this.name = 'MCPSessionError'; } } /** * Sampling-related error */ export class MCPSamplingError extends MCPError { constructor(message, options = {}) { super(message, options); this.name = 'MCPSamplingError'; } } /** * Map MCP errors to AI SDK compatible error types * @param {Error} error - Original error * @returns {Error} Mapped error */ export function mapMCPError(error) { // If already an MCP error, return as-is if (error instanceof MCPError) { return error; } const message = error.message || 'Unknown MCP error'; const originalError = error; // Map common error patterns if (message.includes('session') || message.includes('connection')) { return new MCPSessionError(message, { cause: originalError, code: 'SESSION_ERROR' }); } if (message.includes('sampling') || message.includes('timeout')) { return new MCPSamplingError(message, { cause: originalError, code: 'SAMPLING_ERROR' }); } if (message.includes('capabilities') || message.includes('not supported')) { return new MCPSessionError(message, { cause: originalError, code: 'CAPABILITY_ERROR' }); } // Default to generic MCP error return new MCPError(message, { cause: originalError, code: 'UNKNOWN_ERROR' }); } /** * Check if error is retryable * @param {Error} error - Error to check * @returns {boolean} True if error might be retryable */ export function isRetryableError(error) { if (error instanceof MCPSamplingError && error.code === 'SAMPLING_ERROR') { return true; } if (error instanceof MCPSessionError && error.code === 'SESSION_ERROR') { // Session errors are generally not retryable return false; } // Check for common retryable patterns const message = error.message?.toLowerCase() || ''; return ( message.includes('timeout') || message.includes('network') || message.includes('temporary') ); } ``` -------------------------------------------------------------------------------- /tests/unit/mcp-providers/mcp-provider.test.js: -------------------------------------------------------------------------------- ```javascript /** * tests/unit/mcp-providers/mcp-provider.test.js * Unit tests for MCP provider */ import { jest } from '@jest/globals'; describe('MCPProvider', () => { let MCPProvider; let provider; beforeAll(async () => { // Dynamic import to avoid circular dependency issues const module = await import( '../../../mcp-server/src/providers/mcp-provider.js' ); MCPProvider = module.MCPProvider; }); beforeEach(() => { provider = new MCPProvider(); }); describe('constructor', () => { it('should initialize with correct name', () => { expect(provider.name).toBe('mcp'); }); it('should initialize with null session', () => { expect(provider.session).toBeNull(); }); }); describe('isRequiredApiKey', () => { it('should return false (no API key required)', () => { expect(provider.isRequiredApiKey()).toBe(false); }); }); describe('validateAuth', () => { it('should throw error when no session', () => { expect(() => provider.validateAuth({})).toThrow( 'MCP Provider requires active MCP session' ); }); it('should throw error when session lacks sampling capabilities', () => { provider.session = { clientCapabilities: {} }; expect(() => provider.validateAuth({})).toThrow( 'MCP session must have client sampling capabilities' ); }); it('should pass validation with valid session', () => { provider.session = { clientCapabilities: { sampling: true } }; expect(() => provider.validateAuth({})).not.toThrow(); }); }); describe('setSession', () => { it('should set session when provided', () => { const mockSession = { clientCapabilities: { sampling: true } }; provider.setSession(mockSession); expect(provider.session).toBe(mockSession); }); it('should handle null session gracefully', () => { provider.setSession(null); expect(provider.session).toBeNull(); }); }); describe('hasValidSession', () => { it('should return false when no session', () => { expect(provider.hasValidSession()).toBe(false); }); it('should return false when session lacks sampling capabilities', () => { provider.session = { clientCapabilities: {} }; expect(provider.hasValidSession()).toBe(false); }); it('should return true with valid session', () => { provider.session = { clientCapabilities: { sampling: true } }; expect(provider.hasValidSession()).toBe(true); }); }); }); ``` -------------------------------------------------------------------------------- /scripts/modules/task-manager/parse-prd/parse-prd-non-streaming.js: -------------------------------------------------------------------------------- ```javascript /** * Non-streaming handler for PRD parsing */ import ora from 'ora'; import { generateObjectService } from '../../ai-services-unified.js'; import { LoggingConfig, prdResponseSchema } from './parse-prd-config.js'; import { estimateTokens } from './parse-prd-helpers.js'; /** * Handle non-streaming AI service call * @param {Object} config - Configuration object * @param {Object} prompts - System and user prompts * @returns {Promise<Object>} Generated tasks and telemetry */ export async function handleNonStreamingService(config, prompts) { const logger = new LoggingConfig(config.mcpLog, config.reportProgress); const { systemPrompt, userPrompt } = prompts; const estimatedInputTokens = estimateTokens(systemPrompt + userPrompt); // Initialize spinner for CLI let spinner = null; if (config.outputFormat === 'text' && !config.isMCP) { spinner = ora('Parsing PRD and generating tasks...\n').start(); } try { // Call AI service logger.report( `Calling AI service to generate tasks from PRD${config.research ? ' with research-backed analysis' : ''}...`, 'info' ); const aiServiceResponse = await generateObjectService({ role: config.research ? 'research' : 'main', session: config.session, projectRoot: config.projectRoot, schema: prdResponseSchema, objectName: 'tasks_data', systemPrompt, prompt: userPrompt, commandName: 'parse-prd', outputType: config.isMCP ? 'mcp' : 'cli' }); // Extract generated data let generatedData = null; if (aiServiceResponse?.mainResult) { if ( typeof aiServiceResponse.mainResult === 'object' && aiServiceResponse.mainResult !== null && 'tasks' in aiServiceResponse.mainResult ) { generatedData = aiServiceResponse.mainResult; } else if ( typeof aiServiceResponse.mainResult.object === 'object' && aiServiceResponse.mainResult.object !== null && 'tasks' in aiServiceResponse.mainResult.object ) { generatedData = aiServiceResponse.mainResult.object; } } if (!generatedData || !Array.isArray(generatedData.tasks)) { throw new Error( 'AI service returned unexpected data structure after validation.' ); } if (spinner) { spinner.succeed('Tasks generated successfully!'); } return { parsedTasks: generatedData.tasks, aiServiceResponse, estimatedInputTokens }; } catch (error) { if (spinner) { spinner.fail(`Error parsing PRD: ${error.message}`); } throw error; } } ``` -------------------------------------------------------------------------------- /.github/scripts/utils.mjs: -------------------------------------------------------------------------------- ``` #!/usr/bin/env node import { spawnSync } from 'node:child_process'; import { readFileSync } from 'node:fs'; import { join, dirname, resolve } from 'node:path'; // Find the root directory by looking for package.json with task-master-ai export function findRootDir(startDir) { let currentDir = resolve(startDir); while (currentDir !== '/') { const pkgPath = join(currentDir, 'package.json'); try { const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')); if (pkg.name === 'task-master-ai' || pkg.repository) { return currentDir; } } catch {} currentDir = dirname(currentDir); } throw new Error('Could not find root directory'); } // Run a command with proper error handling export function runCommand(command, args = [], options = {}) { console.log(`Running: ${command} ${args.join(' ')}`); const result = spawnSync(command, args, { encoding: 'utf8', stdio: 'inherit', ...options }); if (result.status !== 0) { console.error(`Command failed with exit code ${result.status}`); process.exit(result.status); } return result; } // Get package version from a package.json file export function getPackageVersion(packagePath) { try { const pkg = JSON.parse(readFileSync(packagePath, 'utf8')); return pkg.version; } catch (error) { console.error( `Failed to read package version from ${packagePath}:`, error.message ); process.exit(1); } } // Check if a git tag exists on remote export function tagExistsOnRemote(tag, remote = 'origin') { const result = spawnSync('git', ['ls-remote', remote, tag], { encoding: 'utf8' }); return result.status === 0 && result.stdout.trim() !== ''; } // Create and push a git tag if it doesn't exist export function createAndPushTag(tag, remote = 'origin') { // Check if tag already exists if (tagExistsOnRemote(tag, remote)) { console.log(`Tag ${tag} already exists on remote, skipping`); return false; } console.log(`Creating new tag: ${tag}`); // Create the tag locally const tagResult = spawnSync('git', ['tag', tag]); if (tagResult.status !== 0) { console.error('Failed to create tag:', tagResult.error || tagResult.stderr); process.exit(1); } // Push the tag to remote const pushResult = spawnSync('git', ['push', remote, tag]); if (pushResult.status !== 0) { console.error('Failed to push tag:', pushResult.error || pushResult.stderr); process.exit(1); } console.log(`✅ Successfully created and pushed tag: ${tag}`); return true; } ``` -------------------------------------------------------------------------------- /.claude/commands/tm/complexity-report/complexity-report.md: -------------------------------------------------------------------------------- ```markdown Display the task complexity analysis report. Arguments: $ARGUMENTS View the detailed complexity analysis generated by analyze-complexity command. ## Viewing Complexity Report Shows comprehensive task complexity analysis with actionable insights. ## Execution ```bash task-master complexity-report [--file=<path>] ``` ## Report Location Default: `.taskmaster/reports/complexity-analysis.md` Custom: Specify with --file parameter ## Report Contents ### 1. **Executive Summary** ``` Complexity Analysis Summary ━━━━━━━━━━━━━━━━━━━━━━━━ Analysis Date: 2024-01-15 Tasks Analyzed: 32 High Complexity: 5 (16%) Medium Complexity: 12 (37%) Low Complexity: 15 (47%) Critical Findings: - 5 tasks need immediate expansion - 3 tasks have high technical risk - 2 tasks block critical path ``` ### 2. **Detailed Task Analysis** For each complex task: - Complexity score breakdown - Contributing factors - Specific risks identified - Expansion recommendations - Similar completed tasks ### 3. **Risk Matrix** Visual representation: ``` Risk vs Complexity Matrix ━━━━━━━━━━━━━━━━━━━━━━━ High Risk | #5(9) #12(8) | #23(6) Med Risk | #34(7) | #45(5) #67(5) Low Risk | #78(8) | [15 tasks] | High Complex | Med Complex ``` ### 4. **Recommendations** **Immediate Actions:** 1. Expand task #5 - Critical path + high complexity 2. Expand task #12 - High risk + dependencies 3. Review task #34 - Consider splitting **Sprint Planning:** - Don't schedule multiple high-complexity tasks together - Ensure expertise available for complex tasks - Build in buffer time for unknowns ## Interactive Features When viewing report: 1. **Quick Actions** - Press 'e' to expand a task - Press 'd' for task details - Press 'r' to refresh analysis 2. **Filtering** - View by complexity level - Filter by risk factors - Show only actionable items 3. **Export Options** - Markdown format - CSV for spreadsheets - JSON for tools ## Report Intelligence - Compares with historical data - Shows complexity trends - Identifies patterns - Suggests process improvements ## Integration Use report for: - Sprint planning sessions - Resource allocation - Risk assessment - Team discussions - Client updates ## Example Usage ``` /project:tm/complexity-report → Opens latest analysis /project:tm/complexity-report --file=archived/2024-01-01.md → View historical analysis After viewing: /project:tm/expand 5 → Expand high-complexity task ``` ``` -------------------------------------------------------------------------------- /assets/claude/commands/tm/complexity-report/complexity-report.md: -------------------------------------------------------------------------------- ```markdown Display the task complexity analysis report. Arguments: $ARGUMENTS View the detailed complexity analysis generated by analyze-complexity command. ## Viewing Complexity Report Shows comprehensive task complexity analysis with actionable insights. ## Execution ```bash task-master complexity-report [--file=<path>] ``` ## Report Location Default: `.taskmaster/reports/complexity-analysis.md` Custom: Specify with --file parameter ## Report Contents ### 1. **Executive Summary** ``` Complexity Analysis Summary ━━━━━━━━━━━━━━━━━━━━━━━━ Analysis Date: 2024-01-15 Tasks Analyzed: 32 High Complexity: 5 (16%) Medium Complexity: 12 (37%) Low Complexity: 15 (47%) Critical Findings: - 5 tasks need immediate expansion - 3 tasks have high technical risk - 2 tasks block critical path ``` ### 2. **Detailed Task Analysis** For each complex task: - Complexity score breakdown - Contributing factors - Specific risks identified - Expansion recommendations - Similar completed tasks ### 3. **Risk Matrix** Visual representation: ``` Risk vs Complexity Matrix ━━━━━━━━━━━━━━━━━━━━━━━ High Risk | #5(9) #12(8) | #23(6) Med Risk | #34(7) | #45(5) #67(5) Low Risk | #78(8) | [15 tasks] | High Complex | Med Complex ``` ### 4. **Recommendations** **Immediate Actions:** 1. Expand task #5 - Critical path + high complexity 2. Expand task #12 - High risk + dependencies 3. Review task #34 - Consider splitting **Sprint Planning:** - Don't schedule multiple high-complexity tasks together - Ensure expertise available for complex tasks - Build in buffer time for unknowns ## Interactive Features When viewing report: 1. **Quick Actions** - Press 'e' to expand a task - Press 'd' for task details - Press 'r' to refresh analysis 2. **Filtering** - View by complexity level - Filter by risk factors - Show only actionable items 3. **Export Options** - Markdown format - CSV for spreadsheets - JSON for tools ## Report Intelligence - Compares with historical data - Shows complexity trends - Identifies patterns - Suggests process improvements ## Integration Use report for: - Sprint planning sessions - Resource allocation - Risk assessment - Team discussions - Client updates ## Example Usage ``` /project:tm/complexity-report → Opens latest analysis /project:tm/complexity-report --file=archived/2024-01-01.md → View historical analysis After viewing: /project:tm/expand 5 → Expand high-complexity task ``` ```