This is page 4 of 69. Use http://codebase.md/eyaltoledano/claude-task-master?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│ ├── config.json
│ └── README.md
├── .claude
│ ├── commands
│ │ └── dedupe.md
│ └── TM_COMMANDS_GUIDE.md
├── .claude-plugin
│ └── marketplace.json
├── .coderabbit.yaml
├── .cursor
│ ├── mcp.json
│ └── rules
│ ├── ai_providers.mdc
│ ├── ai_services.mdc
│ ├── architecture.mdc
│ ├── changeset.mdc
│ ├── commands.mdc
│ ├── context_gathering.mdc
│ ├── cursor_rules.mdc
│ ├── dependencies.mdc
│ ├── dev_workflow.mdc
│ ├── git_workflow.mdc
│ ├── glossary.mdc
│ ├── mcp.mdc
│ ├── new_features.mdc
│ ├── self_improve.mdc
│ ├── tags.mdc
│ ├── taskmaster.mdc
│ ├── tasks.mdc
│ ├── telemetry.mdc
│ ├── test_workflow.mdc
│ ├── tests.mdc
│ ├── ui.mdc
│ └── utilities.mdc
├── .cursorignore
├── .env.example
├── .github
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ ├── enhancements---feature-requests.md
│ │ └── feedback.md
│ ├── PULL_REQUEST_TEMPLATE
│ │ ├── bugfix.md
│ │ ├── config.yml
│ │ ├── feature.md
│ │ └── integration.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── scripts
│ │ ├── auto-close-duplicates.mjs
│ │ ├── backfill-duplicate-comments.mjs
│ │ ├── check-pre-release-mode.mjs
│ │ ├── parse-metrics.mjs
│ │ ├── release.mjs
│ │ ├── tag-extension.mjs
│ │ ├── utils.mjs
│ │ └── validate-changesets.mjs
│ └── workflows
│ ├── auto-close-duplicates.yml
│ ├── backfill-duplicate-comments.yml
│ ├── ci.yml
│ ├── claude-dedupe-issues.yml
│ ├── claude-docs-trigger.yml
│ ├── claude-docs-updater.yml
│ ├── claude-issue-triage.yml
│ ├── claude.yml
│ ├── extension-ci.yml
│ ├── extension-release.yml
│ ├── log-issue-events.yml
│ ├── pre-release.yml
│ ├── release-check.yml
│ ├── release.yml
│ ├── update-models-md.yml
│ └── weekly-metrics-discord.yml
├── .gitignore
├── .kiro
│ ├── hooks
│ │ ├── tm-code-change-task-tracker.kiro.hook
│ │ ├── tm-complexity-analyzer.kiro.hook
│ │ ├── tm-daily-standup-assistant.kiro.hook
│ │ ├── tm-git-commit-task-linker.kiro.hook
│ │ ├── tm-pr-readiness-checker.kiro.hook
│ │ ├── tm-task-dependency-auto-progression.kiro.hook
│ │ └── tm-test-success-task-completer.kiro.hook
│ ├── settings
│ │ └── mcp.json
│ └── steering
│ ├── dev_workflow.md
│ ├── kiro_rules.md
│ ├── self_improve.md
│ ├── taskmaster_hooks_workflow.md
│ └── taskmaster.md
├── .manypkg.json
├── .mcp.json
├── .npmignore
├── .nvmrc
├── .taskmaster
│ ├── CLAUDE.md
│ ├── config.json
│ ├── docs
│ │ ├── autonomous-tdd-git-workflow.md
│ │ ├── MIGRATION-ROADMAP.md
│ │ ├── prd-tm-start.txt
│ │ ├── prd.txt
│ │ ├── README.md
│ │ ├── research
│ │ │ ├── 2025-06-14_how-can-i-improve-the-scope-up-and-scope-down-comm.md
│ │ │ ├── 2025-06-14_should-i-be-using-any-specific-libraries-for-this.md
│ │ │ ├── 2025-06-14_test-save-functionality.md
│ │ │ ├── 2025-06-14_test-the-fix-for-duplicate-saves-final-test.md
│ │ │ └── 2025-08-01_do-we-need-to-add-new-commands-or-can-we-just-weap.md
│ │ ├── task-template-importing-prd.txt
│ │ ├── tdd-workflow-phase-0-spike.md
│ │ ├── tdd-workflow-phase-1-core-rails.md
│ │ ├── tdd-workflow-phase-1-orchestrator.md
│ │ ├── tdd-workflow-phase-2-pr-resumability.md
│ │ ├── tdd-workflow-phase-3-extensibility-guardrails.md
│ │ ├── test-prd.txt
│ │ └── tm-core-phase-1.txt
│ ├── reports
│ │ ├── task-complexity-report_autonomous-tdd-git-workflow.json
│ │ ├── task-complexity-report_cc-kiro-hooks.json
│ │ ├── task-complexity-report_tdd-phase-1-core-rails.json
│ │ ├── task-complexity-report_tdd-workflow-phase-0.json
│ │ ├── task-complexity-report_test-prd-tag.json
│ │ ├── task-complexity-report_tm-core-phase-1.json
│ │ ├── task-complexity-report.json
│ │ └── tm-core-complexity.json
│ ├── state.json
│ ├── tasks
│ │ ├── task_001_tm-start.txt
│ │ ├── task_002_tm-start.txt
│ │ ├── task_003_tm-start.txt
│ │ ├── task_004_tm-start.txt
│ │ ├── task_007_tm-start.txt
│ │ └── tasks.json
│ └── templates
│ ├── example_prd_rpg.md
│ └── example_prd.md
├── .vscode
│ ├── extensions.json
│ └── settings.json
├── apps
│ ├── cli
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── command-registry.ts
│ │ │ ├── commands
│ │ │ │ ├── auth.command.ts
│ │ │ │ ├── autopilot
│ │ │ │ │ ├── abort.command.ts
│ │ │ │ │ ├── commit.command.ts
│ │ │ │ │ ├── complete.command.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── next.command.ts
│ │ │ │ │ ├── resume.command.ts
│ │ │ │ │ ├── shared.ts
│ │ │ │ │ ├── start.command.ts
│ │ │ │ │ └── status.command.ts
│ │ │ │ ├── briefs.command.ts
│ │ │ │ ├── context.command.ts
│ │ │ │ ├── export.command.ts
│ │ │ │ ├── list.command.ts
│ │ │ │ ├── models
│ │ │ │ │ ├── custom-providers.ts
│ │ │ │ │ ├── fetchers.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── prompts.ts
│ │ │ │ │ ├── setup.ts
│ │ │ │ │ └── types.ts
│ │ │ │ ├── next.command.ts
│ │ │ │ ├── set-status.command.ts
│ │ │ │ ├── show.command.ts
│ │ │ │ ├── start.command.ts
│ │ │ │ └── tags.command.ts
│ │ │ ├── index.ts
│ │ │ ├── lib
│ │ │ │ └── model-management.ts
│ │ │ ├── types
│ │ │ │ └── tag-management.d.ts
│ │ │ ├── ui
│ │ │ │ ├── components
│ │ │ │ │ ├── cardBox.component.ts
│ │ │ │ │ ├── dashboard.component.ts
│ │ │ │ │ ├── header.component.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── next-task.component.ts
│ │ │ │ │ ├── suggested-steps.component.ts
│ │ │ │ │ └── task-detail.component.ts
│ │ │ │ ├── display
│ │ │ │ │ ├── messages.ts
│ │ │ │ │ └── tables.ts
│ │ │ │ ├── formatters
│ │ │ │ │ ├── complexity-formatters.ts
│ │ │ │ │ ├── dependency-formatters.ts
│ │ │ │ │ ├── priority-formatters.ts
│ │ │ │ │ ├── status-formatters.spec.ts
│ │ │ │ │ └── status-formatters.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── layout
│ │ │ │ ├── helpers.spec.ts
│ │ │ │ └── helpers.ts
│ │ │ └── utils
│ │ │ ├── auth-helpers.ts
│ │ │ ├── auto-update.ts
│ │ │ ├── brief-selection.ts
│ │ │ ├── display-helpers.ts
│ │ │ ├── error-handler.ts
│ │ │ ├── index.ts
│ │ │ ├── project-root.ts
│ │ │ ├── task-status.ts
│ │ │ ├── ui.spec.ts
│ │ │ └── ui.ts
│ │ ├── tests
│ │ │ ├── integration
│ │ │ │ └── commands
│ │ │ │ └── autopilot
│ │ │ │ └── workflow.test.ts
│ │ │ └── unit
│ │ │ ├── commands
│ │ │ │ ├── autopilot
│ │ │ │ │ └── shared.test.ts
│ │ │ │ ├── list.command.spec.ts
│ │ │ │ └── show.command.spec.ts
│ │ │ └── ui
│ │ │ └── dashboard.component.spec.ts
│ │ ├── tsconfig.json
│ │ └── vitest.config.ts
│ ├── docs
│ │ ├── archive
│ │ │ ├── ai-client-utils-example.mdx
│ │ │ ├── ai-development-workflow.mdx
│ │ │ ├── command-reference.mdx
│ │ │ ├── configuration.mdx
│ │ │ ├── cursor-setup.mdx
│ │ │ ├── examples.mdx
│ │ │ └── Installation.mdx
│ │ ├── best-practices
│ │ │ ├── advanced-tasks.mdx
│ │ │ ├── configuration-advanced.mdx
│ │ │ └── index.mdx
│ │ ├── capabilities
│ │ │ ├── cli-root-commands.mdx
│ │ │ ├── index.mdx
│ │ │ ├── mcp.mdx
│ │ │ ├── rpg-method.mdx
│ │ │ └── task-structure.mdx
│ │ ├── CHANGELOG.md
│ │ ├── command-reference.mdx
│ │ ├── configuration.mdx
│ │ ├── docs.json
│ │ ├── favicon.svg
│ │ ├── getting-started
│ │ │ ├── api-keys.mdx
│ │ │ ├── contribute.mdx
│ │ │ ├── faq.mdx
│ │ │ └── quick-start
│ │ │ ├── configuration-quick.mdx
│ │ │ ├── execute-quick.mdx
│ │ │ ├── installation.mdx
│ │ │ ├── moving-forward.mdx
│ │ │ ├── prd-quick.mdx
│ │ │ ├── quick-start.mdx
│ │ │ ├── requirements.mdx
│ │ │ ├── rules-quick.mdx
│ │ │ └── tasks-quick.mdx
│ │ ├── introduction.mdx
│ │ ├── licensing.md
│ │ ├── logo
│ │ │ ├── dark.svg
│ │ │ ├── light.svg
│ │ │ └── task-master-logo.png
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── style.css
│ │ ├── tdd-workflow
│ │ │ ├── ai-agent-integration.mdx
│ │ │ └── quickstart.mdx
│ │ ├── vercel.json
│ │ └── whats-new.mdx
│ ├── extension
│ │ ├── .vscodeignore
│ │ ├── assets
│ │ │ ├── banner.png
│ │ │ ├── icon-dark.svg
│ │ │ ├── icon-light.svg
│ │ │ ├── icon.png
│ │ │ ├── screenshots
│ │ │ │ ├── kanban-board.png
│ │ │ │ └── task-details.png
│ │ │ └── sidebar-icon.svg
│ │ ├── CHANGELOG.md
│ │ ├── components.json
│ │ ├── docs
│ │ │ ├── extension-CI-setup.md
│ │ │ └── extension-development-guide.md
│ │ ├── esbuild.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── package.mjs
│ │ ├── package.publish.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── components
│ │ │ │ ├── ConfigView.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ ├── TaskDetails
│ │ │ │ │ ├── AIActionsSection.tsx
│ │ │ │ │ ├── DetailsSection.tsx
│ │ │ │ │ ├── PriorityBadge.tsx
│ │ │ │ │ ├── SubtasksSection.tsx
│ │ │ │ │ ├── TaskMetadataSidebar.tsx
│ │ │ │ │ └── useTaskDetails.ts
│ │ │ │ ├── TaskDetailsView.tsx
│ │ │ │ ├── TaskMasterLogo.tsx
│ │ │ │ └── ui
│ │ │ │ ├── badge.tsx
│ │ │ │ ├── breadcrumb.tsx
│ │ │ │ ├── button.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ ├── collapsible.tsx
│ │ │ │ ├── CollapsibleSection.tsx
│ │ │ │ ├── dropdown-menu.tsx
│ │ │ │ ├── label.tsx
│ │ │ │ ├── scroll-area.tsx
│ │ │ │ ├── separator.tsx
│ │ │ │ ├── shadcn-io
│ │ │ │ │ └── kanban
│ │ │ │ │ └── index.tsx
│ │ │ │ └── textarea.tsx
│ │ │ ├── extension.ts
│ │ │ ├── index.ts
│ │ │ ├── lib
│ │ │ │ └── utils.ts
│ │ │ ├── services
│ │ │ │ ├── config-service.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── notification-preferences.ts
│ │ │ │ ├── polling-service.ts
│ │ │ │ ├── polling-strategies.ts
│ │ │ │ ├── sidebar-webview-manager.ts
│ │ │ │ ├── task-repository.ts
│ │ │ │ ├── terminal-manager.ts
│ │ │ │ └── webview-manager.ts
│ │ │ ├── test
│ │ │ │ └── extension.test.ts
│ │ │ ├── utils
│ │ │ │ ├── configManager.ts
│ │ │ │ ├── connectionManager.ts
│ │ │ │ ├── errorHandler.ts
│ │ │ │ ├── event-emitter.ts
│ │ │ │ ├── logger.ts
│ │ │ │ ├── mcpClient.ts
│ │ │ │ ├── notificationPreferences.ts
│ │ │ │ └── task-master-api
│ │ │ │ ├── cache
│ │ │ │ │ └── cache-manager.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── mcp-client.ts
│ │ │ │ ├── transformers
│ │ │ │ │ └── task-transformer.ts
│ │ │ │ └── types
│ │ │ │ └── index.ts
│ │ │ └── webview
│ │ │ ├── App.tsx
│ │ │ ├── components
│ │ │ │ ├── AppContent.tsx
│ │ │ │ ├── EmptyState.tsx
│ │ │ │ ├── ErrorBoundary.tsx
│ │ │ │ ├── PollingStatus.tsx
│ │ │ │ ├── PriorityBadge.tsx
│ │ │ │ ├── SidebarView.tsx
│ │ │ │ ├── TagDropdown.tsx
│ │ │ │ ├── TaskCard.tsx
│ │ │ │ ├── TaskEditModal.tsx
│ │ │ │ ├── TaskMasterKanban.tsx
│ │ │ │ ├── ToastContainer.tsx
│ │ │ │ └── ToastNotification.tsx
│ │ │ ├── constants
│ │ │ │ └── index.ts
│ │ │ ├── contexts
│ │ │ │ └── VSCodeContext.tsx
│ │ │ ├── hooks
│ │ │ │ ├── useTaskQueries.ts
│ │ │ │ ├── useVSCodeMessages.ts
│ │ │ │ └── useWebviewHeight.ts
│ │ │ ├── index.css
│ │ │ ├── index.tsx
│ │ │ ├── providers
│ │ │ │ └── QueryProvider.tsx
│ │ │ ├── reducers
│ │ │ │ └── appReducer.ts
│ │ │ ├── sidebar.tsx
│ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ └── utils
│ │ │ ├── logger.ts
│ │ │ └── toast.ts
│ │ └── tsconfig.json
│ └── mcp
│ ├── CHANGELOG.md
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ ├── shared
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ └── tools
│ │ ├── autopilot
│ │ │ ├── abort.tool.ts
│ │ │ ├── commit.tool.ts
│ │ │ ├── complete.tool.ts
│ │ │ ├── finalize.tool.ts
│ │ │ ├── index.ts
│ │ │ ├── next.tool.ts
│ │ │ ├── resume.tool.ts
│ │ │ ├── start.tool.ts
│ │ │ └── status.tool.ts
│ │ ├── README-ZOD-V3.md
│ │ └── tasks
│ │ ├── get-task.tool.ts
│ │ ├── get-tasks.tool.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ └── vitest.config.ts
├── assets
│ ├── .windsurfrules
│ ├── AGENTS.md
│ ├── claude
│ │ └── TM_COMMANDS_GUIDE.md
│ ├── config.json
│ ├── env.example
│ ├── example_prd_rpg.txt
│ ├── example_prd.txt
│ ├── GEMINI.md
│ ├── gitignore
│ ├── kiro-hooks
│ │ ├── tm-code-change-task-tracker.kiro.hook
│ │ ├── tm-complexity-analyzer.kiro.hook
│ │ ├── tm-daily-standup-assistant.kiro.hook
│ │ ├── tm-git-commit-task-linker.kiro.hook
│ │ ├── tm-pr-readiness-checker.kiro.hook
│ │ ├── tm-task-dependency-auto-progression.kiro.hook
│ │ └── tm-test-success-task-completer.kiro.hook
│ ├── roocode
│ │ ├── .roo
│ │ │ ├── rules-architect
│ │ │ │ └── architect-rules
│ │ │ ├── rules-ask
│ │ │ │ └── ask-rules
│ │ │ ├── rules-code
│ │ │ │ └── code-rules
│ │ │ ├── rules-debug
│ │ │ │ └── debug-rules
│ │ │ ├── rules-orchestrator
│ │ │ │ └── orchestrator-rules
│ │ │ └── rules-test
│ │ │ └── test-rules
│ │ └── .roomodes
│ ├── rules
│ │ ├── cursor_rules.mdc
│ │ ├── dev_workflow.mdc
│ │ ├── self_improve.mdc
│ │ ├── taskmaster_hooks_workflow.mdc
│ │ └── taskmaster.mdc
│ └── scripts_README.md
├── bin
│ └── task-master.js
├── biome.json
├── CHANGELOG.md
├── CLAUDE_CODE_PLUGIN.md
├── CLAUDE.md
├── context
│ ├── chats
│ │ ├── add-task-dependencies-1.md
│ │ └── max-min-tokens.txt.md
│ ├── fastmcp-core.txt
│ ├── fastmcp-docs.txt
│ ├── MCP_INTEGRATION.md
│ ├── mcp-js-sdk-docs.txt
│ ├── mcp-protocol-repo.txt
│ ├── mcp-protocol-schema-03262025.json
│ └── mcp-protocol-spec.txt
├── CONTRIBUTING.md
├── docs
│ ├── claude-code-integration.md
│ ├── CLI-COMMANDER-PATTERN.md
│ ├── command-reference.md
│ ├── configuration.md
│ ├── contributor-docs
│ │ ├── testing-roo-integration.md
│ │ └── worktree-setup.md
│ ├── cross-tag-task-movement.md
│ ├── examples
│ │ ├── claude-code-usage.md
│ │ └── codex-cli-usage.md
│ ├── examples.md
│ ├── licensing.md
│ ├── mcp-provider-guide.md
│ ├── mcp-provider.md
│ ├── migration-guide.md
│ ├── models.md
│ ├── providers
│ │ ├── codex-cli.md
│ │ └── gemini-cli.md
│ ├── README.md
│ ├── scripts
│ │ └── models-json-to-markdown.js
│ ├── task-structure.md
│ └── tutorial.md
├── images
│ ├── hamster-hiring.png
│ └── logo.png
├── index.js
├── jest.config.js
├── jest.resolver.cjs
├── LICENSE
├── llms-install.md
├── mcp-server
│ ├── server.js
│ └── src
│ ├── core
│ │ ├── __tests__
│ │ │ └── context-manager.test.js
│ │ ├── context-manager.js
│ │ ├── direct-functions
│ │ │ ├── add-dependency.js
│ │ │ ├── add-subtask.js
│ │ │ ├── add-tag.js
│ │ │ ├── add-task.js
│ │ │ ├── analyze-task-complexity.js
│ │ │ ├── cache-stats.js
│ │ │ ├── clear-subtasks.js
│ │ │ ├── complexity-report.js
│ │ │ ├── copy-tag.js
│ │ │ ├── create-tag-from-branch.js
│ │ │ ├── delete-tag.js
│ │ │ ├── expand-all-tasks.js
│ │ │ ├── expand-task.js
│ │ │ ├── fix-dependencies.js
│ │ │ ├── generate-task-files.js
│ │ │ ├── initialize-project.js
│ │ │ ├── list-tags.js
│ │ │ ├── models.js
│ │ │ ├── move-task-cross-tag.js
│ │ │ ├── move-task.js
│ │ │ ├── next-task.js
│ │ │ ├── parse-prd.js
│ │ │ ├── remove-dependency.js
│ │ │ ├── remove-subtask.js
│ │ │ ├── remove-task.js
│ │ │ ├── rename-tag.js
│ │ │ ├── research.js
│ │ │ ├── response-language.js
│ │ │ ├── rules.js
│ │ │ ├── scope-down.js
│ │ │ ├── scope-up.js
│ │ │ ├── set-task-status.js
│ │ │ ├── update-subtask-by-id.js
│ │ │ ├── update-task-by-id.js
│ │ │ ├── update-tasks.js
│ │ │ ├── use-tag.js
│ │ │ └── validate-dependencies.js
│ │ ├── task-master-core.js
│ │ └── utils
│ │ ├── env-utils.js
│ │ └── path-utils.js
│ ├── custom-sdk
│ │ ├── errors.js
│ │ ├── index.js
│ │ ├── json-extractor.js
│ │ ├── language-model.js
│ │ ├── message-converter.js
│ │ └── schema-converter.js
│ ├── index.js
│ ├── logger.js
│ ├── providers
│ │ └── mcp-provider.js
│ └── tools
│ ├── add-dependency.js
│ ├── add-subtask.js
│ ├── add-tag.js
│ ├── add-task.js
│ ├── analyze.js
│ ├── clear-subtasks.js
│ ├── complexity-report.js
│ ├── copy-tag.js
│ ├── delete-tag.js
│ ├── expand-all.js
│ ├── expand-task.js
│ ├── fix-dependencies.js
│ ├── generate.js
│ ├── get-operation-status.js
│ ├── index.js
│ ├── initialize-project.js
│ ├── list-tags.js
│ ├── models.js
│ ├── move-task.js
│ ├── next-task.js
│ ├── parse-prd.js
│ ├── README-ZOD-V3.md
│ ├── remove-dependency.js
│ ├── remove-subtask.js
│ ├── remove-task.js
│ ├── rename-tag.js
│ ├── research.js
│ ├── response-language.js
│ ├── rules.js
│ ├── scope-down.js
│ ├── scope-up.js
│ ├── set-task-status.js
│ ├── tool-registry.js
│ ├── update-subtask.js
│ ├── update-task.js
│ ├── update.js
│ ├── use-tag.js
│ ├── utils.js
│ └── validate-dependencies.js
├── mcp-test.js
├── output.json
├── package-lock.json
├── package.json
├── packages
│ ├── ai-sdk-provider-grok-cli
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── errors.test.ts
│ │ │ ├── errors.ts
│ │ │ ├── grok-cli-language-model.ts
│ │ │ ├── grok-cli-provider.test.ts
│ │ │ ├── grok-cli-provider.ts
│ │ │ ├── index.ts
│ │ │ ├── json-extractor.test.ts
│ │ │ ├── json-extractor.ts
│ │ │ ├── message-converter.test.ts
│ │ │ ├── message-converter.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── build-config
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ ├── src
│ │ │ └── tsdown.base.ts
│ │ └── tsconfig.json
│ ├── claude-code-plugin
│ │ ├── .claude-plugin
│ │ │ └── plugin.json
│ │ ├── .gitignore
│ │ ├── agents
│ │ │ ├── task-checker.md
│ │ │ ├── task-executor.md
│ │ │ └── task-orchestrator.md
│ │ ├── CHANGELOG.md
│ │ ├── commands
│ │ │ ├── add-dependency.md
│ │ │ ├── add-subtask.md
│ │ │ ├── add-task.md
│ │ │ ├── analyze-complexity.md
│ │ │ ├── analyze-project.md
│ │ │ ├── auto-implement-tasks.md
│ │ │ ├── command-pipeline.md
│ │ │ ├── complexity-report.md
│ │ │ ├── convert-task-to-subtask.md
│ │ │ ├── expand-all-tasks.md
│ │ │ ├── expand-task.md
│ │ │ ├── fix-dependencies.md
│ │ │ ├── generate-tasks.md
│ │ │ ├── help.md
│ │ │ ├── init-project-quick.md
│ │ │ ├── init-project.md
│ │ │ ├── install-taskmaster.md
│ │ │ ├── learn.md
│ │ │ ├── list-tasks-by-status.md
│ │ │ ├── list-tasks-with-subtasks.md
│ │ │ ├── list-tasks.md
│ │ │ ├── next-task.md
│ │ │ ├── parse-prd-with-research.md
│ │ │ ├── parse-prd.md
│ │ │ ├── project-status.md
│ │ │ ├── quick-install-taskmaster.md
│ │ │ ├── remove-all-subtasks.md
│ │ │ ├── remove-dependency.md
│ │ │ ├── remove-subtask.md
│ │ │ ├── remove-subtasks.md
│ │ │ ├── remove-task.md
│ │ │ ├── setup-models.md
│ │ │ ├── show-task.md
│ │ │ ├── smart-workflow.md
│ │ │ ├── sync-readme.md
│ │ │ ├── tm-main.md
│ │ │ ├── to-cancelled.md
│ │ │ ├── to-deferred.md
│ │ │ ├── to-done.md
│ │ │ ├── to-in-progress.md
│ │ │ ├── to-pending.md
│ │ │ ├── to-review.md
│ │ │ ├── update-single-task.md
│ │ │ ├── update-task.md
│ │ │ ├── update-tasks-from-id.md
│ │ │ ├── validate-dependencies.md
│ │ │ └── view-models.md
│ │ ├── mcp.json
│ │ └── package.json
│ ├── tm-bridge
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── add-tag-bridge.ts
│ │ │ ├── bridge-types.ts
│ │ │ ├── bridge-utils.ts
│ │ │ ├── expand-bridge.ts
│ │ │ ├── index.ts
│ │ │ ├── tags-bridge.ts
│ │ │ ├── update-bridge.ts
│ │ │ └── use-tag-bridge.ts
│ │ └── tsconfig.json
│ └── tm-core
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── docs
│ │ └── listTasks-architecture.md
│ ├── package.json
│ ├── POC-STATUS.md
│ ├── README.md
│ ├── src
│ │ ├── common
│ │ │ ├── constants
│ │ │ │ ├── index.ts
│ │ │ │ ├── paths.ts
│ │ │ │ └── providers.ts
│ │ │ ├── errors
│ │ │ │ ├── index.ts
│ │ │ │ └── task-master-error.ts
│ │ │ ├── interfaces
│ │ │ │ ├── configuration.interface.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── storage.interface.ts
│ │ │ ├── logger
│ │ │ │ ├── factory.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── logger.spec.ts
│ │ │ │ └── logger.ts
│ │ │ ├── mappers
│ │ │ │ ├── TaskMapper.test.ts
│ │ │ │ └── TaskMapper.ts
│ │ │ ├── types
│ │ │ │ ├── database.types.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── legacy.ts
│ │ │ │ └── repository-types.ts
│ │ │ └── utils
│ │ │ ├── git-utils.ts
│ │ │ ├── id-generator.ts
│ │ │ ├── index.ts
│ │ │ ├── path-helpers.ts
│ │ │ ├── path-normalizer.spec.ts
│ │ │ ├── path-normalizer.ts
│ │ │ ├── project-root-finder.spec.ts
│ │ │ ├── project-root-finder.ts
│ │ │ ├── run-id-generator.spec.ts
│ │ │ └── run-id-generator.ts
│ │ ├── index.ts
│ │ ├── modules
│ │ │ ├── ai
│ │ │ │ ├── index.ts
│ │ │ │ ├── interfaces
│ │ │ │ │ └── ai-provider.interface.ts
│ │ │ │ └── providers
│ │ │ │ ├── base-provider.ts
│ │ │ │ └── index.ts
│ │ │ ├── auth
│ │ │ │ ├── auth-domain.spec.ts
│ │ │ │ ├── auth-domain.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── managers
│ │ │ │ │ ├── auth-manager.spec.ts
│ │ │ │ │ └── auth-manager.ts
│ │ │ │ ├── services
│ │ │ │ │ ├── context-store.ts
│ │ │ │ │ ├── oauth-service.ts
│ │ │ │ │ ├── organization.service.ts
│ │ │ │ │ ├── supabase-session-storage.spec.ts
│ │ │ │ │ └── supabase-session-storage.ts
│ │ │ │ └── types.ts
│ │ │ ├── briefs
│ │ │ │ ├── briefs-domain.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── brief-service.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils
│ │ │ │ └── url-parser.ts
│ │ │ ├── commands
│ │ │ │ └── index.ts
│ │ │ ├── config
│ │ │ │ ├── config-domain.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── managers
│ │ │ │ │ ├── config-manager.spec.ts
│ │ │ │ │ └── config-manager.ts
│ │ │ │ └── services
│ │ │ │ ├── config-loader.service.spec.ts
│ │ │ │ ├── config-loader.service.ts
│ │ │ │ ├── config-merger.service.spec.ts
│ │ │ │ ├── config-merger.service.ts
│ │ │ │ ├── config-persistence.service.spec.ts
│ │ │ │ ├── config-persistence.service.ts
│ │ │ │ ├── environment-config-provider.service.spec.ts
│ │ │ │ ├── environment-config-provider.service.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── runtime-state-manager.service.spec.ts
│ │ │ │ └── runtime-state-manager.service.ts
│ │ │ ├── dependencies
│ │ │ │ └── index.ts
│ │ │ ├── execution
│ │ │ │ ├── executors
│ │ │ │ │ ├── base-executor.ts
│ │ │ │ │ ├── claude-executor.ts
│ │ │ │ │ └── executor-factory.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── executor-service.ts
│ │ │ │ └── types.ts
│ │ │ ├── git
│ │ │ │ ├── adapters
│ │ │ │ │ ├── git-adapter.test.ts
│ │ │ │ │ └── git-adapter.ts
│ │ │ │ ├── git-domain.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── services
│ │ │ │ ├── branch-name-generator.spec.ts
│ │ │ │ ├── branch-name-generator.ts
│ │ │ │ ├── commit-message-generator.test.ts
│ │ │ │ ├── commit-message-generator.ts
│ │ │ │ ├── scope-detector.test.ts
│ │ │ │ ├── scope-detector.ts
│ │ │ │ ├── template-engine.test.ts
│ │ │ │ └── template-engine.ts
│ │ │ ├── integration
│ │ │ │ ├── clients
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── supabase-client.ts
│ │ │ │ ├── integration-domain.ts
│ │ │ │ └── services
│ │ │ │ ├── export.service.ts
│ │ │ │ ├── task-expansion.service.ts
│ │ │ │ └── task-retrieval.service.ts
│ │ │ ├── reports
│ │ │ │ ├── index.ts
│ │ │ │ ├── managers
│ │ │ │ │ └── complexity-report-manager.ts
│ │ │ │ └── types.ts
│ │ │ ├── storage
│ │ │ │ ├── adapters
│ │ │ │ │ ├── activity-logger.ts
│ │ │ │ │ ├── api-storage.ts
│ │ │ │ │ └── file-storage
│ │ │ │ │ ├── file-operations.ts
│ │ │ │ │ ├── file-storage.ts
│ │ │ │ │ ├── format-handler.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── path-resolver.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── storage-factory.ts
│ │ │ │ └── utils
│ │ │ │ └── api-client.ts
│ │ │ ├── tasks
│ │ │ │ ├── entities
│ │ │ │ │ └── task.entity.ts
│ │ │ │ ├── parser
│ │ │ │ │ └── index.ts
│ │ │ │ ├── repositories
│ │ │ │ │ ├── supabase
│ │ │ │ │ │ ├── dependency-fetcher.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── supabase-repository.ts
│ │ │ │ │ └── task-repository.interface.ts
│ │ │ │ ├── services
│ │ │ │ │ ├── preflight-checker.service.ts
│ │ │ │ │ ├── tag.service.ts
│ │ │ │ │ ├── task-execution-service.ts
│ │ │ │ │ ├── task-loader.service.ts
│ │ │ │ │ └── task-service.ts
│ │ │ │ └── tasks-domain.ts
│ │ │ ├── ui
│ │ │ │ └── index.ts
│ │ │ └── workflow
│ │ │ ├── managers
│ │ │ │ ├── workflow-state-manager.spec.ts
│ │ │ │ └── workflow-state-manager.ts
│ │ │ ├── orchestrators
│ │ │ │ ├── workflow-orchestrator.test.ts
│ │ │ │ └── workflow-orchestrator.ts
│ │ │ ├── services
│ │ │ │ ├── test-result-validator.test.ts
│ │ │ │ ├── test-result-validator.ts
│ │ │ │ ├── test-result-validator.types.ts
│ │ │ │ ├── workflow-activity-logger.ts
│ │ │ │ └── workflow.service.ts
│ │ │ ├── types.ts
│ │ │ └── workflow-domain.ts
│ │ ├── subpath-exports.test.ts
│ │ ├── tm-core.ts
│ │ └── utils
│ │ └── time.utils.ts
│ ├── tests
│ │ ├── auth
│ │ │ └── auth-refresh.test.ts
│ │ ├── integration
│ │ │ ├── auth-token-refresh.test.ts
│ │ │ ├── list-tasks.test.ts
│ │ │ └── storage
│ │ │ └── activity-logger.test.ts
│ │ ├── mocks
│ │ │ └── mock-provider.ts
│ │ ├── setup.ts
│ │ └── unit
│ │ ├── base-provider.test.ts
│ │ ├── executor.test.ts
│ │ └── smoke.test.ts
│ ├── tsconfig.json
│ └── vitest.config.ts
├── README-task-master.md
├── README.md
├── scripts
│ ├── create-worktree.sh
│ ├── dev.js
│ ├── init.js
│ ├── list-worktrees.sh
│ ├── modules
│ │ ├── ai-services-unified.js
│ │ ├── bridge-utils.js
│ │ ├── commands.js
│ │ ├── config-manager.js
│ │ ├── dependency-manager.js
│ │ ├── index.js
│ │ ├── prompt-manager.js
│ │ ├── supported-models.json
│ │ ├── sync-readme.js
│ │ ├── task-manager
│ │ │ ├── add-subtask.js
│ │ │ ├── add-task.js
│ │ │ ├── analyze-task-complexity.js
│ │ │ ├── clear-subtasks.js
│ │ │ ├── expand-all-tasks.js
│ │ │ ├── expand-task.js
│ │ │ ├── find-next-task.js
│ │ │ ├── generate-task-files.js
│ │ │ ├── is-task-dependent.js
│ │ │ ├── list-tasks.js
│ │ │ ├── migrate.js
│ │ │ ├── models.js
│ │ │ ├── move-task.js
│ │ │ ├── parse-prd
│ │ │ │ ├── index.js
│ │ │ │ ├── parse-prd-config.js
│ │ │ │ ├── parse-prd-helpers.js
│ │ │ │ ├── parse-prd-non-streaming.js
│ │ │ │ ├── parse-prd-streaming.js
│ │ │ │ └── parse-prd.js
│ │ │ ├── remove-subtask.js
│ │ │ ├── remove-task.js
│ │ │ ├── research.js
│ │ │ ├── response-language.js
│ │ │ ├── scope-adjustment.js
│ │ │ ├── set-task-status.js
│ │ │ ├── tag-management.js
│ │ │ ├── task-exists.js
│ │ │ ├── update-single-task-status.js
│ │ │ ├── update-subtask-by-id.js
│ │ │ ├── update-task-by-id.js
│ │ │ └── update-tasks.js
│ │ ├── task-manager.js
│ │ ├── ui.js
│ │ ├── update-config-tokens.js
│ │ ├── utils
│ │ │ ├── contextGatherer.js
│ │ │ ├── fuzzyTaskSearch.js
│ │ │ └── git-utils.js
│ │ └── utils.js
│ ├── task-complexity-report.json
│ ├── test-claude-errors.js
│ └── test-claude.js
├── sonar-project.properties
├── src
│ ├── ai-providers
│ │ ├── anthropic.js
│ │ ├── azure.js
│ │ ├── base-provider.js
│ │ ├── bedrock.js
│ │ ├── claude-code.js
│ │ ├── codex-cli.js
│ │ ├── gemini-cli.js
│ │ ├── google-vertex.js
│ │ ├── google.js
│ │ ├── grok-cli.js
│ │ ├── groq.js
│ │ ├── index.js
│ │ ├── lmstudio.js
│ │ ├── ollama.js
│ │ ├── openai-compatible.js
│ │ ├── openai.js
│ │ ├── openrouter.js
│ │ ├── perplexity.js
│ │ ├── xai.js
│ │ ├── zai-coding.js
│ │ └── zai.js
│ ├── constants
│ │ ├── commands.js
│ │ ├── paths.js
│ │ ├── profiles.js
│ │ ├── rules-actions.js
│ │ ├── task-priority.js
│ │ └── task-status.js
│ ├── profiles
│ │ ├── amp.js
│ │ ├── base-profile.js
│ │ ├── claude.js
│ │ ├── cline.js
│ │ ├── codex.js
│ │ ├── cursor.js
│ │ ├── gemini.js
│ │ ├── index.js
│ │ ├── kilo.js
│ │ ├── kiro.js
│ │ ├── opencode.js
│ │ ├── roo.js
│ │ ├── trae.js
│ │ ├── vscode.js
│ │ ├── windsurf.js
│ │ └── zed.js
│ ├── progress
│ │ ├── base-progress-tracker.js
│ │ ├── cli-progress-factory.js
│ │ ├── parse-prd-tracker.js
│ │ ├── progress-tracker-builder.js
│ │ └── tracker-ui.js
│ ├── prompts
│ │ ├── add-task.json
│ │ ├── analyze-complexity.json
│ │ ├── expand-task.json
│ │ ├── parse-prd.json
│ │ ├── README.md
│ │ ├── research.json
│ │ ├── schemas
│ │ │ ├── parameter.schema.json
│ │ │ ├── prompt-template.schema.json
│ │ │ ├── README.md
│ │ │ └── variant.schema.json
│ │ ├── update-subtask.json
│ │ ├── update-task.json
│ │ └── update-tasks.json
│ ├── provider-registry
│ │ └── index.js
│ ├── schemas
│ │ ├── add-task.js
│ │ ├── analyze-complexity.js
│ │ ├── base-schemas.js
│ │ ├── expand-task.js
│ │ ├── parse-prd.js
│ │ ├── registry.js
│ │ ├── update-subtask.js
│ │ ├── update-task.js
│ │ └── update-tasks.js
│ ├── task-master.js
│ ├── ui
│ │ ├── confirm.js
│ │ ├── indicators.js
│ │ └── parse-prd.js
│ └── utils
│ ├── asset-resolver.js
│ ├── create-mcp-config.js
│ ├── format.js
│ ├── getVersion.js
│ ├── logger-utils.js
│ ├── manage-gitignore.js
│ ├── path-utils.js
│ ├── profiles.js
│ ├── rule-transformer.js
│ ├── stream-parser.js
│ └── timeout-manager.js
├── test-clean-tags.js
├── test-config-manager.js
├── test-prd.txt
├── test-tag-functions.js
├── test-version-check-full.js
├── test-version-check.js
├── tests
│ ├── e2e
│ │ ├── e2e_helpers.sh
│ │ ├── parse_llm_output.cjs
│ │ ├── run_e2e.sh
│ │ ├── run_fallback_verification.sh
│ │ └── test_llm_analysis.sh
│ ├── fixtures
│ │ ├── .taskmasterconfig
│ │ ├── sample-claude-response.js
│ │ ├── sample-prd.txt
│ │ └── sample-tasks.js
│ ├── helpers
│ │ └── tool-counts.js
│ ├── integration
│ │ ├── claude-code-error-handling.test.js
│ │ ├── claude-code-optional.test.js
│ │ ├── cli
│ │ │ ├── commands.test.js
│ │ │ ├── complex-cross-tag-scenarios.test.js
│ │ │ └── move-cross-tag.test.js
│ │ ├── manage-gitignore.test.js
│ │ ├── mcp-server
│ │ │ └── direct-functions.test.js
│ │ ├── move-task-cross-tag.integration.test.js
│ │ ├── move-task-simple.integration.test.js
│ │ ├── profiles
│ │ │ ├── amp-init-functionality.test.js
│ │ │ ├── claude-init-functionality.test.js
│ │ │ ├── cline-init-functionality.test.js
│ │ │ ├── codex-init-functionality.test.js
│ │ │ ├── cursor-init-functionality.test.js
│ │ │ ├── gemini-init-functionality.test.js
│ │ │ ├── opencode-init-functionality.test.js
│ │ │ ├── roo-files-inclusion.test.js
│ │ │ ├── roo-init-functionality.test.js
│ │ │ ├── rules-files-inclusion.test.js
│ │ │ ├── trae-init-functionality.test.js
│ │ │ ├── vscode-init-functionality.test.js
│ │ │ └── windsurf-init-functionality.test.js
│ │ └── providers
│ │ └── temperature-support.test.js
│ ├── manual
│ │ ├── progress
│ │ │ ├── parse-prd-analysis.js
│ │ │ ├── test-parse-prd.js
│ │ │ └── TESTING_GUIDE.md
│ │ └── prompts
│ │ ├── prompt-test.js
│ │ └── README.md
│ ├── README.md
│ ├── setup.js
│ └── unit
│ ├── ai-providers
│ │ ├── base-provider.test.js
│ │ ├── claude-code.test.js
│ │ ├── codex-cli.test.js
│ │ ├── gemini-cli.test.js
│ │ ├── lmstudio.test.js
│ │ ├── mcp-components.test.js
│ │ ├── openai-compatible.test.js
│ │ ├── openai.test.js
│ │ ├── provider-registry.test.js
│ │ ├── zai-coding.test.js
│ │ ├── zai-provider.test.js
│ │ ├── zai-schema-introspection.test.js
│ │ └── zai.test.js
│ ├── ai-services-unified.test.js
│ ├── commands.test.js
│ ├── config-manager.test.js
│ ├── config-manager.test.mjs
│ ├── dependency-manager.test.js
│ ├── init.test.js
│ ├── initialize-project.test.js
│ ├── kebab-case-validation.test.js
│ ├── manage-gitignore.test.js
│ ├── mcp
│ │ └── tools
│ │ ├── __mocks__
│ │ │ └── move-task.js
│ │ ├── add-task.test.js
│ │ ├── analyze-complexity.test.js
│ │ ├── expand-all.test.js
│ │ ├── get-tasks.test.js
│ │ ├── initialize-project.test.js
│ │ ├── move-task-cross-tag-options.test.js
│ │ ├── move-task-cross-tag.test.js
│ │ ├── remove-task.test.js
│ │ └── tool-registration.test.js
│ ├── mcp-providers
│ │ ├── mcp-components.test.js
│ │ └── mcp-provider.test.js
│ ├── parse-prd.test.js
│ ├── profiles
│ │ ├── amp-integration.test.js
│ │ ├── claude-integration.test.js
│ │ ├── cline-integration.test.js
│ │ ├── codex-integration.test.js
│ │ ├── cursor-integration.test.js
│ │ ├── gemini-integration.test.js
│ │ ├── kilo-integration.test.js
│ │ ├── kiro-integration.test.js
│ │ ├── mcp-config-validation.test.js
│ │ ├── opencode-integration.test.js
│ │ ├── profile-safety-check.test.js
│ │ ├── roo-integration.test.js
│ │ ├── rule-transformer-cline.test.js
│ │ ├── rule-transformer-cursor.test.js
│ │ ├── rule-transformer-gemini.test.js
│ │ ├── rule-transformer-kilo.test.js
│ │ ├── rule-transformer-kiro.test.js
│ │ ├── rule-transformer-opencode.test.js
│ │ ├── rule-transformer-roo.test.js
│ │ ├── rule-transformer-trae.test.js
│ │ ├── rule-transformer-vscode.test.js
│ │ ├── rule-transformer-windsurf.test.js
│ │ ├── rule-transformer-zed.test.js
│ │ ├── rule-transformer.test.js
│ │ ├── selective-profile-removal.test.js
│ │ ├── subdirectory-support.test.js
│ │ ├── trae-integration.test.js
│ │ ├── vscode-integration.test.js
│ │ ├── windsurf-integration.test.js
│ │ └── zed-integration.test.js
│ ├── progress
│ │ └── base-progress-tracker.test.js
│ ├── prompt-manager.test.js
│ ├── prompts
│ │ ├── expand-task-prompt.test.js
│ │ └── prompt-migration.test.js
│ ├── scripts
│ │ └── modules
│ │ ├── commands
│ │ │ ├── move-cross-tag.test.js
│ │ │ └── README.md
│ │ ├── dependency-manager
│ │ │ ├── circular-dependencies.test.js
│ │ │ ├── cross-tag-dependencies.test.js
│ │ │ └── fix-dependencies-command.test.js
│ │ ├── task-manager
│ │ │ ├── add-subtask.test.js
│ │ │ ├── add-task.test.js
│ │ │ ├── analyze-task-complexity.test.js
│ │ │ ├── clear-subtasks.test.js
│ │ │ ├── complexity-report-tag-isolation.test.js
│ │ │ ├── expand-all-tasks.test.js
│ │ │ ├── expand-task.test.js
│ │ │ ├── find-next-task.test.js
│ │ │ ├── generate-task-files.test.js
│ │ │ ├── list-tasks.test.js
│ │ │ ├── models-baseurl.test.js
│ │ │ ├── move-task-cross-tag.test.js
│ │ │ ├── move-task.test.js
│ │ │ ├── parse-prd-schema.test.js
│ │ │ ├── parse-prd.test.js
│ │ │ ├── remove-subtask.test.js
│ │ │ ├── remove-task.test.js
│ │ │ ├── research.test.js
│ │ │ ├── scope-adjustment.test.js
│ │ │ ├── set-task-status.test.js
│ │ │ ├── setup.js
│ │ │ ├── update-single-task-status.test.js
│ │ │ ├── update-subtask-by-id.test.js
│ │ │ ├── update-task-by-id.test.js
│ │ │ └── update-tasks.test.js
│ │ ├── ui
│ │ │ └── cross-tag-error-display.test.js
│ │ └── utils-tag-aware-paths.test.js
│ ├── task-finder.test.js
│ ├── task-manager
│ │ ├── clear-subtasks.test.js
│ │ ├── move-task.test.js
│ │ ├── tag-boundary.test.js
│ │ └── tag-management.test.js
│ ├── task-master.test.js
│ ├── ui
│ │ └── indicators.test.js
│ ├── ui.test.js
│ ├── utils-strip-ansi.test.js
│ └── utils.test.js
├── tsconfig.json
├── tsdown.config.ts
├── turbo.json
└── update-task-migration-plan.md
```
# Files
--------------------------------------------------------------------------------
/src/ai-providers/openai.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * openai.js
3 | * AI provider implementation for OpenAI models using Vercel AI SDK.
4 | */
5 |
6 | import { createOpenAI } from '@ai-sdk/openai';
7 | import { BaseAIProvider } from './base-provider.js';
8 |
9 | export class OpenAIProvider extends BaseAIProvider {
10 | constructor() {
11 | super();
12 | this.name = 'OpenAI';
13 | }
14 |
15 | /**
16 | * Returns the environment variable name required for this provider's API key.
17 | * @returns {string} The environment variable name for the OpenAI API key
18 | */
19 | getRequiredApiKeyName() {
20 | return 'OPENAI_API_KEY';
21 | }
22 |
23 | /**
24 | * Creates and returns an OpenAI client instance.
25 | * @param {object} params - Parameters for client initialization
26 | * @param {string} params.apiKey - OpenAI API key
27 | * @param {string} [params.baseURL] - Optional custom API endpoint
28 | * @returns {Function} OpenAI client function
29 | * @throws {Error} If initialization fails
30 | */
31 | getClient(params) {
32 | try {
33 | const { apiKey, baseURL } = params;
34 | const fetchImpl = this.createProxyFetch();
35 |
36 | return createOpenAI({
37 | apiKey,
38 | ...(baseURL && { baseURL }),
39 | ...(fetchImpl && { fetch: fetchImpl })
40 | });
41 | } catch (error) {
42 | this.handleError('client initialization', error);
43 | }
44 | }
45 | }
46 |
```
--------------------------------------------------------------------------------
/scripts/modules/task-manager/is-task-dependent.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Check if a task is dependent on another task (directly or indirectly)
3 | * Used to prevent circular dependencies
4 | * @param {Array} allTasks - Array of all tasks
5 | * @param {Object} task - The task to check
6 | * @param {number} targetTaskId - The task ID to check dependency against
7 | * @returns {boolean} Whether the task depends on the target task
8 | */
9 | function isTaskDependentOn(allTasks, task, targetTaskId) {
10 | // If the task is a subtask, check if its parent is the target
11 | if (task.parentTaskId === targetTaskId) {
12 | return true;
13 | }
14 |
15 | // Check direct dependencies
16 | if (task.dependencies && task.dependencies.includes(targetTaskId)) {
17 | return true;
18 | }
19 |
20 | // Check dependencies of dependencies (recursive)
21 | if (task.dependencies) {
22 | for (const depId of task.dependencies) {
23 | const depTask = allTasks.find((t) => t.id === depId);
24 | if (depTask && isTaskDependentOn(allTasks, depTask, targetTaskId)) {
25 | return true;
26 | }
27 | }
28 | }
29 |
30 | // Check subtasks for dependencies
31 | if (task.subtasks) {
32 | for (const subtask of task.subtasks) {
33 | if (isTaskDependentOn(allTasks, subtask, targetTaskId)) {
34 | return true;
35 | }
36 | }
37 | }
38 |
39 | return false;
40 | }
41 |
42 | export default isTaskDependentOn;
43 |
```
--------------------------------------------------------------------------------
/apps/cli/src/utils/display-helpers.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Display helper utilities for commands
3 | * Provides DRY utilities for displaying headers and other command output
4 | */
5 |
6 | import type { TmCore } from '@tm/core';
7 | import type { StorageType } from '@tm/core';
8 | import { displayHeader } from '../ui/index.js';
9 |
10 | /**
11 | * Display the command header with appropriate storage information
12 | * Handles both API and file storage displays
13 | */
14 | export function displayCommandHeader(
15 | tmCore: TmCore | undefined,
16 | options: {
17 | tag?: string;
18 | storageType: Exclude<StorageType, 'auto'>;
19 | }
20 | ): void {
21 | if (!tmCore) {
22 | // Fallback display if tmCore is not available
23 | displayHeader({
24 | tag: options.tag || 'master',
25 | storageType: options.storageType
26 | });
27 | return;
28 | }
29 |
30 | // Get the resolved storage type from tasks domain
31 | const resolvedStorageType = tmCore.tasks.getStorageType();
32 |
33 | // Get storage display info from tm-core (single source of truth)
34 | const displayInfo = tmCore.auth.getStorageDisplayInfo(resolvedStorageType);
35 |
36 | // Display header with computed display info
37 | displayHeader({
38 | tag: options.tag || 'master',
39 | filePath: displayInfo.filePath,
40 | storageType: displayInfo.storageType,
41 | briefInfo: displayInfo.briefInfo
42 | });
43 | }
44 |
```
--------------------------------------------------------------------------------
/test-version-check.js:
--------------------------------------------------------------------------------
```javascript
1 | import {
2 | displayUpgradeNotification,
3 | compareVersions
4 | } from './scripts/modules/commands.js';
5 |
6 | // Simulate different version scenarios
7 | console.log('=== Simulating version check ===\n');
8 |
9 | // 1. Current version is older than latest (should show update notice)
10 | console.log('Scenario 1: Current version older than latest');
11 | displayUpgradeNotification('0.9.30', '1.0.0');
12 |
13 | // 2. Current version same as latest (no update needed)
14 | console.log(
15 | '\nScenario 2: Current version same as latest (this would not normally show a notice)'
16 | );
17 | console.log('Current: 1.0.0, Latest: 1.0.0');
18 | console.log('compareVersions result:', compareVersions('1.0.0', '1.0.0'));
19 | console.log(
20 | 'Update needed:',
21 | compareVersions('1.0.0', '1.0.0') < 0 ? 'Yes' : 'No'
22 | );
23 |
24 | // 3. Current version newer than latest (e.g., development version, would not show notice)
25 | console.log(
26 | '\nScenario 3: Current version newer than latest (this would not normally show a notice)'
27 | );
28 | console.log('Current: 1.1.0, Latest: 1.0.0');
29 | console.log('compareVersions result:', compareVersions('1.1.0', '1.0.0'));
30 | console.log(
31 | 'Update needed:',
32 | compareVersions('1.1.0', '1.0.0') < 0 ? 'Yes' : 'No'
33 | );
34 |
35 | console.log('\n=== Test complete ===');
36 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/tasks/parser/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Task parsing functionality for the tm-core package
3 | * This file exports all parsing-related classes and functions
4 | */
5 |
6 | import type { PlaceholderTask } from '../../../common/types/index.js';
7 |
8 | // Parser implementations will be defined here
9 | // export * from './prd-parser.js';
10 | // export * from './task-parser.js';
11 | // export * from './markdown-parser.js';
12 |
13 | // Placeholder exports - these will be implemented in later tasks
14 | export interface TaskParser {
15 | parse(content: string): Promise<PlaceholderTask[]>;
16 | validate(content: string): Promise<boolean>;
17 | }
18 |
19 | /**
20 | * @deprecated This is a placeholder class that will be properly implemented in later tasks
21 | */
22 | export class PlaceholderParser implements TaskParser {
23 | async parse(content: string): Promise<PlaceholderTask[]> {
24 | // Simple placeholder parsing logic
25 | const lines = content
26 | .split('\n')
27 | .filter((line) => line.trim().startsWith('-'));
28 | return lines.map((line, index) => ({
29 | id: `task-${index + 1}`,
30 | title: line.trim().replace(/^-\s*/, ''),
31 | status: 'pending' as const,
32 | priority: 'medium' as const
33 | }));
34 | }
35 |
36 | async validate(content: string): Promise<boolean> {
37 | return content.trim().length > 0;
38 | }
39 | }
40 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/common/utils/path-helpers.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Path construction utilities for Task Master
3 | * Provides standardized paths for Task Master project structure
4 | */
5 |
6 | import { join, resolve } from 'node:path';
7 | import { TASKMASTER_TASKS_FILE } from '../constants/paths.js';
8 | import { findProjectRoot } from './project-root-finder.js';
9 |
10 | /**
11 | * Get standard Task Master project paths
12 | * Automatically detects project root using smart detection
13 | *
14 | * @param projectPath - Optional explicit project path (if not provided, auto-detects)
15 | * @returns Object with projectRoot and tasksPath
16 | *
17 | * @example
18 | * ```typescript
19 | * // Auto-detect project root
20 | * const { projectRoot, tasksPath } = getProjectPaths();
21 | *
22 | * // Or specify explicit path
23 | * const { projectRoot, tasksPath } = getProjectPaths('./my-project');
24 | * // projectRoot: '/absolute/path/to/my-project'
25 | * // tasksPath: '/absolute/path/to/my-project/.taskmaster/tasks/tasks.json'
26 | * ```
27 | */
28 | export function getProjectPaths(projectPath?: string): {
29 | projectRoot: string;
30 | tasksPath: string;
31 | } {
32 | const projectRoot = projectPath
33 | ? resolve(process.cwd(), projectPath)
34 | : findProjectRoot();
35 |
36 | return {
37 | projectRoot,
38 | tasksPath: join(projectRoot, TASKMASTER_TASKS_FILE)
39 | };
40 | }
41 |
```
--------------------------------------------------------------------------------
/scripts/modules/bridge-utils.js:
--------------------------------------------------------------------------------
```javascript
1 | import { isSilentMode, log as consoleLog } from './utils.js';
2 | import { getDebugFlag } from './config-manager.js';
3 |
4 | /**
5 | * Create a unified logger and report function for bridge operations
6 | * Handles both MCP and CLI contexts consistently
7 | *
8 | * @param {Object} mcpLog - Optional MCP logger object
9 | * @param {Object} [session] - Optional session object for debug flag checking
10 | * @returns {Object} Object containing logger, report function, and isMCP flag
11 | */
12 | export function createBridgeLogger(mcpLog, session) {
13 | const isMCP = !!mcpLog;
14 |
15 | // Create logger that works in both contexts
16 | const logger = mcpLog || {
17 | info: (msg) => !isSilentMode() && consoleLog('info', msg),
18 | warn: (msg) => !isSilentMode() && consoleLog('warn', msg),
19 | error: (msg) => !isSilentMode() && consoleLog('error', msg),
20 | debug: (msg) =>
21 | !isSilentMode() && getDebugFlag(session) && consoleLog('debug', msg)
22 | };
23 |
24 | // Create report function compatible with bridge
25 | const report = (level, ...args) => {
26 | if (isMCP) {
27 | if (typeof logger[level] === 'function') logger[level](...args);
28 | else logger.info(...args);
29 | } else if (!isSilentMode()) {
30 | consoleLog(level, ...args);
31 | }
32 | };
33 |
34 | return { logger, report, isMCP };
35 | }
36 |
```
--------------------------------------------------------------------------------
/src/ai-providers/google.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * google.js
3 | * AI provider implementation for Google AI models using Vercel AI SDK.
4 | */
5 |
6 | import { createGoogleGenerativeAI } from '@ai-sdk/google';
7 | import { BaseAIProvider } from './base-provider.js';
8 |
9 | export class GoogleAIProvider extends BaseAIProvider {
10 | constructor() {
11 | super();
12 | this.name = 'Google';
13 | }
14 |
15 | /**
16 | * Returns the environment variable name required for this provider's API key.
17 | * @returns {string} The environment variable name for the Google API key
18 | */
19 | getRequiredApiKeyName() {
20 | return 'GOOGLE_API_KEY';
21 | }
22 |
23 | /**
24 | * Creates and returns a Google AI client instance.
25 | * @param {object} params - Parameters for client initialization
26 | * @param {string} params.apiKey - Google API key
27 | * @param {string} [params.baseURL] - Optional custom API endpoint
28 | * @returns {Function} Google AI client function
29 | * @throws {Error} If initialization fails
30 | */
31 | getClient(params) {
32 | try {
33 | const { apiKey, baseURL } = params;
34 | const fetchImpl = this.createProxyFetch();
35 |
36 | return createGoogleGenerativeAI({
37 | apiKey,
38 | ...(baseURL && { baseURL }),
39 | ...(fetchImpl && { fetch: fetchImpl })
40 | });
41 | } catch (error) {
42 | this.handleError('client initialization', error);
43 | }
44 | }
45 | }
46 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/add-dependency.md:
--------------------------------------------------------------------------------
```markdown
1 | Add a dependency between tasks.
2 |
3 | Arguments: $ARGUMENTS
4 |
5 | Parse the task IDs to establish dependency relationship.
6 |
7 | ## Adding Dependencies
8 |
9 | Creates a dependency where one task must be completed before another can start.
10 |
11 | ## Argument Parsing
12 |
13 | Parse natural language or IDs:
14 | - "make 5 depend on 3" → task 5 depends on task 3
15 | - "5 needs 3" → task 5 depends on task 3
16 | - "5 3" → task 5 depends on task 3
17 | - "5 after 3" → task 5 depends on task 3
18 |
19 | ## Execution
20 |
21 | ```bash
22 | task-master add-dependency --id=<task-id> --depends-on=<dependency-id>
23 | ```
24 |
25 | ## Validation
26 |
27 | Before adding:
28 | 1. **Verify both tasks exist**
29 | 2. **Check for circular dependencies**
30 | 3. **Ensure dependency makes logical sense**
31 | 4. **Warn if creating complex chains**
32 |
33 | ## Smart Features
34 |
35 | - Detect if dependency already exists
36 | - Suggest related dependencies
37 | - Show impact on task flow
38 | - Update task priorities if needed
39 |
40 | ## Post-Addition
41 |
42 | After adding dependency:
43 | 1. Show updated dependency graph
44 | 2. Identify any newly blocked tasks
45 | 3. Suggest task order changes
46 | 4. Update project timeline
47 |
48 | ## Example Flows
49 |
50 | ```
51 | /taskmaster:add-dependency 5 needs 3
52 | → Task #5 now depends on Task #3
53 | → Task #5 is now blocked until #3 completes
54 | → Suggested: Also consider if #5 needs #4
55 | ```
```
--------------------------------------------------------------------------------
/packages/tm-core/src/common/constants/providers.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Provider validation constants
3 | * Defines which providers should be validated against the supported-models.json file
4 | */
5 |
6 | // Providers that have predefined model lists and should be validated
7 | export const VALIDATED_PROVIDERS = [
8 | 'anthropic',
9 | 'openai',
10 | 'google',
11 | 'zai',
12 | 'zai-coding',
13 | 'perplexity',
14 | 'xai',
15 | 'groq',
16 | 'mistral'
17 | ] as const;
18 |
19 | export type ValidatedProvider = (typeof VALIDATED_PROVIDERS)[number];
20 |
21 | // Custom providers object for easy named access
22 | export const CUSTOM_PROVIDERS = {
23 | AZURE: 'azure',
24 | VERTEX: 'vertex',
25 | BEDROCK: 'bedrock',
26 | OPENROUTER: 'openrouter',
27 | OLLAMA: 'ollama',
28 | LMSTUDIO: 'lmstudio',
29 | OPENAI_COMPATIBLE: 'openai-compatible',
30 | CLAUDE_CODE: 'claude-code',
31 | MCP: 'mcp',
32 | GEMINI_CLI: 'gemini-cli',
33 | GROK_CLI: 'grok-cli',
34 | CODEX_CLI: 'codex-cli'
35 | } as const;
36 |
37 | export type CustomProvider =
38 | (typeof CUSTOM_PROVIDERS)[keyof typeof CUSTOM_PROVIDERS];
39 |
40 | // Custom providers array (for backward compatibility and iteration)
41 | export const CUSTOM_PROVIDERS_ARRAY = Object.values(CUSTOM_PROVIDERS);
42 |
43 | // All known providers (for reference)
44 | export const ALL_PROVIDERS = [
45 | ...VALIDATED_PROVIDERS,
46 | ...CUSTOM_PROVIDERS_ARRAY
47 | ] as const;
48 |
49 | export type Provider = ValidatedProvider | CustomProvider;
50 |
```
--------------------------------------------------------------------------------
/scripts/dev.js:
--------------------------------------------------------------------------------
```javascript
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * dev.js
5 | * Task Master CLI - AI-driven development task management
6 | *
7 | * This is the refactored entry point that uses the modular architecture.
8 | * It imports functionality from the modules directory and provides a CLI.
9 | */
10 |
11 | import { join } from 'node:path';
12 | import { findProjectRoot } from '@tm/core';
13 | import dotenv from 'dotenv';
14 |
15 | // Store the original working directory
16 | // This is needed for commands that take relative paths as arguments
17 | const originalCwd = process.cwd();
18 |
19 | // Find project root for .env loading
20 | // We don't change the working directory to avoid breaking relative path logic
21 | const projectRoot = findProjectRoot();
22 |
23 | // Load .env from project root without changing cwd
24 | dotenv.config({ path: join(projectRoot, '.env') });
25 |
26 | // Make original cwd available to commands that need it
27 | process.env.TASKMASTER_ORIGINAL_CWD = originalCwd;
28 |
29 | // Add at the very beginning of the file
30 | if (process.env.DEBUG === '1') {
31 | console.error('DEBUG - dev.js received args:', process.argv.slice(2));
32 | }
33 |
34 | // Use dynamic import to ensure dotenv.config() runs before module-level code executes
35 | const { runCLI } = await import('./modules/commands.js');
36 |
37 | // Run the CLI with the process arguments
38 | runCLI(process.argv);
39 |
```
--------------------------------------------------------------------------------
/packages/build-config/src/tsdown.base.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Base tsdown configuration for Task Master monorepo
3 | * Provides shared configuration that can be extended by individual packages
4 | */
5 | import type { UserConfig } from 'tsdown';
6 |
7 | const isProduction = process.env.NODE_ENV === 'production';
8 | const isDevelopment = !isProduction;
9 |
10 | /**
11 | * Environment helpers
12 | */
13 | export const env = {
14 | isProduction,
15 | isDevelopment,
16 | NODE_ENV: process.env.NODE_ENV || 'development'
17 | };
18 |
19 | /**
20 | * Base tsdown configuration for all packages
21 | * Since everything gets bundled into root dist/ anyway, use consistent settings
22 | */
23 | export const baseConfig: Partial<UserConfig> = {
24 | sourcemap: isDevelopment,
25 | format: 'esm',
26 | platform: 'node',
27 | dts: isDevelopment,
28 | minify: isProduction,
29 | treeshake: isProduction,
30 | // Better debugging in development
31 | ...(isDevelopment && {
32 | keepNames: true,
33 | splitting: false // Disable code splitting for better stack traces
34 | }),
35 | // Keep all npm dependencies external (available via node_modules)
36 | external: [/^[^@./]/, /^@(?!tm\/)/]
37 | };
38 |
39 | /**
40 | * Utility function to merge configurations
41 | * Simplified for tsdown usage
42 | */
43 | export function mergeConfig(
44 | base: Partial<UserConfig>,
45 | overrides: Partial<UserConfig>
46 | ): UserConfig {
47 | return {
48 | ...base,
49 | ...overrides
50 | } as UserConfig;
51 | }
52 |
```
--------------------------------------------------------------------------------
/apps/cli/src/ui/formatters/complexity-formatters.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Complexity formatting utilities
3 | * Provides colored complexity displays with labels and scores
4 | */
5 |
6 | import chalk from 'chalk';
7 |
8 | /**
9 | * Get complexity color and label based on score thresholds
10 | */
11 | function getComplexityLevel(score: number): {
12 | color: (text: string) => string;
13 | label: string;
14 | } {
15 | if (score >= 7) {
16 | return { color: chalk.hex('#CC0000'), label: 'High' };
17 | } else if (score >= 4) {
18 | return { color: chalk.hex('#FF8800'), label: 'Medium' };
19 | } else {
20 | return { color: chalk.green, label: 'Low' };
21 | }
22 | }
23 |
24 | /**
25 | * Get colored complexity display with dot indicator (simple format)
26 | */
27 | export function getComplexityWithColor(complexity: number | string): string {
28 | const score =
29 | typeof complexity === 'string' ? Number(complexity.trim()) : complexity;
30 |
31 | if (isNaN(score)) {
32 | return chalk.gray('N/A');
33 | }
34 |
35 | const { color } = getComplexityLevel(score);
36 | return color(`● ${score}`);
37 | }
38 |
39 | /**
40 | * Get colored complexity display with /10 format (for dashboards)
41 | */
42 | export function getComplexityWithScore(complexity: number | undefined): string {
43 | if (typeof complexity !== 'number') {
44 | return chalk.gray('N/A');
45 | }
46 |
47 | const { color, label } = getComplexityLevel(complexity);
48 | return color(`${complexity}/10 (${label})`);
49 | }
50 |
```
--------------------------------------------------------------------------------
/src/utils/logger-utils.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Logger utility functions for Task Master
3 | * Provides standardized logging patterns for both CLI and utility contexts
4 | */
5 |
6 | import { log as utilLog } from '../../scripts/modules/utils.js';
7 |
8 | /**
9 | * Creates a standard logger object that wraps the utility log function
10 | * This provides a consistent logger interface across different parts of the application
11 | * @returns {Object} A logger object with standard logging methods (info, warn, error, debug, success)
12 | */
13 | export function createStandardLogger() {
14 | return {
15 | info: (msg, ...args) => utilLog('info', msg, ...args),
16 | warn: (msg, ...args) => utilLog('warn', msg, ...args),
17 | error: (msg, ...args) => utilLog('error', msg, ...args),
18 | debug: (msg, ...args) => utilLog('debug', msg, ...args),
19 | success: (msg, ...args) => utilLog('success', msg, ...args)
20 | };
21 | }
22 |
23 | /**
24 | * Creates a logger using either the provided logger or a default standard logger
25 | * This is the recommended pattern for functions that accept an optional logger parameter
26 | * @param {Object|null} providedLogger - Optional logger object passed from caller
27 | * @returns {Object} A logger object with standard logging methods
28 | */
29 | export function getLoggerOrDefault(providedLogger = null) {
30 | return providedLogger || createStandardLogger();
31 | }
32 |
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "bundler",
6 | "lib": ["ES2022"],
7 | "types": ["node"],
8 | "allowJs": true,
9 | "resolveJsonModule": true,
10 | "esModuleInterop": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "strict": true,
13 | "skipLibCheck": true,
14 | "noEmit": true,
15 | "baseUrl": ".",
16 | "paths": {
17 | "@tm/core": ["./packages/tm-core/src/index.ts"],
18 | "@tm/core/*": ["./packages/tm-core/src/*"],
19 | "@tm/cli": ["./apps/cli/src/index.ts"],
20 | "@tm/cli/*": ["./apps/cli/src/*"],
21 | "@tm/mcp": ["./apps/mcp/src/index.ts"],
22 | "@tm/mcp/*": ["./apps/mcp/src/*"],
23 | "@tm/build-config": ["./packages/build-config/src/index.ts"],
24 | "@tm/build-config/*": ["./packages/build-config/src/*"],
25 | "@tm/ai-sdk-provider-grok-cli": [
26 | "./packages/ai-sdk-provider-grok-cli/src/index.ts"
27 | ],
28 | "@tm/ai-sdk-provider-grok-cli/*": [
29 | "./packages/ai-sdk-provider-grok-cli/src/*"
30 | ],
31 | "@tm/bridge": ["./packages/tm-bridge/src/index.ts"],
32 | "@tm/bridge/*": ["./packages/tm-bridge/src/*"]
33 | }
34 | },
35 | "tsx": {
36 | "tsconfig": {
37 | "allowImportingTsExtensions": false
38 | }
39 | },
40 | "include": [
41 | "bin/**/*",
42 | "scripts/**/*",
43 | "packages/*/src/**/*",
44 | "apps/*/src/**/*"
45 | ],
46 | "exclude": ["node_modules", "dist", "**/dist"]
47 | }
48 |
```
--------------------------------------------------------------------------------
/apps/cli/src/ui/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Main UI exports
3 | * Organized UI system with components, formatters, display primitives, and layout helpers
4 | */
5 |
6 | // High-level UI components
7 | export * from './components/index.js';
8 |
9 | // Status formatters
10 | export {
11 | getStatusWithColor,
12 | getBriefStatusWithColor,
13 | getBriefStatusIcon,
14 | getBriefStatusColor,
15 | capitalizeStatus
16 | } from './formatters/status-formatters.js';
17 |
18 | // Priority formatters
19 | export { getPriorityWithColor } from './formatters/priority-formatters.js';
20 |
21 | // Complexity formatters
22 | export {
23 | getComplexityWithColor,
24 | getComplexityWithScore
25 | } from './formatters/complexity-formatters.js';
26 |
27 | // Dependency formatters
28 | export { formatDependenciesWithStatus } from './formatters/dependency-formatters.js';
29 |
30 | // Layout helpers
31 | export {
32 | getBoxWidth,
33 | truncate,
34 | createProgressBar
35 | } from './layout/helpers.js';
36 |
37 | // Display messages
38 | // Note: displayError alias is available via namespace (ui.displayError) for backward compat
39 | // but not exported at package level to avoid conflicts with utils/error-handler.ts
40 | export {
41 | displayBanner,
42 | displayErrorBox,
43 | displayError, // Backward compatibility alias
44 | displaySuccess,
45 | displayWarning,
46 | displayInfo
47 | } from './display/messages.js';
48 |
49 | // Display tables
50 | export { createTaskTable } from './display/tables.js';
51 |
```
--------------------------------------------------------------------------------
/mcp-server/src/tools/response-language.js:
--------------------------------------------------------------------------------
```javascript
1 | import { z } from 'zod';
2 | import {
3 | createErrorResponse,
4 | handleApiResult,
5 | withNormalizedProjectRoot
6 | } from './utils.js';
7 | import { responseLanguageDirect } from '../core/direct-functions/response-language.js';
8 |
9 | export function registerResponseLanguageTool(server) {
10 | server.addTool({
11 | name: 'response-language',
12 | description: 'Get or set the response language for the project',
13 | parameters: z.object({
14 | projectRoot: z
15 | .string()
16 | .describe(
17 | 'The root directory for the project. ALWAYS SET THIS TO THE PROJECT ROOT DIRECTORY. IF NOT SET, THE TOOL WILL NOT WORK.'
18 | ),
19 | language: z
20 | .string()
21 | .describe(
22 | 'The new response language to set. like "中文" "English" or "español".'
23 | )
24 | }),
25 | execute: withNormalizedProjectRoot(async (args, { log, session }) => {
26 | try {
27 | log.info(
28 | `Executing response-language tool with args: ${JSON.stringify(args)}`
29 | );
30 |
31 | const result = await responseLanguageDirect(
32 | {
33 | ...args,
34 | projectRoot: args.projectRoot
35 | },
36 | log,
37 | { session }
38 | );
39 | return handleApiResult(result, log, 'Error setting response language');
40 | } catch (error) {
41 | log.error(`Error in response-language tool: ${error.message}`);
42 | return createErrorResponse(error.message);
43 | }
44 | })
45 | });
46 | }
47 |
```
--------------------------------------------------------------------------------
/apps/cli/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "@tm/cli",
3 | "description": "Task Master CLI - Command line interface for task management",
4 | "type": "module",
5 | "private": true,
6 | "main": "./dist/index.js",
7 | "types": "./src/index.ts",
8 | "exports": {
9 | ".": "./src/index.ts"
10 | },
11 | "files": ["dist", "README.md"],
12 | "scripts": {
13 | "typecheck": "tsc --noEmit",
14 | "lint": "biome check src",
15 | "format": "biome format --write src",
16 | "test": "vitest run",
17 | "test:watch": "vitest",
18 | "test:coverage": "vitest run --coverage",
19 | "test:unit": "vitest run -t unit",
20 | "test:integration": "vitest run -t integration",
21 | "test:e2e": "vitest run --dir tests/e2e",
22 | "test:ci": "vitest run --coverage --reporter=dot"
23 | },
24 | "dependencies": {
25 | "@inquirer/search": "^3.2.0",
26 | "@tm/core": "*",
27 | "boxen": "^8.0.1",
28 | "chalk": "5.6.2",
29 | "cli-table3": "^0.6.5",
30 | "commander": "^12.1.0",
31 | "inquirer": "^12.5.0",
32 | "ora": "^8.2.0"
33 | },
34 | "devDependencies": {
35 | "@biomejs/biome": "^1.9.4",
36 | "@types/inquirer": "^9.0.3",
37 | "@types/node": "^22.10.5",
38 | "tsx": "^4.20.4",
39 | "typescript": "^5.9.2",
40 | "vitest": "^2.1.8"
41 | },
42 | "engines": {
43 | "node": ">=18.0.0"
44 | },
45 | "keywords": ["task-master", "cli", "task-management", "productivity"],
46 | "author": "",
47 | "license": "MIT",
48 | "typesVersions": {
49 | "*": {
50 | "*": ["src/*"]
51 | }
52 | },
53 | "version": ""
54 | }
55 |
```
--------------------------------------------------------------------------------
/.github/workflows/backfill-duplicate-comments.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: Backfill Duplicate Comments
2 | # description: Triggers duplicate detection for old issues that don't have duplicate comments
3 |
4 | on:
5 | workflow_dispatch:
6 | inputs:
7 | days_back:
8 | description: "How many days back to look for old issues"
9 | required: false
10 | default: "90"
11 | type: string
12 | dry_run:
13 | description: "Dry run mode (true to only log what would be done)"
14 | required: false
15 | default: "true"
16 | type: choice
17 | options:
18 | - "true"
19 | - "false"
20 |
21 | jobs:
22 | backfill-duplicate-comments:
23 | runs-on: ubuntu-latest
24 | timeout-minutes: 30
25 | permissions:
26 | contents: read
27 | issues: read
28 | actions: write
29 |
30 | steps:
31 | - name: Checkout repository
32 | uses: actions/checkout@v4
33 |
34 | - name: Setup Node.js
35 | uses: actions/setup-node@v4
36 | with:
37 | node-version: 20
38 |
39 | - name: Backfill duplicate comments
40 | run: node .github/scripts/backfill-duplicate-comments.mjs
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
44 | GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
45 | DAYS_BACK: ${{ inputs.days_back }}
46 | DRY_RUN: ${{ inputs.dry_run }}
47 |
```
--------------------------------------------------------------------------------
/tsdown.config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { defineConfig } from 'tsdown';
2 | import { baseConfig, mergeConfig } from '@tm/build-config';
3 | import { config } from 'dotenv';
4 | import { resolve } from 'path';
5 |
6 | // Load .env file explicitly with absolute path
7 | config({ path: resolve(process.cwd(), '.env') });
8 |
9 | // Get all TM_PUBLIC_* env variables for build-time injection
10 | const getBuildTimeEnvs = () => {
11 | const envs: Record<string, string> = {};
12 |
13 | // Inject package.json version at build time
14 | try {
15 | const packageJson = JSON.parse(
16 | require('fs').readFileSync('package.json', 'utf8')
17 | );
18 | envs['TM_PUBLIC_VERSION'] = packageJson.version || 'unknown';
19 | } catch (error) {
20 | console.warn('Could not read package.json version during build:', error);
21 | envs['TM_PUBLIC_VERSION'] = 'unknown';
22 | }
23 |
24 | for (const [key, value] of Object.entries(process.env)) {
25 | if (key.startsWith('TM_PUBLIC_')) {
26 | envs[key] = value || '';
27 | }
28 | }
29 |
30 | return envs;
31 | };
32 |
33 | export default defineConfig(
34 | mergeConfig(baseConfig, {
35 | entry: {
36 | 'task-master': 'scripts/dev.js',
37 | 'mcp-server': 'mcp-server/server.js'
38 | },
39 | outDir: 'dist',
40 | copy: ['assets'],
41 | ignoreWatch: ['node_modules', 'dist', 'tests', 'apps/extension'],
42 | // Bundle only our workspace packages, keep npm dependencies external
43 | noExternal: [/^@tm\//],
44 | env: getBuildTimeEnvs()
45 | })
46 | );
47 |
```
--------------------------------------------------------------------------------
/apps/extension/src/webview/utils/toast.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Toast notification utilities
3 | */
4 |
5 | import type { ToastNotification, AppAction } from '../types';
6 |
7 | let toastIdCounter = 0;
8 |
9 | export const createToast = (
10 | type: ToastNotification['type'],
11 | title: string,
12 | message: string,
13 | duration?: number
14 | ): ToastNotification => ({
15 | id: `toast-${++toastIdCounter}`,
16 | type,
17 | title,
18 | message,
19 | duration
20 | });
21 |
22 | export const showSuccessToast =
23 | (dispatch: React.Dispatch<AppAction>) =>
24 | (title: string, message: string, duration?: number) => {
25 | dispatch({
26 | type: 'ADD_TOAST',
27 | payload: createToast('success', title, message, duration)
28 | });
29 | };
30 |
31 | export const showInfoToast =
32 | (dispatch: React.Dispatch<AppAction>) =>
33 | (title: string, message: string, duration?: number) => {
34 | dispatch({
35 | type: 'ADD_TOAST',
36 | payload: createToast('info', title, message, duration)
37 | });
38 | };
39 |
40 | export const showWarningToast =
41 | (dispatch: React.Dispatch<AppAction>) =>
42 | (title: string, message: string, duration?: number) => {
43 | dispatch({
44 | type: 'ADD_TOAST',
45 | payload: createToast('warning', title, message, duration)
46 | });
47 | };
48 |
49 | export const showErrorToast =
50 | (dispatch: React.Dispatch<AppAction>) =>
51 | (title: string, message: string, duration?: number) => {
52 | dispatch({
53 | type: 'ADD_TOAST',
54 | payload: createToast('error', title, message, duration)
55 | });
56 | };
57 |
```
--------------------------------------------------------------------------------
/src/prompts/schemas/parameter.schema.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "$id": "https://github.com/eyaltoledano/claude-task-master/blob/main/src/prompts/schemas/parameter.schema.json",
4 | "version": "1.0.0",
5 | "title": "Task Master Prompt Parameter",
6 | "description": "Schema for individual prompt template parameters",
7 | "type": "object",
8 | "required": ["type", "description"],
9 | "properties": {
10 | "type": {
11 | "type": "string",
12 | "enum": ["string", "number", "boolean", "array", "object"],
13 | "description": "The expected data type for this parameter"
14 | },
15 | "description": {
16 | "type": "string",
17 | "minLength": 1,
18 | "description": "Human-readable description of the parameter"
19 | },
20 | "required": {
21 | "type": "boolean",
22 | "default": false,
23 | "description": "Whether this parameter is required"
24 | },
25 | "default": {
26 | "description": "Default value for optional parameters"
27 | },
28 | "enum": {
29 | "type": "array",
30 | "description": "Valid values for string parameters",
31 | "items": {
32 | "type": "string"
33 | }
34 | },
35 | "pattern": {
36 | "type": "string",
37 | "description": "Regular expression pattern for string validation"
38 | },
39 | "minimum": {
40 | "type": "number",
41 | "description": "Minimum value for number parameters"
42 | },
43 | "maximum": {
44 | "type": "number",
45 | "description": "Maximum value for number parameters"
46 | }
47 | }
48 | }
49 |
```
--------------------------------------------------------------------------------
/src/ai-providers/bedrock.js:
--------------------------------------------------------------------------------
```javascript
1 | import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
2 | import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
3 | import { BaseAIProvider } from './base-provider.js';
4 |
5 | export class BedrockAIProvider extends BaseAIProvider {
6 | constructor() {
7 | super();
8 | this.name = 'Bedrock';
9 | }
10 |
11 | isRequiredApiKey() {
12 | return false;
13 | }
14 |
15 | /**
16 | * Returns the required API key environment variable name for Bedrock.
17 | * Bedrock uses AWS credentials, so we return the AWS access key identifier.
18 | * @returns {string} The environment variable name
19 | */
20 | getRequiredApiKeyName() {
21 | return 'AWS_ACCESS_KEY_ID';
22 | }
23 |
24 | /**
25 | * Override auth validation - Bedrock uses AWS credentials instead of API keys
26 | * @param {object} params - Parameters to validate
27 | */
28 | validateAuth(params) {}
29 |
30 | /**
31 | * Creates and returns a Bedrock client instance.
32 | * See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
33 | * for AWS SDK environment variables and configuration options.
34 | */
35 | getClient(params) {
36 | try {
37 | const credentialProvider = fromNodeProviderChain();
38 | const fetchImpl = this.createProxyFetch();
39 |
40 | return createAmazonBedrock({
41 | credentialProvider,
42 | ...(fetchImpl && { fetch: fetchImpl })
43 | });
44 | } catch (error) {
45 | this.handleError('client initialization', error);
46 | }
47 | }
48 | }
49 |
```
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancements---feature-requests.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | name: Enhancements & feature requests
3 | about: Suggest an idea for this project
4 | title: 'feat: '
5 | labels: enhancement
6 | assignees: ''
7 | ---
8 |
9 | > "Direct quote or clear summary of user request or need or user story."
10 |
11 | ### Motivation
12 |
13 | Detailed explanation of why this feature is important. Describe the problem it solves or the benefit it provides.
14 |
15 | ### Proposed Solution
16 |
17 | Clearly describe the proposed feature, including:
18 |
19 | - High-level overview of the feature
20 | - Relevant technologies or integrations
21 | - How it fits into the existing workflow or architecture
22 |
23 | ### High-Level Workflow
24 |
25 | 1. Step-by-step description of how the feature will be implemented
26 | 2. Include necessary intermediate milestones
27 |
28 | ### Key Elements
29 |
30 | - Bullet-point list of technical or UX/UI enhancements
31 | - Mention specific integrations or APIs
32 | - Highlight changes needed in existing data models or commands
33 |
34 | ### Example Workflow
35 |
36 | Provide a clear, concrete example demonstrating the feature:
37 |
38 | ```shell
39 | $ task-master [action]
40 | → Expected response/output
41 | ```
42 |
43 | ### Implementation Considerations
44 |
45 | - Dependencies on external components or APIs
46 | - Backward compatibility requirements
47 | - Potential performance impacts or resource usage
48 |
49 | ### Out of Scope (Future Considerations)
50 |
51 | Clearly list any features or improvements not included but relevant for future iterations.
52 |
```
--------------------------------------------------------------------------------
/apps/cli/src/ui/layout/helpers.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Layout helper utilities
3 | * Provides utilities for calculating dimensions, truncating text, and creating visual elements
4 | */
5 |
6 | import chalk from 'chalk';
7 |
8 | /**
9 | * Calculate box width as percentage of terminal width
10 | * @param percentage - Percentage of terminal width to use (default: 0.9)
11 | * @param minWidth - Minimum width to enforce (default: 40)
12 | * @returns Calculated box width
13 | */
14 | export function getBoxWidth(
15 | percentage: number = 0.9,
16 | minWidth: number = 40
17 | ): number {
18 | const terminalWidth = process.stdout.columns || 80;
19 | return Math.max(Math.floor(terminalWidth * percentage), minWidth);
20 | }
21 |
22 | /**
23 | * Truncate text to specified length
24 | */
25 | export function truncate(text: string, maxLength: number): string {
26 | if (text.length <= maxLength) {
27 | return text;
28 | }
29 | return text.substring(0, maxLength - 3) + '...';
30 | }
31 |
32 | /**
33 | * Create a progress bar
34 | */
35 | export function createProgressBar(
36 | completed: number,
37 | total: number,
38 | width: number = 30
39 | ): string {
40 | if (total === 0) {
41 | return chalk.gray('No tasks');
42 | }
43 |
44 | const percentage = Math.round((completed / total) * 100);
45 | const filled = Math.round((completed / total) * width);
46 | const empty = width - filled;
47 |
48 | const bar = chalk.green('█').repeat(filled) + chalk.gray('░').repeat(empty);
49 |
50 | return `${bar} ${chalk.cyan(`${percentage}%`)} (${completed}/${total})`;
51 | }
52 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/execution/types.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Executor types and interfaces for Task Master
3 | */
4 |
5 | import type { Task } from '../../common/types/index.js';
6 |
7 | /**
8 | * Supported executor types
9 | */
10 | export type ExecutorType = 'claude' | 'shell' | 'custom';
11 |
12 | /**
13 | * Options for executor creation
14 | */
15 | export interface ExecutorOptions {
16 | type: ExecutorType;
17 | projectRoot: string;
18 | config?: Record<string, any>;
19 | }
20 |
21 | /**
22 | * Result from task execution
23 | */
24 | export interface ExecutionResult {
25 | success: boolean;
26 | taskId: string;
27 | executorType: ExecutorType;
28 | output?: string;
29 | error?: string;
30 | startTime: string;
31 | endTime?: string;
32 | processId?: number;
33 | }
34 |
35 | /**
36 | * Base interface for all task executors
37 | */
38 | export interface ITaskExecutor {
39 | /**
40 | * Execute a task
41 | */
42 | execute(task: Task): Promise<ExecutionResult>;
43 |
44 | /**
45 | * Stop a running task execution
46 | */
47 | stop?(): Promise<void>;
48 |
49 | /**
50 | * Get executor type
51 | */
52 | getType(): ExecutorType;
53 |
54 | /**
55 | * Check if executor is available/configured
56 | */
57 | isAvailable(): Promise<boolean>;
58 | }
59 |
60 | /**
61 | * Configuration for Claude executor
62 | */
63 | export interface ClaudeExecutorConfig {
64 | command?: string; // Default: 'claude'
65 | systemPrompt?: string;
66 | additionalFlags?: string[];
67 | }
68 |
69 | /**
70 | * Configuration for Shell executor
71 | */
72 | export interface ShellExecutorConfig {
73 | shell?: string; // Default: '/bin/bash'
74 | env?: Record<string, string>;
75 | cwd?: string;
76 | }
77 |
```
--------------------------------------------------------------------------------
/src/ai-providers/ollama.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * ollama.js
3 | * AI provider implementation for Ollama models using the ollama-ai-provider-v2 package.
4 | */
5 |
6 | import { createOllama } from 'ollama-ai-provider-v2';
7 | import { BaseAIProvider } from './base-provider.js';
8 |
9 | export class OllamaAIProvider extends BaseAIProvider {
10 | constructor() {
11 | super();
12 | this.name = 'Ollama';
13 | }
14 |
15 | /**
16 | * Override auth validation - Ollama doesn't require API keys
17 | * @param {object} params - Parameters to validate
18 | */
19 | validateAuth(_params) {
20 | // Ollama runs locally and doesn't require API keys
21 | // No authentication validation needed
22 | }
23 |
24 | /**
25 | * Creates and returns an Ollama client instance.
26 | * @param {object} params - Parameters for client initialization
27 | * @param {string} [params.baseURL] - Optional Ollama base URL (defaults to http://localhost:11434)
28 | * @returns {Function} Ollama client function
29 | * @throws {Error} If initialization fails
30 | */
31 | getClient(params) {
32 | try {
33 | const { baseURL } = params;
34 |
35 | return createOllama({
36 | ...(baseURL && { baseURL })
37 | });
38 | } catch (error) {
39 | this.handleError('client initialization', error);
40 | }
41 | }
42 |
43 | isRequiredApiKey() {
44 | return false;
45 | }
46 |
47 | /**
48 | * Returns the required API key environment variable name for Ollama.
49 | * @returns {string} The environment variable name
50 | */
51 | getRequiredApiKeyName() {
52 | return 'OLLAMA_API_KEY';
53 | }
54 | }
55 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/remove-dependency.md:
--------------------------------------------------------------------------------
```markdown
1 | Remove a dependency between tasks.
2 |
3 | Arguments: $ARGUMENTS
4 |
5 | Parse the task IDs to remove dependency relationship.
6 |
7 | ## Removing Dependencies
8 |
9 | Removes a dependency relationship, potentially unblocking tasks.
10 |
11 | ## Argument Parsing
12 |
13 | Parse natural language or IDs:
14 | - "remove dependency between 5 and 3"
15 | - "5 no longer needs 3"
16 | - "unblock 5 from 3"
17 | - "5 3" → remove dependency of 5 on 3
18 |
19 | ## Execution
20 |
21 | ```bash
22 | task-master remove-dependency --id=<task-id> --depends-on=<dependency-id>
23 | ```
24 |
25 | ## Pre-Removal Checks
26 |
27 | 1. **Verify dependency exists**
28 | 2. **Check impact on task flow**
29 | 3. **Warn if it breaks logical sequence**
30 | 4. **Show what will be unblocked**
31 |
32 | ## Smart Analysis
33 |
34 | Before removing:
35 | - Show why dependency might have existed
36 | - Check if removal makes tasks executable
37 | - Verify no critical path disruption
38 | - Suggest alternative dependencies
39 |
40 | ## Post-Removal
41 |
42 | After removing:
43 | 1. Show updated task status
44 | 2. List newly unblocked tasks
45 | 3. Update project timeline
46 | 4. Suggest next actions
47 |
48 | ## Safety Features
49 |
50 | - Confirm if removing critical dependency
51 | - Show tasks that become immediately actionable
52 | - Warn about potential issues
53 | - Keep removal history
54 |
55 | ## Example
56 |
57 | ```
58 | /taskmaster:remove-dependency 5 from 3
59 | → Removed: Task #5 no longer depends on #3
60 | → Task #5 is now UNBLOCKED and ready to start
61 | → Warning: Consider if #5 still needs #2 completed first
62 | ```
```
--------------------------------------------------------------------------------
/src/ai-providers/lmstudio.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * lmstudio.js
3 | * AI provider implementation for LM Studio local models.
4 | *
5 | * LM Studio is a desktop application for running local LLMs.
6 | * It provides an OpenAI-compatible API server that runs locally.
7 | * Default server: http://localhost:1234/v1
8 | *
9 | * Usage:
10 | * 1. Start LM Studio application
11 | * 2. Load a model (e.g., llama-3.2-1b, mistral-7b)
12 | * 3. Go to "Local Server" tab and click "Start Server"
13 | * 4. Use the model ID from LM Studio in your config
14 | *
15 | * Note: LM Studio only supports `json_schema` mode for structured outputs,
16 | * not `json_object` mode. We disable native structured outputs to force
17 | * the AI SDK to use alternative strategies (like tool calling) which work
18 | * reliably across all LM Studio models.
19 | */
20 |
21 | import { OpenAICompatibleProvider } from './openai-compatible.js';
22 |
23 | /**
24 | * LM Studio provider for local model inference.
25 | * Does not require an API key as it runs locally.
26 | */
27 | export class LMStudioProvider extends OpenAICompatibleProvider {
28 | constructor() {
29 | super({
30 | name: 'LM Studio',
31 | apiKeyEnvVar: 'LMSTUDIO_API_KEY',
32 | requiresApiKey: false, // Local server, no API key needed
33 | defaultBaseURL: 'http://localhost:1234/v1',
34 | supportsStructuredOutputs: true
35 | // LM Studio only supports json_schema mode, not json_object mode
36 | // Disable native structured outputs to use alternative strategies
37 | });
38 | }
39 | }
40 |
```
--------------------------------------------------------------------------------
/.taskmaster/tasks/task_004_tm-start.txt:
--------------------------------------------------------------------------------
```
1 | # Task ID: 4
2 | # Title: Implement claude-code executor
3 | # Status: pending
4 | # Dependencies: 3
5 | # Priority: high
6 | # Description: Add functionality to execute the claude-code command with the built prompt
7 | # Details:
8 | Implement the functionality to execute the claude command with the built prompt. This should use Node.js child_process.exec() to run the command directly in the terminal.
9 |
10 | ```typescript
11 | import { exec } from 'child_process';
12 |
13 | // Inside execute method, after task validation
14 | private async executeClaude(prompt: string): Promise<void> {
15 | console.log('Starting claude-code to implement the task...');
16 |
17 | try {
18 | // Execute claude with the prompt
19 | const claudeCommand = `claude "${prompt.replace(/"/g, '\\"')}"`;
20 |
21 | // Use execSync to wait for the command to complete
22 | const { execSync } = require('child_process');
23 | execSync(claudeCommand, { stdio: 'inherit' });
24 |
25 | console.log('Claude session completed.');
26 | } catch (error) {
27 | console.error('Error executing claude-code:', error.message);
28 | process.exit(1);
29 | }
30 | }
31 | ```
32 |
33 | Then call this method from the execute method after building the prompt.
34 |
35 | # Test Strategy:
36 | Test by running the command with a valid task ID and verifying that the claude command is executed with the correct prompt. Check that the command handles errors appropriately if claude-code is not available.
37 |
```
--------------------------------------------------------------------------------
/apps/cli/src/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Main entry point for @tm/cli package
3 | * Exports all public APIs for the CLI presentation layer
4 | */
5 |
6 | // Commands
7 | export { ListTasksCommand } from './commands/list.command.js';
8 | export { ShowCommand } from './commands/show.command.js';
9 | export { NextCommand } from './commands/next.command.js';
10 | export { AuthCommand } from './commands/auth.command.js';
11 | export { ContextCommand } from './commands/context.command.js';
12 | export { StartCommand } from './commands/start.command.js';
13 | export { SetStatusCommand } from './commands/set-status.command.js';
14 | export { ExportCommand } from './commands/export.command.js';
15 | export { TagsCommand } from './commands/tags.command.js';
16 | export { BriefsCommand } from './commands/briefs.command.js';
17 |
18 | // Command Registry
19 | export {
20 | CommandRegistry,
21 | registerAllCommands,
22 | registerCommandsByCategory,
23 | type CommandMetadata
24 | } from './command-registry.js';
25 |
26 | // General utilities (error handling, auto-update, etc.)
27 | export * from './utils/index.js';
28 |
29 | // UI utilities - exported only via ui namespace to avoid naming conflicts
30 | // Import via: import { ui } from '@tm/cli'; ui.displayBanner();
31 | export * as ui from './ui/index.js';
32 |
33 | export { runInteractiveSetup } from './commands/models/index.js';
34 |
35 | // Re-export commonly used types from tm-core
36 | export type {
37 | Task,
38 | TaskStatus,
39 | TaskPriority,
40 | TmCore
41 | } from '@tm/core';
42 |
```
--------------------------------------------------------------------------------
/apps/extension/src/components/TaskDetails/PriorityBadge.tsx:
--------------------------------------------------------------------------------
```typescript
1 | import type React from 'react';
2 | import type { TaskMasterTask } from '../../webview/types';
3 |
4 | // Custom Priority Badge Component with theme-adaptive styling
5 | export const PriorityBadge: React.FC<{
6 | priority: TaskMasterTask['priority'];
7 | }> = ({ priority }) => {
8 | const getPriorityColors = (priority: string) => {
9 | switch (priority) {
10 | case 'high':
11 | return {
12 | backgroundColor: 'rgba(239, 68, 68, 0.2)', // red-500 with opacity
13 | color: '#dc2626', // red-600 - works in both themes
14 | borderColor: 'rgba(239, 68, 68, 0.4)'
15 | };
16 | case 'medium':
17 | return {
18 | backgroundColor: 'rgba(245, 158, 11, 0.2)', // amber-500 with opacity
19 | color: '#d97706', // amber-600 - works in both themes
20 | borderColor: 'rgba(245, 158, 11, 0.4)'
21 | };
22 | case 'low':
23 | return {
24 | backgroundColor: 'rgba(34, 197, 94, 0.2)', // green-500 with opacity
25 | color: '#16a34a', // green-600 - works in both themes
26 | borderColor: 'rgba(34, 197, 94, 0.4)'
27 | };
28 | default:
29 | return {
30 | backgroundColor: 'rgba(156, 163, 175, 0.2)',
31 | color: 'var(--vscode-foreground)',
32 | borderColor: 'rgba(156, 163, 175, 0.4)'
33 | };
34 | }
35 | };
36 |
37 | const colors = getPriorityColors(priority || '');
38 |
39 | return (
40 | <span
41 | className="inline-flex items-center px-2 py-1 text-xs font-medium rounded-md border"
42 | style={colors}
43 | >
44 | {priority || 'None'}
45 | </span>
46 | );
47 | };
48 |
```
--------------------------------------------------------------------------------
/apps/cli/src/utils/ui.spec.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * CLI UI utilities tests (Backward compatibility tests)
3 | * Tests for apps/cli/src/utils/ui.ts
4 | *
5 | * This file ensures backward compatibility with the old ui.ts module.
6 | * The actual implementation has been moved to src/ui/ organized modules.
7 | * See:
8 | * - ui/layout/helpers.spec.ts
9 | * - ui/formatters/status-formatters.spec.ts
10 | */
11 |
12 | import { describe, expect, it } from 'vitest';
13 | import { getBoxWidth, getBriefStatusWithColor } from './ui.js';
14 |
15 | describe('CLI UI Utilities (Backward Compatibility)', () => {
16 | describe('Re-exports work correctly from ui/', () => {
17 | it('should re-export getBoxWidth', () => {
18 | expect(typeof getBoxWidth).toBe('function');
19 | });
20 |
21 | it('should re-export getBriefStatusWithColor', () => {
22 | expect(typeof getBriefStatusWithColor).toBe('function');
23 | });
24 |
25 | it('should maintain functional behavior for getBoxWidth', () => {
26 | // Simple smoke test - detailed tests are in ui/layout/helpers.spec.ts
27 | const width = getBoxWidth(0.9, 40);
28 | expect(typeof width).toBe('number');
29 | expect(width).toBeGreaterThanOrEqual(40);
30 | });
31 |
32 | it('should maintain functional behavior for getBriefStatusWithColor', () => {
33 | // Simple smoke test - detailed tests are in ui/formatters/status-formatters.spec.ts
34 | const result = getBriefStatusWithColor('done', true);
35 | expect(result).toContain('Done');
36 | expect(result).toContain('✓');
37 | });
38 | });
39 | });
40 |
```
--------------------------------------------------------------------------------
/.taskmaster/reports/task-complexity-report.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "meta": {
3 | "generatedAt": "2025-08-02T14:28:59.851Z",
4 | "tasksAnalyzed": 1,
5 | "totalTasks": 93,
6 | "analysisCount": 1,
7 | "thresholdScore": 5,
8 | "projectName": "Taskmaster",
9 | "usedResearch": false
10 | },
11 | "complexityAnalysis": [
12 | {
13 | "taskId": 24,
14 | "taskTitle": "Implement AI-Powered Test Generation Command",
15 | "complexityScore": 8,
16 | "recommendedSubtasks": 6,
17 | "expansionPrompt": "Expand task 24 'Implement AI-Powered Test Generation Command' into 6 subtasks, focusing on: 1) Command structure implementation, 2) AI prompt engineering for test generation, 3) Test file generation and output, 4) Framework-specific template implementation, 5) MCP tool integration, and 6) Documentation and help system integration. Include detailed implementation steps, dependencies, and testing approaches for each subtask.",
18 | "reasoning": "This task has high complexity due to several challenging aspects: 1) AI integration requiring sophisticated prompt engineering, 2) Test generation across multiple frameworks, 3) File system operations with proper error handling, 4) MCP tool integration, 5) Complex configuration requirements, and 6) Framework-specific template generation. The task already has 5 subtasks but could benefit from reorganization based on the updated implementation details in the info blocks, particularly around framework support and configuration."
19 | }
20 | ]
21 | }
22 |
```
--------------------------------------------------------------------------------
/mcp-server/src/custom-sdk/index.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * src/ai-providers/custom-sdk/mcp/index.js
3 | *
4 | * AI SDK factory function for MCP provider.
5 | * Creates MCP language model instances with session-based AI operations.
6 | */
7 |
8 | import { MCPLanguageModel } from './language-model.js';
9 |
10 | /**
11 | * Create MCP provider factory function following AI SDK patterns
12 | * @param {object} options - Provider options
13 | * @param {object} options.session - MCP session object
14 | * @param {object} options.defaultSettings - Default settings for the provider
15 | * @returns {Function} Provider factory function
16 | */
17 | export function createMCP(options = {}) {
18 | if (!options.session) {
19 | throw new Error('MCP provider requires session object');
20 | }
21 |
22 | // Return the provider factory function that AI SDK expects
23 | const provider = function (modelId, settings = {}) {
24 | if (new.target) {
25 | throw new Error(
26 | 'The MCP model function cannot be called with the new keyword.'
27 | );
28 | }
29 |
30 | return new MCPLanguageModel({
31 | session: options.session,
32 | modelId: modelId || 'claude-3-5-sonnet-20241022',
33 | settings: {
34 | temperature: settings.temperature,
35 | maxTokens: settings.maxTokens,
36 | ...options.defaultSettings,
37 | ...settings
38 | }
39 | });
40 | };
41 |
42 | // Add required methods for AI SDK compatibility
43 | provider.languageModel = (modelId, settings) => provider(modelId, settings);
44 | provider.chat = (modelId, settings) => provider(modelId, settings);
45 |
46 | return provider;
47 | }
48 |
```
--------------------------------------------------------------------------------
/.taskmaster/tasks/task_001_tm-start.txt:
--------------------------------------------------------------------------------
```
1 | # Task ID: 1
2 | # Title: Create start command class structure
3 | # Status: pending
4 | # Dependencies: None
5 | # Priority: high
6 | # Description: Create the basic structure for the start command following the Commander class pattern
7 | # Details:
8 | Create a new file `apps/cli/src/commands/start.command.ts` based on the existing list.command.ts pattern. Implement the command class with proper command registration, description, and argument handling for the task_id parameter. The class should extend the base Command class and implement the required methods.
9 |
10 | Example structure:
11 | ```typescript
12 | import { Command } from 'commander';
13 | import { BaseCommand } from './base.command';
14 |
15 | export class StartCommand extends BaseCommand {
16 | public register(program: Command): void {
17 | program
18 | .command('start')
19 | .alias('tm start')
20 | .description('Start implementing a task using claude-code')
21 | .argument('<task_id>', 'ID of the task to start')
22 | .action(async (taskId: string) => {
23 | await this.execute(taskId);
24 | });
25 | }
26 |
27 | public async execute(taskId: string): Promise<void> {
28 | // Implementation will be added in subsequent tasks
29 | }
30 | }
31 | ```
32 |
33 | # Test Strategy:
34 | Verify the command registers correctly by running the CLI with --help and checking that the start command appears with proper description and arguments. Test the basic structure by ensuring the command can be invoked without errors.
35 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/smart-workflow.md:
--------------------------------------------------------------------------------
```markdown
1 | Execute an intelligent workflow based on current project state and recent commands.
2 |
3 | This command analyzes:
4 | 1. Recent commands you've run
5 | 2. Current project state
6 | 3. Time of day / day of week
7 | 4. Your working patterns
8 |
9 | Arguments: $ARGUMENTS
10 |
11 | ## Intelligent Workflow Selection
12 |
13 | Based on context, I'll determine the best workflow:
14 |
15 | ### Context Analysis
16 | - Previous command executed
17 | - Current task states
18 | - Unfinished work from last session
19 | - Your typical patterns
20 |
21 | ### Smart Execution
22 |
23 | If last command was:
24 | - `status` → Likely starting work → Run daily standup
25 | - `complete` → Task finished → Find next task
26 | - `list pending` → Planning → Suggest sprint planning
27 | - `expand` → Breaking down work → Show complexity analysis
28 | - `init` → New project → Show onboarding workflow
29 |
30 | If no recent commands:
31 | - Morning? → Daily standup workflow
32 | - Many pending tasks? → Sprint planning
33 | - Tasks blocked? → Dependency resolution
34 | - Friday? → Weekly review
35 |
36 | ### Workflow Composition
37 |
38 | I'll chain appropriate commands:
39 | 1. Analyze current state
40 | 2. Execute primary workflow
41 | 3. Suggest follow-up actions
42 | 4. Prepare environment for coding
43 |
44 | ### Learning Mode
45 |
46 | This command learns from your patterns:
47 | - Track command sequences
48 | - Note time preferences
49 | - Remember common workflows
50 | - Adapt to your style
51 |
52 | Example flows detected:
53 | - Morning: standup → next → start
54 | - After lunch: status → continue task
55 | - End of day: complete → commit → status
```
--------------------------------------------------------------------------------
/.kiro/steering/kiro_rules.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | inclusion: always
3 | ---
4 |
5 | - **Required Rule Structure:**
6 | ```markdown
7 | ---
8 | description: Clear, one-line description of what the rule enforces
9 | globs: path/to/files/*.ext, other/path/**/*
10 | alwaysApply: boolean
11 | ---
12 |
13 | - **Main Points in Bold**
14 | - Sub-points with details
15 | - Examples and explanations
16 | ```
17 |
18 | - **File References:**
19 | - Use `[filename](mdc:path/to/file)` ([filename](mdc:filename)) to reference files
20 | - Example: [prisma.md](.kiro/steering/prisma.md) for rule references
21 | - Example: [schema.prisma](mdc:prisma/schema.prisma) for code references
22 |
23 | - **Code Examples:**
24 | - Use language-specific code blocks
25 | ```typescript
26 | // ✅ DO: Show good examples
27 | const goodExample = true;
28 |
29 | // ❌ DON'T: Show anti-patterns
30 | const badExample = false;
31 | ```
32 |
33 | - **Rule Content Guidelines:**
34 | - Start with high-level overview
35 | - Include specific, actionable requirements
36 | - Show examples of correct implementation
37 | - Reference existing code when possible
38 | - Keep rules DRY by referencing other rules
39 |
40 | - **Rule Maintenance:**
41 | - Update rules when new patterns emerge
42 | - Add examples from actual codebase
43 | - Remove outdated patterns
44 | - Cross-reference related rules
45 |
46 | - **Best Practices:**
47 | - Use bullet points for clarity
48 | - Keep descriptions concise
49 | - Include both DO and DON'T examples
50 | - Reference actual code over theoretical examples
51 | - Use consistent formatting across rules
```
--------------------------------------------------------------------------------
/scripts/modules/update-config-tokens.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * update-config-tokens.js
3 | * Updates config.json with correct maxTokens values from supported-models.json
4 | */
5 |
6 | import fs from 'fs';
7 | import supportedModels from './supported-models.json' with { type: 'json' };
8 |
9 | /**
10 | * Updates the config file with correct maxTokens values from supported-models.json
11 | * @param {string} configPath - Path to the config.json file to update
12 | * @returns {boolean} True if successful, false otherwise
13 | */
14 | export function updateConfigMaxTokens(configPath) {
15 | try {
16 | // Load config
17 | const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
18 |
19 | // Update each role's maxTokens if the model exists in supported-models.json
20 | const roles = ['main', 'research', 'fallback'];
21 |
22 | for (const role of roles) {
23 | if (config.models && config.models[role]) {
24 | const provider = config.models[role].provider;
25 | const modelId = config.models[role].modelId;
26 |
27 | // Find the model in supported models
28 | if (supportedModels[provider]) {
29 | const modelData = supportedModels[provider].find(
30 | (m) => m.id === modelId
31 | );
32 | if (modelData && modelData.max_tokens) {
33 | config.models[role].maxTokens = modelData.max_tokens;
34 | }
35 | }
36 | }
37 | }
38 |
39 | // Write back the updated config
40 | fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
41 | return true;
42 | } catch (error) {
43 | console.error('Error updating config maxTokens:', error.message);
44 | return false;
45 | }
46 | }
47 |
```
--------------------------------------------------------------------------------
/tests/unit/task-manager/clear-subtasks.test.js:
--------------------------------------------------------------------------------
```javascript
1 | import fs from 'fs';
2 | import path from 'path';
3 | import clearSubtasks from '../../../scripts/modules/task-manager/clear-subtasks.js';
4 |
5 | const TMP = path.join(process.cwd(), '.tmp_clear_subtasks');
6 | const TASKS = path.join(TMP, 'tasks.json');
7 |
8 | function seed() {
9 | fs.rmSync(TMP, { recursive: true, force: true });
10 | fs.mkdirSync(path.join(TMP, '.taskmaster'), { recursive: true });
11 | fs.writeFileSync(
12 | TASKS,
13 | JSON.stringify(
14 | {
15 | master: {
16 | tasks: [
17 | {
18 | id: 1,
19 | title: 'Parent',
20 | subtasks: [
21 | { id: 1, title: 'Sub1' },
22 | { id: 2, title: 'Sub2' }
23 | ]
24 | },
25 | { id: 2, title: 'Solo' }
26 | ],
27 | metadata: { created: new Date().toISOString() }
28 | }
29 | },
30 | null,
31 | 2
32 | )
33 | );
34 | }
35 |
36 | describe('clearSubtasks', () => {
37 | beforeEach(seed);
38 | afterAll(() => fs.rmSync(TMP, { recursive: true, force: true }));
39 |
40 | it('clears subtasks for given task id', () => {
41 | clearSubtasks(TASKS, '1', { projectRoot: TMP, tag: 'master' });
42 | const data = JSON.parse(fs.readFileSync(TASKS, 'utf8'));
43 | const parent = data.master.tasks.find((t) => t.id === 1);
44 | expect(parent.subtasks.length).toBe(0);
45 | });
46 |
47 | it('does nothing when task has no subtasks', () => {
48 | clearSubtasks(TASKS, '2', { projectRoot: TMP, tag: 'master' });
49 | const data = JSON.parse(fs.readFileSync(TASKS, 'utf8'));
50 | const solo = data.master.tasks.find((t) => t.id === 2);
51 | expect(solo.subtasks).toBeUndefined();
52 | });
53 | });
54 |
```
--------------------------------------------------------------------------------
/packages/ai-sdk-provider-grok-cli/src/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Provider exports for creating and configuring Grok CLI instances.
3 | */
4 |
5 | /**
6 | * Creates a new Grok CLI provider instance and the default provider instance.
7 | */
8 | export { createGrokCli, grokCli } from './grok-cli-provider.js';
9 |
10 | /**
11 | * Type definitions for the Grok CLI provider.
12 | */
13 | export type {
14 | GrokCliProvider,
15 | GrokCliProviderSettings
16 | } from './grok-cli-provider.js';
17 |
18 | /**
19 | * Language model implementation for Grok CLI.
20 | * This class implements the AI SDK's LanguageModelV2 interface.
21 | */
22 | export { GrokCliLanguageModel } from './grok-cli-language-model.js';
23 |
24 | /**
25 | * Type definitions for Grok CLI language models.
26 | */
27 | export type {
28 | GrokCliModelId,
29 | GrokCliLanguageModelOptions,
30 | GrokCliSettings,
31 | GrokCliMessage,
32 | GrokCliResponse,
33 | GrokCliErrorMetadata
34 | } from './types.js';
35 |
36 | /**
37 | * Error handling utilities for Grok CLI.
38 | * These functions help create and identify specific error types.
39 | */
40 | export {
41 | isAuthenticationError,
42 | isTimeoutError,
43 | isInstallationError,
44 | getErrorMetadata,
45 | createAPICallError,
46 | createAuthenticationError,
47 | createTimeoutError,
48 | createInstallationError
49 | } from './errors.js';
50 |
51 | /**
52 | * Message conversion utilities for Grok CLI communication.
53 | */
54 | export {
55 | convertToGrokCliMessages,
56 | convertFromGrokCliResponse,
57 | createPromptFromMessages,
58 | escapeShellArg
59 | } from './message-converter.js';
60 |
61 | /**
62 | * JSON extraction utilities for parsing Grok responses.
63 | */
64 | export { extractJson } from './json-extractor.js';
65 |
```
--------------------------------------------------------------------------------
/mcp-server/src/core/utils/env-utils.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Temporarily sets environment variables from session.env, executes an action,
3 | * and restores the original environment variables.
4 | * @param {object | undefined} sessionEnv - The environment object from the session.
5 | * @param {Function} actionFn - An async function to execute with the temporary environment.
6 | * @returns {Promise<any>} The result of the actionFn.
7 | */
8 | export async function withSessionEnv(sessionEnv, actionFn) {
9 | if (
10 | !sessionEnv ||
11 | typeof sessionEnv !== 'object' ||
12 | Object.keys(sessionEnv).length === 0
13 | ) {
14 | // If no sessionEnv is provided, just run the action directly
15 | return await actionFn();
16 | }
17 |
18 | const originalEnv = {};
19 | const keysToRestore = [];
20 |
21 | // Set environment variables from sessionEnv
22 | for (const key in sessionEnv) {
23 | if (Object.prototype.hasOwnProperty.call(sessionEnv, key)) {
24 | // Store original value if it exists, otherwise mark for deletion
25 | if (process.env[key] !== undefined) {
26 | originalEnv[key] = process.env[key];
27 | }
28 | keysToRestore.push(key);
29 | process.env[key] = sessionEnv[key];
30 | }
31 | }
32 |
33 | try {
34 | // Execute the provided action function
35 | return await actionFn();
36 | } finally {
37 | // Restore original environment variables
38 | for (const key of keysToRestore) {
39 | if (Object.prototype.hasOwnProperty.call(originalEnv, key)) {
40 | process.env[key] = originalEnv[key];
41 | } else {
42 | // If the key didn't exist originally, delete it
43 | delete process.env[key];
44 | }
45 | }
46 | }
47 | }
48 |
```
--------------------------------------------------------------------------------
/apps/cli/src/ui/components/cardBox.component.ts:
--------------------------------------------------------------------------------
```typescript
1 | import boxen from 'boxen';
2 | import chalk from 'chalk';
3 |
4 | /**
5 | * Configuration for the card box component
6 | */
7 | export interface CardBoxConfig {
8 | /** Header text displayed in yellow bold */
9 | header: string;
10 | /** Body paragraphs displayed in white */
11 | body: string[];
12 | /** Call to action section with label and URL */
13 | callToAction: {
14 | label: string;
15 | action: string;
16 | };
17 | /** Footer text displayed in gray (usage instructions) */
18 | footer?: string;
19 | }
20 |
21 | /**
22 | * Creates a formatted boxen card with header, body, call-to-action, and optional footer.
23 | * A reusable component for displaying informational messages in a styled box.
24 | *
25 | * @param config - Configuration for the box sections
26 | * @returns Formatted string ready for console.log
27 | */
28 | export function displayCardBox(config: CardBoxConfig): string {
29 | const { header, body, callToAction, footer } = config;
30 |
31 | // Build the content sections
32 | const sections: string[] = [
33 | // Header
34 | chalk.yellow.bold(header),
35 |
36 | // Body paragraphs
37 | ...body.map((paragraph) => chalk.white(paragraph)),
38 |
39 | // Call to action
40 | chalk.cyan(callToAction.label) +
41 | '\n' +
42 | chalk.blue.underline(callToAction.action)
43 | ];
44 |
45 | // Add footer if provided
46 | if (footer) {
47 | sections.push(chalk.gray(footer));
48 | }
49 |
50 | // Join sections with double newlines
51 | const content = sections.join('\n\n');
52 |
53 | // Wrap in boxen
54 | return boxen(content, {
55 | padding: 1,
56 | borderColor: 'yellow',
57 | borderStyle: 'round',
58 | margin: { top: 1, bottom: 1 }
59 | });
60 | }
61 |
```
--------------------------------------------------------------------------------
/packages/tm-core/vitest.config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import path from 'node:path';
2 | import { fileURLToPath } from 'node:url';
3 | import { defineConfig } from 'vitest/config';
4 |
5 | // __dirname in ESM
6 | const __filename = fileURLToPath(import.meta.url);
7 | const __dirname = path.dirname(__filename);
8 |
9 | export default defineConfig({
10 | test: {
11 | globals: true,
12 | environment: 'node',
13 | include: [
14 | 'tests/**/*.test.ts',
15 | 'tests/**/*.spec.ts',
16 | 'tests/{unit,integration,e2e}/**/*.{test,spec}.ts',
17 | 'src/**/*.test.ts',
18 | 'src/**/*.spec.ts'
19 | ],
20 | exclude: ['node_modules', 'dist', '.git', '.cache'],
21 | coverage: {
22 | provider: 'v8',
23 | reporter: ['text', 'json', 'html', 'lcov'],
24 | exclude: [
25 | 'node_modules/',
26 | 'dist/',
27 | 'tests/',
28 | '**/*.test.ts',
29 | '**/*.spec.ts',
30 | '**/*.d.ts',
31 | '**/mocks/**',
32 | '**/fixtures/**',
33 | 'vitest.config.ts',
34 | 'src/index.ts'
35 | ],
36 | thresholds: {
37 | branches: 80,
38 | functions: 80,
39 | lines: 80,
40 | statements: 80
41 | }
42 | },
43 | setupFiles: ['./tests/setup.ts'],
44 | testTimeout: 10000,
45 | clearMocks: true,
46 | restoreMocks: true,
47 | mockReset: true
48 | },
49 | resolve: {
50 | alias: {
51 | '@': path.resolve(__dirname, './src'),
52 | '@/types': path.resolve(__dirname, './src/types'),
53 | '@/providers': path.resolve(__dirname, './src/providers'),
54 | '@/storage': path.resolve(__dirname, './src/storage'),
55 | '@/parser': path.resolve(__dirname, './src/parser'),
56 | '@/utils': path.resolve(__dirname, './src/utils'),
57 | '@/errors': path.resolve(__dirname, './src/errors')
58 | }
59 | }
60 | });
61 |
```
--------------------------------------------------------------------------------
/apps/cli/src/utils/project-root.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Project root utilities for CLI
3 | * Provides smart project root detection for command execution
4 | */
5 |
6 | import { resolve } from 'node:path';
7 | import { findProjectRoot as findProjectRootCore } from '@tm/core';
8 |
9 | /**
10 | * Get the project root directory with fallback to provided path
11 | *
12 | * This function intelligently detects the project root by looking for markers like:
13 | * - .taskmaster directory (highest priority)
14 | * - .git directory
15 | * - package.json
16 | * - Other project markers
17 | *
18 | * If a projectPath is explicitly provided, it will be resolved to an absolute path.
19 | * Otherwise, it will attempt to find the project root starting from current directory.
20 | *
21 | * @param projectPath - Optional explicit project path from user
22 | * @returns The project root directory path (always absolute)
23 | *
24 | * @example
25 | * ```typescript
26 | * // Auto-detect project root
27 | * const root = getProjectRoot();
28 | *
29 | * // Use explicit path if provided (resolved to absolute path)
30 | * const root = getProjectRoot('./my-project'); // Resolves relative paths
31 | * const root = getProjectRoot('/explicit/path'); // Already absolute, returned as-is
32 | * ```
33 | */
34 | export function getProjectRoot(projectPath?: string): string {
35 | // If explicitly provided, resolve it to an absolute path
36 | // This handles relative paths and ensures Windows paths are normalized
37 | if (projectPath) {
38 | return resolve(projectPath);
39 | }
40 |
41 | // Otherwise, intelligently find the project root
42 | return findProjectRootCore();
43 | }
44 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/tasks/repositories/task-repository.interface.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { Task, TaskTag } from '../../../common/types/index.js';
2 | import { LoadTasksOptions } from '../../../common/interfaces/storage.interface.js';
3 |
4 | /**
5 | * Brief information
6 | */
7 | export interface Brief {
8 | id: string;
9 | accountId: string;
10 | createdAt: string;
11 | name?: string;
12 | description?: string;
13 | status?: string;
14 | }
15 |
16 | export interface TaskRepository {
17 | // Task operations
18 | getTasks(projectId: string, options?: LoadTasksOptions): Promise<Task[]>;
19 | getTask(projectId: string, taskId: string): Promise<Task | null>;
20 | createTask(projectId: string, task: Omit<Task, 'id'>): Promise<Task>;
21 | updateTask(
22 | projectId: string,
23 | taskId: string,
24 | updates: Partial<Task>
25 | ): Promise<Task>;
26 | deleteTask(projectId: string, taskId: string): Promise<void>;
27 |
28 | // Brief operations
29 | getBrief(briefId: string): Promise<Brief | null>;
30 |
31 | // Tag operations
32 | getTags(projectId: string): Promise<TaskTag[]>;
33 | getTag(projectId: string, tagName: string): Promise<TaskTag | null>;
34 | createTag(projectId: string, tag: TaskTag): Promise<TaskTag>;
35 | updateTag(
36 | projectId: string,
37 | tagName: string,
38 | updates: Partial<TaskTag>
39 | ): Promise<TaskTag>;
40 | deleteTag(projectId: string, tagName: string): Promise<void>;
41 |
42 | // Bulk operations
43 | bulkCreateTasks(
44 | projectId: string,
45 | tasks: Omit<Task, 'id'>[]
46 | ): Promise<Task[]>;
47 | bulkUpdateTasks(
48 | projectId: string,
49 | updates: Array<{ id: string; updates: Partial<Task> }>
50 | ): Promise<Task[]>;
51 | bulkDeleteTasks(projectId: string, taskIds: string[]): Promise<void>;
52 | }
53 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/storage/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Storage layer for the tm-core package
3 | * This file exports all storage-related classes and interfaces
4 | */
5 |
6 | // Export storage implementations
7 | export { FileStorage } from './adapters/file-storage/index.js';
8 | export { ApiStorage, type ApiStorageConfig } from './adapters/api-storage.js';
9 | export { StorageFactory } from './services/storage-factory.js';
10 |
11 | // Export activity logger
12 | export {
13 | logActivity,
14 | readActivityLog,
15 | filterActivityLog,
16 | type ActivityEvent,
17 | type ActivityFilter
18 | } from './adapters/activity-logger.js';
19 |
20 | // Export storage interface and types
21 | export type {
22 | IStorage,
23 | StorageStats
24 | } from '../../common/interfaces/storage.interface.js';
25 |
26 | // Placeholder exports - these will be implemented in later tasks
27 | export interface StorageAdapter {
28 | read(path: string): Promise<string | null>;
29 | write(path: string, data: string): Promise<void>;
30 | exists(path: string): Promise<boolean>;
31 | delete(path: string): Promise<void>;
32 | }
33 |
34 | /**
35 | * @deprecated This is a placeholder class that will be properly implemented in later tasks
36 | */
37 | export class PlaceholderStorage implements StorageAdapter {
38 | private data = new Map<string, string>();
39 |
40 | async read(path: string): Promise<string | null> {
41 | return this.data.get(path) || null;
42 | }
43 |
44 | async write(path: string, data: string): Promise<void> {
45 | this.data.set(path, data);
46 | }
47 |
48 | async exists(path: string): Promise<boolean> {
49 | return this.data.has(path);
50 | }
51 |
52 | async delete(path: string): Promise<void> {
53 | this.data.delete(path);
54 | }
55 | }
56 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/validate-dependencies.md:
--------------------------------------------------------------------------------
```markdown
1 | Validate all task dependencies for issues.
2 |
3 | ## Dependency Validation
4 |
5 | Comprehensive check for dependency problems across the entire project.
6 |
7 | ## Execution
8 |
9 | ```bash
10 | task-master validate-dependencies
11 | ```
12 |
13 | ## Validation Checks
14 |
15 | 1. **Circular Dependencies**
16 | - A depends on B, B depends on A
17 | - Complex circular chains
18 | - Self-dependencies
19 |
20 | 2. **Missing Dependencies**
21 | - References to non-existent tasks
22 | - Deleted task references
23 | - Invalid task IDs
24 |
25 | 3. **Logical Issues**
26 | - Completed tasks depending on pending
27 | - Cancelled tasks in dependency chains
28 | - Impossible sequences
29 |
30 | 4. **Complexity Warnings**
31 | - Over-complex dependency chains
32 | - Too many dependencies per task
33 | - Bottleneck tasks
34 |
35 | ## Smart Analysis
36 |
37 | The validation provides:
38 | - Visual dependency graph
39 | - Critical path analysis
40 | - Bottleneck identification
41 | - Suggested optimizations
42 |
43 | ## Report Format
44 |
45 | ```
46 | Dependency Validation Report
47 | ━━━━━━━━━━━━━━━━━━━━━━━━━━
48 | ✅ No circular dependencies found
49 | ⚠️ 2 warnings found:
50 | - Task #23 has 7 dependencies (consider breaking down)
51 | - Task #45 blocks 5 other tasks (potential bottleneck)
52 | ❌ 1 error found:
53 | - Task #67 depends on deleted task #66
54 |
55 | Critical Path: #1 → #5 → #23 → #45 → #50 (15 days)
56 | ```
57 |
58 | ## Actionable Output
59 |
60 | For each issue found:
61 | - Clear description
62 | - Impact assessment
63 | - Suggested fix
64 | - Command to resolve
65 |
66 | ## Next Steps
67 |
68 | After validation:
69 | - Run `/taskmaster:fix-dependencies` to auto-fix
70 | - Manually adjust problematic dependencies
71 | - Rerun to verify fixes
```
--------------------------------------------------------------------------------
/packages/tm-core/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "@tm/core",
3 | "private": true,
4 | "description": "Core library for Task Master - TypeScript task management system",
5 | "type": "module",
6 | "types": "./src/index.ts",
7 | "main": "./dist/index.js",
8 | "exports": {
9 | ".": "./src/index.ts",
10 | "./auth": "./src/auth/index.ts",
11 | "./storage": "./src/storage/index.ts",
12 | "./config": "./src/config/index.ts",
13 | "./providers": "./src/providers/index.ts",
14 | "./services": "./src/services/index.ts",
15 | "./errors": "./src/errors/index.ts",
16 | "./logger": "./src/logger/index.ts",
17 | "./types": "./src/types/index.ts",
18 | "./interfaces": "./src/interfaces/index.ts",
19 | "./utils": "./src/utils/index.ts"
20 | },
21 | "scripts": {
22 | "test": "vitest run",
23 | "test:watch": "vitest",
24 | "test:coverage": "vitest run --coverage",
25 | "lint": "biome check --write",
26 | "lint:check": "biome check",
27 | "lint:fix": "biome check --fix --unsafe",
28 | "format": "biome format --write",
29 | "format:check": "biome format",
30 | "typecheck": "tsc --noEmit"
31 | },
32 | "dependencies": {
33 | "@supabase/supabase-js": "^2.57.4",
34 | "date-fns": "^4.1.0",
35 | "fs-extra": "^11.3.2",
36 | "simple-git": "^3.28.0",
37 | "steno": "^4.0.2",
38 | "zod": "^4.1.11"
39 | },
40 | "devDependencies": {
41 | "@types/fs-extra": "^11.0.4",
42 | "@types/node": "^22.10.5",
43 | "@vitest/coverage-v8": "^3.2.4",
44 | "strip-literal": "3.1.0",
45 | "typescript": "^5.9.2",
46 | "vitest": "^3.2.4"
47 | },
48 | "files": ["src", "README.md", "CHANGELOG.md"],
49 | "keywords": ["task-management", "typescript", "ai", "prd", "parser"],
50 | "author": "Task Master AI",
51 | "version": ""
52 | }
53 |
```
--------------------------------------------------------------------------------
/tests/unit/task-manager/move-task.test.js:
--------------------------------------------------------------------------------
```javascript
1 | import fs from 'fs';
2 | import path from 'path';
3 | import moveTask from '../../../scripts/modules/task-manager/move-task.js';
4 |
5 | const TMP = path.join(process.cwd(), '.tmp_move_task');
6 | const TASKS = path.join(TMP, 'tasks.json');
7 |
8 | function seed(initialTasks) {
9 | fs.rmSync(TMP, { recursive: true, force: true });
10 | fs.mkdirSync(path.join(TMP, '.taskmaster'), { recursive: true });
11 | fs.writeFileSync(
12 | TASKS,
13 | JSON.stringify(
14 | {
15 | master: {
16 | tasks: initialTasks,
17 | metadata: { created: new Date().toISOString() }
18 | }
19 | },
20 | null,
21 | 2
22 | )
23 | );
24 | }
25 |
26 | describe('moveTask basic scenarios', () => {
27 | afterAll(() => fs.rmSync(TMP, { recursive: true, force: true }));
28 |
29 | it('moves a task to a new ID within same tag', async () => {
30 | seed([
31 | { id: 1, title: 'A' },
32 | { id: 2, title: 'B' }
33 | ]);
34 |
35 | await moveTask(TASKS, '1', '3', false, { projectRoot: TMP, tag: 'master' });
36 |
37 | const data = JSON.parse(fs.readFileSync(TASKS, 'utf8'));
38 | const ids = data.master.tasks.map((t) => t.id);
39 | expect(ids).toEqual(expect.arrayContaining([2, 3]));
40 | expect(ids).not.toContain(1);
41 | });
42 |
43 | it('refuses to move across tags', async () => {
44 | // build dual-tag structure
45 | seed([{ id: 1, title: 'task' }]);
46 | const raw = JSON.parse(fs.readFileSync(TASKS, 'utf8'));
47 | raw.other = { tasks: [], metadata: { created: new Date().toISOString() } };
48 | fs.writeFileSync(TASKS, JSON.stringify(raw, null, 2));
49 |
50 | await expect(
51 | moveTask(TASKS, '1', '2', false, { projectRoot: TMP, tag: 'other' })
52 | ).rejects.toThrow(/Source task/);
53 | });
54 | });
55 |
```
--------------------------------------------------------------------------------
/.taskmaster/templates/example_prd.md:
--------------------------------------------------------------------------------
```markdown
1 | <context>
2 | # Overview
3 | [Provide a high-level overview of your product here. Explain what problem it solves, who it's for, and why it's valuable.]
4 |
5 | # Core Features
6 | [List and describe the main features of your product. For each feature, include:
7 | - What it does
8 | - Why it's important
9 | - How it works at a high level]
10 |
11 | # User Experience
12 | [Describe the user journey and experience. Include:
13 | - User personas
14 | - Key user flows
15 | - UI/UX considerations]
16 | </context>
17 | <PRD>
18 | # Technical Architecture
19 | [Outline the technical implementation details:
20 | - System components
21 | - Data models
22 | - APIs and integrations
23 | - Infrastructure requirements]
24 |
25 | # Development Roadmap
26 | [Break down the development process into phases:
27 | - MVP requirements
28 | - Future enhancements
29 | - Do not think about timelines whatsoever -- all that matters is scope and detailing exactly what needs to be build in each phase so it can later be cut up into tasks]
30 |
31 | # Logical Dependency Chain
32 | [Define the logical order of development:
33 | - Which features need to be built first (foundation)
34 | - Getting as quickly as possible to something usable/visible front end that works
35 | - Properly pacing and scoping each feature so it is atomic but can also be built upon and improved as development approaches]
36 |
37 | # Risks and Mitigations
38 | [Identify potential risks and how they'll be addressed:
39 | - Technical challenges
40 | - Figuring out the MVP that we can build upon
41 | - Resource constraints]
42 |
43 | # Appendix
44 | [Include any additional information:
45 | - Research findings
46 | - Technical specifications]
47 | </PRD>
```
--------------------------------------------------------------------------------
/assets/example_prd.txt:
--------------------------------------------------------------------------------
```
1 | <context>
2 | # Overview
3 | [Provide a high-level overview of your product here. Explain what problem it solves, who it's for, and why it's valuable.]
4 |
5 | # Core Features
6 | [List and describe the main features of your product. For each feature, include:
7 | - What it does
8 | - Why it's important
9 | - How it works at a high level]
10 |
11 | # User Experience
12 | [Describe the user journey and experience. Include:
13 | - User personas
14 | - Key user flows
15 | - UI/UX considerations]
16 | </context>
17 | <PRD>
18 | # Technical Architecture
19 | [Outline the technical implementation details:
20 | - System components
21 | - Data models
22 | - APIs and integrations
23 | - Infrastructure requirements]
24 |
25 | # Development Roadmap
26 | [Break down the development process into phases:
27 | - MVP requirements
28 | - Future enhancements
29 | - Do not think about timelines whatsoever -- all that matters is scope and detailing exactly what needs to be build in each phase so it can later be cut up into tasks]
30 |
31 | # Logical Dependency Chain
32 | [Define the logical order of development:
33 | - Which features need to be built first (foundation)
34 | - Getting as quickly as possible to something usable/visible front end that works
35 | - Properly pacing and scoping each feature so it is atomic but can also be built upon and improved as development approaches]
36 |
37 | # Risks and Mitigations
38 | [Identify potential risks and how they'll be addressed:
39 | - Technical challenges
40 | - Figuring out the MVP that we can build upon
41 | - Resource constraints]
42 |
43 | # Appendix
44 | [Include any additional information:
45 | - Research findings
46 | - Technical specifications]
47 | </PRD>
```
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | concurrency: ${{ github.workflow }}-${{ github.ref }}
8 |
9 | permissions:
10 | contents: write
11 | pull-requests: write
12 | id-token: write
13 |
14 | jobs:
15 | release:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/checkout@v4
19 | with:
20 | fetch-depth: 0
21 |
22 | - uses: actions/setup-node@v4
23 | with:
24 | node-version: 20
25 | cache: "npm"
26 |
27 | - name: Cache node_modules
28 | uses: actions/cache@v4
29 | with:
30 | path: |
31 | node_modules
32 | */*/node_modules
33 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
34 | restore-keys: |
35 | ${{ runner.os }}-node-
36 |
37 | - name: Install Dependencies
38 | run: npm ci
39 | timeout-minutes: 2
40 |
41 | - name: Check pre-release mode
42 | run: node ./.github/scripts/check-pre-release-mode.mjs "main"
43 |
44 | - name: Build packages
45 | run: npm run turbo:build
46 | env:
47 | NODE_ENV: production
48 | FORCE_COLOR: 1
49 | TM_PUBLIC_BASE_DOMAIN: ${{ secrets.TM_PUBLIC_BASE_DOMAIN }}
50 | TM_PUBLIC_SUPABASE_URL: ${{ secrets.TM_PUBLIC_SUPABASE_URL }}
51 | TM_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.TM_PUBLIC_SUPABASE_ANON_KEY }}
52 |
53 | - name: Create Release Pull Request or Publish to npm
54 | uses: changesets/action@v1
55 | with:
56 | publish: node ./.github/scripts/release.mjs
57 | env:
58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
60 |
```
--------------------------------------------------------------------------------
/apps/extension/src/components/ui/CollapsibleSection.tsx:
--------------------------------------------------------------------------------
```typescript
1 | import type React from 'react';
2 | import { useState } from 'react';
3 | import { Button } from './button';
4 | import { ChevronDown, ChevronRight } from 'lucide-react';
5 | import type { LucideIcon } from 'lucide-react';
6 |
7 | interface CollapsibleSectionProps {
8 | title: string;
9 | icon?: LucideIcon;
10 | defaultExpanded?: boolean;
11 | className?: string;
12 | headerClassName?: string;
13 | contentClassName?: string;
14 | buttonClassName?: string;
15 | children: React.ReactNode;
16 | rightElement?: React.ReactNode;
17 | }
18 |
19 | export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
20 | title,
21 | icon: Icon,
22 | defaultExpanded = false,
23 | className = '',
24 | headerClassName = '',
25 | contentClassName = '',
26 | buttonClassName = 'text-vscode-foreground/70 hover:text-vscode-foreground',
27 | children,
28 | rightElement
29 | }) => {
30 | const [isExpanded, setIsExpanded] = useState(defaultExpanded);
31 |
32 | return (
33 | <div className={`mb-8 ${className}`}>
34 | <div className={`flex items-center gap-2 mb-4 ${headerClassName}`}>
35 | <Button
36 | variant="ghost"
37 | size="sm"
38 | className={`p-0 h-auto ${buttonClassName}`}
39 | onClick={() => setIsExpanded(!isExpanded)}
40 | >
41 | {isExpanded ? (
42 | <ChevronDown className="w-4 h-4 mr-1" />
43 | ) : (
44 | <ChevronRight className="w-4 h-4 mr-1" />
45 | )}
46 | {Icon && <Icon className="w-4 h-4 mr-1" />}
47 | {title}
48 | </Button>
49 | {rightElement}
50 | </div>
51 |
52 | {isExpanded && (
53 | <div
54 | className={`bg-widget-background rounded-lg p-4 border border-widget-border ${contentClassName}`}
55 | >
56 | {children}
57 | </div>
58 | )}
59 | </div>
60 | );
61 | };
62 |
```
--------------------------------------------------------------------------------
/apps/extension/src/webview/components/SidebarView.tsx:
--------------------------------------------------------------------------------
```typescript
1 | import React, { useState, useEffect } from 'react';
2 | import { TaskMasterLogo } from '../../components/TaskMasterLogo';
3 |
4 | interface SidebarViewProps {
5 | initialConnectionStatus?: boolean;
6 | }
7 |
8 | // Acquire VS Code API only once globally to avoid "already acquired" error
9 | const vscode = window.acquireVsCodeApi ? window.acquireVsCodeApi() : null;
10 |
11 | export const SidebarView: React.FC<SidebarViewProps> = ({
12 | initialConnectionStatus = false
13 | }) => {
14 | const [isConnected, setIsConnected] = useState(initialConnectionStatus);
15 |
16 | useEffect(() => {
17 | const handleMessage = (event: MessageEvent) => {
18 | const message = event.data;
19 | if (message.type === 'connectionStatus') {
20 | setIsConnected(message.data.isConnected);
21 | }
22 | };
23 |
24 | window.addEventListener('message', handleMessage);
25 | return () => {
26 | window.removeEventListener('message', handleMessage);
27 | };
28 | }, []);
29 |
30 | const handleOpenBoard = () => {
31 | vscode?.postMessage({ command: 'openBoard' });
32 | };
33 |
34 | return (
35 | <div className="h-full flex items-center justify-center p-6">
36 | <div className="text-center">
37 | <TaskMasterLogo className="w-20 h-20 mx-auto mb-5 opacity-80 text-vscode-foreground" />
38 |
39 | <h2 className="text-xl font-semibold mb-6 text-vscode-foreground">
40 | TaskMaster
41 | </h2>
42 |
43 | <button
44 | onClick={handleOpenBoard}
45 | className="w-full px-4 py-2 bg-vscode-button-background text-vscode-button-foreground rounded hover:bg-vscode-button-hoverBackground transition-colors text-sm font-medium"
46 | >
47 | Open Kanban Board
48 | </button>
49 | </div>
50 | </div>
51 | );
52 | };
53 |
```
--------------------------------------------------------------------------------
/apps/docs/getting-started/quick-start/requirements.mdx:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | title: Requirements
3 | sidebarTitle: "Requirements"
4 | ---
5 | Before you can start using TaskMaster AI, you'll need to install Node.js and set up at least one model API Key.
6 |
7 | ## 1. Node.js
8 |
9 | TaskMaster AI is built with Node.js and requires it to run. npm (Node Package Manager) comes bundled with Node.js.
10 |
11 | <Accordion title="Install Node.js">
12 |
13 | ### Installation
14 |
15 | **Option 1: Download from official website**
16 | 1. Visit [nodejs.org](https://nodejs.org)
17 | 2. Download the **LTS (Long Term Support)** version for your operating system
18 | 3. Run the installer and follow the setup wizard
19 |
20 | **Option 2: Use a package manager**
21 |
22 | <CodeGroup>
23 |
24 | ```bash Windows (Chocolatey)
25 | choco install nodejs
26 | ```
27 |
28 | ```bash Windows (winget)
29 | winget install OpenJS.NodeJS
30 | ```
31 |
32 | </CodeGroup>
33 |
34 | </Accordion>
35 |
36 | ## 2. Model API Key
37 |
38 | Taskmaster utilizes AI across several commands, and those require a separate API key. For the purpose of a Quick Start we recommend setting up an API Key with Anthropic for your main model and Perplexity for your research model (optional but recommended).
39 |
40 | <Tip>Task Master shows API costs per command used. Most users load $5-10 on their keys and don't have to top it off for a few months.</Tip>
41 |
42 | At least one (1) of the following is required:
43 |
44 | 1. Anthropic API key (Claude API) - **recommended for Quick Start**
45 | 2. OpenAI API key
46 | 3. Google Gemini API key
47 | 4. Perplexity API key (for research model)
48 | 5. xAI API Key (for research or main model)
49 | 6. OpenRouter API Key (for research or main model)
50 | 7. Claude Code (no API key required - requires Claude Code CLI)
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/convert-task-to-subtask.md:
--------------------------------------------------------------------------------
```markdown
1 | Convert an existing task into a subtask.
2 |
3 | Arguments: $ARGUMENTS
4 |
5 | Parse parent ID and task ID to convert.
6 |
7 | ## Task Conversion
8 |
9 | Converts an existing standalone task into a subtask of another task.
10 |
11 | ## Argument Parsing
12 |
13 | - "move task 8 under 5"
14 | - "make 8 a subtask of 5"
15 | - "nest 8 in 5"
16 | - "5 8" → make task 8 a subtask of task 5
17 |
18 | ## Execution
19 |
20 | ```bash
21 | task-master add-subtask --parent=<parent-id> --task-id=<task-to-convert>
22 | ```
23 |
24 | ## Pre-Conversion Checks
25 |
26 | 1. **Validation**
27 | - Both tasks exist and are valid
28 | - No circular parent relationships
29 | - Task isn't already a subtask
30 | - Logical hierarchy makes sense
31 |
32 | 2. **Impact Analysis**
33 | - Dependencies that will be affected
34 | - Tasks that depend on converting task
35 | - Priority alignment needed
36 | - Status compatibility
37 |
38 | ## Conversion Process
39 |
40 | 1. Change task ID from "8" to "5.1" (next available)
41 | 2. Update all dependency references
42 | 3. Inherit parent's context where appropriate
43 | 4. Adjust priorities if needed
44 | 5. Update time estimates
45 |
46 | ## Smart Features
47 |
48 | - Preserve task history
49 | - Maintain dependencies
50 | - Update all references
51 | - Create conversion log
52 |
53 | ## Example
54 |
55 | ```
56 | /taskmaster:add-subtask/from-task 5 8
57 | → Converting: Task #8 becomes subtask #5.1
58 | → Updated: 3 dependency references
59 | → Parent task #5 now has 1 subtask
60 | → Note: Subtask inherits parent's priority
61 |
62 | Before: #8 "Implement validation" (standalone)
63 | After: #5.1 "Implement validation" (subtask of #5)
64 | ```
65 |
66 | ## Post-Conversion
67 |
68 | - Show new task hierarchy
69 | - List updated dependencies
70 | - Verify project integrity
71 | - Suggest related conversions
```
--------------------------------------------------------------------------------
/apps/extension/src/components/ui/scroll-area.tsx:
--------------------------------------------------------------------------------
```typescript
1 | import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
2 | import type * as React from 'react';
3 |
4 | import { cn } from '@/lib/utils';
5 |
6 | function ScrollArea({
7 | className,
8 | children,
9 | ...props
10 | }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
11 | return (
12 | <ScrollAreaPrimitive.Root
13 | data-slot="scroll-area"
14 | className={cn('relative overflow-hidden', className)}
15 | {...props}
16 | >
17 | <ScrollAreaPrimitive.Viewport
18 | data-slot="scroll-area-viewport"
19 | className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 overflow-y-auto"
20 | >
21 | {children}
22 | </ScrollAreaPrimitive.Viewport>
23 | <ScrollBar />
24 | <ScrollAreaPrimitive.Corner />
25 | </ScrollAreaPrimitive.Root>
26 | );
27 | }
28 |
29 | function ScrollBar({
30 | className,
31 | orientation = 'vertical',
32 | ...props
33 | }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
34 | return (
35 | <ScrollAreaPrimitive.ScrollAreaScrollbar
36 | data-slot="scroll-area-scrollbar"
37 | orientation={orientation}
38 | className={cn(
39 | 'flex touch-none p-px transition-colors select-none',
40 | orientation === 'vertical' &&
41 | 'h-full w-2.5 border-l border-l-transparent',
42 | orientation === 'horizontal' &&
43 | 'h-2.5 flex-col border-t border-t-transparent',
44 | className
45 | )}
46 | {...props}
47 | >
48 | <ScrollAreaPrimitive.ScrollAreaThumb
49 | data-slot="scroll-area-thumb"
50 | className="bg-border relative flex-1 rounded-full"
51 | />
52 | </ScrollAreaPrimitive.ScrollAreaScrollbar>
53 | );
54 | }
55 |
56 | export { ScrollArea, ScrollBar };
57 |
```
--------------------------------------------------------------------------------
/apps/extension/src/components/ui/badge.tsx:
--------------------------------------------------------------------------------
```typescript
1 | import { Slot } from '@radix-ui/react-slot';
2 | import { type VariantProps, cva } from 'class-variance-authority';
3 | import type * as React from 'react';
4 |
5 | import { cn } from '@/lib/utils';
6 |
7 | const badgeVariants = cva(
8 | 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-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 transition-[color,box-shadow] overflow-hidden',
9 | {
10 | variants: {
11 | variant: {
12 | default:
13 | 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
14 | secondary:
15 | 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
16 | destructive:
17 | 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
18 | outline:
19 | 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground'
20 | }
21 | },
22 | defaultVariants: {
23 | variant: 'default'
24 | }
25 | }
26 | );
27 |
28 | function Badge({
29 | className,
30 | variant,
31 | asChild = false,
32 | ...props
33 | }: React.ComponentProps<'span'> &
34 | VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
35 | const Comp = asChild ? Slot : 'span';
36 |
37 | return (
38 | <Comp
39 | data-slot="badge"
40 | className={cn(badgeVariants({ variant }), className)}
41 | {...props}
42 | />
43 | );
44 | }
45 |
46 | export { Badge, badgeVariants };
47 |
```
--------------------------------------------------------------------------------
/apps/extension/src/services/polling-strategies.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Polling Strategies - Simplified
3 | * Different algorithms for polling intervals
4 | */
5 |
6 | import type { PollingStrategy } from './polling-service';
7 |
8 | /**
9 | * Fixed interval polling
10 | */
11 | export class FixedIntervalStrategy implements PollingStrategy {
12 | constructor(private interval = 10000) {}
13 |
14 | calculateNextInterval(): number {
15 | return this.interval;
16 | }
17 |
18 | getName(): string {
19 | return 'fixed';
20 | }
21 | }
22 |
23 | /**
24 | * Adaptive polling based on activity
25 | */
26 | export class AdaptivePollingStrategy implements PollingStrategy {
27 | private readonly MIN_INTERVAL = 5000; // 5 seconds
28 | private readonly MAX_INTERVAL = 60000; // 1 minute
29 | private readonly BASE_INTERVAL = 10000; // 10 seconds
30 |
31 | calculateNextInterval(consecutiveNoChanges: number): number {
32 | // Start with base interval
33 | let interval = this.BASE_INTERVAL;
34 |
35 | // If no changes for a while, slow down
36 | if (consecutiveNoChanges > 5) {
37 | interval = Math.min(
38 | this.MAX_INTERVAL,
39 | this.BASE_INTERVAL * 1.5 ** (consecutiveNoChanges - 5)
40 | );
41 | } else if (consecutiveNoChanges === 0) {
42 | // Recent change, poll more frequently
43 | interval = this.MIN_INTERVAL;
44 | }
45 |
46 | return Math.round(interval);
47 | }
48 |
49 | getName(): string {
50 | return 'adaptive';
51 | }
52 | }
53 |
54 | /**
55 | * Create polling strategy from configuration
56 | */
57 | export function createPollingStrategy(config: any): PollingStrategy {
58 | const type = config.get('polling.strategy', 'adaptive');
59 | const interval = config.get('polling.interval', 10000);
60 |
61 | switch (type) {
62 | case 'fixed':
63 | return new FixedIntervalStrategy(interval);
64 | default:
65 | return new AdaptivePollingStrategy();
66 | }
67 | }
68 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/command-pipeline.md:
--------------------------------------------------------------------------------
```markdown
1 | Execute a pipeline of commands based on a specification.
2 |
3 | Arguments: $ARGUMENTS
4 |
5 | ## Command Pipeline Execution
6 |
7 | Parse pipeline specification from arguments. Supported formats:
8 |
9 | ### Simple Pipeline
10 | `init → expand-all → sprint-plan`
11 |
12 | ### Conditional Pipeline
13 | `status → if:pending>10 → sprint-plan → else → next`
14 |
15 | ### Iterative Pipeline
16 | `for:pending-tasks → expand → complexity-check`
17 |
18 | ### Smart Pipeline Patterns
19 |
20 | **1. Project Setup Pipeline**
21 | ```
22 | init [prd] →
23 | expand-all →
24 | complexity-report →
25 | sprint-plan →
26 | show first-sprint
27 | ```
28 |
29 | **2. Daily Work Pipeline**
30 | ```
31 | standup →
32 | if:in-progress → continue →
33 | else → next → start
34 | ```
35 |
36 | **3. Task Completion Pipeline**
37 | ```
38 | complete [id] →
39 | git-commit →
40 | if:blocked-tasks-freed → show-freed →
41 | next
42 | ```
43 |
44 | **4. Quality Check Pipeline**
45 | ```
46 | list in-progress →
47 | for:each → check-idle-time →
48 | if:idle>1day → prompt-update
49 | ```
50 |
51 | ### Pipeline Features
52 |
53 | **Variables**
54 | - Store results: `status → $count=pending-count`
55 | - Use in conditions: `if:$count>10`
56 | - Pass between commands: `expand $high-priority-tasks`
57 |
58 | **Error Handling**
59 | - On failure: `try:complete → catch:show-blockers`
60 | - Skip on error: `optional:test-run`
61 | - Retry logic: `retry:3:commit`
62 |
63 | **Parallel Execution**
64 | - Parallel branches: `[analyze | test | lint]`
65 | - Join results: `parallel → join:report`
66 |
67 | ### Execution Flow
68 |
69 | 1. Parse pipeline specification
70 | 2. Validate command sequence
71 | 3. Execute with state passing
72 | 4. Handle conditions and loops
73 | 5. Aggregate results
74 | 6. Show summary
75 |
76 | This enables complex workflows like:
77 | `parse-prd → expand-all → filter:complex>70 → assign:senior → sprint-plan:weighted`
```
--------------------------------------------------------------------------------
/mcp-server/src/tools/get-operation-status.js:
--------------------------------------------------------------------------------
```javascript
1 | // mcp-server/src/tools/get-operation-status.js
2 | import { z } from 'zod';
3 | import { createErrorResponse, createContentResponse } from './utils.js'; // Assuming these utils exist
4 |
5 | /**
6 | * Register the get_operation_status tool.
7 | * @param {FastMCP} server - FastMCP server instance.
8 | * @param {AsyncOperationManager} asyncManager - The async operation manager.
9 | */
10 | export function registerGetOperationStatusTool(server, asyncManager) {
11 | server.addTool({
12 | name: 'get_operation_status',
13 | description:
14 | 'Retrieves the status and result/error of a background operation.',
15 | parameters: z.object({
16 | operationId: z.string().describe('The ID of the operation to check.')
17 | }),
18 | execute: async (args, { log }) => {
19 | try {
20 | const { operationId } = args;
21 | log.info(`Checking status for operation ID: ${operationId}`);
22 |
23 | const status = asyncManager.getStatus(operationId);
24 |
25 | // Status will now always return an object, but it might have status='not_found'
26 | if (status.status === 'not_found') {
27 | log.warn(`Operation ID not found: ${operationId}`);
28 | return createErrorResponse(
29 | status.error?.message || `Operation ID not found: ${operationId}`,
30 | status.error?.code || 'OPERATION_NOT_FOUND'
31 | );
32 | }
33 |
34 | log.info(`Status for ${operationId}: ${status.status}`);
35 | return createContentResponse(status);
36 | } catch (error) {
37 | log.error(`Error in get_operation_status tool: ${error.message}`, {
38 | stack: error.stack
39 | });
40 | return createErrorResponse(
41 | `Failed to get operation status: ${error.message}`,
42 | 'GET_STATUS_ERROR'
43 | );
44 | }
45 | }
46 | });
47 | }
48 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/execution/executors/executor-factory.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Factory for creating task executors
3 | */
4 |
5 | import { getLogger } from '../../../common/logger/index.js';
6 | import { ClaudeExecutor } from '../executors/claude-executor.js';
7 | import type { ExecutorOptions, ExecutorType, ITaskExecutor } from '../types.js';
8 |
9 | export class ExecutorFactory {
10 | private static logger = getLogger('ExecutorFactory');
11 |
12 | /**
13 | * Create an executor based on the provided options
14 | */
15 | static create(options: ExecutorOptions): ITaskExecutor {
16 | this.logger.debug(`Creating executor of type: ${options.type}`);
17 |
18 | switch (options.type) {
19 | case 'claude':
20 | return new ClaudeExecutor(options.projectRoot, options.config);
21 |
22 | case 'shell':
23 | // Placeholder for shell executor
24 | throw new Error('Shell executor not yet implemented');
25 |
26 | case 'custom':
27 | // Placeholder for custom executor
28 | throw new Error('Custom executor not yet implemented');
29 |
30 | default:
31 | throw new Error(`Unknown executor type: ${options.type}`);
32 | }
33 | }
34 |
35 | /**
36 | * Get the default executor type based on available tools
37 | */
38 | static async getDefaultExecutor(
39 | projectRoot: string
40 | ): Promise<ExecutorType | null> {
41 | // Check for Claude first
42 | const claudeExecutor = new ClaudeExecutor(projectRoot);
43 | if (await claudeExecutor.isAvailable()) {
44 | this.logger.info('Claude CLI detected as default executor');
45 | return 'claude';
46 | }
47 |
48 | // Could check for other executors here
49 | this.logger.warn('No default executor available');
50 | return null;
51 | }
52 |
53 | /**
54 | * Get list of available executor types
55 | */
56 | static getAvailableTypes(): ExecutorType[] {
57 | return ['claude', 'shell', 'custom'];
58 | }
59 | }
60 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/list-tasks.md:
--------------------------------------------------------------------------------
```markdown
1 | List tasks with intelligent argument parsing.
2 |
3 | Parse arguments to determine filters and display options:
4 | - Status: pending, in-progress, done, review, deferred, cancelled
5 | - Priority: high, medium, low (or priority:high)
6 | - Special: subtasks, tree, dependencies, blocked
7 | - IDs: Direct numbers (e.g., "1,3,5" or "1-5")
8 | - Complex: "pending high" = pending AND high priority
9 |
10 | Arguments: $ARGUMENTS
11 |
12 | Let me parse your request intelligently:
13 |
14 | 1. **Detect Filter Intent**
15 | - If arguments contain status keywords → filter by status
16 | - If arguments contain priority → filter by priority
17 | - If arguments contain "subtasks" → include subtasks
18 | - If arguments contain "tree" → hierarchical view
19 | - If arguments contain numbers → show specific tasks
20 | - If arguments contain "blocked" → show blocked tasks only
21 |
22 | 2. **Smart Combinations**
23 | Examples of what I understand:
24 | - "pending high" → pending tasks with high priority
25 | - "done today" → tasks completed today
26 | - "blocked" → tasks with unmet dependencies
27 | - "1-5" → tasks 1 through 5
28 | - "subtasks tree" → hierarchical view with subtasks
29 |
30 | 3. **Execute Appropriate Query**
31 | Based on parsed intent, run the most specific task-master command
32 |
33 | 4. **Enhanced Display**
34 | - Group by relevant criteria
35 | - Show most important information first
36 | - Use visual indicators for quick scanning
37 | - Include relevant metrics
38 |
39 | 5. **Intelligent Suggestions**
40 | Based on what you're viewing, suggest next actions:
41 | - Many pending? → Suggest priority order
42 | - Many blocked? → Show dependency resolution
43 | - Looking at specific tasks? → Show related tasks
```
--------------------------------------------------------------------------------
/packages/tm-core/src/common/types/repository-types.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Type definitions for repository operations
3 | */
4 | import { Database, Tables } from './database.types.js';
5 |
6 | /**
7 | * Task row from database with optional joined relations
8 | */
9 | export interface TaskWithRelations extends Tables<'tasks'> {
10 | document?: {
11 | id: string;
12 | document_name: string;
13 | title: string;
14 | description: string | null;
15 | } | null;
16 | }
17 |
18 | /**
19 | * Dependency row with joined display_id
20 | */
21 | export interface DependencyWithDisplayId {
22 | task_id: string;
23 | depends_on_task: {
24 | display_id: string;
25 | } | null;
26 | }
27 |
28 | /**
29 | * Task metadata structure
30 | */
31 | export interface TaskMetadata {
32 | details?: string;
33 | testStrategy?: string;
34 | [key: string]: unknown; // Allow additional fields but be explicit
35 | }
36 |
37 | /**
38 | * Database update payload for tasks
39 | */
40 | export type TaskDatabaseUpdate =
41 | Database['public']['Tables']['tasks']['Update'];
42 | /**
43 | * Configuration for task queries
44 | */
45 | export interface TaskQueryConfig {
46 | briefId: string;
47 | includeSubtasks?: boolean;
48 | includeDependencies?: boolean;
49 | includeDocument?: boolean;
50 | }
51 |
52 | /**
53 | * Result of a task fetch operation
54 | */
55 | export interface TaskFetchResult {
56 | task: Tables<'tasks'>;
57 | subtasks: Tables<'tasks'>[];
58 | dependencies: Map<string, string[]>;
59 | }
60 |
61 | /**
62 | * Task validation errors
63 | */
64 | export class TaskValidationError extends Error {
65 | constructor(
66 | message: string,
67 | public readonly field: string,
68 | public readonly value: unknown
69 | ) {
70 | super(message);
71 | this.name = 'TaskValidationError';
72 | }
73 | }
74 |
75 | /**
76 | * Context validation errors
77 | */
78 | export class ContextValidationError extends Error {
79 | constructor(message: string) {
80 | super(message);
81 | this.name = 'ContextValidationError';
82 | }
83 | }
84 |
```
--------------------------------------------------------------------------------
/test-config-manager.js:
--------------------------------------------------------------------------------
```javascript
1 | // test-config-manager.js
2 | console.log('=== ENVIRONMENT TEST ===');
3 | console.log('Working directory:', process.cwd());
4 | console.log('NODE_PATH:', process.env.NODE_PATH);
5 |
6 | // Test basic imports
7 | try {
8 | console.log('Importing config-manager');
9 | // Use dynamic import for ESM
10 | const configManagerModule = await import(
11 | './scripts/modules/config-manager.js'
12 | );
13 | const configManager = configManagerModule.default || configManagerModule;
14 | console.log('Config manager loaded successfully');
15 |
16 | console.log('Loading supported models');
17 | // Add after line 14 (after "Config manager loaded successfully")
18 | console.log('Config manager exports:', Object.keys(configManager));
19 | } catch (error) {
20 | console.error('Import error:', error.message);
21 | console.error(error.stack);
22 | }
23 |
24 | // Test file access
25 | try {
26 | console.log('Checking for .taskmasterconfig');
27 | // Use dynamic import for ESM
28 | const { readFileSync, existsSync } = await import('fs');
29 | const { resolve } = await import('path');
30 |
31 | const configExists = existsSync('./.taskmasterconfig');
32 | console.log('.taskmasterconfig exists:', configExists);
33 |
34 | if (configExists) {
35 | const config = JSON.parse(readFileSync('./.taskmasterconfig', 'utf-8'));
36 | console.log('Config keys:', Object.keys(config));
37 | }
38 |
39 | console.log('Checking for supported-models.json');
40 | const modelsPath = resolve('./scripts/modules/supported-models.json');
41 | console.log('Models path:', modelsPath);
42 | const modelsExists = existsSync(modelsPath);
43 | console.log('supported-models.json exists:', modelsExists);
44 | } catch (error) {
45 | console.error('File access error:', error.message);
46 | }
47 |
48 | console.log('=== TEST COMPLETE ===');
49 |
```
--------------------------------------------------------------------------------
/tests/integration/claude-code-error-handling.test.js:
--------------------------------------------------------------------------------
```javascript
1 | import { jest } from '@jest/globals';
2 |
3 | // Mock AI SDK functions at the top level
4 | jest.unstable_mockModule('ai', () => ({
5 | generateObject: jest.fn(),
6 | generateText: jest.fn(),
7 | streamText: jest.fn(),
8 | streamObject: jest.fn(),
9 | zodSchema: jest.fn(),
10 | JSONParseError: class JSONParseError extends Error {},
11 | NoObjectGeneratedError: class NoObjectGeneratedError extends Error {}
12 | }));
13 |
14 | // Mock CLI failure scenario
15 | jest.unstable_mockModule('ai-sdk-provider-claude-code', () => ({
16 | createClaudeCode: jest.fn(() => {
17 | throw new Error('Claude Code CLI not found');
18 | })
19 | }));
20 |
21 | // Import the provider after mocking
22 | const { ClaudeCodeProvider } = await import(
23 | '../../src/ai-providers/claude-code.js'
24 | );
25 |
26 | describe('Claude Code Error Handling', () => {
27 | beforeEach(() => {
28 | jest.clearAllMocks();
29 | });
30 |
31 | it('should throw a CLI-not-available error (with or without commandName)', () => {
32 | const provider = new ClaudeCodeProvider();
33 | expect(() => provider.getClient()).toThrow(
34 | /Claude Code CLI not available/i
35 | );
36 | expect(() => provider.getClient({ commandName: 'test' })).toThrow(
37 | /Claude Code CLI not available/i
38 | );
39 | });
40 |
41 | it('should still support basic provider functionality', () => {
42 | const provider = new ClaudeCodeProvider();
43 |
44 | // These should work even if CLI is not available
45 | expect(provider.name).toBe('Claude Code');
46 | expect(provider.getSupportedModels()).toEqual(['opus', 'sonnet', 'haiku']);
47 | expect(provider.isModelSupported('sonnet')).toBe(true);
48 | expect(provider.isModelSupported('haiku')).toBe(true);
49 | expect(provider.isRequiredApiKey()).toBe(false);
50 | expect(() => provider.validateAuth()).not.toThrow();
51 | });
52 | });
53 |
```
--------------------------------------------------------------------------------
/packages/ai-sdk-provider-grok-cli/src/types.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * Type definitions for Grok CLI provider
3 | */
4 |
5 | /**
6 | * Settings for configuring Grok CLI behavior
7 | */
8 | export interface GrokCliSettings {
9 | /** API key for Grok CLI */
10 | apiKey?: string;
11 | /** Base URL for Grok API */
12 | baseURL?: string;
13 | /** Default model to use */
14 | model?: string;
15 | /** Timeout in milliseconds */
16 | timeout?: number;
17 | /** Working directory for CLI commands */
18 | workingDirectory?: string;
19 | }
20 |
21 | /**
22 | * Model identifiers supported by Grok CLI
23 | */
24 | export type GrokCliModelId = string;
25 |
26 | /**
27 | * Error metadata for Grok CLI operations
28 | */
29 | export interface GrokCliErrorMetadata {
30 | /** Error code */
31 | code?: string;
32 | /** Process exit code */
33 | exitCode?: number;
34 | /** Standard error output */
35 | stderr?: string;
36 | /** Standard output */
37 | stdout?: string;
38 | /** Excerpt of the prompt that caused the error */
39 | promptExcerpt?: string;
40 | /** Timeout value in milliseconds */
41 | timeoutMs?: number;
42 | }
43 |
44 | /**
45 | * Message format for Grok CLI communication
46 | */
47 | export interface GrokCliMessage {
48 | /** Message role (user, assistant, system) */
49 | role: string;
50 | /** Message content */
51 | content: string;
52 | }
53 |
54 | /**
55 | * Response format from Grok CLI
56 | */
57 | export interface GrokCliResponse {
58 | /** Message role */
59 | role: string;
60 | /** Response content */
61 | content: string;
62 | /** Token usage information */
63 | usage?: {
64 | /** Input tokens used */
65 | prompt_tokens?: number;
66 | /** Output tokens used */
67 | completion_tokens?: number;
68 | /** Total tokens used */
69 | total_tokens?: number;
70 | };
71 | }
72 |
73 | /**
74 | * Configuration options for Grok CLI language model
75 | */
76 | export interface GrokCliLanguageModelOptions {
77 | /** Model identifier */
78 | id: GrokCliModelId;
79 | /** Model settings */
80 | settings?: GrokCliSettings;
81 | }
82 |
```
--------------------------------------------------------------------------------
/packages/tm-core/src/modules/reports/types.ts:
--------------------------------------------------------------------------------
```typescript
1 | /**
2 | * @fileoverview Type definitions for complexity analysis reports
3 | */
4 |
5 | /**
6 | * Analysis result for a single task
7 | */
8 | export interface ComplexityAnalysis {
9 | /** Task ID being analyzed */
10 | taskId: string | number;
11 | /** Task title */
12 | taskTitle: string;
13 | /** Complexity score (1-10 scale) */
14 | complexityScore: number;
15 | /** Recommended number of subtasks */
16 | recommendedSubtasks: number;
17 | /** AI-generated prompt for task expansion */
18 | expansionPrompt: string;
19 | /** Reasoning behind the complexity assessment */
20 | complexityReasoning: string;
21 | }
22 |
23 | /**
24 | * Metadata about the complexity report
25 | */
26 | export interface ComplexityReportMetadata {
27 | /** When the report was generated */
28 | generatedAt: string;
29 | /** Number of tasks analyzed in this run */
30 | tasksAnalyzed: number;
31 | /** Total number of tasks in the file */
32 | totalTasks?: number;
33 | /** Total analyses in the report (across all runs) */
34 | analysisCount?: number;
35 | /** Complexity threshold score used */
36 | thresholdScore: number;
37 | /** Project name */
38 | projectName?: string;
39 | /** Whether research mode was used */
40 | usedResearch: boolean;
41 | }
42 |
43 | /**
44 | * Complete complexity analysis report
45 | */
46 | export interface ComplexityReport {
47 | /** Report metadata */
48 | meta: ComplexityReportMetadata;
49 | /** Array of complexity analyses */
50 | complexityAnalysis: ComplexityAnalysis[];
51 | }
52 |
53 | /**
54 | * Complexity data to be attached to a Task
55 | */
56 | export interface TaskComplexityData {
57 | /** Complexity score (1-10 scale) */
58 | complexityScore?: number;
59 | /** Recommended number of subtasks */
60 | recommendedSubtasks?: number;
61 | /** AI-generated expansion prompt */
62 | expansionPrompt?: string;
63 | /** Reasoning behind the assessment */
64 | complexityReasoning?: string;
65 | }
66 |
```
--------------------------------------------------------------------------------
/tests/setup.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Jest setup file
3 | *
4 | * This file is run before each test suite to set up the test environment.
5 | */
6 |
7 | import path from 'path';
8 | import { fileURLToPath } from 'url';
9 |
10 | // Capture the actual original working directory before any changes
11 | const originalWorkingDirectory = process.cwd();
12 |
13 | // Store original working directory and project root
14 | const __filename = fileURLToPath(import.meta.url);
15 | const __dirname = path.dirname(__filename);
16 | const projectRoot = path.resolve(__dirname, '..');
17 |
18 | // Ensure we're always starting from the project root
19 | if (process.cwd() !== projectRoot) {
20 | process.chdir(projectRoot);
21 | }
22 |
23 | // Mock environment variables
24 | process.env.MODEL = 'sonar-pro';
25 | process.env.MAX_TOKENS = '64000';
26 | process.env.TEMPERATURE = '0.2';
27 | process.env.DEBUG = 'false';
28 | process.env.TASKMASTER_LOG_LEVEL = 'error'; // Set to error to reduce noise in tests
29 | process.env.DEFAULT_SUBTASKS = '5';
30 | process.env.DEFAULT_PRIORITY = 'medium';
31 | process.env.PROJECT_NAME = 'Test Project';
32 | process.env.PROJECT_VERSION = '1.0.0';
33 | // Ensure tests don't make real API calls by setting mock API keys
34 | process.env.ANTHROPIC_API_KEY = 'test-mock-api-key-for-tests';
35 | process.env.PERPLEXITY_API_KEY = 'test-mock-perplexity-key-for-tests';
36 |
37 | // Add global test helpers if needed
38 | global.wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
39 |
40 | // Store original working directory for tests that need it
41 | global.originalWorkingDirectory = originalWorkingDirectory;
42 | global.projectRoot = projectRoot;
43 |
44 | // If needed, silence console during tests
45 | if (process.env.SILENCE_CONSOLE === 'true') {
46 | global.console = {
47 | ...console,
48 | log: () => {},
49 | info: () => {},
50 | warn: () => {},
51 | error: () => {}
52 | };
53 | }
54 |
```
--------------------------------------------------------------------------------
/packages/claude-code-plugin/commands/project-status.md:
--------------------------------------------------------------------------------
```markdown
1 | Enhanced status command with comprehensive project insights.
2 |
3 | Arguments: $ARGUMENTS
4 |
5 | ## Intelligent Status Overview
6 |
7 | ### 1. **Executive Summary**
8 | Quick dashboard view:
9 | - 🏃 Active work (in-progress tasks)
10 | - 📊 Progress metrics (% complete, velocity)
11 | - 🚧 Blockers and risks
12 | - ⏱️ Time analysis (estimated vs actual)
13 | - 🎯 Sprint/milestone progress
14 |
15 | ### 2. **Contextual Analysis**
16 |
17 | Based on $ARGUMENTS, focus on:
18 | - "sprint" → Current sprint progress and burndown
19 | - "blocked" → Dependency chains and resolution paths
20 | - "team" → Task distribution and workload
21 | - "timeline" → Schedule adherence and projections
22 | - "risk" → High complexity or overdue items
23 |
24 | ### 3. **Smart Insights**
25 |
26 | **Workflow Health:**
27 | - Idle tasks (in-progress > 24h without updates)
28 | - Bottlenecks (multiple tasks waiting on same dependency)
29 | - Quick wins (low complexity, high impact)
30 |
31 | **Predictive Analytics:**
32 | - Completion projections based on velocity
33 | - Risk of missing deadlines
34 | - Recommended task order for optimal flow
35 |
36 | ### 4. **Visual Intelligence**
37 |
38 | Dynamic visualization based on data:
39 | ```
40 | Sprint Progress: ████████░░ 80% (16/20 tasks)
41 | Velocity Trend: ↗️ +15% this week
42 | Blocked Tasks: 🔴 3 critical path items
43 |
44 | Priority Distribution:
45 | High: ████████ 8 tasks (2 blocked)
46 | Medium: ████░░░░ 4 tasks
47 | Low: ██░░░░░░ 2 tasks
48 | ```
49 |
50 | ### 5. **Actionable Recommendations**
51 |
52 | Based on analysis:
53 | 1. **Immediate actions** (unblock critical path)
54 | 2. **Today's focus** (optimal task sequence)
55 | 3. **Process improvements** (recurring patterns)
56 | 4. **Resource needs** (skills, time, dependencies)
57 |
58 | ### 6. **Historical Context**
59 |
60 | Compare to previous periods:
61 | - Velocity changes
62 | - Pattern recognition
63 | - Improvement areas
64 | - Success patterns to repeat
```